Example #1
0
 public void Initialize()
 {
     logger.Info("Initializing core");
     InitializeEndpoints();
     httpListener.Start();
     VK.Init();
     logger.Success("Started serving");
     tokenSource = new CancellationTokenSource();
     ct          = tokenSource.Token;
     listener    = Task.Factory.StartNew(Listen, ct);
 }
Example #2
0
        public static string RawGet(string uri, WebHeaderCollection headers)
        {
            Log.Info($"Executing {uri} with headers {headers}");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

            request.Proxy = null;
            request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
            request.Headers = headers;
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                using (Stream stream = response.GetResponseStream())
                    using (StreamReader reader = new StreamReader(stream)) {
                        return(reader.ReadToEnd());
                    }
        }
Example #3
0
        public static async Task <bool> WaitForFalseOrTimeout(Func <bool> condition, int timeout)
        {
            if (timeout <= 3000)
            {
                await Task.Delay(timeout);

                return(!condition());
            }
            Console.WriteLine($"Timeout: {timeout}");
            var tokenSource2     = new CancellationTokenSource();
            CancellationToken ct = tokenSource2.Token;

            Task waitTask = Task.Run(async() => {
                try {
                    while (!ct.IsCancellationRequested && condition())
                    {
                        await Task.Delay(1000, ct);
                    }
                } catch (Exception) {
                }
            });
            Task delayTask = Task.Run(async() => {
                try {
                    await Task.Delay(timeout, ct);
                } catch (Exception) {
                }
            });
            Task temp = await Task.WhenAny(waitTask, delayTask);

            tokenSource2.Cancel();
            try {
                Task.WaitAll(waitTask, delayTask);
            } catch (Exception e) {
                taskLog.Info($"{e}");
            } finally {
                tokenSource2.Dispose();
            }
            return(temp == waitTask);
        }
Example #4
0
        public JObject PingPong(
            HttpListenerContext context,
            [PathParam] string botname)
        {
            logger.Info($"{botname} ping");
            LastPing[botname] = DateTime.Now;
            ipCache[botname]  = context.Request.RemoteEndPoint.ToString();

            return(new JObject
            {
                ["success"] = true,
                ["ping"] = "pong",
            });
        }
Example #5
0
        void RefreshConfig()
        {
            JObject data = JObject.Parse(Utility.Request.Get(Consts.Endpoints.BotConfig));

            if (!data.TryGetValue(botName, out JToken Jtoken))
            {
                Log.Error("Gist config contains no bot definition.");
            }
            else
            {
                JObject token = Jtoken as JObject;
                if (token.ContainsKey("obsolete_bot") && token["obsolete_bot"].Type == JTokenType.Boolean && (bool)token["obsolete_bot"])
                {
                    if (obsolete_bot != (bool)token["obsolete_bot"])
                    {
                        obsolete_bot = (bool)token["obsolete_bot"];
                        if (obsolete_bot)
                        {
                            Log.Info("Bot became obsolete.");
                        }
                        else
                        {
                            Log.Warn("Bot became non-obsolete");
                        }
                    }
                }
                if (token["stopsell"].Type != JTokenType.Integer)
                {
                    Log.Error("Have no idea when to stop selling");
                }
                else
                {
                    if (stopsell != (int)token["stopsell"])
                    {
                        stopsell = (int)token["stopsell"];
                    }
                }
                if (token["stopbuy"].Type != JTokenType.Boolean)
                {
                    Log.Error("Have no idea when to stop buying");
                }
                else
                {
                    if (stopbuy != (bool)token["stopbuy"])
                    {
                        stopbuy = (bool)token["stopbuy"];
                    }
                }

                if (token["sell_only"].Type != JTokenType.Boolean)
                {
                    Log.Error($"Sell only is not a boolean for {botName}");
                }
                else
                {
                    if (sellOnly != (bool)token["sell_only"])
                    {
                        Log.Info("Sellonly was changed from {0} to {1}", sellOnly, (bool)token["sell_only"]);
                        sellOnly = (bool)token["sell_only"];
                    }
                }

                if (token["want_to_buy"].Type != JTokenType.Float)
                {
                    Log.Error($"Want to buy is not a float for {botName}");
                }
                else
                {
                    if (WANT_TO_BUY != (double)token["want_to_buy"])
                    {
                        Log.Info("Want to buy was changed from {0} to {1}", WANT_TO_BUY, (double)token["want_to_buy"]);
                        WANT_TO_BUY = (double)token["want_to_buy"];
                    }
                }

                if (token["max_from_median"].Type != JTokenType.Float)
                {
                    Log.Error($"Max from median is not a float for {botName}");
                }
                else
                {
                    if (MAXFROMMEDIAN != (double)token["max_from_median"])
                    {
                        Log.Info("Max from median was changed from {0} to {1}", WANT_TO_BUY, (double)token["max_from_median"]);
                        MAXFROMMEDIAN = (double)token["max_from_median"];
                    }
                }

                if (token["unstickered_order"].Type != JTokenType.Float)
                {
                    Log.Error($"Unstickered order is not a float for {botName}");
                }
                else
                {
                    if (UNSTICKERED_ORDER != (double)token["unstickered_order"])
                    {
                        Log.Info("Unsctickered order was changed from {0} to {1}", UNSTICKERED_ORDER, (double)token["unstickered_order"]);
                        UNSTICKERED_ORDER = (double)token["unstickered_order"];
                    }
                }
                if (token["experiments"] != null)
                {
                    if (token["experiments"]["new_buy_formula"] is JToken new_buy_formula && new_buy_formula != null)
                    {
                        try {
                            DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
                            DateTime start      = DateTime.MinValue;
                            if (new_buy_formula["start"] != null)
                            {
                                start = dtDateTime.AddSeconds((double)new_buy_formula["start"]).ToLocalTime();
                            }
                            DateTime end = dtDateTime.AddSeconds((double)new_buy_formula["end"]).ToLocalTime();
                            if (DateTime.Now < end)
                            {
                                double        want_to_buy = (double)new_buy_formula["want_to_buy"];
                                NewBuyFormula temp        = new NewBuyFormula(start, end, want_to_buy);
                                if (newBuyFormula != temp)
                                {
                                    newBuyFormula = temp;
                                    Log.Info("New newBuyFormula applied:");
                                    Log.Info(new_buy_formula.ToString(Formatting.None));
                                }
                            }
                        } catch {
                            Log.Error("Incorrect experiment");
                        }
                    }
                    if (token["experiments"]["sell_multiplier"] is JToken sell_multiplier && sell_multiplier != null)
                    {
                        try {
                            DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
                            DateTime start      = DateTime.MinValue;
                            if (sell_multiplier["start"] != null)
                            {
                                start = dtDateTime.AddSeconds((double)sell_multiplier["start"]).ToLocalTime();
                            }
                            DateTime end = dtDateTime.AddSeconds((double)sell_multiplier["end"]).ToLocalTime();
                            if (DateTime.Now < end)
                            {
                                double         sellmultiplier = (double)sell_multiplier["multiplier"];
                                SellMultiplier temp           = new SellMultiplier(start, end, sellmultiplier);
                                if (sellMultiplier != temp)
                                {
                                    sellMultiplier = temp;
                                    Log.Info("New sellmultiplier applied:");
                                    Log.Info(sell_multiplier.ToString(Formatting.None));
                                }
                            }
                        } catch {
                            Log.Error("Incorrect experiment");
                        }
                    }
                }
            }
        }
Example #6
0
        private void Process(object o)
        {
            var     context = o as HttpListenerContext;
            JObject resp    = null;

            try {
                logger.Info($"[Request {++requestsServed}] {context.Request.RemoteEndPoint.ToString()} - {context.Request.Url.AbsolutePath}");
                string Endpoint = context.Request.Url.AbsolutePath;
                if (Endpoint == Consts.Endpoints.GetBestToken)
                {
                    var Forced = coreConfig.Bots.Where(x => x.Force && PingedRecently(x.Username));
                    if (Forced.Any())
                    {
                        BotConfig forcedBot = Forced.First();
                        resp = new JObject {
                            ["success"] = true,
                            ["token"]   = TokenCache[forcedBot.Username],
                            ["botname"] = forcedBot.Username,
                        };
                    }
                    else
                    {
                        var Filtered = CurSizes.Where(t => t.Value < Consts.CRITICALTHRESHHOLD && PingedRecently(t.Key));
                        if (!Filtered.Any())
                        {
                            throw new Exception("All bots are overflowing!");
                        }
                        KeyValuePair <string, int> kv = Filtered.OrderBy(
                            t => t.Value / coreConfig.Bots.First(x => x.Username == t.Key).Weight
                            ).FirstOrDefault();
                        if (kv.Key == null)
                        {
                            throw new Exception("Don't know about bot inventory sizes");
                        }

                        JToken extrainfo = new JObject();
                        foreach (var kvp in CurSizes)
                        {
                            extrainfo[kvp.Key] = new JObject {
                                ["inventorysize"] = kvp.Value
                            };
                        }
                        NameValueCollection qscoll = HttpUtility.ParseQueryString(context.Request.Url.Query);
                        bool extradb = qscoll.AllKeys.Contains("extradb");
                        foreach (var key in qscoll.AllKeys)
                        {
                            if (key == "dbhit")
                            {
                                int value = int.Parse(qscoll[key]);
                                foreach (var kvp in salesHistorySizes)
                                {
                                    while (kvp.Value.TryPeek(out var result))
                                    {
                                        if (DateTime.Now.Subtract(result.First).TotalHours <= 1)
                                        {
                                            break;
                                        }
                                        if (!kvp.Value.TryDequeue(out result))
                                        {
                                            break;
                                        }
                                    }
                                    if (!kvp.Value.IsEmpty)
                                    {
                                        extrainfo[kvp.Key]["dbhit"] = kvp.Value.Where(x => x.Second >= value).Count() / (double)kvp.Value.Count;
                                        if (extradb)
                                        {
                                            extrainfo[kvp.Key]["dbcnt"] = kvp.Value.Count;
                                        }
                                    }
                                }
                            }
                        }
                        resp = new JObject {
                            ["success"]   = true,
                            ["token"]     = TokenCache[kv.Key],
                            ["botname"]   = kv.Key,
                            ["extrainfo"] = extrainfo
                        };
                    }
                }
                else if (Endpoint == Consts.Endpoints.BanUser)
                {
                    long id = context.Request.QueryString["id"] == null ? -1 : long.Parse(context.Request.QueryString["id"]);
                    if (id == -1)
                    {
                        throw new Exception($"Id {id} doesn't look good");
                    }
                    if (mongoBannedUsers.Add(id))
                    {
                        resp = new JObject {
                            ["success"] = true
                        };
                    }
                    else
                    {
                        throw new Exception($"Could not add user (possibly he is present)");
                    }
                }
                else if (Endpoint == Consts.Endpoints.UnBanUser)
                {
                    long id = context.Request.QueryString["id"] == null ? -1 : long.Parse(context.Request.QueryString["id"]);
                    if (id == -1)
                    {
                        throw new Exception($"Id {id} doesn't look good");
                    }
                    if (mongoBannedUsers.Delete(id))
                    {
                        resp = new JObject {
                            ["success"] = true
                        };
                    }
                    else
                    {
                        throw new Exception($"Could not delete user (possibly he isn't in banned)");
                    }
                }
                else if (Endpoint == Consts.Endpoints.GetBannedUsers)
                {
                    var stuff = new JArray(mongoBannedUsers.GetBannedUsers().Select(user => user.SteamID64));
                    resp = new JObject {
                        ["success"]  = true,
                        ["userlist"] = stuff
                    };
                }
                else if (Endpoint == Consts.Endpoints.PutTradeToken)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname") ?? new string[0];
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    string[] data = context.Request.Headers.GetValues("data") ?? new string[0];
                    if (data.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 data, {data.Length} were provided");
                    }
                    TokenCache[usernames[0]] = data[0];
                    resp = new JObject {
                        ["success"] = true
                    };
                }
                else if (Endpoint == Consts.Endpoints.PutCurrentInventory)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname") ?? new string[0];
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    string[] data = context.Request.Headers.GetValues("data") ?? new string[0];
                    if (data.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 data, {data.Length} were provided");
                    }
                    CurSizes[usernames[0]] = int.Parse(data[0]);
                    resp = new JObject {
                        ["success"] = true
                    };
                }
                else if (Endpoint == Consts.Endpoints.GetAuthFile)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname") ?? new string[0];
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    string authPath = Path.Combine("authfiles", usernames[0] + ".auth");
                    if (File.Exists(authPath))
                    {
                        resp = new JObject {
                            ["success"] = true,
                            ["data"]    = File.ReadAllText(authPath)
                        };
                    }
                    else
                    {
                        resp = new JObject {
                            ["success"] = false,
                            ["error"]   = "File not found"
                        };
                    }
                }
                else if (Endpoint == Consts.Endpoints.PutEmptyStickered)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname") ?? new string[0];
                    string[] data      = context.Request.Headers.GetValues("data") ?? new string[0];
                    if (data.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 data, {data.Length} were provided");
                    }
                    string[] splitter = data[0].Split('_');
                    unstickeredCache.Add(long.Parse(splitter[0]), long.Parse(splitter[1]));
                    resp = new JObject {
                        ["success"] = true
                    };
                }
                else if (Endpoint == Consts.Endpoints.GetConfig)
                {
                    BotConfig chosen = null;
                    foreach (BotConfig bot in coreConfig.Bots)
                    {
                        if (ipCache.TryGetValue(bot.Username, out string ip) && ip == context.Request.RemoteEndPoint.ToString())
                        {
                            chosen = bot;
                            break;
                        }
                    }
                    if (chosen == null)
                    {
                        foreach (BotConfig bot in coreConfig.Bots)
                        {
                            if (LastPing.TryGetValue(bot.Username, out DateTime dt))
                            {
                                if (DateTime.Now.Subtract(dt).TotalSeconds > 120)
                                {
                                    chosen = bot;
                                    break;
                                }
                            }
                            else
                            {
                                chosen = bot;
                                break;
                            }
                        }
                    }
                    if (chosen == null)
                    {
                        resp = new JObject {
                            ["success"] = false,
                            ["error"]   = "No free instance available"
                        };
                    }
                    else
                    {
                        Configuration cfg = JsonConvert.DeserializeObject <Configuration>(JsonConvert.SerializeObject(coreConfig));

                        cfg.Bots = new BotInfo[] {
                            JsonConvert.DeserializeObject <BotInfo>(JsonConvert.SerializeObject(chosen))
                        };
                        resp = new JObject {
                            ["success"] = true,
                            ["config"]  = JObject.FromObject(cfg)
                        };
                    }
                }
                else if (Endpoint == Consts.Endpoints.MongoFind)
                {
                    string query = context.Request.QueryString["query"] ?? "{}";
                    int    limit = int.Parse(context.Request.QueryString["limit"] ?? "-1");
                    int    skip  = int.Parse(context.Request.QueryString["skip"] ?? "-1");
                    //TODO(noobgam): add other tables
                    var    filtered = mongoLogs.Find(query, limit, skip);
                    var    cursor   = filtered.ToCursor();
                    JArray logs     = new JArray();
                    while (cursor.MoveNext())
                    {
                        foreach (var msg in cursor.Current)
                        {
                            logs.Add(msg.ToString());
                        }
                    }
                    resp = new JObject {
                        ["success"]   = true,
                        ["extrainfo"] = logs
                    };
                }
                else if (Endpoint == Consts.Endpoints.PingPong)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname") ?? new string[0];
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    logger.Info($"{usernames[0]} ping");
                    LastPing[usernames[0]] = DateTime.Now;
                    ipCache[usernames[0]]  = context.Request.RemoteEndPoint.ToString();

                    resp = new JObject {
                        ["success"] = true,
                        ["ping"]    = "pong",
                    };
                }
                else if (Endpoint == Consts.Endpoints.SalesHistorySize)
                {
                    // deprecated
                    string[] usernames = context.Request.Headers.GetValues("botname");
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    string[] data = context.Request.Headers.GetValues("data");
                    if (data.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 data, {data.Length} were provided");
                    }
                    if (!salesHistorySizes.ContainsKey(usernames[0]))
                    {
                        salesHistorySizes[usernames[0]] = new ConcurrentQueue <Pair <DateTime, int> >();
                    }
                    salesHistorySizes[usernames[0]].Enqueue(new Pair <DateTime, int>(DateTime.Now, int.Parse(data[0])));
                }
                else if (Endpoint == Consts.Endpoints.PutTradableCost)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname");
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    string[] data = context.Request.Headers.GetValues("data");
                    if (data.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 data, {data.Length} were provided");
                    }
                    string[] stuff = data[0].Split(':');
                    CurTradable[usernames[0]]  = double.Parse(stuff[0]);
                    CurUntracked[usernames[0]] = int.Parse(stuff[1]);
                    resp = new JObject {
                        ["success"] = true
                    };
                }
                else if (Endpoint == Consts.Endpoints.PutMedianCost)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname");
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    string[] data = context.Request.Headers.GetValues("data");
                    if (data.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 data, {data.Length} were provided");
                    }
                    CurMedian[usernames[0]] = double.Parse(data[0]);
                    resp = new JObject {
                        ["success"] = true
                    };
                }
                else if (Endpoint == Consts.Endpoints.PutMoney)
                {
                    string[] usernames = context.Request.Headers.GetValues("botname");
                    if (usernames.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 username, {usernames.Length} were provided");
                    }
                    string[] data = context.Request.Headers.GetValues("data");
                    if (data.Length != 1)
                    {
                        throw new Exception($"You have to provide 1 data, {data.Length} were provided");
                    }
                    CurMoney[usernames[0]] = int.Parse(data[0]);
                    resp = new JObject {
                        ["success"] = true
                    };
                }
                else if (Endpoint == Consts.Endpoints.GetSalesDatabase)
                {
                    byte[] bytes = File.ReadAllBytes(Path.Combine("assets", "newDatabase"));
                    resp = new JObject {
                        ["success"] = true,
                        ["data"]    = StringUtils.ToBase64(bytes)
                    };
                }
                else if (Endpoint == Consts.Endpoints.GetEmptyStickeredDatabase)
                {
                    string[] lines = unstickeredCache.Dump();
                    byte[]   bytes = BinarySerialization.NS.Serialize(lines, true);
                    resp = new JObject {
                        ["success"] = true,
                        ["data"]    = StringUtils.ToBase64(bytes)
                    };
                }
                else if (Endpoint == Consts.Endpoints.GetSalesDatabase)
                {
                    byte[] bytes = BinarySerialization.NS.Serialize(unstickeredCache);
                    resp = new JObject {
                        ["success"] = true,
                        ["data"]    = StringUtils.ToBase64(bytes)
                    };
                }
                else if (Endpoint == Consts.Endpoints.RPS)
                {
                    resp = new JObject {
                        ["success"] = true,
                        //["rps"] = Balancer.GetNewItemsRPS()
                    };
                }
                else if (Endpoint == Consts.Endpoints.Status)
                {
                    bool   full      = context.Request.QueryString["full"] == null ? false : bool.Parse(context.Request.QueryString["full"]);
                    bool   table     = context.Request.QueryString["table"] == null ? false : bool.Parse(context.Request.QueryString["table"]);
                    JToken extrainfo = new JObject();
                    double moneySum  = 0;
                    foreach (var kvp in CurSizes)
                    {
                        if (extrainfo[kvp.Key] == null)
                        {
                            extrainfo[kvp.Key] = new JObject();
                        }
                        extrainfo[kvp.Key]["inventorysize"] = kvp.Value;
                    }
                    foreach (var kvp in CurMoney)
                    {
                        double myMoney = (double)kvp.Value / 100;
                        if (full)
                        {
                            if (extrainfo[kvp.Key] == null)
                            {
                                extrainfo[kvp.Key] = new JObject();
                            }
                            extrainfo[kvp.Key]["curmoney"] = myMoney.ToString("C", new CultureInfo("ru-RU"));
                        }
                        moneySum += myMoney;
                    }
                    foreach (var kvp in CurMedian)
                    {
                        if (kvp.Value == 0)
                        {
                            continue;
                        }
                        if (extrainfo[kvp.Key] == null)
                        {
                            extrainfo[kvp.Key] = new JObject();
                        }
                        extrainfo[kvp.Key]["median_sum"] = kvp.Value.ToString("C", new CultureInfo("en-US"));
                    }
                    double usd_trade_sum = 0;
                    foreach (var kvp in CurTradable)
                    {
                        if (full)
                        {
                            if (extrainfo[kvp.Key] == null)
                            {
                                extrainfo[kvp.Key] = new JObject();
                            }
                            extrainfo[kvp.Key]["tradable_usd_cost"] = kvp.Value.ToString("C", new CultureInfo("en-US"));
                        }
                        usd_trade_sum += kvp.Value;
                    }
                    resp = new JObject {
                        ["success"]   = true,
                        ["extrainfo"] = extrainfo,
                        ["moneysum"]  = new JObject()
                        {
                            ["RUB"]   = moneySum,
                            ["USD"]   = Economy.ConvertCurrency(Economy.Currency.RUB, Economy.Currency.USD, moneySum).ToString("C", new CultureInfo("en-US")),
                            ["TRADE"] = usd_trade_sum.ToString("C", new CultureInfo("en-US"))
                        }
                    };
                    if (table)
                    {
                        if (RespondTable(context, resp))
                        {
                            return;
                        }
                    }
                }
                if (resp == null)
                {
                    resp = new JObject {
                        ["success"] = false,
                        ["error"]   = "Unsupported request"
                    }
                }
                ;
                Respond(context, resp);
            } catch (Exception ex) {
                resp = new JObject {
                    ["success"] = false,
                    ["error"]   = ex.Message,
                    ["trace"]   = ex.StackTrace
                };
                Respond(context, resp);
            }
        }