Sync with ArchiBoT, closes #58

This commit is contained in:
JustArchi
2016-01-02 17:22:35 +01:00
parent 356df9098e
commit f236d6c33f
2 changed files with 152 additions and 40 deletions

View File

@@ -24,18 +24,61 @@
using SteamKit2;
using SteamKit2.Internal;
using System;
using System.Collections.Generic;
using System.IO;
namespace ArchiSteamFarm {
internal sealed class ArchiHandler : ClientMsgHandler {
/*
____ _ _ _ _
/ ___| __ _ | || || |__ __ _ ___ | | __ ___
| | / _` || || || '_ \ / _` | / __|| |/ // __|
| |___| (_| || || || |_) || (_| || (__ | < \__ \
\____|\__,_||_||_||_.__/ \__,_| \___||_|\_\|___/
*/
internal sealed class NotificationsCallback : CallbackMsg {
internal class Notification {
internal enum ENotificationType {
Unknown = 0,
Trading = 1,
}
internal ENotificationType NotificationType { get; set; }
}
internal List<Notification> Notifications { get; private set; }
internal NotificationsCallback(JobID jobID, CMsgClientUserNotifications msg) {
JobID = jobID;
if (msg == null) {
return;
}
Notifications = new List<Notification>();
foreach (var notification in msg.notifications) {
Notifications.Add(new Notification {
NotificationType = (Notification.ENotificationType) notification.user_notification_type
});
}
}
}
internal sealed class OfflineMessageCallback : CallbackMsg {
internal uint OfflineMessages { get; private set; }
internal List<uint> Users { get; private set; }
internal OfflineMessageCallback(CMsgClientOfflineMessageNotification body) {
OfflineMessages = body.offline_messages;
Users = body.friends_with_offline_messages;
internal OfflineMessageCallback(JobID jobID, CMsgClientOfflineMessageNotification msg) {
JobID = jobID;
if (msg == null) {
return;
}
OfflineMessages = msg.offline_messages;
Users = msg.friends_with_offline_messages;
}
}
@@ -53,14 +96,23 @@ namespace ArchiSteamFarm {
internal EResult Result { get; private set; }
internal EPurchaseResult PurchaseResult { get; private set; }
internal KeyValue ReceiptInfo { get; private set; } = new KeyValue();
internal Dictionary<uint, string> Items { get; private set; } = new Dictionary<uint, string>();
internal KeyValue ReceiptInfo { get; private set; }
internal Dictionary<uint, string> Items { get; private set; }
internal PurchaseResponseCallback(CMsgClientPurchaseResponse body) {
Result = (EResult) body.eresult;
PurchaseResult = (EPurchaseResult) body.purchase_result_details;
internal PurchaseResponseCallback(JobID jobID, CMsgClientPurchaseResponse msg) {
JobID = jobID;
using (MemoryStream ms = new MemoryStream(body.purchase_receipt_info)) {
if (msg == null) {
return;
}
ReceiptInfo = new KeyValue();
Items = new Dictionary<uint, string>();
Result = (EResult) msg.eresult;
PurchaseResult = (EPurchaseResult) msg.purchase_result_details;
using (MemoryStream ms = new MemoryStream(msg.purchase_receipt_info)) {
if (!ReceiptInfo.TryReadAsBinary(ms)) {
return;
}
@@ -72,36 +124,42 @@ namespace ArchiSteamFarm {
}
}
internal sealed class NotificationCallback : CallbackMsg {
internal enum ENotificationType {
Unknown = 0,
Trading = 1,
}
/*
__ __ _ _ _
| \/ | ___ | |_ | |__ ___ __| | ___
| |\/| | / _ \| __|| '_ \ / _ \ / _` |/ __|
| | | || __/| |_ | | | || (_) || (_| |\__ \
|_| |_| \___| \__||_| |_| \___/ \__,_||___/
internal ENotificationType NotificationType { get; private set; }
internal NotificationCallback(CMsgClientUserNotifications.Notification body) {
NotificationType = (ENotificationType) body.user_notification_type;
}
}
*/
internal void AcceptClanInvite(ulong clanID) {
if (clanID == 0) {
return;
}
var request = new ClientMsg<CMsgClientClanInviteAction>((int) EMsg.ClientAcknowledgeClanInvite);
request.Body.GroupID = clanID;
request.Body.AcceptInvite = true;
Client.Send(request);
}
internal void DeclineClanInvite(ulong clanID) {
if (clanID == 0) {
return;
}
var request = new ClientMsg<CMsgClientClanInviteAction>((int) EMsg.ClientAcknowledgeClanInvite);
request.Body.GroupID = clanID;
request.Body.AcceptInvite = false;
Client.Send(request);
}
internal void PlayGames(params uint[] gameIDs) {
internal void PlayGames(params ulong[] gameIDs) {
var request = new ClientMsgProtobuf<CMsgClientGamesPlayed>(EMsg.ClientGamesPlayed);
foreach (uint gameID in gameIDs) {
foreach (ulong gameID in gameIDs) {
if (gameID == 0) {
continue;
}
@@ -110,6 +168,7 @@ namespace ArchiSteamFarm {
game_id = new GameID(gameID),
});
}
Client.Send(request);
}
@@ -124,16 +183,32 @@ namespace ArchiSteamFarm {
game_id = new GameID(gameID),
});
}
Client.Send(request);
}
// Will provide result in ClientPurchaseResponse, regardless if success or not
internal void RedeemKey(string key) {
internal AsyncJob<PurchaseResponseCallback> RedeemKey(string key) {
if (string.IsNullOrEmpty(key)) {
return null;
}
var request = new ClientMsgProtobuf<CMsgClientRegisterKey>(EMsg.ClientRegisterKey);
request.SourceJobID = Client.GetNextJobID();
request.Body.key = key;
Client.Send(request);
return new AsyncJob<PurchaseResponseCallback>(Client, request.SourceJobID);
}
/*
_ _ _ _
| | | | __ _ _ __ __| || | ___ _ __ ___
| |_| | / _` || '_ \ / _` || | / _ \| '__|/ __|
| _ || (_| || | | || (_| || || __/| | \__ \
|_| |_| \__,_||_| |_| \__,_||_| \___||_| |___/
*/
public sealed override void HandleMsg(IPacketMsg packetMsg) {
if (packetMsg == null) {
return;
@@ -158,7 +233,11 @@ namespace ArchiSteamFarm {
}
var response = new ClientMsgProtobuf<CMsgClientOfflineMessageNotification>(packetMsg);
Client.PostCallback(new OfflineMessageCallback(response.Body));
if (response == null) {
return;
}
Client.PostCallback(new OfflineMessageCallback(packetMsg.TargetJobID, response.Body));
}
private void HandlePurchaseResponse(IPacketMsg packetMsg) {
@@ -167,7 +246,11 @@ namespace ArchiSteamFarm {
}
var response = new ClientMsgProtobuf<CMsgClientPurchaseResponse>(packetMsg);
Client.PostCallback(new PurchaseResponseCallback(response.Body));
if (response == null) {
return;
}
Client.PostCallback(new PurchaseResponseCallback(packetMsg.TargetJobID, response.Body));
}
private void HandleUserNotifications(IPacketMsg packetMsg) {
@@ -176,9 +259,11 @@ namespace ArchiSteamFarm {
}
var response = new ClientMsgProtobuf<CMsgClientUserNotifications>(packetMsg);
foreach (var notification in response.Body.notifications) {
Client.PostCallback(new NotificationCallback(notification));
if (response == null) {
return;
}
Client.PostCallback(new NotificationsCallback(packetMsg.TargetJobID, response.Body));
}
}
}

View File

@@ -160,7 +160,7 @@ namespace ArchiSteamFarm {
CallbackManager.Subscribe<SteamUser.LoginKeyCallback>(OnLoginKey);
CallbackManager.Subscribe<SteamUser.UpdateMachineAuthCallback>(OnMachineAuth);
CallbackManager.Subscribe<ArchiHandler.NotificationCallback>(OnNotification);
CallbackManager.Subscribe<ArchiHandler.NotificationsCallback>(OnNotifications);
CallbackManager.Subscribe<ArchiHandler.OfflineMessageCallback>(OnOfflineMessage);
CallbackManager.Subscribe<ArchiHandler.PurchaseResponseCallback>(OnPurchaseResponse);
@@ -499,6 +499,29 @@ namespace ArchiSteamFarm {
}
}
private async Task ResponseRedeem(ulong steamID, string key) {
if (steamID == 0 || string.IsNullOrEmpty(key)) {
return;
}
ArchiHandler.PurchaseResponseCallback result;
try {
result = await ArchiHandler.RedeemKey(key);
} catch (Exception e) {
Logging.LogGenericException(BotName, e);
return;
}
if (result == null) {
return;
}
var purchaseResult = result.PurchaseResult;
var items = result.Items;
SendMessage(SteamMasterID, "Status: " + purchaseResult + " | Items: " + string.Join("", items));
}
private void ResponseStart(ulong steamID, string botName) {
if (steamID == 0 || string.IsNullOrEmpty(botName)) {
return;
@@ -536,7 +559,7 @@ namespace ArchiSteamFarm {
private async Task HandleMessage(ulong steamID, string message) {
if (IsValidCdKey(message)) {
ArchiHandler.RedeemKey(message);
await ResponseRedeem(steamID, message).ConfigureAwait(false);
return;
}
@@ -575,7 +598,7 @@ namespace ArchiSteamFarm {
Response2FAOff(steamID, args[1]);
break;
case "!redeem":
ArchiHandler.RedeemKey(args[1]);
await ResponseRedeem(steamID, args[1]).ConfigureAwait(false);
break;
case "!start":
ResponseStart(steamID, args[1]);
@@ -924,15 +947,22 @@ namespace ArchiSteamFarm {
});
}
private void OnNotification(ArchiHandler.NotificationCallback callback) {
private void OnNotifications(ArchiHandler.NotificationsCallback callback) {
if (callback == null) {
return;
}
switch (callback.NotificationType) {
case ArchiHandler.NotificationCallback.ENotificationType.Trading:
Trading.CheckTrades();
break;
bool checkTrades = false;
foreach (var notification in callback.Notifications) {
switch (notification.NotificationType) {
case ArchiHandler.NotificationsCallback.Notification.ENotificationType.Trading:
checkTrades = true;
break;
}
}
if (checkTrades) {
Trading.CheckTrades();
}
}
@@ -954,9 +984,6 @@ namespace ArchiSteamFarm {
}
var purchaseResult = callback.PurchaseResult;
var items = callback.Items;
SendMessage(SteamMasterID, "Status: " + purchaseResult + " | Items: " + string.Join("", items));
if (purchaseResult == ArchiHandler.PurchaseResponseCallback.EPurchaseResult.OK) {
// We will restart CF module to recalculate current status and decide about new optimal approach
await CardsFarmer.RestartFarming().ConfigureAwait(false);