From 33a4f5e29eae73603fadd8afdaf4eaa0b221707c Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 10 May 2011 17:29:32 +1200 Subject: [PATCH] Support loopback servers for solo play --- OpenRA.Game/Game.cs | 18 ++++++---- OpenRA.Game/GameRules/Settings.cs | 5 +-- OpenRA.Game/Server/Server.cs | 11 +++--- OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs | 36 +++++++------------ .../Widgets/CncServerCreationLogic.cs | 20 ++++++++--- .../Delegates/CreateServerMenuDelegate.cs | 5 +-- 6 files changed, 50 insertions(+), 45 deletions(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index a4542d7ea2..c7a96b1f04 100755 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -364,16 +364,20 @@ namespace OpenRA { return modData.ObjectCreator.CreateObject( name ); } - - public static void CreateServer(Settings settings, string map) + + public static void CreateServer(int port, string name, string map) { - server = new Server.Server(modData, settings, map); + server = new Server.Server(IPAddress.Any, port, name, Settings.Game.Mods, map, modData); } - - public static void CreateAndJoinServer(Settings settings, string map) + + public static void CreateLocalServer(string map) { - CreateServer(settings, map); - JoinServer(IPAddress.Loopback.ToString(), settings.Server.ListenPort); + server = new Server.Server(IPAddress.Loopback, + Game.Settings.Server.LoopbackPort, + "Skirmish Game", + Game.Settings.Game.Mods, + map, + modData); } public static bool IsCurrentWorld(World world) diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index a913ea7797..334571f6b2 100755 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -22,8 +22,9 @@ namespace OpenRA.GameRules public class ServerSettings { public string Name = "OpenRA Game"; - public int ListenPort = 1234; - public int ExternalPort = 1234; + public int LoopbackPort = 1234; // Port used for soloplay servers + public int ListenPort = 1234; // Port that we listen on + public int ExternalPort = 1234; // Router port that the master server forwards people to public bool AdvertiseOnline = true; public string MasterServer = "http://master.open-ra.org/"; public bool AllowCheats = false; diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index c6278203f4..64a7d47b7a 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -49,22 +49,21 @@ namespace OpenRA.Server shutdown = true; } - public Server(ModData modData, Settings settings, string map) + public Server(IPAddress ip, int port, string serverName, string[] mods, string map, ModData modData) { Log.AddChannel("server", "server.log"); - - listener = new TcpListener(IPAddress.Any, settings.Server.ListenPort); - Name = settings.Server.Name; + listener = new TcpListener(ip, port); + Name = serverName; randomSeed = (int)DateTime.Now.ToBinary(); ModData = modData; foreach (var trait in modData.Manifest.ServerTraits) ServerTraits.Add( modData.ObjectCreator.CreateObject(trait) ); - lobbyInfo = new Session( settings.Game.Mods ); + lobbyInfo = new Session( mods ); lobbyInfo.GlobalSettings.RandomSeed = randomSeed; lobbyInfo.GlobalSettings.Map = map; - lobbyInfo.GlobalSettings.ServerName = settings.Server.Name; + lobbyInfo.GlobalSettings.ServerName = serverName; foreach (var t in ServerTraits.WithInterface()) t.ServerStarted(this); diff --git a/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs index 5ea7bb0587..5587968fa3 100755 --- a/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/CncMenuLogic.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using OpenRA.FileFormats; +using System.Net; using OpenRA.Network; using OpenRA.Server; using OpenRA.Widgets; @@ -68,8 +69,8 @@ namespace OpenRA.Mods.Cnc.Widgets Menu = MenuType.None; Widget.OpenWindow("SERVERBROWSER_PANEL", new Dictionary() { - {"onExit", new Action(ReturnToMultiplayerMenu)}, - { "openLobby", new Action(() => OpenLobbyPanel(MenuType.Main)) } + { "onExit", new Action(() => ReturnToMenu(MenuType.Multiplayer)) }, + { "openLobby", new Action(() => OpenLobbyPanel(MenuType.Multiplayer)) } }); }; @@ -78,7 +79,7 @@ namespace OpenRA.Mods.Cnc.Widgets Menu = MenuType.None; Widget.OpenWindow("CREATESERVER_PANEL", new Dictionary() { - { "onExit", new Action(ReturnToMultiplayerMenu) }, + { "onExit", new Action(() => ReturnToMenu(MenuType.Multiplayer)) }, { "openLobby", new Action(() => OpenLobbyPanel(MenuType.Multiplayer)) } }); }; @@ -88,7 +89,7 @@ namespace OpenRA.Mods.Cnc.Widgets Menu = MenuType.None; Widget.OpenWindow("DIRECTCONNECT_PANEL", new Dictionary() { - { "onExit", new Action(ReturnToMultiplayerMenu) }, + { "onExit", new Action(() => ReturnToMenu(MenuType.Multiplayer)) }, { "openLobby", new Action(() => OpenLobbyPanel(MenuType.Multiplayer)) } }); }; @@ -103,9 +104,9 @@ namespace OpenRA.Mods.Cnc.Widgets settingsMenu.GetWidget("BACK_BUTTON").OnClick = () => Menu = MenuType.Main; } - void ReturnToMultiplayerMenu() + void ReturnToMenu(MenuType menu) { - Menu = MenuType.Multiplayer; + Menu = menu; Widget.CloseWindow(); } @@ -118,18 +119,10 @@ namespace OpenRA.Mods.Cnc.Widgets void OpenLobbyPanel(MenuType menu) { - // Quit the lobby: disconnect and restore menu - Action onLobbyClose = () => - { - Game.DisconnectOnly(); - Menu = menu; - Widget.CloseWindow(); - }; - Menu = MenuType.None; Game.OpenWindow("SERVER_LOBBY", new Dictionary() { - { "onExit", onLobbyClose }, + { "onExit", new Action(() => { Game.DisconnectOnly(); ReturnToMenu(menu); }) }, { "onStart", new Action(RemoveShellmapUI) } }); } @@ -138,14 +131,11 @@ namespace OpenRA.Mods.Cnc.Widgets { var map = Game.modData.AvailableMaps.FirstOrDefault(m => m.Value.Selectable).Key; - var settings = Game.Settings; - settings.Server.Name = "Skirmish Game"; - // TODO: we want to prevent binding a port altogether - settings.Server.ListenPort = 1234; - settings.Server.ExternalPort = 1234; - Game.CreateAndJoinServer(settings, map); - - OpenLobbyPanel(MenuType.Main); + Game.CreateLocalServer(map); + CncConnectingLogic.Connect(IPAddress.Loopback.ToString(), + Game.Settings.Server.LoopbackPort, + new Action(() => OpenLobbyPanel(MenuType.Main)), + new Action(() => ReturnToMenu(MenuType.Main))); } } } diff --git a/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs b/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs index 72a702f32e..9b71eb21cf 100644 --- a/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/CncServerCreationLogic.cs @@ -71,14 +71,24 @@ namespace OpenRA.Mods.Cnc.Widgets void CreateAndJoin() { - Game.Settings.Server.Name = panel.GetWidget("SERVER_NAME").Text; - Game.Settings.Server.ListenPort = int.Parse(panel.GetWidget("LISTEN_PORT").Text); - Game.Settings.Server.ExternalPort = int.Parse(panel.GetWidget("EXTERNAL_PORT").Text); + var name = panel.GetWidget("SERVER_NAME").Text; + int listenPort, externalPort; + if (!int.TryParse(panel.GetWidget("LISTEN_PORT").Text, out listenPort)) + listenPort = 1234; + + if (!int.TryParse(panel.GetWidget("EXTERNAL_PORT").Text, out externalPort)) + externalPort = 1234; + + // Save new settings + Game.Settings.Server.Name = name; + Game.Settings.Server.ListenPort = listenPort; + Game.Settings.Server.ExternalPort = externalPort; Game.Settings.Server.AdvertiseOnline = advertiseOnline; Game.Settings.Server.LastMap = map.Uid; Game.Settings.Save(); - - Game.CreateServer(Game.Settings, map.Uid); + + // Create and join the server + Game.CreateServer(listenPort, name, map.Uid); Widget.CloseWindow(); CncConnectingLogic.Connect(IPAddress.Loopback.ToString(), Game.Settings.Server.ListenPort, onCreate, onExit); } diff --git a/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs index f8adf5ec66..05c7f1b627 100644 --- a/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/CreateServerMenuDelegate.cs @@ -33,8 +33,9 @@ namespace OpenRA.Mods.RA.Widgets.Delegates settings.Server.ListenPort = int.Parse(cs.GetWidget("LISTEN_PORT").Text); settings.Server.ExternalPort = int.Parse(cs.GetWidget("EXTERNAL_PORT").Text); settings.Save(); - - Game.CreateAndJoinServer(settings, map); + + Game.CreateServer(settings.Server.ListenPort, settings.Server.Name, map); + Game.JoinServer(IPAddress.Loopback.ToString(), settings.Server.ListenPort); return true; };