Merge pull request #2403 from Mailaender/mono-nat
Use Mono.Nat for UPnP port forwarding.
This commit is contained in:
3
Makefile
3
Makefile
@@ -1,7 +1,7 @@
|
||||
CSC = gmcs
|
||||
CSFLAGS = -nologo -warn:4 -debug:full -optimize- -codepage:utf8 -unsafe -warnaserror
|
||||
DEFINE = DEBUG;TRACE
|
||||
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll thirdparty/FuzzyLogicLibrary.dll
|
||||
COMMON_LIBS = System.dll System.Core.dll System.Drawing.dll System.Xml.dll thirdparty/ICSharpCode.SharpZipLib.dll thirdparty/FuzzyLogicLibrary.dll thirdparty/Mono.Nat.dll
|
||||
PHONY = core tools package all mods clean distclean dependencies
|
||||
|
||||
.SUFFIXES:
|
||||
@@ -258,6 +258,7 @@ install: all
|
||||
@$(INSTALL_PROGRAM) thirdparty/FuzzyLogicLibrary.dll $(INSTALL_DIR)
|
||||
@$(INSTALL_PROGRAM) thirdparty/SharpFont.dll $(INSTALL_DIR)
|
||||
@cp thirdparty/SharpFont.dll.config $(INSTALL_DIR)
|
||||
@$(INSTALL_PROGRAM) thirdparty/Mono.Nat.dll $(INSTALL_DIR)
|
||||
|
||||
@echo "#!/bin/sh" > openra
|
||||
@echo 'BINDIR=$$(dirname $$(readlink -f $$0))' >> openra
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenRA
|
||||
public static class Log
|
||||
{
|
||||
static string LogPathPrefix = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + Path.DirectorySeparatorChar;
|
||||
static Dictionary<string, ChannelInfo> channels = new Dictionary<string,ChannelInfo>();
|
||||
public static readonly Dictionary<string, ChannelInfo> Channels = new Dictionary<string, ChannelInfo>();
|
||||
|
||||
public static string LogPath
|
||||
{
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA
|
||||
|
||||
public static void AddChannel(string channelName, string baseFilename)
|
||||
{
|
||||
if (channels.ContainsKey(channelName)) return;
|
||||
if (Channels.ContainsKey(channelName)) return;
|
||||
|
||||
foreach (var filename in FilenamesForChannel(channelName, baseFilename))
|
||||
try
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA
|
||||
var writer = File.CreateText(filename);
|
||||
writer.AutoFlush = true;
|
||||
|
||||
channels.Add(channelName,
|
||||
Channels.Add(channelName,
|
||||
new ChannelInfo()
|
||||
{
|
||||
Filename = filename,
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA
|
||||
public static void Write(string channel, string format, params object[] args)
|
||||
{
|
||||
ChannelInfo info;
|
||||
if (!channels.TryGetValue(channel, out info))
|
||||
if (!Channels.TryGetValue(channel, out info))
|
||||
throw new Exception("Tried logging to non-existant channel " + channel);
|
||||
|
||||
info.Writer.WriteLine(format, args);
|
||||
|
||||
@@ -21,6 +21,10 @@ 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
|
||||
@@ -34,6 +38,8 @@ namespace OpenRA
|
||||
public static ModData modData;
|
||||
static WorldRenderer worldRenderer;
|
||||
|
||||
public static INatDevice natDevice;
|
||||
|
||||
public static Viewport viewport;
|
||||
public static Settings Settings;
|
||||
|
||||
@@ -257,6 +263,24 @@ namespace OpenRA
|
||||
Log.AddChannel("perf", "perf.log");
|
||||
Log.AddChannel("debug", "debug.log");
|
||||
Log.AddChannel("sync", "syncreport.log");
|
||||
Log.AddChannel("server", "server.log");
|
||||
|
||||
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.AllowUPnP = false;
|
||||
}
|
||||
|
||||
FileSystem.Mount("."); // Needed to access shaders
|
||||
Renderer.Initialize( Game.Settings.Graphics.Mode );
|
||||
@@ -268,6 +292,44 @@ namespace OpenRA
|
||||
|
||||
Sound.Create(Settings.Sound.Engine);
|
||||
InitializeWithMods(Settings.Game.Mods);
|
||||
|
||||
RunAfterDelay(Settings.Server.NatDiscoveryTimeout, () =>
|
||||
{
|
||||
NatUtility.StopDiscovery();
|
||||
Log.Write("server", "NAT discovery stopped.");
|
||||
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.AllowUPnP = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void DeviceFound(object sender, DeviceEventArgs args)
|
||||
{
|
||||
natDevice = args.Device;
|
||||
|
||||
Log.Write("server", "NAT device discovered.");
|
||||
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);
|
||||
|
||||
Settings.Server.NatDeviceAvailable = true;
|
||||
Settings.Server.AllowUPnP = true;
|
||||
}
|
||||
|
||||
public static void DeviceLost(object sender, DeviceEventArgs args)
|
||||
{
|
||||
natDevice = args.Device;
|
||||
|
||||
Log.Write("server", "NAT device lost.");
|
||||
Log.Write("server", "Type: {0}", natDevice.GetType());
|
||||
|
||||
Settings.Server.NatDeviceAvailable = false;
|
||||
Settings.Server.AllowUPnP = false;
|
||||
}
|
||||
|
||||
public static void InitializeWithMods(string[] mods)
|
||||
@@ -416,7 +478,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);
|
||||
Game.Settings.Game.Mods, settings, modData, natDevice);
|
||||
}
|
||||
|
||||
public static int CreateLocalServer(string map)
|
||||
@@ -433,7 +495,7 @@ namespace OpenRA
|
||||
settings.AllowUPnP = false;
|
||||
|
||||
server = new Server.Server(new IPEndPoint(IPAddress.Loopback, 0),
|
||||
Game.Settings.Game.Mods, settings, modData);
|
||||
Game.Settings.Game.Mods, settings, modData, natDevice);
|
||||
|
||||
return server.Port;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ namespace OpenRA.GameRules
|
||||
public int ExternalPort = 1234;
|
||||
public bool AdvertiseOnline = true;
|
||||
public string MasterServer = "http://master.open-ra.org/";
|
||||
public bool AllowUPnP = false;
|
||||
public bool AllowUPnP = true; // let the user disable it
|
||||
public bool NatDeviceAvailable = false; // internal check if discovery succeeded
|
||||
public int NatDiscoveryTimeout = 1000; // ms to search for UPnP enabled NATs
|
||||
public bool VerboseNatDiscovery = false; // print very detailed logs for debugging
|
||||
public bool AllowCheats = false;
|
||||
public string Map = null;
|
||||
public string[] Ban = null;
|
||||
@@ -49,6 +52,9 @@ namespace OpenRA.GameRules
|
||||
AdvertiseOnline = other.AdvertiseOnline;
|
||||
MasterServer = other.MasterServer;
|
||||
AllowUPnP = other.AllowUPnP;
|
||||
NatDeviceAvailable = other.NatDeviceAvailable;
|
||||
NatDiscoveryTimeout = other.NatDiscoveryTimeout;
|
||||
VerboseNatDiscovery = other.VerboseNatDiscovery;
|
||||
AllowCheats = other.AllowCheats;
|
||||
Map = other.Map;
|
||||
Ban = other.Ban;
|
||||
|
||||
@@ -60,8 +60,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
</Reference>
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
@@ -70,6 +69,12 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\thirdparty\SharpFont.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Mono.Nat, Version=1.1.0.0, Culture=neutral">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<Private>False</Private>
|
||||
<Package>mono.nat</Package>
|
||||
<HintPath>..\thirdparty\Mono.Nat.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Tao.OpenAl, Version=1.1.0.1, Culture=neutral, PublicKeyToken=a7579dda88828311">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\thirdparty\Tao\Tao.OpenAl.dll</HintPath>
|
||||
@@ -151,7 +156,6 @@
|
||||
<Compile Include="Server\Server.cs" />
|
||||
<Compile Include="Server\ServerOrder.cs" />
|
||||
<Compile Include="Server\TraitInterfaces.cs" />
|
||||
<Compile Include="Server\UPnP.cs" />
|
||||
<Compile Include="Sound.cs" />
|
||||
<Compile Include="Support\Arguments.cs" />
|
||||
<Compile Include="Support\PerfHistory.cs" />
|
||||
|
||||
@@ -16,14 +16,18 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Net.NetworkInformation;
|
||||
using UPnP;
|
||||
using System.Threading;
|
||||
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.GameRules;
|
||||
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
|
||||
@@ -50,6 +54,8 @@ namespace OpenRA.Server
|
||||
|
||||
public readonly IPAddress Ip;
|
||||
public readonly int Port;
|
||||
public INatDevice NatDevice;
|
||||
|
||||
int randomSeed;
|
||||
public readonly Thirdparty.Random Random = new Thirdparty.Random();
|
||||
|
||||
@@ -74,11 +80,9 @@ namespace OpenRA.Server
|
||||
{
|
||||
foreach (var t in ServerTraits.WithInterface<IEndGame>())
|
||||
t.GameEnded(this);
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
}
|
||||
|
||||
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData)
|
||||
public Server(IPEndPoint endpoint, string[] mods, ServerSettings settings, ModData modData, INatDevice natDevice)
|
||||
{
|
||||
Log.AddChannel("server", "server.log");
|
||||
|
||||
@@ -91,46 +95,12 @@ namespace OpenRA.Server
|
||||
|
||||
Settings = settings;
|
||||
ModData = modData;
|
||||
NatDevice = natDevice;
|
||||
|
||||
randomSeed = (int)DateTime.Now.ToBinary();
|
||||
|
||||
if (Settings.AllowUPnP)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (UPnP.NAT.Discover())
|
||||
{
|
||||
Log.Write("server", "UPnP-enabled router discovered.");
|
||||
Log.Write("server", "Your IP is: {0}", UPnP.NAT.GetExternalIP() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Write("server", "No UPnP-enabled router detected.");
|
||||
Settings.AllowUPnP = false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
OpenRA.Log.Write("server", "Can't discover UPnP-enabled routers: {0}", e);
|
||||
Settings.AllowUPnP = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.AllowUPnP)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (UPnP.NAT.ForwardPort(Port, ProtocolType.Tcp, "OpenRA"))
|
||||
Log.Write("server", "Port {0} (TCP) has been forwarded.", Port);
|
||||
else
|
||||
Settings.AllowUPnP = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
OpenRA.Log.Write("server", "Can not forward ports via UPnP: {0}", e);
|
||||
Settings.AllowUPnP = false;
|
||||
}
|
||||
}
|
||||
ForwardPort();
|
||||
|
||||
foreach (var trait in modData.Manifest.ServerTraits)
|
||||
ServerTraits.Add( modData.ObjectCreator.CreateObject<ServerTrait>(trait) );
|
||||
@@ -156,7 +126,7 @@ namespace OpenRA.Server
|
||||
var timeout = ServerTraits.WithInterface<ITick>().Min(t => t.TickTimeout);
|
||||
for( ; ; )
|
||||
{
|
||||
var checkRead = new ArrayList();
|
||||
var checkRead = new List<Socket>();
|
||||
checkRead.Add( listener.Server );
|
||||
foreach( var c in conns ) checkRead.Add( c.socket );
|
||||
foreach( var c in preConns ) checkRead.Add( c.socket );
|
||||
@@ -168,7 +138,7 @@ namespace OpenRA.Server
|
||||
break;
|
||||
}
|
||||
|
||||
foreach( Socket s in checkRead )
|
||||
foreach( var s in checkRead )
|
||||
if( s == listener.Server ) AcceptConnection();
|
||||
else if (preConns.Count > 0)
|
||||
{
|
||||
@@ -187,6 +157,8 @@ namespace OpenRA.Server
|
||||
if (State == ServerState.ShuttingDown)
|
||||
{
|
||||
EndGame();
|
||||
if (Settings.AllowUPnP)
|
||||
RemovePortforward();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -202,16 +174,33 @@ 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.AllowUPnP = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RemovePortforward()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (UPnP.NAT.DeleteForwardingRule(Port, ProtocolType.Tcp))
|
||||
Log.Write("server", "Port {0} (TCP) forwarding rules has been removed.", Port);
|
||||
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)
|
||||
catch (Exception e)
|
||||
{
|
||||
OpenRA.Log.Write("server", "Can not remove UPnP portforwarding rules: {0}", e);
|
||||
Log.Write("server", "Can not remove UPnP portforwarding rules: {0}", e);
|
||||
Settings.AllowUPnP = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2008-2009 http://www.codeproject.com/Members/Harold-Aptroot
|
||||
* Source: http://www.codeproject.com/Articles/27992/NAT-Traversal-with-UPnP-in-C
|
||||
* This file is licensed under A Public Domain dedication.
|
||||
* For more information, see http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
|
||||
namespace UPnP
|
||||
{
|
||||
public class NAT
|
||||
{
|
||||
static string _serviceUrl;
|
||||
|
||||
public static bool Discover()
|
||||
{
|
||||
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||||
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
|
||||
s.ReceiveTimeout = 3000; //3 seconds
|
||||
string req = "M-SEARCH * HTTP/1.1\r\n" +
|
||||
"HOST: 239.255.255.250:1900\r\n" +
|
||||
"ST:upnp:rootdevice\r\n" +
|
||||
"MAN:\"ssdp:discover\"\r\n" +
|
||||
"MX:3\r\n\r\n";
|
||||
byte[] data = Encoding.ASCII.GetBytes(req);
|
||||
IPEndPoint ipe = new IPEndPoint(IPAddress.Broadcast, 1900);
|
||||
byte[] buffer = new byte[0x1000];
|
||||
|
||||
try
|
||||
{
|
||||
s.SendTo(data, ipe);
|
||||
int length = 0;
|
||||
do
|
||||
{
|
||||
length = s.Receive(buffer);
|
||||
|
||||
string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower();
|
||||
if (resp.Contains("upnp:rootdevice"))
|
||||
{
|
||||
resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9);
|
||||
resp = resp.Substring(0, resp.IndexOf("\r")).Trim();
|
||||
if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp)))
|
||||
{
|
||||
s.Close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while (length > 0);
|
||||
s.Close();
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
s.Close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String GetServiceUrl(string resp)
|
||||
{
|
||||
XmlDocument desc = new XmlDocument();
|
||||
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(resp);
|
||||
r.KeepAlive = false;
|
||||
using (WebResponse wres = r.GetResponse())
|
||||
{
|
||||
using (Stream ress = wres.GetResponseStream())
|
||||
{
|
||||
desc.Load(ress);
|
||||
XmlNamespaceManager nsMgr = new XmlNamespaceManager(desc.NameTable);
|
||||
nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0");
|
||||
XmlNode typen = desc.SelectSingleNode("//tns:device/tns:deviceType/text()", nsMgr);
|
||||
if (!typen.Value.Contains("InternetGatewayDevice"))
|
||||
return null;
|
||||
XmlNode node = desc.SelectSingleNode("//tns:service[tns:serviceType=\"urn:schemas-upnp-org:service:WANIPConnection:1\"]/tns:controlURL/text()", nsMgr);
|
||||
if (node == null)
|
||||
return null;
|
||||
Uri respUri = new Uri(resp);
|
||||
Uri combinedUri = new Uri(respUri, node.Value);
|
||||
return combinedUri.AbsoluteUri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ForwardPort(int port, ProtocolType protocol, string description)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_serviceUrl))
|
||||
throw new Exception("No UPnP service available or Discover() has not been called");
|
||||
string body = String.Format("<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">"+
|
||||
"<NewRemoteHost></NewRemoteHost><NewExternalPort>{0}</NewExternalPort>"+
|
||||
"<NewProtocol>{1}</NewProtocol><NewInternalPort>{0}</NewInternalPort>" +
|
||||
"<NewInternalClient>{2}</NewInternalClient><NewEnabled>1</NewEnabled>" +
|
||||
"<NewPortMappingDescription>{3}</NewPortMappingDescription>"+
|
||||
"<NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping>",
|
||||
port, protocol.ToString().ToUpper(),Dns.GetHostAddresses(Dns.GetHostName())[0], description);
|
||||
if (SOAPRequest(_serviceUrl, body, "AddPortMapping") != null)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool DeleteForwardingRule(int port, ProtocolType protocol)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_serviceUrl))
|
||||
throw new Exception("No UPnP service available or Discover() has not been called");
|
||||
string body = String.Format("<u:DeletePortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
||||
"<NewRemoteHost></NewRemoteHost><NewExternalPort>{0}</NewExternalPort>"+
|
||||
"<NewProtocol>{1}</NewProtocol></u:DeletePortMapping>", port, protocol.ToString().ToUpper() );
|
||||
if (SOAPRequest(_serviceUrl, body, "DeletePortMapping") != null)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IPAddress GetExternalIP()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_serviceUrl))
|
||||
throw new Exception("No UPnP service available or Discover() has not been called");
|
||||
XmlDocument xdoc = SOAPRequest(_serviceUrl, "<u:GetExternalIPAddress xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" +
|
||||
"</u:GetExternalIPAddress>", "GetExternalIPAddress");
|
||||
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable);
|
||||
nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0");
|
||||
string IP = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr).Value;
|
||||
return IPAddress.Parse(IP);
|
||||
}
|
||||
|
||||
private static XmlDocument SOAPRequest(string url, string soap, string function)
|
||||
{
|
||||
string body = "<?xml version=\"1.0\"?>" +
|
||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" +
|
||||
"<s:Body>" +
|
||||
soap +
|
||||
"</s:Body>" +
|
||||
"</s:Envelope>";
|
||||
HttpWebRequest r = (HttpWebRequest)WebRequest.Create(url);
|
||||
r.KeepAlive = false;
|
||||
r.Method = "POST";
|
||||
byte[] b = Encoding.UTF8.GetBytes(body);
|
||||
r.Headers.Add("SOAPACTION", "\"urn:schemas-upnp-org:service:WANIPConnection:1#" + function + "\"");
|
||||
r.ContentType = "text/xml; charset=\"utf-8\"";
|
||||
r.ContentLength = b.Length;
|
||||
Stream newStream = r.GetRequestStream();
|
||||
newStream.Write(b, 0, b.Length);
|
||||
XmlDocument resp = new XmlDocument();
|
||||
using (WebResponse wres = r.GetResponse())
|
||||
{
|
||||
using (Stream ress = wres.GetResponseStream())
|
||||
{
|
||||
resp.Load(ress);
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
var UPnPCheckbox = panel.Get<CheckboxWidget>("UPNP_CHECKBOX");
|
||||
UPnPCheckbox.IsChecked = () => allowUPnP;
|
||||
UPnPCheckbox.OnClick = () => allowUPnP ^= true;
|
||||
UPnPCheckbox.IsDisabled = () => !Game.Settings.Server.NatDeviceAvailable;
|
||||
}
|
||||
|
||||
void CreateAndJoin()
|
||||
|
||||
@@ -75,7 +75,7 @@ Container@CREATESERVER_PANEL:
|
||||
Y:180
|
||||
Width:300
|
||||
Height:20
|
||||
Text:Allow UPnP port forwarding
|
||||
Text:Automatic port forwarding
|
||||
Label@EXTERNAL_PORT_LABEL:
|
||||
X:15
|
||||
Y:219
|
||||
|
||||
@@ -65,7 +65,7 @@ Background@CREATESERVER_BG:
|
||||
Y:165
|
||||
Width:300
|
||||
Height:20
|
||||
Text:Allow UPnP port forwarding
|
||||
Text:Automatic port forwarding
|
||||
Button@CREATE_BUTTON:
|
||||
X:130
|
||||
Y:PARENT_BOTTOM - 45
|
||||
|
||||
@@ -50,6 +50,9 @@ cp thirdparty/FuzzyLogicLibrary.dll packaging/built
|
||||
# SharpFont for FreeType support
|
||||
cp thirdparty/SharpFont* packaging/built
|
||||
|
||||
# Mono.NAT for UPnP support
|
||||
cp thirdparty/Mono.Nat.dll packaging/built
|
||||
|
||||
# Copy game icon for windows package
|
||||
cp OpenRA.Game/OpenRA.ico packaging/built
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ Section "Client" Client
|
||||
File "${SRCDIR}\OpenRA.Renderer.Null.dll"
|
||||
File "${SRCDIR}\ICSharpCode.SharpZipLib.dll"
|
||||
File "${SRCDIR}\FuzzyLogicLibrary.dll"
|
||||
File "${SRCDIR}\Mono.Nat.dll"
|
||||
File "${SRCDIR}\COPYING"
|
||||
File "${SRCDIR}\HACKING"
|
||||
File "${SRCDIR}\INSTALL"
|
||||
@@ -91,13 +92,13 @@ Section "Client" Client
|
||||
File "${SRCDIR}\OpenRA.ico"
|
||||
File "${SRCDIR}\Tao.*.dll"
|
||||
File "${SRCDIR}\SharpFont.*.dll"
|
||||
|
||||
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\OpenRA.lnk" $OUTDIR\OpenRA.Game.exe "" \
|
||||
"$OUTDIR\OpenRA.Game.exe" "" "" "" ""
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
|
||||
|
||||
SetOutPath "$INSTDIR\cg"
|
||||
File "${SRCDIR}\cg\*.fx"
|
||||
SetOutPath "$INSTDIR\glsl"
|
||||
@@ -263,6 +264,7 @@ Function ${UN}Clean
|
||||
Delete $INSTDIR\OpenRA.Renderer.SdlCommon.dll
|
||||
Delete $INSTDIR\ICSharpCode.SharpZipLib.dll
|
||||
Delete $INSTDIR\FuzzyLogicLibrary.dll
|
||||
Delete $INSTDIR\Mono.Nat.dll
|
||||
Delete $INSTDIR\Tao.*.dll
|
||||
Delete $INSTDIR\SharpFont.*.dll
|
||||
Delete $INSTDIR\COPYING
|
||||
|
||||
BIN
thirdparty/Mono.Nat.dll
vendored
Normal file
BIN
thirdparty/Mono.Nat.dll
vendored
Normal file
Binary file not shown.
Reference in New Issue
Block a user