Beispiel #1
0
 public JObject PutEmptyStickered(
     [PathParam] string data)
 {
     string[] splitter = data.Split('_');
     unstickeredCache.Add(long.Parse(splitter[0]), long.Parse(splitter[1]));
     return(new JObject
     {
         ["success"] = true
     });
 }
Beispiel #2
0
        public void EndToEnd()
        {
            EmptyStickeredDatabase database = new EmptyStickeredDatabase();

            CheckDump(database);
            for (int i = 0; i < 100; ++i)
            {
                database.Add(i, i * i);
                CheckDump(database);
                Assert.IsTrue(database.NoStickers(i, i * i));
            }
        }
Beispiel #3
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);
            }
        }