From 9691e2a37bfe868f72084ad8327c025f2f591fd9 Mon Sep 17 00:00:00 2001 From: JustArchi Date: Sat, 17 Feb 2018 20:42:47 +0100 Subject: [PATCH] Improve FileSystemWatcher --- ArchiSteamFarm/ASF.cs | 89 +++++---------------------------------- ArchiSteamFarm/Bot.cs | 72 ++++++++++++++++--------------- ArchiSteamFarm/Events.cs | 9 +++- ArchiSteamFarm/Program.cs | 2 +- 4 files changed, 57 insertions(+), 115 deletions(-) diff --git a/ArchiSteamFarm/ASF.cs b/ArchiSteamFarm/ASF.cs index 948ef5987..4cb21e40a 100644 --- a/ArchiSteamFarm/ASF.cs +++ b/ArchiSteamFarm/ASF.cs @@ -212,26 +212,6 @@ namespace ArchiSteamFarm { FileSystemWatcher.EnableRaisingEvents = true; } - private static async Task CreateBot(string botName) { - if (string.IsNullOrEmpty(botName)) { - ArchiLogger.LogNullError(nameof(botName)); - return; - } - - if (Bot.Bots.ContainsKey(botName)) { - return; - } - - // It's entirely possible that some process is still accessing our file, allow at least a second before trying to read it - await Task.Delay(1000).ConfigureAwait(false); - - if (Bot.Bots.ContainsKey(botName)) { - return; - } - - await Bot.RegisterBot(botName).ConfigureAwait(false); - } - private static bool IsUnixVariant(string variant) { if (string.IsNullOrEmpty(variant)) { ArchiLogger.LogNullError(nameof(variant)); @@ -274,7 +254,6 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericDebug(e.Name + " | " + e.FullPath); await OnChangedFile(e.Name, e.FullPath).ConfigureAwait(false); } @@ -284,52 +263,7 @@ namespace ArchiSteamFarm { return; } - string botName = Path.GetFileNameWithoutExtension(name); - if (string.IsNullOrEmpty(botName) || (botName[0] == '.')) { - return; - } - - DateTime lastWriteTime = DateTime.UtcNow; - - if (LastWriteTimes.TryGetValue(botName, out DateTime savedLastWriteTime)) { - if (savedLastWriteTime >= lastWriteTime) { - return; - } - } - - LastWriteTimes[botName] = lastWriteTime; - - // It's entirely possible that some process is still accessing our file, allow at least a second before trying to read it - await Task.Delay(1000).ConfigureAwait(false); - - // It's also possible that we got some other event in the meantime - if (LastWriteTimes.TryGetValue(botName, out savedLastWriteTime)) { - if (lastWriteTime != savedLastWriteTime) { - return; - } - - if (LastWriteTimes.TryRemove(botName, out savedLastWriteTime)) { - if (lastWriteTime != savedLastWriteTime) { - return; - } - } - } - - if (botName.Equals(SharedInfo.ASF)) { - ArchiLogger.LogGenericInfo(Strings.GlobalConfigChanged); - await RestartOrExit().ConfigureAwait(false); - return; - } - - if (!Bot.Bots.TryGetValue(botName, out Bot bot)) { - if (IsValidBotName(botName)) { - await CreateBot(botName).ConfigureAwait(false); - } - - return; - } - - await bot.OnNewConfigLoaded(new BotConfigEventArgs(BotConfig.Load(fullPath))).ConfigureAwait(false); + await OnCreatedConfigFile(name, fullPath).ConfigureAwait(false); } private static async Task OnChangedFile(string name, string fullPath) { @@ -360,7 +294,6 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericDebug(e.Name + " | " + e.FullPath); await OnCreatedFile(e.Name, e.FullPath).ConfigureAwait(false); } @@ -411,7 +344,11 @@ namespace ArchiSteamFarm { return; } - await CreateBot(botName).ConfigureAwait(false); + if (Bot.Bots.TryGetValue(botName, out Bot bot)) { + await bot.OnConfigChanged(false).ConfigureAwait(false); + } else { + await Bot.RegisterBot(botName).ConfigureAwait(false); + } } private static async Task OnCreatedFile(string name, string fullPath) { @@ -482,7 +419,6 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericDebug(e.Name + " | " + e.FullPath); await OnDeletedFile(e.Name, e.FullPath).ConfigureAwait(false); } @@ -540,8 +476,12 @@ namespace ArchiSteamFarm { return; } + if (!IsValidBotName(botName)) { + return; + } + if (Bot.Bots.TryGetValue(botName, out Bot bot)) { - await bot.OnNewConfigLoaded(new BotConfigEventArgs()).ConfigureAwait(false); + await bot.OnConfigChanged(true).ConfigureAwait(false); } } @@ -566,7 +506,6 @@ namespace ArchiSteamFarm { return; } - ArchiLogger.LogGenericDebug(e.OldName + " | " + e.OldFullPath + " | " + e.Name + " | " + e.FullPath); await OnDeletedFile(e.OldName, e.OldFullPath).ConfigureAwait(false); await OnCreatedFile(e.Name, e.FullPath).ConfigureAwait(false); } @@ -647,12 +586,6 @@ namespace ArchiSteamFarm { } } - internal sealed class BotConfigEventArgs : EventArgs { - internal readonly BotConfig BotConfig; - - internal BotConfigEventArgs(BotConfig botConfig = null) => BotConfig = botConfig; - } - internal enum EUserInputType : byte { Unknown, DeviceID, diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 66f461514..5d977d1e0 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -791,6 +791,40 @@ namespace ArchiSteamFarm { await ResponseLoot(steamMasterID).ConfigureAwait(false); } + internal async Task OnConfigChanged(bool deleted) { + if (deleted) { + Destroy(); + return; + } + + BotConfig botConfig = BotConfig.Load(ConfigFilePath); + + if (botConfig == null) { + Destroy(); + return; + } + + if (botConfig == BotConfig) { + return; + } + + await InitializationSemaphore.WaitAsync().ConfigureAwait(false); + + try { + if (botConfig == BotConfig) { + return; + } + + Stop(botConfig.Enabled); + BotConfig = botConfig; + + InitModules(); + InitStart(); + } finally { + InitializationSemaphore.Release(); + } + } + internal async Task OnFarmingFinished(bool farmedSomething) { await OnFarmingStopped().ConfigureAwait(false); @@ -815,38 +849,6 @@ namespace ArchiSteamFarm { internal async Task OnFarmingStopped() => await ResetGamesPlayed().ConfigureAwait(false); - internal async Task OnNewConfigLoaded(ASF.BotConfigEventArgs args) { - if (args == null) { - ArchiLogger.LogNullError(nameof(args)); - return; - } - - if (args.BotConfig == null) { - Destroy(); - return; - } - - if (args.BotConfig == BotConfig) { - return; - } - - await InitializationSemaphore.WaitAsync().ConfigureAwait(false); - - try { - if (args.BotConfig == BotConfig) { - return; - } - - Stop(false); - BotConfig = args.BotConfig; - - InitModules(); - InitStart(); - } finally { - InitializationSemaphore.Release(); - } - } - internal async Task RefreshSession() { if (!IsConnectedAndLoggedOn) { return false; @@ -1161,7 +1163,7 @@ namespace ArchiSteamFarm { } } - internal void Stop(bool withShutdownEvent = true) { + internal void Stop(bool skipShutdownEvent = false) { if (!KeepRunning) { return; } @@ -1173,8 +1175,8 @@ namespace ArchiSteamFarm { Disconnect(); } - if (withShutdownEvent) { - Events.OnBotShutdown(); + if (!skipShutdownEvent) { + Events.OnBotShutdown().Forget(); } } diff --git a/ArchiSteamFarm/Events.cs b/ArchiSteamFarm/Events.cs index ccb0b969d..f430a440f 100644 --- a/ArchiSteamFarm/Events.cs +++ b/ArchiSteamFarm/Events.cs @@ -25,13 +25,20 @@ using ArchiSteamFarm.Localization; namespace ArchiSteamFarm { internal static class Events { - internal static async void OnBotShutdown() { + internal static async Task OnBotShutdown() { if (Program.ServiceMode || IPC.IsRunning || Bot.Bots.Values.Any(bot => bot.KeepRunning)) { return; } ASF.ArchiLogger.LogGenericInfo(Strings.NoBotsAreRunning); + + // We give user extra 5 seconds for eventual config changes await Task.Delay(5000).ConfigureAwait(false); + + if (Program.ServiceMode || IPC.IsRunning || Bot.Bots.Values.Any(bot => bot.KeepRunning)) { + return; + } + await Program.Exit().ConfigureAwait(false); } } diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index 8d759ddf8..723691acd 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -359,7 +359,7 @@ namespace ArchiSteamFarm { } if (Bot.Bots.Count > 0) { - IEnumerable tasks = Bot.Bots.Values.Select(bot => Task.Run(() => bot.Stop(false))); + IEnumerable tasks = Bot.Bots.Values.Select(bot => Task.Run(() => bot.Stop(true))); switch (GlobalConfig.OptimizationMode) { case GlobalConfig.EOptimizationMode.MinMemoryUsage: