diff --git a/ArchiSteamFarm/ArchiWebHandler.cs b/ArchiSteamFarm/ArchiWebHandler.cs index 50b43d7251d40..46c3db53cbc56 100644 --- a/ArchiSteamFarm/ArchiWebHandler.cs +++ b/ArchiSteamFarm/ArchiWebHandler.cs @@ -181,7 +181,7 @@ internal async Task ReconnectIfNeeded() { bool? isLoggedIn = await IsLoggedIn().ConfigureAwait(false); if (isLoggedIn.HasValue && !isLoggedIn.Value) { Logging.LogGenericInfo(Bot.BotName, "Reconnecting because our sessionID expired!"); - Bot.SteamClient.Disconnect(); // Bot will handle reconnect + await Bot.Restart().ConfigureAwait(false); return true; } diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 671715c9e6701..1ccfc13f84333 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -55,7 +55,6 @@ internal sealed class Bot { internal readonly Trading Trading; private bool LoggedInElsewhere = false; - private bool IsRunning = false; private string AuthCode, LoginKey, TwoFactorAuth; internal SteamGuardAccount SteamGuardAccount { get; private set; } @@ -166,7 +165,8 @@ internal Bot(string botName) { Trading = new Trading(this); // Start - var fireAndForget = Task.Run(async () => await Start().ConfigureAwait(false)); + var handleCallbacks = Task.Run(() => HandleCallbacks()); + var start = Task.Run(async () => await Start().ConfigureAwait(false)); } internal async Task AcceptAllConfirmations() { @@ -343,8 +343,13 @@ private bool ReadConfig() { return true; } + internal async Task Restart() { + await Stop().ConfigureAwait(false); + await Start().ConfigureAwait(false); + } + internal async Task Start() { - if (IsRunning) { + if (SteamClient.IsConnected) { return; } @@ -355,18 +360,18 @@ internal async Task Start() { await Program.LimitSteamRequestsAsync().ConfigureAwait(false); } - IsRunning = true; SteamClient.Connect(); - var fireAndForget = Task.Run(() => HandleCallbacks()); } internal async Task Stop() { - if (!IsRunning) { + if (!SteamClient.IsConnected) { return; } - await CardsFarmer.StopFarming().ConfigureAwait(false); - IsRunning = false; + await Utilities.SleepAsync(0); // TODO: This is here only to make VS happy, for now + + Logging.LogGenericInfo(BotName, "Stopping..."); + SteamClient.Disconnect(); } @@ -396,7 +401,7 @@ internal async Task OnFarmingFinished() { private void HandleCallbacks() { TimeSpan timeSpan = TimeSpan.FromMilliseconds(CallbackSleep); - while (IsRunning) { + while (true) { CallbackManager.RunWaitCallbacks(timeSpan); } } @@ -545,11 +550,6 @@ private async Task HandleMessage(ulong steamID, string message) { case "!exit": await ShutdownAllBots().ConfigureAwait(false); break; - case "!farm": - SendMessage(steamID, "Please wait..."); - await CardsFarmer.StartFarming().ConfigureAwait(false); - SendMessage(steamID, "Done!"); - break; case "!restart": await Program.Restart().ConfigureAwait(false); break; @@ -585,10 +585,6 @@ private async Task HandleMessage(ulong steamID, string message) { } } - - - - private void OnConnected(SteamClient.ConnectedCallback callback) { if (callback == null) { return; @@ -636,20 +632,22 @@ private async void OnDisconnected(SteamClient.DisconnectedCallback callback) { return; } - if (!IsRunning) { + Logging.LogGenericInfo(BotName, "Disconnected from Steam!"); + await CardsFarmer.StopFarming().ConfigureAwait(false); + + // If we initiated disconnect, do not attempt to reconnect + if (callback.UserInitiated) { return; } - Logging.LogGenericInfo(BotName, "Disconnected from Steam, reconnecting..."); - - await CardsFarmer.StopFarming().ConfigureAwait(false); - if (LoggedInElsewhere) { LoggedInElsewhere = false; - Logging.LogGenericWarning(BotName, "Account is being used elsewhere, will try reconnecting in 5 minutes..."); - await Utilities.SleepAsync(5 * 60 * 1000).ConfigureAwait(false); + Logging.LogGenericWarning(BotName, "Account is being used elsewhere, will try reconnecting in 30 minutes..."); + await Utilities.SleepAsync(30 * 60 * 1000).ConfigureAwait(false); } + Logging.LogGenericInfo(BotName, "Reconnecting..."); + // 2FA tokens are expiring soon, use limiter only when we don't have any pending if (TwoFactorAuth == null) { await Program.LimitSteamRequestsAsync().ConfigureAwait(false); @@ -865,8 +863,7 @@ private async void OnLoggedOn(SteamUser.LoggedOnCallback callback) { case EResult.Timeout: case EResult.TryAnotherCM: Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + result + ", retrying..."); - await Stop().ConfigureAwait(false); - await Start().ConfigureAwait(false); + await Restart().ConfigureAwait(false); break; default: Logging.LogGenericWarning(BotName, "Unable to login to Steam: " + result); diff --git a/ArchiSteamFarm/CardsFarmer.cs b/ArchiSteamFarm/CardsFarmer.cs index 7cd5b07f01d10..5a9227b65141b 100755 --- a/ArchiSteamFarm/CardsFarmer.cs +++ b/ArchiSteamFarm/CardsFarmer.cs @@ -45,7 +45,7 @@ internal sealed class CardsFarmer { internal readonly ConcurrentDictionary GamesToFarm = new ConcurrentDictionary(); internal readonly List CurrentGamesFarming = new List(); - private volatile bool NowFarming = false; + private bool NowFarming = false; internal CardsFarmer(Bot bot) { Bot = bot; @@ -105,10 +105,10 @@ internal bool FarmMultiple() { Logging.LogGenericInfo(Bot.BotName, "Now farming: " + string.Join(", ", GamesToFarm.Keys)); if (Farm(maxHour, GamesToFarm.Keys)) { + CurrentGamesFarming.Clear(); return true; } else { CurrentGamesFarming.Clear(); - NowFarming = false; return false; } } @@ -128,13 +128,11 @@ internal async Task FarmSolo(uint appID) { return true; } else { CurrentGamesFarming.Clear(); - NowFarming = false; return false; } } internal async Task StartFarming() { - await StopFarming().ConfigureAwait(false); await Semaphore.WaitAsync().ConfigureAwait(false); if (NowFarming) { @@ -142,26 +140,6 @@ internal async Task StartFarming() { return; } - // Check if farming is possible - Logging.LogGenericInfo(Bot.BotName, "Checking possibility to farm..."); - - NowFarming = true; - Semaphore.Release(); - - /* - Bot.ArchiHandler.PlayGames(1337); - - // We'll now either receive OnLoggedOff() with LoggedInElsewhere, or nothing happens - if (await Task.Run(() => FarmResetEvent.WaitOne(5000)).ConfigureAwait(false)) { // If LoggedInElsewhere happens in 5 seconds from now, abort farming - NowFarming = false; - return; - } - */ - - Logging.LogGenericInfo(Bot.BotName, "Farming is possible!"); - - await Semaphore.WaitAsync().ConfigureAwait(false); - if (await Bot.ArchiWebHandler.ReconnectIfNeeded().ConfigureAwait(false)) { Semaphore.Release(); return; @@ -172,7 +150,7 @@ internal async Task StartFarming() { // Find the number of badge pages HtmlDocument badgesDocument = await Bot.ArchiWebHandler.GetBadgePage(1).ConfigureAwait(false); if (badgesDocument == null) { - Logging.LogGenericWarning(Bot.BotName, "Could not get badges information, farming is stopped!"); + Logging.LogGenericWarning(Bot.BotName, "Could not get badges information, will try again later!"); Semaphore.Release(); return; } @@ -254,8 +232,13 @@ internal async Task StartFarming() { Logging.LogGenericInfo(Bot.BotName, "Farming in progress..."); - NowFarming = GamesToFarm.Count > 0; - Semaphore.Release(); + if (GamesToFarm.Count == 0) { + Semaphore.Release(); + return; + } + + NowFarming = true; + Semaphore.Release(); // From this point we allow other calls to shut us down // Now the algorithm used for farming depends on whether account is restricted or not if (Bot.CardDropsRestricted) { @@ -271,6 +254,7 @@ internal async Task StartFarming() { Logging.LogGenericInfo(Bot.BotName, "Done farming: " + appID); gamesToFarmSolo.Remove(appID); } else { + NowFarming = false; return; } } @@ -279,6 +263,7 @@ internal async Task StartFarming() { if (success) { Logging.LogGenericInfo(Bot.BotName, "Done farming: " + string.Join(", ", GamesToFarm.Keys)); } else { + NowFarming = false; return; } } @@ -292,6 +277,7 @@ internal async Task StartFarming() { if (success) { Logging.LogGenericInfo(Bot.BotName, "Done farming: " + appID); } else { + NowFarming = false; return; } } @@ -305,6 +291,7 @@ internal async Task StartFarming() { internal async Task StopFarming() { await Semaphore.WaitAsync().ConfigureAwait(false); + if (!NowFarming) { Semaphore.Release(); return;