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 }); }
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)); } }
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); } }