diff --git a/ArchiSteamFarm/Steam/Bot.cs b/ArchiSteamFarm/Steam/Bot.cs index c50b7938497fa..a5f7c495b171f 100644 --- a/ArchiSteamFarm/Steam/Bot.cs +++ b/ArchiSteamFarm/Steam/Bot.cs @@ -3564,14 +3564,7 @@ private async void RedeemGamesInBackground(object? state = null) { (string? key, string? name) = BotDatabase.GetGameToRedeemInBackground(); if (string.IsNullOrEmpty(key)) { - ArchiLogger.LogNullError(key); - - break; - } - - if (string.IsNullOrEmpty(name)) { - ArchiLogger.LogNullError(name); - + // No more games to redeem left, possible due to e.g. queue purge break; } @@ -3639,6 +3632,8 @@ private async void RedeemGamesInBackground(object? state = null) { BotDatabase.RemoveGameToRedeemInBackground(key); // If user omitted the name or intentionally provided the same name as key, replace it with the Steam result + name ??= key; + if (name.Equals(key, StringComparison.OrdinalIgnoreCase) && (items?.Count > 0)) { name = string.Join(", ", items.Values); } diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index 9f0cfd245312b..02d16ee0ef5b8 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -127,6 +127,8 @@ public static EAccess GetProxyAccess(Bot bot, EAccess access, ulong steamID = 0) return ResponseWalletBalance(access); case "BGR": return ResponseBackgroundGamesRedeemer(access); + case "BGRCLEAR": + return ResponseBackgroundGamesRedeemerClear(access); case "EXIT": return ResponseExit(access); case "FARM": @@ -198,6 +200,8 @@ public static EAccess GetProxyAccess(Bot bot, EAccess access, ulong steamID = 0) return await ResponseWalletBalance(access, Utilities.GetArgsAsText(args, 1, ","), steamID).ConfigureAwait(false); case "BGR": return await ResponseBackgroundGamesRedeemer(access, Utilities.GetArgsAsText(args, 1, ","), steamID).ConfigureAwait(false); + case "BGRCLEAR": + return await ResponseBackgroundGamesRedeemerClear(access, Utilities.GetArgsAsText(args, 1, ","), steamID).ConfigureAwait(false); case "ENCRYPT" when args.Length > 2: return ResponseEncrypt(access, args[1], Utilities.GetArgsAsText(message, 2)); case "FARM": @@ -1148,6 +1152,40 @@ internal void OnNewLicenseList() { return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } + private string? ResponseBackgroundGamesRedeemerClear(EAccess access) { + if (!Enum.IsDefined(access)) { + throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(EAccess)); + } + + if (access < EAccess.Master) { + return null; + } + + Bot.BotDatabase.ClearGamesToRedeemInBackground(); + + return FormatBotResponse(Strings.Done); + } + + private static async Task ResponseBackgroundGamesRedeemerClear(EAccess access, string botNames, ulong steamID = 0) { + if (!Enum.IsDefined(access)) { + throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(EAccess)); + } + + ArgumentException.ThrowIfNullOrEmpty(botNames); + + HashSet? bots = Bot.GetBots(botNames); + + if ((bots == null) || (bots.Count == 0)) { + return access >= EAccess.Owner ? FormatStaticResponse(Strings.FormatBotNotFound(botNames)) : null; + } + + IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseBackgroundGamesRedeemerClear(GetProxyAccess(bot, access, steamID))))).ConfigureAwait(false); + + List responses = [..results.Where(static result => !string.IsNullOrEmpty(result))!]; + + return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; + } + private static string? ResponseEncrypt(EAccess access, string cryptoMethodText, string stringToEncrypt) { if (!Enum.IsDefined(access)) { throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(EAccess)); diff --git a/ArchiSteamFarm/Steam/Storage/BotDatabase.cs b/ArchiSteamFarm/Steam/Storage/BotDatabase.cs index 38559dc3de4a5..102ac265d2a96 100644 --- a/ArchiSteamFarm/Steam/Storage/BotDatabase.cs +++ b/ArchiSteamFarm/Steam/Storage/BotDatabase.cs @@ -256,6 +256,18 @@ internal void AddGamesToRedeemInBackground(IOrderedDictionary games) { Utilities.InBackground(Save); } + internal void ClearGamesToRedeemInBackground() { + lock (GamesToRedeemInBackground) { + if (GamesToRedeemInBackground.Count == 0) { + return; + } + + GamesToRedeemInBackground.Clear(); + } + + Utilities.InBackground(Save); + } + internal static async Task CreateOrLoad(string filePath) { ArgumentException.ThrowIfNullOrEmpty(filePath);