public void PreProcessGameList(ref JObject Paramaters, ref List <GameData> RawGames, ref Dictionary <string, JObject> ExtraData) { bool DoProxy = true; try { DoProxy = Paramaters["__pluginProxy"]?.Value <bool?>() ?? DoProxy; } catch { } bool ShowSource = false; try { ShowSource = Paramaters["__pluginShowSource"]?.Value <bool?>() ?? ShowSource; } catch { } bool ShowStatus = false; try { ShowStatus = Paramaters["__pluginShowStatus"]?.Value <bool?>() ?? ShowStatus; } catch { } bool QueryServers = false; try { QueryServers = Paramaters["__pluginQueryServers"]?.Value <bool?>() ?? QueryServers; } catch { } if (QueryServers) { lock (pongCache) { pongCache.Where(dr => dr.Value.cacheTime.AddSeconds(30) < DateTime.UtcNow).Select(dr => dr.Key).ToList().ForEach(dr => pongCache.Remove(dr)); } } long rowIdCounter = -1; { GameData hardCodedGame = new GameData() { addr = @"0.0.0.0:17770", clientReqId = 0, gameId = "BZ2", lastUpdate = DateTime.UtcNow, rowId = rowIdCounter--, rowPW = string.Empty, timeoutSec = 300, //updatePw = string.Empty }; hardCodedGame.GameAttributes.Add(new CustomGameDataField() { Key = "n", Value = "\"IonDriver Bismuth (Raknet Master2 Emulator)\"" }); hardCodedGame.GameAttributes.Add(new CustomGameDataField() { Key = "l", Value = "\"1\"" }); hardCodedGame.GameAttributes.Add(new CustomGameDataField() { Key = "m", Value = "\"bismuth\"" }); //hardCodedGame.GameAttributes.Add(new CustomGameDataField("d", string.Empty)); //hardCodedGame.GameAttributes.Add(new CustomGameDataField("k", 1.ToString())); //hardCodedGame.GameAttributes.Add(new CustomGameDataField("t", 7.ToString())); //hardCodedGame.GameAttributes.Add(new CustomGameDataField("r", @"@ZA@d1")); //hardCodedGame.GameAttributes.Add(new CustomGameDataField("v", @"S1")); RawGames.Add(hardCodedGame); } JObject statusData = null; if (DoProxy && ShowStatus) { statusData = new JObject(); } if (DoProxy) { object counterLock = new object(); int counter = sources.Count; sources.AsParallel().ForAll(dr => { RemoteCallStatus cacheType = RemoteCallStatus.cached; try { if (dr.Date == null || dr.Date.AddMilliseconds(dr.Stale) < DateTime.UtcNow) { cacheType = RemoteCallStatus.none; //lock (dr) dr.WebRequestActive.Wait(); //await dr.WebRequestActive.WaitAsync(); try { // make sure another thread didn't do this for us while we were locked if (dr.Date == null || dr.Date.AddMilliseconds(dr.Stale) < DateTime.UtcNow) { try { using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromMilliseconds(dr.Timeout); //var response = await client.GetAsync(dr.Url); var responseTask = client.GetAsync(dr.Url); responseTask.Wait(); if (responseTask.IsCompleted && !responseTask.IsCanceled && !responseTask.IsFaulted) { var response = responseTask.Result; if (response.IsSuccessStatusCode) { dr.LastData = JObject.Parse(response.Content.ReadAsStringAsync().Result); dr.Date = DateTime.UtcNow; cacheType = RemoteCallStatus.@new; } else if (dr.Date == null || dr.Date.AddMilliseconds(dr.MaxStale) < DateTime.UtcNow) { // we failed to get data and it's too old, so destroy the cache dr.LastData = null; dr.Date = DateTime.UtcNow; cacheType = RemoteCallStatus.expired; } } else if (dr.Date == null || dr.Date.AddMilliseconds(dr.MaxStale) < DateTime.UtcNow) { // we failed to get data and it's too old, so destroy the cache dr.LastData = null; dr.Date = DateTime.UtcNow; cacheType = RemoteCallStatus.expired; } } } catch (Exception ex) { if (dr.Date == null || dr.Date.AddMilliseconds(dr.MaxStale) < DateTime.UtcNow) { dr.LastData = null; dr.Date = DateTime.UtcNow; } } } } finally { dr.WebRequestActive.Release(); } } } //catch(Exception ex) //{ // Console.WriteLine(ex.ToString()); //} finally { if (ShowStatus) { var tmp = new JObject(); tmp["updated"] = dr.Date; tmp["status"] = cacheType.ToString(); tmp["success"] = dr.LastData != null; lock (statusData) { statusData[dr.ProxySource] = tmp; } } lock (counterLock) { counter--; } } }); // the async member inside appears to be causing it to not join, but I can't await it so I have to do a block while (counter > 0) { Thread.Sleep(100); } HashSet <int> usedPorts = new HashSet <int>() { 17770 }; // start with hardcoded game already there // clone list so that it can't be modified under us by another thread List <ListSource> sourcesClone = sources.ToList(); foreach (ListSource source in sourcesClone) { if (source.LastData != null) { RawGames.AddRange(((JArray)(source.LastData["GET"])).Cast <JObject>().ToList().Select(dr => { string addressPossibleRemap = string.Empty; try { string[] urlbits = dr["__addr"].Value <string>().Split(':'); if (urlbits.Length > 0 && urlbits.Length <= 2 && urlbits[0] == "0.0.0.0") { int portNum = 17770; string port = urlbits.Length > 1 ? urlbits[1] : "17770"; if (!int.TryParse(port, out portNum)) { portNum = 17770; } while (usedPorts.Contains(portNum)) { portNum++; } usedPorts.Add(portNum); if (portNum != 17770) { addressPossibleRemap = urlbits[0] + ":" + portNum; } else { addressPossibleRemap = dr["__addr"].Value <string>(); } } else { addressPossibleRemap = dr["__addr"].Value <string>(); } } catch { addressPossibleRemap = dr["__addr"].Value <string>(); } try { GameData remoteGame = new GameData() { addr = addressPossibleRemap,//dr["__addr"].Value<string>(), clientReqId = dr["__clientReqId"]?.Value <long>(), gameId = dr["__gameId"]?.Value <string>() ?? "BZ2", lastUpdate = DateTime.UtcNow, rowId = rowIdCounter--, rowPW = string.Empty, timeoutSec = dr["__timeoutSec"]?.Value <long>() ?? 60, //updatePw = string.Empty }; dr.Properties().ToList().ForEach(dx => { if (!dx.Name.StartsWith("__") && dx.Value.Type != JTokenType.Null) { remoteGame.GameAttributes.Add(new CustomGameDataField() { Key = dx.Name, Value = (dx.Value.Type == JTokenType.String ? ("\"" + dx.Value.ToString() + "\"") : dx.Value.ToString()) }); } }); if (ShowSource) { remoteGame.GameAttributes.Add(new CustomGameDataField() { Key = "proxySource", Value = "\"" + source.ProxySource + "\"" }); } //rawGames.Add(kebbzGame); return(remoteGame); } catch (Exception ex) { } return(null); }).Where(dr => dr != null)); } } } if (QueryServers) { RawGames.AsParallel().ForAll(game => { { RaknetPong packetOut = new RaknetPong();// { Players = true, Teams = true, ServerInfo = false }; IPEndPoint endPoint = null; { Uri url; IPAddress _ip; if (Uri.TryCreate(String.Format("http://{0}", game.addr), UriKind.Absolute, out url) && IPAddress.TryParse(url.Host, out _ip)) { endPoint = new IPEndPoint(_ip, url.IsDefaultPort ? 17770 : url.Port); } } if (endPoint != null) { try { lock (pongCache) { if (pongCache.ContainsKey(endPoint)) { game.CustomAttributes.Add("pong", pongCache[endPoint].data); return; } } UdpClient udpServer = new UdpClient(0); byte[] dataSend = packetOut.GetPacket(); var receivedData = udpServer.ReceiveAsync(); udpServer.SendAsync(dataSend, dataSend.Length, endPoint).Wait(); receivedData.Wait(1000); if (receivedData.IsCompleted && !receivedData.IsCanceled && !receivedData.IsFaulted) { var receivedData2 = receivedData.Result; RaknetPongResponse rakPong = null; using (MemoryStream mem = new MemoryStream(receivedData2.Buffer)) using (BinaryReader reader = new BinaryReader(mem)) { UInt32 PacketType = reader.ReadUInt32(); if (PacketType != 0x0000001c) { return; } byte nul = reader.ReadByte(); if (nul != 0x00) { return; } UInt32 Pong = reader.ReadUInt32(); if (Pong != packetOut.Ping) { return; } UInt64 Unknown1 = reader.ReadUInt64(); byte Switch1 = reader.ReadByte(); if (Switch1 != 0x00 && Switch1 != 0xff) { return; } byte Switch2 = reader.ReadByte(); if (Switch2 != 0x00 && Switch2 != 0xff) { return; } byte Switch3 = reader.ReadByte(); if (Switch3 != 0x00 && Switch3 != 0xff) { return; } nul = reader.ReadByte(); if (nul != 0x00) { return; } UInt32 Unknown2 = reader.ReadUInt32(); UInt32 Unknown3 = reader.ReadUInt32(); UInt32 Unknown4 = reader.ReadUInt32(); rakPong = new RaknetPongResponse(reader); byte[] ZLibData = reader.ReadBytes(rakPong.m_CompressedLen); byte[] Remainder = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position + 1)); ZLibData = ZLibData.Skip(2).ToArray(); byte[] uncompressedData = new byte[1038]; FixedBufferDecompress(ZLibData, ref uncompressedData); using (var compressedStream = new MemoryStream(uncompressedData)) using (var compressedStreamReader = new BinaryReader(compressedStream)) { rakPong.CompressedData = new CompressibleRaknetPongResponse(compressedStreamReader); rakPong.CompressedData.CurrentPlayerCount = rakPong.CurPlayers; } } if (rakPong != null) { JObject customRakObject = JObject.FromObject(rakPong); game.CustomAttributes.Add("pong", customRakObject); lock (pongCache) { pongCache[endPoint] = new PongCacheData() { cacheTime = DateTime.UtcNow, data = customRakObject }; } } } } catch { } } } }); } if (statusData != null) { ExtraData["proxyStatus"] = statusData; } //return rawGames; }
public void PreProcessGameList(ref JObject Paramaters, ref List <GameData> RawGames, ref Dictionary <string, JObject> ExtraData) { bool DoProxy = true; try { DoProxy = Paramaters["__pluginProxy"]?.Value <bool?>() ?? DoProxy; } catch { } bool ShowSource = false; try { ShowSource = Paramaters["__pluginShowSource"]?.Value <bool?>() ?? ShowSource; } catch { } bool ShowStatus = false; try { ShowStatus = Paramaters["__pluginShowStatus"]?.Value <bool?>() ?? ShowStatus; } catch { } long rowIdCounter = -1; /*{ * GameData hardCodedGame = new GameData() * { * addr = @"0.0.0.0:17770", * clientReqId = 0, * gameId = "BZ2", * lastUpdate = DateTime.UtcNow, * rowId = rowIdCounter--, * rowPW = string.Empty, * timeoutSec = 300, * //updatePw = string.Empty * }; * hardCodedGame.GameAttributes.Add(new CustomGameDataField() { Key = "n", Value = @"SW9uRHJpdmVyIEJpc211dGggKE1hc3RlciBFbXVsYXRvcikAAAAAAA==" }); // IonDriver Bismuth (Master Emulator) * hardCodedGame.GameAttributes.Add(new CustomGameDataField() { Key = "l", Value = @"1" }); * hardCodedGame.GameAttributes.Add(new CustomGameDataField() { Key = "m", Value = @"bismuth" }); * //hardCodedGame.GameAttributes.Add(new CustomGameDataField("d", string.Empty)); * //hardCodedGame.GameAttributes.Add(new CustomGameDataField("k", 1.ToString())); * //hardCodedGame.GameAttributes.Add(new CustomGameDataField("t", 7.ToString())); * //hardCodedGame.GameAttributes.Add(new CustomGameDataField("r", @"@ZA@d1")); * //hardCodedGame.GameAttributes.Add(new CustomGameDataField("v", @"S1")); * * rawGames.Add(hardCodedGame); * }*/ JObject statusData = null; if (DoProxy && ShowStatus) { statusData = new JObject(); } if (DoProxy) { object counterLock = new object(); int counter = sources.Count; sources.AsParallel().ForAll(dr => { RemoteCallStatus cacheType = RemoteCallStatus.cached; try { if (dr.Date == null || dr.Date.AddMilliseconds(dr.Stale) < DateTime.UtcNow) { cacheType = RemoteCallStatus.none; //lock (dr) dr.WebRequestActive.Wait(); //await dr.WebRequestActive.WaitAsync(); try { // make sure another thread didn't do this for us while we were locked if (dr.Date == null || dr.Date.AddMilliseconds(dr.Stale) < DateTime.UtcNow) { try { using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromMilliseconds(dr.Timeout); //var response = await client.GetAsync(dr.Url); var responseTask = client.GetAsync(dr.Url); responseTask.Wait(); if (responseTask.IsCompleted && !responseTask.IsCanceled && !responseTask.IsFaulted) { var response = responseTask.Result; if (response.IsSuccessStatusCode) { dr.LastData = JObject.Parse(response.Content.ReadAsStringAsync().Result); dr.Date = DateTime.UtcNow; cacheType = RemoteCallStatus.@new; } else if (dr.Date == null || dr.Date.AddMilliseconds(dr.MaxStale) < DateTime.UtcNow) { // we failed to get data and it's too old, so destroy the cache dr.LastData = null; dr.Date = DateTime.UtcNow; cacheType = RemoteCallStatus.expired; } } else if (dr.Date == null || dr.Date.AddMilliseconds(dr.MaxStale) < DateTime.UtcNow) { // we failed to get data and it's too old, so destroy the cache dr.LastData = null; dr.Date = DateTime.UtcNow; cacheType = RemoteCallStatus.expired; } } } catch (Exception ex) { if (dr.Date == null || dr.Date.AddMilliseconds(dr.MaxStale) < DateTime.UtcNow) { dr.LastData = null; dr.Date = DateTime.UtcNow; } } } } finally { dr.WebRequestActive.Release(); } } } //catch(Exception ex) //{ // Console.WriteLine(ex.ToString()); //} finally { if (ShowStatus) { var tmp = new JObject(); tmp["updated"] = dr.Date; tmp["status"] = cacheType.ToString(); tmp["success"] = dr.LastData != null; lock (statusData) { statusData[dr.ProxySource] = tmp; } } lock (counterLock) { counter--; } } }); // the async member inside appears to be causing it to not join, but I can't await it so I have to do a block while (counter > 0) { Thread.Sleep(100); } HashSet <int> usedPorts = new HashSet <int>() { 17770 }; // start with hardcoded game already there // clone list so that it can't be modified under us by another thread List <ListSource> sourcesClone = sources.ToList(); foreach (ListSource source in sourcesClone) { if (source.LastData != null) { RawGames.AddRange(((JArray)(source.LastData["GET"])).Cast <JObject>().ToList().Select(dr => { //string addressPossibleRemap = string.Empty; //addressPossibleRemap = "0.0.0.0"; try { GameData remoteGame = new GameData() { addr = null,//addressPossibleRemap,//dr["__addr"].Value<string>(), clientReqId = dr["__clientReqId"]?.Value <long>(), gameId = dr["__gameId"]?.Value <string>() ?? "BZCC", lastUpdate = DateTime.UtcNow, rowId = rowIdCounter--, rowPW = string.Empty, timeoutSec = dr["__timeoutSec"]?.Value <long>() ?? 60, //updatePw = string.Empty }; dr.Properties().ToList().ForEach(dx => { if (!dx.Name.StartsWith("__") && dx.Value.Type != JTokenType.Null) { remoteGame.GameAttributes.Add(new CustomGameDataField() { Key = dx.Name, Value = (dx.Value.Type == JTokenType.String ? ("\"" + dx.Value.ToString() + "\"") : dx.Value.ToString()) }); } }); if (ShowSource) { remoteGame.GameAttributes.Add(new CustomGameDataField() { Key = "proxySource", Value = $"\"{source.ProxySource}\"" }); } //rawGames.Add(kebbzGame); return(remoteGame); } catch (Exception ex) { } return(null); }).Where(dr => dr != null)); } } } if (statusData != null) { ExtraData["proxyStatus"] = statusData; } //return rawGames; }