From 2478dd6c10e45adc0d9cbd7df4116697a15e870b Mon Sep 17 00:00:00 2001 From: ArchiBot Date: Fri, 27 Sep 2024 02:20:15 +0000 Subject: [PATCH 01/23] Automatic translations update --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 7d6723153936d..15ec805ef1ede 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 7d6723153936ded85980765045984b08dd9bb1a8 +Subproject commit 15ec805ef1ede5740afc3eb0e2bf620c50c65bab From 246429f7a13f2dc840d503fa01e590455c0ebdbb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 12:36:42 +0000 Subject: [PATCH 02/23] chore(deps): update docker/build-push-action action to v6.8.0 --- .github/workflows/docker-ci.yml | 2 +- .github/workflows/docker-publish-latest.yml | 2 +- .github/workflows/docker-publish-main.yml | 2 +- .github/workflows/docker-publish-released.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-ci.yml b/.github/workflows/docker-ci.yml index 65cbe68c85334..a53ea7c42d4a7 100644 --- a/.github/workflows/docker-ci.yml +++ b/.github/workflows/docker-ci.yml @@ -28,7 +28,7 @@ jobs: uses: docker/setup-buildx-action@v3.6.1 - name: Build ${{ matrix.configuration }} Docker image from ${{ matrix.file }} - uses: docker/build-push-action@v6.7.0 + uses: docker/build-push-action@v6.8.0 with: build-args: CONFIGURATION=${{ matrix.configuration }} context: . diff --git a/.github/workflows/docker-publish-latest.yml b/.github/workflows/docker-publish-latest.yml index f884aaa679b58..6940b802dea7e 100644 --- a/.github/workflows/docker-publish-latest.yml +++ b/.github/workflows/docker-publish-latest.yml @@ -50,7 +50,7 @@ jobs: echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV" - name: Build and publish Docker image from Dockerfile.Service - uses: docker/build-push-action@v6.7.0 + uses: docker/build-push-action@v6.8.0 with: context: . file: Dockerfile.Service diff --git a/.github/workflows/docker-publish-main.yml b/.github/workflows/docker-publish-main.yml index 9cabed31c896c..2cb2aa045bcc8 100644 --- a/.github/workflows/docker-publish-main.yml +++ b/.github/workflows/docker-publish-main.yml @@ -50,7 +50,7 @@ jobs: echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV" - name: Build and publish Docker image from Dockerfile - uses: docker/build-push-action@v6.7.0 + uses: docker/build-push-action@v6.8.0 with: context: . platforms: ${{ env.PLATFORMS }} diff --git a/.github/workflows/docker-publish-released.yml b/.github/workflows/docker-publish-released.yml index dd424c06dd817..331f05d82c29a 100644 --- a/.github/workflows/docker-publish-released.yml +++ b/.github/workflows/docker-publish-released.yml @@ -51,7 +51,7 @@ jobs: echo "DH_REPOSITORY=$(echo ${{ secrets.DOCKERHUB_USERNAME }}/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_ENV" - name: Build and publish Docker image from Dockerfile - uses: docker/build-push-action@v6.7.0 + uses: docker/build-push-action@v6.8.0 with: context: . platforms: ${{ env.PLATFORMS }} From 088161e9ba7ac8969b546de1cc7de2b393e345ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Fri, 27 Sep 2024 23:23:55 +0200 Subject: [PATCH 03/23] Experimental update channel rebrand --- .github/RELEASE_TEMPLATE.md | 2 +- ArchiSteamFarm/Steam/Interaction/Commands.cs | 6 ++++++ ArchiSteamFarm/Storage/GlobalConfig.cs | 5 ++++- README.md | 6 +++--- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/RELEASE_TEMPLATE.md b/.github/RELEASE_TEMPLATE.md index e6e9ac42561d2..65d37e6dace50 100644 --- a/.github/RELEASE_TEMPLATE.md +++ b/.github/RELEASE_TEMPLATE.md @@ -1,6 +1,6 @@ ### Notice -**Pre-releases are experimental versions that often contain unpatched bugs, work-in-progress features and rewritten implementations. If you don't consider yourself advanced user, please download **[latest stable release](https://github.com/JustArchiNET/ArchiSteamFarm/releases/latest)** instead. Pre-release versions are dedicated to users who know how to report bugs, deal with issues and give feedback - no technical support will be given. Check out ASF **[release cycle](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Release-cycle)** if you'd like to learn more.** +**Pre-releases are test versions that often contain unpatched bugs, work-in-progress features and rewritten implementations. If you don't consider yourself advanced user, please download **[latest stable release](https://github.com/JustArchiNET/ArchiSteamFarm/releases/latest)** instead. Pre-release versions are dedicated to users who know how to report bugs, deal with issues and give feedback - no technical support will be given. Check out ASF **[release cycle](https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Release-cycle)** if you'd like to learn more.** --- diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index 37c14b7ac4e8f..9f0cfd245312b 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -3355,6 +3355,12 @@ internal void OnNewLicenseList() { if (!Enum.TryParse(channelText, true, out channel) || (channel == GlobalConfig.EUpdateChannel.None)) { return FormatStaticResponse(Strings.FormatErrorIsInvalid(nameof(channelText))); } + +#pragma warning disable CS0618 // TODO: Remove me in the future + if (channelText.Contains(nameof(GlobalConfig.EUpdateChannel.Experimental), StringComparison.OrdinalIgnoreCase)) { + return FormatStaticResponse(Strings.FormatWarningFailedWithError(Strings.FormatWarningDeprecated(nameof(GlobalConfig.EUpdateChannel.Experimental), nameof(GlobalConfig.EUpdateChannel.PreRelease)))); + } +#pragma warning restore CS0618 // TODO: Remove me in the future } (bool success, string? message, Version? version) = await Actions.Update(channel, forced).ConfigureAwait(false); diff --git a/ArchiSteamFarm/Storage/GlobalConfig.cs b/ArchiSteamFarm/Storage/GlobalConfig.cs index c38795d8c46d5..a3911a516368c 100644 --- a/ArchiSteamFarm/Storage/GlobalConfig.cs +++ b/ArchiSteamFarm/Storage/GlobalConfig.cs @@ -619,6 +619,9 @@ public enum EPluginsUpdateMode : byte { public enum EUpdateChannel : byte { None, Stable, - Experimental + PreRelease, + + [Obsolete($"Use {nameof(PreRelease)} instead, this alias will be removed in the future version")] + Experimental = PreRelease } } diff --git a/README.md b/README.md index 25080bf4a4a98..78ae97a74c99c 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,9 @@ [![GitHub stable release date](https://img.shields.io/github/release-date/JustArchiNET/ArchiSteamFarm.svg?label=Released&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases/latest) [![Github stable release downloads](https://img.shields.io/github/downloads/JustArchiNET/ArchiSteamFarm/latest/total.svg?label=Downloads&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases/latest) -[![GitHub experimental release version](https://img.shields.io/github/v/release/JustArchiNET/ArchiSteamFarm?include_prereleases&label=Experimental&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases) -[![GitHub experimental release date](https://img.shields.io/github/release-date-pre/JustArchiNET/ArchiSteamFarm.svg?label=Released&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases) -[![Github experimental release downloads](https://img.shields.io/github/downloads-pre/JustArchiNET/ArchiSteamFarm/latest/total.svg?label=Downloads&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases) +[![GitHub pre-release version](https://img.shields.io/github/v/release/JustArchiNET/ArchiSteamFarm?include_prereleases&label=Pre-release&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases) +[![GitHub pre-release date](https://img.shields.io/github/release-date-pre/JustArchiNET/ArchiSteamFarm.svg?label=Released&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases) +[![Github pre-release downloads](https://img.shields.io/github/downloads-pre/JustArchiNET/ArchiSteamFarm/latest/total.svg?label=Downloads&logo=github&cacheSeconds=600)](https://github.com/JustArchiNET/ArchiSteamFarm/releases) [![GitHub sponsor](https://img.shields.io/badge/GitHub-sponsor-ea4aaa.svg?logo=github-sponsors)](https://github.com/sponsors/JustArchi) [![PayPal.me donate](https://img.shields.io/badge/PayPal.me-donate-00457c.svg?logo=paypal)](https://paypal.me/JustArchi) From 1fc4ac8e073845055ab20621e65b4fe027094a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Fri, 27 Sep 2024 23:31:01 +0200 Subject: [PATCH 04/23] Update GlobalConfig.cs --- ArchiSteamFarm/Storage/GlobalConfig.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ArchiSteamFarm/Storage/GlobalConfig.cs b/ArchiSteamFarm/Storage/GlobalConfig.cs index a3911a516368c..c9018f96ee272 100644 --- a/ArchiSteamFarm/Storage/GlobalConfig.cs +++ b/ArchiSteamFarm/Storage/GlobalConfig.cs @@ -615,6 +615,7 @@ public enum EPluginsUpdateMode : byte { Blacklist } +#pragma warning disable CA1027 // TODO: Remove me after Experimental alias disappears [PublicAPI] public enum EUpdateChannel : byte { None, @@ -624,4 +625,5 @@ public enum EUpdateChannel : byte { [Obsolete($"Use {nameof(PreRelease)} instead, this alias will be removed in the future version")] Experimental = PreRelease } +#pragma warning restore CA1027 // TODO: Remove me after Experimental alias disappears } From 0c21c223be615717c5756381bcc8a4540f49a419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Sat, 28 Sep 2024 00:03:15 +0200 Subject: [PATCH 05/23] Closes #3294 --- ArchiSteamFarm/Steam/Bot.cs | 11 ++---- ArchiSteamFarm/Steam/Interaction/Commands.cs | 38 ++++++++++++++++++++ ArchiSteamFarm/Steam/Storage/BotDatabase.cs | 12 +++++++ 3 files changed, 53 insertions(+), 8 deletions(-) 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); From 9f4d5df8d2b3434c160a7b0381c15364790a5205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Sat, 28 Sep 2024 00:18:33 +0200 Subject: [PATCH 06/23] Bump --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 5a7f180e445e0..2b2148484e3cf 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 6.0.7.5 + 6.0.7.6 From 168dc5cb35db6f0db9388455e3c94b913a9f9ba0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:19:00 +0000 Subject: [PATCH 07/23] chore(deps): update asf-ui digest to faa5f79 --- ASF-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ASF-ui b/ASF-ui index 9f5672d65a1bd..faa5f797f0e0f 160000 --- a/ASF-ui +++ b/ASF-ui @@ -1 +1 @@ -Subproject commit 9f5672d65a1bd3b0f5d16ea6a1b5d220d670223c +Subproject commit faa5f797f0e0fab6f98bf04724ad389141b6cca9 From da04f6b10056ee8f2615eb52bc7ed4bb1a9dad91 Mon Sep 17 00:00:00 2001 From: ArchiBot Date: Sat, 28 Sep 2024 02:19:20 +0000 Subject: [PATCH 08/23] Automatic translations update --- .../Localization/Strings.cs-CZ.resx | 5 ++++- wiki | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/Localization/Strings.cs-CZ.resx b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/Localization/Strings.cs-CZ.resx index 6c4314502d49b..9a2aa3924e729 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/Localization/Strings.cs-CZ.resx +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/Localization/Strings.cs-CZ.resx @@ -68,7 +68,10 @@ {0} je v současné době v souladu s vaší konfigurací zakázán. Pokud byste chtěli pomoci SteamDB při odesílání dat, podívejte se na naši wiki. {0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin") - + + {0} byl úspěšně inicializován, předem děkujeme za vaši pomoc. První zpráva bude vygenerována zhruba za {1}. + {0} will be replaced by the name of the plugin (e.g. "SteamTokenDumperPlugin"), {1} will be replaced by translated TimeSpan string (such as "53 minutes") + {0} nelze načíst, nová instance bude inicializována... {0} will be replaced by the name of the file (e.g. "GlobalCache") diff --git a/wiki b/wiki index 15ec805ef1ede..e597c1494967a 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 15ec805ef1ede5740afc3eb0e2bf620c50c65bab +Subproject commit e597c1494967a9a391f40ef05b92f2b34ab2b9c6 From 37afe1959a99a01243763f8d2f19d62a868bb92c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 28 Sep 2024 10:46:57 +0000 Subject: [PATCH 09/23] chore(deps): update asf-ui digest to fa46e12 --- ASF-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ASF-ui b/ASF-ui index faa5f797f0e0f..fa46e12afad52 160000 --- a/ASF-ui +++ b/ASF-ui @@ -1 +1 @@ -Subproject commit faa5f797f0e0fab6f98bf04724ad389141b6cca9 +Subproject commit fa46e12afad522ea60014c995b40f0a0b656cde7 From e44d1ac62ed4ba1737f08b0a53ce6917aa3a73f0 Mon Sep 17 00:00:00 2001 From: ArchiBot Date: Sun, 29 Sep 2024 02:21:59 +0000 Subject: [PATCH 10/23] Automatic translations update --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index e597c1494967a..3ef30e399d431 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit e597c1494967a9a391f40ef05b92f2b34ab2b9c6 +Subproject commit 3ef30e399d43125a813f17c50f0f661d1acd45d7 From c6261af03c1b0adb73fb8dc5b5bef476f76ac11f Mon Sep 17 00:00:00 2001 From: ArchiBot Date: Mon, 30 Sep 2024 02:21:42 +0000 Subject: [PATCH 11/23] Automatic translations update --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 3ef30e399d431..dfd7523082027 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 3ef30e399d43125a813f17c50f0f661d1acd45d7 +Subproject commit dfd7523082027bdc59a8acf5a9b9013dfc65707c From b66dd2c01ba40b3c940025878ee4bcb438e0910f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:22:56 +0000 Subject: [PATCH 12/23] chore(deps): update swashbuckle-aspnetcore monorepo to 6.8.1 --- Directory.Packages.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index c02dcd69dfc70..8d50dd0019029 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -16,8 +16,8 @@ - - + + From a7f2556b48a20856b49a414632778315bb113ba6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 13:49:28 +0000 Subject: [PATCH 13/23] chore(deps): update github/codeql-action action to v3.26.10 --- .github/workflows/code-quality.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index a2c4c98afe942..af001970b02e1 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -34,6 +34,6 @@ jobs: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} - name: Report Qodana results to GitHub - uses: github/codeql-action/upload-sarif@v3.26.9 + uses: github/codeql-action/upload-sarif@v3.26.10 with: sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json From ba1195294521b945d6d2eba0850b3d88bdeb6a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 19:16:52 +0200 Subject: [PATCH 14/23] Handle exceptions in ArchiCacheable While our code does not throw them, this is public helper and we don't need to enforce from other callers exceptions-less flow. We can use it for a failure. --- ArchiSteamFarm/Helpers/ArchiCacheable.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ArchiSteamFarm/Helpers/ArchiCacheable.cs b/ArchiSteamFarm/Helpers/ArchiCacheable.cs index 8ad0641eac88e..e64c193aac2eb 100644 --- a/ArchiSteamFarm/Helpers/ArchiCacheable.cs +++ b/ArchiSteamFarm/Helpers/ArchiCacheable.cs @@ -87,6 +87,10 @@ public ArchiCacheable(Func> r } catch (OperationCanceledException e) { ASF.ArchiLogger.LogGenericDebuggingException(e); + return GetFailedValueFor(cacheFallback); + } catch (Exception e) { + ASF.ArchiLogger.LogGenericException(e); + return GetFailedValueFor(cacheFallback); } finally { InitSemaphore.Release(); From c2abbf0fc07cb68c7efba4cc147637fa7752b581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 19:19:26 +0200 Subject: [PATCH 15/23] Misc optimization --- .../RemoteCommunication.cs | 2 +- ArchiSteamFarm/Steam/Exchange/Trading.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs index b7389d784ebef..8c5681958d4e0 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs @@ -1255,7 +1255,7 @@ private async Task MatchActively(ImmutableHashSet listedUsers, Dictionary fairClassIDsToGive = new(); Dictionary fairClassIDsToReceive = new(); - foreach (ListedUser listedUser in listedUsers.Where(listedUser => (listedUser.SteamID != Bot.SteamID) && acceptedMatchableTypes.Any(listedUser.MatchableTypes.Contains) && !Bot.IsBlacklistedFromTrades(listedUser.SteamID)).OrderByDescending(listedUser => !deprioritizedSteamIDs.Contains(listedUser.SteamID)).ThenByDescending(static listedUser => listedUser.TotalGamesCount > 1).ThenByDescending(static listedUser => listedUser.MatchEverything).ThenBy(static listedUser => listedUser.TotalInventoryCount)) { + foreach (ListedUser listedUser in listedUsers.Where(listedUser => (listedUser.SteamID != Bot.SteamID) && acceptedMatchableTypes.Overlaps(listedUser.MatchableTypes) && !Bot.IsBlacklistedFromTrades(listedUser.SteamID)).OrderByDescending(listedUser => !deprioritizedSteamIDs.Contains(listedUser.SteamID)).ThenByDescending(static listedUser => listedUser.TotalGamesCount > 1).ThenByDescending(static listedUser => listedUser.MatchEverything).ThenBy(static listedUser => listedUser.TotalInventoryCount)) { if (failuresInRow >= WebBrowser.MaxTries) { Bot.ArchiLogger.LogGenericWarning(Strings.FormatWarningFailedWithError($"{nameof(failuresInRow)} >= {WebBrowser.MaxTries}")); diff --git a/ArchiSteamFarm/Steam/Exchange/Trading.cs b/ArchiSteamFarm/Steam/Exchange/Trading.cs index 900c8e6d7d2bd..8d5431d241a03 100644 --- a/ArchiSteamFarm/Steam/Exchange/Trading.cs +++ b/ArchiSteamFarm/Steam/Exchange/Trading.cs @@ -556,7 +556,7 @@ private async Task ParseTrade(TradeOffer tradeOffer, ISet<(uin if (accept) { // Ensure that accepting this trade offer does not create conflicts with other lock (handledSets) { - if (wantedSets.Any(handledSets.Contains)) { + if (handledSets.Overlaps(wantedSets)) { Bot.ArchiLogger.LogGenericDebug(Strings.FormatBotTradeOfferResult(tradeOffer.TradeOfferID, ParseTradeResult.EResult.RetryAfterOthers, nameof(handledSets))); return ParseTradeResult.EResult.RetryAfterOthers; From 55d49f87ff79a3d58cc097bd93e7ce7485cb35a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 22:02:09 +0200 Subject: [PATCH 16/23] Closes #3299 --- .../IPC/Controllers/Api/BotController.cs | 28 ++++++ .../Steam/Integration/ArchiHandler.cs | 31 +++++++ ArchiSteamFarm/Steam/Interaction/Actions.cs | 7 ++ ArchiSteamFarm/Steam/Interaction/Commands.cs | 87 +++++++++++++++++++ 4 files changed, 153 insertions(+) diff --git a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs index ab78e4edae78e..8973a6b5de9cb 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs @@ -74,6 +74,34 @@ public async Task> AddLicensePost(string botNames, return Ok(new GenericResponse>(result)); } + /// + /// Redeems points on given bots. + /// + [Consumes("application/json")] + [HttpPost("{botNames:required}/RedeemPoints/{definitionID:required}")] + [ProducesResponseType>>((int) HttpStatusCode.OK)] + [ProducesResponseType((int) HttpStatusCode.BadRequest)] + public async Task> AddLicensePost(string botNames, uint definitionID) { + ArgumentException.ThrowIfNullOrEmpty(botNames); + ArgumentOutOfRangeException.ThrowIfZero(definitionID); + + HashSet? bots = Bot.GetBots(botNames); + + if ((bots == null) || (bots.Count == 0)) { + return BadRequest(new GenericResponse(false, Strings.FormatBotNotFound(botNames))); + } + + IList results = await Utilities.InParallel(bots.Select(bot => bot.Actions.RedeemPoints(definitionID))).ConfigureAwait(false); + + Dictionary result = new(bots.Count, Bot.BotsComparer); + + foreach (Bot bot in bots) { + result[bot.BotName] = results[result.Count]; + } + + return Ok(new GenericResponse>(result)); + } + /// /// Deletes all files related to given bots. /// diff --git a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs index 90160b51c9a28..23e0c5ca55300 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs @@ -61,6 +61,7 @@ public sealed class ArchiHandler : ClientMsgHandler { private readonly SteamUnifiedMessages.UnifiedService UnifiedEconService; private readonly SteamUnifiedMessages.UnifiedService UnifiedFamilyGroups; private readonly SteamUnifiedMessages.UnifiedService UnifiedFriendMessagesService; + private readonly SteamUnifiedMessages.UnifiedService UnifiedLoyaltyRewards; private readonly SteamUnifiedMessages.UnifiedService UnifiedPlayerService; private readonly SteamUnifiedMessages.UnifiedService UnifiedStoreService; private readonly SteamUnifiedMessages.UnifiedService UnifiedTwoFactorService; @@ -80,6 +81,7 @@ internal ArchiHandler(ArchiLogger archiLogger, SteamUnifiedMessages steamUnified UnifiedEconService = steamUnifiedMessages.CreateService(); UnifiedFamilyGroups = steamUnifiedMessages.CreateService(); UnifiedFriendMessagesService = steamUnifiedMessages.CreateService(); + UnifiedLoyaltyRewards = steamUnifiedMessages.CreateService(); UnifiedPlayerService = steamUnifiedMessages.CreateService(); UnifiedStoreService = steamUnifiedMessages.CreateService(); UnifiedTwoFactorService = steamUnifiedMessages.CreateService(); @@ -500,6 +502,35 @@ public async Task LeaveChatRoomGroup(ulong chatGroupID) { return response.Result == EResult.OK; } + [PublicAPI] + public async Task RedeemPoints(uint definitionID) { + ArgumentOutOfRangeException.ThrowIfZero(definitionID); + + if (Client == null) { + throw new InvalidOperationException(nameof(Client)); + } + + if (!Client.IsConnected) { + return EResult.NoConnection; + } + + CLoyaltyRewards_RedeemPoints_Request request = new() { + defid = definitionID + }; + + SteamUnifiedMessages.ServiceMethodResponse response; + + try { + response = await UnifiedLoyaltyRewards.SendMessage(x => x.RedeemPoints(request)).ToLongRunningTask().ConfigureAwait(false); + } catch (Exception e) { + ArchiLogger.LogGenericWarningException(e); + + return EResult.Timeout; + } + + return response.Result; + } + [PublicAPI] public async Task RemoveFriend(ulong steamID) { if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) { diff --git a/ArchiSteamFarm/Steam/Interaction/Actions.cs b/ArchiSteamFarm/Steam/Interaction/Actions.cs index 12526ee487a7a..31e0fcf3b9b21 100644 --- a/ArchiSteamFarm/Steam/Interaction/Actions.cs +++ b/ArchiSteamFarm/Steam/Interaction/Actions.cs @@ -313,6 +313,13 @@ public static string Hash(ArchiCryptoHelper.EHashingMethod hashingMethod, string return await Bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false); } + [PublicAPI] + public async Task RedeemPoints(uint definitionID) { + ArgumentOutOfRangeException.ThrowIfZero(definitionID); + + return await Bot.ArchiHandler.RedeemPoints(definitionID).ConfigureAwait(false); + } + [PublicAPI] public static (bool Success, string Message) Restart() { if (!Program.RestartAllowed) { diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index 02d16ee0ef5b8..fd6c137edf659 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -298,6 +298,10 @@ public static EAccess GetProxyAccess(Bot bot, EAccess access, ulong steamID = 0) return await ResponseAdvancedRedeem(access, args[1], args[2], Utilities.GetArgsAsText(args, 3, ","), steamID).ConfigureAwait(false); case "R^" or "REDEEM^" when args.Length > 2: return await ResponseAdvancedRedeem(access, args[1], args[2], steamID).ConfigureAwait(false); + case "RP" or "REDEEMPOINTS" when args.Length > 2: + return await ResponseRedeemPoints(access, args[1], Utilities.GetArgsAsText(args, 2, ","), steamID).ConfigureAwait(false); + case "RP" or "REDEEMPOINTS": + return await ResponseRedeemPoints(access, args[1]).ConfigureAwait(false); case "RESET": return await ResponseReset(access, Utilities.GetArgsAsText(args, 1, ","), steamID).ConfigureAwait(false); case "RESUME": @@ -2763,6 +2767,89 @@ internal void OnNewLicenseList() { return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } + private async Task ResponseRedeemPoints(EAccess access, HashSet definitionIDs) { + if (!Enum.IsDefined(access)) { + throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(EAccess)); + } + + if ((definitionIDs == null) || (definitionIDs.Count == 0)) { + throw new ArgumentNullException(nameof(definitionIDs)); + } + + if (access < EAccess.Operator) { + return null; + } + + if (!Bot.IsConnectedAndLoggedOn) { + return FormatBotResponse(Strings.BotNotConnected); + } + + StringBuilder response = new(); + + foreach (uint definitionID in definitionIDs) { + EResult result = await Bot.Actions.RedeemPoints(definitionID).ConfigureAwait(false); + + response.AppendLine(FormatBotResponse(Strings.FormatBotAddLicense(definitionID, result))); + } + + return response.Length > 0 ? response.ToString() : null; + } + + private async Task ResponseRedeemPoints(EAccess access, string targetDefinitionIDs) { + if (!Enum.IsDefined(access)) { + throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(EAccess)); + } + + ArgumentException.ThrowIfNullOrEmpty(targetDefinitionIDs); + + if (access < EAccess.Operator) { + return null; + } + + if (!Bot.IsConnectedAndLoggedOn) { + return FormatBotResponse(Strings.BotNotConnected); + } + + string[] definitions = targetDefinitionIDs.Split(SharedInfo.ListElementSeparators, StringSplitOptions.RemoveEmptyEntries); + + if (definitions.Length == 0) { + return FormatBotResponse(Strings.FormatErrorIsEmpty(nameof(definitions))); + } + + HashSet definitionIDs = new(definitions.Length); + + foreach (string definition in definitions) { + if (!uint.TryParse(definition, out uint definitionID) || (definitionID == 0)) { + return FormatBotResponse(Strings.FormatErrorIsInvalid(nameof(definition))); + } + + definitionIDs.Add(definitionID); + } + + return await ResponseRedeemPoints(access, definitionIDs).ConfigureAwait(false); + } + + private static async Task ResponseRedeemPoints(EAccess access, string botNames, string targetDefinitionIDs, ulong steamID = 0) { + if (!Enum.IsDefined(access)) { + throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(EAccess)); + } + + ArgumentException.ThrowIfNullOrEmpty(botNames); + ArgumentException.ThrowIfNullOrEmpty(targetDefinitionIDs); + + 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 => bot.Commands.ResponseRedeemPoints(GetProxyAccess(bot, access, steamID), targetDefinitionIDs))).ConfigureAwait(false); + + List responses = [..results.Where(static result => !string.IsNullOrEmpty(result))!]; + + return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; + } + private async Task ResponseReset(EAccess access) { if (!Enum.IsDefined(access)) { throw new InvalidEnumArgumentException(nameof(access), (int) access, typeof(EAccess)); From b7a6cc515806113b0fd15474d235e1bfa08983c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 22:15:38 +0200 Subject: [PATCH 17/23] Activate multiple definitions in parallel --- ArchiSteamFarm/Steam/Interaction/Commands.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index fd6c137edf659..b8f0185b5acc4 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -2784,12 +2784,14 @@ internal void OnNewLicenseList() { return FormatBotResponse(Strings.BotNotConnected); } + IList results = await Utilities.InParallel(definitionIDs.Select(Bot.Actions.RedeemPoints)).ConfigureAwait(false); + + int i = 0; + StringBuilder response = new(); foreach (uint definitionID in definitionIDs) { - EResult result = await Bot.Actions.RedeemPoints(definitionID).ConfigureAwait(false); - - response.AppendLine(FormatBotResponse(Strings.FormatBotAddLicense(definitionID, result))); + response.AppendLine(FormatBotResponse(Strings.FormatBotAddLicense(definitionID, results[i++]))); } return response.Length > 0 ? response.ToString() : null; From d5df9e0af95038cbd24f06428e8c61ed5006be8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 22:24:04 +0200 Subject: [PATCH 18/23] Bump --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 2b2148484e3cf..a8b9b37c81feb 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 6.0.7.6 + 6.0.8.0 From 889795a326cfb9d47b0357413de65726002a8e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 22:24:40 +0200 Subject: [PATCH 19/23] Bump --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index a8b9b37c81feb..205501e65c7d9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 6.0.8.0 + 6.0.8.1 From f984a9122e684db5044cedfa294969f91df65dc3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 22:25:50 +0200 Subject: [PATCH 20/23] chore(deps): update wiki digest to 66d2709 (#3295) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index dfd7523082027..66d27099d8889 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit dfd7523082027bdc59a8acf5a9b9013dfc65707c +Subproject commit 66d27099d888992dab65b7eae01f04813cb667af From 641cf5a350ff7998f3b80ae34ba318d7ac88e11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 22:45:02 +0200 Subject: [PATCH 21/23] Rewrite points balance from AWH to AH --- .../Steam/Integration/ArchiHandler.cs | 41 +++++++++++++++++++ .../Steam/Integration/ArchiWebHandler.cs | 1 + ArchiSteamFarm/Steam/Interaction/Commands.cs | 2 +- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs index 23e0c5ca55300..f4787fba8cb04 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs @@ -359,6 +359,47 @@ public async IAsyncEnumerable GetMyInventoryAsync(uint appID = Asset.Stea return body.games.ToDictionary(static game => (uint) game.appid, static game => game.name); } + [PublicAPI] + public async Task GetPointsBalance() { + if (Client == null) { + throw new InvalidOperationException(nameof(Client)); + } + + if (!Client.IsConnected) { + return null; + } + + if (Client.SteamID == null) { + throw new InvalidOperationException(nameof(Client.SteamID)); + } + + ulong steamID = Client.SteamID; + + if (steamID == 0) { + throw new InvalidOperationException(nameof(Client.SteamID)); + } + + CLoyaltyRewards_GetSummary_Request request = new() { steamid = steamID }; + + SteamUnifiedMessages.ServiceMethodResponse response; + + try { + response = await UnifiedLoyaltyRewards.SendMessage(x => x.GetSummary(request)).ToLongRunningTask().ConfigureAwait(false); + } catch (Exception e) { + ArchiLogger.LogGenericWarningException(e); + + return null; + } + + if (response.Result != EResult.OK) { + return null; + } + + CLoyaltyRewards_GetSummary_Response body = response.GetDeserializedResponse(); + + return body.summary?.points; + } + [PublicAPI] public async Task GetSteamGuardStatus() { if (Client == null) { diff --git a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs index 6e4c5b692c7a0..cc7616a88298b 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs @@ -394,6 +394,7 @@ public async IAsyncEnumerable GetInventoryAsync(ulong steamID = 0, uint a } } + [Obsolete($"Use {nameof(ArchiHandler)}.{nameof(ArchiHandler.GetPointsBalance)} instead, this endpoint will be removed in the future version")] [PublicAPI] public async Task GetPointsBalance() { string? accessToken = Bot.AccessToken; diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index b8f0185b5acc4..4c83194b9c143 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -2309,7 +2309,7 @@ internal void OnNewLicenseList() { return FormatBotResponse(Strings.BotNotConnected); } - uint? points = await Bot.ArchiWebHandler.GetPointsBalance().ConfigureAwait(false); + long? points = await Bot.ArchiHandler.GetPointsBalance().ConfigureAwait(false); return FormatBotResponse(points.HasValue ? Strings.FormatBotPointsBalance(points) : Strings.WarningFailed); } From ae0704e2bb856969bba436d5f4cf9003b5b0ef7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 22:46:48 +0200 Subject: [PATCH 22/23] Remove obsolete alias --- ArchiSteamFarm/Steam/Interaction/Commands.cs | 6 ------ ArchiSteamFarm/Storage/GlobalConfig.cs | 7 +------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index 4c83194b9c143..f69d02bd235f5 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -3482,12 +3482,6 @@ internal void OnNewLicenseList() { if (!Enum.TryParse(channelText, true, out channel) || (channel == GlobalConfig.EUpdateChannel.None)) { return FormatStaticResponse(Strings.FormatErrorIsInvalid(nameof(channelText))); } - -#pragma warning disable CS0618 // TODO: Remove me in the future - if (channelText.Contains(nameof(GlobalConfig.EUpdateChannel.Experimental), StringComparison.OrdinalIgnoreCase)) { - return FormatStaticResponse(Strings.FormatWarningFailedWithError(Strings.FormatWarningDeprecated(nameof(GlobalConfig.EUpdateChannel.Experimental), nameof(GlobalConfig.EUpdateChannel.PreRelease)))); - } -#pragma warning restore CS0618 // TODO: Remove me in the future } (bool success, string? message, Version? version) = await Actions.Update(channel, forced).ConfigureAwait(false); diff --git a/ArchiSteamFarm/Storage/GlobalConfig.cs b/ArchiSteamFarm/Storage/GlobalConfig.cs index c9018f96ee272..5c64ca98c05ff 100644 --- a/ArchiSteamFarm/Storage/GlobalConfig.cs +++ b/ArchiSteamFarm/Storage/GlobalConfig.cs @@ -615,15 +615,10 @@ public enum EPluginsUpdateMode : byte { Blacklist } -#pragma warning disable CA1027 // TODO: Remove me after Experimental alias disappears [PublicAPI] public enum EUpdateChannel : byte { None, Stable, - PreRelease, - - [Obsolete($"Use {nameof(PreRelease)} instead, this alias will be removed in the future version")] - Experimental = PreRelease + PreRelease } -#pragma warning restore CA1027 // TODO: Remove me after Experimental alias disappears } From 1e3461918efea13864eb4117a6ff8545ce1271eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Mon, 30 Sep 2024 22:49:03 +0200 Subject: [PATCH 23/23] Misc --- ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs index cc7616a88298b..e2ab8b8090766 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs @@ -55,7 +55,10 @@ public sealed class ArchiWebHandler : IDisposable { internal const ushort MaxItemsInSingleInventoryRequest = 5000; private const string EconService = "IEconService"; + + [Obsolete] private const string LoyaltyRewardsService = "ILoyaltyRewardsService"; + private const byte MaxTradeOfferMessageLength = 128; private const byte MinimumSessionValidityInSeconds = 10; private const byte SessionIDLength = 24; // For maximum compatibility, should be divisible by 2 and match the length of "sessionid" property that Steam uses across their websites