Skip to content

Commit

Permalink
Reduce delay in determining booster marketability
Browse files Browse the repository at this point in the history
  • Loading branch information
Citrinate committed Mar 24, 2024
1 parent 4b9db73 commit d4bd335
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 4 deletions.
69 changes: 68 additions & 1 deletion BoosterManager/Data/MarketableApps.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Steam;
using ArchiSteamFarm.Web.Responses;
using BoosterManager.Localization;

namespace BoosterManager {
internal static class MarketableApps {
internal static HashSet<uint> AppIDs = new();

private static Uri Source = new("https://raw.githubusercontent.com/Citrinate/Steam-MarketableApps/main/data/marketable_apps.min.json");
private static TimeSpan UpdateFrequency = TimeSpan.FromMinutes(30);
private static TimeSpan SteamUpdateFrequency = TimeSpan.FromMinutes(5);

private static DateTime? LastUpdate;
private static DateTime? LastSteamUpdate;
private static SemaphoreSlim UpdateSemaphore = new SemaphoreSlim(1, 1);

internal static async Task<bool> Update() {
Expand All @@ -20,7 +27,9 @@ internal static async Task<bool> Update() {
await UpdateSemaphore.WaitAsync().ConfigureAwait(false);
try {
if (LastUpdate != null && (LastUpdate + UpdateFrequency) > DateTime.Now) {
// Data is still fresh
// Source data is still fresh, though it won't hurt to try to update from Steam
await UpdateFromSteam().ConfigureAwait(false);

return true;
}

Expand All @@ -38,10 +47,68 @@ internal static async Task<bool> Update() {
AppIDs = response.Content;
LastUpdate = DateTime.Now;

// We're good to stop here, but let's try to replace the cached data that may be up to 1 hour old with fresh data from Steam
await UpdateFromSteam().ConfigureAwait(false);

return true;
} finally {
UpdateSemaphore.Release();
}
}

private static async Task UpdateFromSteam() {
if (LastSteamUpdate != null && (LastSteamUpdate + SteamUpdateFrequency) > DateTime.Now) {
return;
}

if (AppIDs.Count == 0) {
// Without known good data, we can't tell if the data recieve from Steam is good or not
return;
}

Bot? bot = Bot.BotsReadOnly?.Values.FirstOrDefault(static bot => bot.IsConnectedAndLoggedOn);
if (bot == null) {
return;
}

MethodInfo? GetMarketableAppIDs = typeof(Bot).GetMethods(BindingFlags.NonPublic|BindingFlags.Public|BindingFlags.Instance).FirstOrDefault(x => x.Name == "GetMarketableAppIDs");
if (GetMarketableAppIDs == null) {
ASF.ArchiLogger.LogGenericError(Strings.PluginError);

return;
}

HashSet<uint>? newerAppIDs;
try {
var res = (Task<HashSet<uint>?>?) GetMarketableAppIDs.Invoke(bot, new object[]{});
if (res == null) {
ASF.ArchiLogger.LogNullError(res);

return;
}

await res.ConfigureAwait(false);
if (res.Result == null) {
ASF.ArchiLogger.LogNullError(res.Result);

return;
}

newerAppIDs = res.Result;
} catch (Exception e) {
ASF.ArchiLogger.LogGenericException(e);

return;
}

LastSteamUpdate = DateTime.Now;

if (AppIDs.Count - newerAppIDs.Count > 10000) {
// Bad data from Steam, ignore it
return;
}

AppIDs = newerAppIDs;
}
}
}
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,6 @@ Command | Alias |
"AllowCraftUnmarketableBoosters": false,
```

> [!NOTE]
> There can be a delay of up to 1 hour before the plugin is aware that the booster for a new game is marketable, or that the booster for a removed game is unmarketable.
---

### GamesToBooster
Expand Down

0 comments on commit d4bd335

Please sign in to comment.