public void Lookup(IPAddress ip, Action <GeoInfo> callback) { uint ipInt = Ip4Utils.ToInt(ip); GeoInfo geoInfo; lock (cache) { object cached; if (!cache.TryGetValue(ipInt, out cached)) { cache.Add(ipInt, callback); this.queue.Add(ip); return; } geoInfo = cached as GeoInfo; if (geoInfo == null) { var callbacks = (Action <GeoInfo>)cached; callbacks += callback; cache[ipInt] = callbacks; return; } } callback(geoInfo); }
public void Lookup(IPAddress ip, Action <GeoInfo> callback) { uint ipInt = Ip4Utils.ToInt(ip); GeoInfo geoInfo = null; lock (cache) { if (cache.TryGetValue(ipInt, out var cached)) { geoInfo = cached as GeoInfo; } if (geoInfo == null) { if (this.usageExceeded == DateTime.UtcNow.Date) { return; } if (cached == null) { cache.Add(ipInt, callback); this.queue.Add(ip); } else { var callbacks = (Action <GeoInfo>)cached; callbacks += callback; cache[ipInt] = callbacks; } return; } } callback(geoInfo); }
public void LoadCache() { if (!File.Exists(this.cacheFile)) { return; } lock (cache) { foreach (var line in File.ReadAllLines(this.cacheFile)) { try { var parts = line.Split(new[] { '=' }, 2); uint ipInt = 0; var octets = parts[0].Split('.'); foreach (var octet in octets) { ipInt = (ipInt << 8) + uint.Parse(octet); } var loc = parts[1].Split('|'); var countryCode = loc[0]; var latitude = decimal.Parse(loc[5], NumberFormatInfo.InvariantInfo); var longitude = decimal.Parse(loc[6], NumberFormatInfo.InvariantInfo); if (countryCode != "") { var geoInfo = new GeoInfo(countryCode, loc[1], loc[2], loc[3], loc[4], latitude, longitude); cache[ipInt] = geoInfo; } } catch { // ignore } } // override wrong geo-IP information (MS Azure IPs list Washington even for NL/EU servers) cache[Ip4Utils.ToInt(104, 40, 134, 97)] = new GeoInfo("NL", "Netherlands", null, null, null, 0, 0); cache[Ip4Utils.ToInt(104, 40, 213, 215)] = new GeoInfo("NL", "Netherlands", null, null, null, 0, 0); // Vultr also spreads their IPs everywhere cache[Ip4Utils.ToInt(45, 32, 153, 115)] = new GeoInfo("DE", "Germany", null, null, null, 0, 0); // listed as NL, but is DE cache[Ip4Utils.ToInt(45, 32, 205, 149)] = new GeoInfo("US", "United States", "TX", null, null, 0, 0); // listed as NL, but is TX // i3d.net cache[Ip4Utils.ToInt(185, 179, 200, 69)] = new GeoInfo("ZA", "South Africa", null, null, null, 0, 0); // listed as NL, but is ZA } }
private void ProcessLoop() { using (var client = new XWebClient(5000)) { while (true) { var ip = this.queue.Take(); if (ip == null) { break; } bool err = true; var ipInt = Ip4Utils.ToInt(ip); try { var url = string.Format(this.ServiceUrlFormat, ip); var result = client.DownloadString(url); if (result != null) { object o; Action <GeoInfo> callbacks; lock (cache) callbacks = cache.TryGetValue(ipInt, out o) ? o as Action <GeoInfo> : null; var geoInfo = this.HandleResult(ipInt, result); if (callbacks != null && geoInfo != null) { ThreadPool.QueueUserWorkItem(ctx => callbacks(geoInfo)); } err = false; } } catch { // ignore } if (err) { lock (this.cache) this.cache.Remove(ipInt); } } } }
public void LoadFromIni(IniFile iniFile, IniFile.Section ini, GameExtensionPool pool, bool ignoreMasterServer) { this.Source = (SourceType)ini.GetInt("Type"); this.Caption = ini.GetString("TabName"); this.MasterServer = (ignoreMasterServer ? null : ini.GetString("MasterServer")) ?? ""; this.InitialGameID = ini.GetInt("InitialGameID"); this.FilterMod = ini.GetString("FilterMod"); this.FilterMap = ini.GetString("FilterMap"); this.TagsIncludeServer = ini.GetString("TagsInclude"); this.TagsExcludeServer = ini.GetString("TagsExclude"); this.VersionMatch = ini.GetString("VersionMatch"); this.GetEmptyServers = ini.GetBool("GetEmptyServers", true); this.GetFullServers = ini.GetBool("GetFullServers", true); this.MasterServerQueryLimit = ini.GetInt("MasterServerQueryLimit", this.MasterServerQueryLimit); this.GridFilter = ini.GetString("GridFilter"); this.MinPlayers = ini.GetInt("MinPlayers"); this.MinPlayersInclBots = ini.GetBool("MinPlayersInclBots"); this.MaxPing = ini.GetInt("MaxPing"); this.TagsIncludeClient = ini.GetString("TagsIncludeClient"); this.TagsExcludeClient = ini.GetString("TagsExcludeClient"); this.CustomDetailColumns.Clear(); foreach (var detail in (ini.GetString("CustomDetailColumns") ?? "").Split(',')) { if (detail != "") { CustomRuleColumns.Add(detail); } } this.CustomRuleColumns.Clear(); foreach (var rule in (ini.GetString("CustomRuleColumns") ?? "").Split(',')) { if (rule != "") { CustomRuleColumns.Add(rule); } } this.HideColumns.Clear(); foreach (var col in (ini.GetString("HideColumns") ?? "").Split(',')) { if (col != "") { HideColumns.Add(col); } } var layout = ini.GetString("GridLayout"); if (!string.IsNullOrEmpty(layout)) { this.ServerGridLayout = new MemoryStream(Convert.FromBase64String(layout)); } this.gameExtension = pool.Get((Game)this.InitialGameID); if (this.Source == SourceType.CustomList) { this.Servers = new List <ServerRow>(); // new config format var sec = iniFile.GetSection(ini.Name + "_Servers"); if (sec != null) { foreach (var key in sec.Keys) { var row = new ServerRow(Ip4Utils.ParseEndpoint(key), this.gameExtension); row.CachedName = sec.GetString(key); this.Servers.Add(row); } } else { // old config format var oldSetting = ini.GetString("Servers") ?? ""; foreach (var server in oldSetting.Split('\n', ' ')) { var s = server.Trim(); if (s == "") { continue; } this.Servers.Add(new ServerRow(Ip4Utils.ParseEndpoint(s), this.gameExtension)); } } } }