diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 422edf20f6..b3afb462a6 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -86,10 +86,16 @@ namespace OpenRA public const int Timestep = 40; public const int TimestepJankThreshold = 250; // Don't catch up for delays larger than 250ms + public static event Action OnRemoteDirectConnect = (a, b) => { }; public static event Action ConnectionStateChanged = _ => { }; static ConnectionState lastConnectionState = ConnectionState.PreConnecting; public static int LocalClientId { get { return orderManager.Connection.LocalClientId; } } + public static void RemoteDirectConnect(string host, int port) + { + OnRemoteDirectConnect(host, port); + } + // Hacky workaround for orderManager visibility public static Widget OpenWindow(World world, string widget) { @@ -261,6 +267,9 @@ namespace OpenRA LobbyInfoChanged = () => { }; ConnectionStateChanged = om => { }; BeforeGameStart = () => { }; + OnRemoteDirectConnect = (a, b) => { }; + delayedActions = new ActionQueue(); + Ui.ResetAll(); if (worldRenderer != null) diff --git a/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs b/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs index 1649fc3986..a8fcaa3e1a 100644 --- a/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs +++ b/OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.Linq; using OpenRA.FileSystem; using OpenRA.Widgets; +using OpenRA.Mods.Common.Widgets.Logic; namespace OpenRA.Mods.Common.LoadScreens { @@ -57,6 +58,23 @@ namespace OpenRA.Mods.Common.LoadScreens return; } + // Join a server directly + var connect = args != null ? args.GetValue("Launch.Connect", null) : null; + if (!string.IsNullOrEmpty(connect)) + { + var parts = connect.Split(':'); + + if (parts.Length == 2) + { + var host = parts[0]; + var port = Exts.ParseIntegerInvariant(parts[1]); + Game.LoadShellMap(); + Game.RemoteDirectConnect(host, port); + return; + } + } + + // Load a replay directly var replay = args != null ? args.GetValue("Launch.Replay", null) : null; if (!string.IsNullOrEmpty(replay)) { diff --git a/OpenRA.Mods.RA/Widgets/Logic/MainMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/MainMenuLogic.cs index 43d78833cf..d037ee8bf3 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/MainMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/MainMenuLogic.cs @@ -48,7 +48,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic Ui.OpenWindow("SERVERBROWSER_PANEL", new WidgetArgs { { "onStart", RemoveShellmapUI }, - { "onExit", () => menuType = MenuType.Main } + { "onExit", () => menuType = MenuType.Main }, + { "directConnectHost", null }, + { "directConnectPort", 0 }, }); }; @@ -173,6 +175,18 @@ namespace OpenRA.Mods.RA.Widgets.Logic newsButton.IsHighlighted = () => newsHighlighted && Game.LocalTick % 50 < 25; } + + Game.OnRemoteDirectConnect += (host, port) => + { + menuType = MenuType.None; + Ui.OpenWindow("SERVERBROWSER_PANEL", new WidgetArgs + { + { "onStart", RemoveShellmapUI }, + { "onExit", () => menuType = MenuType.Main }, + { "directConnectHost", host }, + { "directConnectPort", port }, + }); + }; } void SetNewsStatus(string message) diff --git a/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs index 114f823c0e..96bf17574f 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ServerBrowserLogic.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic } [ObjectCreator.UseCtor] - public ServerBrowserLogic(Widget widget, Action onStart, Action onExit) + public ServerBrowserLogic(Widget widget, Action onStart, Action onExit, string directConnectHost, int directConnectPort) { panel = widget; this.onStart = onStart; @@ -116,6 +116,18 @@ namespace OpenRA.Mods.RA.Widgets.Logic } RefreshServerList(); + + if (directConnectHost != null) + { + // The connection window must be opened at the end of the tick for the widget hierarchy to + // work out, but we also want to prevent the server browser from flashing visible for one tick. + widget.Visible = false; + Game.RunAfterTick(() => + { + ConnectionLogic.Connect(directConnectHost, directConnectPort, "", OpenLobby, DoNothing); + widget.Visible = true; + }); + } } void RefreshServerList()