IssueOrder() public method

public IssueOrder ( Order order ) : void
order Order
return void
Exemplo n.º 1
0
		public static void ShowSlotDropDown(Ruleset rules, DropDownButtonWidget dropdown, Session.Slot slot,
			Session.Client client, OrderManager orderManager)
		{
			var options = new Dictionary<string, IEnumerable<SlotDropDownOption>>() {{"Slot", new List<SlotDropDownOption>()
			{
				new SlotDropDownOption("Open", "slot_open "+slot.PlayerReference, () => (!slot.Closed && client == null)),
				new SlotDropDownOption("Closed", "slot_close "+slot.PlayerReference, () => slot.Closed)
			}}};

			var bots = new List<SlotDropDownOption>();
			if (slot.AllowBots)
			{
				foreach (var b in rules.Actors["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name))
				{
					var bot = b;
					var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
					bots.Add(new SlotDropDownOption(bot,
						"slot_bot {0} {1} {2}".F(slot.PlayerReference, botController.Index, bot),
						() => client != null && client.Bot == bot));
				}
			}
			options.Add(bots.Any() ? "Bots" : "Bots Disabled", bots);

			Func<SlotDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
			{
				var item = ScrollItemWidget.Setup(itemTemplate,
					o.Selected,
					() => orderManager.IssueOrder(Order.Command(o.Order)));
				item.Get<LabelWidget>("LABEL").GetText = () => o.Title;
				return item;
			};

			dropdown.ShowDropDown<SlotDropDownOption>("LABEL_DROPDOWN_TEMPLATE", 167, options, setupItem);
		}
Exemplo n.º 2
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world)
        {
            World = world;
            var chatPanel = (ContainerWidget) widget;

            ChatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
            ChatOverlayDisplay = ChatOverlay.Get<ChatDisplayWidget>("CHAT_DISPLAY");
            ChatOverlay.Visible = false;

            ChatChrome = chatPanel.Get<ContainerWidget>("CHAT_CHROME");
            ChatChrome.Visible = true;

            var chatMode = ChatChrome.Get<ButtonWidget>("CHAT_MODE");
            chatMode.GetText = () => TeamChat ? "Team" : "All";
            chatMode.OnClick = () => TeamChat = !TeamChat;

            ChatText = ChatChrome.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            ChatText.OnTabKey = () => { TeamChat = !TeamChat; return true; };
            ChatText.OnEnterKey = () =>
            {
                ChatText.Text = ChatText.Text.Trim();
                if (ChatText.Text != "")
                    orderManager.IssueOrder(Order.Chat(TeamChat, ChatText.Text));
                CloseChat();
                return true;
            };
            ChatText.OnEscKey = () => {CloseChat(); return true; };

            var chatClose = ChatChrome.Get<ButtonWidget>("CHAT_CLOSE");
            chatClose.OnClick += () => CloseChat();

            chatPanel.OnKeyPress = (e) =>
            {
                if (e.Event == KeyInputEvent.Up) return false;
                if (!IsOpen && (e.KeyName == "enter" || e.KeyName == "return") )
                {

                    var shift = e.Modifiers.HasModifier(Modifiers.Shift);
                    var toggle = Game.Settings.Game.TeamChatToggle ;
                    TeamChat = (!toggle && shift) || ( toggle &&  (TeamChat ^ shift) );
                    OpenChat();
                    return true;
                }

                return false;
            };

            ChatScrollPanel = ChatChrome.Get<ScrollPanelWidget>("CHAT_SCROLLPANEL");
            ChatTemplate = ChatScrollPanel.Get<ContainerWidget>("CHAT_TEMPLATE");

            Game.AddChatLine += AddChatLine;
            Game.BeforeGameStart += UnregisterEvents;

            CloseChat();
            ChatOverlayDisplay.AddLine(Color.White, null, "Use RETURN key to open chat window...");
        }
Exemplo n.º 3
0
		public static void ShowTeamDropDown(DropDownButtonWidget dropdown, Session.Client client,
			OrderManager orderManager, int teamCount)
		{
			Func<int, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, itemTemplate) =>
			{
				var item = ScrollItemWidget.Setup(itemTemplate,
					() => client.Team == ii,
					() => orderManager.IssueOrder(Order.Command("team {0} {1}".F(client.Index, ii))));
				item.Get<LabelWidget>("LABEL").GetText = () => ii == 0 ? "-" : ii.ToString();
				return item;
			};

			var options = Exts.MakeArray(teamCount + 1, i => i).ToList();
			dropdown.ShowDropDown("TEAM_DROPDOWN_TEMPLATE", 150, options, setupItem);
		}
Exemplo n.º 4
0
        public static void ShowRaceDropDown(DropDownButtonWidget dropdown, Session.Client client,
			OrderManager orderManager, Dictionary<string, string> countryNames)
        {
            Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (race, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                    () => client.Country == race,
                    () => orderManager.IssueOrder(Order.Command("race {0} {1}".F(client.Index, race))));
                item.GetWidget<LabelWidget>("LABEL").GetText = () => countryNames[race];
                var flag = item.GetWidget<ImageWidget>("FLAG");
                flag.GetImageCollection = () => "flags";
                flag.GetImageName = () => race;
                return item;
            };

            dropdown.ShowDropDown("RACE_DROPDOWN_TEMPLATE", 150, countryNames.Keys.ToList(), setupItem);
        }
        public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, Map map, MouseInput mi)
        {
            if (map == null || mi.Button != MouseButton.Left
                || orderManager.LocalClient.State == Session.ClientState.Ready)
                return;

            var selectedSpawn = map.GetSpawnPoints()
                .Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(sp), i))
                .Where(a => (a.First - mi.Location).LengthSquared < 64)
                .Select(a => a.Second + 1)
                .FirstOrDefault();

            var owned = orderManager.LobbyInfo.Clients.Any(c => c.SpawnPoint == selectedSpawn);
            if (selectedSpawn == 0 || !owned)
            {
                var locals = orderManager.LobbyInfo.Clients.Where(c => c.Index == orderManager.LocalClient.Index || (Game.IsHost && c.Bot != null));
                var playerToMove = locals.Where(c => (selectedSpawn == 0) ^ (c.SpawnPoint == 0)).FirstOrDefault();
                orderManager.IssueOrder(Order.Command("spawn {0} {1}".F((playerToMove ?? orderManager.LocalClient).Index, selectedSpawn)));
            }
        }
        public static void SetupNameWidget(OrderManager orderManager, Session.Client c, TextFieldWidget name)
        {
            name.Text = c.Name;
            name.OnEnterKey = () =>
            {
                name.Text = name.Text.Trim();
                if (name.Text.Length == 0)
                    name.Text = c.Name;

                name.LoseFocus();
                if (name.Text == c.Name)
                    return true;

                orderManager.IssueOrder(Order.Command("name " + name.Text));
                Game.Settings.Player.Name = name.Text;
                Game.Settings.Save();
                return true;
            };
            name.OnLoseFocus = () => name.OnEnterKey();
        }
Exemplo n.º 7
0
        public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            if (world != null)
            {
                if (!world.WorldActor.TraitsImplementing<IValidateOrder>().All(vo =>
                    vo.OrderValidation(orderManager, world, clientId, order)))
                    return;
            }

            switch (order.OrderString)
            {
                case "Chat":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                        {
                            var player = world != null ? world.FindPlayerByClient(client) : null;
                            var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
                            Game.AddChatLine(client.ColorRamp.GetColor(0), client.Name + suffix, order.TargetString);
                        }
                        else
                            Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
                        break;
                    }
                case "Disconnected": /* reports that the target player disconnected */
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                        {
                            client.State = Session.ClientState.Disconnected;
                        }
                        break;
                    }
                case "TeamChat":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                        if (client != null)
                        {
                            if (world == null)
                            {
                                if (client.Team == orderManager.LocalClient.Team)
                                    Game.AddChatLine(client.ColorRamp.GetColor(0), client.Name + " (Team)",
                                                     order.TargetString);
                            }
                            else
                            {
                                var player = world.FindPlayerByClient(client);
                                var display = player != null
                                              &&
                                              (world.LocalPlayer != null &&
                                               player.Stances[world.LocalPlayer] == Stance.Ally
                                               || player.WinState == WinState.Lost);

                                if (display)
                                {
                                    var suffix = (player != null && player.WinState == WinState.Lost)
                                                     ? " (Dead)"
                                                     : " (Team)";
                                    Game.AddChatLine(client.ColorRamp.GetColor(0), client.Name + suffix, order.TargetString);
                                }
                            }
                        }
                        break;
                    }
                case "StartGame":
                    {
                        Game.AddChatLine(Color.White, "Server", "The game has started.");
                        Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map);
                        break;
                    }

                case "HandshakeRequest":
                {
                    var request = HandshakeRequest.Deserialize(order.TargetString);

                    // Check that the map exists on the client
                    if (!Game.modData.AvailableMaps.ContainsKey(request.Map))
                        throw new InvalidOperationException("Missing map {0}".F(request.Map));

                    var info = new Session.Client()
                    {
                        Name = Game.Settings.Player.Name,
                        ColorRamp = Game.Settings.Player.ColorRamp,
                        Country = "random",
                        SpawnPoint = 0,
                        Team = 0,
                        State = Session.ClientState.NotReady
                    };

                    var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m,Mod.AllMods[m].Version)).ToArray();
                    var response = new HandshakeResponse()
                    {
                        Client = info,
                        Mods = localMods,
                        Password = "******"
                    };

                    orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
                    break;
                }
                case "ServerError":
                    orderManager.ServerError = order.TargetString;
                break;
                case "SyncInfo":
                    {
                        orderManager.LobbyInfo = Session.Deserialize(order.TargetString);

                        if (orderManager.FramesAhead != orderManager.LobbyInfo.GlobalSettings.OrderLatency
                            && !orderManager.GameStarted)
                        {
                            orderManager.FramesAhead = orderManager.LobbyInfo.GlobalSettings.OrderLatency;
                            Game.Debug(
                                "Order lag is now {0} frames.".F(orderManager.LobbyInfo.GlobalSettings.OrderLatency));
                        }
                        Game.SyncLobbyInfo();
                        break;
                    }

                case "SetStance":
                    {
                        if (Game.orderManager.LobbyInfo.GlobalSettings.LockTeams)
                            return;

                        var targetPlayer = order.Player.World.players[order.TargetLocation.X];
                        var newStance = (Stance)order.TargetLocation.Y;

                        SetPlayerStance(world, order.Player, targetPlayer, newStance);

                        Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
                            order.Player.PlayerName, targetPlayer.PlayerName, newStance));

                        // automatically declare war reciprocally
                        if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
                        {
                            SetPlayerStance(world, targetPlayer, order.Player, newStance);
                            Game.Debug("{0} has reciprocated",targetPlayer.PlayerName);
                        }

                        break;
                    }
                default:
                    {
                        if( !order.IsImmediate )
                        {
                            var self = order.Subject;
                            var health = self.TraitOrDefault<Health>();
                            if( health == null || !health.IsDead )
                                foreach( var t in self.TraitsImplementing<IResolveOrder>() )
                                    t.ResolveOrder( self, order );
                        }
                        break;
                    }
            }
        }
        public static void ShowSlotDropDown(DropDownButtonWidget dropdown, Session.Slot slot,
			Session.Client client, OrderManager orderManager)
        {
            var options = new List<SlotDropDownOption>()
            {
                new SlotDropDownOption("Open", "slot_open "+slot.PlayerReference, () => (!slot.Closed && client == null)),
                new SlotDropDownOption("Closed", "slot_close "+slot.PlayerReference, () => slot.Closed)
            };

            if (slot.AllowBots)
                foreach (var b in Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name))
                {
                    var bot = b;
                    options.Add(new SlotDropDownOption("Bot: {0}".F(bot),
                        "slot_bot {0} {1}".F(slot.PlayerReference, bot),
                        () => client != null && client.Bot == bot));
                }

            Func<SlotDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                    o.Selected,
                    () => orderManager.IssueOrder(Order.Command(o.Order)));
                item.Get<LabelWidget>("LABEL").GetText = () => o.Title;
                return item;
            };

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem);
        }
Exemplo n.º 9
0
        public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            if (world != null)
            {
                if (!world.WorldActor.TraitsImplementing <IValidateOrder>().All(vo =>
                                                                                vo.OrderValidation(orderManager, world, clientId, order)))
                {
                    return;
                }
            }

            switch (order.OrderString)
            {
            case "Chat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var player = world != null?world.FindPlayerByClient(client) : null;

                    var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
                    suffix = client.IsObserver ? " (Spectator)" : suffix;
                    Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                }
                else
                {
                    Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
                }
                break;
            }

            case "Message":                     // Server message
                Game.AddChatLine(Color.White, "Server", order.TargetString);
                break;

            case "Disconnected":                     /* reports that the target player disconnected */
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    client.State = Session.ClientState.Disconnected;
                }
                break;
            }

            case "TeamChat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                if (client != null)
                {
                    if (world == null)
                    {
                        if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
                        {
                            Game.AddChatLine(client.Color.RGB, client.Name + " (Team)",
                                             order.TargetString);
                        }
                    }
                    else
                    {
                        var player = world.FindPlayerByClient(client);
                        if (player == null)
                        {
                            return;
                        }

                        if (world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally || player.WinState == WinState.Lost)
                        {
                            var suffix = player.WinState == WinState.Lost ? " (Dead)" : " (Team)";
                            Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                        }
                    }
                }
                break;
            }

            case "StartGame":
            {
                Game.AddChatLine(Color.White, "Server", "The game has started.");
                Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
                break;
            }

            case "PauseGame":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var pause = order.TargetString == "Pause";
                    if (orderManager.world.Paused != pause && !world.LobbyInfo.IsSinglePlayer)
                    {
                        var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
                        Game.AddChatLine(Color.White, "", pausetext);
                    }

                    orderManager.world.Paused          = pause;
                    orderManager.world.PredictedPaused = pause;
                }
                break;
            }

            case "HandshakeRequest":
            {
                var request   = HandshakeRequest.Deserialize(order.TargetString);
                var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m, Mod.AllMods[m].Version)).ToArray();

                // Check if mods match
                if (localMods.FirstOrDefault().ToString().Split('@')[0] != request.Mods.FirstOrDefault().ToString().Split('@')[0])
                {
                    throw new InvalidOperationException("Server's mod ({0}) and yours ({1}) don't match".F(localMods.FirstOrDefault().ToString().Split('@')[0], request.Mods.FirstOrDefault().ToString().Split('@')[0]));
                }
                // Check that the map exists on the client
                if (!Game.modData.AvailableMaps.ContainsKey(request.Map))
                {
                    if (Game.Settings.Game.AllowDownloading)
                    {
                        Game.DownloadMap(request.Map);
                    }
                    else
                    {
                        throw new InvalidOperationException("Missing map {0}".F(request.Map));
                    }
                }

                var info = new Session.Client()
                {
                    Name           = Game.Settings.Player.Name,
                    PreferredColor = Game.Settings.Player.Color,
                    Color          = Game.Settings.Player.Color,
                    Country        = "random",
                    SpawnPoint     = 0,
                    Team           = 0,
                    State          = Session.ClientState.NotReady
                };

                var response = new HandshakeResponse()
                {
                    Client   = info,
                    Mods     = localMods,
                    Password = "******"
                };

                orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
                break;
            }

            case "ServerError":
                orderManager.ServerError = order.TargetString;
                break;

            case "SyncInfo":
            {
                orderManager.LobbyInfo = Session.Deserialize(order.TargetString);

                if (orderManager.FramesAhead != orderManager.LobbyInfo.GlobalSettings.OrderLatency &&
                    !orderManager.GameStarted)
                {
                    orderManager.FramesAhead = orderManager.LobbyInfo.GlobalSettings.OrderLatency;
                    Game.Debug("Order lag is now {0} frames.".F(orderManager.LobbyInfo.GlobalSettings.OrderLatency));
                }
                Game.SyncLobbyInfo();
                break;
            }

            case "SetStance":
            {
                if (!Game.orderManager.LobbyInfo.GlobalSettings.FragileAlliances)
                {
                    return;
                }

                var targetPlayer = order.Player.World.Players.FirstOrDefault(p => p.InternalName == order.TargetString);
                var newStance    = (Stance)order.TargetLocation.X;

                SetPlayerStance(world, order.Player, targetPlayer, newStance);

                Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
                               order.Player.PlayerName, targetPlayer.PlayerName, newStance));

                // automatically declare war reciprocally
                if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
                {
                    SetPlayerStance(world, targetPlayer, order.Player, newStance);
                    Game.Debug("{0} has reciprocated", targetPlayer.PlayerName);
                }

                break;
            }

            case "Ping":
            {
                orderManager.IssueOrder(Order.Pong(order.TargetString));
                break;
            }

            default:
            {
                if (!order.IsImmediate)
                {
                    var self   = order.Subject;
                    var health = self.TraitOrDefault <Health>();
                    if (health == null || !health.IsDead)
                    {
                        foreach (var t in self.TraitsImplementing <IResolveOrder>())
                        {
                            t.ResolveOrder(self, order);
                        }
                    }
                }
                break;
            }
            }
        }
Exemplo n.º 10
0
 public static void SetupEditableReadyWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
 {
     var status = parent.Get<CheckboxWidget>("STATUS_CHECKBOX");
     status.IsChecked = () => orderManager.LocalClient.IsReady || c.Bot != null;
     status.IsVisible = () => true;
     status.IsDisabled = () => c.Bot != null;
     status.OnClick = () => orderManager.IssueOrder(Order.Command("ready"));
 }
Exemplo n.º 11
0
        public IngameChatLogic(Widget widget, OrderManager orderManager, World world, Ruleset modRules)
        {
            this.modRules = modRules;

            chatTraits = world.WorldActor.TraitsImplementing<INotifyChat>().ToList();

            var players = world.Players.Where(p => p != world.LocalPlayer && !p.NonCombatant && !p.IsBot);
            var disableTeamChat = world.LocalPlayer == null || world.LobbyInfo.IsSinglePlayer || !players.Any(p => p.IsAlliedWith(world.LocalPlayer));
            teamChat = !disableTeamChat;

            var chatPanel = (ContainerWidget)widget;
            chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
            chatOverlayDisplay = chatOverlay.Get<ChatDisplayWidget>("CHAT_DISPLAY");
            chatOverlay.Visible = false;

            chatChrome = chatPanel.Get<ContainerWidget>("CHAT_CHROME");
            chatChrome.Visible = true;

            var chatMode = chatChrome.Get<ButtonWidget>("CHAT_MODE");
            chatMode.GetText = () => teamChat ? "Team" : "All";
            chatMode.OnClick = () => teamChat ^= true;
            chatMode.IsDisabled = () => disableTeamChat;

            chatText = chatChrome.Get<TextFieldWidget>("CHAT_TEXTFIELD");
            chatText.OnTabKey = () =>
            {
                if (!disableTeamChat)
                    teamChat ^= true;
                return true;
            };
            chatText.OnEnterKey = () =>
            {
                var team = teamChat && !disableTeamChat;
                if (chatText.Text != "")
                    orderManager.IssueOrder(Order.Chat(team, chatText.Text.Trim()));

                CloseChat();
                return true;
            };

            chatText.OnEscKey = () => { CloseChat(); return true; };

            var chatClose = chatChrome.Get<ButtonWidget>("CHAT_CLOSE");
            chatClose.OnClick += () => CloseChat();

            chatPanel.OnKeyPress = (e) =>
            {
                if (e.Event == KeyInputEvent.Up)
                    return false;

                if (!chatChrome.IsVisible() && (e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER))
                {
                    OpenChat();
                    return true;
                }

                return false;
            };

            chatScrollPanel = chatChrome.Get<ScrollPanelWidget>("CHAT_SCROLLPANEL");
            chatTemplate = chatScrollPanel.Get<ContainerWidget>("CHAT_TEMPLATE");
            chatScrollPanel.RemoveChildren();

            Game.AddChatLine += AddChatLine;
            Game.BeforeGameStart += UnregisterEvents;

            CloseChat();
        }
Exemplo n.º 12
0
        public static void SetupEditableNameWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
        {
            var name = parent.Get<TextFieldWidget>("NAME");
            name.IsVisible = () => true;
            name.IsDisabled = () => orderManager.LocalClient.IsReady;

            name.Text = c.Name;
            name.OnEnterKey = () =>
            {
                name.Text = name.Text.Trim();
                if (name.Text.Length == 0)
                    name.Text = c.Name;

                name.LoseFocus();
                if (name.Text == c.Name)
                    return true;

                orderManager.IssueOrder(Order.Command("name " + name.Text));
                Game.Settings.Player.Name = name.Text;
                Game.Settings.Save();
                return true;
            };

            name.OnLoseFocus = () => name.OnEnterKey();
        }
Exemplo n.º 13
0
        public static void SetupKickSpectatorsWidget(Widget parent, OrderManager orderManager, Widget lobby, Action before, Action after, bool skirmishMode)
        {
            var checkBox = parent.Get<CheckboxWidget>("TOGGLE_SPECTATORS");
            checkBox.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowSpectators;
            checkBox.IsVisible = () => orderManager.LocalClient.IsAdmin && !skirmishMode;
            checkBox.IsDisabled = () => false;

            Action okPressed = () =>
            {
                orderManager.IssueOrder(Order.Command("allow_spectators {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowSpectators)));
                orderManager.IssueOrders(
                    orderManager.LobbyInfo.Clients.Where(
                        c => c.IsObserver && !c.IsAdmin).Select(
                            client => Order.Command("kick {0} {1}".F(client.Index, client.Name))).ToArray());

                after();
            };

            checkBox.OnClick = () =>
            {
                before();

                var spectatorCount = orderManager.LobbyInfo.Clients.Count(c => c.IsObserver);
                if (spectatorCount > 0)
                {
                    Game.LoadWidget(null, "KICK_SPECTATORS_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
                    {
                        { "clientCount", "{0}".F(spectatorCount) },
                        { "okPressed", okPressed },
                        { "cancelPressed", after }
                    });
                }
                else
                {
                    orderManager.IssueOrder(Order.Command("allow_spectators {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowSpectators)));
                    after();
                }
            };
        }
Exemplo n.º 14
0
        public static void SetupEditableNameWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
        {
            var name = parent.Get<TextFieldWidget>("NAME");
            name.IsVisible = () => true;
            name.IsDisabled = () => orderManager.LocalClient.IsReady;

            name.Text = c.Name;
            var escPressed = false;
            name.OnLoseFocus = () =>
            {
                if (escPressed)
                {
                    escPressed = false;
                    return;
                }

                name.Text = name.Text.Trim();
                if (name.Text.Length == 0)
                    name.Text = c.Name;
                else if (name.Text != c.Name)
                {
                    name.Text = Settings.SanitizedPlayerName(name.Text);
                    orderManager.IssueOrder(Order.Command("name " + name.Text));
                    Game.Settings.Player.Name = name.Text;
                    Game.Settings.Save();
                }
            };

            name.OnEnterKey = () => { name.YieldKeyboardFocus(); return true; };
            name.OnEscKey = () =>
            {
                name.Text = c.Name;
                escPressed = true;
                name.YieldKeyboardFocus();
                return true;
            };
        }
Exemplo n.º 15
0
        public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            if (world != null)
            {
                if (!world.WorldActor.TraitsImplementing <IValidateOrder>().All(vo =>
                                                                                vo.OrderValidation(orderManager, world, clientId, order)))
                {
                    return;
                }
            }

            switch (order.OrderString)
            {
            case "Chat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var player = world != null?world.FindPlayerByClient(client) : null;

                    var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
                    suffix = client.IsObserver ? " (Spectator)" : suffix;
                    Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                }
                else
                {
                    Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
                }
                break;
            }

            case "Message":                     // Server message
                Game.AddChatLine(Color.White, "Server", order.TargetString);
                break;

            case "Disconnected":                     /* reports that the target player disconnected */
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    client.State = Session.ClientState.Disconnected;
                }
                break;
            }

            case "TeamChat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                if (client != null)
                {
                    if (world == null)
                    {
                        if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
                        {
                            Game.AddChatLine(client.Color.RGB, client.Name + " (Team)",
                                             order.TargetString);
                        }
                    }
                    else
                    {
                        var player = world.FindPlayerByClient(client);
                        if (player == null)
                        {
                            return;
                        }

                        if (world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally || player.WinState == WinState.Lost)
                        {
                            var suffix = player.WinState == WinState.Lost ? " (Dead)" : " (Team)";
                            Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                        }
                    }
                }
                break;
            }

            case "StartGame":
            {
                Game.AddChatLine(Color.White, "Server", "The game has started.");
                Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
                break;
            }

            case "PauseGame":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var pause = order.TargetString == "Pause";
                    if (orderManager.world.Paused != pause && !world.LobbyInfo.IsSinglePlayer)
                    {
                        var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
                        Game.AddChatLine(Color.White, "", pausetext);
                    }

                    orderManager.world.Paused          = pause;
                    orderManager.world.PredictedPaused = pause;
                }
                break;
            }

            case "HandshakeRequest":
            {
                // TODO: Switch to the server's mod if we have it
                // Otherwise send the handshake with our current settings and let the server reject us
                var mod = Game.modData.Manifest.Mod;

                var info = new Session.Client()
                {
                    Name           = Game.Settings.Player.Name,
                    PreferredColor = Game.Settings.Player.Color,
                    Color          = Game.Settings.Player.Color,
                    Country        = "random",
                    SpawnPoint     = 0,
                    Team           = 0,
                    State          = Session.ClientState.Invalid
                };

                var response = new HandshakeResponse()
                {
                    Client   = info,
                    Mod      = mod.Id,
                    Version  = mod.Version,
                    Password = orderManager.Password
                };

                orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
                break;
            }

            case "ServerError":
            {
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = false;
                break;
            }

            case "AuthenticationError":
            {
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = true;
                break;
            }

            case "SyncInfo":
            {
                orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
                SetOrderLag(orderManager);
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyClients":
            {
                var clients = new List <Session.Client>();
                var nodes   = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Client")
                    {
                        clients.Add(Session.Client.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.Clients = clients;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbySlots":
            {
                var slots = new Dictionary <string, Session.Slot>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Slot")
                    {
                        var slot = Session.Slot.Deserialize(node.Value);
                        slots.Add(slot.PlayerReference, slot);
                    }
                }

                orderManager.LobbyInfo.Slots = slots;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyGlobalSettings":
            {
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "GlobalSettings")
                    {
                        orderManager.LobbyInfo.GlobalSettings = Session.Global.Deserialize(node.Value);
                    }
                }

                SetOrderLag(orderManager);
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncClientPings":
            {
                var pings = new List <Session.ClientPing>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "ClientPing")
                    {
                        pings.Add(Session.ClientPing.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.ClientPings = pings;
                break;
            }

            case "SetStance":
            {
                if (!Game.orderManager.LobbyInfo.GlobalSettings.FragileAlliances)
                {
                    return;
                }

                var targetPlayer = order.Player.World.Players.FirstOrDefault(p => p.InternalName == order.TargetString);
                var newStance    = (Stance)order.ExtraData;

                SetPlayerStance(world, order.Player, targetPlayer, newStance);

                Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
                               order.Player.PlayerName, targetPlayer.PlayerName, newStance));

                // automatically declare war reciprocally
                if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
                {
                    SetPlayerStance(world, targetPlayer, order.Player, newStance);
                    Game.Debug("{0} has reciprocated", targetPlayer.PlayerName);
                }

                break;
            }

            case "Ping":
            {
                orderManager.IssueOrder(Order.Pong(order.TargetString));
                break;
            }

            default:
            {
                if (!order.IsImmediate)
                {
                    var self   = order.Subject;
                    var health = self.TraitOrDefault <Health>();
                    if (health == null || !health.IsDead)
                    {
                        foreach (var t in self.TraitsImplementing <IResolveOrder>())
                        {
                            t.ResolveOrder(self, order);
                        }
                    }
                }
                break;
            }
            }
        }
Exemplo n.º 16
0
		public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
		{
			if (world != null)
			{
				if (!world.WorldActor.TraitsImplementing<IValidateOrder>().All(vo =>
					vo.OrderValidation(orderManager, world, clientId, order)))
					return;
			}

			switch (order.OrderString)
			{
				case "Chat":
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
						if (client != null)
						{
							var player = world != null ? world.FindPlayerByClient(client) : null;
							var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
							suffix = client.IsObserver ? " (Spectator)" : suffix;
							Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
						}
						else
							Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
						break;
					}

				case "Message": // Server message
						Game.AddChatLine(Color.White, "Server", order.TargetString);
					break;

				case "Disconnected": /* reports that the target player disconnected */
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
						if (client != null)
							client.State = Session.ClientState.Disconnected;
						break;
					}

				case "TeamChat":
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

						if (client != null)
						{
							if (world == null)
							{
								if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
									Game.AddChatLine(client.Color.RGB, client.Name + " (Team)",
										order.TargetString);
							}
							else
							{
								var player = world.FindPlayerByClient(client);
								if (player == null) return;

								if (world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally || player.WinState == WinState.Lost)
								{
									var suffix = player.WinState == WinState.Lost ? " (Dead)" : " (Team)";
									Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
								}
							}
						}
						break;
					}

				case "StartGame":
					{
						Game.AddChatLine(Color.White, "Server", "The game has started.");
						Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
						break;
					}

				case "PauseGame":
					{
						var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
						if (client != null)
						{
							var pause = order.TargetString == "Pause";
							if (orderManager.world.Paused != pause && !world.LobbyInfo.IsSinglePlayer)
							{
								var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
								Game.AddChatLine(Color.White, "", pausetext);
							}

							orderManager.world.Paused = pause;
							orderManager.world.PredictedPaused = pause;
						}
						break;
					}

				case "HandshakeRequest":
					{
						// TODO: Switch to the server's mod if we have it
						// Otherwise send the handshake with our current settings and let the server reject us
						var mod = Game.modData.Manifest.Mod;

						var info = new Session.Client()
						{
							Name = Game.Settings.Player.Name,
							PreferredColor = Game.Settings.Player.Color,
							Color = Game.Settings.Player.Color,
							Country = "random",
							SpawnPoint = 0,
							Team = 0,
							State = Session.ClientState.Invalid
						};

						var response = new HandshakeResponse()
						{
							Client = info,
							Mod = mod.Id,
							Version = mod.Version,
							Password = orderManager.Password
						};

						orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
						break;
					}

				case "ServerError":
					{
						orderManager.ServerError = order.TargetString;
						orderManager.AuthenticationFailed = false;
						break;
					}

				case "AuthenticationError":
					{
						orderManager.ServerError = order.TargetString;
						orderManager.AuthenticationFailed = true;
						break;
					}

				case "SyncInfo":
					{
						orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
						SetOrderLag(orderManager);
						Game.SyncLobbyInfo();
						break;
					}

				case "SyncLobbyClients":
					{
						var clients = new List<Session.Client>();
						var nodes = MiniYaml.FromString(order.TargetString);
						foreach (var node in nodes)
						{
							var strings = node.Key.Split('@');
							if (strings[0] == "Client")
								clients.Add(Session.Client.Deserialize(node.Value));
						}

						orderManager.LobbyInfo.Clients = clients;
						Game.SyncLobbyInfo();
						break;
					}

				case "SyncLobbySlots":
					{
						var slots = new Dictionary<string, Session.Slot>();
						var nodes = MiniYaml.FromString(order.TargetString);
						foreach (var node in nodes)
						{
							var strings = node.Key.Split('@');
							if (strings[0] == "Slot")
							{
								var slot = Session.Slot.Deserialize(node.Value);
								slots.Add(slot.PlayerReference, slot);
							}
						}

						orderManager.LobbyInfo.Slots = slots;
						Game.SyncLobbyInfo();
						break;
					}

				case "SyncLobbyGlobalSettings":
					{
						var nodes = MiniYaml.FromString(order.TargetString);
						foreach (var node in nodes)
						{
							var strings = node.Key.Split('@');
							if (strings[0] == "GlobalSettings")
								orderManager.LobbyInfo.GlobalSettings = Session.Global.Deserialize(node.Value);
						}

						SetOrderLag(orderManager);
						Game.SyncLobbyInfo();
						break;
					}

				case "SyncClientPings":
					{
						var pings = new List<Session.ClientPing>();
						var nodes = MiniYaml.FromString(order.TargetString);
						foreach (var node in nodes)
						{
							var strings = node.Key.Split('@');
							if (strings[0] == "ClientPing")
								pings.Add(Session.ClientPing.Deserialize(node.Value));
						}

						orderManager.LobbyInfo.ClientPings = pings;
						break;
					}

				case "SetStance":
					{
						if (!Game.orderManager.LobbyInfo.GlobalSettings.FragileAlliances)
							return;

						var targetPlayer = order.Player.World.Players.FirstOrDefault(p => p.InternalName == order.TargetString);
						var newStance = (Stance)order.ExtraData;

						SetPlayerStance(world, order.Player, targetPlayer, newStance);

						Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
							order.Player.PlayerName, targetPlayer.PlayerName, newStance));

						// automatically declare war reciprocally
						if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
						{
							SetPlayerStance(world, targetPlayer, order.Player, newStance);
							Game.Debug("{0} has reciprocated",targetPlayer.PlayerName);
						}

						break;
					}

				case "Ping":
					{
						orderManager.IssueOrder(Order.Pong(order.TargetString));
						break;
					}

				default:
					{
						if (!order.IsImmediate)
						{
							var self = order.Subject;
							var health = self.TraitOrDefault<Health>();
							if (health == null || !health.IsDead)
								foreach (var t in self.TraitsImplementing<IResolveOrder>())
									t.ResolveOrder(self, order);
						}
						break;
					}
			}
		}
Exemplo n.º 17
0
        public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            if (world != null)
            {
                if (!world.WorldActor.TraitsImplementing <IValidateOrder>().All(vo =>
                                                                                vo.OrderValidation(orderManager, world, clientId, order)))
                {
                    return;
                }
            }

            switch (order.OrderString)
            {
            case "Chat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var player = world != null?world.FindPlayerByClient(client) : null;

                    var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
                    suffix = client.IsObserver ? " (Spectator)" : suffix;

                    if (orderManager.LocalClient != null && client != orderManager.LocalClient && client.Team > 0 && client.Team == orderManager.LocalClient.Team)
                    {
                        suffix += " (Ally)";
                    }

                    Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                }
                else
                {
                    Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
                }
                break;
            }

            case "Message":                     // Server message
                Game.AddChatLine(Color.White, "Server", order.TargetString);
                break;

            case "Disconnected":                     /* reports that the target player disconnected */
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    client.State = Session.ClientState.Disconnected;
                }
                break;
            }

            case "TeamChat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                if (client != null)
                {
                    if (world == null)
                    {
                        if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
                        {
                            Game.AddChatLine(client.Color.RGB, "[Team] " + client.Name, order.TargetString);
                        }
                    }
                    else
                    {
                        var player = world.FindPlayerByClient(client);
                        if (player != null && player.WinState == WinState.Lost)
                        {
                            Game.AddChatLine(client.Color.RGB, client.Name + " (Dead)", order.TargetString);
                        }
                        else if (player != null && world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally)
                        {
                            Game.AddChatLine(client.Color.RGB, "[Team] " + client.Name, order.TargetString);
                        }
                        else if (orderManager.LocalClient != null && orderManager.LocalClient.IsObserver && client.IsObserver)
                        {
                            Game.AddChatLine(client.Color.RGB, "[Spectators] " + client.Name, order.TargetString);
                        }
                    }
                }

                break;
            }

            case "StartGame":
            {
                if (Game.ModData.MapCache[orderManager.LobbyInfo.GlobalSettings.Map].Status != MapStatus.Available)
                {
                    Game.Disconnect();
                    Game.LoadShellMap();

                    // TODO: After adding a startup error dialog, notify the replay load failure.
                    break;
                }

                Game.AddChatLine(Color.White, "Server", "The game has started.");
                Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, WorldType.Regular);
                break;
            }

            case "PauseGame":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var pause = order.TargetString == "Pause";
                    if (orderManager.World.Paused != pause && world != null && !world.LobbyInfo.IsSinglePlayer)
                    {
                        var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
                        Game.AddChatLine(Color.White, "", pausetext);
                    }

                    orderManager.World.Paused          = pause;
                    orderManager.World.PredictedPaused = pause;
                }

                break;
            }

            case "HandshakeRequest":
            {
                // Switch to the server's mod if we need and are able to
                var mod     = Game.ModData.Manifest;
                var request = HandshakeRequest.Deserialize(order.TargetString);

                Manifest serverMod;
                if (request.Mod != mod.Id &&
                    Game.Mods.TryGetValue(request.Mod, out serverMod) &&
                    serverMod.Metadata.Version == request.Version)
                {
                    var replay        = orderManager.Connection as ReplayConnection;
                    var launchCommand = replay != null ?
                                        "Launch.Replay=" + replay.Filename :
                                        "Launch.Connect=" + orderManager.Host + ":" + orderManager.Port;

                    Game.ModData.LoadScreen.Display();
                    Game.InitializeMod(request.Mod, new Arguments(launchCommand));

                    break;
                }

                Game.Settings.Player.Name = Settings.SanitizedPlayerName(Game.Settings.Player.Name);
                Game.Settings.Save();

                // Otherwise send the handshake with our current settings and let the server reject us
                var info = new Session.Client()
                {
                    Name           = Game.Settings.Player.Name,
                    PreferredColor = Game.Settings.Player.Color,
                    Color          = Game.Settings.Player.Color,
                    Faction        = "Random",
                    SpawnPoint     = 0,
                    Team           = 0,
                    State          = Session.ClientState.Invalid
                };

                var response = new HandshakeResponse()
                {
                    Client   = info,
                    Mod      = mod.Id,
                    Version  = mod.Metadata.Version,
                    Password = orderManager.Password
                };

                orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
                break;
            }

            case "ServerError":
            {
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = false;
                break;
            }

            case "AuthenticationError":
            {
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = true;
                break;
            }

            case "SyncInfo":
            {
                orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
                SetOrderLag(orderManager);
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyClients":
            {
                var clients = new List <Session.Client>();
                var nodes   = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Client")
                    {
                        clients.Add(Session.Client.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.Clients = clients;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbySlots":
            {
                var slots = new Dictionary <string, Session.Slot>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Slot")
                    {
                        var slot = Session.Slot.Deserialize(node.Value);
                        slots.Add(slot.PlayerReference, slot);
                    }
                }

                orderManager.LobbyInfo.Slots = slots;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyGlobalSettings":
            {
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "GlobalSettings")
                    {
                        orderManager.LobbyInfo.GlobalSettings = Session.Global.Deserialize(node.Value);
                    }
                }

                SetOrderLag(orderManager);
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncClientPings":
            {
                var pings = new List <Session.ClientPing>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "ClientPing")
                    {
                        pings.Add(Session.ClientPing.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.ClientPings = pings;
                break;
            }

            case "Ping":
            {
                orderManager.IssueOrder(Order.Pong(order.TargetString));
                break;
            }

            default:
            {
                if (!order.IsImmediate)
                {
                    var self = order.Subject;
                    if (!self.IsDead)
                    {
                        foreach (var t in self.TraitsImplementing <IResolveOrder>())
                        {
                            t.ResolveOrder(self, order);
                        }
                    }
                }

                break;
            }
            }
        }
Exemplo n.º 18
0
		internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager,
			Action onExit, Action onStart, bool skirmishMode, Ruleset modRules)
		{
			lobby = widget;
			this.orderManager = orderManager;
			this.onStart = onStart;
			this.onExit = onExit;
			this.skirmishMode = skirmishMode;
			this.modRules = modRules;
			shellmapWorld = worldRenderer.World;

			orderManager.AddChatLine += AddChatLine;
			Game.LobbyInfoChanged += UpdateCurrentMap;
			Game.LobbyInfoChanged += UpdatePlayerList;
			Game.BeforeGameStart += OnGameStart;
			Game.ConnectionStateChanged += ConnectionStateChanged;

			var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
			if (name != null)
				name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

			Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
			{
				{ "orderManager", orderManager },
				{ "lobby", this }
			});

			UpdateCurrentMap();

			var playerBin = Ui.LoadWidget("LOBBY_PLAYER_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
			playerBin.IsVisible = () => panel == PanelType.Players;

			players = playerBin.Get<ScrollPanelWidget>("LOBBY_PLAYERS");
			editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER");
			nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
			emptySlotTemplate = players.Get("TEMPLATE_EMPTY");
			editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
			nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
			newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR");
			colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
			colorPreview.Color = Game.Settings.Player.Color;

			foreach (var f in modRules.Actors["world"].TraitInfos<FactionInfo>())
				factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description });

			var gameStarting = false;
			Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
				panel == PanelType.Kick || panel == PanelType.ForceStart ||
				orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

			var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
			if (mapButton != null)
			{
				mapButton.IsDisabled = () => gameStarting || panel == PanelType.Kick || panel == PanelType.ForceStart ||
					orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
				mapButton.OnClick = () =>
				{
					var onSelect = new Action<string>(uid =>
					{
						// Don't select the same map again
						if (uid == Map.Uid)
							return;

						orderManager.IssueOrder(Order.Command("map " + uid));
						Game.Settings.Server.Map = uid;
						Game.Settings.Save();
					});

					Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
					{
						{ "initialMap", Map.Uid },
						{ "initialTab", MapClassification.System },
						{ "onExit", DoNothing },
						{ "onSelect", Game.IsHost ? onSelect : null },
						{ "filter", MapVisibility.Lobby },
					});
				};
			}

			var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
			if (slotsButton != null)
			{
				slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
					Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

				var botNames = modRules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name);
				slotsButton.OnMouseDown = _ =>
				{
					var options = new Dictionary<string, IEnumerable<DropDownOption>>();

					var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
					if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
					{
						var botOptions = new List<DropDownOption>()
						{
							new DropDownOption()
							{
								Title = "Add",
								IsSelected = () => false,
								OnClick = () =>
								{
									foreach (var slot in orderManager.LobbyInfo.Slots)
									{
										var bot = botNames.Random(Game.CosmeticRandom);
										var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
										if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
											orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
									}
								}
							}
						};

						if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
						{
							botOptions.Add(new DropDownOption()
							{
								Title = "Remove",
								IsSelected = () => false,
								OnClick = () =>
								{
									foreach (var slot in orderManager.LobbyInfo.Slots)
									{
										var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
										if (c != null && c.Bot != null)
											orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
									}
								}
							});
						}

						options.Add("Configure Bots", botOptions);
					}

					var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
					if (teamCount >= 1)
					{
						var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
						{
							Title = "{0} Teams".F(d),
							IsSelected = () => false,
							OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
						}).ToList();

						if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
						{
							teamOptions.Add(new DropDownOption
							{
								Title = "Humans vs Bots",
								IsSelected = () => false,
								OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
							});
						}

						teamOptions.Add(new DropDownOption
						{
							Title = "Free for all",
							IsSelected = () => false,
							OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
						});

						options.Add("Configure Teams", teamOptions);
					}

					Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
					{
						var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
						item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
						return item;
					};
					slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
				};
			}

			var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
			optionsBin.IsVisible = () => panel == PanelType.Options;

			var musicBin = Ui.LoadWidget("LOBBY_MUSIC_BIN", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
			{
				{ "onExit", DoNothing },
				{ "world", worldRenderer.World }
			});
			musicBin.IsVisible = () => panel == PanelType.Music;

			var optionsTab = lobby.Get<ButtonWidget>("OPTIONS_TAB");
			optionsTab.IsHighlighted = () => panel == PanelType.Options;
			optionsTab.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart;
			optionsTab.OnClick = () => panel = PanelType.Options;

			var playersTab = lobby.Get<ButtonWidget>("PLAYERS_TAB");
			playersTab.IsHighlighted = () => panel == PanelType.Players;
			playersTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
			playersTab.OnClick = () => panel = PanelType.Players;

			var musicTab = lobby.Get<ButtonWidget>("MUSIC_TAB");
			musicTab.IsHighlighted = () => panel == PanelType.Music;
			musicTab.IsDisabled = () => panel == PanelType.Kick || panel == PanelType.ForceStart;
			musicTab.OnClick = () => panel = PanelType.Music;

			// Force start panel
			Action startGame = () =>
			{
				gameStarting = true;
				orderManager.IssueOrder(Order.Command("startgame"));
			};

			var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
			if (startGameButton != null)
			{
				startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached ||
					orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
				startGameButton.OnClick = () =>
				{
					// Bots and admins don't count
					if (orderManager.LobbyInfo.Clients.Any(c => c.Slot != null && !c.IsAdmin && c.Bot == null && !c.IsReady))
						panel = PanelType.ForceStart;
					else
						startGame();
				};
			}

			var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs());
			forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
			forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
			forceStartBin.Get<ButtonWidget>("OK_BUTTON").OnClick = startGame;
			forceStartBin.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

			// Options panel
			var allowCheats = optionsBin.GetOrNull<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
			if (allowCheats != null)
			{
				allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
				allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled();
				allowCheats.OnClick = () => orderManager.IssueOrder(Order.Command(
						"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
			}

			var crates = optionsBin.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
			if (crates != null)
			{
				crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
				crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled();
				crates.OnClick = () => orderManager.IssueOrder(Order.Command(
					"crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
			}

			var creeps = optionsBin.GetOrNull<CheckboxWidget>("CREEPS_CHECKBOX");
			if (creeps != null)
			{
				creeps.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Creeps;
				creeps.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Creeps.HasValue || configurationDisabled();
				creeps.OnClick = () => orderManager.IssueOrder(Order.Command(
					"creeps {0}".F(!orderManager.LobbyInfo.GlobalSettings.Creeps)));
			}

			var allybuildradius = optionsBin.GetOrNull<CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");
			if (allybuildradius != null)
			{
				allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
				allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
				allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
					"allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
			}

			var fragileAlliance = optionsBin.GetOrNull<CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");
			if (fragileAlliance != null)
			{
				fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
				fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled();
				fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command(
					"fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
			}

			var shortGame = optionsBin.GetOrNull<CheckboxWidget>("SHORTGAME_CHECKBOX");
			if (shortGame != null)
			{
				shortGame.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.ShortGame;
				shortGame.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.ShortGame.HasValue || configurationDisabled();
				shortGame.OnClick = () => orderManager.IssueOrder(Order.Command(
					"shortgame {0}".F(!orderManager.LobbyInfo.GlobalSettings.ShortGame)));
			}

			var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
			if (difficulty != null)
			{
				difficulty.IsVisible = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any();
				difficulty.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled();
				difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
				difficulty.OnMouseDown = _ =>
				{
					var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption
					{
						Title = d,
						IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
						OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
					});
					Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
					{
						var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
						item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
						return item;
					};
					difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
				};

				optionsBin.Get<LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
			}

			var startingUnits = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");
			if (startingUnits != null)
			{
				var startUnitsInfo = modRules.Actors["world"].TraitInfos<MPStartUnitsInfo>();
				var classes = startUnitsInfo.Select(a => a.Class).Distinct();
				Func<string, string> className = c =>
				{
					var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
					return selectedClass != null ? selectedClass : c;
				};

				startingUnits.IsDisabled = () => Map.Status != MapStatus.Available ||
					!Map.Map.Options.ConfigurableStartingUnits || configurationDisabled();
				startingUnits.GetText = () => Map.Status != MapStatus.Available ||
					!Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
				startingUnits.OnMouseDown = _ =>
				{
					var options = classes.Select(c => new DropDownOption
					{
						Title = className(c),
						IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
						OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
					});

					Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
					{
						var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
						item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
						return item;
					};

					startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
				};

				optionsBin.Get<LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
			}

			var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");
			if (startingCash != null)
			{
				startingCash.IsDisabled = () => Map.Status != MapStatus.Available ||
					Map.Map.Options.StartingCash.HasValue || configurationDisabled();
				startingCash.GetText = () => Map.Status != MapStatus.Available ||
					Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
				startingCash.OnMouseDown = _ =>
				{
					var options = modRules.Actors["player"].TraitInfo<PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
					{
						Title = "${0}".F(c),
						IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
						OnClick = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
					});

					Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
					{
						var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
						item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
						return item;
					};

					startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
				};
			}

			var techLevel = optionsBin.GetOrNull<DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");
			if (techLevel != null)
			{
				var techTraits = modRules.Actors["player"].TraitInfos<ProvidesTechPrerequisiteInfo>().ToList();
				techLevel.IsVisible = () => techTraits.Count > 0;

				var techLevelDescription = optionsBin.GetOrNull<LabelWidget>("TECHLEVEL_DESC");
				if (techLevelDescription != null)
					techLevelDescription.IsVisible = () => techTraits.Count > 0;

				techLevel.IsDisabled = () => Map.Status != MapStatus.Available ||
					Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Count <= 1;
				techLevel.GetText = () => Map.Status != MapStatus.Available ||
					Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
				techLevel.OnMouseDown = _ =>
				{
					var options = techTraits.Select(c => new DropDownOption
					{
						Title = "{0}".F(c.Name),
						IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
						OnClick = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name)))
					});

					Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
					{
						var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
						item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
						return item;
					};

					techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
				};
			}

			var gameSpeed = optionsBin.GetOrNull<DropDownButtonWidget>("GAMESPEED_DROPDOWNBUTTON");
			if (gameSpeed != null)
			{
				var speeds = Game.ModData.Manifest.Get<GameSpeeds>().Speeds;

				gameSpeed.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled();
				gameSpeed.GetText = () =>
				{
					if (Map.Status != MapStatus.Available)
						return "Not Available";

					GameSpeed speed;
					if (!speeds.TryGetValue(orderManager.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
						return "Unknown";

					return speed.Name;
				};

				gameSpeed.OnMouseDown = _ =>
				{
					var options = speeds.Select(s => new DropDownOption
					{
						Title = s.Value.Name,
						IsSelected = () => orderManager.LobbyInfo.GlobalSettings.GameSpeedType == s.Key,
						OnClick = () => orderManager.IssueOrder(Order.Command("gamespeed {0}".F(s.Key)))
					});

					Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
					{
						var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
						item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
						return item;
					};

					gameSpeed.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
				};
			}

			var exploredMap = optionsBin.GetOrNull<CheckboxWidget>("EXPLORED_MAP_CHECKBOX");
			if (exploredMap != null)
			{
				exploredMap.IsChecked = () => !orderManager.LobbyInfo.GlobalSettings.Shroud;
				exploredMap.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled();
				exploredMap.OnClick = () => orderManager.IssueOrder(Order.Command(
					"shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
			}

			var enableFog = optionsBin.GetOrNull<CheckboxWidget>("FOG_CHECKBOX");
			if (enableFog != null)
			{
				enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog;
				enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled();
				enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
					"fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
			}

			var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
			disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

			if (skirmishMode)
				disconnectButton.Text = "Back";

			var globalChat = Game.LoadWidget(null, "LOBBY_GLOBALCHAT_PANEL", lobby.Get("GLOBALCHAT_ROOT"), new WidgetArgs());
			var globalChatInput = globalChat.Get<TextFieldWidget>("CHAT_TEXTFIELD");

			globalChat.IsVisible = () => chatPanel == ChatPanelType.Global;

			var globalChatTab = lobby.Get<ButtonWidget>("GLOBALCHAT_TAB");
			globalChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Global;
			globalChatTab.OnClick = () =>
			{
				chatPanel = ChatPanelType.Global;
				globalChatInput.TakeKeyboardFocus();
			};

			var globalChatLabel = globalChatTab.Text;
			globalChatTab.GetText = () =>
			{
				if (globalChatUnreadMessages == 0 || chatPanel == ChatPanelType.Global)
					return globalChatLabel;

				return globalChatLabel + " ({0})".F(globalChatUnreadMessages);
			};

			globalChatLastReadMessages = Game.GlobalChat.History.Count;

			var lobbyChat = lobby.Get("LOBBYCHAT");
			lobbyChat.IsVisible = () => chatPanel == ChatPanelType.Lobby;

			chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
			var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");
			chatTextField.TakeKeyboardFocus();
			chatTextField.OnEnterKey = () =>
			{
				if (chatTextField.Text.Length == 0)
					return true;

				// Always scroll to bottom when we've typed something
				lobbyChatPanel.ScrollToBottom();

				orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
				chatTextField.Text = "";
				return true;
			};

			chatTextField.OnTabKey = () =>
			{
				var previousText = chatTextField.Text;
				chatTextField.Text = tabCompletion.Complete(chatTextField.Text);
				chatTextField.CursorPosition = chatTextField.Text.Length;

				if (chatTextField.Text == previousText)
					return SwitchTeamChat();
				else
					return true;
			};

			chatTextField.OnEscKey = () => { chatTextField.Text = ""; return true; };

			var lobbyChatTab = lobby.Get<ButtonWidget>("LOBBYCHAT_TAB");
			lobbyChatTab.IsHighlighted = () => chatPanel == ChatPanelType.Lobby;
			lobbyChatTab.OnClick = () =>
			{
				chatPanel = ChatPanelType.Lobby;
				chatTextField.TakeKeyboardFocus();
			};

			var lobbyChatLabel = lobbyChatTab.Text;
			lobbyChatTab.GetText = () =>
			{
				if (lobbyChatUnreadMessages == 0 || chatPanel == ChatPanelType.Lobby)
					return lobbyChatLabel;

				return lobbyChatLabel + " ({0})".F(lobbyChatUnreadMessages);
			};

			lobbyChatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
			chatTemplate = lobbyChatPanel.Get("CHAT_TEMPLATE");
			lobbyChatPanel.RemoveChildren();

			var settingsButton = lobby.GetOrNull<ButtonWidget>("SETTINGS_BUTTON");
			if (settingsButton != null)
			{
				settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
				{
					{ "onExit", DoNothing },
					{ "worldRenderer", worldRenderer }
				});
			}

			// Add a bot on the first lobbyinfo update
			if (skirmishMode)
			{
				Game.LobbyInfoChanged += WidgetUtils.Once(() =>
				{
					var slot = orderManager.LobbyInfo.FirstEmptyBotSlot();
					var bot = modRules.Actors["player"].TraitInfos<IBotInfo>().Select(t => t.Name).FirstOrDefault();
					var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
					if (slot != null && bot != null)
						orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
				});
			}
		}
Exemplo n.º 19
0
        public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            if (world != null)
            {
                if (!world.WorldActor.TraitsImplementing<IValidateOrder>().All(vo =>
                    vo.OrderValidation(orderManager, world, clientId, order)))
                    return;
            }

            switch (order.OrderString)
            {
                case "Chat":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                        {
                            var player = world != null ? world.FindPlayerByClient(client) : null;
                            var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
                            suffix = client.IsObserver ? " (Spectator)" : suffix;

                            if (orderManager.LocalClient != null && client != orderManager.LocalClient && client.Team > 0 && client.Team == orderManager.LocalClient.Team)
                                suffix += " (Ally)";

                            Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                        }
                        else
                            Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
                        break;
                    }

                case "Message": // Server message
                    Game.AddChatLine(Color.White, "Server", order.TargetString);
                    break;

                case "Disconnected": /* reports that the target player disconnected */
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                            client.State = Session.ClientState.Disconnected;
                        break;
                    }

                case "TeamChat":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                        if (client != null)
                        {
                            if (world == null)
                            {
                                if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
                                    Game.AddChatLine(client.Color.RGB, "[Team] " + client.Name, order.TargetString);
                            }
                            else
                            {
                                var player = world.FindPlayerByClient(client);
                                if (player != null && player.WinState == WinState.Lost)
                                    Game.AddChatLine(client.Color.RGB, client.Name + " (Dead)", order.TargetString);
                                else if (player != null && world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally)
                                    Game.AddChatLine(client.Color.RGB, "[Team] " + client.Name, order.TargetString);
                                else if (orderManager.LocalClient != null && orderManager.LocalClient.IsObserver && client.IsObserver)
                                    Game.AddChatLine(client.Color.RGB, "[Spectators] " + client.Name, order.TargetString);
                            }
                        }

                        break;
                    }

                case "StartGame":
                    {
                        if (Game.ModData.MapCache[orderManager.LobbyInfo.GlobalSettings.Map].Status != MapStatus.Available)
                        {
                            Game.Disconnect();
                            Game.LoadShellMap();

                            // TODO: After adding a startup error dialog, notify the replay load failure.
                            break;
                        }

                        Game.AddChatLine(Color.White, "Server", "The game has started.");
                        Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, WorldType.Regular);
                        break;
                    }

                case "PauseGame":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                        {
                            var pause = order.TargetString == "Pause";
                            if (orderManager.World.Paused != pause && world != null && !world.LobbyInfo.IsSinglePlayer)
                            {
                                var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
                                Game.AddChatLine(Color.White, "", pausetext);
                            }

                            orderManager.World.Paused = pause;
                            orderManager.World.PredictedPaused = pause;
                        }

                        break;
                    }

                case "HandshakeRequest":
                    {
                        // Switch to the server's mod if we need and are able to
                        var mod = Game.ModData.Manifest;
                        var request = HandshakeRequest.Deserialize(order.TargetString);

                        Manifest serverMod;
                        if (request.Mod != mod.Id &&
                            Game.Mods.TryGetValue(request.Mod, out serverMod) &&
                            serverMod.Metadata.Version == request.Version)
                        {
                            var replay = orderManager.Connection as ReplayConnection;
                            var launchCommand = replay != null ?
                                "Launch.Replay=" + replay.Filename :
                                "Launch.Connect=" + orderManager.Host + ":" + orderManager.Port;

                            Game.ModData.LoadScreen.Display();
                            Game.InitializeMod(request.Mod, new Arguments(launchCommand));

                            break;
                        }

                        Game.Settings.Player.Name = Settings.SanitizedPlayerName(Game.Settings.Player.Name);
                        Game.Settings.Save();

                        // Otherwise send the handshake with our current settings and let the server reject us
                        var info = new Session.Client()
                        {
                            Name = Game.Settings.Player.Name,
                            PreferredColor = Game.Settings.Player.Color,
                            Color = Game.Settings.Player.Color,
                            Faction = "Random",
                            SpawnPoint = 0,
                            Team = 0,
                            State = Session.ClientState.Invalid
                        };

                        var response = new HandshakeResponse()
                        {
                            Client = info,
                            Mod = mod.Id,
                            Version = mod.Metadata.Version,
                            Password = orderManager.Password
                        };

                        orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
                        break;
                    }

                case "ServerError":
                    {
                        orderManager.ServerError = order.TargetString;
                        orderManager.AuthenticationFailed = false;
                        break;
                    }

                case "AuthenticationError":
                    {
                        orderManager.ServerError = order.TargetString;
                        orderManager.AuthenticationFailed = true;
                        break;
                    }

                case "SyncInfo":
                    {
                        orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
                        SetOrderLag(orderManager);
                        Game.SyncLobbyInfo();
                        break;
                    }

                case "SyncLobbyClients":
                    {
                        var clients = new List<Session.Client>();
                        var nodes = MiniYaml.FromString(order.TargetString);
                        foreach (var node in nodes)
                        {
                            var strings = node.Key.Split('@');
                            if (strings[0] == "Client")
                                clients.Add(Session.Client.Deserialize(node.Value));
                        }

                        orderManager.LobbyInfo.Clients = clients;
                        Game.SyncLobbyInfo();
                        break;
                    }

                case "SyncLobbySlots":
                    {
                        var slots = new Dictionary<string, Session.Slot>();
                        var nodes = MiniYaml.FromString(order.TargetString);
                        foreach (var node in nodes)
                        {
                            var strings = node.Key.Split('@');
                            if (strings[0] == "Slot")
                            {
                                var slot = Session.Slot.Deserialize(node.Value);
                                slots.Add(slot.PlayerReference, slot);
                            }
                        }

                        orderManager.LobbyInfo.Slots = slots;
                        Game.SyncLobbyInfo();
                        break;
                    }

                case "SyncLobbyGlobalSettings":
                    {
                        var nodes = MiniYaml.FromString(order.TargetString);
                        foreach (var node in nodes)
                        {
                            var strings = node.Key.Split('@');
                            if (strings[0] == "GlobalSettings")
                                orderManager.LobbyInfo.GlobalSettings = Session.Global.Deserialize(node.Value);
                        }

                        SetOrderLag(orderManager);
                        Game.SyncLobbyInfo();
                        break;
                    }

                case "SyncClientPings":
                    {
                        var pings = new List<Session.ClientPing>();
                        var nodes = MiniYaml.FromString(order.TargetString);
                        foreach (var node in nodes)
                        {
                            var strings = node.Key.Split('@');
                            if (strings[0] == "ClientPing")
                                pings.Add(Session.ClientPing.Deserialize(node.Value));
                        }

                        orderManager.LobbyInfo.ClientPings = pings;
                        break;
                    }

                case "Ping":
                    {
                        orderManager.IssueOrder(Order.Pong(order.TargetString));
                        break;
                    }

                default:
                    {
                        if (!order.IsImmediate)
                        {
                            var self = order.Subject;
                            if (!self.IsDead)
                                foreach (var t in self.TraitsImplementing<IResolveOrder>())
                                    t.ResolveOrder(self, order);
                        }

                        break;
                    }
            }
        }
Exemplo n.º 20
0
        internal LobbyDelegate( [ObjectCreator.Param( "widget" )] Widget lobby, [ObjectCreator.Param] OrderManager orderManager )
        {
            this.orderManager = orderManager;
            Game.LobbyInfoChanged += UpdateCurrentMap;
            UpdateCurrentMap();

            CurrentColorPreview1 = Game.Settings.Player.Color1;
            CurrentColorPreview2 = Game.Settings.Player.Color2;

            Players = lobby.GetWidget("PLAYERS");
            LocalPlayerTemplate = Players.GetWidget("TEMPLATE_LOCAL");
            RemotePlayerTemplate = Players.GetWidget("TEMPLATE_REMOTE");
            EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY");
            EmptySlotTemplateHost = Players.GetWidget("TEMPLATE_EMPTY_HOST");

            var mapPreview = lobby.GetWidget<MapPreviewWidget>("LOBBY_MAP_PREVIEW");
            mapPreview.Map = () => Map;
            mapPreview.OnSpawnClick = sp =>
            {
                if (orderManager.LocalClient.State == Session.ClientState.Ready) return;
                var owned = orderManager.LobbyInfo.Clients.Any(c => c.SpawnPoint == sp);
                if (sp == 0 || !owned)
                    orderManager.IssueOrder(Order.Command("spawn {0}".F(sp)));
            };

            mapPreview.SpawnColors = () =>
            {
                var spawns = Map.SpawnPoints;
                var sc = new Dictionary<int2, Color>();

                for (int i = 1; i <= spawns.Count(); i++)
                {
                    var client = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.SpawnPoint == i);
                    if (client == null)
                        continue;
                    sc.Add(spawns.ElementAt(i - 1), client.Color1);
                }
                return sc;
            };

            CountryNames = Rules.Info["world"].Traits.WithInterface<OpenRA.Traits.CountryInfo>().ToDictionary(a => a.Race, a => a.Name);

            CountryNames.Add("random", "Random");

            var mapButton = lobby.GetWidget("CHANGEMAP_BUTTON");
            mapButton.OnMouseUp = mi =>
            {
                Widget.OpenWindow( "MAP_CHOOSER", new Dictionary<string, object> { { "orderManager", orderManager }, { "mapName", MapUid } } );
                return true;
            };

            mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;

            var disconnectButton = lobby.GetWidget("DISCONNECT_BUTTON");
            disconnectButton.OnMouseUp = mi =>
            {
                Game.Disconnect();
                return true;
            };

            var lockTeamsCheckbox = lobby.GetWidget<CheckboxWidget>("LOCKTEAMS_CHECKBOX");
            lockTeamsCheckbox.IsVisible = () => lockTeamsCheckbox.Visible && true;
            lockTeamsCheckbox.Checked = () => orderManager.LobbyInfo.GlobalSettings.LockTeams;
            lockTeamsCheckbox.OnMouseDown = mi =>
            {
                if (Game.IsHost)
                    orderManager.IssueOrder(Order.Command(
                        "lockteams {0}".F(!orderManager.LobbyInfo.GlobalSettings.LockTeams)));
                return true;
            };

            var startGameButton = lobby.GetWidget("START_GAME_BUTTON");
            startGameButton.OnMouseUp = mi =>
            {
                mapButton.Visible = false;
                disconnectButton.Visible = false;
                lockTeamsCheckbox.Visible = false;
                orderManager.IssueOrder(Order.Command("startgame"));
                return true;
            };

            // Todo: Only show if the map requirements are met for player slots
            startGameButton.IsVisible = () => Game.IsHost;

            Game.LobbyInfoChanged += JoinedServer;
            Game.ConnectionStateChanged += ResetConnectionState;
            Game.LobbyInfoChanged += UpdatePlayerList;

            Game.AddChatLine += lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").AddLine;

            bool teamChat = false;
            var chatLabel = lobby.GetWidget<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.GetWidget<TextFieldWidget>("CHAT_TEXTFIELD");
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                var order = (teamChat) ? Order.TeamChat(chatTextField.Text) : Order.Chat(chatTextField.Text);
                orderManager.IssueOrder(order);
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return true;
            };

            var colorChooser = lobby.GetWidget("COLOR_CHOOSER");
            var hueSlider = colorChooser.GetWidget<SliderWidget>("HUE_SLIDER");
            var satSlider = colorChooser.GetWidget<SliderWidget>("SAT_SLIDER");
            var lumSlider = colorChooser.GetWidget<SliderWidget>("LUM_SLIDER");
            var rangeSlider = colorChooser.GetWidget<SliderWidget>("RANGE_SLIDER");

            hueSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());
            satSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());
            lumSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());
            rangeSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());

            colorChooser.GetWidget<ButtonWidget>("BUTTON_OK").OnMouseUp = mi =>
            {
                colorChooser.IsVisible = () => false;
                UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());
                UpdatePlayerColor(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());
                return true;
            };
        }
Exemplo n.º 21
0
 public static void SetupKickWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager)
 {
     var button = parent.Get<ButtonWidget>("KICK");
     button.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
     button.IsDisabled = () => orderManager.LocalClient.IsReady;
     button.OnClick = () => orderManager.IssueOrder(Order.Command("kick " + c.Index));
 }
Exemplo n.º 22
0
        public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
			OrderManager orderManager, ColorPickerPaletteModifier preview)
        {
            Action<ColorRamp> onSelect = c =>
            {
                if (client.Bot == null)
                {
                    Game.Settings.Player.ColorRamp = c;
                    Game.Settings.Save();
                }

                color.RemovePanel();
                orderManager.IssueOrder(Order.Command("color {0} {1}".F(client.Index, c)));
            };

            Action<ColorRamp> onChange = c => preview.Ramp = c;

            var colorChooser = Game.LoadWidget(orderManager.world, "COLOR_CHOOSER", null, new WidgetArgs()
            {
                { "onSelect", onSelect },
                { "onChange", onChange },
                { "initialRamp", client.ColorRamp }
            });

            color.AttachPanel(colorChooser);
        }
Exemplo n.º 23
0
        internal static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            if (world != null)
            {
                if (!world.WorldActor.TraitsImplementing <IValidateOrder>().All(vo =>
                                                                                vo.OrderValidation(orderManager, world, clientId, order)))
                {
                    return;
                }
            }

            switch (order.OrderString)
            {
            case "Chat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                // Cut chat messages to the hard limit to avoid exploits
                var message = order.TargetString;
                if (message.Length > ChatMessageMaxLength)
                {
                    message = order.TargetString.Substring(0, ChatMessageMaxLength);
                }

                if (client != null)
                {
                    var player = world != null?world.FindPlayerByClient(client) : null;

                    var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
                    suffix = client.IsObserver ? " (Spectator)" : suffix;

                    if (orderManager.LocalClient != null && client != orderManager.LocalClient && client.Team > 0 && client.Team == orderManager.LocalClient.Team)
                    {
                        suffix += " (Ally)";
                    }

                    Game.AddChatLine(client.Color.RGB, client.Name + suffix, message);
                }
                else
                {
                    Game.AddChatLine(Color.White, "(player {0})".F(clientId), message);
                }
                break;
            }

            case "Message":                     // Server message
                Game.AddChatLine(Color.White, ServerChatName, order.TargetString);
                break;

            case "Disconnected":                     /* reports that the target player disconnected */
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    client.State = Session.ClientState.Disconnected;
                }
                break;
            }

            case "TeamChat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                if (client != null)
                {
                    if (world == null)
                    {
                        if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
                        {
                            Game.AddChatLine(client.Color.RGB, "[Team] " + client.Name, order.TargetString);
                        }
                    }
                    else
                    {
                        var player = world.FindPlayerByClient(client);
                        if (player != null && player.WinState == WinState.Lost)
                        {
                            Game.AddChatLine(client.Color.RGB, client.Name + " (Dead)", order.TargetString);
                        }
                        else if ((player != null && world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally) || (world.IsReplay && player != null))
                        {
                            Game.AddChatLine(client.Color.RGB, "[Team" + (world.IsReplay ? " " + client.Team : "") + "] " + client.Name, order.TargetString);
                        }
                        else if ((orderManager.LocalClient != null && orderManager.LocalClient.IsObserver && client.IsObserver) || (world.IsReplay && client.IsObserver))
                        {
                            Game.AddChatLine(client.Color.RGB, "[Spectators] " + client.Name, order.TargetString);
                        }
                    }
                }

                break;
            }

            case "StartGame":
            {
                if (Game.ModData.MapCache[orderManager.LobbyInfo.GlobalSettings.Map].Status != MapStatus.Available)
                {
                    Game.Disconnect();
                    Game.LoadShellMap();

                    // TODO: After adding a startup error dialog, notify the replay load failure.
                    break;
                }

                Game.AddChatLine(Color.White, ServerChatName, "The game has started.");
                Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, WorldType.Regular);
                break;
            }

            case "PauseGame":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var pause = order.TargetString == "Pause";

                    // Prevent injected unpause orders from restarting a finished game
                    if (orderManager.World.PauseStateLocked && !pause)
                    {
                        break;
                    }

                    if (orderManager.World.Paused != pause && world != null && world.LobbyInfo.NonBotClients.Count() > 1)
                    {
                        var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
                        Game.AddChatLine(Color.White, ServerChatName, pausetext);
                    }

                    orderManager.World.Paused          = pause;
                    orderManager.World.PredictedPaused = pause;
                }

                break;
            }

            case "HandshakeRequest":
            {
                // Switch to the server's mod if we need and are able to
                var mod     = Game.ModData.Manifest;
                var request = HandshakeRequest.Deserialize(order.TargetString);

                var         externalKey = ExternalMod.MakeKey(request.Mod, request.Version);
                ExternalMod external;
                if ((request.Mod != mod.Id || request.Version != mod.Metadata.Version) &&
                    Game.ExternalMods.TryGetValue(externalKey, out external))
                {
                    // The ConnectionFailedLogic will prompt the user to switch mods
                    orderManager.ServerExternalMod = external;
                    orderManager.Connection.Dispose();
                    break;
                }

                Game.Settings.Player.Name = Settings.SanitizedPlayerName(Game.Settings.Player.Name);
                Game.Settings.Save();

                // Otherwise send the handshake with our current settings and let the server reject us
                var info = new Session.Client()
                {
                    Name           = Game.Settings.Player.Name,
                    PreferredColor = Game.Settings.Player.Color,
                    Color          = Game.Settings.Player.Color,
                    Faction        = "Random",
                    SpawnPoint     = 0,
                    Team           = 0,
                    State          = Session.ClientState.Invalid
                };

                var response = new HandshakeResponse()
                {
                    Client   = info,
                    Mod      = mod.Id,
                    Version  = mod.Metadata.Version,
                    Password = orderManager.Password
                };

                orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
                break;
            }

            case "ServerError":
            {
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = false;
                break;
            }

            case "AuthenticationError":
            {
                // The ConnectionFailedLogic will prompt the user for the password
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = true;
                break;
            }

            case "SyncInfo":
            {
                orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
                SetOrderLag(orderManager);
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyClients":
            {
                var clients = new List <Session.Client>();
                var nodes   = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Client")
                    {
                        clients.Add(Session.Client.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.Clients = clients;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbySlots":
            {
                var slots = new Dictionary <string, Session.Slot>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Slot")
                    {
                        var slot = Session.Slot.Deserialize(node.Value);
                        slots.Add(slot.PlayerReference, slot);
                    }
                }

                orderManager.LobbyInfo.Slots = slots;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyGlobalSettings":
            {
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "GlobalSettings")
                    {
                        orderManager.LobbyInfo.GlobalSettings = Session.Global.Deserialize(node.Value);
                    }
                }

                SetOrderLag(orderManager);
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncClientPings":
            {
                var pings = new List <Session.ClientPing>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "ClientPing")
                    {
                        pings.Add(Session.ClientPing.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.ClientPings = pings;
                break;
            }

            case "Ping":
            {
                orderManager.IssueOrder(Order.Pong(order.TargetString));
                break;
            }

            default:
            {
                if (!order.IsImmediate)
                {
                    var self = order.Subject;
                    if (!self.IsDead)
                    {
                        foreach (var t in self.TraitsImplementing <IResolveOrder>())
                        {
                            t.ResolveOrder(self, order);
                        }
                    }
                }

                break;
            }
            }
        }
Exemplo n.º 24
0
        internal static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            switch (order.OrderString)
            {
            // Server message
            case "Message":
                Game.AddSystemLine(order.TargetString);
                break;

            // Reports that the target player disconnected
            case "Disconnected":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    client.State = Session.ClientState.Disconnected;
                    var player = world?.FindPlayerByClient(client);
                    if (player != null)
                    {
                        world.OnPlayerDisconnected(player);
                    }
                }

                break;
            }

            case "Chat":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client == null)
                {
                    break;
                }

                // Cut chat messages to the hard limit to avoid exploits
                var message = order.TargetString;
                if (message.Length > ChatMessageMaxLength)
                {
                    message = order.TargetString.Substring(0, ChatMessageMaxLength);
                }

                // ExtraData 0 means this is a normal chat order, everything else is team chat
                if (order.ExtraData == 0)
                {
                    var p = world != null?world.FindPlayerByClient(client) : null;

                    var suffix = (p != null && p.WinState == WinState.Lost) ? " (Dead)" : "";
                    suffix = client.IsObserver ? " (Spectator)" : suffix;

                    if (orderManager.LocalClient != null && client != orderManager.LocalClient && client.Team > 0 && client.Team == orderManager.LocalClient.Team)
                    {
                        suffix += " (Ally)";
                    }

                    Game.AddChatLine(client.Name + suffix, client.Color, message);
                    break;
                }

                // We are still in the lobby
                if (world == null)
                {
                    var prefix = order.ExtraData == uint.MaxValue ? "[Spectators] " : "[Team] ";
                    if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
                    {
                        Game.AddChatLine(prefix + client.Name, client.Color, message);
                    }

                    break;
                }

                var player = world.FindPlayerByClient(client);
                var localClientIsObserver = world.IsReplay || (orderManager.LocalClient != null && orderManager.LocalClient.IsObserver) ||
                                            (world.LocalPlayer != null && world.LocalPlayer.WinState != WinState.Undefined);

                // ExtraData gives us the team number, uint.MaxValue means Spectators
                if (order.ExtraData == uint.MaxValue && localClientIsObserver)
                {
                    // Validate before adding the line
                    if (client.IsObserver || (player != null && player.WinState != WinState.Undefined))
                    {
                        Game.AddChatLine("[Spectators] " + client.Name, client.Color, message);
                    }

                    break;
                }

                var valid      = client.Team == order.ExtraData && player != null && player.WinState == WinState.Undefined;
                var isSameTeam = orderManager.LocalClient != null && order.ExtraData == orderManager.LocalClient.Team &&
                                 world.LocalPlayer != null && world.LocalPlayer.WinState == WinState.Undefined;

                if (valid && (isSameTeam || world.IsReplay))
                {
                    Game.AddChatLine("[Team" + (world.IsReplay ? " " + order.ExtraData : "") + "] " + client.Name, client.Color, message);
                }

                break;
            }

            case "StartGame":
            {
                if (Game.ModData.MapCache[orderManager.LobbyInfo.GlobalSettings.Map].Status != MapStatus.Available)
                {
                    Game.Disconnect();
                    Game.LoadShellMap();

                    // TODO: After adding a startup error dialog, notify the replay load failure.
                    break;
                }

                if (!string.IsNullOrEmpty(order.TargetString))
                {
                    var data = MiniYaml.FromString(order.TargetString);
                    var saveLastOrdersFrame = data.FirstOrDefault(n => n.Key == "SaveLastOrdersFrame");
                    if (saveLastOrdersFrame != null)
                    {
                        orderManager.GameSaveLastFrame =
                            FieldLoader.GetValue <int>("saveLastOrdersFrame", saveLastOrdersFrame.Value.Value);
                    }

                    var saveSyncFrame = data.FirstOrDefault(n => n.Key == "SaveSyncFrame");
                    if (saveSyncFrame != null)
                    {
                        orderManager.GameSaveLastSyncFrame =
                            FieldLoader.GetValue <int>("SaveSyncFrame", saveSyncFrame.Value.Value);
                    }
                }
                else
                {
                    Game.AddSystemLine("The game has started.");
                }

                Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, WorldType.Regular);
                break;
            }

            case "SaveTraitData":
            {
                var data       = MiniYaml.FromString(order.TargetString)[0];
                var traitIndex = int.Parse(data.Key);

                world?.AddGameSaveTraitData(traitIndex, data.Value);

                break;
            }

            case "GameSaved":
                if (!orderManager.World.IsReplay)
                {
                    Game.AddSystemLine("Game saved");
                }

                foreach (var nsr in orderManager.World.WorldActor.TraitsImplementing <INotifyGameSaved>())
                {
                    nsr.GameSaved(orderManager.World);
                }
                break;

            case "PauseGame":
            {
                var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                if (client != null)
                {
                    var pause = order.TargetString == "Pause";

                    // Prevent injected unpause orders from restarting a finished game
                    if (orderManager.World.PauseStateLocked && !pause)
                    {
                        break;
                    }

                    if (orderManager.World.Paused != pause && world != null && world.LobbyInfo.NonBotClients.Count() > 1)
                    {
                        var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
                        Game.AddSystemLine(pausetext);
                    }

                    orderManager.World.Paused          = pause;
                    orderManager.World.PredictedPaused = pause;
                }

                break;
            }

            case "HandshakeRequest":
            {
                // Switch to the server's mod if we need and are able to
                var mod     = Game.ModData.Manifest;
                var request = HandshakeRequest.Deserialize(order.TargetString);

                var externalKey = ExternalMod.MakeKey(request.Mod, request.Version);
                if ((request.Mod != mod.Id || request.Version != mod.Metadata.Version) &&
                    Game.ExternalMods.TryGetValue(externalKey, out var external))
                {
                    // The ConnectionFailedLogic will prompt the user to switch mods
                    orderManager.ServerExternalMod = external;
                    orderManager.Connection.Dispose();
                    break;
                }

                Game.Settings.Player.Name = Settings.SanitizedPlayerName(Game.Settings.Player.Name);
                Game.Settings.Save();

                // Otherwise send the handshake with our current settings and let the server reject us
                var info = new Session.Client()
                {
                    Name           = Game.Settings.Player.Name,
                    PreferredColor = Game.Settings.Player.Color,
                    Color          = Game.Settings.Player.Color,
                    Faction        = "Random",
                    SpawnPoint     = 0,
                    Team           = 0,
                    State          = Session.ClientState.Invalid
                };

                var localProfile = Game.LocalPlayerProfile;
                var response     = new HandshakeResponse()
                {
                    Client         = info,
                    Mod            = mod.Id,
                    Version        = mod.Metadata.Version,
                    Password       = orderManager.Password,
                    Fingerprint    = localProfile.Fingerprint,
                    OrdersProtocol = ProtocolVersion.Orders
                };

                if (request.AuthToken != null && response.Fingerprint != null)
                {
                    response.AuthSignature = localProfile.Sign(request.AuthToken);
                }

                orderManager.IssueOrder(new Order("HandshakeResponse", null, false)
                    {
                        Type         = OrderType.Handshake,
                        IsImmediate  = true,
                        TargetString = response.Serialize()
                    });

                break;
            }

            case "ServerError":
            {
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = false;
                break;
            }

            case "AuthenticationError":
            {
                // The ConnectionFailedLogic will prompt the user for the password
                orderManager.ServerError          = order.TargetString;
                orderManager.AuthenticationFailed = true;
                break;
            }

            case "SyncInfo":
            {
                orderManager.LobbyInfo = Session.Deserialize(order.TargetString);
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyClients":
            {
                var clients = new List <Session.Client>();
                var nodes   = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Client")
                    {
                        clients.Add(Session.Client.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.Clients = clients;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbySlots":
            {
                var slots = new Dictionary <string, Session.Slot>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "Slot")
                    {
                        var slot = Session.Slot.Deserialize(node.Value);
                        slots.Add(slot.PlayerReference, slot);
                    }
                }

                orderManager.LobbyInfo.Slots = slots;
                Game.SyncLobbyInfo();
                break;
            }

            case "SyncLobbyGlobalSettings":
            {
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "GlobalSettings")
                    {
                        orderManager.LobbyInfo.GlobalSettings = Session.Global.Deserialize(node.Value);
                    }
                }

                Game.SyncLobbyInfo();
                break;
            }

            case "SyncClientPings":
            {
                var pings = new List <Session.ClientPing>();
                var nodes = MiniYaml.FromString(order.TargetString);
                foreach (var node in nodes)
                {
                    var strings = node.Key.Split('@');
                    if (strings[0] == "ClientPing")
                    {
                        pings.Add(Session.ClientPing.Deserialize(node.Value));
                    }
                }

                orderManager.LobbyInfo.ClientPings = pings;
                break;
            }

            case "Ping":
            {
                orderManager.IssueOrder(Order.FromTargetString("Pong", order.TargetString, true));
                break;
            }

            default:
            {
                if (world == null)
                {
                    break;
                }

                if (order.GroupedActors == null)
                {
                    ResolveOrder(order, world, orderManager, clientId);
                }
                else
                {
                    foreach (var subject in order.GroupedActors)
                    {
                        ResolveOrder(Order.FromGroupedOrder(order, subject), world, orderManager, clientId);
                    }
                }

                break;
            }
            }
        }
Exemplo n.º 25
0
        internal LobbyLogic(Widget widget, WorldRenderer worldRenderer, OrderManager orderManager,
			Action onExit, Action onStart, bool skirmishMode, Ruleset modRules)
        {
            lobby = widget;
            this.orderManager = orderManager;
            this.onStart = onStart;
            this.onExit = onExit;
            this.skirmishMode = skirmishMode;
            this.modRules = modRules;

            orderManager.AddChatLine += AddChatLine;
            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            Game.BeforeGameStart += OnGameStart;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
            if (name != null)
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

            Ui.LoadWidget("LOBBY_MAP_PREVIEW", lobby.Get("MAP_PREVIEW_ROOT"), new WidgetArgs
            {
                { "orderManager", orderManager },
                { "lobby", this }
            });

            UpdateCurrentMap();
            players = Ui.LoadWidget<ScrollPanelWidget>("LOBBY_PLAYER_BIN", lobby.Get("PLAYER_BIN_ROOT"), new WidgetArgs());
            players.IsVisible = () => panel == PanelType.Players;

            var playerBinHeaders = lobby.GetOrNull<ContainerWidget>("LABEL_CONTAINER");
            if (playerBinHeaders != null)
                playerBinHeaders.IsVisible = () => panel == PanelType.Players;

            editablePlayerTemplate = players.Get("TEMPLATE_EDITABLE_PLAYER");
            nonEditablePlayerTemplate = players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            emptySlotTemplate = players.Get("TEMPLATE_EMPTY");
            editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            countryNames = modRules.Actors["world"].Traits.WithInterface<CountryInfo>()
                .Where(c => c.Selectable)
                .ToDictionary(a => a.Race, a => a.Name);
            countryNames.Add("random", "Any");

            var gameStarting = false;
            Func<bool> configurationDisabled = () => !Game.IsHost || gameStarting ||
                panel == PanelType.Kick || panel == PanelType.ForceStart ||
                orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

            var mapButton = lobby.GetOrNull<ButtonWidget>("CHANGEMAP_BUTTON");
            if (mapButton != null)
            {
                mapButton.IsDisabled = configurationDisabled;
                mapButton.OnClick = () =>
                {
                    var onSelect = new Action<string>(uid =>
                    {
                        // Don't select the same map again
                        if (uid == Map.Uid)
                            return;

                        orderManager.IssueOrder(Order.Command("map " + uid));
                        Game.Settings.Server.Map = uid;
                        Game.Settings.Save();
                    });

                    Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                    {
                        { "initialMap", Map.Uid },
                        { "onExit", DoNothing },
                        { "onSelect", onSelect }
                    });
                };
            }

            var slotsButton = lobby.GetOrNull<DropDownButtonWidget>("SLOTS_DROPDOWNBUTTON");
            if (slotsButton != null)
            {
                slotsButton.IsDisabled = () => configurationDisabled() || panel != PanelType.Players ||
                    Map.RuleStatus != MapRuleStatus.Cached || !orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots || !s.LockTeam);

                var botNames = modRules.Actors["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name);
                slotsButton.OnMouseDown = _ =>
                {
                    var options = new Dictionary<string, IEnumerable<DropDownOption>>();

                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (orderManager.LobbyInfo.Slots.Values.Any(s => s.AllowBots))
                    {
                        var botOptions = new List<DropDownOption>()
                        {
                            new DropDownOption()
                            {
                                Title = "Add",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var bot = botNames.Random(Game.CosmeticRandom);
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (slot.Value.AllowBots == true && (c == null || c.Bot != null))
                                            orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot.Key, botController.Index, bot)));
                                    }
                                }
                            }
                        };

                        if (orderManager.LobbyInfo.Clients.Any(c => c.Bot != null))
                        {
                            botOptions.Add(new DropDownOption()
                            {
                                Title = "Remove",
                                IsSelected = () => false,
                                OnClick = () =>
                                {
                                    foreach (var slot in orderManager.LobbyInfo.Slots)
                                    {
                                        var c = orderManager.LobbyInfo.ClientInSlot(slot.Key);
                                        if (c != null && c.Bot != null)
                                            orderManager.IssueOrder(Order.Command("slot_open " + slot.Value.PlayerReference));
                                    }
                                }
                            });
                        }

                        options.Add("Configure Bots", botOptions);
                    }

                    var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
                    if (teamCount >= 1)
                    {
                        var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
                        {
                            Title = "{0} Teams".F(d),
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                        }).ToList();

                        if (orderManager.LobbyInfo.Slots.Any(s => s.Value.AllowBots))
                        {
                            teamOptions.Add(new DropDownOption
                            {
                                Title = "Humans vs Bots",
                                IsSelected = () => false,
                                OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
                            });
                        }

                        teamOptions.Add(new DropDownOption
                        {
                            Title = "Free for all",
                            IsSelected = () => false,
                            OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
                        });

                        options.Add("Configure Teams", teamOptions);
                    }

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    slotsButton.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 175, options, setupItem);
                };
            }

            var optionsBin = Ui.LoadWidget("LOBBY_OPTIONS_BIN", lobby, new WidgetArgs());
            optionsBin.IsVisible = () => panel == PanelType.Options;

            var optionsButton = lobby.Get<ButtonWidget>("OPTIONS_BUTTON");
            optionsButton.IsDisabled = () => Map.RuleStatus != MapRuleStatus.Cached || panel == PanelType.Kick || panel == PanelType.ForceStart;
            optionsButton.GetText = () => panel == PanelType.Options ? "Players" : "Options";
            optionsButton.OnClick = () => panel = (panel == PanelType.Options) ? PanelType.Players : PanelType.Options;

            // Force start panel
            Action startGame = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            var startGameButton = lobby.GetOrNull<ButtonWidget>("START_GAME_BUTTON");
            if (startGameButton != null)
            {
                startGameButton.IsDisabled = () => configurationDisabled() || Map.RuleStatus != MapRuleStatus.Cached ||
                    orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
                startGameButton.OnClick = () =>
                {
                    Func<KeyValuePair<string, Session.Slot>, bool> notReady = sl =>
                    {
                        var cl = orderManager.LobbyInfo.ClientInSlot(sl.Key);

                        // Bots and admins don't count
                        return cl != null && !cl.IsAdmin && cl.Bot == null && !cl.IsReady;
                    };

                    if (orderManager.LobbyInfo.Slots.Any(notReady))
                        panel = PanelType.ForceStart;
                    else
                        startGame();
                };
            }

            var forceStartBin = Ui.LoadWidget("FORCE_START_DIALOG", lobby, new WidgetArgs());
            forceStartBin.IsVisible = () => panel == PanelType.ForceStart;
            forceStartBin.Get("KICK_WARNING").IsVisible = () => orderManager.LobbyInfo.Clients.Any(c => c.IsInvalid);
            forceStartBin.Get<ButtonWidget>("OK_BUTTON").OnClick = startGame;
            forceStartBin.Get<ButtonWidget>("CANCEL_BUTTON").OnClick = () => panel = PanelType.Players;

            // Options panel
            var allowCheats = optionsBin.GetOrNull<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            if (allowCheats != null)
            {
                allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
                allowCheats.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Cheats.HasValue || configurationDisabled();
                allowCheats.OnClick = () =>	orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            }

            var crates = optionsBin.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
            if (crates != null)
            {
                crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Crates.HasValue || configurationDisabled();
                crates.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var allybuildradius = optionsBin.GetOrNull<CheckboxWidget>("ALLYBUILDRADIUS_CHECKBOX");
            if (allybuildradius != null)
            {
                allybuildradius.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius;
                allybuildradius.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.AllyBuildRadius.HasValue || configurationDisabled();
                allybuildradius.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "allybuildradius {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllyBuildRadius)));
            }

            var fragileAlliance = optionsBin.GetOrNull<CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");
            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.FragileAlliances.HasValue || configurationDisabled();
                fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            }

            var difficulty = optionsBin.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
            if (difficulty != null)
            {
                difficulty.IsVisible = () => Map.Status == MapStatus.Available && Map.Map.Options.Difficulties.Any();
                difficulty.IsDisabled = () => Map.Status != MapStatus.Available || configurationDisabled();
                difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Map.Options.Difficulties.Select(d => new DropDownOption
                    {
                        Title = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("DIFFICULTY_DESC").IsVisible = difficulty.IsVisible;
            }

            var startingUnits = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGUNITS_DROPDOWNBUTTON");
            if (startingUnits != null)
            {
                var startUnitsInfo = modRules.Actors["world"].Traits.WithInterface<MPStartUnitsInfo>();
                var classes = startUnitsInfo.Select(a => a.Class).Distinct();
                Func<string, string> className = c =>
                {
                    var selectedClass = startUnitsInfo.Where(s => s.Class == c).Select(u => u.ClassName).FirstOrDefault();
                    return selectedClass != null ? selectedClass : c;
                };

                startingUnits.IsDisabled = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits || configurationDisabled();
                startingUnits.GetText = () => Map.Status != MapStatus.Available || !Map.Map.Options.ConfigurableStartingUnits ? "Not Available" : className(orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass);
                startingUnits.OnMouseDown = _ =>
                {
                    var options = classes.Select(c => new DropDownOption
                    {
                        Title = className(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingUnitsClass == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingunits {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingUnits.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };

                optionsBin.Get<LabelWidget>("STARTINGUNITS_DESC").IsVisible = startingUnits.IsVisible;
            }

            var startingCash = optionsBin.GetOrNull<DropDownButtonWidget>("STARTINGCASH_DROPDOWNBUTTON");
            if (startingCash != null)
            {
                startingCash.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue || configurationDisabled();
                startingCash.GetText = () => Map.Status != MapStatus.Available || Map.Map.Options.StartingCash.HasValue ? "Not Available" : "${0}".F(orderManager.LobbyInfo.GlobalSettings.StartingCash);
                startingCash.OnMouseDown = _ =>
                {
                    var options = modRules.Actors["player"].Traits.Get<PlayerResourcesInfo>().SelectableCash.Select(c => new DropDownOption
                    {
                        Title = "${0}".F(c),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.StartingCash == c,
                        OnClick = () => orderManager.IssueOrder(Order.Command("startingcash {0}".F(c)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    startingCash.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var techLevel = optionsBin.GetOrNull<DropDownButtonWidget>("TECHLEVEL_DROPDOWNBUTTON");
            if (techLevel != null)
            {
                var techTraits = modRules.Actors["player"].Traits.WithInterface<ProvidesTechPrerequisiteInfo>().ToArray();
                techLevel.IsVisible = () => techTraits.Length > 0;
                optionsBin.GetOrNull<LabelWidget>("TECHLEVEL_DESC").IsVisible = () => techTraits.Length > 0;
                techLevel.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null || configurationDisabled() || techTraits.Length <= 1;
                techLevel.GetText = () => Map.Status != MapStatus.Available || Map.Map.Options.TechLevel != null ? "Not Available" : "{0}".F(orderManager.LobbyInfo.GlobalSettings.TechLevel);
                techLevel.OnMouseDown = _ =>
                {
                    var options = techTraits.Select(c => new DropDownOption
                    {
                        Title = "{0}".F(c.Name),
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.TechLevel == c.Name,
                        OnClick = () => orderManager.IssueOrder(Order.Command("techlevel {0}".F(c.Name)))
                    });

                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };

                    techLevel.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var enableShroud = optionsBin.GetOrNull<CheckboxWidget>("SHROUD_CHECKBOX");
            if (enableShroud != null)
            {
                enableShroud.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Shroud;
                enableShroud.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Shroud.HasValue || configurationDisabled();
                enableShroud.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "shroud {0}".F(!orderManager.LobbyInfo.GlobalSettings.Shroud)));
            }

            var enableFog = optionsBin.GetOrNull<CheckboxWidget>("FOG_CHECKBOX");
            if (enableFog != null)
            {
                enableFog.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Fog;
                enableFog.IsDisabled = () => Map.Status != MapStatus.Available || Map.Map.Options.Fog.HasValue || configurationDisabled();
                enableFog.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fog {0}".F(!orderManager.LobbyInfo.GlobalSettings.Fog)));
            }

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            if (skirmishMode)
                disconnectButton.Text = "Cancel";

            var teamChat = false;
            var chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.TakeKeyboardFocus();

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                // Always scroll to bottom when we've typed something
                chatPanel.ScrollToBottom();

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };
            chatTextField.OnAltKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = teamChat ? "Team:" : "Chat:";
                return true;
            };
            chatTextField.OnTabKey = () =>
            {
                chatTextField.Text = tabCompletion.Complete(chatTextField.Text);
                chatTextField.CursorPosition = chatTextField.Text.Length;
                return true;
            };

            chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull<ButtonWidget>("MUSIC_BUTTON");
            if (musicButton != null)
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "world", orderManager.world }
                });

            var settingsButton = lobby.GetOrNull<ButtonWidget>("SETTINGS_BUTTON");
            if (settingsButton != null)
            {
                settingsButton.OnClick = () => Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs
                {
                    { "onExit", DoNothing },
                    { "worldRenderer", worldRenderer }
                });
            }

            // Add a bot on the first lobbyinfo update
            if (skirmishMode)
            {
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot = orderManager.LobbyInfo.FirstEmptyBotSlot();
                    var bot = modRules.Actors["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.IsAdmin);
                    if (slot != null && bot != null)
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                });
            }
        }
Exemplo n.º 26
0
        public static void SetupEditableReadyWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, MapPreview map, bool forceDisable)
        {
            var status = parent.Get<CheckboxWidget>("STATUS_CHECKBOX");
            status.IsChecked = () => orderManager.LocalClient.IsReady || c.Bot != null;
            status.IsVisible = () => true;
            status.IsDisabled = () => c.Bot != null || map.Status != MapStatus.Available || forceDisable;

            var state = orderManager.LocalClient.IsReady ? Session.ClientState.NotReady : Session.ClientState.Ready;
            status.OnClick = () => orderManager.IssueOrder(Order.Command("state {0}".F(state)));
        }
Exemplo n.º 27
0
        public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
			OrderManager orderManager, World world, ColorPreviewManagerWidget preview)
        {
            Action onExit = () =>
            {
                if (client.Bot == null)
                {
                    Game.Settings.Player.Color = preview.Color;
                    Game.Settings.Save();
                }

                color.RemovePanel();
                orderManager.IssueOrder(Order.Command("color {0} {1}".F(client.Index, preview.Color)));
            };

            Action<HSLColor> onChange = c => preview.Color = c;

            var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs()
            {
                { "onChange", onChange },
                { "initialColor", client.Color }
            });

            color.AttachPanel(colorChooser, onExit);
        }
Exemplo n.º 28
0
        public static void SetupKickWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, Widget lobby, Action before, Action after)
        {
            var button = parent.Get<ButtonWidget>("KICK");
            button.IsVisible = () => Game.IsHost && c.Index != orderManager.LocalClient.Index;
            button.IsDisabled = () => orderManager.LocalClient.IsReady;
            Action<bool> okPressed = tempBan => { orderManager.IssueOrder(Order.Command("kick {0} {1}".F(c.Index, tempBan))); after(); };
            button.OnClick = () =>
            {
                before();

                Game.LoadWidget(null, "KICK_CLIENT_DIALOG", lobby.Get("TOP_PANELS_ROOT"), new WidgetArgs
                {
                    { "clientName", c.Name },
                    { "okPressed", okPressed },
                    { "cancelPressed", after }
                });
            };
        }
Exemplo n.º 29
0
 private static void SetSpawnPoint(OrderManager orderManager, Session.Client playerToMove, int selectedSpawn)
 {
     var owned = orderManager.LobbyInfo.Clients.Any(c => c.SpawnPoint == selectedSpawn);
     if (selectedSpawn == 0 || !owned)
         orderManager.IssueOrder(Order.Command("spawn {0} {1}".F((playerToMove ?? orderManager.LocalClient).Index, selectedSpawn)));
 }
Exemplo n.º 30
0
        public static void ShowFactionDropDown(DropDownButtonWidget dropdown, Session.Client client,
			OrderManager orderManager, Dictionary<string, LobbyFaction> factions)
        {
            Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (factionId, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                    () => client.Faction == factionId,
                    () => orderManager.IssueOrder(Order.Command("faction {0} {1}".F(client.Index, factionId))));
                var faction = factions[factionId];
                item.Get<LabelWidget>("LABEL").GetText = () => faction.Name;
                var flag = item.Get<ImageWidget>("FLAG");
                flag.GetImageCollection = () => "flags";
                flag.GetImageName = () => factionId;
                item.GetTooltipText = () => faction.Description;
                return item;
            };

            var options = factions.Where(f => f.Value.Selectable).GroupBy(f => f.Value.Side)
                .ToDictionary(g => g.Key ?? "", g => g.Select(f => f.Key));

            dropdown.ShowDropDown("FACTION_DROPDOWN_TEMPLATE", 150, options, setupItem);
        }
Exemplo n.º 31
0
        public static void ProcessOrder(OrderManager orderManager, World world, int clientId, Order order)
        {
            if (world != null)
            {
                if (!world.WorldActor.TraitsImplementing<IValidateOrder>().All(vo =>
                    vo.OrderValidation(orderManager, world, clientId, order)))
                    return;
            }

            switch (order.OrderString)
            {
                case "Chat":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                        {
                            var player = world != null ? world.FindPlayerByClient(client) : null;
                            var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
                            suffix = client.IsObserver ? " (Spectator)" : suffix;
                            Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                        }
                        else
                            Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
                        break;
                    }
                case "Message": // Server message
                        Game.AddChatLine(Color.White, "Server", order.TargetString);
                    break;
                case "Disconnected": /* reports that the target player disconnected */
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                            client.State = Session.ClientState.Disconnected;
                        break;
                    }

                case "TeamChat":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);

                        if (client != null)
                        {
                            if (world == null)
                            {
                                if (orderManager.LocalClient != null && client.Team == orderManager.LocalClient.Team)
                                    Game.AddChatLine(client.Color.RGB, client.Name + " (Team)",
                                        order.TargetString);
                            }
                            else
                            {
                                var player = world.FindPlayerByClient(client);
                                if (player == null) return;

                                if (world.LocalPlayer != null && player.Stances[world.LocalPlayer] == Stance.Ally || player.WinState == WinState.Lost)
                                {
                                    var suffix = player.WinState == WinState.Lost ? " (Dead)" : " (Team)";
                                    Game.AddChatLine(client.Color.RGB, client.Name + suffix, order.TargetString);
                                }
                            }
                        }
                        break;
                    }

                case "StartGame":
                    {
                        Game.AddChatLine(Color.White, "Server", "The game has started.");
                        Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false);
                        break;
                    }

                case "PauseGame":
                    {
                        var client = orderManager.LobbyInfo.ClientWithIndex(clientId);
                        if (client != null)
                        {
                            var pause = order.TargetString == "Pause";
                            if (orderManager.world.Paused != pause && !world.LobbyInfo.IsSinglePlayer)
                            {
                                var pausetext = "The game is {0} by {1}".F(pause ? "paused" : "un-paused", client.Name);
                                Game.AddChatLine(Color.White, "", pausetext);
                            }

                            orderManager.world.Paused = pause;
                            orderManager.world.PredictedPaused = pause;
                        }
                        break;
                    }

                case "HandshakeRequest":
                    {
                        var request = HandshakeRequest.Deserialize(order.TargetString);
                        var localMods = orderManager.LobbyInfo.GlobalSettings.Mods.Select(m => "{0}@{1}".F(m,Mod.AllMods[m].Version)).ToArray();

                        // Check if mods match
                        if (localMods.FirstOrDefault().ToString().Split('@')[0] != request.Mods.FirstOrDefault().ToString().Split('@')[0])
                            throw new InvalidOperationException("Server's mod ({0}) and yours ({1}) don't match".F(localMods.FirstOrDefault().ToString().Split('@')[0], request.Mods.FirstOrDefault().ToString().Split('@')[0]));
                        // Check that the map exists on the client
                        if (!Game.modData.AvailableMaps.ContainsKey(request.Map))
                        {
                            if (Game.Settings.Game.AllowDownloading)
                                Game.DownloadMap(request.Map);
                            else
                                throw new InvalidOperationException("Missing map {0}".F(request.Map));
                        }

                        var info = new Session.Client()
                        {
                            Name = Game.Settings.Player.Name,
                            PreferredColor = Game.Settings.Player.Color,
                            Color = Game.Settings.Player.Color,
                            Country = "random",
                            SpawnPoint = 0,
                            Team = 0,
                            State = Session.ClientState.NotReady
                        };

                        var response = new HandshakeResponse()
                        {
                            Client = info,
                            Mods = localMods,
                            Password = "******"
                        };

                        orderManager.IssueOrder(Order.HandshakeResponse(response.Serialize()));
                        break;
                    }

                case "ServerError":
                    {
                        orderManager.ServerError = order.TargetString;
                        break;
                    }

                case "SyncInfo":
                    {
                        orderManager.LobbyInfo = Session.Deserialize(order.TargetString);

                        if (orderManager.FramesAhead != orderManager.LobbyInfo.GlobalSettings.OrderLatency
                            && !orderManager.GameStarted)
                        {
                            orderManager.FramesAhead = orderManager.LobbyInfo.GlobalSettings.OrderLatency;
                            Game.Debug("Order lag is now {0} frames.".F(orderManager.LobbyInfo.GlobalSettings.OrderLatency));
                        }
                        Game.SyncLobbyInfo();
                        break;
                    }

                case "SetStance":
                    {
                        if (!Game.orderManager.LobbyInfo.GlobalSettings.FragileAlliances)
                            return;

                        var targetPlayer = order.Player.World.Players.FirstOrDefault(p => p.InternalName == order.TargetString);
                        var newStance = (Stance)order.TargetLocation.X;

                        SetPlayerStance(world, order.Player, targetPlayer, newStance);

                        Game.Debug("{0} has set diplomatic stance vs {1} to {2}".F(
                            order.Player.PlayerName, targetPlayer.PlayerName, newStance));

                        // automatically declare war reciprocally
                        if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
                        {
                            SetPlayerStance(world, targetPlayer, order.Player, newStance);
                            Game.Debug("{0} has reciprocated",targetPlayer.PlayerName);
                        }

                        break;
                    }
                case "Ping":
                    {
                        orderManager.IssueOrder(Order.Pong(order.TargetString));
                        break;
                    }
                default:
                    {
                        if (!order.IsImmediate)
                        {
                            var self = order.Subject;
                            var health = self.TraitOrDefault<Health>();
                            if (health == null || !health.IsDead)
                                foreach (var t in self.TraitsImplementing<IResolveOrder>())
                                    t.ResolveOrder(self, order);
                        }
                        break;
                    }
            }
        }
Exemplo n.º 32
0
        internal LobbyLogic([ObjectCreator.Param( "widget" )] Widget lobby,
		                    [ObjectCreator.Param] OrderManager orderManager,
		                    [ObjectCreator.Param] WorldRenderer worldRenderer)
        {
            this.orderManager = orderManager;
            this.worldRenderer = worldRenderer;
            this.lobby = lobby;
            Game.BeforeGameStart += CloseWindow;
            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            UpdateCurrentMap();

            CurrentColorPreview = Game.Settings.Player.ColorRamp;

            Players = lobby.GetWidget<ScrollPanelWidget>("PLAYERS");
            LocalPlayerTemplate = Players.GetWidget("TEMPLATE_LOCAL");
            RemotePlayerTemplate = Players.GetWidget("TEMPLATE_REMOTE");
            EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY");
            EmptySlotTemplateHost = Players.GetWidget("TEMPLATE_EMPTY_HOST");
            LocalSpectatorTemplate = Players.GetWidget("TEMPLATE_LOCAL_SPECTATOR");
            RemoteSpectatorTemplate = Players.GetWidget("TEMPLATE_REMOTE_SPECTATOR");
            NewSpectatorTemplate = Players.GetWidget("TEMPLATE_NEW_SPECTATOR");

            var mapPreview = lobby.GetWidget<MapPreviewWidget>("LOBBY_MAP_PREVIEW");
            mapPreview.Map = () => Map;
            mapPreview.OnMouseDown = mi =>
            {
                var map = mapPreview.Map();
                if (map == null || mi.Button != MouseButton.Left
                    || orderManager.LocalClient.State == Session.ClientState.Ready)
                    return;

                var p = map.SpawnPoints
                    .Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(map, sp), i))
                    .Where(a => (a.First - mi.Location).LengthSquared < 64)
                    .Select(a => a.Second + 1)
                    .FirstOrDefault();

                var owned = orderManager.LobbyInfo.Clients.Any(c => c.SpawnPoint == p);
                if (p == 0 || !owned)
                    orderManager.IssueOrder(Order.Command("spawn {0} {1}".F(orderManager.LocalClient.Index, p)));
            };

            mapPreview.SpawnColors = () =>
            {
                var spawns = Map.SpawnPoints;
                var sc = new Dictionary<int2, Color>();

                for (int i = 1; i <= spawns.Count(); i++)
                {
                    var client = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.SpawnPoint == i);
                    if (client == null)
                        continue;
                    sc.Add(spawns.ElementAt(i - 1), client.ColorRamp.GetColor(0));
                }
                return sc;
            };

            CountryNames = Rules.Info["world"].Traits.WithInterface<OpenRA.Traits.CountryInfo>()
                .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Random");

            var mapButton = lobby.GetWidget<ButtonWidget>("CHANGEMAP_BUTTON");
            mapButton.OnClick = () =>
            {
                Widget.OpenWindow("MAP_CHOOSER", new WidgetArgs()
                {
                    { "orderManager", orderManager },
                    { "mapName", MapUid }
                });
            };

            mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;

            var disconnectButton = lobby.GetWidget<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () =>
            {
                CloseWindow();
                Game.Disconnect();
                Game.LoadShellMap();
                Widget.OpenWindow("MAINMENU_BG");
            };

            var allowCheats = lobby.GetWidget<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
            allowCheats.OnClick = () =>
            {
                if (Game.IsHost)
                    orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
            };

            var startGameButton = lobby.GetWidget<ButtonWidget>("START_GAME_BUTTON");
            startGameButton.OnClick = () =>
            {
                mapButton.Visible = false;
                disconnectButton.Visible = false;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            // Todo: Only show if the map requirements are met for player slots
            startGameButton.IsVisible = () => Game.IsHost;

            bool teamChat = false;
            var chatLabel = lobby.GetWidget<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.GetWidget<TextFieldWidget>("CHAT_TEXTFIELD");
            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                var order = (teamChat) ? Order.TeamChat(chatTextField.Text) : Order.Chat(chatTextField.Text);
                orderManager.IssueOrder(order);
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return true;
            };

            Game.AddChatLine += AddChatLine;
        }
Exemplo n.º 33
0
        internal CncLobbyLogic([ObjectCreator.Param( "widget" )] Widget lobby,
		                       [ObjectCreator.Param] World world, // Shellmap world
		                       [ObjectCreator.Param] OrderManager orderManager,
		                       [ObjectCreator.Param] Action onExit,
		                       [ObjectCreator.Param] Action onStart,
		                       [ObjectCreator.Param] bool addBots)
        {
            this.orderManager = orderManager;
            this.OnGameStart = () => { CloseWindow(); onStart(); };
            this.onExit = onExit;

            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            Game.BeforeGameStart += OnGameStart;
            Game.AddChatLine += AddChatLine;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            UpdateCurrentMap();
            PlayerPalettePreview = world.WorldActor.Trait<CncColorPickerPaletteModifier>();
            PlayerPalettePreview.Ramp = Game.Settings.Player.ColorRamp;
            Players = lobby.GetWidget<ScrollPanelWidget>("PLAYERS");
            EditablePlayerTemplate = Players.GetWidget("TEMPLATE_EDITABLE_PLAYER");
            NonEditablePlayerTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_PLAYER");
            EmptySlotTemplate = Players.GetWidget("TEMPLATE_EMPTY");
            EditableSpectatorTemplate = Players.GetWidget("TEMPLATE_EDITABLE_SPECTATOR");
            NonEditableSpectatorTemplate = Players.GetWidget("TEMPLATE_NONEDITABLE_SPECTATOR");
            NewSpectatorTemplate = Players.GetWidget("TEMPLATE_NEW_SPECTATOR");

            var mapPreview = lobby.GetWidget<MapPreviewWidget>("MAP_PREVIEW");
            mapPreview.IsVisible = () => Map != null;
            mapPreview.Map = () => Map;
            mapPreview.OnMouseDown = mi =>
            {
                var map = mapPreview.Map();
                if (map == null || mi.Button != MouseButton.Left
                    || orderManager.LocalClient.State == Session.ClientState.Ready)
                    return;

                var p = map.SpawnPoints
                    .Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(map, sp), i))
                    .Where(a => (a.First - mi.Location).LengthSquared < 64)
                    .Select(a => a.Second + 1)
                    .FirstOrDefault();

                var owned = orderManager.LobbyInfo.Clients.Any(c => c.SpawnPoint == p);
                if (p == 0 || !owned)
                    orderManager.IssueOrder(Order.Command("spawn {0} {1}".F(orderManager.LocalClient.Index, p)));
            };

            var mapTitle = lobby.GetWidget<LabelWidget>("MAP_TITLE");
            mapTitle.IsVisible = () => Map != null;
            mapTitle.GetText = () => Map.Title;

            mapPreview.SpawnColors = () =>
            {
                var spawns = Map.SpawnPoints;
                var sc = new Dictionary<int2, Color>();

                for (int i = 1; i <= spawns.Count(); i++)
                {
                    var client = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.SpawnPoint == i);
                    if (client == null)
                        continue;
                    sc.Add(spawns.ElementAt(i - 1), client.ColorRamp.GetColor(0));
                }
                return sc;
            };

            CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
                .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Any");

            var mapButton = lobby.GetWidget<ButtonWidget>("CHANGEMAP_BUTTON");
            mapButton.OnClick = () =>
            {
                var onSelect = new Action<Map>(m =>
                {
                    orderManager.IssueOrder(Order.Command("map " + m.Uid));
                    Game.Settings.Server.Map = m.Uid;
                    Game.Settings.Save();
                });

                Widget.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", Map.Uid },
                    { "onExit", () => {} },
                    { "onSelect", onSelect }
                });
            };
            mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;

            var disconnectButton = lobby.GetWidget<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            var gameStarting = false;

            var allowCheats = lobby.GetWidget<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
            allowCheats.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null
                || orderManager.LocalClient.State == Session.ClientState.Ready;
            allowCheats.OnClick = () =>	orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));

            var startGameButton = lobby.GetWidget<ButtonWidget>("START_GAME_BUTTON");
            startGameButton.IsVisible = () => Game.IsHost;
            startGameButton.IsDisabled = () => gameStarting;
            startGameButton.OnClick = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            bool teamChat = false;
            var chatLabel = lobby.GetWidget<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.GetWidget<TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return true;
            };

            chatPanel = lobby.GetWidget<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.GetWidget("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            lobby.GetWidget<ButtonWidget>("MUSIC_BUTTON").OnClick = () =>
            {
                Widget.OpenWindow("MUSIC_PANEL", new WidgetArgs()
                {
                    { "onExit", () => {} },
                });
            };

            // Add a bot on the first lobbyinfo update
            if (addBots)
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot = orderManager.LobbyInfo.FirstEmptySlot();
                    var bot = Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    if (slot != null && bot != null)
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1}".F(slot, bot)));
                });
        }
Exemplo n.º 34
0
        internal LobbyLogic(Widget widget, World world, OrderManager orderManager,
			Action onExit, Action onStart, bool addBots)
        {
            var lobby = widget;
            this.orderManager = orderManager;
            this.OnGameStart = () => { CloseWindow(); onStart(); };
            this.onExit = onExit;

            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            Game.BeforeGameStart += OnGameStart;
            Game.AddChatLine += AddChatLine;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            UpdateCurrentMap();
            PlayerPalettePreview = world.WorldActor.Trait<ColorPickerPaletteModifier>();
            PlayerPalettePreview.Ramp = Game.Settings.Player.ColorRamp;
            Players = lobby.Get<ScrollPanelWidget>("PLAYERS");
            EditablePlayerTemplate = Players.Get("TEMPLATE_EDITABLE_PLAYER");
            NonEditablePlayerTemplate = Players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            EmptySlotTemplate = Players.Get("TEMPLATE_EMPTY");
            EditableSpectatorTemplate = Players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            NonEditableSpectatorTemplate = Players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            NewSpectatorTemplate = Players.Get("TEMPLATE_NEW_SPECTATOR");

            var mapPreview = lobby.Get<MapPreviewWidget>("MAP_PREVIEW");
            mapPreview.IsVisible = () => Map != null;
            mapPreview.Map = () => Map;
            mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
            mapPreview.SpawnColors = () => LobbyUtils.GetSpawnColors( orderManager, Map );

            var mapTitle = lobby.GetOrNull<LabelWidget>("MAP_TITLE");
            if (mapTitle != null)
            {
                mapTitle.IsVisible = () => Map != null;
                mapTitle.GetText = () => Map.Title;
            }

            CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
                .Where(c => c.Selectable)
                .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Any");

            var mapButton = lobby.Get<ButtonWidget>("CHANGEMAP_BUTTON");
            mapButton.OnClick = () =>
            {
                var onSelect = new Action<Map>(m =>
                {
                    orderManager.IssueOrder(Order.Command("map " + m.Uid));
                    Game.Settings.Server.Map = m.Uid;
                    Game.Settings.Save();
                });

                Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", Map.Uid },
                    { "onExit", () => {} },
                    { "onSelect", onSelect }
                });
            };
            mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            var gameStarting = false;

            var allowCheats = lobby.Get<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
            allowCheats.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null
                || orderManager.LocalClient.IsReady;
            allowCheats.OnClick = () =>	orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));

            var startGameButton = lobby.Get<ButtonWidget>("START_GAME_BUTTON");
            startGameButton.IsVisible = () => Game.IsHost;
            startGameButton.IsDisabled = () => gameStarting;
            startGameButton.OnClick = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            bool teamChat = false;
            var chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return true;
            };

            chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull<ButtonWidget>("MUSIC_BUTTON");
            if (musicButton != null)
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                    { { "onExit", () => {} } });

            // Add a bot on the first lobbyinfo update
            if (addBots)
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot = orderManager.LobbyInfo.FirstEmptySlot();
                    var bot = Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    if (slot != null && bot != null)
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1}".F(slot, bot)));
                });
        }
Exemplo n.º 35
0
        internal LobbyLogic(Widget widget, World world, OrderManager orderManager,
			Action onExit, Action onStart, bool addBots)
        {
            var lobby = widget;
            this.orderManager = orderManager;
            this.OnGameStart = () => { CloseWindow(); onStart(); };
            this.onExit = onExit;

            Game.LobbyInfoChanged += UpdateCurrentMap;
            Game.LobbyInfoChanged += UpdatePlayerList;
            Game.BeforeGameStart += OnGameStart;
            Game.AddChatLine += AddChatLine;
            Game.ConnectionStateChanged += ConnectionStateChanged;

            var name = lobby.GetOrNull<LabelWidget>("SERVER_NAME");
            if (name != null)
                name.GetText = () => orderManager.LobbyInfo.GlobalSettings.ServerName;

            UpdateCurrentMap();
            Players = lobby.Get<ScrollPanelWidget>("PLAYERS");
            EditablePlayerTemplate = Players.Get("TEMPLATE_EDITABLE_PLAYER");
            NonEditablePlayerTemplate = Players.Get("TEMPLATE_NONEDITABLE_PLAYER");
            EmptySlotTemplate = Players.Get("TEMPLATE_EMPTY");
            EditableSpectatorTemplate = Players.Get("TEMPLATE_EDITABLE_SPECTATOR");
            NonEditableSpectatorTemplate = Players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
            NewSpectatorTemplate = Players.Get("TEMPLATE_NEW_SPECTATOR");
            colorPreview = lobby.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
            colorPreview.Color = Game.Settings.Player.Color;

            var mapPreview = lobby.Get<MapPreviewWidget>("MAP_PREVIEW");
            mapPreview.IsVisible = () => Map != null;
            mapPreview.Map = () => Map;
            mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
            mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map);

            var mapTitle = lobby.GetOrNull<LabelWidget>("MAP_TITLE");
            if (mapTitle != null)
            {
                mapTitle.IsVisible = () => Map != null;
                mapTitle.GetText = () => Map.Title;
            }

            var mapType = lobby.GetOrNull<LabelWidget>("MAP_TYPE");
            if (mapType != null)
            {
                mapType.IsVisible = () => Map != null;
                mapType.GetText = () => Map.Type;
            }

            var mapAuthor = lobby.GetOrNull<LabelWidget>("MAP_AUTHOR");
            if (mapAuthor != null)
            {
                mapAuthor.IsVisible = () => Map != null;
                mapAuthor.GetText = () => "Created by {0}".F(Map.Author);
            }

            CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
                .Where(c => c.Selectable)
                .ToDictionary(a => a.Race, a => a.Name);
            CountryNames.Add("random", "Any");

            var gameStarting = false;

            var mapButton = lobby.Get<ButtonWidget>("CHANGEMAP_BUTTON");
            mapButton.OnClick = () =>
            {
                var onSelect = new Action<Map>(m =>
                {
                    orderManager.IssueOrder(Order.Command("map " + m.Uid));
                    Game.Settings.Server.Map = m.Uid;
                    Game.Settings.Save();
                });

                Ui.OpenWindow("MAPCHOOSER_PANEL", new WidgetArgs()
                {
                    { "initialMap", Map.Uid },
                    { "onExit", () => {} },
                    { "onSelect", onSelect }
                });
            };
            mapButton.IsVisible = () => mapButton.Visible && Game.IsHost;

            var assignTeams = lobby.GetOrNull<DropDownButtonWidget>("ASSIGNTEAMS_DROPDOWNBUTTON");
            if (assignTeams != null)
            {
                assignTeams.IsVisible = () => Game.IsHost;
                assignTeams.IsDisabled = () => gameStarting || orderManager.LobbyInfo.Clients.Count(c => c.Slot != null) < 2
                    || orderManager.LocalClient == null || orderManager.LocalClient.IsReady;

                assignTeams.OnMouseDown = _ =>
                {
                    var options = Enumerable.Range(2, orderManager.LobbyInfo.Clients.Count(c => c.Slot != null).Clamp(2, 8) - 1).Select(d => new DropDownOption
                    {
                        Title = "{0} Teams".F(d),
                        IsSelected = () => false,
                        OnClick = () => orderManager.IssueOrder(Order.Command("assignteams {0}".F(d.ToString())))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    assignTeams.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var disconnectButton = lobby.Get<ButtonWidget>("DISCONNECT_BUTTON");
            disconnectButton.OnClick = () => { CloseWindow(); onExit(); };

            var allowCheats = lobby.Get<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
            allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
            allowCheats.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null
                || orderManager.LocalClient.IsReady;
            allowCheats.OnClick = () =>	orderManager.IssueOrder(Order.Command(
                        "allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));

            var crates = lobby.GetOrNull<CheckboxWidget>("CRATES_CHECKBOX");
            if (crates != null)
            {
                crates.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.Crates;
                crates.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null
                    || orderManager.LocalClient.IsReady; // maybe disable the checkbox if a map forcefully removes CrateDrop?
                crates.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "crates {0}".F(!orderManager.LobbyInfo.GlobalSettings.Crates)));
            }

            var fragileAlliance = lobby.GetOrNull<CheckboxWidget>("FRAGILEALLIANCES_CHECKBOX");
            if (fragileAlliance != null)
            {
                fragileAlliance.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.FragileAlliances;
                fragileAlliance.IsDisabled = () => !Game.IsHost || gameStarting
                    || orderManager.LocalClient == null	|| orderManager.LocalClient.IsReady;
                fragileAlliance.OnClick = () => orderManager.IssueOrder(Order.Command(
                    "fragilealliance {0}".F(!orderManager.LobbyInfo.GlobalSettings.FragileAlliances)));
            };

            var difficulty = lobby.GetOrNull<DropDownButtonWidget>("DIFFICULTY_DROPDOWNBUTTON");
            if (difficulty != null)
            {
                difficulty.IsVisible = () => Map != null && Map.Difficulties != null && Map.Difficulties.Any();
                difficulty.IsDisabled = () => !Game.IsHost || gameStarting || orderManager.LocalClient == null || orderManager.LocalClient.IsReady;
                difficulty.GetText = () => orderManager.LobbyInfo.GlobalSettings.Difficulty;
                difficulty.OnMouseDown = _ =>
                {
                    var options = Map.Difficulties.Select(d => new DropDownOption
                    {
                        Title = d,
                        IsSelected = () => orderManager.LobbyInfo.GlobalSettings.Difficulty == d,
                        OnClick = () => orderManager.IssueOrder(Order.Command("difficulty {0}".F(d)))
                    });
                    Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                    {
                        var item = ScrollItemWidget.Setup(template, option.IsSelected, option.OnClick);
                        item.Get<LabelWidget>("LABEL").GetText = () => option.Title;
                        return item;
                    };
                    difficulty.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", options.Count() * 30, options, setupItem);
                };
            }

            var startGameButton = lobby.Get<ButtonWidget>("START_GAME_BUTTON");
            startGameButton.IsVisible = () => Game.IsHost;
            startGameButton.IsDisabled = () => gameStarting
                || orderManager.LobbyInfo.Slots.Any(sl => sl.Value.Required && orderManager.LobbyInfo.ClientInSlot(sl.Key) == null);
            startGameButton.OnClick = () =>
            {
                gameStarting = true;
                orderManager.IssueOrder(Order.Command("startgame"));
            };

            bool teamChat = false;
            var chatLabel = lobby.Get<LabelWidget>("LABEL_CHATTYPE");
            var chatTextField = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");

            chatTextField.OnEnterKey = () =>
            {
                if (chatTextField.Text.Length == 0)
                    return true;

                orderManager.IssueOrder(Order.Chat(teamChat, chatTextField.Text));
                chatTextField.Text = "";
                return true;
            };

            chatTextField.OnTabKey = () =>
            {
                teamChat ^= true;
                chatLabel.Text = (teamChat) ? "Team:" : "Chat:";
                return true;
            };

            chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
            chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
            chatPanel.RemoveChildren();

            var musicButton = lobby.GetOrNull<ButtonWidget>("MUSIC_BUTTON");
            if (musicButton != null)
                musicButton.OnClick = () => Ui.OpenWindow("MUSIC_PANEL", new WidgetArgs
                    { { "onExit", () => {} } });

            // Add a bot on the first lobbyinfo update
            if (addBots)
                Game.LobbyInfoChanged += WidgetUtils.Once(() =>
                {
                    var slot = orderManager.LobbyInfo.FirstEmptySlot();
                    var bot = Rules.Info["player"].Traits.WithInterface<IBotInfo>().Select(t => t.Name).FirstOrDefault();
                    var botController = orderManager.LobbyInfo.Clients.Where(c => c.IsAdmin).FirstOrDefault();
                    if (slot != null && bot != null)
                        orderManager.IssueOrder(Order.Command("slot_bot {0} {1} {2}".F(slot, botController.Index, bot)));
                });
        }