From a90573e0ea95ab89a632c8d180ddc92535f36106 Mon Sep 17 00:00:00 2001 From: JustArchi Date: Thu, 28 Jul 2016 21:20:57 +0200 Subject: [PATCH] Implement smart algorithm of avoiding OnCooldown I really like this approach, as it has only one caveat: memory usage. We need to keep in memory list of all packages that our account owns, which will result of N * 32bit extra memory usage, where N is equal to number of package licenses the account owns. This results in around 16 KB extra memory usage for my 4k account. However, apart from that there are no real caveats as checking if we own given packageID is O(1) operation, and I think that apart from this extra memory footprint there can be more benefits of having this field in future, besides, my 16 KB is extreme case, as usually nobody goes that high. Ship it! --- ArchiSteamFarm/Bot.cs | 20 +++++++++++++++++++- ArchiSteamFarm/ConcurrentHashSet.cs | 10 ++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index bb0589409..ea56f6ea2 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -64,6 +64,7 @@ namespace ArchiSteamFarm { private readonly CardsFarmer CardsFarmer; private readonly ConcurrentHashSet HandledGifts = new ConcurrentHashSet(); + private readonly ConcurrentHashSet OwnedPackageIDs = new ConcurrentHashSet(); private readonly SteamApps SteamApps; private readonly SteamFriends SteamFriends; private readonly SteamUser SteamUser; @@ -185,6 +186,7 @@ namespace ArchiSteamFarm { SteamApps = SteamClient.GetHandler(); CallbackManager.Subscribe(OnFreeLicense); CallbackManager.Subscribe(OnGuestPassList); + CallbackManager.Subscribe(OnLicenseList); SteamFriends = SteamClient.GetHandler(); CallbackManager.Subscribe(OnChatInvite); @@ -971,7 +973,8 @@ namespace ArchiSteamFarm { } bool alreadyHandled = false; - foreach (Bot bot in Bots.Values.Where(bot => (bot != this) && bot.SteamClient.IsConnected)) { + foreach (Bot bot in Bots.Values.Where(bot => (bot != this) && bot.SteamClient.IsConnected && result.Items.Keys.Any(packageID => !bot.OwnedPackageIDs.Contains(packageID)))) { + ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false); if (otherResult == null) { response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: Timeout!"); @@ -1619,6 +1622,21 @@ namespace ArchiSteamFarm { } } + private void OnLicenseList(SteamApps.LicenseListCallback callback) { + if (callback?.LicenseList == null) { + Logging.LogNullError(nameof(callback) + " || " + nameof(callback.LicenseList), BotName); + return; + } + + OwnedPackageIDs.Clear(); + + foreach (SteamApps.LicenseListCallback.License license in callback.LicenseList) { + OwnedPackageIDs.Add(license.PackageID); + } + + OwnedPackageIDs.TrimExcess(); + } + private void OnChatInvite(SteamFriends.ChatInviteCallback callback) { if ((callback?.ChatRoomID == null) || (callback.PatronID == null)) { Logging.LogNullError(nameof(callback) + " || " + nameof(callback.ChatRoomID) + " || " + nameof(callback.PatronID), BotName); diff --git a/ArchiSteamFarm/ConcurrentHashSet.cs b/ArchiSteamFarm/ConcurrentHashSet.cs index a8b246824..a35071a12 100644 --- a/ArchiSteamFarm/ConcurrentHashSet.cs +++ b/ArchiSteamFarm/ConcurrentHashSet.cs @@ -100,6 +100,16 @@ namespace ArchiSteamFarm { } } + public void TrimExcess() { + Lock.EnterWriteLock(); + + try { + HashSet.TrimExcess(); + } finally { + Lock.ExitWriteLock(); + } + } + public void Dispose() => Lock.Dispose(); public void CopyTo(T[] array, int arrayIndex) {