示例#1
0
        public static bool ValidateCommand(S server, EW.Server.Connection conn, Session.Client client, string cmd)
        {
            if (server.State == ServerState.GameStarted)
            {
                server.SendOrderTo(conn, "Message", "Cannot change state when game started.({0})".F(cmd));
                return(false);
            }
            else if (client.State == Session.ClientState.Ready && !(cmd.StartsWith("state") || cmd == "startgame"))
            {
                server.SendOrderTo(conn, "Message", "Cannot change state when marked as ready.");
                return(false);
            }

            return(true);
        }
示例#2
0
        static bool ValidateSlotCommand(S server, Connection conn, Session.Client client, string arg, bool requiresHost)
        {
            if (!server.LobbyInfo.Slots.ContainsKey(arg))
            {
                return(false);
            }

            if (requiresHost && !client.IsAdmin)
            {
                server.SendOrderTo(conn, "Message", "Only the host can do that");
                return(false);
            }
            return(true);
        }
示例#3
0
        static HSLColor SanitizePlayerColor(S server, HSLColor askedColor, int playerIndex, Connection connectionToEcho = null)
        {
            var validator = server.ModData.Manifest.Get <ColorValidator>();
            var askColor  = askedColor;

            Action <string> onError = message =>
            {
                if (connectionToEcho != null)
                {
                    server.SendOrderTo(connectionToEcho, "Message", message);
                }
            };

            var tileset       = server.Map.Rules.TileSet;
            var terrainColors = tileset.TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color).ToList();
            var playerColors  = server.LobbyInfo.Clients.Where(c => c.Index != playerIndex).Select(c => c.Color.RGB)
                                .Concat(server.Map.Players.Players.Values.Select(p => p.Color.RGB)).ToList();

            return(validator.MakeValid(askColor.RGB, server.Random, terrainColors, playerColors, onError));
        }
示例#4
0
        void ITick.Tick(S server)
        {
            if ((WarGame.RunTime - lastPing) > PingInterval || isInitialPing)
            {
                isInitialPing = false;
                lastPing      = WarGame.RunTime;

                //Ignore client timeout in singleplayer games to make debugging easier
                if (server.LobbyInfo.NonBotClients.Count() < 2 && !server.Dedicated)
                {
                    foreach (var c in server.Conns.ToList())
                    {
                        server.SendOrderTo(c, "Ping", WarGame.RunTime.ToString());
                    }
                }
                else
                {
                    foreach (var c in server.Conns.ToList())
                    {
                        if (c == null || c.Socket == null)
                        {
                            continue;
                        }

                        var client = server.GetClient(c);
                        if (client == null)
                        {
                            server.DropClient(c);
                            server.SendMessage("A player has been dropped after timing out.");
                            continue;
                        }

                        if (c.TimeSinceLastResponse < ConnTimeout)
                        {
                            server.SendOrderTo(c, "Ping", WarGame.RunTime.ToString());
                            if (!c.TimeoutMessageShown && c.TimeSinceLastResponse > PingInterval * 2)
                            {
                                server.SendMessage(client.Name + " is experiencing connection problems.");
                                c.TimeoutMessageShown = true;
                            }
                        }
                        else
                        {
                            server.SendMessage(client.Name + " has benn dropped after timing out.");
                            server.DropClient(c);
                        }
                    }
                }

                if (WarGame.RunTime - lastConnReport > ConnReportInterval)
                {
                    lastConnReport = WarGame.RunTime;

                    var timeouts = server.Conns.Where(c => c.TimeSinceLastResponse > ConnReportInterval && c.TimeSinceLastResponse < ConnTimeout).OrderBy(c => c.TimeSinceLastResponse);

                    foreach (var c in timeouts)
                    {
                        if (c == null || c.Socket == null)
                        {
                            continue;
                        }

                        var client = server.GetClient(c);
                        if (client != null)
                        {
                            server.SendMessage("{0} will be dropped in {1} seconds.".F(client.Name, (ConnTimeout - c.TimeSinceLastResponse) / 1000));
                        }
                    }
                }
            }
        }
示例#5
0
        public bool InterpretCommand(S server, EW.Server.Connection conn, Session.Client client, string cmd)
        {
            if (server == null || conn == null || client == null || !ValidateCommand(server, conn, client, cmd))
            {
                return(false);
            }

            var dict = new Dictionary <string, Func <string, bool> >
            {
                {
                    "state",
                    s =>
                    {
                        var state = Session.ClientState.Invalid;
                        if (!Enum <Session.ClientState> .TryParse(s, false, out state))
                        {
                            server.SendOrderTo(conn, "Message", "Malformed state command");
                            return(true);
                        }
                        client.State = state;

                        server.SyncLobbyClients();
                        CheckAutoStart(server);
                        return(true);
                    }
                },
                {
                    "startgame",
                    s =>
                    {
                        if (!client.IsAdmin)
                        {
                            server.SendOrderTo(conn, "Message", "Only the host can start the game.");
                            return(true);
                        }

                        if (server.LobbyInfo.Slots.Any(sl => sl.Value.Required &&
                                                       server.LobbyInfo.ClientInSlot(sl.Key) == null))
                        {
                            server.SendOrderTo(conn, "Message", "Unable to start the game until required slots are full.");
                            return(true);
                        }

                        if (!server.LobbyInfo.GlobalSettings.EnableSinglePlayer && server.LobbyInfo.NonBotPlayers.Count() < 2)
                        {
                            server.SendOrderTo(conn, "Message", server.TwoHumansRequiredText);
                            return(true);
                        }

                        server.StartGame();
                        return(true);
                    }
                },
                {
                    "slot_bot",
                    s => {
                        var parts = s.Split(' ');

                        if (parts.Length < 3)
                        {
                            server.SendOrderTo(conn, "Message", " Malformed slot_bot command");
                            return(true);
                        }

                        if (!ValidateSlotCommand(server, conn, client, parts[0], true))
                        {
                            return(false);
                        }

                        var slot = server.LobbyInfo.Slots[parts[0]];
                        var bot  = server.LobbyInfo.ClientInSlot(parts[0]);
                        int controllerClientIndex;

                        if (!Exts.TryParseIntegerInvariant(parts[1], out controllerClientIndex))
                        {
                            return(false);
                        }
                        // Invalid slot

                        if (bot != null && bot.Bot == null)
                        {
                            server.SendOrderTo(conn, "Message", "Can't add bots to a slot with  another client");
                            return(true);
                        }

                        var botType = parts[2];
                        var botInfo = server.Map.Rules.Actors["player"].TraitInfos <IBotInfo>().FirstOrDefault(b => b.Type == botType);

                        if (botInfo == null)
                        {
                            server.SendOrderTo(conn, "Message", "Invalid bot type.");
                            return(true);
                        }

                        slot.Closed = false;
                        if (bot == null)
                        {
                            //Create a new bot
                            bot = new Session.Client()
                            {
                                Index      = server.ChooseFreePlayerIndex(),
                                Name       = botInfo.Name,
                                Bot        = botType,
                                Slot       = parts[0],
                                Faction    = "Random",
                                SpawnPoint = 0,
                                Team       = 0,
                                State      = Session.ClientState.NotReady,
                                BotControllerClientIndex = controllerClientIndex,
                            };

                            // Pick a random color for the bot
                            var validator     = server.ModData.Manifest.Get <ColorValidator>();
                            var tileset       = server.Map.Rules.TileSet;
                            var terrainColors = tileset.TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color);
                            var playerColors  = server.LobbyInfo.Clients.Select(c => c.Color.RGB)
                                                .Concat(server.Map.Players.Players.Values.Select(p => p.Color.RGB));

                            bot.Color = bot.PreferredColor = validator.RandomValidColor(server.Random, terrainColors, playerColors);

                            server.LobbyInfo.Clients.Add(bot);
                        }
                        else
                        {
                            // Change the type of the existing bot
                            bot.Name = botInfo.Name;
                            bot.Bot  = botType;
                        }

                        S.SyncClientToPlayerReference(bot, server.Map.Players.Players[parts[0]]);
                        server.SyncLobbyClients();
                        server.SyncLobbySlots();
                        return(true);
                    }
                },
                {
                    "map",
                    s =>
                    {
                        if (!client.IsAdmin)
                        {
                            server.SendOrderTo(conn, "Message", "Only the host can change the map.");
                            return(true);
                        }

                        var lastMap = server.LobbyInfo.GlobalSettings.Map;

                        Action <MapPreview> selectMap = map =>
                        {
                            if (server.LobbyInfo.GlobalSettings.Map != lastMap)
                            {
                                return;
                            }

                            server.LobbyInfo.GlobalSettings.Map = map.Uid;

                            var oldSlots = server.LobbyInfo.Slots.Keys.ToArray();
                            server.Map = server.ModData.MapCache[server.LobbyInfo.GlobalSettings.Map];

                            server.LobbyInfo.Slots = server.Map.Players.Players
                                                     .Select(p => MakeSlotFromPlayerReference(p.Value))
                                                     .Where(ss => ss != null)
                                                     .ToDictionary(ss => ss.PlayerReference, ss => ss);

                            LoadMapSettings(server, server.LobbyInfo.GlobalSettings, server.Map.Rules);

                            //Reset Client states.
                            foreach (var c in server.LobbyInfo.Clients)
                            {
                                c.State = Session.ClientState.Invalid;
                            }

                            var botTypes = server.Map.Rules.Actors["player"].TraitInfos <IBotInfo>().Select(t => t.Type);
                            var slots    = server.LobbyInfo.Slots.Keys.ToArray();
                            var i        = 0;
                            foreach (var os in oldSlots)
                            {
                                var c = server.LobbyInfo.ClientInSlot(os);
                                if (c == null)
                                {
                                    continue;
                                }

                                c.SpawnPoint = 0;
                                c.Slot       = i < slots.Length?slots[i++]:null;
                                if (c.Slot != null)
                                {
                                    if (c.Bot != null && (!server.Map.Players.Players[c.Slot].AllowBots || !botTypes.Contains(c.Bot)))
                                    {
                                        server.LobbyInfo.Clients.Remove(c);
                                    }

                                    S.SyncClientToPlayerReference(c, server.Map.Players.Players[c.Slot]);
                                }
                                else if (c.Bot != null)
                                {
                                    server.LobbyInfo.Clients.Remove(c);
                                }
                            }

                            foreach (var c in server.LobbyInfo.Clients)
                            {
                                if (c.Slot != null && !server.LobbyInfo.Slots[c.Slot].LockColor)
                                {
                                    c.Color = c.PreferredColor = SanitizePlayerColor(server, c.Color, c.Index, conn);
                                }
                            }

                            server.SyncLobbyInfo();

                            server.SendMessage("{0} changed the map to {1}.".F(client.Name, server.Map.Title));

                            if (!server.LobbyInfo.GlobalSettings.EnableSingleplayer)
                            {
                                server.SendMessage(server.TwoHumansRequiredText);
                            }
                            else if (server.Map.Players.Players.Where(p => p.Value.Playable).All(p => !p.Value.AllowBots))
                            {
                                server.SendMessage("Bots have been disabled on this map.");
                            }

                            var briefing = MissionBriefingOrDefault(server);
                            if (briefing != null)
                            {
                                server.SendMessage(briefing);
                            }
                        };

                        Action queryFailed = () =>
                                             server.SendOrderTo(conn, "Message", "Map was not found on server.");

                        var m = server.ModData.MapCache[s];
                        if (m.Status == MapStatus.Available || m.Status == MapStatus.DownloadAvailable)
                        {
                            selectMap(m);
                        }
                        else if (server.Settings.QueryMapRepository)
                        {
                        }
                        else
                        {
                            queryFailed();
                        }
                        return(true);
                    }
                }
            };

            var cmdName  = cmd.Split(' ').First();
            var cmdValue = cmd.Split(' ').Skip(1).JoinWith(" ");

            Func <string, bool> a;

            if (!dict.TryGetValue(cmdName, out a))
            {
                return(false);
            }

            return(a(cmdValue));
        }