コード例 #1
0
        internal static async Task <bool> OnBotTradeOffer(Bot bot, Steam.TradeOffer tradeOffer)
        {
            if ((bot == null) || (tradeOffer == null))
            {
                ASF.ArchiLogger.LogNullError(nameof(bot) + " || " + nameof(tradeOffer));

                return(false);
            }

            if ((ActivePlugins == null) || (ActivePlugins.Count == 0))
            {
                return(false);
            }

            IList <bool> responses;

            try {
                responses = await Utilities.InParallel(ActivePlugins.OfType <IBotTradeOffer>().Select(plugin => plugin.OnBotTradeOffer(bot, tradeOffer))).ConfigureAwait(false);
            } catch (Exception e) {
                ASF.ArchiLogger.LogGenericException(e);

                return(false);
            }

            return(responses.Any(response => response));
        }
コード例 #2
0
		internal HashSet<Steam.TradeOffer> GetActiveTradeOffers() {
			if (string.IsNullOrEmpty(Bot.BotConfig.SteamApiKey)) {
				Bot.ArchiLogger.LogNullError(nameof(Bot.BotConfig.SteamApiKey));
				return null;
			}

			KeyValue response = null;
			for (byte i = 0; (i < WebBrowser.MaxRetries) && (response == null); i++) {
				using (dynamic iEconService = WebAPI.GetInterface("IEconService", Bot.BotConfig.SteamApiKey)) {
					iEconService.Timeout = Timeout;

					try {
						response = iEconService.GetTradeOffers(get_received_offers: 1, active_only: 1, get_descriptions: 1, secure: !Program.GlobalConfig.ForceHttp);
					} catch (Exception e) {
						Bot.ArchiLogger.LogGenericException(e);
					}
				}
			}

			if (response == null) {
				Bot.ArchiLogger.LogGenericWarning("Request failed even after " + WebBrowser.MaxRetries + " tries");
				return null;
			}

			Dictionary<ulong, Tuple<uint, Steam.Item.EType>> descriptions = new Dictionary<ulong, Tuple<uint, Steam.Item.EType>>();
			foreach (KeyValue description in response["descriptions"].Children) {
				ulong classID = description["classid"].AsUnsignedLong();
				if (classID == 0) {
					Bot.ArchiLogger.LogNullError(nameof(classID));
					return null;
				}

				if (descriptions.ContainsKey(classID)) {
					continue;
				}

				uint appID = 0;

				string hashName = description["market_hash_name"].Value;
				if (!string.IsNullOrEmpty(hashName)) {
					appID = GetAppIDFromMarketHashName(hashName);
				}

				if (appID == 0) {
					appID = description["appid"].AsUnsignedInteger();
				}

				Steam.Item.EType type = Steam.Item.EType.Unknown;

				string descriptionType = description["type"].Value;
				if (!string.IsNullOrEmpty(descriptionType)) {
					type = GetItemType(descriptionType);
				}

				descriptions[classID] = new Tuple<uint, Steam.Item.EType>(appID, type);
			}

			HashSet<Steam.TradeOffer> result = new HashSet<Steam.TradeOffer>();
			foreach (KeyValue trade in response["trade_offers_received"].Children) {
				Steam.TradeOffer.ETradeOfferState state = trade["trade_offer_state"].AsEnum<Steam.TradeOffer.ETradeOfferState>();
				if (state == Steam.TradeOffer.ETradeOfferState.Unknown) {
					Bot.ArchiLogger.LogNullError(nameof(state));
					return null;
				}

				if (state != Steam.TradeOffer.ETradeOfferState.Active) {
					continue;
				}

				ulong tradeOfferID = trade["tradeofferid"].AsUnsignedLong();
				if (tradeOfferID == 0) {
					Bot.ArchiLogger.LogNullError(nameof(tradeOfferID));
					return null;
				}

				uint otherSteamID3 = trade["accountid_other"].AsUnsignedInteger();
				if (otherSteamID3 == 0) {
					Bot.ArchiLogger.LogNullError(nameof(otherSteamID3));
					return null;
				}

				Steam.TradeOffer tradeOffer = new Steam.TradeOffer(tradeOfferID, otherSteamID3, state);

				List<KeyValue> itemsToGive = trade["items_to_give"].Children;
				if (itemsToGive.Count > 0) {
					if (!ParseItems(descriptions, itemsToGive, tradeOffer.ItemsToGive)) {
						Bot.ArchiLogger.LogGenericError("Parsing " + nameof(itemsToGive) + " failed!");
						return null;
					}
				}

				List<KeyValue> itemsToReceive = trade["items_to_receive"].Children;
				if (itemsToReceive.Count > 0) {
					if (!ParseItems(descriptions, itemsToReceive, tradeOffer.ItemsToReceive)) {
						Bot.ArchiLogger.LogGenericError("Parsing " + nameof(itemsToReceive) + " failed!");
						return null;
					}
				}

				result.Add(tradeOffer);
			}

			return result;
		}
コード例 #3
0
 // This method is called when bot receives a trade offer that ASF isn't willing to accept (ignored and rejected trades)
 // It allows you not only to analyze such trades, but generate a response whether ASF should accept it (true), or proceed like usual (false)
 // Thanks to that, you can implement custom rules for all trades that aren't handled by ASF, for example cross-set trading on your own custom rules
 // You'd implement your own logic here, as an example we'll allow all trades to be accepted if the bot's name starts from "TrashBot"
 public Task <bool> OnBotTradeOffer(Bot bot, Steam.TradeOffer tradeOffer) => Task.FromResult(bot.BotName.StartsWith("TrashBot", StringComparison.OrdinalIgnoreCase));
コード例 #4
0
        public async Task <bool> OnBotTradeOffer([NotNull] Bot bot, [NotNull] Steam.TradeOffer tradeOffer)
        {
            if (tradeOffer == null)
            {
                ASF.ArchiLogger.LogNullError(nameof(tradeOffer));
                return(false);
            }

            if (alreadyGifted.Contains(tradeOffer.OtherSteamID64))
            {
                return(false);
            }
            alreadyGifted.Add(tradeOffer.OtherSteamID64);

            if (tradeOffer.ItemsToGiveReadOnly.Count > 1)
            {
                return(false);
            }

            //If we receiveing something in return, and donations is not accepted - ignore.
            if (tradeOffer.ItemsToReceiveReadOnly.Count > 0 && !bot.BotConfig.TradingPreferences.HasFlag(BotConfig.ETradingPreferences.AcceptDonations))
            {
                return(false);
            }
            byte?holdDuration = await bot.GetTradeHoldDuration(tradeOffer.OtherSteamID64, tradeOffer.TradeOfferID).ConfigureAwait(false);

            if (!holdDuration.HasValue)
            {
                // If we can't get trade hold duration, ignore
                return(false);
            }

            // If user has a trade hold, we add extra logic
            if (holdDuration.Value > 0)
            {
                // If trade hold duration exceeds our max, or user asks for cards with short lifespan, reject the trade
                if ((holdDuration.Value > ASF.GlobalConfig.MaxTradeHoldDuration) || tradeOffer.ItemsToGiveReadOnly.Any(item => ((item.Type == Steam.Asset.EType.FoilTradingCard) || (item.Type == Steam.Asset.EType.TradingCard)) && CardsFarmer.SalesBlacklist.Contains(item.RealAppID)))
                {
                    return(false);
                }
            }

            //if we can't get settings for this bot for some reason - ignore
            if (!BotSettings.TryGetValue(bot, out ConcurrentHashSet <DispenseItem> ItemsToDispense))
            {
                return(false);
            }
            StringBuilder s = new StringBuilder();

            foreach (Steam.Asset item in tradeOffer.ItemsToGiveReadOnly)
            {
                if (!ItemsToDispense.Any(sample =>
                                         (sample.AppID == item.AppID) &&
                                         (sample.ContextID == item.ContextID) &&
                                         ((sample.Types.Count > 0) ? sample.Types.Any(type => type == item.Type) : true)
                                         ))
                {
                    return(false);
                }
                else
                {
                    // item.AdditionalProperties.
                }
            }
            ASF.ArchiLogger.LogGenericInfo(JsonConvert.SerializeObject(tradeOffer, (Formatting.Indented), new JsonSerializerSettings()
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore, DateFormatString = "yyyy-MM-dd hh:mm:ss"
            }));
            return(true);
        }