From 18800ff8d565c41e4816e6586705016e6cede25f Mon Sep 17 00:00:00 2001 From: JustArchi Date: Fri, 5 Feb 2016 20:10:15 +0100 Subject: [PATCH] Major cleanup and improvements, closes #100 --- ArchiSteamFarm/Bot.cs | 198 +++++++++++++++++++++----------------- ArchiSteamFarm/Program.cs | 6 +- 2 files changed, 114 insertions(+), 90 deletions(-) diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index f6bd0c39d2dea..efd30d14022b4 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -61,11 +61,11 @@ internal sealed class Bot { internal readonly ArchiWebHandler ArchiWebHandler; internal readonly SteamClient SteamClient; - private bool KeepRunning = true; private bool InvalidPassword = false; private bool LoggedInElsewhere = false; private string AuthCode, LoginKey, TwoFactorAuth; + internal bool KeepRunning { get; private set; } = false; internal SteamGuardAccount SteamGuardAccount { get; private set; } // Config variables @@ -110,10 +110,6 @@ internal static string GetAnyBotName() { return null; } - internal static int GetRunningBotsCount() { - return Bots.Count; - } - internal static void RefreshCMs() { bool initialized = false; while (!initialized) { @@ -148,12 +144,12 @@ internal Bot(string botName, bool initialLaunch = false) { return; } + Bots.AddOrUpdate(BotName, this, (key, value) => this); + if (initialLaunch && !StartOnLaunch) { return; } - Bots.AddOrUpdate(BotName, this, (key, value) => this); - // Initialize SteamClient = new SteamClient(); @@ -203,7 +199,6 @@ internal Bot(string botName, bool initialLaunch = false) { } // Start - var handleCallbacks = Task.Run(() => HandleCallbacks()); var start = Task.Run(async () => await Start().ConfigureAwait(false)); } @@ -400,7 +395,7 @@ private bool ReadConfig() { } internal async Task Restart() { - await Stop().ConfigureAwait(false); + Stop(); await Start().ConfigureAwait(false); } @@ -409,6 +404,11 @@ internal async Task Start() { return; } + if (!KeepRunning) { + KeepRunning = true; + var handleCallbacks = Task.Run(() => HandleCallbacks()); + } + Logging.LogGenericInfo("Starting...", BotName); // 2FA tokens are expiring soon, use limiter only when we don't have any pending @@ -419,46 +419,28 @@ internal async Task Start() { SteamClient.Connect(); } - internal async Task Stop() { + internal void Stop() { if (!SteamClient.IsConnected) { return; } - await Utilities.SleepAsync(0); // TODO: This is here only to make VS happy, for now - Logging.LogGenericInfo("Stopping...", BotName); SteamClient.Disconnect(); } - internal async Task Shutdown() { + internal void Shutdown() { KeepRunning = false; - await Stop().ConfigureAwait(false); - Bot bot; - Bots.TryRemove(BotName, out bot); + Stop(); Program.OnBotShutdown(); } - internal static async Task Shutdown(string botName) { - if (string.IsNullOrEmpty(botName)) { - return false; - } - - Bot bot; - if (!Bots.TryGetValue(botName, out bot)) { - return false; - } - - await bot.Shutdown().ConfigureAwait(false); - return true; - } - internal async Task OnFarmingFinished() { if (SendOnFarmingFinished) { await ResponseSendTrade(BotName).ConfigureAwait(false); } if (ShutdownOnFarmingFinished) { - await Shutdown().ConfigureAwait(false); + Shutdown(); } } @@ -482,6 +464,14 @@ private void SendMessage(ulong steamID, string message) { } } + internal string ResponseStatus() { + if (CardsFarmer.CurrentGamesFarming.Count > 0) { + return "Bot " + BotName + " is currently farming appIDs: " + string.Join(", ", CardsFarmer.CurrentGamesFarming) + " and has a total of " + CardsFarmer.GamesToFarm.Count + " games left to farm."; + } else { + return "Bot " + BotName + " is currently not farming anything."; + } + } + internal static string ResponseStatus(string botName) { if (string.IsNullOrEmpty(botName)) { return null; @@ -495,59 +485,49 @@ internal static string ResponseStatus(string botName) { return bot.ResponseStatus(); } - internal string ResponseStatus() { - if (CardsFarmer.CurrentGamesFarming.Count > 0) { - return "Bot " + BotName + " is currently farming appIDs: " + string.Join(", ", CardsFarmer.CurrentGamesFarming) + " and has a total of " + CardsFarmer.GamesToFarm.Count + " games left to farm."; - } else { - return "Bot " + BotName + " is not farming."; - } - } - internal static string ResponseStatusAll() { StringBuilder result = new StringBuilder(Environment.NewLine); + + int totalBotsCount = Bots.Count; + int runningBotsCount = 0; + foreach (Bot bot in Bots.Values) { result.Append(bot.ResponseStatus() + Environment.NewLine); + if (bot.KeepRunning) { + runningBotsCount++; + } } - result.Append("Currently " + Bots.Count + " bots are running."); + result.Append("There are " + totalBotsCount + " bots initialized and " + runningBotsCount + " of them are currently running."); return result.ToString(); } - internal static async Task ResponseSendTrade(string botName) { - if (string.IsNullOrEmpty(botName)) { - return null; - } - - Bot bot; - if (!Bots.TryGetValue(botName, out bot)) { - return "Couldn't find any bot named " + botName + "!"; - } - - if (bot.SteamMasterID == 0) { + internal async Task ResponseSendTrade() { + if (SteamMasterID == 0) { return "Trade couldn't be send because SteamMasterID is not defined!"; } string token = null; - if (!string.IsNullOrEmpty(bot.SteamTradeToken) && !bot.SteamTradeToken.Equals("null")) { - token = bot.SteamTradeToken; + if (!string.IsNullOrEmpty(SteamTradeToken) && !SteamTradeToken.Equals("null")) { + token = SteamTradeToken; } await Trading.LimitInventoryRequestsAsync().ConfigureAwait(false); - List inventory = await bot.ArchiWebHandler.GetInventory().ConfigureAwait(false); + List inventory = await ArchiWebHandler.GetInventory().ConfigureAwait(false); if (inventory == null || inventory.Count == 0) { return "Nothing to send, inventory seems empty!"; } - if (await bot.ArchiWebHandler.SendTradeOffer(inventory, bot.SteamMasterID, token).ConfigureAwait(false)) { - await bot.AcceptAllConfirmations().ConfigureAwait(false); + if (await ArchiWebHandler.SendTradeOffer(inventory, SteamMasterID, token).ConfigureAwait(false)) { + await AcceptAllConfirmations().ConfigureAwait(false); return "Trade offer sent successfully!"; } else { return "Trade offer failed due to error!"; } } - internal static string Response2FA(string botName) { + internal static async Task ResponseSendTrade(string botName) { if (string.IsNullOrEmpty(botName)) { return null; } @@ -557,15 +537,19 @@ internal static string Response2FA(string botName) { return "Couldn't find any bot named " + botName + "!"; } - if (bot.SteamGuardAccount == null) { + return await bot.ResponseSendTrade().ConfigureAwait(false); + } + + internal string Response2FA() { + if (SteamGuardAccount == null) { return "That bot doesn't have ASF 2FA enabled!"; } long timeLeft = 30 - TimeAligner.GetSteamTime() % 30; - return "2FA Token: " + bot.SteamGuardAccount.GenerateSteamGuardCode() + " (expires in " + timeLeft + " seconds)"; + return "2FA Token: " + SteamGuardAccount.GenerateSteamGuardCode() + " (expires in " + timeLeft + " seconds)"; } - internal static string Response2FAOff(string botName) { + internal static string Response2FA(string botName) { if (string.IsNullOrEmpty(botName)) { return null; } @@ -575,17 +559,34 @@ internal static string Response2FAOff(string botName) { return "Couldn't find any bot named " + botName + "!"; } - if (bot.SteamGuardAccount == null) { + return bot.Response2FA(); + } + + internal string Response2FAOff() { + if (SteamGuardAccount == null) { return "That bot doesn't have ASF 2FA enabled!"; } - if (bot.DelinkMobileAuthenticator()) { + if (DelinkMobileAuthenticator()) { return "Done! Bot is no longer using ASF 2FA"; } else { return "Something went wrong during delinking mobile authenticator!"; } } + internal static string Response2FAOff(string botName) { + if (string.IsNullOrEmpty(botName)) { + return null; + } + + Bot bot; + if (!Bots.TryGetValue(botName, out bot)) { + return "Couldn't find any bot named " + botName + "!"; + } + + return bot.Response2FAOff(); + } + internal async Task ResponseRedeem(string message, bool validate) { if (string.IsNullOrEmpty(message)) { return null; @@ -739,6 +740,15 @@ internal static async Task ResponseRedeem(string botName, string message return await bot.ResponseRedeem(message, validate).ConfigureAwait(false); } + internal async Task ResponseAddLicense(uint gameID) { + if (gameID == 0) { + return null; + } + + var result = await SteamApps.RequestFreeLicense(gameID); + return "Result: " + result.Result + " | Granted apps: " + string.Join(", ", result.GrantedApps) + " " + string.Join(", ", result.GrantedPackages); + } + internal static async Task ResponseAddLicense(string botName, string game) { if (string.IsNullOrEmpty(botName) || string.IsNullOrEmpty(game)) { return null; @@ -754,8 +764,13 @@ internal static async Task ResponseAddLicense(string botName, string gam return "Couldn't parse game as a number!"; } - var result = await bot.SteamApps.RequestFreeLicense(gameID); - return "Result: " + result.Result + " | Granted apps: " + string.Join(", ", result.GrantedApps) + " " + string.Join(", ", result.GrantedPackages); + return await bot.ResponseAddLicense(gameID).ConfigureAwait(false); + } + + internal async Task ResponsePlay(uint gameID) { + await CardsFarmer.SwitchToManualMode(gameID != 0).ConfigureAwait(false); + ArchiHandler.PlayGames(gameID); + return "Done!"; } internal static async Task ResponsePlay(string botName, string game) { @@ -773,44 +788,51 @@ internal static async Task ResponsePlay(string botName, string game) { return "Couldn't parse game as a number!"; } - await bot.CardsFarmer.SwitchToManualMode(gameID != 0).ConfigureAwait(false); - bot.ArchiHandler.PlayGames(gameID); + return await bot.ResponsePlay(gameID).ConfigureAwait(false); + } + internal async Task ResponseStart() { + if (KeepRunning) { + return "That bot instance is already running!"; + } + + await Start().ConfigureAwait(false); return "Done!"; } - internal static string ResponseStart(string botName) { + internal static async Task ResponseStart(string botName) { if (string.IsNullOrEmpty(botName)) { return null; } - if (Bots.ContainsKey(botName)) { - return "That bot instance is already running!"; + Bot bot; + if (!Bots.TryGetValue(botName, out bot)) { + return "Couldn't find any bot named " + botName + "!"; } - new Bot(botName); - if (Bots.ContainsKey(botName)) { - return "Done!"; - } else { - return "That bot instance failed to start, make sure that XML config exists and bot is active!"; + return await bot.ResponseStart().ConfigureAwait(false); + } + + internal string ResponseStop() { + if (!KeepRunning) { + return "That bot instance is already inactive!"; } + + Shutdown(); + return "Done!"; } - internal static async Task ResponseStop(string botName) { + internal static string ResponseStop(string botName) { if (string.IsNullOrEmpty(botName)) { return null; } Bot bot; if (!Bots.TryGetValue(botName, out bot)) { - return "That bot instance is already inactive!"; + return "Couldn't find any bot named " + botName + "!"; } - if (await Shutdown(botName).ConfigureAwait(false)) { - return "Done!"; - } else { - return "That bot instance failed to shutdown!"; - } + return bot.ResponseStop(); } internal async Task HandleMessage(string message) { @@ -825,9 +847,9 @@ internal async Task HandleMessage(string message) { if (!message.Contains(" ")) { switch (message) { case "!2fa": - return Response2FA(BotName); + return Response2FA(); case "!2faoff": - return Response2FAOff(BotName); + return Response2FAOff(); case "!exit": Program.Exit(); return "Done"; @@ -839,9 +861,9 @@ internal async Task HandleMessage(string message) { case "!statusall": return ResponseStatusAll(); case "!stop": - return await ResponseStop(BotName).ConfigureAwait(false); + return ResponseStop(); case "!loot": - return await ResponseSendTrade(BotName).ConfigureAwait(false); + return await ResponseSendTrade().ConfigureAwait(false); default: return "Unrecognized command: " + message; } @@ -871,9 +893,9 @@ internal async Task HandleMessage(string message) { return await ResponseRedeem(BotName, args[1], false).ConfigureAwait(false); } case "!start": - return ResponseStart(args[1]); + return await ResponseStart(args[1]).ConfigureAwait(false); case "!stop": - return await ResponseStop(args[1]).ConfigureAwait(false); + return ResponseStop(args[1]); case "!status": return ResponseStatus(args[1]); case "!loot": @@ -1184,7 +1206,7 @@ private async void OnLoggedOn(SteamUser.LoggedOnCallback callback) { break; default: // Unexpected result, shutdown immediately Logging.LogGenericWarning("Unable to login to Steam: " + result, BotName); - await Shutdown().ConfigureAwait(false); + Shutdown(); break; } } diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index 33d361d7efed2..751bf1638dfc9 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -149,8 +149,10 @@ internal static string GetUserInput(string botLogin, EUserInputType userInputTyp } internal static void OnBotShutdown() { - if (Bot.GetRunningBotsCount() > 0) { - return; + foreach (Bot bot in Bot.Bots.Values) { + if (bot.KeepRunning) { + return; + } } if (WCF.IsServerRunning()) {