From ba07405d9aa76b39e1f7832cbfdb73cfb71970cf Mon Sep 17 00:00:00 2001 From: Archi <JustArchi@JustArchi.net> Date: Tue, 23 Jan 2024 22:49:33 +0100 Subject: [PATCH] Refactor selected boolean bot config properties All of them are common enough to be contained into a single flags property, this will vastly improve readability of the bot config, among being ready to add more properties in the future without polluting it. Also hooray for 6 bytes less of memory usage of each bot, glorious. --- ArchiSteamFarm/Steam/Bot.cs | 10 +- ArchiSteamFarm/Steam/Cards/CardsFarmer.cs | 12 +- ArchiSteamFarm/Steam/Exchange/Trading.cs | 2 +- ArchiSteamFarm/Steam/Interaction/Commands.cs | 2 +- ArchiSteamFarm/Steam/Storage/BotConfig.cs | 172 +++++++++++++------ 5 files changed, 128 insertions(+), 70 deletions(-) diff --git a/ArchiSteamFarm/Steam/Bot.cs b/ArchiSteamFarm/Steam/Bot.cs index e7f3aa9ce3a2f..2c34f9e23f2c7 100644 --- a/ArchiSteamFarm/Steam/Bot.cs +++ b/ArchiSteamFarm/Steam/Bot.cs @@ -1070,7 +1070,7 @@ internal static string FormatBotResponse(string response, string botName) { return (0, DateTime.MaxValue, true); } - if ((hoursPlayed < CardsFarmer.HoursForRefund) && BotConfig.SkipRefundableGames) { + if ((hoursPlayed < CardsFarmer.HoursForRefund) && BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.SkipRefundableGames)) { DateTime mostRecent = DateTime.MinValue; foreach (uint packageID in packageIDs) { @@ -1531,13 +1531,13 @@ internal async Task OnConfigChanged(bool deleted) { internal async Task OnFarmingFinished(bool farmedSomething) { await OnFarmingStopped().ConfigureAwait(false); - if (BotConfig is { SendOnFarmingFinished: true, LootableTypes.Count: > 0 } && (farmedSomething || !FirstTradeSent)) { + if (BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.SendOnFarmingFinished) && (BotConfig.LootableTypes.Count > 0) && (farmedSomething || !FirstTradeSent)) { FirstTradeSent = true; await Actions.SendInventory(filterFunction: item => BotConfig.LootableTypes.Contains(item.Type)).ConfigureAwait(false); } - if (BotConfig.ShutdownOnFarmingFinished) { + if (BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.ShutdownOnFarmingFinished)) { Stop(); } @@ -2378,7 +2378,7 @@ private async Task InitModules() { AccessToken = accessToken; RefreshToken = refreshToken; - CardsFarmer.SetInitialState(BotConfig.Paused); + CardsFarmer.SetInitialState(BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.FarmingPausedByDefault)); if (SendItemsTimer != null) { await SendItemsTimer.DisposeAsync().ConfigureAwait(false); @@ -2407,7 +2407,7 @@ private async Task InitModules() { ); } - if (BotConfig.AutoSteamSaleEvent) { + if (BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.AutoSteamSaleEvent)) { SteamSaleEvent = new SteamSaleEvent(this); } diff --git a/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs b/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs index 29695474271c9..1393b13610ac3 100644 --- a/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs +++ b/ArchiSteamFarm/Steam/Cards/CardsFarmer.cs @@ -258,7 +258,7 @@ internal async Task OnNewItemsNotification() { // If we're not farming, and we got new items, it's likely to be a booster pack or likewise // In this case, perform a loot if user wants to do so - if (Bot.BotConfig is { SendOnFarmingFinished: true, LootableTypes.Count: > 0 }) { + if (Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.SendOnFarmingFinished) && (Bot.BotConfig.LootableTypes.Count > 0)) { await Bot.Actions.SendInventory(filterFunction: item => Bot.BotConfig.LootableTypes.Contains(item.Type)).ConfigureAwait(false); } } @@ -313,7 +313,7 @@ internal async Task StartFarming() { return; } - if (!Bot.CanReceiveSteamCards || (Bot.BotConfig.FarmPriorityQueueOnly && (Bot.BotDatabase.FarmingPriorityQueueAppIDs.Count == 0))) { + if (!Bot.CanReceiveSteamCards || (Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.FarmPriorityQueueOnly) && (Bot.BotDatabase.FarmingPriorityQueueAppIDs.Count == 0))) { Bot.ArchiLogger.LogGenericInfo(Strings.NothingToIdle); await Bot.OnFarmingFinished(false).ConfigureAwait(false); @@ -1106,12 +1106,12 @@ private async Task<bool> FarmSolo(Game game) { // Find the number of badge pages Bot.ArchiLogger.LogGenericInfo(Strings.CheckingFirstBadgePage); - using IDocument? htmlDocument = await Bot.ArchiWebHandler.GetBadgePage(1, Bot.BotConfig.EnableRiskyCardsDiscovery ? (byte) 2 : WebBrowser.MaxTries).ConfigureAwait(false); + using IDocument? htmlDocument = await Bot.ArchiWebHandler.GetBadgePage(1, Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.EnableRiskyCardsDiscovery) ? (byte) 2 : WebBrowser.MaxTries).ConfigureAwait(false); if (htmlDocument == null) { Bot.ArchiLogger.LogGenericWarning(Strings.WarningCouldNotCheckBadges); - if (!Bot.BotConfig.EnableRiskyCardsDiscovery) { + if (!Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.EnableRiskyCardsDiscovery)) { return null; } @@ -1195,7 +1195,7 @@ private async Task<bool> FarmSolo(Game game) { ShouldResumeFarming = false; // Allow changing to risky algorithm only if we failed at least some badge pages and we have the prop enabled - if (allTasksSucceeded || !Bot.BotConfig.EnableRiskyCardsDiscovery) { + if (allTasksSucceeded || !Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.EnableRiskyCardsDiscovery)) { return false; } @@ -1341,7 +1341,7 @@ private async Task<bool> IsPlayableGame(Game game) { private bool ShouldIdle(uint appID) { ArgumentOutOfRangeException.ThrowIfZero(appID); - if (SalesBlacklist.Contains(appID) || (ASF.GlobalConfig?.Blacklist.Contains(appID) == true) || Bot.IsBlacklistedFromIdling(appID) || (Bot.BotConfig.FarmPriorityQueueOnly && !Bot.IsPriorityIdling(appID))) { + if (SalesBlacklist.Contains(appID) || (ASF.GlobalConfig?.Blacklist.Contains(appID) == true) || Bot.IsBlacklistedFromIdling(appID) || (Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.FarmPriorityQueueOnly) && !Bot.IsPriorityIdling(appID))) { // We're configured to ignore this appID, so skip it return false; } diff --git a/ArchiSteamFarm/Steam/Exchange/Trading.cs b/ArchiSteamFarm/Steam/Exchange/Trading.cs index 90aa72390ae1e..e5c133c1de276 100644 --- a/ArchiSteamFarm/Steam/Exchange/Trading.cs +++ b/ArchiSteamFarm/Steam/Exchange/Trading.cs @@ -372,7 +372,7 @@ internal async Task OnNewTrade() { lootableTypesReceived = await ParseActiveTrades().ConfigureAwait(false); } - if (lootableTypesReceived && Bot.BotConfig is { SendOnFarmingFinished: true, LootableTypes.Count: > 0 }) { + if (lootableTypesReceived && Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.SendOnFarmingFinished) && (Bot.BotConfig.LootableTypes.Count > 0)) { await Bot.Actions.SendInventory(filterFunction: item => Bot.BotConfig.LootableTypes.Contains(item.Type)).ConfigureAwait(false); } } finally { diff --git a/ArchiSteamFarm/Steam/Interaction/Commands.cs b/ArchiSteamFarm/Steam/Interaction/Commands.cs index f379cfdb4f106..4cca8be2cadc0 100644 --- a/ArchiSteamFarm/Steam/Interaction/Commands.cs +++ b/ArchiSteamFarm/Steam/Interaction/Commands.cs @@ -1239,7 +1239,7 @@ internal void OnNewLicenseList() { } switch (Bot.CardsFarmer.NowFarming) { - case false when Bot.BotConfig.FarmPriorityQueueOnly: + case false when Bot.BotConfig.FarmingPreferences.HasFlag(BotConfig.EFarmingPreferences.FarmPriorityQueueOnly): Utilities.InBackground(Bot.CardsFarmer.StartFarming); break; diff --git a/ArchiSteamFarm/Steam/Storage/BotConfig.cs b/ArchiSteamFarm/Steam/Storage/BotConfig.cs index 8c721aa07cf49..59a89bca4a650 100644 --- a/ArchiSteamFarm/Steam/Storage/BotConfig.cs +++ b/ArchiSteamFarm/Steam/Storage/BotConfig.cs @@ -47,9 +47,6 @@ public sealed class BotConfig { [PublicAPI] public const bool DefaultAcceptGifts = false; - [PublicAPI] - public const bool DefaultAutoSteamSaleEvent = false; - [PublicAPI] public const EBotBehaviour DefaultBotBehaviour = EBotBehaviour.None; @@ -63,10 +60,7 @@ public sealed class BotConfig { public const bool DefaultEnabled = false; [PublicAPI] - public const bool DefaultEnableRiskyCardsDiscovery = false; - - [PublicAPI] - public const bool DefaultFarmPriorityQueueOnly = false; + public const EFarmingPreferences DefaultFarmingPreferences = EFarmingPreferences.None; [PublicAPI] public const byte DefaultHoursUntilCardDrops = 3; @@ -80,27 +74,15 @@ public sealed class BotConfig { [PublicAPI] public const ArchiCryptoHelper.ECryptoMethod DefaultPasswordFormat = ArchiCryptoHelper.ECryptoMethod.PlainText; - [PublicAPI] - public const bool DefaultPaused = false; - [PublicAPI] public const ERedeemingPreferences DefaultRedeemingPreferences = ERedeemingPreferences.None; [PublicAPI] public const ERemoteCommunication DefaultRemoteCommunication = ERemoteCommunication.All; - [PublicAPI] - public const bool DefaultSendOnFarmingFinished = false; - [PublicAPI] public const byte DefaultSendTradePeriod = 0; - [PublicAPI] - public const bool DefaultShutdownOnFarmingFinished = false; - - [PublicAPI] - public const bool DefaultSkipRefundableGames = false; - [PublicAPI] public const string? DefaultSteamLogin = null; @@ -155,9 +137,6 @@ public sealed class BotConfig { [JsonProperty(Required = Required.DisallowNull)] public bool AcceptGifts { get; private set; } = DefaultAcceptGifts; - [JsonProperty(Required = Required.DisallowNull)] - public bool AutoSteamSaleEvent { get; private set; } = DefaultAutoSteamSaleEvent; - [JsonProperty(Required = Required.DisallowNull)] public EBotBehaviour BotBehaviour { get; private set; } = DefaultBotBehaviour; @@ -174,14 +153,11 @@ public sealed class BotConfig { [JsonProperty(Required = Required.DisallowNull)] public bool Enabled { get; private set; } = DefaultEnabled; - [JsonProperty] - public bool EnableRiskyCardsDiscovery { get; private set; } = DefaultEnableRiskyCardsDiscovery; - [JsonProperty(Required = Required.DisallowNull)] public ImmutableList<EFarmingOrder> FarmingOrders { get; private set; } = DefaultFarmingOrders; [JsonProperty(Required = Required.DisallowNull)] - public bool FarmPriorityQueueOnly { get; private set; } = DefaultFarmPriorityQueueOnly; + public EFarmingPreferences FarmingPreferences { get; private set; } = DefaultFarmingPreferences; [JsonProperty(Required = Required.DisallowNull)] [MaxLength(ArchiHandler.MaxGamesPlayedConcurrently)] @@ -208,28 +184,16 @@ public sealed class BotConfig { [JsonProperty(Required = Required.DisallowNull)] public ArchiCryptoHelper.ECryptoMethod PasswordFormat { get; internal set; } = DefaultPasswordFormat; - [JsonProperty(Required = Required.DisallowNull)] - public bool Paused { get; private set; } = DefaultPaused; - [JsonProperty(Required = Required.DisallowNull)] public ERedeemingPreferences RedeemingPreferences { get; private set; } = DefaultRedeemingPreferences; [JsonProperty(Required = Required.DisallowNull)] public ERemoteCommunication RemoteCommunication { get; private set; } = DefaultRemoteCommunication; - [JsonProperty(Required = Required.DisallowNull)] - public bool SendOnFarmingFinished { get; private set; } = DefaultSendOnFarmingFinished; - [JsonProperty(Required = Required.DisallowNull)] [Range(byte.MinValue, byte.MaxValue)] public byte SendTradePeriod { get; private set; } = DefaultSendTradePeriod; - [JsonProperty(Required = Required.DisallowNull)] - public bool ShutdownOnFarmingFinished { get; private set; } = DefaultShutdownOnFarmingFinished; - - [JsonProperty(Required = Required.DisallowNull)] - public bool SkipRefundableGames { get; private set; } = DefaultSkipRefundableGames; - [JsonProperty] public string? SteamLogin { get => BackingSteamLogin; @@ -310,6 +274,104 @@ internal Dictionary<string, JToken>? AdditionalProperties { private string? BackingSteamParentalCode = DefaultSteamParentalCode; private string? BackingSteamPassword = DefaultSteamPassword; + [JsonProperty(Required = Required.DisallowNull)] + [Obsolete] + private bool AutoSteamSaleEvent { + set { + ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(AutoSteamSaleEvent), nameof(FarmingPreferences))); + + if (value) { + FarmingPreferences |= EFarmingPreferences.AutoSteamSaleEvent; + } else { + FarmingPreferences &= ~EFarmingPreferences.AutoSteamSaleEvent; + } + } + } + + [JsonProperty(Required = Required.DisallowNull)] + [Obsolete] + private bool EnableRiskyCardsDiscovery { + set { + ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(EnableRiskyCardsDiscovery), nameof(FarmingPreferences))); + + if (value) { + FarmingPreferences |= EFarmingPreferences.EnableRiskyCardsDiscovery; + } else { + FarmingPreferences &= ~EFarmingPreferences.EnableRiskyCardsDiscovery; + } + } + } + + [JsonProperty(Required = Required.DisallowNull)] + [Obsolete] + private bool FarmPriorityQueueOnly { + set { + ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(FarmPriorityQueueOnly), nameof(FarmingPreferences))); + + if (value) { + FarmingPreferences |= EFarmingPreferences.FarmPriorityQueueOnly; + } else { + FarmingPreferences &= ~EFarmingPreferences.FarmPriorityQueueOnly; + } + } + } + + [JsonProperty(Required = Required.DisallowNull)] + [Obsolete] + private bool Paused { + set { + ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(Paused), nameof(FarmingPreferences))); + + if (value) { + FarmingPreferences |= EFarmingPreferences.FarmingPausedByDefault; + } else { + FarmingPreferences &= ~EFarmingPreferences.FarmingPausedByDefault; + } + } + } + + [JsonProperty(Required = Required.DisallowNull)] + [Obsolete] + private bool SendOnFarmingFinished { + set { + ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(SendOnFarmingFinished), nameof(FarmingPreferences))); + + if (value) { + FarmingPreferences |= EFarmingPreferences.SendOnFarmingFinished; + } else { + FarmingPreferences &= ~EFarmingPreferences.SendOnFarmingFinished; + } + } + } + + [JsonProperty(Required = Required.DisallowNull)] + [Obsolete] + private bool ShutdownOnFarmingFinished { + set { + ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(ShutdownOnFarmingFinished), nameof(FarmingPreferences))); + + if (value) { + FarmingPreferences |= EFarmingPreferences.ShutdownOnFarmingFinished; + } else { + FarmingPreferences &= ~EFarmingPreferences.ShutdownOnFarmingFinished; + } + } + } + + [JsonProperty(Required = Required.DisallowNull)] + [Obsolete] + private bool SkipRefundableGames { + set { + ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDeprecated, nameof(SkipRefundableGames), nameof(FarmingPreferences))); + + if (value) { + FarmingPreferences |= EFarmingPreferences.SkipRefundableGames; + } else { + FarmingPreferences &= ~EFarmingPreferences.SkipRefundableGames; + } + } + } + [JsonProperty($"{SharedInfo.UlongCompatibilityStringPrefix}{nameof(SteamMasterClanID)}", Required = Required.DisallowNull)] private string SSteamMasterClanID { get => SteamMasterClanID.ToString(CultureInfo.InvariantCulture); @@ -331,9 +393,6 @@ internal BotConfig() { } [UsedImplicitly] public bool ShouldSerializeAcceptGifts() => !Saving || (AcceptGifts != DefaultAcceptGifts); - [UsedImplicitly] - public bool ShouldSerializeAutoSteamSaleEvent() => !Saving || (AutoSteamSaleEvent != DefaultAutoSteamSaleEvent); - [UsedImplicitly] public bool ShouldSerializeBotBehaviour() => !Saving || (BotBehaviour != DefaultBotBehaviour); @@ -349,14 +408,11 @@ internal BotConfig() { } [UsedImplicitly] public bool ShouldSerializeEnabled() => !Saving || (Enabled != DefaultEnabled); - [UsedImplicitly] - public bool ShouldSerializeEnableRiskyCardsDiscovery() => !Saving || (EnableRiskyCardsDiscovery != DefaultEnableRiskyCardsDiscovery); - [UsedImplicitly] public bool ShouldSerializeFarmingOrders() => !Saving || ((FarmingOrders != DefaultFarmingOrders) && !FarmingOrders.SequenceEqual(DefaultFarmingOrders)); [UsedImplicitly] - public bool ShouldSerializeFarmPriorityQueueOnly() => !Saving || (FarmPriorityQueueOnly != DefaultFarmPriorityQueueOnly); + public bool ShouldSerializeFarmingPreferences() => !Saving || (FarmingPreferences != DefaultFarmingPreferences); [UsedImplicitly] public bool ShouldSerializeGamesPlayedWhileIdle() => !Saving || ((GamesPlayedWhileIdle != DefaultGamesPlayedWhileIdle) && !GamesPlayedWhileIdle.SequenceEqual(DefaultGamesPlayedWhileIdle)); @@ -379,27 +435,15 @@ internal BotConfig() { } [UsedImplicitly] public bool ShouldSerializePasswordFormat() => !Saving || (PasswordFormat != DefaultPasswordFormat); - [UsedImplicitly] - public bool ShouldSerializePaused() => !Saving || (Paused != DefaultPaused); - [UsedImplicitly] public bool ShouldSerializeRedeemingPreferences() => !Saving || (RedeemingPreferences != DefaultRedeemingPreferences); [UsedImplicitly] public bool ShouldSerializeRemoteCommunication() => !Saving || (RemoteCommunication != DefaultRemoteCommunication); - [UsedImplicitly] - public bool ShouldSerializeSendOnFarmingFinished() => !Saving || (SendOnFarmingFinished != DefaultSendOnFarmingFinished); - [UsedImplicitly] public bool ShouldSerializeSendTradePeriod() => !Saving || (SendTradePeriod != DefaultSendTradePeriod); - [UsedImplicitly] - public bool ShouldSerializeShutdownOnFarmingFinished() => !Saving || (ShutdownOnFarmingFinished != DefaultShutdownOnFarmingFinished); - - [UsedImplicitly] - public bool ShouldSerializeSkipRefundableGames() => !Saving || (SkipRefundableGames != DefaultSkipRefundableGames); - [UsedImplicitly] public bool ShouldSerializeSSteamMasterClanID() => !Saving; @@ -697,6 +741,20 @@ public enum EFarmingOrder : byte { MarketableDescending } + [Flags] + [PublicAPI] + public enum EFarmingPreferences : byte { + None = 0, + FarmingPausedByDefault = 1, + ShutdownOnFarmingFinished = 2, + SendOnFarmingFinished = 4, + FarmPriorityQueueOnly = 8, + SkipRefundableGames = 16, + EnableRiskyCardsDiscovery = 32, + AutoSteamSaleEvent = 64, + All = FarmingPausedByDefault | ShutdownOnFarmingFinished | SendOnFarmingFinished | FarmPriorityQueueOnly | SkipRefundableGames | EnableRiskyCardsDiscovery | AutoSteamSaleEvent + } + [Flags] [PublicAPI] public enum ERedeemingPreferences : byte {