private GeoIP getResponse() { GeoIPServiceSoapClient client = new GeoIPServiceSoapClient(); GeoIP response = client.GetGeoIP(ip); return(response); }
public ServerListReport(IPAddress listen, ushort port, Action <string, string> log, Action <string, string> logError) { Log = log; LogError = logError; GeoIP.Initialize(log, Category); Servers = new ConcurrentDictionary <string, GameServer>(); Thread = new Thread(StartServer) { Name = "Server Reporting Socket Thread" }; Thread.Start(new AddressInfo() { Address = listen, Port = port }); new Thread(StartCleanup) { Name = "Server Reporting Cleanup Thread" }.Start(); new Thread(StartDynamicInfoReload) { Name = "Dynamic Info Reload Thread" }.Start(); }
public AnonymousProfileTooltipLogic(Widget widget, OrderManager orderManager, Session.Client client) { var address = LobbyUtils.GetExternalIP(client, orderManager); var cachedDescriptiveIP = address ?? "Unknown IP"; var nameLabel = widget.Get <LabelWidget>("NAME"); var nameFont = Game.Renderer.Fonts[nameLabel.Font]; widget.Bounds.Width = nameFont.Measure(nameLabel.Text).X + 2 * nameLabel.Bounds.Left; var ipLabel = widget.Get <LabelWidget>("IP"); ipLabel.GetText = () => cachedDescriptiveIP; var locationLabel = widget.Get <LabelWidget>("LOCATION"); var cachedCountryLookup = GeoIP.LookupCountry(address); locationLabel.GetText = () => cachedCountryLookup; if (client.IsAdmin) { var adminLabel = widget.Get("GAME_ADMIN"); adminLabel.IsVisible = () => client.IsAdmin; widget.Bounds.Height += adminLabel.Bounds.Height; } }
private void CheckGeoIP(string sURL, ref string sIP, ref string sCountry, ref string sCountryCode) { string domainCode; Utilities utilities = Globals.G_Utilities; lock (utilities) { sIP = Globals.G_Utilities.UrlToIP(sURL); domainCode = Globals.G_Utilities.GetDomainCode(sURL); } GeoIP oip = Globals.G_GEOIP; lock (oip) { if (Globals.G_GEOIP.CountryCodeExist(domainCode)) { sCountry = Globals.G_GEOIP.CountryNameByCode(domainCode); sCountryCode = Globals.G_GEOIP.LookupCountryCode(sIP); } else { sCountry = Globals.G_GEOIP.LookupCountry(sIP); sCountryCode = Globals.G_GEOIP.LookupCountryCode(sIP); } } }
private static void timeOffsetCheck(IFlyMiningEntityDI fDb) { try { if (fDb.UserProfile2.Any(t => (t.TimeZone == null || (t.TimeZone != null && t.TimeZone == "")) && t.userIP != "::1")) { List <UserProfile2> userlist = fDb.UserProfile2.Where(t => (t.TimeZone == null || (t.TimeZone != null && t.TimeZone == "")) && t.userIP != "::1").ToList(); foreach (UserProfile2 user in userlist) { GeoData myLocation = GeoIP.GetCountryInfo(user.userIP); if (myLocation == null || myLocation.timeZone == "") { myLocation = GeoIP.GetCountryInfoCheck(user.userIP); } if (myLocation != null) { user.TimeOffset = myLocation.timeOffset; user.TimeZone = myLocation.timeZone; if (user.TimeZone.Length >= 50) { user.TimeZone = myLocation.timeZone.Substring(0, 50); } } } fDb.SaveChanges(); } } catch (Exception ex) { Logger.AddLogRecord("timeOffsetCheck " + Convert.ToString(ex)); } }
public LoginServer(IPAddress listen, ushort clientManagerPort, ushort searchManagerPort, Action <string, string> log, Action <string, string> logError) { ServicePointManager.SetTcpKeepAlive(true, 60 * 1000 * 10, 1000); Log = log; LogError = logError; GeoIP.Initialize(log, Category); ThreadClientManager = new Thread(StartServerClientManager) { Name = "Login Thread Client Manager" }; ThreadClientManager.Start(new AddressInfo() { Address = listen, Port = clientManagerPort }); ThreadSearchManager = new Thread(StartServerSearchManager) { Name = "Login Thread Search Manager" }; ThreadSearchManager.Start(new AddressInfo() { Address = listen, Port = searchManagerPort }); }
private async Task CargarItems() { if (!Plugin.Connectivity.CrossConnectivity.Current.IsConnected) { await DisplayAlert("Advertencia", "No hay internet", "Cerrar"); return; } IsBusy = true; Items.Clear(); var Ip = IPAddress.Text; if (Ip == "" || Ip == null) { await DisplayAlert("Digitar IP", "Debe digitar un dirección IP", "Cerrar"); } else { var ciudades = await CargarDatos(Ip); GeoIP geoData = new GeoIP(); if (ciudades.Status == "fail") { ciudades.Mensaje = "La ip: " + ciudades.IpAdress + " no se pudo encontrar"; geoData.Mensaje = ciudades.Mensaje; } else { var latitud = double.Parse(ciudades.Latitud, CultureInfo.InvariantCulture); var longitud = double.Parse(ciudades.Longitud, CultureInfo.InvariantCulture); var position = new Position(latitud, longitud); // Latitude, Longitude var pin = new Pin { Type = PinType.Place, Position = position, Label = "custom pin", Address = "custom detail info" }; geoData.Pais = ciudades.Pais; geoData.Ciudad = ciudades.Ciudad; geoData.Region = ciudades.Region; geoData.ISP = ciudades.ISP; geoData.Zip = ciudades.Zip; geoData.Mensaje = "Ip encontrada: " + ciudades.IpAdress; Mapa.MoveToRegion(MapSpan.FromCenterAndRadius( position, Distance.FromMiles(0.3))); Mapa.Pins.Add(pin); } Items.Add(geoData); } IsBusy = false; }
public static void GeoIPRoute(IEndpointRouteBuilder endpoints) { endpoints.Map(Config.IpPerfix, async context => await context.WriteResponseAsync(RealIP.Get(context).ToString())); endpoints.Map(Config.IpPerfix + "/source", async context => { var jObject = new JObject { { "IP", RealIP.Get(context).ToString() }, { "UserHostAddress", context.Connection.RemoteIpAddress.ToString() } }; if (context.Request.Headers.TryGetValue("X-Forwarded-For", out var xFwdValue)) { jObject.Add("X-Forwarded-For", xFwdValue.ToString()); } if (context.Request.Headers.TryGetValue("CF-Connecting-IP", out var xCfValue)) { jObject.Add("CF-Connecting-IP", xCfValue.ToString()); } if (context.Request.Headers.TryGetValue("X-Real-IP", out var xRealValue)) { jObject.Add("X-Real-IP", xRealValue.ToString()); } await context.WriteResponseAsync(jObject.ToString(), type: "application/json"); }); endpoints.Map(Config.IpPerfix + "/json", async context => { var(responseAsn, responseCity) = GeoIP.GetAsnCityValueTuple(context.Request.Query.ContainsKey("ip") ? IPAddress.Parse(context.Request.Query["ip"].ToString()) : RealIP.Get(context)); var jObject = new JObject { { "IP", responseAsn.IPAddress }, { "ASN", responseAsn.AutonomousSystemNumber }, { "Organization", responseAsn.AutonomousSystemOrganization }, { "CountryCode", responseCity.Country.IsoCode }, { "Country", responseCity.Country.Name } }; if (!string.IsNullOrWhiteSpace(responseCity.MostSpecificSubdivision.IsoCode)) { jObject.Add("ProvinceCode", responseCity.MostSpecificSubdivision.IsoCode); } if (!string.IsNullOrWhiteSpace(responseCity.MostSpecificSubdivision.Name)) { jObject.Add("Province", responseCity.MostSpecificSubdivision.Name); } if (!string.IsNullOrWhiteSpace(responseCity.City.Name)) { jObject.Add("City", responseCity.City.Name); } var cnIsp = GeoIP.GetCnISP(responseAsn, responseCity); if (!string.IsNullOrWhiteSpace(cnIsp)) { jObject.Add("ISP", cnIsp); } await context.WriteResponseAsync(jObject.ToString(), type: "application/json"); }); }
/// <summary> /// Protected constructor, common functionality for this class and subclasses /// </summary> /// <param name="socket">TCP socket for communicating with the remote server</param> /// <param name="connectionLogWriter">Log writer module</param> /// <param name="serverList">Server List object</param> /// <param name="geoIP">GeoIP resolver</param> protected Connection(Socket socket, IConnectionLogWriter logWriter, ServerList serverList, GeoIP geoIP) { this.socket = socket; this.logWriter = logWriter; this.serverList = serverList; this.geoIP = geoIP; // Socket ID for logging SocketID = String.Format("{0}:{1}", (socket.RemoteEndPoint as IPEndPoint).Address, (socket.RemoteEndPoint as IPEndPoint).Port); }
public void GetGeoIPTest() { var ipInformation = new GeoIP(); Assert.IsNotNull(ipInformation.City); Assert.IsNotNull(ipInformation.Country); Assert.IsNotNull(ipInformation.CountryCode); Assert.IsNotNull(ipInformation.Region); Assert.IsNotNull(ipInformation.WanIp); }
public ServerListReport(IPAddress listen, ushort port) { GeoIP.Initialize(Log, Category); StartServer(new AddressInfo() { Address = listen, Port = port }); }
public void OnGet() { var city = GeoIP.GetIPInfo(IP); if (city?.Latitude != null && city?.Longitude != null) { InitialLatitude = city.Latitude.Value; InitialLongitude = city.Longitude.Value; InitialZoom = 9; } }
/// <summary> /// Master server constructor. Initialises child objects, helpers and listeners /// </summary> /// <param name="statusDisplay"></param> /// <param name="commandInterface"></param> private MasterServer(IStatusDisplay statusDisplay, ICommandInterface commandInterface, ICDKeyValidator cdKeyValidator, IGameStatsLog gameStats, ILogWriter logWriter) { if (MasterServer.instance != null) { throw new InvalidOperationException("Attempted to create a Master Server instance whilst another instance was still active"); } // Assign static references MasterServer.instance = this; MasterServer.logWriter = logWriter; // Assign instance references this.statusDisplay = statusDisplay; this.commandInterface = commandInterface; this.cdKeyValidator = cdKeyValidator; this.gameStats = gameStats; // Initialise the command interface if we have one if (commandInterface != null) { commandInterface.OnChange += new EventHandler(DisplayCommandInterface); } // GeoIP resolver is used to resolve IP addresses to locations geoIP = new GeoIP(); // MD5 database is used to download new MD5 package data to connecting servers md5Manager = new MD5Manager(); // IP ban manager used to ban clients from accessing the server banManager = new IPBanManager(); // Create the Server List object serverList = new ServerList(this); // Create the web server webServer = new WebServer(banManager); // Initialise the status display module if we have one if (statusDisplay != null) { logBufferSize = statusDisplay.LogBufferSize; logBufferWrap = statusDisplay.LogBufferWrap; displayTimer = new Timer(new TimerCallback(this.Display)); Display(null); } // Load the GeoIP database, MD5 database and ban list from the files (this happens last because they may take a while) geoIP.Load(MasterServer.Settings.GeoIPDataFile); md5Manager.Load(MasterServer.Settings.MD5DataFile); banManager.Load(MasterServer.Settings.BanListFile); }
/// <summary> /// Creates a new ServerList /// </summary> /// <param name="masterServer"></param> public ServerList(MasterServer masterServer) { this.masterServer = masterServer; this.geoIP = masterServer.GeoIP; this.connectionLogWriter = ModuleManager.GetModule <IConnectionLogWriter>(); StartService(); // RPC Server UpdateLinks(); // RPC Client scavengeTimer = new Timer(new TimerCallback(this.Scavenge), null, 10000, Timeout.Infinite); ModuleManager.RegisterCommandListener(this); }
public HttpServer(IPAddress listen, ushort port) { GeoIP.Initialize(Log, Category); _thread = new Thread(StartServer) { Name = "Http Socket Thread" }; _thread.Start(new AddressInfo() { Address = listen, Port = port }); }
public Main(NWR_Client.Client client) { InitializeComponent(); Clients = null; xClient = client; Functions.Center(this); conAddr = new List <string>(); Icon = GlobalProperties.ApplicationIcon; GlobalProperties.MainForm = this; log = new Log(this); received = 0; sent = 0; peak = 0; total = Settings.GetTotal(); lblTotal.Text = "Total: " + total.ToString(); SelectionCount = 0; MultiFlood = false; geoIp = new GeoIP(); User32.RegisterHotKey(Handle, 0, 0, (int)Keys.F1); User32.RegisterHotKey(Handle, 1, 0, (int)Keys.F2); User32.RegisterHotKey(Handle, 2, 0, (int)Keys.F3); User32.RegisterHotKey(Handle, 3, 0, (int)Keys.F4); User32.RegisterHotKey(Handle, 4, 0, (int)Keys.F5); User32.RegisterHotKey(Handle, 5, 0, (int)Keys.F6); xClient.DataReceived += new EventHandler <NWR_Client.DataReceivedEventArgs>(xClient_DataReceived); xClient.Disconnected += new EventHandler(xClient_Disconnected); GlobalProperties.Client = xClient; PluginHelper.PluginChanged += new EventHandler(PluginHelper_PluginChanged); FloodTimer.TimerStarted += new EventHandler(FloodTimer_TimerStarted); FloodTimer.TimerAborted += new EventHandler(FloodTimer_TimerAborted); FloodTimer.TimerChanged += new FloodTimer.FloodTimerChangedEventHandler(FloodTimer_TimerChanged); FloodTimer.TimerFinished += new EventHandler(FloodTimer_TimerFinished); Load += new EventHandler(Main_Load); NatUtility.StartDiscovery(); NatUtility.DeviceFound += (S, E) => { GlobalProperties.NatDevices.Add(E.Device); }; NatUtility.DeviceLost += (S, E) => { GlobalProperties.NatDevices.Remove(E.Device); }; GlobalProperties.NI = ni; }
public Main(NWR_Client.Client client) { InitializeComponent(); Clients = null; xClient = client; Functions.Center(this); conAddr = new List<string>(); Icon = GlobalProperties.ApplicationIcon; GlobalProperties.MainForm = this; log = new Log(this); received = 0; sent = 0; peak = 0; total = Settings.GetTotal(); lblTotal.Text = "Total: " + total.ToString(); SelectionCount = 0; MultiFlood = false; geoIp = new GeoIP(); User32.RegisterHotKey(Handle, 0, 0, (int)Keys.F1); User32.RegisterHotKey(Handle, 1, 0, (int)Keys.F2); User32.RegisterHotKey(Handle, 2, 0, (int)Keys.F3); User32.RegisterHotKey(Handle, 3, 0, (int)Keys.F4); User32.RegisterHotKey(Handle, 4, 0, (int)Keys.F5); User32.RegisterHotKey(Handle, 5, 0, (int)Keys.F6); xClient.DataReceived += new EventHandler<NWR_Client.DataReceivedEventArgs>(xClient_DataReceived); xClient.Disconnected += new EventHandler(xClient_Disconnected); GlobalProperties.Client = xClient; PluginHelper.PluginChanged += new EventHandler(PluginHelper_PluginChanged); FloodTimer.TimerStarted += new EventHandler(FloodTimer_TimerStarted); FloodTimer.TimerAborted += new EventHandler(FloodTimer_TimerAborted); FloodTimer.TimerChanged += new FloodTimer.FloodTimerChangedEventHandler(FloodTimer_TimerChanged); FloodTimer.TimerFinished += new EventHandler(FloodTimer_TimerFinished); Load += new EventHandler(Main_Load); NatUtility.StartDiscovery(); NatUtility.DeviceFound += (S, E) => { GlobalProperties.NatDevices.Add(E.Device); }; NatUtility.DeviceLost += (S, E) => { GlobalProperties.NatDevices.Remove(E.Device); }; GlobalProperties.NI = ni; }
private static void SetServerVariables(GameServer gameServer, string[] serverDataFrag, IPEndPoint remote) { gameServer.Country = (remote.Address.AddressFamily == AddressFamily.InterNetwork) ? GeoIP.GetCountryCode(remote.Address).ToUpperInvariant() : "??"; for (int i = 0; i < serverDataFrag.Length - 1; i += 2) { //Fetch the properties PropertyInfo property = typeof(GameServer).GetProperty(serverDataFrag[i]); if (property == null) { continue; } } }
public ServerNatNeg(IPAddress listen, ushort port, Action <string, string> log, Action <string, string> logError) { Log = log; LogError = logError; GeoIP.Initialize(log, Category); Thread = new Thread(StartServer) { Name = "Server NatNeg Socket Thread" }; Thread.Start(new AddressInfo() { Address = listen, Port = port }); }
public void TestDropConditions() { JObject jsonInputLine1 = new JObject { { "type", "Win32-FileLog" }, { "IP", "8.8.8.8" } }; string jsonFilter = @"{ ""TimberWinR"":{ ""Filters"":[ { ""geoip"":{ ""type"": ""Win32-FileLog"", ""target"": ""mygeoip"", ""source"": ""IP"" } }] } }"; // Positive Tests Configuration c = Configuration.FromString(jsonFilter); GeoIP jf = c.Filters.First() as GeoIP; Assert.IsTrue(jf.Apply(jsonInputLine1)); JObject stuff = jsonInputLine1["mygeoip"] as JObject; Assert.IsNotNull(stuff); Assert.AreEqual("8.8.8.8", stuff["ip"].ToString()); Assert.AreEqual("US", stuff["country_code2"].ToString()); Assert.AreEqual("United States", stuff["country_name"].ToString()); Assert.AreEqual("CA", stuff["region_name"].ToString()); Assert.AreEqual("Mountain View", stuff["city_name"].ToString()); Assert.AreEqual("California", stuff["real_region_name"].ToString()); Assert.AreEqual(37.386f, (float)stuff["latitude"]); Assert.AreEqual(-122.0838f, (float)stuff["longitude"]); }
// public static void SendToAllConnected() // { //_socket. // } public ServerListReport(IPAddress listen, ushort port, Action <string, string> log, Action <string, string> logError, string gameName) { if (gameName != null) { _gameName = gameName; } List <byte> initialMessage = new byte[] { 0x09, 0x00, 0x00, 0x00, 0x00 }.ToList(); initialMessage.AddRange(Encoding.ASCII.GetBytes(_gameName)); initialMessage.Add(0x00); //Console.WriteLine("[initial:]" + _initialMessage[0] + _initialMessage[1] + _initialMessage[2] + _initialMessage[3] + _initialMessage[4] + ',' + _initialMessage[5] + ',' + _initialMessage[6] + ',' + _initialMessage[7] + ',' + _initialMessage[8] + ',' + _initialMessage[9]); _initialMessage = initialMessage.ToArray(); //Console.WriteLine("[initial:]" + _initialMessage[0] + _initialMessage[1] + _initialMessage[2] + _initialMessage[3] + _initialMessage[4] + ',' + _initialMessage[5] + ',' + _initialMessage[6] + ',' + _initialMessage[7] + ',' + _initialMessage[8]); Log = log; LogError = logError; GeoIP.Initialize(log, Category); Servers = new ConcurrentDictionary <string, GameServer>(); Thread = new Thread(StartServer) { Name = "Server Reporting Socket Thread" }; Thread.Start(new AddressInfo() { Address = listen, Port = port }); new Thread(StartCleanup) { Name = "Server Reporting Cleanup Thread" }.Start(); new Thread(StartDynamicInfoReload) { Name = "Dynamic Info Reload Thread" }.Start(); }
/// <summary> /// Shut down this listener and all child threads /// </summary> public void Shutdown() { aborted = true; this.serverList = null; this.geoIP = null; this.cdKeyValidator = null; this.gameStats = null; this.md5Manager = null; this.banManager = null; if (listenThread != null) { // Try to close the listen socket if (listenSocket != null) { try { listenSocket.Close(); } catch { } } // Try to forcibly abort the listen thread listenThread.Abort(); listenThread.Join(); listenThread = null; MasterServer.Log("[NET] Query listener socket {0} shut down.", endpoint.Port); } // Abort active connections ConnectionManager.AbortAll(endpoint.Port); // Release log writer ModuleManager.ReleaseModule <IConnectionLogWriter>(); }
/// <summary> /// Constructor, create a new query listener at the specified endpoint /// </summary> /// <param name="endpoint">Endpoint for this listener</param> /// <param name="serverList">Server list object to pass to new connections</param> /// <param name="geoIP">GeoIP resolver to pass to new connections</param> /// <param name="md5Manager">MD5 manager to pass to new connections</param> /// <param name="banManager">IP ban manager to pass to new connections</param> /// <param name="cdKeyValidator">CD key validator module to pass to new connections</param> /// <param name="gameStats">Game stats module to pass to new connections</param> public QueryListener(IPEndPoint endpoint, ServerList serverList, GeoIP geoIP, MD5Manager md5Manager, IPBanManager banManager, ICDKeyValidator cdKeyValidator, IGameStatsLog gameStats) { // Endpoint to listen this.endpoint = endpoint; // These objects are passed to new connections this.serverList = serverList; this.geoIP = geoIP; this.md5Manager = md5Manager; this.banManager = banManager; this.cdKeyValidator = cdKeyValidator; this.gameStats = gameStats; // Get configured connection log writer module this.logWriter = ModuleManager.GetModule <IConnectionLogWriter>(); // Bind the listen socket ready to begin listening listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); listenSocket.Bind(this.Endpoint); // Create and start the listen thread listenThread = new Thread(ListenThreadProc); listenThread.Start(); }
static void Initialize(Arguments args) { Console.WriteLine("Platform is {0}", Platform.CurrentPlatform); // Load the engine version as early as possible so it can be written to exception logs try { EngineVersion = File.ReadAllText(Platform.ResolvePath(Path.Combine(".", "VERSION"))).Trim(); } catch { } if (string.IsNullOrEmpty(EngineVersion)) { EngineVersion = "Unknown"; } Console.WriteLine("Engine version is {0}", EngineVersion); // Special case handling of Game.Mod argument: if it matches a real filesystem path // then we use this to override the mod search path, and replace it with the mod id var modID = args.GetValue("Game.Mod", null); var explicitModPaths = new string[0]; if (modID != null && (File.Exists(modID) || Directory.Exists(modID))) { explicitModPaths = new[] { modID }; modID = Path.GetFileNameWithoutExtension(modID); } InitializeSettings(args); Log.AddChannel("perf", "perf.log"); Log.AddChannel("debug", "debug.log"); Log.AddChannel("server", "server.log"); Log.AddChannel("sound", "sound.log"); Log.AddChannel("graphics", "graphics.log"); Log.AddChannel("geoip", "geoip.log"); Log.AddChannel("irc", "irc.log"); Log.AddChannel("nat", "nat.log"); Sound = new Sound(); Renderer = new Renderer(Settings.Graphics); GeoIP.Initialize(); if (Settings.Server.DiscoverNatDevices) { discoverNat = UPnP.DiscoverNatDevices(Settings.Server.NatDiscoveryTimeout); } var modSearchArg = args.GetValue("Engine.ModSearchPaths", null); var modSearchPaths = modSearchArg != null? FieldLoader.GetValue <string[]>("Engine.ModsPath", modSearchArg) : new[] { Path.Combine(".", "mods") }; Mods = new InstalledMods(modSearchPaths, explicitModPaths); Console.WriteLine("Internal mods:"); foreach (var mod in Mods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version); } ExternalMods = new ExternalMods(); Manifest currentMod; if (modID != null && Mods.TryGetValue(modID, out currentMod)) { var launchPath = args.GetValue("Engine.LaunchPath", Assembly.GetEntryAssembly().Location); // Sanitize input from platform-specific launchers // Process.Start requires paths to not be quoted, even if they contain spaces if (launchPath.First() == '"' && launchPath.Last() == '"') { launchPath = launchPath.Substring(1, launchPath.Length - 2); } ExternalMods.Register(Mods[modID], launchPath, ModRegistration.User); ExternalMod activeMod; if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out activeMod)) { ExternalMods.ClearInvalidRegistrations(activeMod, ModRegistration.User); } } Console.WriteLine("External mods:"); foreach (var mod in ExternalMods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version); } InitializeMod(modID, args); }
void ValidateClient(Connection newConn, string data) { try { if (State == ServerState.GameStarted) { Log.Write("server", "Rejected connection from {0}; game is already started.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "The game has already started"); DropClient(newConn); return; } var handshake = HandshakeResponse.Deserialize(data); if (!string.IsNullOrEmpty(Settings.Password) && handshake.Password != Settings.Password) { var message = string.IsNullOrEmpty(handshake.Password) ? "Server requires a password" : "Incorrect password"; SendOrderTo(newConn, "AuthenticationError", message); DropClient(newConn); return; } var ipAddress = ((IPEndPoint)newConn.Socket.RemoteEndPoint).Address; var client = new Session.Client { Name = OpenRA.Settings.SanitizedPlayerName(handshake.Client.Name), IPAddress = ipAddress.ToString(), AnonymizedIPAddress = Type != ServerType.Local && Settings.ShareAnonymizedIPs ? Session.AnonymizeIP(ipAddress) : null, Location = GeoIP.LookupCountry(ipAddress), Index = newConn.PlayerIndex, PreferredColor = handshake.Client.PreferredColor, Color = handshake.Client.Color, Faction = "Random", SpawnPoint = 0, Team = 0, State = Session.ClientState.Invalid, }; if (ModData.Manifest.Id != handshake.Mod) { Log.Write("server", "Rejected connection from {0}; mods do not match.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server is running an incompatible mod"); DropClient(newConn); return; } if (ModData.Manifest.Metadata.Version != handshake.Version) { Log.Write("server", "Rejected connection from {0}; Not running the same version.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server is running an incompatible version"); DropClient(newConn); return; } if (handshake.OrdersProtocol != ProtocolVersion.Orders) { Log.Write("server", "Rejected connection from {0}; incompatible Orders protocol version {1}.", newConn.Socket.RemoteEndPoint, handshake.OrdersProtocol); SendOrderTo(newConn, "ServerError", "Server is running an incompatible protocol"); DropClient(newConn); return; } // Check if IP is banned var bans = Settings.Ban.Union(TempBans); if (bans.Contains(client.IPAddress)) { Log.Write("server", "Rejected connection from {0}; Banned.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "You have been {0} from the server".F(Settings.Ban.Contains(client.IPAddress) ? "banned" : "temporarily banned")); DropClient(newConn); return; } Action completeConnection = () => { lock (LobbyInfo) { client.Slot = LobbyInfo.FirstEmptySlot(); client.IsAdmin = !LobbyInfo.Clients.Any(c1 => c1.IsAdmin); if (client.IsObserver && !LobbyInfo.GlobalSettings.AllowSpectators) { SendOrderTo(newConn, "ServerError", "The game is full"); DropClient(newConn); return; } if (client.Slot != null) { SyncClientToPlayerReference(client, Map.Players.Players[client.Slot]); } else { client.Color = Color.White; } // Promote connection to a valid client PreConns.Remove(newConn); Conns.Add(newConn); LobbyInfo.Clients.Add(client); newConn.Validated = true; var clientPing = new Session.ClientPing { Index = client.Index }; LobbyInfo.ClientPings.Add(clientPing); Log.Write("server", "Client {0}: Accepted connection from {1}.", newConn.PlayerIndex, newConn.Socket.RemoteEndPoint); if (client.Fingerprint != null) { Log.Write("server", "Client {0}: Player fingerprint is {1}.", newConn.PlayerIndex, client.Fingerprint); } foreach (var t in serverTraits.WithInterface <IClientJoined>()) { t.ClientJoined(this, newConn); } SyncLobbyInfo(); Log.Write("server", "{0} ({1}) has joined the game.", client.Name, newConn.Socket.RemoteEndPoint); // Report to all other players SendMessage("{0} has joined the game.".F(client.Name), newConn); // Send initial ping SendOrderTo(newConn, "Ping", Game.RunTime.ToString(CultureInfo.InvariantCulture)); if (Type == ServerType.Dedicated) { var motdFile = Platform.ResolvePath(Platform.SupportDirPrefix, "motd.txt"); if (!File.Exists(motdFile)) { File.WriteAllText(motdFile, "Welcome, have fun and good luck!"); } var motd = File.ReadAllText(motdFile); if (!string.IsNullOrEmpty(motd)) { SendOrderTo(newConn, "Message", motd); } } if (Map.DefinesUnsafeCustomRules) { SendOrderTo(newConn, "Message", "This map contains custom rules. Game experience may change."); } if (!LobbyInfo.GlobalSettings.EnableSingleplayer) { SendOrderTo(newConn, "Message", TwoHumansRequiredText); } else if (Map.Players.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots)) { SendOrderTo(newConn, "Message", "Bots have been disabled on this map."); } } }; if (Type == ServerType.Local) { // Local servers can only be joined by the local client, so we can trust their identity without validation client.Fingerprint = handshake.Fingerprint; completeConnection(); } else if (!string.IsNullOrEmpty(handshake.Fingerprint) && !string.IsNullOrEmpty(handshake.AuthSignature)) { waitingForAuthenticationCallback++; Action <DownloadDataCompletedEventArgs> onQueryComplete = i => { PlayerProfile profile = null; if (i.Error == null) { try { var yaml = MiniYaml.FromString(Encoding.UTF8.GetString(i.Result)).First(); if (yaml.Key == "Player") { profile = FieldLoader.Load <PlayerProfile>(yaml.Value); var publicKey = Encoding.ASCII.GetString(Convert.FromBase64String(profile.PublicKey)); var parameters = CryptoUtil.DecodePEMPublicKey(publicKey); if (!profile.KeyRevoked && CryptoUtil.VerifySignature(parameters, newConn.AuthToken, handshake.AuthSignature)) { client.Fingerprint = handshake.Fingerprint; Log.Write("server", "{0} authenticated as {1} (UID {2})", newConn.Socket.RemoteEndPoint, profile.ProfileName, profile.ProfileID); } else if (profile.KeyRevoked) { profile = null; Log.Write("server", "{0} failed to authenticate as {1} (key revoked)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); } else { profile = null; Log.Write("server", "{0} failed to authenticate as {1} (signature verification failed)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); } } else { Log.Write("server", "{0} failed to authenticate as {1} (invalid server response: `{2}` is not `Player`)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint, yaml.Key); } } catch (Exception ex) { Log.Write("server", "{0} failed to authenticate as {1} (exception occurred)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint); Log.Write("server", ex.ToString()); } } else { Log.Write("server", "{0} failed to authenticate as {1} (server error: `{2}`)", newConn.Socket.RemoteEndPoint, handshake.Fingerprint, i.Error); } delayedActions.Add(() => { var notAuthenticated = Type == ServerType.Dedicated && profile == null && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Any()); var blacklisted = Type == ServerType.Dedicated && profile != null && Settings.ProfileIDBlacklist.Contains(profile.ProfileID); var notWhitelisted = Type == ServerType.Dedicated && Settings.ProfileIDWhitelist.Any() && (profile == null || !Settings.ProfileIDWhitelist.Contains(profile.ProfileID)); if (notAuthenticated) { Log.Write("server", "Rejected connection from {0}; Not authenticated.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server requires players to have an OpenRA forum account"); DropClient(newConn); } else if (blacklisted || notWhitelisted) { if (blacklisted) { Log.Write("server", "Rejected connection from {0}; In server blacklist.", newConn.Socket.RemoteEndPoint); } else { Log.Write("server", "Rejected connection from {0}; Not in server whitelist.", newConn.Socket.RemoteEndPoint); } SendOrderTo(newConn, "ServerError", "You do not have permission to join this server"); DropClient(newConn); } else { completeConnection(); } waitingForAuthenticationCallback--; }, 0); }; new Download(playerDatabase.Profile + handshake.Fingerprint, _ => { }, onQueryComplete); } else { if (Type == ServerType.Dedicated && (Settings.RequireAuthentication || Settings.ProfileIDWhitelist.Any())) { Log.Write("server", "Rejected connection from {0}; Not authenticated.", newConn.Socket.RemoteEndPoint); SendOrderTo(newConn, "ServerError", "Server requires players to have an OpenRA forum account"); DropClient(newConn); } else { completeConnection(); } } } catch (Exception ex) { Log.Write("server", "Dropping connection {0} because an error occurred:", newConn.Socket.RemoteEndPoint); Log.Write("server", ex.ToString()); DropClient(newConn); } }
public Server(List <IPEndPoint> endpoints, ServerSettings settings, ModData modData, ServerType type) { Log.AddChannel("server", "server.log", true); SocketException lastException = null; var checkReadServer = new List <Socket>(); foreach (var endpoint in endpoints) { var listener = new TcpListener(endpoint); try { try { listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 1); } catch (Exception ex) { if (ex is SocketException || ex is ArgumentException) { Log.Write("server", "Failed to set socket option on {0}: {1}", endpoint.ToString(), ex.Message); } else { throw; } } listener.Start(); listeners.Add(listener); checkReadServer.Add(listener.Server); } catch (SocketException ex) { lastException = ex; Log.Write("server", "Failed to listen on {0}: {1}", endpoint.ToString(), ex.Message); } } if (listeners.Count == 0) { throw lastException; } Type = type; Settings = settings; Settings.Name = OpenRA.Settings.SanitizedServerName(Settings.Name); ModData = modData; playerDatabase = modData.Manifest.Get <PlayerDatabase>(); randomSeed = (int)DateTime.Now.ToBinary(); if (type != ServerType.Local && settings.EnableGeoIP) { GeoIP.Initialize(); } if (UPnP.Status == UPnPStatus.Enabled) { UPnP.ForwardPort(Settings.ListenPort, Settings.ListenPort).Wait(); } foreach (var trait in modData.Manifest.ServerTraits) { serverTraits.Add(modData.ObjectCreator.CreateObject <ServerTrait>(trait)); } serverTraits.TrimExcess(); LobbyInfo = new Session { GlobalSettings = { RandomSeed = randomSeed, Map = settings.Map, ServerName = settings.Name, EnableSingleplayer = settings.EnableSingleplayer || Type != ServerType.Dedicated, EnableSyncReports = settings.EnableSyncReports, GameUid = Guid.NewGuid().ToString(), Dedicated = Type == ServerType.Dedicated } }; new Thread(_ => { foreach (var t in serverTraits.WithInterface <INotifyServerStart>()) { t.ServerStarted(this); } Log.Write("server", "Initial mod: {0}", ModData.Manifest.Id); Log.Write("server", "Initial map: {0}", LobbyInfo.GlobalSettings.Map); while (true) { var checkRead = new List <Socket>(); if (State == ServerState.WaitingPlayers) { checkRead.AddRange(checkReadServer); } checkRead.AddRange(Conns.Select(c => c.Socket)); checkRead.AddRange(PreConns.Select(c => c.Socket)); // Block for at most 1 second in order to guarantee a minimum tick rate for ServerTraits // Decrease this to 100ms to improve responsiveness if we are waiting for an authentication query var localTimeout = waitingForAuthenticationCallback > 0 ? 100000 : 1000000; if (checkRead.Count > 0) { Socket.Select(checkRead, null, null, localTimeout); } if (State == ServerState.ShuttingDown) { EndGame(); break; } foreach (var s in checkRead) { var serverIndex = checkReadServer.IndexOf(s); if (serverIndex >= 0) { AcceptConnection(listeners[serverIndex]); continue; } var preConn = PreConns.SingleOrDefault(c => c.Socket == s); if (preConn != null) { preConn.ReadData(this); continue; } var conn = Conns.SingleOrDefault(c => c.Socket == s); conn?.ReadData(this); } delayedActions.PerformActions(0); // PERF: Dedicated servers need to drain the action queue to remove references blocking the GC from cleaning up disposed objects. if (Type == ServerType.Dedicated) { Game.PerformDelayedActions(); } foreach (var t in serverTraits.WithInterface <ITick>()) { t.Tick(this); } if (State == ServerState.ShuttingDown) { EndGame(); if (UPnP.Status == UPnPStatus.Enabled) { UPnP.RemovePortForward().Wait(); } break; } } foreach (var t in serverTraits.WithInterface <INotifyServerShutdown>()) { t.ServerShutdown(this); } PreConns.Clear(); Conns.Clear(); foreach (var listener in listeners) { try { listener.Stop(); } catch { } } }) { IsBackground = true }.Start(); }
List <Widget> LoadGameRows(List <GameServer> games, out ScrollItemWidget nextServerRow) { nextServerRow = null; var rows = new List <Widget>(); var mods = games.GroupBy(g => g.ModLabel) .OrderByDescending(g => GroupSortOrder(g.First())) .ThenByDescending(g => g.Count()); foreach (var modGames in mods) { if (modGames.All(Filtered)) { continue; } var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => { }); var headerTitle = modGames.First().ModLabel; header.Get <LabelWidget>("LABEL").GetText = () => headerTitle; rows.Add(header); Func <GameServer, int> listOrder = g => { // Servers waiting for players are always first if (g.State == (int)ServerState.WaitingPlayers && g.Players > 0) { return(0); } // Then servers with spectators if (g.State == (int)ServerState.WaitingPlayers && g.Spectators > 0) { return(1); } // Then active games if (g.State >= (int)ServerState.GameStarted) { return(2); } // Empty servers are shown at the end because a flood of empty servers // at the top of the game list make the community look dead return(3); }; foreach (var modGamesByState in modGames.GroupBy(listOrder).OrderBy(g => g.Key)) { // Sort 'Playing' games by Started, others by number of players foreach (var game in modGamesByState.Key == 2 ? modGamesByState.OrderByDescending(g => g.Started) : modGamesByState.OrderByDescending(g => g.Players)) { if (Filtered(game)) { continue; } var canJoin = game.IsJoinable; var item = ScrollItemWidget.Setup(serverTemplate, () => currentServer == game, () => SelectServer(game), () => onJoin(game)); var title = item.GetOrNull <LabelWidget>("TITLE"); if (title != null) { var font = Game.Renderer.Fonts[title.Font]; var label = WidgetUtils.TruncateText(game.Name, title.Bounds.Width, font); title.GetText = () => label; title.GetColor = () => canJoin ? title.TextColor : incompatibleGameColor; } var password = item.GetOrNull <ImageWidget>("PASSWORD_PROTECTED"); if (password != null) { password.IsVisible = () => game.Protected; password.GetImageName = () => canJoin ? "protected" : "protected-disabled"; } var players = item.GetOrNull <LabelWithTooltipWidget>("PLAYERS"); if (players != null) { var label = "{0} / {1}".F(game.Players + game.Bots, game.MaxPlayers + game.Bots) + (game.Spectators > 0 ? " + {0}".F(game.Spectators) : ""); var color = canJoin ? players.TextColor : incompatibleGameColor; players.GetText = () => label; players.GetColor = () => color; if (game.Clients.Any()) { var displayClients = game.Clients.Select(c => c.Name); if (game.Clients.Length > 10) { displayClients = displayClients .Take(9) .Append("+ {0} other players".F(game.Clients.Length - 9)); } var tooltip = displayClients.JoinWith("\n"); players.GetTooltipText = () => tooltip; } else { players.GetTooltipText = null; } } var state = item.GetOrNull <LabelWidget>("STATUS"); if (state != null) { var label = game.State >= (int)ServerState.GameStarted ? "Playing" : "Waiting"; state.GetText = () => label; var color = GetStateColor(game, state, !canJoin); state.GetColor = () => color; } var location = item.GetOrNull <LabelWidget>("LOCATION"); if (location != null) { var font = Game.Renderer.Fonts[location.Font]; var cachedServerLocation = game.Id != -1 ? GeoIP.LookupCountry(game.Address.Split(':')[0]) : "Local Network"; var label = WidgetUtils.TruncateText(cachedServerLocation, location.Bounds.Width, font); location.GetText = () => label; location.GetColor = () => canJoin ? location.TextColor : incompatibleGameColor; } if (currentServer != null && game.Address == currentServer.Address) { nextServerRow = item; } rows.Add(item); } } } return(rows); }
static void Initialize(Arguments args) { var supportDirArg = args.GetValue("Engine.SupportDir", null); if (supportDirArg != null) { Platform.OverrideSupportDir(supportDirArg); } Console.WriteLine("Platform is {0}", Platform.CurrentPlatform); // Load the engine version as early as possible so it can be written to exception logs try { EngineVersion = File.ReadAllText(Platform.ResolvePath(Path.Combine(".", "VERSION"))).Trim(); } catch { } if (string.IsNullOrEmpty(EngineVersion)) { EngineVersion = "Unknown"; } Console.WriteLine("Engine version is {0}", EngineVersion); // Special case handling of Game.Mod argument: if it matches a real filesystem path // then we use this to override the mod search path, and replace it with the mod id var modID = args.GetValue("Game.Mod", null); var explicitModPaths = new string[0]; if (modID != null && (File.Exists(modID) || Directory.Exists(modID))) { explicitModPaths = new[] { modID }; modID = Path.GetFileNameWithoutExtension(modID); } InitializeSettings(args); Log.AddChannel("perf", "perf.log"); Log.AddChannel("debug", "debug.log"); Log.AddChannel("server", "server.log", true); Log.AddChannel("sound", "sound.log"); Log.AddChannel("graphics", "graphics.log"); Log.AddChannel("geoip", "geoip.log"); Log.AddChannel("nat", "nat.log"); var platforms = new[] { Settings.Game.Platform, "Default", null }; foreach (var p in platforms) { if (p == null) { throw new InvalidOperationException("Failed to initialize platform-integration library. Check graphics.log for details."); } Settings.Game.Platform = p; try { var rendererPath = Platform.ResolvePath(Path.Combine(".", "OpenRA.Platforms." + p + ".dll")); var assembly = Assembly.LoadFile(rendererPath); var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t)); if (platformType == null) { throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation."); } var platform = (IPlatform)platformType.GetConstructor(Type.EmptyTypes).Invoke(null); Renderer = new Renderer(platform, Settings.Graphics); Sound = new Sound(platform, Settings.Sound); break; } catch (Exception e) { Log.Write("graphics", "{0}", e); Console.WriteLine("Renderer initialization failed. Check graphics.log for details."); if (Renderer != null) { Renderer.Dispose(); } if (Sound != null) { Sound.Dispose(); } } } GeoIP.Initialize(); if (Settings.Server.DiscoverNatDevices) { discoverNat = UPnP.DiscoverNatDevices(Settings.Server.NatDiscoveryTimeout); } var modSearchArg = args.GetValue("Engine.ModSearchPaths", null); var modSearchPaths = modSearchArg != null? FieldLoader.GetValue <string[]>("Engine.ModsPath", modSearchArg) : new[] { Path.Combine(".", "mods") }; Mods = new InstalledMods(modSearchPaths, explicitModPaths); Console.WriteLine("Internal mods:"); foreach (var mod in Mods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version); } modLaunchWrapper = args.GetValue("Engine.LaunchWrapper", null); ExternalMods = new ExternalMods(); Manifest currentMod; if (modID != null && Mods.TryGetValue(modID, out currentMod)) { var launchPath = args.GetValue("Engine.LaunchPath", Assembly.GetEntryAssembly().Location); // Sanitize input from platform-specific launchers // Process.Start requires paths to not be quoted, even if they contain spaces if (launchPath.First() == '"' && launchPath.Last() == '"') { launchPath = launchPath.Substring(1, launchPath.Length - 2); } ExternalMods.Register(Mods[modID], launchPath, ModRegistration.User); ExternalMod activeMod; if (ExternalMods.TryGetValue(ExternalMod.MakeKey(Mods[modID]), out activeMod)) { ExternalMods.ClearInvalidRegistrations(activeMod, ModRegistration.User); } } Console.WriteLine("External mods:"); foreach (var mod in ExternalMods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version); } InitializeMod(modID, args); }
internal static void Initialize(Arguments args) { Console.WriteLine("Platform is {0}", Platform.CurrentPlatform); // Special case handling of Game.Mod argument: if it matches a real filesystem path // then we use this to override the mod search path, and replace it with the mod id var modArgument = args.GetValue("Game.Mod", null); string customModPath = null; if (modArgument != null && (File.Exists(modArgument) || Directory.Exists(modArgument))) { customModPath = modArgument; args.ReplaceValue("Game.Mod", Path.GetFileNameWithoutExtension(modArgument)); } InitializeSettings(args); Log.AddChannel("perf", "perf.log"); Log.AddChannel("debug", "debug.log"); Log.AddChannel("server", "server.log"); Log.AddChannel("sound", "sound.log"); Log.AddChannel("graphics", "graphics.log"); Log.AddChannel("geoip", "geoip.log"); Log.AddChannel("irc", "irc.log"); Log.AddChannel("nat", "nat.log"); var platforms = new[] { Settings.Game.Platform, "Default", null }; foreach (var p in platforms) { if (p == null) { throw new InvalidOperationException("Failed to initialize platform-integration library. Check graphics.log for details."); } Settings.Game.Platform = p; try { var rendererPath = Platform.ResolvePath(Path.Combine(".", "OpenRA.Platforms." + p + ".dll")); var assembly = Assembly.LoadFile(rendererPath); var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t)); if (platformType == null) { throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation."); } var platform = (IPlatform)platformType.GetConstructor(Type.EmptyTypes).Invoke(null); Renderer = new Renderer(platform, Settings.Graphics); Sound = new Sound(platform, Settings.Sound); break; } catch (Exception e) { Log.Write("graphics", "{0}", e); Console.WriteLine("Renderer initialization failed. Check graphics.log for details."); if (Renderer != null) { Renderer.Dispose(); } if (Sound != null) { Sound.Dispose(); } } } GeoIP.Initialize(); if (!Settings.Server.DiscoverNatDevices) { Settings.Server.AllowPortForward = false; } else { discoverNat = UPnP.DiscoverNatDevices(Settings.Server.NatDiscoveryTimeout); Settings.Server.AllowPortForward = true; } GlobalChat = new GlobalChat(); Mods = new InstalledMods(customModPath); Console.WriteLine("Available mods:"); foreach (var mod in Mods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Metadata.Title, mod.Value.Metadata.Version); } InitializeMod(Settings.Game.Mod, args); }
internal static void Initialize(Arguments args) { Console.WriteLine("Platform is {0}", Platform.CurrentPlatform); InitializeSettings(args); Log.AddChannel("perf", "perf.log"); Log.AddChannel("debug", "debug.log"); Log.AddChannel("sync", "syncreport.log"); Log.AddChannel("server", "server.log"); Log.AddChannel("sound", "sound.log"); Log.AddChannel("graphics", "graphics.log"); Log.AddChannel("geoip", "geoip.log"); Log.AddChannel("irc", "irc.log"); if (Settings.Server.DiscoverNatDevices) { UPnP.TryNatDiscovery(); } else { Settings.Server.NatDeviceAvailable = false; Settings.Server.AllowPortForward = false; } GeoIP.Initialize(); var renderers = new[] { Settings.Graphics.Renderer, "Default", null }; foreach (var r in renderers) { if (r == null) { throw new InvalidOperationException("No suitable renderers were found. Check graphics.log for details."); } Settings.Graphics.Renderer = r; try { Renderer = new Renderer(Settings.Graphics, Settings.Server); break; } catch (Exception e) { Log.Write("graphics", "{0}", e); Console.WriteLine("Renderer initialization failed. Fallback in place. Check graphics.log for details."); } } Sound = new Sound(Settings.Sound.Engine); GlobalChat = new GlobalChat(); Console.WriteLine("Available mods:"); foreach (var mod in ModMetadata.AllMods) { Console.WriteLine("\t{0}: {1} ({2})", mod.Key, mod.Value.Title, mod.Value.Version); } InitializeMod(Settings.Game.Mod, args); if (Settings.Server.DiscoverNatDevices) { RunAfterDelay(Settings.Server.NatDiscoveryTimeout, UPnP.StoppingNatDiscovery); } }
public ClientTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, OrderManager orderManager, int clientIndex) { var admin = widget.Get <LabelWidget>("ADMIN"); var adminFont = Game.Renderer.Fonts[admin.Font]; var latency = widget.GetOrNull <LabelWidget>("LATENCY"); if (latency != null) { latencyFont = Game.Renderer.Fonts[latency.Font]; } var latencyPrefix = widget.GetOrNull <LabelWidget>("LATENCY_PREFIX"); if (latencyPrefix != null) { latencyPrefixFont = Game.Renderer.Fonts[latencyPrefix.Font]; } var ip = widget.Get <LabelWidget>("IP"); var addressFont = Game.Renderer.Fonts[ip.Font]; var location = widget.Get <LabelWidget>("LOCATION"); var locationFont = Game.Renderer.Fonts[location.Font]; var locationOffset = location.Bounds.Y; var addressOffset = ip.Bounds.Y; var latencyOffset = latency == null ? 0 : latency.Bounds.Y; var tooltipHeight = widget.Bounds.Height; var margin = widget.Bounds.Width; widget.IsVisible = () => (orderManager.LobbyInfo.ClientWithIndex(clientIndex) != null); tooltipContainer.BeforeRender = () => { if (!widget.IsVisible()) { return; } var latencyPrefixSize = latencyPrefix == null ? 0 : latencyPrefix.Bounds.X + latencyPrefixFont.Measure(latencyPrefix.GetText() + " ").X; var locationWidth = locationFont.Measure(location.GetText()).X; var adminWidth = adminFont.Measure(admin.GetText()).X; var addressWidth = addressFont.Measure(ip.GetText()).X; var latencyWidth = latencyFont == null ? 0 : latencyPrefixSize + latencyFont.Measure(latency.GetText()).X; var width = Math.Max(locationWidth, Math.Max(adminWidth, Math.Max(addressWidth, latencyWidth))); widget.Bounds.Width = width + 2 * margin; if (latency != null) { latency.Bounds.Width = widget.Bounds.Width; } ip.Bounds.Width = widget.Bounds.Width; admin.Bounds.Width = widget.Bounds.Width; location.Bounds.Width = widget.Bounds.Width; ip.Bounds.Y = addressOffset; if (latency != null) { latency.Bounds.Y = latencyOffset; } location.Bounds.Y = locationOffset; widget.Bounds.Height = tooltipHeight; if (admin.IsVisible()) { ip.Bounds.Y += admin.Bounds.Height; if (latency != null) { latency.Bounds.Y += admin.Bounds.Height; } location.Bounds.Y += admin.Bounds.Height; widget.Bounds.Height += admin.Bounds.Height; } if (latencyPrefix != null) { latencyPrefix.Bounds.Y = latency.Bounds.Y; } if (latency != null) { latency.Bounds.X = latencyPrefixSize; } }; admin.IsVisible = () => orderManager.LobbyInfo.ClientWithIndex(clientIndex).IsAdmin; var client = orderManager.LobbyInfo.ClientWithIndex(clientIndex); var ping = orderManager.LobbyInfo.PingFromClient(client); if (latency != null) { latency.GetText = () => LobbyUtils.LatencyDescription(ping); latency.GetColor = () => LobbyUtils.LatencyColor(ping); } var address = LobbyUtils.GetExternalIP(clientIndex, orderManager); var cachedDescriptiveIP = LobbyUtils.DescriptiveIpAddress(address); ip.GetText = () => cachedDescriptiveIP; var cachedCountryLookup = GeoIP.LookupCountry(address); location.GetText = () => cachedCountryLookup; }