diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/GlobalCache.cs b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/GlobalCache.cs index 4496f94ea..4bf36c58d 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/GlobalCache.cs +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/GlobalCache.cs @@ -93,9 +93,9 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper { internal ulong GetAppToken(uint appID) => AppTokens[appID]; - internal Dictionary GetAppTokensForSubmission() => AppTokens.Where(appToken => (SteamTokenDumperPlugin.Config?.SecretAppIDs.Contains(appToken.Key) == false) && (appToken.Value > 0) && (!SubmittedApps.TryGetValue(appToken.Key, out ulong token) || (appToken.Value != token))).ToDictionary(appToken => appToken.Key, appToken => appToken.Value); - internal Dictionary GetDepotKeysForSubmission() => DepotKeys.Where(depotKey => (SteamTokenDumperPlugin.Config?.SecretDepotIDs.Contains(depotKey.Key) == false) && !string.IsNullOrEmpty(depotKey.Value) && (!SubmittedDepots.TryGetValue(depotKey.Key, out string? key) || (depotKey.Value != key))).ToDictionary(depotKey => depotKey.Key, depotKey => depotKey.Value); - internal Dictionary GetPackageTokensForSubmission() => PackageTokens.Where(packageToken => (SteamTokenDumperPlugin.Config?.SecretPackageIDs.Contains(packageToken.Key) == false) && (packageToken.Value > 0) && (!SubmittedPackages.TryGetValue(packageToken.Key, out ulong token) || (packageToken.Value != token))).ToDictionary(packageToken => packageToken.Key, packageToken => packageToken.Value); + internal Dictionary GetAppTokensForSubmission() => AppTokens.Where(appToken => (SteamTokenDumperPlugin.Config?.SecretAppIDs.Contains(appToken.Key) == false) && (appToken.Value > 0) && (!SubmittedApps.TryGetValue(appToken.Key, out ulong token) || (appToken.Value != token))).ToDictionary(static appToken => appToken.Key, static appToken => appToken.Value); + internal Dictionary GetDepotKeysForSubmission() => DepotKeys.Where(depotKey => (SteamTokenDumperPlugin.Config?.SecretDepotIDs.Contains(depotKey.Key) == false) && !string.IsNullOrEmpty(depotKey.Value) && (!SubmittedDepots.TryGetValue(depotKey.Key, out string? key) || (depotKey.Value != key))).ToDictionary(static depotKey => depotKey.Key, static depotKey => depotKey.Value); + internal Dictionary GetPackageTokensForSubmission() => PackageTokens.Where(packageToken => (SteamTokenDumperPlugin.Config?.SecretPackageIDs.Contains(packageToken.Key) == false) && (packageToken.Value > 0) && (!SubmittedPackages.TryGetValue(packageToken.Key, out ulong token) || (packageToken.Value != token))).ToDictionary(static packageToken => packageToken.Key, static packageToken => packageToken.Value); internal static async Task Load() { if (!File.Exists(SharedFilePath)) { diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/RequestData.cs b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/RequestData.cs index 27cafeaf8..cb27ad052 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/RequestData.cs +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/RequestData.cs @@ -71,9 +71,9 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper { SteamID = steamID; - Apps = apps.ToImmutableDictionary(app => app.Key.ToString(CultureInfo.InvariantCulture), app => app.Value.ToString(CultureInfo.InvariantCulture)); - Subs = accessTokens.ToImmutableDictionary(package => package.Key.ToString(CultureInfo.InvariantCulture), package => package.Value.ToString(CultureInfo.InvariantCulture)); - Depots = depots.ToImmutableDictionary(depot => depot.Key.ToString(CultureInfo.InvariantCulture), depot => depot.Value); + Apps = apps.ToImmutableDictionary(static app => app.Key.ToString(CultureInfo.InvariantCulture), static app => app.Value.ToString(CultureInfo.InvariantCulture)); + Subs = accessTokens.ToImmutableDictionary(static package => package.Key.ToString(CultureInfo.InvariantCulture), static package => package.Value.ToString(CultureInfo.InvariantCulture)); + Depots = depots.ToImmutableDictionary(static depot => depot.Key.ToString(CultureInfo.InvariantCulture), static depot => depot.Value); } } } diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs index b53dc9529..22800ddc2 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs @@ -271,7 +271,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper { throw new InvalidOperationException(nameof(GlobalCache)); } - Dictionary packageTokens = callback.LicenseList.Where(license => !Config.SecretPackageIDs.Contains(license.PackageID) && ((license.PaymentMethod != EPaymentMethod.AutoGrant) || !Config.SkipAutoGrantPackages)).GroupBy(license => license.PackageID).ToDictionary(group => group.Key, group => group.OrderByDescending(license => license.TimeCreated).First().AccessToken); + Dictionary packageTokens = callback.LicenseList.Where(static license => !Config.SecretPackageIDs.Contains(license.PackageID) && ((license.PaymentMethod != EPaymentMethod.AutoGrant) || !Config.SkipAutoGrantPackages)).GroupBy(static license => license.PackageID).ToDictionary(static group => group.Key, static group => group.OrderByDescending(static license => license.TimeCreated).First().AccessToken); GlobalCache.UpdatePackageTokens(packageTokens); @@ -308,17 +308,17 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper { return; } - packageIDs ??= bot.OwnedPackageIDs.Where(package => !Config.SecretPackageIDs.Contains(package.Key) && ((package.Value.PaymentMethod != EPaymentMethod.AutoGrant) || !Config.SkipAutoGrantPackages)).Select(package => package.Key).ToHashSet(); + packageIDs ??= bot.OwnedPackageIDs.Where(static package => !Config.SecretPackageIDs.Contains(package.Key) && ((package.Value.PaymentMethod != EPaymentMethod.AutoGrant) || !Config.SkipAutoGrantPackages)).Select(static package => package.Key).ToHashSet(); HashSet appIDsToRefresh = new(); - foreach (uint packageID in packageIDs.Where(packageID => !Config.SecretPackageIDs.Contains(packageID))) { + foreach (uint packageID in packageIDs.Where(static packageID => !Config.SecretPackageIDs.Contains(packageID))) { if (!ASF.GlobalDatabase.PackagesDataReadOnly.TryGetValue(packageID, out (uint ChangeNumber, ImmutableHashSet? AppIDs) packageData) || (packageData.AppIDs == null)) { // ASF might not have the package info for us at the moment, we'll retry later continue; } - appIDsToRefresh.UnionWith(packageData.AppIDs.Where(appID => !Config.SecretAppIDs.Contains(appID) && GlobalCache.ShouldRefreshAppInfo(appID))); + appIDsToRefresh.UnionWith(packageData.AppIDs.Where(static appID => !Config.SecretAppIDs.Contains(appID) && GlobalCache.ShouldRefreshAppInfo(appID))); } if (appIDsToRefresh.Count == 0) { @@ -387,7 +387,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper { AsyncJobMultiple.ResultSet response; try { - response = await bot.SteamApps.PICSGetProductInfo(appIDsThisRound.Select(appID => new SteamApps.PICSRequest(appID, GlobalCache.GetAppToken(appID))), Enumerable.Empty()).ToLongRunningTask().ConfigureAwait(false); + response = await bot.SteamApps.PICSGetProductInfo(appIDsThisRound.Select(static appID => new SteamApps.PICSRequest(appID, GlobalCache.GetAppToken(appID))), Enumerable.Empty()).ToLongRunningTask().ConfigureAwait(false); } catch (Exception e) { bot.ArchiLogger.LogGenericWarningException(e); @@ -408,7 +408,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper { HashSet> depotTasks = new(); - foreach (SteamApps.PICSProductInfoCallback.PICSProductInfo app in response.Results.SelectMany(result => result.Apps.Values)) { + foreach (SteamApps.PICSProductInfoCallback.PICSProductInfo app in response.Results.SelectMany(static result => result.Apps.Values)) { appChangeNumbers[app.ID] = app.ChangeNumber; if (GlobalCache.ShouldRefreshDepotKey(app.ID)) { @@ -489,7 +489,7 @@ namespace ArchiSteamFarm.OfficialPlugins.SteamTokenDumper { return; } - ulong contributorSteamID = (ASF.GlobalConfig.SteamOwnerID > 0) && new SteamID(ASF.GlobalConfig.SteamOwnerID).IsIndividualAccount ? ASF.GlobalConfig.SteamOwnerID : Bot.Bots.Values.Where(bot => bot.SteamID > 0).OrderByDescending(bot => bot.OwnedPackageIDs.Count).FirstOrDefault()?.SteamID ?? 0; + ulong contributorSteamID = (ASF.GlobalConfig.SteamOwnerID > 0) && new SteamID(ASF.GlobalConfig.SteamOwnerID).IsIndividualAccount ? ASF.GlobalConfig.SteamOwnerID : Bot.Bots.Values.Where(static bot => bot.SteamID > 0).OrderByDescending(static bot => bot.OwnedPackageIDs.Count).FirstOrDefault()?.SteamID ?? 0; if (contributorSteamID == 0) { ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionNoContributorSet, nameof(ASF.GlobalConfig.SteamOwnerID))); diff --git a/ArchiSteamFarm.Tests/Bot.cs b/ArchiSteamFarm.Tests/Bot.cs index a95f0cdf3..8d25a40f3 100644 --- a/ArchiSteamFarm.Tests/Bot.cs +++ b/ArchiSteamFarm.Tests/Bot.cs @@ -51,9 +51,7 @@ namespace ArchiSteamFarm.Tests { HashSet itemsToSend = GetItemsForFullBadge(items, itemsPerSet, MinCardsPerBadge); - Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = items.Where(item => item.RealAppID == relevantAppID) - .GroupBy(item => (item.RealAppID, item.ContextID, item.ClassID)) - .ToDictionary(grouping => grouping.Key, grouping => (uint) grouping.Sum(item => item.Amount)); + Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), uint> expectedResult = items.Where(static item => item.RealAppID == relevantAppID).GroupBy(static item => (item.RealAppID, item.ContextID, item.ClassID)).ToDictionary(static group => group.Key, static group => (uint) group.Sum(static item => item.Amount)); AssertResultMatchesExpectation(expectedResult, itemsToSend); } @@ -497,7 +495,7 @@ namespace ArchiSteamFarm.Tests { throw new ArgumentNullException(nameof(itemsToSend)); } - Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), long> realResult = itemsToSend.GroupBy(asset => (asset.RealAppID, asset.ContextID, asset.ClassID)).ToDictionary(group => group.Key, group => group.Sum(asset => asset.Amount)); + Dictionary<(uint RealAppID, ulong ContextID, ulong ClassID), long> realResult = itemsToSend.GroupBy(static asset => (asset.RealAppID, asset.ContextID, asset.ClassID)).ToDictionary(static group => group.Key, static group => group.Sum(static asset => asset.Amount)); Assert.AreEqual(expectedResult.Count, realResult.Count); Assert.IsTrue(expectedResult.All(expectation => realResult.TryGetValue(expectation.Key, out long reality) && (expectation.Value == reality))); } @@ -509,7 +507,7 @@ namespace ArchiSteamFarm.Tests { private static HashSet GetItemsForFullBadge(IReadOnlyCollection inventory, IDictionary cardsPerSet, ushort maxItems = Steam.Exchange.Trading.MaxItemsPerTrade) { Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), List> inventorySets = Steam.Exchange.Trading.GetInventorySets(inventory); - return GetItemsForFullSets(inventory, inventorySets.ToDictionary(kv => kv.Key, kv => (SetsToExtract: inventorySets[kv.Key][0], cardsPerSet[kv.Key.RealAppID])), maxItems).ToHashSet(); + return GetItemsForFullSets(inventory, inventorySets.ToDictionary(static kv => kv.Key, kv => (SetsToExtract: inventorySets[kv.Key][0], cardsPerSet[kv.Key.RealAppID])), maxItems).ToHashSet(); } } } diff --git a/ArchiSteamFarm.Tests/SteamChatMessage.cs b/ArchiSteamFarm.Tests/SteamChatMessage.cs index a69562f60..5367df8c8 100644 --- a/ArchiSteamFarm.Tests/SteamChatMessage.cs +++ b/ArchiSteamFarm.Tests/SteamChatMessage.cs @@ -267,7 +267,7 @@ namespace ArchiSteamFarm.Tests { string[] lines = messagePart.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); - int bytes = lines.Where(line => line.Length > 0).Sum(Encoding.UTF8.GetByteCount) + ((lines.Length - 1) * NewlineWeight); + int bytes = lines.Where(static line => line.Length > 0).Sum(Encoding.UTF8.GetByteCount) + ((lines.Length - 1) * NewlineWeight); if (bytes > MaxMessageBytesForUnlimitedAccounts) { Assert.Fail(); diff --git a/ArchiSteamFarm.sln.DotSettings b/ArchiSteamFarm.sln.DotSettings index fb0e4d757..437a29026 100644 --- a/ArchiSteamFarm.sln.DotSettings +++ b/ArchiSteamFarm.sln.DotSettings @@ -197,12 +197,14 @@ SUGGESTION SUGGESTION + HINT WARNING SUGGESTION True SUGGESTION WARNING + WARNING SUGGESTION SUGGESTION SUGGESTION @@ -261,6 +263,7 @@ SUGGESTION WARNING SUGGESTION + SUGGESTION SUGGESTION SUGGESTION SUGGESTION @@ -287,6 +290,7 @@ SUGGESTION SUGGESTION SUGGESTION + WARNING SUGGESTION SUGGESTION SUGGESTION diff --git a/ArchiSteamFarm/Core/ASF.cs b/ArchiSteamFarm/Core/ASF.cs index ff56a0ad1..f2b86148e 100644 --- a/ArchiSteamFarm/Core/ASF.cs +++ b/ArchiSteamFarm/Core/ASF.cs @@ -428,7 +428,7 @@ namespace ArchiSteamFarm.Core { Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework - loadedAssembliesNames = loadedAssemblies.Select(loadedAssembly => loadedAssembly.FullName).Where(name => !string.IsNullOrEmpty(name)).ToHashSet()!; + loadedAssembliesNames = loadedAssemblies.Select(static loadedAssembly => loadedAssembly.FullName).Where(static name => !string.IsNullOrEmpty(name)).ToHashSet()!; } foreach (AssemblyName assemblyName in assembly.GetReferencedAssemblies().Where(assemblyName => !loadedAssembliesNames.Contains(assemblyName.FullName))) { @@ -832,7 +832,7 @@ namespace ArchiSteamFarm.Core { if (!servers.Any()) { ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.Initializing, nameof(SteamDirectory))); - SteamConfiguration steamConfiguration = SteamConfiguration.Create(builder => builder.WithProtocolTypes(GlobalConfig.SteamProtocols).WithCellID(GlobalDatabase.CellID).WithServerListProvider(GlobalDatabase.ServerListProvider).WithHttpClientFactory(() => WebBrowser.GenerateDisposableHttpClient())); + SteamConfiguration steamConfiguration = SteamConfiguration.Create(static builder => builder.WithProtocolTypes(GlobalConfig.SteamProtocols).WithCellID(GlobalDatabase.CellID).WithServerListProvider(GlobalDatabase.ServerListProvider).WithHttpClientFactory(static () => WebBrowser.GenerateDisposableHttpClient())); try { await SteamDirectory.LoadAsync(steamConfiguration).ConfigureAwait(false); @@ -848,7 +848,7 @@ namespace ArchiSteamFarm.Core { HashSet botNames; try { - botNames = Directory.EnumerateFiles(SharedInfo.ConfigDirectory, $"*{SharedInfo.JsonConfigExtension}").Select(Path.GetFileNameWithoutExtension).Where(botName => !string.IsNullOrEmpty(botName) && IsValidBotName(botName)).ToHashSet(Bot.BotsComparer)!; + botNames = Directory.EnumerateFiles(SharedInfo.ConfigDirectory, $"*{SharedInfo.JsonConfigExtension}").Select(Path.GetFileNameWithoutExtension).Where(static botName => !string.IsNullOrEmpty(botName) && IsValidBotName(botName)).ToHashSet(Bot.BotsComparer)!; } catch (Exception e) { ArchiLogger.LogGenericException(e); @@ -867,7 +867,7 @@ namespace ArchiSteamFarm.Core { break; } - await Utilities.InParallel(botNames.OrderBy(botName => botName, Bot.BotsComparer).Select(Bot.RegisterBot)).ConfigureAwait(false); + await Utilities.InParallel(botNames.OrderBy(static botName => botName, Bot.BotsComparer).Select(Bot.RegisterBot)).ConfigureAwait(false); } private static async Task UpdateAndRestart() { @@ -994,7 +994,7 @@ namespace ArchiSteamFarm.Core { } // Now enumerate over files in the zip archive, skip directory entries that we're not interested in (we can create them ourselves if needed) - foreach (ZipArchiveEntry zipFile in archive.Entries.Where(zipFile => !string.IsNullOrEmpty(zipFile.Name))) { + foreach (ZipArchiveEntry zipFile in archive.Entries.Where(static zipFile => !string.IsNullOrEmpty(zipFile.Name))) { string file = Path.GetFullPath(Path.Combine(targetDirectory, zipFile.FullName)); if (!file.StartsWith(targetDirectory, StringComparison.Ordinal)) { diff --git a/ArchiSteamFarm/Core/Events.cs b/ArchiSteamFarm/Core/Events.cs index b14c2c8bc..76076c04c 100644 --- a/ArchiSteamFarm/Core/Events.cs +++ b/ArchiSteamFarm/Core/Events.cs @@ -27,7 +27,7 @@ using ArchiSteamFarm.Steam; namespace ArchiSteamFarm.Core { internal static class Events { internal static async Task OnBotShutdown() { - if (Program.ProcessRequired || ((Bot.Bots != null) && Bot.Bots.Values.Any(bot => bot.KeepRunning))) { + if (Program.ProcessRequired || ((Bot.Bots != null) && Bot.Bots.Values.Any(static bot => bot.KeepRunning))) { return; } @@ -36,7 +36,7 @@ namespace ArchiSteamFarm.Core { // We give user extra 5 seconds for eventual config changes await Task.Delay(5000).ConfigureAwait(false); - if (Program.ProcessRequired || ((Bot.Bots != null) && Bot.Bots.Values.Any(bot => bot.KeepRunning))) { + if (Program.ProcessRequired || ((Bot.Bots != null) && Bot.Bots.Values.Any(static bot => bot.KeepRunning))) { return; } diff --git a/ArchiSteamFarm/Core/Statistics.cs b/ArchiSteamFarm/Core/Statistics.cs index 9acec4289..f1e206b70 100644 --- a/ArchiSteamFarm/Core/Statistics.cs +++ b/ArchiSteamFarm/Core/Statistics.cs @@ -225,7 +225,7 @@ namespace ArchiSteamFarm.Core { Dictionary data = new(9, StringComparer.Ordinal) { { "AvatarHash", avatarHash ?? "" }, - { "GamesCount", inventory.Select(item => item.RealAppID).Distinct().Count().ToString(CultureInfo.InvariantCulture) }, + { "GamesCount", inventory.Select(static item => item.RealAppID).Distinct().Count().ToString(CultureInfo.InvariantCulture) }, { "Guid", (ASF.GlobalDatabase?.Identifier ?? Guid.NewGuid()).ToString("N") }, { "ItemsCount", inventory.Count.ToString(CultureInfo.InvariantCulture) }, { "MatchableTypes", JsonConvert.SerializeObject(acceptedMatchableTypes) }, @@ -300,7 +300,7 @@ namespace ArchiSteamFarm.Core { } // Bot must have at least one accepted matchable type set - if ((Bot.BotConfig.MatchableTypes.Count == 0) || Bot.BotConfig.MatchableTypes.All(type => !AcceptedMatchableTypes.Contains(type))) { + if ((Bot.BotConfig.MatchableTypes.Count == 0) || Bot.BotConfig.MatchableTypes.All(static type => !AcceptedMatchableTypes.Contains(type))) { Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(Bot.BotConfig.MatchableTypes)}: {string.Join(", ", Bot.BotConfig.MatchableTypes)}")); return false; @@ -425,7 +425,7 @@ namespace ArchiSteamFarm.Core { HashSet<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity)> skippedSetsThisRound = new(); - foreach (ListedUser listedUser in listedUsers.Where(listedUser => (listedUser.SteamID != Bot.SteamID) && acceptedMatchableTypes.Any(listedUser.MatchableTypes.Contains) && (!triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet? GivenAssetIDs, ISet? ReceivedAssetIDs) attempt) || (attempt.Tries < byte.MaxValue)) && !Bot.IsBlacklistedFromTrades(listedUser.SteamID)).OrderBy(listedUser => triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet? GivenAssetIDs, ISet? ReceivedAssetIDs) attempt) ? attempt.Tries : 0).ThenByDescending(listedUser => listedUser.MatchEverything).ThenByDescending(listedUser => listedUser.MatchEverything || (listedUser.ItemsCount < MaxItemsForFairBots)).ThenByDescending(listedUser => listedUser.Score)) { + foreach (ListedUser listedUser in listedUsers.Where(listedUser => (listedUser.SteamID != Bot.SteamID) && acceptedMatchableTypes.Any(listedUser.MatchableTypes.Contains) && (!triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet? GivenAssetIDs, ISet? ReceivedAssetIDs) attempt) || (attempt.Tries < byte.MaxValue)) && !Bot.IsBlacklistedFromTrades(listedUser.SteamID)).OrderBy(listedUser => triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet? GivenAssetIDs, ISet? ReceivedAssetIDs) attempt) ? attempt.Tries : 0).ThenByDescending(static listedUser => listedUser.MatchEverything).ThenByDescending(static listedUser => listedUser.MatchEverything || (listedUser.ItemsCount < MaxItemsForFairBots)).ThenByDescending(static listedUser => listedUser.Score)) { HashSet<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity)> wantedSets = ourTradableState.Keys.Where(set => !skippedSetsThisRound.Contains(set) && listedUser.MatchableTypes.Contains(set.Type)).ToHashSet(); if (wantedSets.Count == 0) { @@ -485,7 +485,7 @@ namespace ArchiSteamFarm.Core { Dictionary fairClassIDsToGive = new(); Dictionary fairClassIDsToReceive = new(); - foreach (((uint RealAppID, Asset.EType Type, Asset.ERarity Rarity) set, Dictionary ourFullItems) in ourFullState.Where(set => !skippedSetsThisUser.Contains(set.Key) && listedUser.MatchableTypes.Contains(set.Key.Type) && set.Value.Values.Any(count => count > 1))) { + foreach (((uint RealAppID, Asset.EType Type, Asset.ERarity Rarity) set, Dictionary ourFullItems) in ourFullState.Where(set => !skippedSetsThisUser.Contains(set.Key) && listedUser.MatchableTypes.Contains(set.Key.Type) && set.Value.Values.Any(static count => count > 1))) { if (!ourTradableState.TryGetValue(set, out Dictionary? ourTradableItems) || (ourTradableItems.Count == 0)) { continue; } @@ -536,7 +536,7 @@ namespace ArchiSteamFarm.Core { do { match = false; - foreach ((ulong ourItem, uint ourFullAmount) in ourFullSet.Where(item => item.Value > 1).OrderByDescending(item => item.Value)) { + foreach ((ulong ourItem, uint ourFullAmount) in ourFullSet.Where(static item => item.Value > 1).OrderByDescending(static item => item.Value)) { if (!ourTradableSet.TryGetValue(ourItem, out uint ourTradableAmount) || (ourTradableAmount == 0)) { continue; } @@ -554,11 +554,11 @@ namespace ArchiSteamFarm.Core { fairClassIDsToReceive[theirItem] = ++fairReceivedAmount; // Filter their inventory for the sets we're trading or have traded with this user - HashSet fairFiltered = theirInventory.Where(item => ((item.RealAppID == set.RealAppID) && (item.Type == set.Type) && (item.Rarity == set.Rarity)) || skippedSetsThisTrade.Contains((item.RealAppID, item.Type, item.Rarity))).Select(item => item.CreateShallowCopy()).ToHashSet(); + HashSet fairFiltered = theirInventory.Where(item => ((item.RealAppID == set.RealAppID) && (item.Type == set.Type) && (item.Rarity == set.Rarity)) || skippedSetsThisTrade.Contains((item.RealAppID, item.Type, item.Rarity))).Select(static item => item.CreateShallowCopy()).ToHashSet(); // Copy list to HashSet - HashSet fairItemsToGive = Trading.GetTradableItemsFromInventory(ourInventory.Where(item => ((item.RealAppID == set.RealAppID) && (item.Type == set.Type) && (item.Rarity == set.Rarity)) || skippedSetsThisTrade.Contains((item.RealAppID, item.Type, item.Rarity))).Select(item => item.CreateShallowCopy()).ToHashSet(), fairClassIDsToGive.ToDictionary(classID => classID.Key, classID => classID.Value)); - HashSet fairItemsToReceive = Trading.GetTradableItemsFromInventory(fairFiltered.Select(item => item.CreateShallowCopy()).ToHashSet(), fairClassIDsToReceive.ToDictionary(classID => classID.Key, classID => classID.Value)); + HashSet fairItemsToGive = Trading.GetTradableItemsFromInventory(ourInventory.Where(item => ((item.RealAppID == set.RealAppID) && (item.Type == set.Type) && (item.Rarity == set.Rarity)) || skippedSetsThisTrade.Contains((item.RealAppID, item.Type, item.Rarity))).Select(static item => item.CreateShallowCopy()).ToHashSet(), fairClassIDsToGive.ToDictionary(static classID => classID.Key, static classID => classID.Value)); + HashSet fairItemsToReceive = Trading.GetTradableItemsFromInventory(fairFiltered.Select(static item => item.CreateShallowCopy()).ToHashSet(), fairClassIDsToReceive.ToDictionary(static classID => classID.Key, static classID => classID.Value)); // Actual check: if (!Trading.IsTradeNeutralOrBetter(fairFiltered, fairItemsToReceive, fairItemsToGive)) { @@ -646,23 +646,23 @@ namespace ArchiSteamFarm.Core { } if (triedSteamIDs.TryGetValue(listedUser.SteamID, out (byte Tries, ISet? GivenAssetIDs, ISet? ReceivedAssetIDs) previousAttempt)) { - if ((previousAttempt.GivenAssetIDs == null) || (previousAttempt.ReceivedAssetIDs == null) || (itemsToGive.Select(item => item.AssetID).All(previousAttempt.GivenAssetIDs.Contains) && itemsToReceive.Select(item => item.AssetID).All(previousAttempt.ReceivedAssetIDs.Contains))) { + if ((previousAttempt.GivenAssetIDs == null) || (previousAttempt.ReceivedAssetIDs == null) || (itemsToGive.Select(static item => item.AssetID).All(previousAttempt.GivenAssetIDs.Contains) && itemsToReceive.Select(static item => item.AssetID).All(previousAttempt.ReceivedAssetIDs.Contains))) { // This user didn't respond in our previous round, avoid him for remaining ones triedSteamIDs[listedUser.SteamID] = (byte.MaxValue, previousAttempt.GivenAssetIDs, previousAttempt.ReceivedAssetIDs); break; } - previousAttempt.GivenAssetIDs.UnionWith(itemsToGive.Select(item => item.AssetID)); - previousAttempt.ReceivedAssetIDs.UnionWith(itemsToReceive.Select(item => item.AssetID)); + previousAttempt.GivenAssetIDs.UnionWith(itemsToGive.Select(static item => item.AssetID)); + previousAttempt.ReceivedAssetIDs.UnionWith(itemsToReceive.Select(static item => item.AssetID)); } else { - previousAttempt.GivenAssetIDs = new HashSet(itemsToGive.Select(item => item.AssetID)); - previousAttempt.ReceivedAssetIDs = new HashSet(itemsToReceive.Select(item => item.AssetID)); + previousAttempt.GivenAssetIDs = new HashSet(itemsToGive.Select(static item => item.AssetID)); + previousAttempt.ReceivedAssetIDs = new HashSet(itemsToReceive.Select(static item => item.AssetID)); } triedSteamIDs[listedUser.SteamID] = (++previousAttempt.Tries, previousAttempt.GivenAssetIDs, previousAttempt.ReceivedAssetIDs); - Bot.ArchiLogger.LogGenericTrace($"{Bot.SteamID} <- {string.Join(", ", itemsToReceive.Select(item => $"{item.RealAppID}/{item.Type}-{item.ClassID} #{item.Amount}"))} | {string.Join(", ", itemsToGive.Select(item => $"{item.RealAppID}/{item.Type}-{item.ClassID} #{item.Amount}"))} -> {listedUser.SteamID}"); + Bot.ArchiLogger.LogGenericTrace($"{Bot.SteamID} <- {string.Join(", ", itemsToReceive.Select(static item => $"{item.RealAppID}/{item.Type}-{item.ClassID} #{item.Amount}"))} | {string.Join(", ", itemsToGive.Select(static item => $"{item.RealAppID}/{item.Type}-{item.ClassID} #{item.Amount}"))} -> {listedUser.SteamID}"); (bool success, HashSet? mobileTradeOfferIDs) = await Bot.ArchiWebHandler.SendTradeOffer(listedUser.SteamID, itemsToGive, itemsToReceive, listedUser.TradeToken, true).ConfigureAwait(false); @@ -717,7 +717,7 @@ namespace ArchiSteamFarm.Core { Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.ActivelyMatchingItemsRound, skippedSetsThisRound.Count)); // Keep matching when we either traded something this round (so it makes sense for a refresh) or if we didn't try all available bots yet (so it makes sense to keep going) - return ((totalMatches > 0) && ((skippedSetsThisRound.Count > 0) || triedSteamIDs.Values.All(data => data.Tries < 2)), skippedSetsThisRound.Count > 0); + return ((totalMatches > 0) && ((skippedSetsThisRound.Count > 0) || triedSteamIDs.Values.All(static data => data.Tries < 2)), skippedSetsThisRound.Count > 0); } [SuppressMessage("ReSharper", "ClassCannotBeInstantiated")] diff --git a/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs b/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs index 1fad3ccdb..c42a26261 100644 --- a/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs +++ b/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs @@ -39,7 +39,7 @@ namespace ArchiSteamFarm.Helpers { private const byte SteamParentalSCryptBlocksCount = 8; private const ushort SteamParentalSCryptIterations = 8192; - private static IEnumerable SteamParentalCharacters => Enumerable.Range('0', 10).Select(character => (byte) character); + private static IEnumerable SteamParentalCharacters => Enumerable.Range('0', 10).Select(static character => (byte) character); private static IEnumerable SteamParentalCodes { get { diff --git a/ArchiSteamFarm/IPC/ArchiKestrel.cs b/ArchiSteamFarm/IPC/ArchiKestrel.cs index 9ae2b9999..371d305cf 100644 --- a/ArchiSteamFarm/IPC/ArchiKestrel.cs +++ b/ArchiSteamFarm/IPC/ArchiKestrel.cs @@ -84,7 +84,7 @@ namespace ArchiSteamFarm.IPC { // Firstly initialize settings that user is free to override builder.ConfigureLogging( - logging => { + static logging => { logging.ClearProviders(); logging.SetMinimumLevel(Debugging.IsUserDebugging ? LogLevel.Trace : LogLevel.Warning); } @@ -112,7 +112,7 @@ namespace ArchiSteamFarm.IPC { } // Use custom config for logging configuration - builder.ConfigureLogging((hostingContext, logging) => logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"))); + builder.ConfigureLogging(static (hostingContext, logging) => logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"))); } // Enable NLog integration for logging @@ -129,10 +129,10 @@ namespace ArchiSteamFarm.IPC { webBuilder.UseConfiguration(new ConfigurationBuilder().SetBasePath(absoluteConfigDirectory).AddJsonFile(SharedInfo.IPCConfigFile, false, Program.ConfigWatch).Build()); // Use custom config for Kestrel configuration - webBuilder.UseKestrel((builderContext, options) => options.Configure(builderContext.Configuration.GetSection("Kestrel"))); + webBuilder.UseKestrel(static (builderContext, options) => options.Configure(builderContext.Configuration.GetSection("Kestrel"))); } else { // Use ASF defaults for Kestrel - webBuilder.UseKestrel(options => options.ListenLocalhost(1242)); + webBuilder.UseKestrel(static options => options.ListenLocalhost(1242)); } // Specify Startup class for IPC diff --git a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs index 267125d2e..ef27512ac 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/BotController.cs @@ -60,9 +60,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList results = await Utilities.InParallel(bots.Select(bot => bot.DeleteAllRelatedFiles())).ConfigureAwait(false); + IList results = await Utilities.InParallel(bots.Select(static bot => bot.DeleteAllRelatedFiles())).ConfigureAwait(false); - return Ok(new GenericResponse(results.All(result => result))); + return Ok(new GenericResponse(results.All(static result => result))); } /// @@ -82,7 +82,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(bots)))); } - return Ok(new GenericResponse>(bots.Where(bot => !string.IsNullOrEmpty(bot.BotName)).ToDictionary(bot => bot.BotName, bot => bot, Bot.BotsComparer))); + return Ok(new GenericResponse>(bots.Where(static bot => !string.IsNullOrEmpty(bot.BotName)).ToDictionary(static bot => bot.BotName, static bot => bot, Bot.BotsComparer))); } /// @@ -115,7 +115,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { HashSet bots = botNames.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToHashSet(Bot.BotsComparer); - if (bots.Any(botName => !ASF.IsValidBotName(botName))) { + if (bots.Any(static botName => !ASF.IsValidBotName(botName))) { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(botNames)))); } @@ -157,7 +157,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { result[botName] = await BotConfig.Write(filePath, request.BotConfig).ConfigureAwait(false); } - return Ok(new GenericResponse>(result.Values.All(value => value), result)); + return Ok(new GenericResponse>(result.Values.All(static value => value), result)); } /// @@ -177,9 +177,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(bot.DeleteRedeemedKeysFiles))).ConfigureAwait(false); + IList results = await Utilities.InParallel(bots.Select(static bot => Task.Run(bot.DeleteRedeemedKeysFiles))).ConfigureAwait(false); - return Ok(results.All(result => result) ? new GenericResponse(true) : new GenericResponse(false, Strings.WarningFailed)); + return Ok(results.All(static result => result) ? new GenericResponse(true) : new GenericResponse(false, Strings.WarningFailed)); } /// @@ -199,7 +199,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList<(Dictionary? UnusedKeys, Dictionary? UsedKeys)> results = await Utilities.InParallel(bots.Select(bot => bot.GetUsedAndUnusedKeys())).ConfigureAwait(false); + IList<(Dictionary? UnusedKeys, Dictionary? UsedKeys)> results = await Utilities.InParallel(bots.Select(static bot => bot.GetUsedAndUnusedKeys())).ConfigureAwait(false); Dictionary result = new(bots.Count, Bot.BotsComparer); @@ -282,7 +282,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.SetUserInput(request.Type, request.Value)))).ConfigureAwait(false); - return Ok(results.All(result => result) ? new GenericResponse(true) : new GenericResponse(false, Strings.WarningFailed)); + return Ok(results.All(static result => result) ? new GenericResponse(true) : new GenericResponse(false, Strings.WarningFailed)); } /// @@ -309,7 +309,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { IList<(bool Success, string Message)> results = await Utilities.InParallel(bots.Select(bot => bot.Actions.Pause(request.Permanent, request.ResumeInSeconds))).ConfigureAwait(false); - return Ok(new GenericResponse(results.All(result => result.Success), string.Join(Environment.NewLine, results.Select(result => result.Message)))); + return Ok(new GenericResponse(results.All(static result => result.Success), string.Join(Environment.NewLine, results.Select(static result => result.Message)))); } /// @@ -342,7 +342,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList results = await Utilities.InParallel(bots.Select(bot => request.KeysToRedeem.Select(key => bot.Actions.RedeemKey(key))).SelectMany(task => task)).ConfigureAwait(false); + IList results = await Utilities.InParallel(bots.Select(bot => request.KeysToRedeem.Select(key => bot.Actions.RedeemKey(key))).SelectMany(static task => task)).ConfigureAwait(false); Dictionary> result = new(bots.Count, Bot.BotsComparer); @@ -357,7 +357,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { } } - return Ok(new GenericResponse>>(result.Values.SelectMany(responses => responses.Values).All(value => value != null), result)); + return Ok(new GenericResponse>>(result.Values.SelectMany(static responses => responses.Values).All(static value => value != null), result)); } /// @@ -410,9 +410,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList<(bool Success, string Message)> results = await Utilities.InParallel(bots.Select(bot => Task.Run(bot.Actions.Resume))).ConfigureAwait(false); + IList<(bool Success, string Message)> results = await Utilities.InParallel(bots.Select(static bot => Task.Run(bot.Actions.Resume))).ConfigureAwait(false); - return Ok(new GenericResponse(results.All(result => result.Success), string.Join(Environment.NewLine, results.Select(result => result.Message)))); + return Ok(new GenericResponse(results.All(static result => result.Success), string.Join(Environment.NewLine, results.Select(static result => result.Message)))); } /// @@ -432,9 +432,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList<(bool Success, string Message)> results = await Utilities.InParallel(bots.Select(bot => Task.Run(bot.Actions.Start))).ConfigureAwait(false); + IList<(bool Success, string Message)> results = await Utilities.InParallel(bots.Select(static bot => Task.Run(bot.Actions.Start))).ConfigureAwait(false); - return Ok(new GenericResponse(results.All(result => result.Success), string.Join(Environment.NewLine, results.Select(result => result.Message)))); + return Ok(new GenericResponse(results.All(static result => result.Success), string.Join(Environment.NewLine, results.Select(static result => result.Message)))); } /// @@ -454,9 +454,9 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList<(bool Success, string Message)> results = await Utilities.InParallel(bots.Select(bot => Task.Run(bot.Actions.Stop))).ConfigureAwait(false); + IList<(bool Success, string Message)> results = await Utilities.InParallel(bots.Select(static bot => Task.Run(bot.Actions.Stop))).ConfigureAwait(false); - return Ok(new GenericResponse(results.All(result => result.Success), string.Join(Environment.NewLine, results.Select(result => result.Message)))); + return Ok(new GenericResponse(results.All(static result => result.Success), string.Join(Environment.NewLine, results.Select(static result => result.Message)))); } /// @@ -513,7 +513,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse>>(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botNames))); } - IList<(bool Success, string? Token, string Message)> results = await Utilities.InParallel(bots.Select(bot => bot.Actions.GenerateTwoFactorAuthenticationToken())).ConfigureAwait(false); + IList<(bool Success, string? Token, string Message)> results = await Utilities.InParallel(bots.Select(static bot => bot.Actions.GenerateTwoFactorAuthenticationToken())).ConfigureAwait(false); Dictionary> result = new(bots.Count, Bot.BotsComparer); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs index e8cc0cd00..e426c7f94 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/CommandController.cs @@ -61,7 +61,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorIsInvalid, nameof(ASF.GlobalConfig.SteamOwnerID)))); } - Bot? targetBot = Bot.Bots?.OrderBy(bot => bot.Key, Bot.BotsComparer).Select(bot => bot.Value).FirstOrDefault(); + Bot? targetBot = Bot.Bots?.OrderBy(static bot => bot.Key, Bot.BotsComparer).Select(static bot => bot.Value).FirstOrDefault(); if (targetBot == null) { return BadRequest(new GenericResponse(false, Strings.ErrorNoBotsDefined)); diff --git a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs index ff98bb949..c31429097 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/NLogController.cs @@ -124,7 +124,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { string json = JsonConvert.SerializeObject(new GenericResponse(newHistoryEntryArgs.Message)); - await Task.WhenAll(ActiveLogWebSockets.Where(kv => kv.Key.State == WebSocketState.Open).Select(kv => PostLoggedJsonUpdate(kv.Key, json, kv.Value.Semaphore, kv.Value.CancellationToken))).ConfigureAwait(false); + await Task.WhenAll(ActiveLogWebSockets.Where(static kv => kv.Key.State == WebSocketState.Open).Select(kv => PostLoggedJsonUpdate(kv.Key, json, kv.Value.Semaphore, kv.Value.CancellationToken))).ConfigureAwait(false); } private static async Task PostLoggedJsonUpdate(WebSocket webSocket, string json, SemaphoreSlim sendSemaphore, CancellationToken cancellationToken) { diff --git a/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs b/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs index eaf6d5ca7..dd4775685 100644 --- a/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs +++ b/ArchiSteamFarm/IPC/Controllers/Api/TypeController.cs @@ -55,13 +55,13 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { } string? baseType = targetType.BaseType?.GetUnifiedName(); - HashSet customAttributes = targetType.CustomAttributes.Select(attribute => attribute.AttributeType.GetUnifiedName()).Where(customAttribute => !string.IsNullOrEmpty(customAttribute)).ToHashSet(StringComparer.Ordinal)!; + HashSet customAttributes = targetType.CustomAttributes.Select(static attribute => attribute.AttributeType.GetUnifiedName()).Where(static customAttribute => !string.IsNullOrEmpty(customAttribute)).ToHashSet(StringComparer.Ordinal)!; string? underlyingType = null; Dictionary body = new(StringComparer.Ordinal); if (targetType.IsClass) { - foreach (FieldInfo field in targetType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(field => !field.IsPrivate)) { + foreach (FieldInfo field in targetType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(static field => !field.IsPrivate)) { JsonPropertyAttribute? jsonProperty = field.GetCustomAttribute(); if (jsonProperty != null) { @@ -74,7 +74,7 @@ namespace ArchiSteamFarm.IPC.Controllers.Api { } } - foreach (PropertyInfo property in targetType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(property => property.CanRead && (property.GetMethod?.IsPrivate == false))) { + foreach (PropertyInfo property in targetType.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(static property => property.CanRead && (property.GetMethod?.IsPrivate == false))) { JsonPropertyAttribute? jsonProperty = property.GetCustomAttribute(); if (jsonProperty != null) { diff --git a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs index 2294ab425..f93013c67 100644 --- a/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs +++ b/ArchiSteamFarm/IPC/Integration/ApiAuthenticationMiddleware.cs @@ -141,7 +141,7 @@ namespace ArchiSteamFarm.IPC.Integration { return (HttpStatusCode.Unauthorized, true); } - string? inputPassword = passwords.FirstOrDefault(password => !string.IsNullOrEmpty(password)); + string? inputPassword = passwords.FirstOrDefault(static password => !string.IsNullOrEmpty(password)); if (string.IsNullOrEmpty(inputPassword)) { return (HttpStatusCode.Unauthorized, true); diff --git a/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs b/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs index 6554979c3..1ee0689b6 100644 --- a/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs +++ b/ArchiSteamFarm/IPC/Integration/SwaggerValidValuesAttribute.cs @@ -40,11 +40,11 @@ namespace ArchiSteamFarm.IPC.Integration { OpenApiArray validValues = new(); if (ValidIntValues != null) { - validValues.AddRange(ValidIntValues.Select(type => new OpenApiInteger(type))); + validValues.AddRange(ValidIntValues.Select(static type => new OpenApiInteger(type))); } if (ValidStringValues != null) { - validValues.AddRange(ValidStringValues.Select(type => new OpenApiString(type))); + validValues.AddRange(ValidStringValues.Select(static type => new OpenApiString(type))); } if (schema.Items is { Reference: null }) { diff --git a/ArchiSteamFarm/IPC/Requests/TwoFactorAuthenticationConfirmationsRequest.cs b/ArchiSteamFarm/IPC/Requests/TwoFactorAuthenticationConfirmationsRequest.cs index 2678bfae4..d8988e5d4 100644 --- a/ArchiSteamFarm/IPC/Requests/TwoFactorAuthenticationConfirmationsRequest.cs +++ b/ArchiSteamFarm/IPC/Requests/TwoFactorAuthenticationConfirmationsRequest.cs @@ -56,7 +56,7 @@ namespace ArchiSteamFarm.IPC.Requests { /// [JsonProperty(PropertyName = SharedInfo.UlongCompatibilityStringPrefix + nameof(AcceptedCreatorIDs), Required = Required.DisallowNull)] public ImmutableHashSet SAcceptedCreatorIDs { - get => AcceptedCreatorIDs.Select(creatorID => creatorID.ToString(CultureInfo.InvariantCulture)).ToImmutableHashSet(); + get => AcceptedCreatorIDs.Select(static creatorID => creatorID.ToString(CultureInfo.InvariantCulture)).ToImmutableHashSet(); set { if (value == null) { throw new ArgumentNullException(nameof(value)); diff --git a/ArchiSteamFarm/IPC/Startup.cs b/ArchiSteamFarm/IPC/Startup.cs index 4a9bd347b..d7402cae8 100644 --- a/ArchiSteamFarm/IPC/Startup.cs +++ b/ArchiSteamFarm/IPC/Startup.cs @@ -98,7 +98,7 @@ namespace ArchiSteamFarm.IPC { // The default HTML file (usually index.html) is responsible for IPC GUI routing, so re-execute all non-API calls on / // This must be called before default files, because we don't know the exact file name that will be used for index page - app.UseWhen(context => !context.Request.Path.StartsWithSegments("/Api", StringComparison.OrdinalIgnoreCase), appBuilder => appBuilder.UseStatusCodePagesWithReExecute("/")); + app.UseWhen(static context => !context.Request.Path.StartsWithSegments("/Api", StringComparison.OrdinalIgnoreCase), static appBuilder => appBuilder.UseStatusCodePagesWithReExecute("/")); // Add support for default root path redirection (GET / -> GET /index.html), must come before static files app.UseDefaultFiles(); @@ -106,7 +106,7 @@ namespace ArchiSteamFarm.IPC { // Add support for static files (e.g. HTML, CSS and JS from IPC GUI) app.UseStaticFiles( new StaticFileOptions { - OnPrepareResponse = context => { + OnPrepareResponse = static context => { if (context.File.Exists && !context.File.IsDirectory && !string.IsNullOrEmpty(context.File.Name)) { string extension = Path.GetExtension(context.File.Name); @@ -146,7 +146,7 @@ namespace ArchiSteamFarm.IPC { #endif // We want to protect our API with IPCPassword and additional security, this should be called after routing, so the middleware won't have to deal with API endpoints that do not exist - app.UseWhen(context => context.Request.Path.StartsWithSegments("/Api", StringComparison.OrdinalIgnoreCase), appBuilder => appBuilder.UseMiddleware()); + app.UseWhen(static context => context.Request.Path.StartsWithSegments("/Api", StringComparison.OrdinalIgnoreCase), static appBuilder => appBuilder.UseMiddleware()); string? ipcPassword = ASF.GlobalConfig != null ? ASF.GlobalConfig.IPCPassword : GlobalConfig.DefaultIPCPassword; @@ -163,7 +163,7 @@ namespace ArchiSteamFarm.IPC { #if NETFRAMEWORK app.UseMvcWithDefaultRoute(); #else - app.UseEndpoints(endpoints => endpoints.MapControllers()); + app.UseEndpoints(static endpoints => endpoints.MapControllers()); #endif // Add support for swagger, responsible for automatic API documentation generation, this should be on the end, once we're done with API @@ -171,7 +171,7 @@ namespace ArchiSteamFarm.IPC { // Add support for swagger UI, this should be after swagger, obviously app.UseSwaggerUI( - options => { + static options => { options.DisplayRequestDuration(); options.EnableDeepLinking(); options.ShowExtensions(); @@ -237,12 +237,12 @@ namespace ArchiSteamFarm.IPC { if (!string.IsNullOrEmpty(ipcPassword)) { // We want to apply CORS policy in order to allow userscripts and other third-party integrations to communicate with ASF API // We apply CORS policy only with IPCPassword set as an extra authentication measure - services.AddCors(options => options.AddDefaultPolicy(policyBuilder => policyBuilder.AllowAnyOrigin())); + services.AddCors(static options => options.AddDefaultPolicy(static policyBuilder => policyBuilder.AllowAnyOrigin())); } // Add support for swagger, responsible for automatic API documentation generation services.AddSwaggerGen( - options => { + static options => { options.AddSecurityDefinition( nameof(GlobalConfig.IPCPassword), new OpenApiSecurityScheme { Description = $"{nameof(GlobalConfig.IPCPassword)} authentication using request headers. Check {SharedInfo.ProjectURL}/wiki/IPC#authentication for more info.", @@ -267,7 +267,7 @@ namespace ArchiSteamFarm.IPC { } ); - options.CustomSchemaIds(type => type.GetUnifiedName()); + options.CustomSchemaIds(static type => type.GetUnifiedName()); options.EnableAnnotations(true, true); options.SchemaFilter(); @@ -339,7 +339,7 @@ namespace ArchiSteamFarm.IPC { #else mvc.AddNewtonsoftJson( #endif - options => { + static options => { // Fix default contract resolver to use original names and not a camel case options.SerializerSettings.ContractResolver = new DefaultContractResolver(); diff --git a/ArchiSteamFarm/IPC/WebUtilities.cs b/ArchiSteamFarm/IPC/WebUtilities.cs index b5f84a1be..242c633f8 100644 --- a/ArchiSteamFarm/IPC/WebUtilities.cs +++ b/ArchiSteamFarm/IPC/WebUtilities.cs @@ -37,7 +37,7 @@ namespace ArchiSteamFarm.IPC { throw new ArgumentNullException(nameof(type)); } - return type.GenericTypeArguments.Length == 0 ? type.FullName : $"{type.Namespace}.{type.Name}{string.Join("", type.GenericTypeArguments.Select(innerType => $"[{innerType.GetUnifiedName()}]"))}"; + return type.GenericTypeArguments.Length == 0 ? type.FullName : $"{type.Namespace}.{type.Name}{string.Join("", type.GenericTypeArguments.Select(static innerType => $"[{innerType.GetUnifiedName()}]"))}"; } internal static Type? ParseType(string typeText) { diff --git a/ArchiSteamFarm/NLog/Logging.cs b/ArchiSteamFarm/NLog/Logging.cs index 9e688ee34..b0a4bf142 100644 --- a/ArchiSteamFarm/NLog/Logging.cs +++ b/ArchiSteamFarm/NLog/Logging.cs @@ -61,7 +61,7 @@ namespace ArchiSteamFarm.NLog { bool reload = false; - foreach (LoggingRule rule in LogManager.Configuration.LoggingRules.Where(rule => rule.IsLoggingEnabledForLevel(LogLevel.Debug) && !rule.IsLoggingEnabledForLevel(LogLevel.Trace))) { + foreach (LoggingRule rule in LogManager.Configuration.LoggingRules.Where(static rule => rule.IsLoggingEnabledForLevel(LogLevel.Debug) && !rule.IsLoggingEnabledForLevel(LogLevel.Trace))) { rule.EnableLoggingForLevel(LogLevel.Trace); reload = true; } @@ -344,7 +344,7 @@ namespace ArchiSteamFarm.NLog { command = command[commandPrefix.Length..]; } - Bot? targetBot = Bot.Bots?.OrderBy(bot => bot.Key, Bot.BotsComparer).Select(bot => bot.Value).FirstOrDefault(); + Bot? targetBot = Bot.Bots?.OrderBy(static bot => bot.Key, Bot.BotsComparer).Select(static bot => bot.Value).FirstOrDefault(); if (targetBot == null) { Console.WriteLine($@"<< {Strings.ErrorNoBotsDefined}"); @@ -385,7 +385,7 @@ namespace ArchiSteamFarm.NLog { private static void InitConsoleLoggers() { ConsoleLoggingRules.Clear(); - foreach (LoggingRule loggingRule in LogManager.Configuration.LoggingRules.Where(loggingRule => loggingRule.Targets.Any(target => target is ColoredConsoleTarget or ConsoleTarget))) { + foreach (LoggingRule loggingRule in LogManager.Configuration.LoggingRules.Where(static loggingRule => loggingRule.Targets.Any(static target => target is ColoredConsoleTarget or ConsoleTarget))) { ConsoleLoggingRules.Add(loggingRule); } } @@ -414,7 +414,7 @@ namespace ArchiSteamFarm.NLog { bool reconfigure = false; - foreach (LoggingRule consoleLoggingRule in ConsoleLoggingRules.Where(consoleLoggingRule => !LogManager.Configuration.LoggingRules.Contains(consoleLoggingRule))) { + foreach (LoggingRule consoleLoggingRule in ConsoleLoggingRules.Where(static consoleLoggingRule => !LogManager.Configuration.LoggingRules.Contains(consoleLoggingRule))) { LogManager.Configuration.LoggingRules.Add(consoleLoggingRule); reconfigure = true; } @@ -433,7 +433,7 @@ namespace ArchiSteamFarm.NLog { bool reconfigure = false; - foreach (LoggingRule _ in ConsoleLoggingRules.Where(consoleLoggingRule => LogManager.Configuration.LoggingRules.Remove(consoleLoggingRule))) { + foreach (LoggingRule _ in ConsoleLoggingRules.Where(static consoleLoggingRule => LogManager.Configuration.LoggingRules.Remove(consoleLoggingRule))) { reconfigure = true; } diff --git a/ArchiSteamFarm/NLog/Targets/SteamTarget.cs b/ArchiSteamFarm/NLog/Targets/SteamTarget.cs index f36916230..bdb95e018 100644 --- a/ArchiSteamFarm/NLog/Targets/SteamTarget.cs +++ b/ArchiSteamFarm/NLog/Targets/SteamTarget.cs @@ -106,7 +106,7 @@ namespace ArchiSteamFarm.NLog.Targets { } if (bot == null) { - bot = Bot.Bots?.Values.FirstOrDefault(targetBot => targetBot.IsConnectedAndLoggedOn); + bot = Bot.Bots?.Values.FirstOrDefault(static targetBot => targetBot.IsConnectedAndLoggedOn); if (bot == null) { return; diff --git a/ArchiSteamFarm/Plugins/PluginsCore.cs b/ArchiSteamFarm/Plugins/PluginsCore.cs index 3534a0216..957d1d359 100644 --- a/ArchiSteamFarm/Plugins/PluginsCore.cs +++ b/ArchiSteamFarm/Plugins/PluginsCore.cs @@ -43,7 +43,7 @@ using SteamKit2; namespace ArchiSteamFarm.Plugins { internal static class PluginsCore { - internal static bool HasCustomPluginsLoaded => ActivePlugins?.Any(plugin => plugin is not OfficialPlugin officialPlugin || !officialPlugin.HasSameVersion()) == true; + internal static bool HasCustomPluginsLoaded => ActivePlugins?.Any(static plugin => plugin is not OfficialPlugin officialPlugin || !officialPlugin.HasSameVersion()) == true; [ImportMany] internal static ImmutableHashSet? ActivePlugins { get; private set; } @@ -56,7 +56,7 @@ namespace ArchiSteamFarm.Plugins { IList results; try { - results = await Utilities.InParallel(ActivePlugins.OfType().Select(plugin => Task.Run(() => plugin.BotsComparer))).ConfigureAwait(false); + results = await Utilities.InParallel(ActivePlugins.OfType().Select(static plugin => Task.Run(() => plugin.BotsComparer))).ConfigureAwait(false); } catch (Exception e) { ASF.ArchiLogger.LogGenericException(e); @@ -78,7 +78,7 @@ namespace ArchiSteamFarm.Plugins { IList results; try { - results = await Utilities.InParallel(ActivePlugins.OfType().Select(plugin => plugin.GetPreferredChangeNumberToStartFrom())).ConfigureAwait(false); + results = await Utilities.InParallel(ActivePlugins.OfType().Select(static plugin => plugin.GetPreferredChangeNumberToStartFrom())).ConfigureAwait(false); } catch (Exception e) { ASF.ArchiLogger.LogGenericException(e); @@ -113,7 +113,7 @@ namespace ArchiSteamFarm.Plugins { return new CrossProcessFileBasedSemaphore(resourceName); } - return responses.FirstOrDefault(response => response != null) ?? new CrossProcessFileBasedSemaphore(resourceName); + return responses.FirstOrDefault(static response => response != null) ?? new CrossProcessFileBasedSemaphore(resourceName); } internal static bool InitPlugins() { @@ -276,7 +276,7 @@ namespace ArchiSteamFarm.Plugins { return null; } - return string.Join(Environment.NewLine, responses.Where(response => !string.IsNullOrEmpty(response))); + return string.Join(Environment.NewLine, responses.Where(static response => !string.IsNullOrEmpty(response))); } internal static async Task OnBotDestroy(Bot bot) { @@ -382,7 +382,7 @@ namespace ArchiSteamFarm.Plugins { return false; } - return responses.Any(response => response); + return responses.Any(static response => response); } internal static async Task OnBotInit(Bot bot) { @@ -460,7 +460,7 @@ namespace ArchiSteamFarm.Plugins { return null; } - return string.Join(Environment.NewLine, responses.Where(response => !string.IsNullOrEmpty(response))); + return string.Join(Environment.NewLine, responses.Where(static response => !string.IsNullOrEmpty(response))); } internal static async Task OnBotSteamCallbacksInit(Bot bot, CallbackManager callbackManager) { @@ -502,7 +502,7 @@ namespace ArchiSteamFarm.Plugins { return null; } - return responses.Where(response => response != null).SelectMany(handlers => handlers ?? Enumerable.Empty()).ToHashSet(); + return responses.Where(static response => response != null).SelectMany(static handlers => handlers ?? Enumerable.Empty()).ToHashSet(); } internal static async Task OnBotTradeOffer(Bot bot, TradeOffer tradeOffer) { @@ -528,7 +528,7 @@ namespace ArchiSteamFarm.Plugins { return false; } - return responses.Any(response => response); + return responses.Any(static response => response); } internal static async Task OnBotTradeOfferResults(Bot bot, IReadOnlyCollection tradeResults) { diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index ed75f90c4..16819300b 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -412,7 +412,7 @@ namespace ArchiSteamFarm { // Stop all the active bots so they can disconnect cleanly if (Bot.Bots?.Count > 0) { // Stop() function can block due to SK2 sockets, don't forget a maximum delay - await Task.WhenAny(Utilities.InParallel(Bot.Bots.Values.Select(bot => Task.Run(() => bot.Stop(true)))), Task.Delay(Bot.Bots.Count * WebBrowser.MaxTries * 1000)).ConfigureAwait(false); + await Task.WhenAny(Utilities.InParallel(Bot.Bots.Values.Select(static bot => Task.Run(() => bot.Stop(true)))), Task.Delay(Bot.Bots.Count * WebBrowser.MaxTries * 1000)).ConfigureAwait(false); // Extra second for Steam requests to go through await Task.Delay(1000).ConfigureAwait(false); diff --git a/ArchiSteamFarm/Steam/Bot.cs b/ArchiSteamFarm/Steam/Bot.cs index 28d16c329..b3bbdb5f5 100644 --- a/ArchiSteamFarm/Steam/Bot.cs +++ b/ArchiSteamFarm/Steam/Bot.cs @@ -393,7 +393,7 @@ namespace ArchiSteamFarm.Steam { public async Task DeleteAllRelatedFiles() { await BotDatabase.MakeReadOnly().ConfigureAwait(false); - foreach (string filePath in RelatedFiles.Select(file => file.FilePath).Where(File.Exists)) { + foreach (string filePath in RelatedFiles.Select(static file => file.FilePath).Where(File.Exists)) { try { File.Delete(filePath); } catch (Exception e) { @@ -443,7 +443,7 @@ namespace ArchiSteamFarm.Steam { foreach (string botName in botNames) { if (botName.Equals(SharedInfo.ASF, StringComparison.OrdinalIgnoreCase)) { - IEnumerable allBots = Bots.OrderBy(bot => bot.Key, BotsComparer).Select(bot => bot.Value); + IEnumerable allBots = Bots.OrderBy(static bot => bot.Key, BotsComparer).Select(static bot => bot.Value); result.UnionWith(allBots); return result; @@ -459,7 +459,7 @@ namespace ArchiSteamFarm.Steam { Bot? lastBot = GetBot(botRange[1]); if (lastBot != null) { - foreach (Bot bot in Bots.OrderBy(bot => bot.Key, BotsComparer).Select(bot => bot.Value).SkipWhile(bot => bot != firstBot)) { + foreach (Bot bot in Bots.OrderBy(static bot => bot.Key, BotsComparer).Select(static bot => bot.Value).SkipWhile(bot => bot != firstBot)) { result.Add(bot); if (bot == lastBot) { @@ -494,7 +494,7 @@ namespace ArchiSteamFarm.Steam { return null; } - IEnumerable regexMatches = Bots.Where(kvp => regex.IsMatch(kvp.Key)).Select(kvp => kvp.Value); + IEnumerable regexMatches = Bots.Where(kvp => regex.IsMatch(kvp.Key)).Select(static kvp => kvp.Value); result.UnionWith(regexMatches); continue; @@ -560,9 +560,9 @@ namespace ArchiSteamFarm.Steam { } HashSet result = new(); - Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), Dictionary>> itemsPerClassIDPerSet = inventory.GroupBy(item => (item.RealAppID, item.Type, item.Rarity)).ToDictionary(grouping => grouping.Key, grouping => grouping.GroupBy(item => item.ClassID).ToDictionary(group => group.Key, group => group.ToHashSet())); + Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), Dictionary>> itemsPerClassIDPerSet = inventory.GroupBy(static item => (item.RealAppID, item.Type, item.Rarity)).ToDictionary(static grouping => grouping.Key, static grouping => grouping.GroupBy(static item => item.ClassID).ToDictionary(static group => group.Key, static group => group.ToHashSet())); - foreach (((uint RealAppID, Asset.EType Type, Asset.ERarity Rarity) set, (uint setsToExtract, byte itemsPerSet)) in amountsToExtract.OrderBy(kv => kv.Value.ItemsPerSet)) { + foreach (((uint RealAppID, Asset.EType Type, Asset.ERarity Rarity) set, (uint setsToExtract, byte itemsPerSet)) in amountsToExtract.OrderBy(static kv => kv.Value.ItemsPerSet)) { if (!itemsPerClassIDPerSet.TryGetValue(set, out Dictionary>? itemsPerClassID)) { continue; } @@ -769,7 +769,7 @@ namespace ArchiSteamFarm.Steam { IEnumerable> tasks = uniqueAppIDs.Select(async appID => (AppID: appID, Cards: await ArchiWebHandler.GetCardCountForGame(appID).ConfigureAwait(false))); IList<(uint AppID, byte Cards)> results = await Utilities.InParallel(tasks).ConfigureAwait(false); - return results.All(tuple => tuple.Cards > 0) ? results.ToDictionary(res => res.AppID, res => res.Cards) : null; + return results.All(static tuple => tuple.Cards > 0) ? results.ToDictionary(static res => res.AppID, static res => res.Cards) : null; } } @@ -885,7 +885,7 @@ namespace ArchiSteamFarm.Steam { inputValue = inputValue.ToUpperInvariant(); - if (inputValue.Any(character => !MobileAuthenticator.CodeCharacters.Contains(character))) { + if (inputValue.Any(static character => !MobileAuthenticator.CodeCharacters.Contains(character))) { return false; } @@ -1055,7 +1055,7 @@ namespace ArchiSteamFarm.Steam { return (optimisticDiscovery ? appID : 0, DateTime.MinValue, true); } - foreach (Dictionary productInfoApps in productInfoResultSet.Results.Select(result => result.Apps)) { + foreach (Dictionary productInfoApps in productInfoResultSet.Results.Select(static result => result.Apps)) { if (!productInfoApps.TryGetValue(appID, out SteamApps.PICSProductInfoCallback.PICSProductInfo? productInfoApp)) { continue; } @@ -1199,7 +1199,7 @@ namespace ArchiSteamFarm.Steam { Dictionary? AppIDs)> result = new(); - foreach (SteamApps.PICSProductInfoCallback.PICSProductInfo productInfo in productInfoResultSet.Results.SelectMany(productInfoResult => productInfoResult.Packages).Where(productInfoPackages => productInfoPackages.Key != 0).Select(productInfoPackages => productInfoPackages.Value)) { + foreach (SteamApps.PICSProductInfoCallback.PICSProductInfo productInfo in productInfoResultSet.Results.SelectMany(static productInfoResult => productInfoResult.Packages).Where(static productInfoPackages => productInfoPackages.Key != 0).Select(static productInfoPackages => productInfoPackages.Value)) { if (productInfo.KeyValues == KeyValue.Invalid) { ArchiLogger.LogNullError(nameof(productInfo)); @@ -1218,7 +1218,7 @@ namespace ArchiSteamFarm.Steam { appIDs = new HashSet(appIDsKv.Children.Count); - foreach (string? appIDText in appIDsKv.Children.Select(app => app.Value)) { + foreach (string? appIDText in appIDsKv.Children.Select(static app => app.Value)) { if (!uint.TryParse(appIDText, out uint appID) || (appID == 0)) { ArchiLogger.LogNullError(nameof(appID)); @@ -1281,10 +1281,10 @@ namespace ArchiSteamFarm.Steam { string? gameName = null; if (!string.IsNullOrEmpty(BotConfig.CustomGamePlayedWhileFarming)) { - gameName = string.Format(CultureInfo.CurrentCulture, BotConfig.CustomGamePlayedWhileFarming!, string.Join(", ", games.Select(game => game.AppID)), string.Join(", ", games.Select(game => game.GameName))); + gameName = string.Format(CultureInfo.CurrentCulture, BotConfig.CustomGamePlayedWhileFarming!, string.Join(", ", games.Select(static game => game.AppID)), string.Join(", ", games.Select(static game => game.GameName))); } - await ArchiHandler.PlayGames(games.Select(game => game.PlayableAppID).ToHashSet(), gameName).ConfigureAwait(false); + await ArchiHandler.PlayGames(games.Select(static game => game.PlayableAppID).ToHashSet(), gameName).ConfigureAwait(false); } internal async Task ImportKeysToRedeem(string filePath) { @@ -1586,7 +1586,7 @@ namespace ArchiSteamFarm.Steam { await BotDatabase.MakeReadOnly().ConfigureAwait(false); // We handle the config file last as it'll trigger new bot creation - foreach ((string filePath, EFileType fileType) in RelatedFiles.Where(file => File.Exists(file.FilePath)).OrderByDescending(file => file.FileType != EFileType.Config)) { + foreach ((string filePath, EFileType fileType) in RelatedFiles.Where(static file => File.Exists(file.FilePath)).OrderByDescending(static file => file.FileType != EFileType.Config)) { string newFilePath = GetFilePath(newBotName, fileType); if (string.IsNullOrEmpty(newFilePath)) { @@ -1840,7 +1840,7 @@ namespace ArchiSteamFarm.Steam { HashSet result = new(); - foreach (string? badgeUri in linkElements.Select(htmlNode => htmlNode.GetAttribute("href"))) { + foreach (string? badgeUri in linkElements.Select(static htmlNode => htmlNode.GetAttribute("href"))) { if (string.IsNullOrEmpty(badgeUri)) { ArchiLogger.LogNullError(nameof(badgeUri)); @@ -2030,7 +2030,7 @@ namespace ArchiSteamFarm.Steam { SendItemsTimer = null; } - if ((BotConfig.SendTradePeriod > 0) && (BotConfig.LootableTypes.Count > 0) && BotConfig.SteamUserPermissions.Values.Any(permission => permission >= BotConfig.EAccess.Master)) { + if ((BotConfig.SendTradePeriod > 0) && (BotConfig.LootableTypes.Count > 0) && BotConfig.SteamUserPermissions.Values.Any(static permission => permission >= BotConfig.EAccess.Master)) { SendItemsTimer = new Timer( OnSendItemsTimer, null, @@ -2376,7 +2376,7 @@ namespace ArchiSteamFarm.Steam { throw new ArgumentNullException(nameof(callback)); } - foreach (SteamFriends.FriendsListCallback.Friend friend in callback.FriendList.Where(friend => friend.Relationship == EFriendRelationship.RequestRecipient)) { + foreach (SteamFriends.FriendsListCallback.Friend friend in callback.FriendList.Where(static friend => friend.Relationship == EFriendRelationship.RequestRecipient)) { switch (friend.SteamID.AccountType) { case EAccountType.Clan when IsMasterClanID(friend.SteamID): ArchiLogger.LogInvite(friend.SteamID, true); @@ -2461,7 +2461,7 @@ namespace ArchiSteamFarm.Steam { return; } - HashSet guestPassIDs = callback.GuestPasses.Select(guestPass => guestPass["gid"].AsUnsignedLong()).Where(gid => gid != 0).ToHashSet(); + HashSet guestPassIDs = callback.GuestPasses.Select(static guestPass => guestPass["gid"].AsUnsignedLong()).Where(static gid => gid != 0).ToHashSet(); if (guestPassIDs.Count == 0) { return; @@ -2601,7 +2601,7 @@ namespace ArchiSteamFarm.Steam { Dictionary packageAccessTokens = new(); Dictionary packagesToRefresh = new(); - foreach (SteamApps.LicenseListCallback.License license in callback.LicenseList.GroupBy(license => license.PackageID, (_, licenses) => licenses.OrderByDescending(license => license.TimeCreated).First())) { + foreach (SteamApps.LicenseListCallback.License license in callback.LicenseList.GroupBy(static license => license.PackageID, static (_, licenses) => licenses.OrderByDescending(static license => license.TimeCreated).First())) { ownedPackageIDs[license.PackageID] = (license.PaymentMethod, license.TimeCreated); if (!ASF.GlobalDatabase.PackageAccessTokensReadOnly.TryGetValue(license.PackageID, out ulong packageAccessToken) || (packageAccessToken != license.AccessToken)) { @@ -2988,12 +2988,12 @@ namespace ArchiSteamFarm.Steam { string? avatarHash = null; - if ((callback.AvatarHash.Length > 0) && callback.AvatarHash.Any(singleByte => singleByte != 0)) { + if ((callback.AvatarHash.Length > 0) && callback.AvatarHash.Any(static singleByte => singleByte != 0)) { #pragma warning disable CA1308 // False positive, we're intentionally converting this part to lowercase and it's not used for any security decisions based on the result of the normalization avatarHash = BitConverter.ToString(callback.AvatarHash).Replace("-", "", StringComparison.Ordinal).ToLowerInvariant(); #pragma warning restore CA1308 // False positive, we're intentionally converting this part to lowercase and it's not used for any security decisions based on the result of the normalization - if (string.IsNullOrEmpty(avatarHash) || avatarHash.All(singleChar => singleChar == '0')) { + if (string.IsNullOrEmpty(avatarHash) || avatarHash.All(static singleChar => singleChar == '0')) { avatarHash = null; } } @@ -3331,7 +3331,7 @@ namespace ArchiSteamFarm.Steam { } Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), List> inventorySets = Trading.GetInventorySets(inventory); - appIDs.IntersectWith(inventorySets.Where(kv => kv.Value.Count >= MinCardsPerBadge).Select(kv => kv.Key.RealAppID)); + appIDs.IntersectWith(inventorySets.Where(static kv => kv.Value.Count >= MinCardsPerBadge).Select(static kv => kv.Key.RealAppID)); if (appIDs.Count == 0) { return; @@ -3343,9 +3343,9 @@ namespace ArchiSteamFarm.Steam { return; } - Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), (uint Sets, byte CardsPerSet)> itemsToTakePerInventorySet = inventorySets.Where(kv => appIDs.Contains(kv.Key.RealAppID)).ToDictionary(kv => kv.Key, kv => (kv.Value[0], cardCountPerAppID[kv.Key.RealAppID])); + Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), (uint Sets, byte CardsPerSet)> itemsToTakePerInventorySet = inventorySets.Where(kv => appIDs.Contains(kv.Key.RealAppID)).ToDictionary(static kv => kv.Key, kv => (kv.Value[0], cardCountPerAppID[kv.Key.RealAppID])); - if (itemsToTakePerInventorySet.Values.All(value => value.Sets == 0)) { + if (itemsToTakePerInventorySet.Values.All(static value => value.Sets == 0)) { return; } @@ -3474,7 +3474,7 @@ namespace ArchiSteamFarm.Steam { byte i = 0; byte[] password = new byte[steamParentalCode.Length]; - foreach (char character in steamParentalCode.TakeWhile(character => character is >= '0' and <= '9')) { + foreach (char character in steamParentalCode.TakeWhile(static character => character is >= '0' and <= '9')) { password[i++] = (byte) character; } diff --git a/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs b/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs index ca3527ee2..4aebb2b6e 100644 --- a/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs +++ b/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs @@ -73,7 +73,7 @@ namespace ArchiSteamFarm.Steam.Cards { public TimeSpan TimeRemaining => new( Bot.BotConfig.HoursUntilCardDrops > 0 ? (ushort) Math.Ceiling(GamesToFarm.Count / (float) ArchiHandler.MaxGamesPlayedConcurrently) * Bot.BotConfig.HoursUntilCardDrops : 0, - 30 * GamesToFarm.Sum(game => game.CardsRemaining), + 30 * GamesToFarm.Sum(static game => game.CardsRemaining), 0 ); @@ -176,7 +176,7 @@ namespace ArchiSteamFarm.Steam.Cards { // We should restart the farming if the order or efficiency of the farming could be affected by the newly-activated product // The order is affected when user uses farming order that isn't independent of the game data (it could alter the order in deterministic way if the game was considered in current queue) // The efficiency is affected only in complex algorithm (entirely), as it depends on hours order that is not independent (as specified above) - if ((Bot.BotConfig.HoursUntilCardDrops > 0) || ((Bot.BotConfig.FarmingOrders.Count > 0) && Bot.BotConfig.FarmingOrders.Any(farmingOrder => (farmingOrder != BotConfig.EFarmingOrder.Unordered) && (farmingOrder != BotConfig.EFarmingOrder.Random)))) { + if ((Bot.BotConfig.HoursUntilCardDrops > 0) || ((Bot.BotConfig.FarmingOrders.Count > 0) && Bot.BotConfig.FarmingOrders.Any(static farmingOrder => (farmingOrder != BotConfig.EFarmingOrder.Unordered) && (farmingOrder != BotConfig.EFarmingOrder.Random)))) { await StopFarming().ConfigureAwait(false); await StartFarming().ConfigureAwait(false); } @@ -731,7 +731,7 @@ namespace ArchiSteamFarm.Steam.Cards { private async Task Farm() { do { - Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.GamesToIdle, GamesToFarm.Count, GamesToFarm.Sum(game => game.CardsRemaining), TimeRemaining.ToHumanReadable())); + Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.GamesToIdle, GamesToFarm.Count, GamesToFarm.Sum(static game => game.CardsRemaining), TimeRemaining.ToHumanReadable())); // Now the algorithm used for farming depends on whether account is restricted or not if (Bot.BotConfig.HoursUntilCardDrops > 0) { @@ -768,7 +768,7 @@ namespace ArchiSteamFarm.Steam.Cards { // In order to maximize efficiency, we'll take games that are closest to our HoursPlayed first // We must call ToList() here as we can't remove items while enumerating - foreach (Game game in GamesToFarm.OrderByDescending(game => game.HoursPlayed).ToList()) { + foreach (Game game in GamesToFarm.OrderByDescending(static game => game.HoursPlayed).ToList()) { if (!await IsPlayableGame(game).ConfigureAwait(false)) { GamesToFarm.Remove(game); @@ -790,7 +790,7 @@ namespace ArchiSteamFarm.Steam.Cards { // Otherwise, we farm our innerGamesToFarm batch until any game hits HoursUntilCardDrops if (await FarmMultiple(innerGamesToFarm).ConfigureAwait(false)) { - Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.IdlingFinishedForGames, string.Join(", ", innerGamesToFarm.Select(game => game.AppID)))); + Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.IdlingFinishedForGames, string.Join(", ", innerGamesToFarm.Select(static game => game.AppID)))); } else { NowFarming = false; @@ -869,7 +869,7 @@ namespace ArchiSteamFarm.Steam.Cards { throw new ArgumentNullException(nameof(games)); } - float maxHour = games.Max(game => game.HoursPlayed); + float maxHour = games.Max(static game => game.HoursPlayed); if (maxHour < 0) { Bot.ArchiLogger.LogNullError(nameof(maxHour)); @@ -888,7 +888,7 @@ namespace ArchiSteamFarm.Steam.Cards { bool success = true; while (maxHour < Bot.BotConfig.HoursUntilCardDrops) { - Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.StillIdlingList, string.Join(", ", games.Select(game => game.AppID)))); + Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.StillIdlingList, string.Join(", ", games.Select(static game => game.AppID)))); DateTime startFarmingPeriod = DateTime.UtcNow; @@ -910,7 +910,7 @@ namespace ArchiSteamFarm.Steam.Cards { maxHour += timePlayed; } - Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.StoppedIdlingList, string.Join(", ", games.Select(game => game.AppID)))); + Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.StoppedIdlingList, string.Join(", ", games.Select(static game => game.AppID)))); return success; } @@ -926,7 +926,7 @@ namespace ArchiSteamFarm.Steam.Cards { Game game = games.First(); Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.NowIdling, game.AppID, game.GameName)); } else { - Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.NowIdlingList, string.Join(", ", games.Select(game => game.AppID)))); + Bot.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.NowIdlingList, string.Join(", ", games.Select(static game => game.AppID)))); } bool result = await FarmHours(games).ConfigureAwait(false); @@ -1125,27 +1125,27 @@ namespace ArchiSteamFarm.Steam.Cards { case BotConfig.EFarmingOrder.Unordered: break; case BotConfig.EFarmingOrder.AppIDsAscending: - orderedGamesToFarm = orderedGamesToFarm.ThenBy(game => game.AppID); + orderedGamesToFarm = orderedGamesToFarm.ThenBy(static game => game.AppID); break; case BotConfig.EFarmingOrder.AppIDsDescending: - orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(game => game.AppID); + orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(static game => game.AppID); break; case BotConfig.EFarmingOrder.BadgeLevelsAscending: - orderedGamesToFarm = orderedGamesToFarm.ThenBy(game => game.BadgeLevel); + orderedGamesToFarm = orderedGamesToFarm.ThenBy(static game => game.BadgeLevel); break; case BotConfig.EFarmingOrder.BadgeLevelsDescending: - orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(game => game.BadgeLevel); + orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(static game => game.BadgeLevel); break; case BotConfig.EFarmingOrder.CardDropsAscending: - orderedGamesToFarm = orderedGamesToFarm.ThenBy(game => game.CardsRemaining); + orderedGamesToFarm = orderedGamesToFarm.ThenBy(static game => game.CardsRemaining); break; case BotConfig.EFarmingOrder.CardDropsDescending: - orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(game => game.CardsRemaining); + orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(static game => game.CardsRemaining); break; case BotConfig.EFarmingOrder.MarketableAscending: @@ -1173,23 +1173,23 @@ namespace ArchiSteamFarm.Steam.Cards { break; case BotConfig.EFarmingOrder.HoursAscending: - orderedGamesToFarm = orderedGamesToFarm.ThenBy(game => game.HoursPlayed); + orderedGamesToFarm = orderedGamesToFarm.ThenBy(static game => game.HoursPlayed); break; case BotConfig.EFarmingOrder.HoursDescending: - orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(game => game.HoursPlayed); + orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(static game => game.HoursPlayed); break; case BotConfig.EFarmingOrder.NamesAscending: - orderedGamesToFarm = orderedGamesToFarm.ThenBy(game => game.GameName); + orderedGamesToFarm = orderedGamesToFarm.ThenBy(static game => game.GameName); break; case BotConfig.EFarmingOrder.NamesDescending: - orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(game => game.GameName); + orderedGamesToFarm = orderedGamesToFarm.ThenByDescending(static game => game.GameName); break; case BotConfig.EFarmingOrder.Random: - orderedGamesToFarm = orderedGamesToFarm.ThenBy(_ => Utilities.RandomNext()); + orderedGamesToFarm = orderedGamesToFarm.ThenBy(static _ => Utilities.RandomNext()); break; case BotConfig.EFarmingOrder.RedeemDateTimesAscending: diff --git a/ArchiSteamFarm/Steam/Exchange/ParseTradeResult.cs b/ArchiSteamFarm/Steam/Exchange/ParseTradeResult.cs index 6ed731c1d..b6fcb3453 100644 --- a/ArchiSteamFarm/Steam/Exchange/ParseTradeResult.cs +++ b/ArchiSteamFarm/Steam/Exchange/ParseTradeResult.cs @@ -50,7 +50,7 @@ namespace ArchiSteamFarm.Steam.Exchange { Result = result; if (itemsToReceive?.Count > 0) { - ReceivedItemTypes = itemsToReceive.Select(item => item.Type).ToImmutableHashSet(); + ReceivedItemTypes = itemsToReceive.Select(static item => item.Type).ToImmutableHashSet(); } } diff --git a/ArchiSteamFarm/Steam/Exchange/Trading.cs b/ArchiSteamFarm/Steam/Exchange/Trading.cs index 8f7e4bf03..50b7b42fc 100644 --- a/ArchiSteamFarm/Steam/Exchange/Trading.cs +++ b/ArchiSteamFarm/Steam/Exchange/Trading.cs @@ -63,7 +63,7 @@ namespace ArchiSteamFarm.Steam.Exchange { Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), Dictionary> sets = GetInventoryState(inventory); - return sets.ToDictionary(set => set.Key, set => set.Value.Values.OrderBy(amount => amount).ToList()); + return sets.ToDictionary(static set => set.Key, static set => set.Value.Values.OrderBy(static amount => amount).ToList()); } [PublicAPI] @@ -248,7 +248,7 @@ namespace ArchiSteamFarm.Steam.Exchange { Dictionary<(uint RealAppID, Asset.EType Type, Asset.ERarity Rarity), Dictionary> tradableState = new(); - foreach (Asset item in inventory.Where(item => item.Tradable)) { + foreach (Asset item in inventory.Where(static item => item.Tradable)) { (uint RealAppID, Asset.EType Type, Asset.ERarity Rarity) key = (item.RealAppID, item.Type, item.Rarity); if (tradableState.TryGetValue(key, out Dictionary? tradableSet)) { @@ -272,7 +272,7 @@ namespace ArchiSteamFarm.Steam.Exchange { HashSet result = new(); - foreach (Asset item in inventory.Where(item => item.Tradable)) { + foreach (Asset item in inventory.Where(static item => item.Tradable)) { if (!classIDs.TryGetValue(item.ClassID, out uint amount)) { continue; } @@ -415,14 +415,14 @@ namespace ArchiSteamFarm.Steam.Exchange { } if (HandledTradeOfferIDs.Count > 0) { - HandledTradeOfferIDs.IntersectWith(tradeOffers.Select(tradeOffer => tradeOffer.TradeOfferID)); + HandledTradeOfferIDs.IntersectWith(tradeOffers.Select(static tradeOffer => tradeOffer.TradeOfferID)); } IEnumerable> tasks = tradeOffers.Where(tradeOffer => !HandledTradeOfferIDs.Contains(tradeOffer.TradeOfferID)).Select(ParseTrade); IList<(ParseTradeResult? TradeResult, bool RequiresMobileConfirmation)> results = await Utilities.InParallel(tasks).ConfigureAwait(false); if (Bot.HasMobileAuthenticator) { - HashSet mobileTradeOfferIDs = results.Where(result => (result.TradeResult?.Result == ParseTradeResult.EResult.Accepted) && result.RequiresMobileConfirmation).Select(result => result.TradeResult!.TradeOfferID).ToHashSet(); + HashSet mobileTradeOfferIDs = results.Where(static result => (result.TradeResult?.Result == ParseTradeResult.EResult.Accepted) && result.RequiresMobileConfirmation).Select(static result => result.TradeResult!.TradeOfferID).ToHashSet(); if (mobileTradeOfferIDs.Count > 0) { (bool twoFactorSuccess, _, _) = await Bot.Actions.HandleTwoFactorAuthenticationConfirmations(true, Confirmation.EType.Trade, mobileTradeOfferIDs, true).ConfigureAwait(false); @@ -435,7 +435,7 @@ namespace ArchiSteamFarm.Steam.Exchange { } } - HashSet validTradeResults = results.Where(result => result.TradeResult != null).Select(result => result.TradeResult!).ToHashSet(); + HashSet validTradeResults = results.Where(static result => result.TradeResult != null).Select(static result => result.TradeResult!).ToHashSet(); if (validTradeResults.Count > 0) { await PluginsCore.OnBotTradeOfferResults(Bot, validTradeResults).ConfigureAwait(false); @@ -489,7 +489,7 @@ namespace ArchiSteamFarm.Steam.Exchange { goto case ParseTradeResult.EResult.TryAgain; } - if (tradeOffer.ItemsToReceive.Sum(item => item.Amount) > tradeOffer.ItemsToGive.Sum(item => item.Amount)) { + if (tradeOffer.ItemsToReceive.Sum(static item => item.Amount) > tradeOffer.ItemsToGive.Sum(static item => item.Amount)) { Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.BotAcceptedDonationTrade, tradeOffer.TradeOfferID)); } @@ -625,7 +625,7 @@ namespace ArchiSteamFarm.Steam.Exchange { // If user has a trade hold, we add extra logic // If trade hold duration exceeds our max, or user asks for cards with short lifespan, reject the trade - case > 0 when (holdDuration.Value > ASF.GlobalConfig.MaxTradeHoldDuration) || tradeOffer.ItemsToGive.Any(item => item.Type is Asset.EType.FoilTradingCard or Asset.EType.TradingCard && CardsFarmer.SalesBlacklist.Contains(item.RealAppID)): + case > 0 when (holdDuration.Value > ASF.GlobalConfig.MaxTradeHoldDuration) || tradeOffer.ItemsToGive.Any(static item => item.Type is Asset.EType.FoilTradingCard or Asset.EType.TradingCard && CardsFarmer.SalesBlacklist.Contains(item.RealAppID)): Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Rejected, $"{nameof(holdDuration)} > 0: {holdDuration.Value}")); return ParseTradeResult.EResult.Rejected; @@ -672,7 +672,7 @@ namespace ArchiSteamFarm.Steam.Exchange { return ParseTradeResult.EResult.TryAgain; } - bool accept = IsTradeNeutralOrBetter(inventory, tradeOffer.ItemsToGive.Select(item => item.CreateShallowCopy()).ToHashSet(), tradeOffer.ItemsToReceive.Select(item => item.CreateShallowCopy()).ToHashSet()); + bool accept = IsTradeNeutralOrBetter(inventory, tradeOffer.ItemsToGive.Select(static item => item.CreateShallowCopy()).ToHashSet(), tradeOffer.ItemsToReceive.Select(static item => item.CreateShallowCopy()).ToHashSet()); // We're now sure whether the trade is neutral+ for us or not ParseTradeResult.EResult acceptResult = accept ? ParseTradeResult.EResult.Accepted : ParseTradeResult.EResult.Rejected; diff --git a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs index 747ac0c1b..27324f742 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs @@ -127,7 +127,7 @@ namespace ArchiSteamFarm.Steam.Integration { CPlayer_GetOwnedGames_Response body = response.GetDeserializedResponse(); - return body.games.ToDictionary(game => (uint) game.appid, game => game.name); + return body.games.ToDictionary(static game => (uint) game.appid, static game => game.name); } public override void HandleMsg(IPacketMsg packetMsg) { @@ -385,7 +385,7 @@ namespace ArchiSteamFarm.Steam.Integration { CChatRoom_GetMyChatRoomGroups_Response body = response.GetDeserializedResponse(); - return body.chat_room_groups.Select(chatRoom => chatRoom.group_summary.chat_group_id).ToHashSet(); + return body.chat_room_groups.Select(static chatRoom => chatRoom.group_summary.chat_group_id).ToHashSet(); } internal async Task GetPrivacySettings() { @@ -555,7 +555,7 @@ namespace ArchiSteamFarm.Steam.Integration { if (gameIDs.Count > 0) { #pragma warning disable CA1508 // False positive, not every IReadOnlyCollection is ISet - IEnumerable uniqueValidGameIDs = (gameIDs as ISet ?? gameIDs.Distinct()).Where(gameID => gameID > 0); + IEnumerable uniqueValidGameIDs = (gameIDs as ISet ?? gameIDs.Distinct()).Where(static gameID => gameID > 0); #pragma warning restore CA1508 // False positive, not every IReadOnlyCollection is ISet foreach (uint gameID in uniqueValidGameIDs) { diff --git a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs index 129c6519e..641b28662 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs @@ -1662,7 +1662,7 @@ namespace ArchiSteamFarm.Steam.Integration { HashSet result = new(apps.Count); - foreach (uint appID in apps.Select(app => app["appid"].AsUnsignedInteger())) { + foreach (uint appID in apps.Select(static app => app["appid"].AsUnsignedInteger())) { if (appID == 0) { Bot.ArchiLogger.LogNullError(nameof(appID)); @@ -1766,7 +1766,7 @@ namespace ArchiSteamFarm.Steam.Integration { HashSet results = new(); - foreach (string? giftCardIDText in htmlNodes.Select(node => node.GetAttribute("id"))) { + foreach (string? giftCardIDText in htmlNodes.Select(static node => node.GetAttribute("id"))) { if (string.IsNullOrEmpty(giftCardIDText)) { Bot.ArchiLogger.LogNullError(nameof(giftCardIDText)); @@ -1812,7 +1812,7 @@ namespace ArchiSteamFarm.Steam.Integration { HashSet result = new(); - foreach (string? miniProfile in htmlNodes.Select(htmlNode => htmlNode.GetAttribute("data-miniprofile"))) { + foreach (string? miniProfile in htmlNodes.Select(static htmlNode => htmlNode.GetAttribute("data-miniprofile"))) { if (string.IsNullOrEmpty(miniProfile)) { Bot.ArchiLogger.LogNullError(nameof(miniProfile)); @@ -2681,7 +2681,7 @@ namespace ArchiSteamFarm.Steam.Integration { bool[] results = await Task.WhenAll(UnlockParentalAccountForService(SteamCommunityURL, parentalCode), UnlockParentalAccountForService(SteamStoreURL, parentalCode)).ConfigureAwait(false); - if (results.Any(result => !result)) { + if (results.Any(static result => !result)) { Bot.ArchiLogger.LogGenericWarning(Strings.WarningFailed); return false; diff --git a/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs b/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs index d121d5222..d2dc47f92 100644 --- a/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs +++ b/ArchiSteamFarm/Steam/Integration/SteamChatMessage.cs @@ -222,7 +222,7 @@ namespace ArchiSteamFarm.Steam.Integration { string[] prefixLines = escapedSteamMessagePrefix.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); - return prefixLines.Where(prefixLine => prefixLine.Length > 0).Sum(Encoding.UTF8.GetByteCount) + ((prefixLines.Length - 1) * NewlineWeight); + return prefixLines.Where(static prefixLine => prefixLine.Length > 0).Sum(Encoding.UTF8.GetByteCount) + ((prefixLines.Length - 1) * NewlineWeight); } } } diff --git a/ArchiSteamFarm/Steam/Integration/SteamPICSChanges.cs b/ArchiSteamFarm/Steam/Integration/SteamPICSChanges.cs index 7e38b593f..658625b35 100644 --- a/ArchiSteamFarm/Steam/Integration/SteamPICSChanges.cs +++ b/ArchiSteamFarm/Steam/Integration/SteamPICSChanges.cs @@ -67,7 +67,7 @@ namespace ArchiSteamFarm.Steam.Integration { SteamApps.PICSChangesCallback? picsChanges = null; for (byte i = 0; (i < WebBrowser.MaxTries) && (picsChanges == null); i++) { - refreshBot = Bot.Bots?.Values.FirstOrDefault(bot => bot.IsConnectedAndLoggedOn); + refreshBot = Bot.Bots?.Values.FirstOrDefault(static bot => bot.IsConnectedAndLoggedOn); if (refreshBot == null) { LiveUpdate = false; @@ -115,7 +115,7 @@ namespace ArchiSteamFarm.Steam.Integration { ASF.GlobalDatabase.LastChangeNumber = picsChanges.CurrentChangeNumber; if (picsChanges.PackageChanges.Count > 0) { - await ASF.GlobalDatabase.RefreshPackages(refreshBot, picsChanges.PackageChanges.ToDictionary(package => package.Key, package => package.Value.ChangeNumber)).ConfigureAwait(false); + await ASF.GlobalDatabase.RefreshPackages(refreshBot, picsChanges.PackageChanges.ToDictionary(static package => package.Key, static package => package.Value.ChangeNumber)).ConfigureAwait(false); } } diff --git a/ArchiSteamFarm/Steam/Interaction/Actions.cs b/ArchiSteamFarm/Steam/Interaction/Actions.cs index 1a75042f9..d6ee476b3 100644 --- a/ArchiSteamFarm/Steam/Interaction/Actions.cs +++ b/ArchiSteamFarm/Steam/Interaction/Actions.cs @@ -89,7 +89,7 @@ namespace ArchiSteamFarm.Steam.Interaction { public static (bool Success, string Message) Exit() { // Schedule the task after some time so user can receive response Utilities.InBackground( - async () => { + static async () => { await Task.Delay(1000).ConfigureAwait(false); await Program.Exit().ConfigureAwait(false); } @@ -257,7 +257,7 @@ namespace ArchiSteamFarm.Steam.Interaction { // Schedule the task after some time so user can receive response Utilities.InBackground( - async () => { + static async () => { await Task.Delay(1000).ConfigureAwait(false); await Program.Restart().ConfigureAwait(false); } @@ -348,7 +348,7 @@ namespace ArchiSteamFarm.Steam.Interaction { return (false, Strings.BotNotConnected); } - filterFunction ??= _ => true; + filterFunction ??= static _ => true; HashSet inventory; @@ -507,7 +507,7 @@ namespace ArchiSteamFarm.Steam.Interaction { internal void OnDisconnected() => HandledGifts.Clear(); private ulong GetFirstSteamMasterID() { - ulong steamMasterID = Bot.BotConfig.SteamUserPermissions.Where(kv => (kv.Key > 0) && (kv.Key != Bot.SteamID) && new SteamID(kv.Key).IsIndividualAccount && (kv.Value == BotConfig.EAccess.Master)).Select(kv => kv.Key).OrderBy(steamID => steamID).FirstOrDefault(); + ulong steamMasterID = Bot.BotConfig.SteamUserPermissions.Where(kv => (kv.Key > 0) && (kv.Key != Bot.SteamID) && new SteamID(kv.Key).IsIndividualAccount && (kv.Value == BotConfig.EAccess.Master)).Select(static kv => kv.Key).OrderBy(static steamID => steamID).FirstOrDefault(); if (steamMasterID > 0) { return steamMasterID; diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index d3dc9f7ef..0db24c6af 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -537,7 +537,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.Response2FA(steamID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -581,7 +581,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.Response2FAConfirm(steamID, confirm))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -643,7 +643,7 @@ namespace ArchiSteamFarm.Steam.Interaction { break; } - response.AppendLine(FormatBotResponse((callback.GrantedApps.Count > 0) || (callback.GrantedPackages.Count > 0) ? string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicenseWithItems, $"app/{gameID}", callback.Result, string.Join(", ", callback.GrantedApps.Select(appID => $"app/{appID}").Union(callback.GrantedPackages.Select(subID => $"sub/{subID}")))) : string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, $"app/{gameID}", callback.Result))); + response.AppendLine(FormatBotResponse((callback.GrantedApps.Count > 0) || (callback.GrantedPackages.Count > 0) ? string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicenseWithItems, $"app/{gameID}", callback.Result, string.Join(", ", callback.GrantedApps.Select(static appID => $"app/{appID}").Union(callback.GrantedPackages.Select(static subID => $"sub/{subID}")))) : string.Format(CultureInfo.CurrentCulture, Strings.BotAddLicense, $"app/{gameID}", callback.Result))); break; default: @@ -679,7 +679,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseAddLicense(steamID, query))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -743,7 +743,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseAdvancedLoot(steamID, appID, contextID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -858,7 +858,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseAdvancedRedeem(steamID, options, keys))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -974,7 +974,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseAdvancedTransfer(steamID, appID, contextID, targetBot))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1010,7 +1010,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseBackgroundGamesRedeemer(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1040,7 +1040,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseBlacklist(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1098,7 +1098,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseBlacklistAdd(steamID, targetSteamIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1156,7 +1156,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseBlacklistRemove(steamID, targetSteamIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1240,7 +1240,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseFarm(steamID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1304,7 +1304,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseIdleBlacklist(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1375,7 +1375,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseIdleBlacklistAdd(steamID, targetAppIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1441,7 +1441,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseIdleBlacklistRemove(steamID, targetAppIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1471,7 +1471,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseIdleQueue(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1549,7 +1549,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseIdleQueueAdd(steamID, targetAppIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1620,7 +1620,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseIdleQueueRemove(steamID, targetAppIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1682,7 +1682,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseInput(steamID, propertyName, inputValue)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1722,7 +1722,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseLevel(steamID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1766,7 +1766,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseLoot(steamID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1834,7 +1834,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseLootByRealAppIDs(steamID, realAppIDsText, exclude))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1864,7 +1864,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseMatchActivelyBlacklist(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1922,7 +1922,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseMatchActivelyBlacklistAdd(steamID, targetAppIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -1980,7 +1980,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseMatchActivelyBlacklistRemove(steamID, targetAppIDs)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2028,7 +2028,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseNickname(steamID, nickname)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2206,7 +2206,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList<(string? Response, Dictionary? OwnedGames)> results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseOwns(steamID, query))).ConfigureAwait(false); - List<(string Response, Dictionary OwnedGames)> validResults = new(results.Where(result => !string.IsNullOrEmpty(result.Response) && (result.OwnedGames != null))!); + List<(string Response, Dictionary OwnedGames)> validResults = new(results.Where(static result => !string.IsNullOrEmpty(result.Response) && (result.OwnedGames != null))!); if (validResults.Count == 0) { return null; @@ -2214,7 +2214,7 @@ namespace ArchiSteamFarm.Steam.Interaction { Dictionary ownedGamesStats = new(StringComparer.Ordinal); - foreach ((string gameID, string gameName) in validResults.Where(validResult => validResult.OwnedGames.Count > 0).SelectMany(validResult => validResult.OwnedGames)) { + foreach ((string gameID, string gameName) in validResults.Where(static validResult => validResult.OwnedGames.Count > 0).SelectMany(static validResult => validResult.OwnedGames)) { if (ownedGamesStats.TryGetValue(gameID, out (ushort Count, string GameName) ownedGameStats)) { ownedGameStats.Count++; } else { @@ -2230,7 +2230,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IEnumerable extraResponses = ownedGamesStats.Select(kv => FormatStaticResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotOwnsOverviewPerGame, kv.Value.Count, validResults.Count, kv.Key + (!string.IsNullOrEmpty(kv.Value.GameName) ? $" | {kv.Value.GameName}" : "")))); - return string.Join(Environment.NewLine, validResults.Select(result => result.Response).Concat(extraResponses)); + return string.Join(Environment.NewLine, validResults.Select(static result => result.Response).Concat(extraResponses)); } private string? ResponsePassword(ulong steamID) { @@ -2251,7 +2251,7 @@ namespace ArchiSteamFarm.Steam.Interaction { { ArchiCryptoHelper.ECryptoMethod.ProtectedDataForCurrentUser, ArchiCryptoHelper.Encrypt(ArchiCryptoHelper.ECryptoMethod.ProtectedDataForCurrentUser, Bot.BotConfig.DecryptedSteamPassword!) ?? "" } }; - return FormatBotResponse(string.Join(", ", encryptedPasswords.Where(kv => !string.IsNullOrEmpty(kv.Value)).Select(kv => string.Format(CultureInfo.CurrentCulture, Strings.BotEncryptedPassword, kv.Key, kv.Value)))); + return FormatBotResponse(string.Join(", ", encryptedPasswords.Where(static kv => !string.IsNullOrEmpty(kv.Value)).Select(static kv => string.Format(CultureInfo.CurrentCulture, Strings.BotEncryptedPassword, kv.Key, kv.Value)))); } private static async Task ResponsePassword(ulong steamID, string botNames) { @@ -2271,7 +2271,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponsePassword(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2317,7 +2317,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponsePause(steamID, permanent, resumeInSecondsText))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2412,7 +2412,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponsePlay(steamID, targetGameIDs))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2452,7 +2452,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponsePointsBalance(steamID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2612,7 +2612,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponsePrivacy(steamID, privacySettingsText))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2666,7 +2666,7 @@ namespace ArchiSteamFarm.Steam.Interaction { // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework string startingKey = key!; - using (IEnumerator botsEnumerator = Bot.Bots.Where(bot => (bot.Value != Bot) && bot.Value.IsConnectedAndLoggedOn && bot.Value.Commands.Bot.HasAccess(steamID, BotConfig.EAccess.Operator)).OrderByDescending(bot => Bot.BotsComparer?.Compare(bot.Key, Bot.BotName) > 0).ThenBy(bot => bot.Key, Bot.BotsComparer).Select(bot => bot.Value).GetEnumerator()) { + using (IEnumerator botsEnumerator = Bot.Bots.Where(bot => (bot.Value != Bot) && bot.Value.IsConnectedAndLoggedOn && bot.Value.Commands.Bot.HasAccess(steamID, BotConfig.EAccess.Operator)).OrderByDescending(bot => Bot.BotsComparer?.Compare(bot.Key, Bot.BotName) > 0).ThenBy(static bot => bot.Key, Bot.BotsComparer).Select(static bot => bot.Value).GetEnumerator()) { Bot? currentBot = Bot; while (!string.IsNullOrEmpty(key) && (currentBot != null)) { @@ -2769,7 +2769,7 @@ namespace ArchiSteamFarm.Steam.Interaction { bool alreadyHandled = false; - foreach (Bot innerBot in Bot.Bots.Where(bot => (bot.Value != currentBot) && (!redeemFlags.HasFlag(ERedeemFlags.SkipInitial) || (bot.Value != Bot)) && !triedBots.Contains(bot.Value) && !rateLimitedBots.Contains(bot.Value) && bot.Value.IsConnectedAndLoggedOn && bot.Value.Commands.Bot.HasAccess(steamID, BotConfig.EAccess.Operator) && ((items.Count == 0) || items.Keys.Any(packageID => !bot.Value.OwnedPackageIDs.ContainsKey(packageID)))).OrderBy(bot => bot.Key, Bot.BotsComparer).Select(bot => bot.Value)) { + foreach (Bot innerBot in Bot.Bots.Where(bot => (bot.Value != currentBot) && (!redeemFlags.HasFlag(ERedeemFlags.SkipInitial) || (bot.Value != Bot)) && !triedBots.Contains(bot.Value) && !rateLimitedBots.Contains(bot.Value) && bot.Value.IsConnectedAndLoggedOn && bot.Value.Commands.Bot.HasAccess(steamID, BotConfig.EAccess.Operator) && ((items.Count == 0) || items.Keys.Any(packageID => !bot.Value.OwnedPackageIDs.ContainsKey(packageID)))).OrderBy(static bot => bot.Key, Bot.BotsComparer).Select(static bot => bot.Value)) { // ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework PurchaseResponseCallback? otherResult = await innerBot.Actions.RedeemKey(key!).ConfigureAwait(false); @@ -2881,7 +2881,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseRedeem(steamID, keysText, redeemFlags))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2921,7 +2921,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseReset(steamID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -2971,7 +2971,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseResume(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -3007,7 +3007,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseStart(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -3061,12 +3061,12 @@ namespace ArchiSteamFarm.Steam.Interaction { } if (Bot.CardsFarmer.CurrentGamesFarmingReadOnly.Count > 1) { - return (FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotStatusIdlingList, string.Join(", ", Bot.CardsFarmer.CurrentGamesFarmingReadOnly.Select(game => $"{game.AppID} ({game.GameName})")), Bot.CardsFarmer.GamesToFarmReadOnly.Count, Bot.CardsFarmer.GamesToFarmReadOnly.Sum(game => game.CardsRemaining), Bot.CardsFarmer.TimeRemaining.ToHumanReadable())), Bot); + return (FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotStatusIdlingList, string.Join(", ", Bot.CardsFarmer.CurrentGamesFarmingReadOnly.Select(static game => $"{game.AppID} ({game.GameName})")), Bot.CardsFarmer.GamesToFarmReadOnly.Count, Bot.CardsFarmer.GamesToFarmReadOnly.Sum(static game => game.CardsRemaining), Bot.CardsFarmer.TimeRemaining.ToHumanReadable())), Bot); } Game soloGame = Bot.CardsFarmer.CurrentGamesFarmingReadOnly.First(); - return (FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotStatusIdling, soloGame.AppID, soloGame.GameName, soloGame.CardsRemaining, Bot.CardsFarmer.GamesToFarmReadOnly.Count, Bot.CardsFarmer.GamesToFarmReadOnly.Sum(game => game.CardsRemaining), Bot.CardsFarmer.TimeRemaining.ToHumanReadable())), Bot); + return (FormatBotResponse(string.Format(CultureInfo.CurrentCulture, Strings.BotStatusIdling, soloGame.AppID, soloGame.GameName, soloGame.CardsRemaining, Bot.CardsFarmer.GamesToFarmReadOnly.Count, Bot.CardsFarmer.GamesToFarmReadOnly.Sum(static game => game.CardsRemaining), Bot.CardsFarmer.TimeRemaining.ToHumanReadable())), Bot); } private static async Task ResponseStatus(ulong steamID, string botNames) { @@ -3086,17 +3086,17 @@ namespace ArchiSteamFarm.Steam.Interaction { IList<(string? Response, Bot Bot)> results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseStatus(steamID)))).ConfigureAwait(false); - List<(string Response, Bot Bot)> validResults = new(results.Where(result => !string.IsNullOrEmpty(result.Response))!); + List<(string Response, Bot Bot)> validResults = new(results.Where(static result => !string.IsNullOrEmpty(result.Response))!); if (validResults.Count == 0) { return null; } - HashSet botsRunning = validResults.Where(result => result.Bot.KeepRunning).Select(result => result.Bot).ToHashSet(); + HashSet botsRunning = validResults.Where(static result => result.Bot.KeepRunning).Select(static result => result.Bot).ToHashSet(); - string extraResponse = string.Format(CultureInfo.CurrentCulture, Strings.BotStatusOverview, botsRunning.Count, validResults.Count, botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarmReadOnly.Count), botsRunning.Sum(bot => bot.CardsFarmer.GamesToFarmReadOnly.Sum(game => game.CardsRemaining))); + string extraResponse = string.Format(CultureInfo.CurrentCulture, Strings.BotStatusOverview, botsRunning.Count, validResults.Count, botsRunning.Sum(static bot => bot.CardsFarmer.GamesToFarmReadOnly.Count), botsRunning.Sum(static bot => bot.CardsFarmer.GamesToFarmReadOnly.Sum(static game => game.CardsRemaining))); - return string.Join(Environment.NewLine, validResults.Select(result => result.Response).Union(extraResponse.ToEnumerable())); + return string.Join(Environment.NewLine, validResults.Select(static result => result.Response).Union(extraResponse.ToEnumerable())); } private string? ResponseStop(ulong steamID) { @@ -3130,7 +3130,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseStop(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -3196,7 +3196,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseTransfer(steamID, botNameTo))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -3328,7 +3328,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseTransferByRealAppIDs(steamID, realAppIDs, targetBot, exclude))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -3359,7 +3359,7 @@ namespace ArchiSteamFarm.Steam.Interaction { // It'd also make sense to run all of this in parallel, but it seems that Steam has a lot of problems with inventory-related parallel requests | https://steamcommunity.com/groups/archiasf/discussions/1/3559414588264550284/ try { - await foreach (Asset item in Bot.ArchiWebHandler.GetInventoryAsync().Where(item => item.Type == Asset.EType.BoosterPack).ConfigureAwait(false)) { + await foreach (Asset item in Bot.ArchiWebHandler.GetInventoryAsync().Where(static item => item.Type == Asset.EType.BoosterPack).ConfigureAwait(false)) { if (!await Bot.ArchiWebHandler.UnpackBooster(item.RealAppID, item.AssetID).ConfigureAwait(false)) { completeSuccess = false; } @@ -3394,7 +3394,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseUnpackBoosters(steamID))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } @@ -3450,7 +3450,7 @@ namespace ArchiSteamFarm.Steam.Interaction { IList results = await Utilities.InParallel(bots.Select(bot => Task.Run(() => bot.Commands.ResponseWalletBalance(steamID)))).ConfigureAwait(false); - List responses = new(results.Where(result => !string.IsNullOrEmpty(result))!); + List responses = new(results.Where(static result => !string.IsNullOrEmpty(result))!); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } diff --git a/ArchiSteamFarm/Steam/SteamKit2/InMemoryServerListProvider.cs b/ArchiSteamFarm/Steam/SteamKit2/InMemoryServerListProvider.cs index 5b85566c4..be70f4568 100644 --- a/ArchiSteamFarm/Steam/SteamKit2/InMemoryServerListProvider.cs +++ b/ArchiSteamFarm/Steam/SteamKit2/InMemoryServerListProvider.cs @@ -32,14 +32,14 @@ namespace ArchiSteamFarm.Steam.SteamKit2 { [JsonProperty(Required = Required.DisallowNull)] private readonly ConcurrentHashSet ServerRecords = new(); - public Task> FetchServerListAsync() => Task.FromResult(ServerRecords.Where(server => !string.IsNullOrEmpty(server.Host) && (server.Port > 0) && (server.ProtocolTypes > 0)).Select(server => ServerRecord.CreateServer(server.Host, server.Port, server.ProtocolTypes))); + public Task> FetchServerListAsync() => Task.FromResult(ServerRecords.Where(static server => !string.IsNullOrEmpty(server.Host) && (server.Port > 0) && (server.ProtocolTypes > 0)).Select(static server => ServerRecord.CreateServer(server.Host, server.Port, server.ProtocolTypes))); public Task UpdateServerListAsync(IEnumerable endpoints) { if (endpoints == null) { throw new ArgumentNullException(nameof(endpoints)); } - HashSet newServerRecords = endpoints.Select(ep => new ServerRecordEndPoint(ep.GetHost(), (ushort) ep.GetPort(), ep.ProtocolTypes)).ToHashSet(); + HashSet newServerRecords = endpoints.Select(static endpoint => new ServerRecordEndPoint(endpoint.GetHost(), (ushort) endpoint.GetPort(), endpoint.ProtocolTypes)).ToHashSet(); if (ServerRecords.ReplaceIfNeededWith(newServerRecords)) { ServerListUpdated?.Invoke(this, EventArgs.Empty); diff --git a/ArchiSteamFarm/Steam/Storage/BotConfig.cs b/ArchiSteamFarm/Steam/Storage/BotConfig.cs index 4c987ca79..9bb60357d 100644 --- a/ArchiSteamFarm/Steam/Storage/BotConfig.cs +++ b/ArchiSteamFarm/Steam/Storage/BotConfig.cs @@ -452,7 +452,7 @@ namespace ArchiSteamFarm.Steam.Storage { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(BotBehaviour), BotBehaviour)); } - foreach (EFarmingOrder farmingOrder in FarmingOrders.Where(farmingOrder => !Enum.IsDefined(typeof(EFarmingOrder), farmingOrder))) { + foreach (EFarmingOrder farmingOrder in FarmingOrders.Where(static farmingOrder => !Enum.IsDefined(typeof(EFarmingOrder), farmingOrder))) { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(FarmingOrders), farmingOrder)); } @@ -464,7 +464,7 @@ namespace ArchiSteamFarm.Steam.Storage { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(GamesPlayedWhileIdle), $"{nameof(GamesPlayedWhileIdle.Count)} {GamesPlayedWhileIdle.Count} > {ArchiHandler.MaxGamesPlayedConcurrently}")); } - foreach (Asset.EType lootableType in LootableTypes.Where(lootableType => !Enum.IsDefined(typeof(Asset.EType), lootableType))) { + foreach (Asset.EType lootableType in LootableTypes.Where(static lootableType => !Enum.IsDefined(typeof(Asset.EType), lootableType))) { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(LootableTypes), lootableType)); } @@ -482,7 +482,7 @@ namespace ArchiSteamFarm.Steam.Storage { throw new InvalidOperationException(nameof(completeTypesToSendValidValues)); } - completeTypesToSendValidTypes = completeTypesToSendValidValues.ValidIntValues.Select(value => (Asset.EType) value).ToHashSet(); + completeTypesToSendValidTypes = completeTypesToSendValidValues.ValidIntValues.Select(static value => (Asset.EType) value).ToHashSet(); } if (!completeTypesToSendValidTypes.Contains(completableType)) { @@ -490,7 +490,7 @@ namespace ArchiSteamFarm.Steam.Storage { } } - foreach (Asset.EType matchableType in MatchableTypes.Where(matchableType => !Enum.IsDefined(typeof(Asset.EType), matchableType))) { + foreach (Asset.EType matchableType in MatchableTypes.Where(static matchableType => !Enum.IsDefined(typeof(Asset.EType), matchableType))) { return (false, string.Format(CultureInfo.CurrentCulture, Strings.ErrorConfigPropertyInvalid, nameof(MatchableTypes), matchableType)); } diff --git a/ArchiSteamFarm/Storage/GlobalDatabase.cs b/ArchiSteamFarm/Storage/GlobalDatabase.cs index 3932d18d7..910d410d1 100644 --- a/ArchiSteamFarm/Storage/GlobalDatabase.cs +++ b/ArchiSteamFarm/Storage/GlobalDatabase.cs @@ -243,7 +243,7 @@ namespace ArchiSteamFarm.Storage { HashSet result = new(); - foreach (uint packageID in packageIDs.Where(packageID => packageID != 0)) { + foreach (uint packageID in packageIDs.Where(static packageID => packageID != 0)) { if (!PackagesData.TryGetValue(packageID, out (uint ChangeNumber, ImmutableHashSet? AppIDs) packagesData) || (packagesData.AppIDs?.Contains(appID) != true)) { continue; } @@ -269,7 +269,7 @@ namespace ArchiSteamFarm.Storage { LastChangeNumber = currentChangeNumber; - Bot? refreshBot = Bot.Bots.Values.FirstOrDefault(bot => bot.IsConnectedAndLoggedOn); + Bot? refreshBot = Bot.Bots.Values.FirstOrDefault(static bot => bot.IsConnectedAndLoggedOn); if (refreshBot == null) { return; @@ -279,7 +279,7 @@ namespace ArchiSteamFarm.Storage { return; } - Dictionary packageIDs = PackagesData.Keys.ToDictionary(packageID => packageID, _ => currentChangeNumber); + Dictionary packageIDs = PackagesData.Keys.ToDictionary(static packageID => packageID, _ => currentChangeNumber); await RefreshPackages(refreshBot, packageIDs).ConfigureAwait(false); } @@ -315,7 +315,7 @@ namespace ArchiSteamFarm.Storage { await PackagesRefreshSemaphore.WaitAsync().ConfigureAwait(false); try { - HashSet packageIDs = packages.Where(package => (package.Key != 0) && (!PackagesData.TryGetValue(package.Key, out (uint ChangeNumber, ImmutableHashSet? AppIDs) previousData) || (previousData.ChangeNumber < package.Value))).Select(package => package.Key).ToHashSet(); + HashSet packageIDs = packages.Where(package => (package.Key != 0) && (!PackagesData.TryGetValue(package.Key, out (uint ChangeNumber, ImmutableHashSet? AppIDs) previousData) || (previousData.ChangeNumber < package.Value))).Select(static package => package.Key).ToHashSet(); if (packageIDs.Count == 0) { return; diff --git a/ArchiSteamFarm/Web/GitHub.cs b/ArchiSteamFarm/Web/GitHub.cs index cf40b191c..eca7cd70e 100644 --- a/ArchiSteamFarm/Web/GitHub.cs +++ b/ArchiSteamFarm/Web/GitHub.cs @@ -164,7 +164,7 @@ namespace ArchiSteamFarm.Web { MarkdownDocument markdownDocument = Markdown.Parse(markdownText); MarkdownDocument result = new(); - foreach (Block block in markdownDocument.SkipWhile(block => block is not HeadingBlock { Inline: { FirstChild: LiteralInline literalInline } } || !literalInline.Content.ToString().Equals("Changelog", StringComparison.OrdinalIgnoreCase)).Skip(1).TakeWhile(block => block is not ThematicBreakBlock).ToList()) { + foreach (Block block in markdownDocument.SkipWhile(static block => block is not HeadingBlock { Inline: { FirstChild: LiteralInline literalInline } } || !literalInline.Content.ToString().Equals("Changelog", StringComparison.OrdinalIgnoreCase)).Skip(1).TakeWhile(static block => block is not ThematicBreakBlock).ToList()) { // All blocks that we're interested in must be removed from original markdownDocument firstly markdownDocument.Remove(block); result.Add(block); diff --git a/ArchiSteamFarm/Web/WebBrowser.cs b/ArchiSteamFarm/Web/WebBrowser.cs index 11ed581fb..1e7ab7beb 100644 --- a/ArchiSteamFarm/Web/WebBrowser.cs +++ b/ArchiSteamFarm/Web/WebBrowser.cs @@ -785,7 +785,7 @@ namespace ArchiSteamFarm.Web { try { requestMessage.Content = new FormUrlEncodedContent(nameValueCollection); } catch (UriFormatException) { - requestMessage.Content = new StringContent(string.Join("&", nameValueCollection.Select(kv => $"{WebUtility.UrlEncode(kv.Key)}={WebUtility.UrlEncode(kv.Value)}")), null, "application/x-www-form-urlencoded"); + requestMessage.Content = new StringContent(string.Join("&", nameValueCollection.Select(static kv => $"{WebUtility.UrlEncode(kv.Key)}={WebUtility.UrlEncode(kv.Value)}")), null, "application/x-www-form-urlencoded"); } break;