Exemple #1
0
        public void DropClient(Connection toDrop)
        {
            if (preConns.Contains(toDrop))
            {
                preConns.Remove(toDrop);
            }
            else
            {
                conns.Remove(toDrop);

                OpenRA.Network.Session.Client dropClient = lobbyInfo.Clients.Where(c1 => c1.Index == toDrop.PlayerIndex).Single();

                // Send disconnected order, even if still in the lobby
                SendMessage("{0} has disconnected.".F(dropClient.Name));
                DispatchOrdersToClients(toDrop, 0, new ServerOrder("Disconnected", "").Serialize());

                lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);

                // Client was the server admin
                // TODO: Reassign admin for game in progress via an order
                if (lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && State == ServerState.WaitingPlayers)
                {
                    // Remove any bots controlled by the admin
                    lobbyInfo.Clients.RemoveAll(c => c.Bot != null && c.BotControllerClientIndex == toDrop.PlayerIndex);

                    OpenRA.Network.Session.Client nextAdmin = lobbyInfo.Clients.Where(c1 => c1.Bot == null)
                                                              .OrderBy(c => c.Index).FirstOrDefault();

                    if (nextAdmin != null)
                    {
                        nextAdmin.IsAdmin = true;
                        SendMessage("{0} is now the admin.".F(nextAdmin.Name));
                    }
                }

                DispatchOrders(toDrop, toDrop.MostRecentFrame, new byte[] { 0xbf });

                if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated)
                {
                    SyncLobbyInfo();
                }

                if (!lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin)
                {
                    Shutdown();
                }
            }

            try
            {
                toDrop.socket.Disconnect(false);
            }
            catch { }
        }
Exemple #2
0
        public void DropClient(Connection toDrop)
        {
            if (preConns.Contains(toDrop))
            {
                preConns.Remove(toDrop);
            }
            else
            {
                conns.Remove(toDrop);
                SendChat(toDrop, "Connection Dropped");

                OpenRA.Network.Session.Client dropClient = lobbyInfo.Clients.Where(c1 => c1.Index == toDrop.PlayerIndex).Single();

                if (GameStarted)
                {
                    SendDisconnected(toDrop);                     /* Report disconnection */
                }
                lobbyInfo.Clients.RemoveAll(c => c.Index == toDrop.PlayerIndex);

                // reassign admin if necessary
                if (lobbyInfo.GlobalSettings.Dedicated && dropClient.IsAdmin && !GameStarted)
                {
                    if (lobbyInfo.Clients.Count() > 0)
                    {
                        // client was not alone on the server but he was admin: set admin to the last connected client
                        OpenRA.Network.Session.Client lastClient = lobbyInfo.Clients.Last();
                        lastClient.IsAdmin = true;
                        SendChat(toDrop, "Admin left! {0} is a new admin now!".F(lastClient.Name));
                    }
                }

                DispatchOrders(toDrop, toDrop.MostRecentFrame, new byte[] { 0xbf });

                if (conns.Count != 0 || lobbyInfo.GlobalSettings.Dedicated)
                {
                    SyncLobbyInfo();
                }
            }

            try
            {
                toDrop.socket.Disconnect(false);
            }
            catch { }
        }
Exemple #3
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);
                var client    = handshake.Client;
                var mods      = handshake.Mods;

                // Check that the client has compatible mods
                var validMod = mods.All(m => m.Contains('@')) &&                 //valid format
                               mods.Count() == Game.CurrentMods.Count() &&       //same number
                               mods.Select(m => Pair.New(m.Split('@')[0], m.Split('@')[1])).All(kv => Game.CurrentMods.ContainsKey(kv.First));

                if (!validMod)
                {
                    Log.Write("server", "Rejected connection from {0}; mods do not match.",
                              newConn.socket.RemoteEndPoint);

                    SendOrderTo(newConn, "ServerError", "Your mods don't match the server");
                    DropClient(newConn);
                    return;
                }

                var validVersion = mods.Select(m => Pair.New(m.Split('@')[0], m.Split('@')[1])).All(
                    kv => kv.Second == Game.CurrentMods[kv.First].Version);

                if (!validVersion && !lobbyInfo.GlobalSettings.AllowVersionMismatch)
                {
                    Log.Write("server", "Rejected connection from {0}; Not running the same version.",
                              newConn.socket.RemoteEndPoint);

                    SendOrderTo(newConn, "ServerError", "Not running the same version.");
                    DropClient(newConn);
                    return;
                }

                client.IpAddress = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString();

                // Check if IP is banned
                if (lobbyInfo.GlobalSettings.Ban != null)
                {
                    if (lobbyInfo.GlobalSettings.Ban.Contains(client.IpAddress))
                    {
                        Console.WriteLine("Rejected connection from " + client.Name + "(" + newConn.socket.RemoteEndPoint + "); Banned.");
                        Log.Write("server", "Rejected connection from {0}; Banned.",
                                  newConn.socket.RemoteEndPoint);
                        SendOrderTo(newConn, "ServerError", "You are banned from the server!");
                        DropClient(newConn);
                        return;
                    }
                }

                // Promote connection to a valid client
                preConns.Remove(newConn);
                conns.Add(newConn);

                // Enforce correct PlayerIndex and Slot
                client.Index = newConn.PlayerIndex;
                client.Slot  = lobbyInfo.FirstEmptySlot();

                if (client.Slot != null)
                {
                    SyncClientToPlayerReference(client, Map.Players[client.Slot]);
                }

                lobbyInfo.Clients.Add(client);

                // Assume that first validated client is server admin
                if (lobbyInfo.Clients.Where(c1 => c1.Bot == null).Count() == 1)
                {
                    client.IsAdmin = true;
                }

                OpenRA.Network.Session.Client clientAdmin = lobbyInfo.Clients.Where(c1 => c1.IsAdmin).Single();

                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 (File.Exists("{0}motd_{1}.txt".F(Platform.SupportDir, lobbyInfo.GlobalSettings.Mods[0])))
                {
                    var motd = System.IO.File.ReadAllText("{0}motd_{1}.txt".F(Platform.SupportDir, lobbyInfo.GlobalSettings.Mods[0]));
                    SendOrderTo(newConn, "Message", motd);
                }

                if (lobbyInfo.GlobalSettings.Dedicated)
                {
                    var message = client.IsAdmin ? "You are the server admin." : "{0} is the server admin.".F(clientAdmin.Name);
                    SendOrderTo(newConn, "Message", message);
                }

                if (mods.Any(m => m.Contains("{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) { DropClient(newConn); }
        }
Exemple #4
0
        void ValidateClient(Connection newConn, string data)
        {
            try
            {
                if (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);
                var client    = handshake.Client;
                var mods      = handshake.Mods;

                // Check that the client has compatible mods
                var valid = mods.All(m => m.Contains('@')) &&                  //valid format
                            mods.Count() == Game.CurrentMods.Count() &&        //same number
                            mods.Select(m => Pair.New(m.Split('@')[0], m.Split('@')[1])).All(kv => Game.CurrentMods.ContainsKey(kv.First) &&
                                                                                             (kv.Second == "{DEV_VERSION}" || Game.CurrentMods[kv.First].Version == "{DEV_VERSION}" || kv.Second == Game.CurrentMods[kv.First].Version));

                if (!valid)
                {
                    Log.Write("server", "Rejected connection from {0}; mods do not match.",
                              newConn.socket.RemoteEndPoint);

                    SendOrderTo(newConn, "ServerError", "Your mods don't match the server");
                    DropClient(newConn);
                    return;
                }

                // Drop DEV_VERSION if it's a Dedicated
                if (lobbyInfo.GlobalSettings.Dedicated && mods.Any(m => m.Contains("{DEV_VERSION}")))
                {
                    Log.Write("server", "Rejected connection from {0}; DEV_VERSION is not allowed here.",
                              newConn.socket.RemoteEndPoint);

                    SendOrderTo(newConn, "ServerError", "DEV_VERSION is not allowed here");
                    DropClient(newConn);
                    return;
                }

                // Check if IP is banned
                if (lobbyInfo.GlobalSettings.Ban != null)
                {
                    var remote_addr = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString();
                    if (lobbyInfo.GlobalSettings.Ban.Contains(remote_addr))
                    {
                        Console.WriteLine("Rejected connection from " + client.Name + "(" + newConn.socket.RemoteEndPoint + "); Banned.");
                        Log.Write("server", "Rejected connection from {0}; Banned.",
                                  newConn.socket.RemoteEndPoint);
                        SendOrderTo(newConn, "ServerError", "You are banned from the server!");
                        DropClient(newConn);
                        return;
                    }
                }

                // Promote connection to a valid client
                preConns.Remove(newConn);
                conns.Add(newConn);

                // Enforce correct PlayerIndex and Slot
                client.Index = newConn.PlayerIndex;
                client.Slot  = lobbyInfo.FirstEmptySlot();

                if (client.Slot != null)
                {
                    SyncClientToPlayerReference(client, Map.Players[client.Slot]);
                }

                lobbyInfo.Clients.Add(client);
                //Assume that first validated client is server admin
                if (lobbyInfo.Clients.Count == 1)
                {
                    client.IsAdmin = true;
                }

                OpenRA.Network.Session.Client clientAdmin = lobbyInfo.Clients.Where(c1 => c1.IsAdmin).Single();

                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();
                SendChat(newConn, "has joined the game.");

                if (lobbyInfo.GlobalSettings.Dedicated)
                {
                    if (lobbyInfo.GlobalSettings.DedicatedMOTD != null)
                    {
                        SendChatTo(newConn, lobbyInfo.GlobalSettings.DedicatedMOTD);
                    }
                    if (client.IsAdmin)
                    {
                        SendChatTo(newConn, "    You are admin now!");
                    }
                    else
                    {
                        SendChatTo(newConn, "    Current admin is {0}".F(clientAdmin.Name));
                    }
                }

                if (mods.Any(m => m.Contains("{DEV_VERSION}")))
                {
                    SendChat(newConn, "is running a development version, " +
                             "and may cause desync if they have any incompatible changes.");
                }
            }
            catch (Exception) { DropClient(newConn); }
        }