From 645d7f7da11a6728ad441f48b6edab5a25e96cdd Mon Sep 17 00:00:00 2001 From: Citrinate Date: Thu, 30 May 2024 17:38:27 -0400 Subject: [PATCH] Prevent double crafts if ASF was stopped while crafting --- BoosterManager/Boosters/Booster.cs | 5 ++- BoosterManager/Boosters/BoosterDatabase.cs | 20 +++++++++++ BoosterManager/Boosters/BoosterJob.cs | 2 ++ BoosterManager/Handlers/BoosterHandler.cs | 40 ++++++++++++++++++++-- 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/BoosterManager/Boosters/Booster.cs b/BoosterManager/Boosters/Booster.cs index be11198..993a204 100644 --- a/BoosterManager/Boosters/Booster.cs +++ b/BoosterManager/Boosters/Booster.cs @@ -13,7 +13,7 @@ internal sealed class Booster { internal readonly Steam.BoosterInfo Info; private readonly DateTime InitTime; private readonly BoosterLastCraft? LastCraft; - internal bool WasCrafted = false; + internal bool WasCrafted { get; private set; } = false; internal Booster(Bot bot, uint gameID, Steam.BoosterInfo info, BoosterJob boosterJob) { Bot = bot; @@ -25,6 +25,8 @@ internal Booster(Bot bot, uint gameID, Steam.BoosterInfo info, BoosterJob booste } internal async Task Craft(Steam.TradabilityPreference nTp) { + await BoosterDatabase.PreCraft(this).ConfigureAwait(false); + Steam.BoostersResponse? result = await WebRequest.CreateBooster(Bot, Info.AppID, Info.Series, nTp).ConfigureAwait(false); if (result?.Result?.Result == EResult.OK) { @@ -35,6 +37,7 @@ internal Booster(Bot bot, uint gameID, Steam.BoosterInfo info, BoosterJob booste } internal void SetWasCrafted() { + BoosterDatabase.PostCraft(); BoosterDatabase.SetLastCraft(GameID, DateTime.Now); WasCrafted = true; } diff --git a/BoosterManager/Boosters/BoosterDatabase.cs b/BoosterManager/Boosters/BoosterDatabase.cs index e04a796..bf26344 100644 --- a/BoosterManager/Boosters/BoosterDatabase.cs +++ b/BoosterManager/Boosters/BoosterDatabase.cs @@ -16,6 +16,12 @@ internal sealed class BoosterDatabase : SerializableFile { [JsonInclude] internal List BoosterJobs { get; private set; } = new(); + [JsonInclude] + internal uint? CraftingGameID { get; private set; } = null; + + [JsonInclude] + internal DateTime? CraftingTime { get; private set; } = null; + [JsonConstructor] private BoosterDatabase() { } @@ -99,5 +105,19 @@ internal void UpdateBoosterJobs(List boosterJobs) { Utilities.InBackground(Save); } + + internal async Task PreCraft(Booster booster) { + CraftingGameID = booster.GameID; + CraftingTime = booster.Info.AvailableAtTime; + + await Save().ConfigureAwait(false); + } + + internal void PostCraft() { + CraftingGameID = null; + CraftingTime = null; + + Utilities.InBackground(Save); + } } } diff --git a/BoosterManager/Boosters/BoosterJob.cs b/BoosterManager/Boosters/BoosterJob.cs index 9d91bf0..f2b15d2 100644 --- a/BoosterManager/Boosters/BoosterJob.cs +++ b/BoosterManager/Boosters/BoosterJob.cs @@ -307,6 +307,8 @@ internal int RemoveBoosters(uint gameID) { } if (numRemoved > 0) { + SaveJobState(); + for (int i = 0; i < numRemoved; i++) { Bot.ArchiLogger.LogGenericInfo(String.Format(Strings.BoosterUnqueuedByUser, gameID)); } diff --git a/BoosterManager/Handlers/BoosterHandler.cs b/BoosterManager/Handlers/BoosterHandler.cs index 7c0f10d..4171964 100644 --- a/BoosterManager/Handlers/BoosterHandler.cs +++ b/BoosterManager/Handlers/BoosterHandler.cs @@ -209,8 +209,44 @@ private void CancelBoosterJobs() { } private void RestoreBoosterJobs() { - foreach (BoosterJobState jobState in BoosterDatabase.BoosterJobs) { - Jobs.Add(new BoosterJob(Bot, BoosterJobType.Limited, jobState)); + uint? craftingGameID = BoosterDatabase.CraftingGameID; + DateTime? craftingTime = BoosterDatabase.CraftingTime; + if (craftingGameID != null && craftingTime != null) { + // We were in the middle of crafting a booster when ASF was reset, check to see if that booster was crafted or not + void handler(Dictionary boosterInfos) { + try { + if (!boosterInfos.TryGetValue(craftingGameID.Value, out Steam.BoosterInfo? newBoosterInfo)) { + // No longer have access to craft boosters for this game (game removed from account, or sometimes due to very rare Steam bugs) + + return; + } + + if (newBoosterInfo.Unavailable && newBoosterInfo.AvailableAtTime != null + && newBoosterInfo.AvailableAtTime != craftingTime.Value + && (newBoosterInfo.AvailableAtTime.Value - craftingTime.Value).TotalHours > 2 // Make sure the change in time isn't due to daylight savings + ) { + // Booster was crafted + Bot.ArchiLogger.LogGenericInfo(String.Format(Strings.BoosterUnexpectedlyCrafted, craftingGameID.Value)); + + // Remove 1 of this booster from our jobs + BoosterDatabase.BoosterJobs.Any(jobState => jobState.GameIDs.Remove(craftingGameID.Value)); + BoosterDatabase.PostCraft(); + + foreach (BoosterJobState jobState in BoosterDatabase.BoosterJobs) { + Jobs.Add(new BoosterJob(Bot, BoosterJobType.Limited, jobState)); + } + } + } finally { + BoosterQueue.OnBoosterInfosUpdated -= handler; + } + } + + BoosterQueue.OnBoosterInfosUpdated += handler; + BoosterQueue.Start(); + } else { + foreach (BoosterJobState jobState in BoosterDatabase.BoosterJobs) { + Jobs.Add(new BoosterJob(Bot, BoosterJobType.Limited, jobState)); + } } }