Inheritance: IDisposable
示例#1
0
		// Listen for connection failures
		void ConnectionStateChanged(OrderManager om)
		{
			if (om.Connection.ConnectionState == ConnectionState.NotConnected)
			{
				// Show connection failed dialog
				CloseWindow();

				Action onConnect = () =>
				{
					Game.OpenWindow("SERVER_LOBBY", new WidgetArgs()
					{
						{ "onExit", onExit },
						{ "onStart", onStart },
						{ "skirmishMode", false }
					});
				};

				Action<string> onRetry = password => ConnectionLogic.Connect(om.Host, om.Port, password, onConnect, onExit);

				Ui.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
				{
					{ "orderManager", om },
					{ "onAbort", onExit },
					{ "onRetry", onRetry }
				});
			}
		}
示例#2
0
        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.GetWidget<LabelWidget>("LABEL").GetText = () => o.Title;
                return item;
            };

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem);
        }
示例#3
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);
		}
        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);
        }
示例#5
0
		public GameTimerLogic(Widget widget, OrderManager orderManager, World world)
		{
			var timer = widget.GetOrNull<LabelWidget>("GAME_TIMER");
			if (timer != null)
				timer.GetText = () => WidgetUtils.FormatTime(world.WorldTick);

			var status = widget.GetOrNull<LabelWidget>("GAME_TIMER_STATUS");
			if (status != null)
			{
				var startTick = Ui.LastTickTime;
				// Blink the status line
				status.IsVisible = () => (world.Paused || world.Timestep != Game.Timestep)
					&& (Ui.LastTickTime - startTick) / 1000 % 2 == 0;

				status.GetText = () =>
				{
					if (world.Paused || world.Timestep == 0)
						return "Paused";

					if (world.Timestep == 1)
						return "Max Speed";

					return "{0:F1}x Speed".F(Game.Timestep * 1f / world.Timestep);
				};
			}
		}
示例#6
0
        public ConnectionFailedLogic(Widget widget, OrderManager orderManager, Action onAbort, Action<string> onRetry)
        {
            var panel = widget;
            var abortButton = panel.Get<ButtonWidget>("ABORT_BUTTON");
            var retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");

            abortButton.Visible = onAbort != null;
            abortButton.OnClick = () => { Ui.CloseWindow(); onAbort(); };

            retryButton.Visible = onRetry != null;
            retryButton.OnClick = () =>
            {
                var password = passwordField != null && passwordField.IsVisible() ? passwordField.Text : orderManager.Password;

                Ui.CloseWindow();
                onRetry(password);
            };

            widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () =>
                "Could not connect to {0}:{1}".F(orderManager.Host, orderManager.Port);

            var connectionError = widget.Get<LabelWidget>("CONNECTION_ERROR");
            connectionError.GetText = () => orderManager.ServerError;

            passwordField = panel.GetOrNull<PasswordFieldWidget>("PASSWORD");
            if (passwordField != null)
            {
                passwordField.Text = orderManager.Password;
                passwordField.IsVisible = () => orderManager.AuthenticationFailed;
                var passwordLabel = widget.Get<LabelWidget>("PASSWORD_LABEL");
                passwordLabel.IsVisible = passwordField.IsVisible;
                passwordField.OnEnterKey = () => { retryButton.OnClick(); return true; };
                passwordField.OnEscKey = () => { abortButton.OnClick(); return true; };
            }

            passwordOffsetAdjusted = false;
            var connectionFailedTicker = panel.GetOrNull<LogicTickerWidget>("CONNECTION_FAILED_TICKER");
            if (connectionFailedTicker != null)
            {
                connectionFailedTicker.OnTick = () =>
                {
                    // Adjust the dialog once the AuthenticationError is parsed.
                    if (passwordField.IsVisible() && !passwordOffsetAdjusted)
                    {
                        var offset = passwordField.Bounds.Y - connectionError.Bounds.Y;
                        abortButton.Bounds.Y += offset;
                        retryButton.Bounds.Y += offset;
                        panel.Bounds.Height += offset;
                        panel.Bounds.Y -= offset / 2;

                        var background = panel.GetOrNull("CONNECTION_BACKGROUND");
                        if (background != null)
                            background.Bounds.Height += offset;

                        passwordOffsetAdjusted = true;
                    }
                };
            }
        }
示例#7
0
 public void RemoveHandlers(OrderManager orderManager)
 {
     if (!orderManager.GameStarted)
     {
         Game.ConnectionStateChanged -= RemoveHandlers;
         objectives.OnObjectivesUpdated -= UpdateObjectives;
     }
 }
示例#8
0
        public GameTimerLogic(Widget widget, OrderManager orderManager, World world)
        {
            var timer = widget.GetOrNull<LabelWidget>("GAME_TIMER");
            var status = widget.GetOrNull<LabelWidget>("GAME_TIMER_STATUS");
            var startTick = Ui.LastTickTime;

            Func<bool> shouldShowStatus = () => (world.Paused || world.Timestep != world.LobbyInfo.GlobalSettings.Timestep)
                && (Ui.LastTickTime - startTick) / 1000 % 2 == 0;

            Func<string> statusText = () =>
            {
                if (world.Paused || world.Timestep == 0)
                    return "Paused";

                if (world.Timestep == 1)
                    return "Max Speed";

                return "{0}% Speed".F(world.LobbyInfo.GlobalSettings.Timestep * 100 / world.Timestep);
            };

            if (timer != null)
            {
                // Timers in replays should be synced to the effective game time, not the playback time.
                var timestep = world.Timestep;
                if (world.IsReplay)
                {
                    GameSpeed speed;
                    var gameSpeeds = Game.ModData.Manifest.Get<GameSpeeds>();
                    if (gameSpeeds.Speeds.TryGetValue(world.LobbyInfo.GlobalSettings.GameSpeedType, out speed))
                        timestep = speed.Timestep;
                }

                timer.GetText = () =>
                {
                    if (status == null && shouldShowStatus())
                        return statusText();

                    return WidgetUtils.FormatTime(world.WorldTick, timestep);
                };
            }

            if (status != null)
            {
                // Blink the status line
                status.IsVisible = shouldShowStatus;
                status.GetText = statusText;
            }

            var percentage = widget.GetOrNull<LabelWidget>("GAME_TIMER_PERCENTAGE");
            if (percentage != null)
            {
                var connection = orderManager.Connection as ReplayConnection;
                if (connection != null && connection.TickCount != 0)
                    percentage.GetText = () => "({0}%)".F(orderManager.NetFrameNumber * 100 / connection.TickCount);
                else if (timer != null)
                    timer.Bounds.Width += percentage.Bounds.Width;
            }
        }
示例#9
0
        public ConnectionFailedLogic(Widget widget, OrderManager orderManager, Action onRetry, Action onAbort)
        {
            var panel = widget;
            panel.Get<ButtonWidget>("ABORT_BUTTON").OnClick = () => { Ui.CloseWindow(); onAbort(); };
            panel.Get<ButtonWidget>("RETRY_BUTTON").OnClick = () => { Ui.CloseWindow(); onRetry(); };

            widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () =>
                "Could not connect to {0}:{1}\n{2}".F(orderManager.Host, orderManager.Port, orderManager.ServerError);
        }
 protected ClientTooltipRegionWidget(ClientTooltipRegionWidget other)
     : base(other)
 {
     Template = other.Template;
     TooltipContainer = other.TooltipContainer;
     tooltipContainer = Lazy.New(() => Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
     orderManager = other.orderManager;
     clientIndex = other.clientIndex;
 }
 public static Dictionary<int2, Color> GetSpawnColors(OrderManager orderManager, Map map)
 {
     var spawns = map.GetSpawnPoints();
     return orderManager.LobbyInfo.Clients
         .Where( c => c.SpawnPoint != 0 )
         .ToDictionary(
             c => spawns[c.SpawnPoint - 1],
             c => c.ColorRamp.GetColor(0));
 }
示例#12
0
 public static Dictionary<int2, Session.Client> GetSpawnClients(OrderManager orderManager, Map map)
 {
     var spawns = map.GetSpawnPoints();
     return orderManager.LobbyInfo.Clients
         .Where(c => c.SpawnPoint != 0)
             .ToDictionary(
                 c => spawns[c.SpawnPoint - 1],
                 c => c);
 }
示例#13
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...");
        }
示例#14
0
        public GameTimerLogic(Widget widget, OrderManager orderManager, World world)
        {
            var timer = widget.GetOrNull<LabelWidget>("GAME_TIMER");
            var status = widget.GetOrNull<LabelWidget>("GAME_TIMER_STATUS");
            var startTick = Ui.LastTickTime;

            Func<bool> shouldShowStatus = () => (world.Paused || world.Timestep != world.LobbyInfo.GlobalSettings.Timestep)
                && (Ui.LastTickTime - startTick) / 1000 % 2 == 0;

            Func<string> statusText = () =>
            {
                if (world.Paused || world.Timestep == 0)
                    return "Paused";

                if (world.Timestep == 1)
                    return "Max Speed";

                return "{0}% Speed".F(world.LobbyInfo.GlobalSettings.Timestep * 100 / world.Timestep);
            };

            if (timer != null)
            {
                // Timers in replays should be synced to the effective game time, not the playback time.
                var timestep = world.Timestep;
                if (world.IsReplay)
                    timestep = world.WorldActor.Trait<MapOptions>().GameSpeed.Timestep;

                timer.GetText = () =>
                {
                    if (status == null && shouldShowStatus())
                        return statusText();

                    return WidgetUtils.FormatTime(world.WorldTick, timestep);
                };
            }

            if (status != null)
            {
                // Blink the status line
                status.IsVisible = shouldShowStatus;
                status.GetText = statusText;
            }

            var timerTooltip = timer as LabelWithTooltipWidget;
            if (timerTooltip != null)
            {
                var connection = orderManager.Connection as ReplayConnection;
                if (connection != null && connection.TickCount != 0)
                    timerTooltip.GetTooltipText = () => "{0}% complete".F(orderManager.NetFrameNumber * 100 / connection.TickCount);
                else
                    timerTooltip.GetTooltipText = null;
            }
        }
示例#15
0
        public static string GetExternalIP(int clientIndex, OrderManager orderManager)
        {
            var address = orderManager.LobbyInfo.ClientWithIndex(clientIndex).IpAddress;
            if (clientIndex == orderManager.LocalClient.Index && address == IPAddress.Loopback.ToString())
            {
                var externalIP = UPnP.GetExternalIP();
                if (externalIP != null)
                    address = externalIP.ToString();
            }

            return address;
        }
		public ProductionPaletteWidget(OrderManager orderManager, World world, WorldRenderer worldRenderer)
		{
			this.orderManager = orderManager;
			this.World = world;
			this.worldRenderer = worldRenderer;
			tooltipContainer = Exts.Lazy(() =>
				Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));

			cantBuild = new Animation(world, "clock");
			cantBuild.PlayFetchIndex("idle", () => 0);
			clock = new Animation(world, "clock");
		}
示例#17
0
        public BuildPaletteWidget(OrderManager orderManager, World world, WorldRenderer worldRenderer)
        {
            this.orderManager = orderManager;
            this.world = world;
            this.worldRenderer = worldRenderer;

            cantBuild = new Animation(world, "clock");
            cantBuild.PlayFetchIndex("idle", () => 0);
            clock = new Animation(world, "clock");
            VisibleQueues = new List<ProductionQueue>();
            CurrentQueue = null;
        }
示例#18
0
        public static string GetExternalIP(int clientIndex, OrderManager orderManager)
        {
            var client = orderManager.LobbyInfo.ClientWithIndex(clientIndex);
            var address = client != null ? client.IpAddress : "";
            var lc = orderManager.LocalClient;
            if (lc != null && lc.Index == clientIndex && address == IPAddress.Loopback.ToString())
            {
                var externalIP = UPnP.ExternalIP;
                if (externalIP != null)
                    address = externalIP.ToString();
            }

            return address;
        }
示例#19
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);
		}
示例#20
0
        public GameTimerLogic(Widget widget, OrderManager orderManager, World world)
        {
            var timer = widget.GetOrNull<LabelWidget>("GAME_TIMER");
            var status = widget.GetOrNull<LabelWidget>("GAME_TIMER_STATUS");
            var startTick = Ui.LastTickTime;

            Func<bool> shouldShowStatus = () => (world.Paused || world.Timestep != Game.Timestep)
                && (Ui.LastTickTime - startTick) / 1000 % 2 == 0;

            Func<string> statusText = () =>
            {
                if (world.Paused || world.Timestep == 0)
                    return "Paused";

                if (world.Timestep == 1)
                    return "Max Speed";

                return "{0}% Speed".F(Game.Timestep * 100 / world.Timestep);
            };

            if (timer != null)
            {
                timer.GetText = () =>
                {
                    if (status == null && shouldShowStatus())
                        return statusText();

                    return WidgetUtils.FormatTime(world.WorldTick);
                };
            }

            if (status != null)
            {
                // Blink the status line
                status.IsVisible = shouldShowStatus;
                status.GetText = statusText;
            }

            var percentage = widget.GetOrNull<LabelWidget>("GAME_TIMER_PERCENTAGE");
            if (percentage != null)
            {
                var connection = orderManager.Connection as ReplayConnection;
                if (connection != null && connection.TickCount != 0)
                    percentage.GetText = () => "({0}%)".F(orderManager.NetFrameNumber * 100 / connection.TickCount);
                else
                    timer.Bounds.Width += percentage.Bounds.Width;
            }
        }
示例#21
0
        public DisconnectWatcherLogic(Widget widget, OrderManager orderManager)
        {
            var disconnected = false;
            widget.Get<LogicTickerWidget>("DISCONNECT_WATCHER").OnTick = () =>
            {
                if (disconnected || orderManager.Connection.ConnectionState != ConnectionState.NotConnected)
                    return;

                Game.RunAfterTick(() => Ui.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs {
                    { "orderManager", orderManager },
                    { "onAbort", null },
                    { "onRetry", null }
                }));

                disconnected = true;
            };
        }
示例#22
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);
        }
示例#23
0
		void ConnectionStateChanged(OrderManager om)
		{
			if (om.Connection.ConnectionState == ConnectionState.Connected)
			{
				CloseWindow();
				onConnect();
			}
			else if (om.Connection.ConnectionState == ConnectionState.NotConnected)
			{
				CloseWindow();
				Ui.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
				{
					{ "orderManager", om },
					{ "onAbort", onAbort },
					{ "onRetry", onRetry }
				});
			}
		}
示例#24
0
		void SetupProductionGroupButton(OrderManager orderManager, ProductionTypeButtonWidget button)
		{
			if (button == null)
				return;

			// Classic production queues are initialized at game start, and then never change.
			var queues = world.LocalPlayer.PlayerActor.TraitsImplementing<ProductionQueue>()
				.Where(q => q.Info.Type == button.ProductionGroup)
				.ToArray();

			Action<bool> selectTab = reverse =>
			{
				palette.CurrentQueue = queues.FirstOrDefault(q => q.Enabled);

				// When a tab is selected, scroll to the top because the current row position may be invalid for the new tab
				palette.ScrollToTop();

				// Attempt to pick up a completed building (if there is one) so it can be placed
				palette.PickUpCompletedBuilding();
			};

			Func<ButtonWidget, Hotkey> getKey = _ => Hotkey.Invalid;
			if (!string.IsNullOrEmpty(button.HotkeyName))
			{
				var ks = Game.Settings.Keys;
				var field = ks.GetType().GetField(button.HotkeyName);
				if (field != null)
					getKey = _ => (Hotkey)field.GetValue(ks);
			}

			button.IsDisabled = () => !queues.Any(q => q.BuildableItems().Any());
			button.OnMouseUp = mi => selectTab(mi.Modifiers.HasModifier(Modifiers.Shift));
			button.OnKeyPress = e => selectTab(e.Modifiers.HasModifier(Modifiers.Shift));
			button.OnClick = () => selectTab(false);
			button.IsHighlighted = () => queues.Contains(palette.CurrentQueue);
			button.GetKey = getKey;

			var chromeName = button.ProductionGroup.ToLowerInvariant();
			var icon = button.Get<ImageWidget>("ICON");
			icon.GetImageName = () => button.IsDisabled() ? chromeName + "-disabled" :
				queues.Any(q => q.CurrentDone) ? chromeName + "-alert" : chromeName;
		}
示例#25
0
        public ClientTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, OrderManager orderManager, int clientIndex)
        {
            var admin = widget.Get<LabelWidget>("ADMIN");
            var adminFont = Game.Renderer.Fonts[admin.Font];

            var latency = widget.Get<LabelWidget>("LATENCY");
            var latencyFont = Game.Renderer.Fonts[latency.Font];

            var ip = widget.Get<LabelWidget>("IP");
            var ipFont = Game.Renderer.Fonts[ip.Font];

            var ipOffset = ip.Bounds.Y;
            var latencyOffset = latency.Bounds.Y;
            var tooltipHeight = widget.Bounds.Height;

            var margin = widget.Bounds.Width;

            tooltipContainer.IsVisible = () => (orderManager.LobbyInfo.ClientWithIndex(clientIndex) != null);
            tooltipContainer.BeforeRender = () =>
            {
                var width = Math.Max(adminFont.Measure(admin.GetText()).X, Math.Max(ipFont.Measure(ip.GetText()).X, latencyFont.Measure(latency.GetText()).X));
                widget.Bounds.Width = width + 2*margin;
                latency.Bounds.Width = widget.Bounds.Width;
                ip.Bounds.Width = widget.Bounds.Width;
                admin.Bounds.Width = widget.Bounds.Width;

                ip.Bounds.Y = ipOffset;
                latency.Bounds.Y = latencyOffset;
                widget.Bounds.Height = tooltipHeight;

                if (admin.IsVisible())
                {
                    ip.Bounds.Y += admin.Bounds.Height;
                    latency.Bounds.Y += admin.Bounds.Height;
                    widget.Bounds.Height += admin.Bounds.Height;
                }
            };

            admin.IsVisible = () => orderManager.LobbyInfo.ClientWithIndex(clientIndex).IsAdmin;
            latency.GetText = () => "Latency: {0}".F(LobbyUtils.LatencyDescription(orderManager.LobbyInfo.ClientWithIndex(clientIndex).Latency));
            ip.GetText = () => LobbyUtils.DescriptiveIpAddress(orderManager.LobbyInfo.ClientWithIndex(clientIndex).IpAddress);
        }
        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();
        }
        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)));
            }
        }
示例#28
0
 void ConnectionStateChanged(OrderManager om)
 {
     if (om.Connection.ConnectionState == ConnectionState.Connected)
     {
         CloseWindow();
         onConnect();
     }
     else if (om.Connection.ConnectionState == ConnectionState.NotConnected)
     {
         // Show connection failed dialog
         CloseWindow();
         Widget.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
         {
             { "onAbort", onAbort },
             { "onRetry", onRetry },
             { "host", host },
             { "port", port }
         });
     }
 }
示例#29
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;

                order.Player.SetStance(targetPlayer, newStance);

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

                // automatically declare war reciprocally
                if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
                {
                    targetPlayer.SetStance(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;
            }
            }
        }
示例#30
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, 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":
            {
                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.Mod;
                var request = HandshakeRequest.Deserialize(order.TargetString);

                ModMetadata serverMod;
                if (request.Mod != mod.Id &&
                    ModMetadata.AllMods.TryGetValue(request.Mod, out serverMod) &&
                    serverMod.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.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;

                order.Player.SetStance(targetPlayer, newStance);

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

                // automatically declare war reciprocally
                if (newStance == Stance.Enemy && targetPlayer.Stances[order.Player] == Stance.Ally)
                {
                    targetPlayer.SetStance(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;
                    if (!self.IsDead)
                    {
                        foreach (var t in self.TraitsImplementing <IResolveOrder>())
                        {
                            t.ResolveOrder(self, order);
                        }
                    }
                }

                break;
            }
            }
        }
示例#31
0
 internal ChatEntryWidget( [ObjectCreator.Param] OrderManager orderManager )
 {
     this.orderManager = orderManager;
 }
示例#32
0
 static void StopMusic(OrderManager orderManager)
 {
     if (!orderManager.GameStarted)
     {
         Sound.StopMusic();
         Game.ConnectionStateChanged -= StopMusic;
     }
 }
示例#33
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, 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";
                    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;
            }
            }
        }