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 client = new Session.Client { Name = OpenRA.Settings.SanitizedPlayerName(handshake.Client.Name), IpAddress = ((IPEndPoint)newConn.Socket.RemoteEndPoint).Address.ToString(), Index = newConn.PlayerIndex, Slot = LobbyInfo.FirstEmptySlot(), PreferredColor = handshake.Client.Color, Color = handshake.Client.Color, Faction = "Random", SpawnPoint = 0, Team = 0, State = Session.ClientState.Invalid, 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 = HSLColor.FromRGB(255, 255, 255); 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 && !LobbyInfo.GlobalSettings.AllowVersionMismatch) { 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; } // 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; } // Promote connection to a valid client PreConns.Remove(newConn); Conns.Add(newConn); LobbyInfo.Clients.Add(client); 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); 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); if (Dedicated || !LobbyInfo.IsSinglePlayer) SendMessage("{0} has joined the game.".F(client.Name)); // Send initial ping SendOrderTo(newConn, "Ping", Game.RunTime.ToString(CultureInfo.InvariantCulture)); if (Dedicated) { var motdFile = Platform.ResolvePath("^", "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 (!LobbyInfo.IsSinglePlayer && 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 (handshake.Mod == "{DEV_VERSION}") SendMessage("{0} is running an unversioned development build, ".F(client.Name) + "and may desynchronize the game state if they have incompatible rules."); } catch (Exception ex) { Log.Write("server", "Dropping connection {0} because an error occurred:", newConn.Socket.RemoteEndPoint); Log.Write("server", ex.ToString()); DropClient(newConn); } }
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 client = new Session.Client() { Name = handshake.Client.Name, IpAddress = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString(), Index = newConn.PlayerIndex, Slot = LobbyInfo.FirstEmptySlot(), PreferredColor = handshake.Client.Color, Color = handshake.Client.Color, Country = "random", SpawnPoint = 0, Team = 0, State = Session.ClientState.Invalid, 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[client.Slot]); else client.Color = HSLColor.FromRGB(255, 255, 255); if (ModData.Manifest.Mod.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.Mod.Version != handshake.Version && !LobbyInfo.GlobalSettings.AllowVersionMismatch) { 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; } // 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; } // Promote connection to a valid client PreConns.Remove(newConn); Conns.Add(newConn); LobbyInfo.Clients.Add(client); var clientPing = new Session.ClientPing(); clientPing.Index = client.Index; LobbyInfo.ClientPings.Add(clientPing); Log.Write("server", "Client {0}: Accepted connection from {1}.", newConn.PlayerIndex, newConn.socket.RemoteEndPoint); foreach (var t in serverTraits.WithInterface<IClientJoined>()) t.ClientJoined(this, newConn); SyncLobbyInfo(); SendMessage("{0} has joined the server.".F(client.Name)); // Send initial ping SendOrderTo(newConn, "Ping", Environment.TickCount.ToString()); if (Settings.Dedicated) { var motdFile = Path.Combine(Platform.SupportDir, "motd.txt"); if (!File.Exists(motdFile)) System.IO.File.WriteAllText(motdFile, "Welcome, have fun and good luck!"); var motd = System.IO.File.ReadAllText(motdFile); if (!string.IsNullOrEmpty(motd)) SendOrderTo(newConn, "Message", motd); } if (handshake.Mod == "{DEV_VERSION}") SendMessage("{0} is running an unversioned development build, ".F(client.Name) + "and may desynchronize the game state if they have incompatible rules."); SetOrderLag(); } catch (Exception) { DropClient(newConn); } }