Skip to content

Commit

Permalink
Prevent double crafts if ASF was stopped while crafting
Browse files Browse the repository at this point in the history
  • Loading branch information
Citrinate committed May 30, 2024
1 parent 5cb96f5 commit 645d7f7
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
5 changes: 4 additions & 1 deletion BoosterManager/Boosters/Booster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -25,6 +25,8 @@ internal Booster(Bot bot, uint gameID, Steam.BoosterInfo info, BoosterJob booste
}

internal async Task<Steam.BoostersResponse?> 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) {
Expand All @@ -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;
}
Expand Down
20 changes: 20 additions & 0 deletions BoosterManager/Boosters/BoosterDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ internal sealed class BoosterDatabase : SerializableFile {
[JsonInclude]
internal List<BoosterJobState> BoosterJobs { get; private set; } = new();

[JsonInclude]
internal uint? CraftingGameID { get; private set; } = null;

[JsonInclude]
internal DateTime? CraftingTime { get; private set; } = null;

[JsonConstructor]
private BoosterDatabase() { }

Expand Down Expand Up @@ -99,5 +105,19 @@ internal void UpdateBoosterJobs(List<BoosterJobState> 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);
}
}
}
2 changes: 2 additions & 0 deletions BoosterManager/Boosters/BoosterJob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
40 changes: 38 additions & 2 deletions BoosterManager/Handlers/BoosterHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint, Steam.BoosterInfo> 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));
}
}
}

Expand Down

0 comments on commit 645d7f7

Please sign in to comment.