Пример #1
0
        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);
            }
        }
Пример #2
0
        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); }
        }