From ebe9805e5b32498bb87271d56f43e8d78edc4f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Thu, 18 Apr 2013 00:02:14 +0200 Subject: [PATCH] separate UPnP from Game/Server into it's own class --- OpenRA.Game/Game.cs | 102 ++--------------------- OpenRA.Game/Network/UPnP.cs | 146 +++++++++++++++++++++++++++++++++ OpenRA.Game/OpenRA.Game.csproj | 1 + OpenRA.Game/Server/Server.cs | 42 +--------- 4 files changed, 155 insertions(+), 136 deletions(-) create mode 100644 OpenRA.Game/Network/UPnP.cs diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 1efa2152d3..4383978ed9 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -21,10 +21,6 @@ using OpenRA.Network; using OpenRA.Support; using OpenRA.Widgets; -using Mono.Nat; -using Mono.Nat.Pmp; -using Mono.Nat.Upnp; - using XRandom = OpenRA.Thirdparty.Random; namespace OpenRA @@ -38,8 +34,6 @@ namespace OpenRA public static ModData modData; static WorldRenderer worldRenderer; - public static INatDevice natDevice; - public static Viewport viewport; public static Settings Settings; @@ -266,24 +260,7 @@ namespace OpenRA Log.AddChannel("server", "server.log"); if (Settings.Server.DiscoverNatDevices) - { - try - { - NatUtility.Logger = Log.Channels["server"].Writer; - NatUtility.Verbose = Settings.Server.VerboseNatDiscovery; - NatUtility.DeviceFound += DeviceFound; - NatUtility.DeviceLost += DeviceLost; - Settings.Server.NatDeviceAvailable = false; - NatUtility.StartDiscovery(); - Log.Write("server", "NAT discovery started."); - } - catch (Exception e) - { - Log.Write("server", "Can't discover UPnP-enabled device: {0}", e); - Settings.Server.NatDeviceAvailable = false; - Settings.Server.AllowPortForward = false; - } - } + UPnP.TryNatDiscovery(); else { Settings.Server.NatDeviceAvailable = false; @@ -304,80 +281,11 @@ namespace OpenRA if (Settings.Server.DiscoverNatDevices) { RunAfterDelay(Settings.Server.NatDiscoveryTimeout, () => - { - Log.Write("server", "Stopping NAT discovery."); - - try - { - NatUtility.StopDiscovery(); - } - catch (Exception e) - { - Log.Write("server", "Failed to stop NAT device discovery: {0}", e); - Settings.Server.NatDeviceAvailable = false; - Settings.Server.AllowPortForward = false; - } - - if (natDevice == null) - { - Log.Write("server", "No NAT devices with UPnP enabled found within {0} ms deadline. Disabling automatic port forwarding.".F(Settings.Server.NatDiscoveryTimeout)); - Settings.Server.NatDeviceAvailable = false; - Settings.Server.AllowPortForward = false; - } - }); + UPnP.TryStoppingNatDiscovery() + ); } } - public static void DeviceFound(object sender, DeviceEventArgs args) - { - if (args.Device == null) - return; - - Log.Write("server", "NAT device discovered."); - - Settings.Server.NatDeviceAvailable = true; - Settings.Server.AllowPortForward = true; - - try - { - natDevice = args.Device; - Log.Write("server", "Type: {0}", natDevice.GetType()); - Log.Write("server", "Your external IP is: {0}", natDevice.GetExternalIP()); - - foreach (var mp in natDevice.GetAllMappings()) - Log.Write("server", "Existing port mapping: protocol={0}, public={1}, private={2}", - mp.Protocol, mp.PublicPort, mp.PrivatePort); - } - catch (Exception e) - { - Log.Write("server", "Can't fetch information from NAT device: {0}", e); - - Settings.Server.NatDeviceAvailable = false; - Settings.Server.AllowPortForward = false; - } - } - - public static void DeviceLost(object sender, DeviceEventArgs args) - { - Log.Write("server", "NAT device lost."); - - if (args.Device == null) - return; - - try - { - natDevice = args.Device; - Log.Write("server", "Type: {0}", natDevice.GetType()); - } - catch (Exception e) - { - Log.Write("server", "Can't fetch type from lost NAT device: {0}", e); - } - - Settings.Server.NatDeviceAvailable = false; - Settings.Server.AllowPortForward = false; - } - public static void InitializeWithMods(string[] mods) { // Clear static state if we have switched mods @@ -524,7 +432,7 @@ namespace OpenRA public static void CreateServer(ServerSettings settings) { server = new Server.Server(new IPEndPoint(IPAddress.Any, settings.ListenPort), - Game.Settings.Game.Mods, settings, modData, natDevice); + Game.Settings.Game.Mods, settings, modData); } public static int CreateLocalServer(string map) @@ -541,7 +449,7 @@ namespace OpenRA settings.AllowPortForward = false; server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0), - Game.Settings.Game.Mods, settings, modData, natDevice); + Game.Settings.Game.Mods, settings, modData); return server.Port; } diff --git a/OpenRA.Game/Network/UPnP.cs b/OpenRA.Game/Network/UPnP.cs new file mode 100644 index 0000000000..4252a86af3 --- /dev/null +++ b/OpenRA.Game/Network/UPnP.cs @@ -0,0 +1,146 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; + +using Mono.Nat; +using Mono.Nat.Pmp; +using Mono.Nat.Upnp; + +namespace OpenRA.Network +{ + class UPnP + { + public static INatDevice NatDevice; + + public static void TryNatDiscovery() + { + try + { + NatUtility.Logger = Log.Channels["server"].Writer; + NatUtility.Verbose = Game.Settings.Server.VerboseNatDiscovery; + NatUtility.DeviceFound += DeviceFound; + NatUtility.DeviceLost += DeviceLost; + Game.Settings.Server.NatDeviceAvailable = false; + NatUtility.StartDiscovery(); + Log.Write("server", "NAT discovery started."); + } + catch (Exception e) + { + Log.Write("server", "Can't discover UPnP-enabled device: {0}", e); + Game.Settings.Server.NatDeviceAvailable = false; + Game.Settings.Server.AllowPortForward = false; + } + } + + public static void TryStoppingNatDiscovery() + { + Log.Write("server", "Stopping NAT discovery."); + + try + { + NatUtility.StopDiscovery(); + } + catch (Exception e) + { + Log.Write("server", "Failed to stop NAT device discovery: {0}", e); + Game.Settings.Server.NatDeviceAvailable = false; + Game.Settings.Server.AllowPortForward = false; + } + + if (NatDevice == null) + { + Log.Write("server", "No NAT devices with UPnP enabled found within {0} ms deadline. Disabling automatic port forwarding.".F(Game.Settings.Server.NatDiscoveryTimeout)); + Game.Settings.Server.NatDeviceAvailable = false; + Game.Settings.Server.AllowPortForward = false; + } + } + + public static void DeviceFound(object sender, DeviceEventArgs args) + { + if (args.Device == null) + return; + + Log.Write("server", "NAT device discovered."); + + Game.Settings.Server.NatDeviceAvailable = true; + Game.Settings.Server.AllowPortForward = true; + + try + { + NatDevice = args.Device; + Log.Write("server", "Type: {0}", NatDevice.GetType()); + Log.Write("server", "Your external IP is: {0}", NatDevice.GetExternalIP()); + + foreach (var mp in NatDevice.GetAllMappings()) + Log.Write("server", "Existing port mapping: protocol={0}, public={1}, private={2}", + mp.Protocol, mp.PublicPort, mp.PrivatePort); + } + catch (Exception e) + { + Log.Write("server", "Can't fetch information from NAT device: {0}", e); + + Game.Settings.Server.NatDeviceAvailable = false; + Game.Settings.Server.AllowPortForward = false; + } + } + + public static void DeviceLost(object sender, DeviceEventArgs args) + { + Log.Write("server", "NAT device lost."); + + if (args.Device == null) + return; + + try + { + NatDevice = args.Device; + Log.Write("server", "Type: {0}", NatDevice.GetType()); + } + catch (Exception e) + { + Log.Write("server", "Can't fetch type from lost NAT device: {0}", e); + } + + Game.Settings.Server.NatDeviceAvailable = false; + Game.Settings.Server.AllowPortForward = false; + } + + public static void ForwardPort() + { + try + { + var mapping = new Mapping(Protocol.Tcp, Game.Settings.Server.ExternalPort, Game.Settings.Server.ListenPort); + NatDevice.CreatePortMap(mapping); + Log.Write("server", "Create port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort); + } + catch (Exception e) + { + Log.Write("server", "Can not forward ports via UPnP: {0}", e); + Game.Settings.Server.AllowPortForward = false; + } + } + + public static void RemovePortforward() + { + try + { + var mapping = new Mapping(Protocol.Tcp, Game.Settings.Server.ExternalPort, Game.Settings.Server.ListenPort); + NatDevice.DeletePortMap(mapping); + Log.Write("server", "Remove port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort); + } + catch (Exception e) + { + Log.Write("server", "Can not remove UPnP portforwarding rules: {0}", e); + Game.Settings.Server.AllowPortForward = false; + } + } + } +} \ No newline at end of file diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 670708792d..6cf977a09a 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -222,6 +222,7 @@ + diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index 5ade506ef9..ac37c9d75f 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -24,10 +24,6 @@ using OpenRA.Network; using XTimer = System.Timers.Timer; -using Mono.Nat; -using Mono.Nat.Pmp; -using Mono.Nat.Upnp; - namespace OpenRA.Server { public enum ServerState : int @@ -54,7 +50,6 @@ namespace OpenRA.Server public readonly IPAddress Ip; public readonly int Port; - public INatDevice NatDevice; int randomSeed; public readonly Thirdparty.Random Random = new Thirdparty.Random(); @@ -82,7 +77,7 @@ namespace OpenRA.Server t.GameEnded(this); } - public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData, INatDevice natDevice) + public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData) { Log.AddChannel("server", "server.log"); @@ -95,12 +90,11 @@ namespace OpenRA.Server Settings = settings; ModData = modData; - NatDevice = natDevice; randomSeed = (int)DateTime.Now.ToBinary(); if (Settings.AllowPortForward) - ForwardPort(); + UPnP.ForwardPort(); foreach (var trait in modData.Manifest.ServerTraits) ServerTraits.Add( modData.ObjectCreator.CreateObject(trait) ); @@ -158,7 +152,7 @@ namespace OpenRA.Server { EndGame(); if (Settings.AllowPortForward) - RemovePortforward(); + UPnP.RemovePortforward(); break; } } @@ -174,36 +168,6 @@ namespace OpenRA.Server } - void ForwardPort() - { - try - { - var mapping = new Mapping(Protocol.Tcp, Settings.ExternalPort, Settings.ListenPort); - NatDevice.CreatePortMap(mapping); - Log.Write("server", "Create port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort); - } - catch (Exception e) - { - Log.Write("server", "Can not forward ports via UPnP: {0}", e); - Settings.AllowPortForward = false; - } - } - - void RemovePortforward() - { - try - { - var mapping = new Mapping(Protocol.Tcp, Settings.ExternalPort, Settings.ListenPort); - NatDevice.DeletePortMap(mapping); - Log.Write("server", "Remove port mapping: protocol={0}, public={1}, private={2}", mapping.Protocol, mapping.PublicPort, mapping.PrivatePort); - } - catch (Exception e) - { - Log.Write("server", "Can not remove UPnP portforwarding rules: {0}", e); - Settings.AllowPortForward = false; - } - } - /* lobby rework TODO: * - "teams together" option for team games -- will eliminate most need * for manual spawnpoint choosing.