diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 92b2d77f4..3c5a986da 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -788,7 +788,7 @@ namespace ArchiSteamFarm { FirstTradeSent = true; if (BotConfig.SendOnFarmingFinished) { - await Actions.SendTradeOffer().ConfigureAwait(false); + await Actions.SendTradeOffer(wantedTypes: BotConfig.LootableTypes).ConfigureAwait(false); } } @@ -1426,7 +1426,7 @@ namespace ArchiSteamFarm { if ((BotConfig.SendTradePeriod > 0) && BotConfig.SteamUserPermissions.Values.Any(permission => permission >= BotConfig.EPermission.Master)) { SendItemsTimer = new Timer( - async e => await Actions.SendTradeOffer().ConfigureAwait(false), + async e => await Actions.SendTradeOffer(wantedTypes: BotConfig.LootableTypes).ConfigureAwait(false), null, TimeSpan.FromHours(BotConfig.SendTradePeriod) + TimeSpan.FromSeconds(Program.LoadBalancingDelay * Bots.Count), // Delay TimeSpan.FromHours(BotConfig.SendTradePeriod) // Period diff --git a/ArchiSteamFarm/BotConfig.cs b/ArchiSteamFarm/BotConfig.cs index b7bbceeec..12d872a87 100644 --- a/ArchiSteamFarm/BotConfig.cs +++ b/ArchiSteamFarm/BotConfig.cs @@ -63,6 +63,7 @@ namespace ArchiSteamFarm { private static readonly ImmutableHashSet DefaultLootableTypes = ImmutableHashSet.Create(Steam.Asset.EType.BoosterPack, Steam.Asset.EType.FoilTradingCard, Steam.Asset.EType.TradingCard); private static readonly ImmutableHashSet DefaultMatchableTypes = ImmutableHashSet.Create(Steam.Asset.EType.TradingCard); private static readonly ImmutableDictionary DefaultSteamUserPermissions = ImmutableDictionary.Empty; + private static readonly ImmutableHashSet DefaultTransferableTypes = ImmutableHashSet.Create(Steam.Asset.EType.BoosterPack, Steam.Asset.EType.FoilTradingCard, Steam.Asset.EType.TradingCard); private static readonly SemaphoreSlim WriteSemaphore = new SemaphoreSlim(1, 1); @@ -135,6 +136,9 @@ namespace ArchiSteamFarm { [JsonProperty(Required = Required.DisallowNull)] internal readonly ETradingPreferences TradingPreferences = DefaultTradingPreferences; + [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)] + internal readonly ImmutableHashSet TransferableTypes = DefaultTransferableTypes; + [JsonProperty(Required = Required.DisallowNull)] internal readonly bool UseLoginKeys = DefaultUseLoginKeys; @@ -438,6 +442,7 @@ namespace ArchiSteamFarm { public bool ShouldSerializeSteamTradeToken() => ShouldSerializeEverything || (SteamTradeToken != DefaultSteamTradeToken); public bool ShouldSerializeSteamUserPermissions() => ShouldSerializeEverything || ((SteamUserPermissions != DefaultSteamUserPermissions) && ((SteamUserPermissions.Count != DefaultSteamUserPermissions.Count) || SteamUserPermissions.Except(DefaultSteamUserPermissions).Any())); public bool ShouldSerializeTradingPreferences() => ShouldSerializeEverything || (TradingPreferences != DefaultTradingPreferences); + public bool ShouldSerializeTransferableTypes() => ShouldSerializeEverything || ((TransferableTypes != DefaultTransferableTypes) && !TransferableTypes.SetEquals(DefaultTransferableTypes)); public bool ShouldSerializeUseLoginKeys() => ShouldSerializeEverything || (UseLoginKeys != DefaultUseLoginKeys); // ReSharper restore UnusedMember.Global diff --git a/ArchiSteamFarm/CardsFarmer.cs b/ArchiSteamFarm/CardsFarmer.cs index ef8a12745..96a03ec96 100755 --- a/ArchiSteamFarm/CardsFarmer.cs +++ b/ArchiSteamFarm/CardsFarmer.cs @@ -169,7 +169,7 @@ namespace ArchiSteamFarm { // 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.SendOnFarmingFinished) { - await Bot.Actions.SendTradeOffer().ConfigureAwait(false); + await Bot.Actions.SendTradeOffer(wantedTypes: Bot.BotConfig.LootableTypes).ConfigureAwait(false); } } diff --git a/ArchiSteamFarm/Commands.cs b/ArchiSteamFarm/Commands.cs index 99a054a4a..31ed69a3e 100644 --- a/ArchiSteamFarm/Commands.cs +++ b/ArchiSteamFarm/Commands.cs @@ -269,15 +269,11 @@ namespace ArchiSteamFarm { case "STOP": return await ResponseStop(steamID, Utilities.GetArgsAsText(args, 1, ",")).ConfigureAwait(false); case "TRANSFER": - if (args.Length > 3) { - return await ResponseTransfer(steamID, args[1], args[2], Utilities.GetArgsAsText(args, 3, ",")).ConfigureAwait(false); - } - if (args.Length > 2) { - return await ResponseTransfer(steamID, args[1], args[2]).ConfigureAwait(false); + return await ResponseTransfer(steamID, args[1], Utilities.GetArgsAsText(args, 2, ",")).ConfigureAwait(false); } - goto default; + return await ResponseTransfer(steamID, args[1]).ConfigureAwait(false); case "TRANSFER^": if (args.Length > 4) { return await ResponseAdvancedTransfer(steamID, args[1], args[2], args[3], Utilities.GetArgsAsText(args, 4, ",")).ConfigureAwait(false); @@ -1234,7 +1230,7 @@ namespace ArchiSteamFarm { realAppIDs.Add(appID); } - (bool success, string output) = await Bot.Actions.SendTradeOffer(wantedRealAppIDs: realAppIDs).ConfigureAwait(false); + (bool success, string output) = await Bot.Actions.SendTradeOffer(wantedTypes: Bot.BotConfig.LootableTypes, wantedRealAppIDs: realAppIDs).ConfigureAwait(false); return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output)); } @@ -2113,9 +2109,9 @@ namespace ArchiSteamFarm { return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; } - private async Task ResponseTransfer(ulong steamID, string mode, string botNameTo) { - if ((steamID == 0) || string.IsNullOrEmpty(botNameTo) || string.IsNullOrEmpty(mode)) { - ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(mode) + " || " + nameof(botNameTo)); + private async Task ResponseTransfer(ulong steamID, string botNameTo) { + if ((steamID == 0) || string.IsNullOrEmpty(botNameTo)) { + ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNameTo)); return null; } @@ -2139,63 +2135,13 @@ namespace ArchiSteamFarm { return FormatBotResponse(Strings.BotSendingTradeToYourself); } - string[] modes = mode.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - - if (modes.Length == 0) { - return FormatBotResponse(string.Format(Strings.ErrorIsEmpty, nameof(modes))); - } - - HashSet transferTypes = new HashSet(); - - foreach (string singleMode in modes) { - switch (singleMode.ToUpper()) { - case "A": - case "ALL": - foreach (Steam.Asset.EType type in Enum.GetValues(typeof(Steam.Asset.EType))) { - transferTypes.Add(type); - } - - break; - case "BG": - case "BACKGROUND": - transferTypes.Add(Steam.Asset.EType.ProfileBackground); - break; - case "BO": - case "BOOSTER": - transferTypes.Add(Steam.Asset.EType.BoosterPack); - break; - case "C": - case "CARD": - transferTypes.Add(Steam.Asset.EType.TradingCard); - break; - case "E": - case "EMOTICON": - transferTypes.Add(Steam.Asset.EType.Emoticon); - break; - case "F": - case "FOIL": - transferTypes.Add(Steam.Asset.EType.FoilTradingCard); - break; - case "G": - case "GEMS": - transferTypes.Add(Steam.Asset.EType.SteamGems); - break; - case "U": - case "UNKNOWN": - transferTypes.Add(Steam.Asset.EType.Unknown); - break; - default: - return FormatBotResponse(string.Format(Strings.ErrorIsInvalid, mode)); - } - } - - (bool success, string output) = await Bot.Actions.SendTradeOffer(targetSteamID: targetBot.SteamID, wantedTypes: transferTypes).ConfigureAwait(false); + (bool success, string output) = await Bot.Actions.SendTradeOffer(targetSteamID: targetBot.SteamID, wantedTypes: Bot.BotConfig.TransferableTypes).ConfigureAwait(false); return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output)); } - private static async Task ResponseTransfer(ulong steamID, string botNames, string mode, string botNameTo) { - if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(mode) || string.IsNullOrEmpty(botNameTo)) { - ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(mode) + " || " + nameof(botNameTo)); + private static async Task ResponseTransfer(ulong steamID, string botNames, string botNameTo) { + if ((steamID == 0) || string.IsNullOrEmpty(botNames) || string.IsNullOrEmpty(botNameTo)) { + ASF.ArchiLogger.LogNullError(nameof(steamID) + " || " + nameof(botNames) + " || " + nameof(botNameTo)); return null; } @@ -2204,7 +2150,7 @@ namespace ArchiSteamFarm { return ASF.IsOwner(steamID) ? FormatStaticResponse(string.Format(Strings.BotNotFound, botNames)) : null; } - IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseTransfer(steamID, mode, botNameTo))).ConfigureAwait(false); + IList results = await Utilities.InParallel(bots.Select(bot => bot.Commands.ResponseTransfer(steamID, botNameTo))).ConfigureAwait(false); List responses = new List(results.Where(result => !string.IsNullOrEmpty(result))); return responses.Count > 0 ? string.Join(Environment.NewLine, responses) : null; @@ -2232,7 +2178,7 @@ namespace ArchiSteamFarm { return FormatBotResponse(Strings.BotSendingTradeToYourself); } - (bool success, string output) = await Bot.Actions.SendTradeOffer(targetSteamID: targetBot.SteamID, wantedRealAppIDs: realAppIDs).ConfigureAwait(false); + (bool success, string output) = await Bot.Actions.SendTradeOffer(targetSteamID: targetBot.SteamID, wantedTypes: Bot.BotConfig.TransferableTypes, wantedRealAppIDs: realAppIDs).ConfigureAwait(false); return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output)); } @@ -2246,22 +2192,10 @@ namespace ArchiSteamFarm { return null; } - if (!Bot.IsConnectedAndLoggedOn) { - return FormatBotResponse(Strings.BotNotConnected); - } - if (!Bot.Bots.TryGetValue(botNameTo, out Bot targetBot)) { return ASF.IsOwner(steamID) ? FormatBotResponse(string.Format(Strings.BotNotFound, botNameTo)) : null; } - if (!targetBot.IsConnectedAndLoggedOn) { - return FormatBotResponse(Strings.BotNotConnected); - } - - if (targetBot.SteamID == Bot.SteamID) { - return FormatBotResponse(Strings.BotSendingTradeToYourself); - } - string[] appIDTexts = realAppIDsText.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (appIDTexts.Length == 0) { return FormatBotResponse(string.Format(Strings.ErrorIsEmpty, nameof(appIDTexts))); @@ -2276,8 +2210,7 @@ namespace ArchiSteamFarm { realAppIDs.Add(appID); } - (bool success, string output) = await Bot.Actions.SendTradeOffer(targetSteamID: targetBot.SteamID, wantedRealAppIDs: realAppIDs).ConfigureAwait(false); - return FormatBotResponse(success ? output : string.Format(Strings.WarningFailedWithError, output)); + return await ResponseTransferByRealAppIDs(steamID, realAppIDs, targetBot).ConfigureAwait(false); } private static async Task ResponseTransferByRealAppIDs(ulong steamID, string botNames, string realAppIDsText, string botNameTo) { diff --git a/ArchiSteamFarm/Trading.cs b/ArchiSteamFarm/Trading.cs index cc3192898..7eb463ab4 100644 --- a/ArchiSteamFarm/Trading.cs +++ b/ArchiSteamFarm/Trading.cs @@ -212,7 +212,7 @@ namespace ArchiSteamFarm { if (results.Any(result => (result != null) && ((result.Result == ParseTradeResult.EResult.AcceptedWithItemLose) || (result.Result == ParseTradeResult.EResult.AcceptedWithoutItemLose))) && Bot.BotConfig.SendOnFarmingFinished) { // If we finished a trade, perform a loot if user wants to do so - await Bot.Actions.SendTradeOffer().ConfigureAwait(false); + await Bot.Actions.SendTradeOffer(wantedTypes: Bot.BotConfig.LootableTypes).ConfigureAwait(false); } } diff --git a/ArchiSteamFarm/config/example.json b/ArchiSteamFarm/config/example.json index 4e4df20a3..4a02fafed 100644 --- a/ArchiSteamFarm/config/example.json +++ b/ArchiSteamFarm/config/example.json @@ -32,5 +32,10 @@ "SteamTradeToken": null, "SteamUserPermissions": {}, "TradingPreferences": 0, + "TransferableTypes": [ + 1, + 3, + 5 + ], "UseLoginKeys": true }