Beispiel #1
0
        /// <summary>
        /// Reads how many days of escrow the user has
        /// </summary>
        /// <param name="trade">Trade object containing user information</param>
        /// <returns>Returns EscrowDuration class, if failed returns null</returns>
        public int GetUserEscrowWaitingPeriod(Config.TradeObject trade)
        {
            string url = "https://steamcommunity.com/tradeoffer/new/";

            SteamID steamId = new SteamID();

            steamId.SetFromUInt64(trade.SteamId);

            var data = new NameValueCollection();

            data.Add("partner", steamId.AccountID.ToString());
            data.Add("token", trade.RU_Token);

            string response = string.Empty;

            for (int i = 0; i < 3; i++)
            {
                try
                {
                    response = mSteam.Web.Fetch(url, "GET", data, false);
                }
                catch (WebException ex)
                {
                    var webResponse = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
                    mLogOffer.Write(Log.LogLevel.Error, $"Web exception when getting user escrow waiting period at {ex.Message}");
                }
            }

            return(Functions.ParseEscrowResponse(response));
        }
Beispiel #2
0
        /// <summary>
        /// Request items from a deposit
        /// </summary>
        /// <param name="steamid">User steamid64</param>
        /// <param name="tradeToken">User trade token</param>
        /// <param name="message">Message to include in offer</param>
        /// <param name="itemList">List of item ids</param>
        /// <returns>Returns empty string if failed, else offerid</returns>
        public string SendTradeOffer(Config.TradeObject trade, string message)
        {
            var offer = mSteam.TradeOfferManager.NewOffer(trade.SteamId);

            mLogOffer.Write(Log.LogLevel.Debug, $"Created new trade offer to user {trade.SteamId} to {trade.tradeType} with security token {trade.SecurityToken}.");

            var addedItems = new List <long>();

            foreach (var item in trade.Items)
            {
                if (item.AssetId == 0)
                {
                    mLog.Write(Log.LogLevel.Debug, $"AssetId for this item was 0. Skipping.");
                    break;
                }

                addedItems.Add(item.AssetId);
                switch (trade.tradeType)
                {
                /*For deposit we want to add their items*/
                case Config.TradeType.Deposit:
                    offer.Items.AddTheirItem(730, 2, item.AssetId);
                    mLogOffer.Write(Log.LogLevel.Debug, $"Added their item to trade. ClassID/AssetId: {item.ClassId}/{item.AssetId}");
                    break;

                /*As for withdraw we want to add our items*/
                case Config.TradeType.Withdraw:
                    offer.Items.AddMyItem(730, 2, item.AssetId);
                    mLogOffer.Write(Log.LogLevel.Debug, $"Added my item to trade. ClassID/AssetId: {item.ClassId}/{item.AssetId}");
                    break;
                }
            }

            if (addedItems.Count == 0)
            {
                mLog.Write(Log.LogLevel.Warn, $"No items to add to trade");
                return(string.Empty);
            }

            return(RequestTradeOffer(offer, trade, message));
        }
Beispiel #3
0
        /// <summary>
        /// Checks if a user has an escrow waiting period
        /// </summary>
        /// <param name="trade">Trade to check</param>
        /// <returns>Returns true if it's ok to trade</returns>
        private bool IsUserEscrowReady(Config.TradeObject trade)
        {
            int daysTheirEscrow = mBotHost.GetUserEscrowWaitingPeriod(trade);

            if (daysTheirEscrow > 0)
            {
                /*User has an escrow waiting period, which means we can't sent the trade to them*/
                mLog.Write(Log.LogLevel.Error, $"User {trade.SteamId} has an escrow waiting period of {daysTheirEscrow} days. Will not continue.");
                trade.tradeStatus.Status = trade.tradeType == Config.TradeType.Deposit ? Config.TradeStatusType.DepositDeclined : Config.TradeStatusType.WithdrawDeclined;

                /*123 is the default number that means something went wrong with the request*/
                if (daysTheirEscrow == 123)
                {
                    mLog.Write(Log.LogLevel.Info, $"123 days means that it failed to check how many days the user has left.");
                }

                return(false);
            }

            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Sends trade offer to user
        /// </summary>
        /// <param name="offer">Offer to send</param>
        /// <returns>Returns empty if failed, else offer id</returns>
        private string RequestTradeOffer(TradeOffer offer, Config.TradeObject trade, string message)
        {
            string offerId      = string.Empty;
            string exceptionMsg = string.Empty;

            for (int i = 0; i < 5; i++)
            {
                try
                {
                    if (offer.SendWithToken(out offerId, trade.RU_Token, message))
                    {
                        mLogOffer.Write(Log.LogLevel.Debug, $"Trade offer sent to user {offer.PartnerSteamId} with id {offerId}");
                        break;
                    }
                }
                catch (WebException ex)
                {
                    var respStream = ex?.Response?.GetResponseStream();
                    if (respStream != null)
                    {
                        var read = new StreamReader(respStream).ReadToEnd();
                        exceptionMsg = $"Webexeption: {read}";
                    }
                }
                catch (Exception ex)
                {
                    exceptionMsg = $"Exception: {ex.Message}";
                }

                mLogOffer.Write(Log.LogLevel.Warn, $"Unable to send trade offer to user {trade.SteamId}. Trying again in 3 seconds.");
                Thread.Sleep(3000);
            }

            if (string.IsNullOrWhiteSpace(offerId))
            {
                mLogOffer.Write(Log.LogLevel.Error, $"Failed to send trade offer to user {trade.SteamId}. Error: {exceptionMsg}");
            }

            return(offerId);
        }
Beispiel #5
0
        /// <summary>
        /// Updates the bot owner of items
        /// </summary>
        /// <param name="trade">tradeobject</param>
        /// <param name="ownerId">owner to update to</param>
        public void UpdateItemOwners(Config.TradeObject trade)
        {
            using (var transaction = mSqlCon.BeginTransaction())
            {
                foreach (var item in trade.Items)
                {
                    using (var cmd = new SQLiteCommand($"UPDATE items SET BotOwner = {trade.SteamId} WHERE ID = {item.ID}", mSqlCon))
                    {
                        cmd.ExecuteNonQuery();
                    }
                }

                try
                {
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    mLog.Write(Log.LogLevel.Info, $"Error updating items ex: {ex.Message}");
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Deal with deposit offers
        /// </summary>
        /// <param name="trade">TradeObject</param>
        private Config.TradeStatus HandleDeposit(Config.TradeObject trade)
        {
            /*Attempt to send the trade offer to user*/
            mLog.Write(Log.LogLevel.Info, $"Attempting to send deposit trade offer to {trade.SteamId} with token {trade.SecurityToken}");
            string offerId = mBotHost.SendTradeOffer(trade, $"{EndPoints.Website.DOMAIN.ToUpper()} DEPOSIT | {trade.SecurityToken}");

            if (string.IsNullOrWhiteSpace(offerId))
            {
                /*Trade offer id was empty, so that means the offer failed to send*/
                mLog.Write(Log.LogLevel.Error, $"Deposit trade offer was not sent to user {trade.SteamId}");
                trade.tradeStatus.Status = Config.TradeStatusType.DepositDeclined;
            }
            else
            {
                /*Offer was sent successfully*/
                mLog.Write(Log.LogLevel.Success, $"Deposit trade offer was sent to user {trade.SteamId}");
                trade.tradeStatus.Status    = Config.TradeStatusType.DepositSent;
                trade.tradeStatus.Tradelink = offerId;
                mActiveTradesListQueue.Add(trade);
            }

            return(trade.tradeStatus);
        }
Beispiel #7
0
        /// <summary>
        /// Deal with withdraw offers
        /// </summary>
        /// <param name="trade">TradeObject</param>
        private Config.TradeStatus HandleWithdraw(Config.TradeObject trade)
        {
            /*Get all items from database*/
            var itemList = new List <Config.Item>();

            foreach (var item in trade.Items.GroupBy(o => o.ClassId).Select(q => q.First()))
            {
                itemList.AddRange(mDatabase.FindEntries(Database.DBCols.ClassId, item.ClassId.ToString()));
            }

            /*Sort them so we'll best the best possible bots*/
            itemList = Functions.SortDBItems(itemList, trade.Items);
            mLog.Write(Log.LogLevel.Info, $"Found {itemList.Count} perfect items. Requested count: {trade.Items.Count}");

            /*We won't really do anything about this, but it's good to keep track of*/
            if (itemList.Count < trade.Items.Count)
            {
                mLog.Write(Log.LogLevel.Error, $"We found less items than what was requested");
            }

            /*Group up all the items depending on the owner*/
            var itemGroups = itemList.GroupBy(o => o.BotOwner);

            /*Go through all the groups*/
            int offersSent = 0;

            foreach (var group in itemGroups)
            {
                /*Find the bot that owns this item based on steamid*/
                var bot = mBotList.Find(o => o.GetBotSteamId64() == group.Key);

                /*Make sure we don't want to send a trade from hostbot to hostbot
                 * because obviously that won't work, dummy. And there's no need to*/
                if (bot.GetBotSteamId64() == mBotHost.GetBotSteamId64())
                {
                    continue;
                }

                /*Set up a trade object*/
                var storageTrade = new Config.TradeObject()
                {
                    Items       = FindUpdatedItems(bot.GetInventory(), group.ToList()),
                    RU_Token    = mBotHost.mSettings.tradeToken,
                    SteamId     = mBotHost.GetBotSteamId64(),
                    tradeType   = Config.TradeType.Withdraw,
                    tradeStatus = new Config.TradeStatus()
                };

                /*Send the trade offer*/
                var storeOfferId = bot.SendTradeOffer(storageTrade, EndPoints.Steam.STORAGE_MESSAGE);
                if (string.IsNullOrWhiteSpace(storeOfferId))
                {
                    mLog.Write(Log.LogLevel.Error, $"Inhouse offer wasn't sent");
                }
                else
                {
                    offersSent++;
                    mLog.Write(Log.LogLevel.Success, $"Inhouse trade offer sent");
                    mDatabase.InsertUsedItems(storageTrade.Items.Select(o => o.AssetId).ToList());
                    storageTrade.tradeStatus.Id = storeOfferId;
                    Thread.Sleep(1000);
                    bot.ConfirmTrades();
                }
            }

            /*Accept all trades on hostbot*/
            if (offersSent > 0)
            {
                Thread.Sleep(3000);
                mBotHost.GetOffers();
            }

            /*Get the new itemids for each item*/
            var newItemList = FindUpdatedItems(mBotHost.GetInventory(), itemList);

            if (newItemList.Count < itemList.Count)
            {
                mLog.Write(Log.LogLevel.Info, $"We're missing items to withdraw.");
                trade.tradeStatus.Status = Config.TradeStatusType.WithdrawDeclined;
                return(trade.tradeStatus);
            }
            else
            {
                /*Set the updated list to trade list*/
                trade.Items = newItemList;
            }

            /*Send the trade offer*/
            mLog.Write(Log.LogLevel.Info, $"Attempting to send withdraw trade offer to {trade.SteamId} with token {trade.SecurityToken}");
            string offerId = mBotHost.SendTradeOffer(trade, $"{EndPoints.Website.DOMAIN.ToUpper()} WITHDRAW | {trade.SecurityToken}");

            if (string.IsNullOrWhiteSpace(offerId))
            {
                /*Trade offer id was empty, so that means the offer failed to send*/
                mLog.Write(Log.LogLevel.Error, $"Withdraw trade offer was not sent to user {trade.SteamId}");
                trade.tradeStatus.Status = Config.TradeStatusType.WithdrawDeclined;
            }
            else
            {
                /*Offer was sent successfully, update the trade status*/
                mLog.Write(Log.LogLevel.Success, $"Withdraw trade offer was sent to user {trade.SteamId}");
                trade.tradeStatus.Status    = Config.TradeStatusType.WithdrawSent;
                trade.tradeStatus.Tradelink = offerId;

                /*Set state to sent which means that next withdraw won't pick the same items*/
                var idList = trade.Items.Select(o => o.ID).ToList();
                mDatabase.UpdateItemStates(idList, Database.ItemState.Sent);
                mDatabase.InsertUsedItems(trade.Items.Select(o => o.AssetId).ToList());
                mLog.Write(Log.LogLevel.Info, $"{idList.Count} items updated in the database");
                mActiveTradesListQueue.Add(trade);
            }

            return(trade.tradeStatus);
        }
Beispiel #8
0
        /// <summary>
        /// Sends items to storage bots
        /// </summary>
        private void SendItemsToStorage()
        {
            /*Check how many items in the database that belongs to the host bot*/
            var hostItemList = mDatabase.FindEntries(Database.DBCols.BotOwner, mBotHost.GetBotSteamId64().ToString());

            mLog.Write(Log.LogLevel.Debug, $"Host owns {hostItemList.Count} items that can be sent to storage");
            if (hostItemList.Count >= mSettings.hostItemLimit)
            {
                mLog.Write(Log.LogLevel.Info, $"We have {hostItemList.Count} items stored on Host. Moving some to storage.");

                /*Set all selected items to busy so they won't be touched*/
                mDatabase.UpdateItemStates(hostItemList.Select(o => o.ID).ToList(), Database.ItemState.Busy);

                /*Go through all storage bots*/
                foreach (var bot in mBotList.Where(o => o.mBotType == Bot.BotType.Storage))
                {
                    /*Load the inventory and skip if we have too many items*/
                    var inventory = bot.GetInventory(true);
                    if (inventory.Count() >= mSettings.itemLimitPerBot)
                    {
                        continue;
                    }

                    /*Get amount of free slots on the bot
                     * Although we need to limit it by n to ensure a stable offer*/
                    int inventorySlots = mSettings.itemLimitPerBot - inventory.Count();
                    if (inventorySlots > mSettings.storageTradeOfferMaxItems)
                    {
                        inventorySlots = mSettings.storageTradeOfferMaxItems;
                    }

                    /*Take items from the original list
                     * We also need to make sure we have more than one item to trade*/
                    var itemList = hostItemList.Take(inventorySlots).ToList();
                    if (itemList.Count() > 0)
                    {
                        /*Set up a trade object to the storage bot*/
                        var trade = new Config.TradeObject()
                        {
                            Items       = FindUpdatedItems(mBotHost.GetInventory(), itemList),
                            RU_Token    = bot.mSettings.tradeToken,
                            SteamId     = bot.GetBotSteamId64(),
                            tradeType   = Config.TradeType.Withdraw,
                            tradeStatus = new Config.TradeStatus()
                        };

                        /*Send trade offer from host bot to this bot*/
                        var offerId = mBotHost.SendTradeOffer(trade, EndPoints.Steam.STORAGE_MESSAGE);
                        if (string.IsNullOrWhiteSpace(offerId))
                        {
                            mLog.Write(Log.LogLevel.Error, $"Storage offer failed to send? Beep boop error pls fix");

                            /*Since the offer failed we set all the items back to active*/
                            mDatabase.UpdateItemStates(hostItemList.Select(o => o.ID).ToList(), Database.ItemState.Active);
                        }
                        else
                        {
                            mLog.Write(Log.LogLevel.Success, $"Storage offer sent to bot {bot.mSettings.username}");
                            trade.tradeStatus.Tradelink = offerId;

                            /*Add items sent to used items in the database*/
                            mDatabase.InsertUsedItems(trade.Items.Select(o => o.AssetId).ToList());

                            /*Set item state to storage sent*/
                            var idList = trade.Items.Select(o => o.ID).ToList();
                            mDatabase.UpdateItemStates(idList, Database.ItemState.OnHold);
                            mLog.Write(Log.LogLevel.Info, $"{idList.Count} items updated in the database to OnHold");
                            mActiveStorageTradesList.Add(trade);
                        }
                    }

                    /*Since we got this far then we can stop checking*/
                    break;
                }

                Thread.Sleep(1500);
            }
        }