Added automatically port forwarding using UPnP
This commit is contained in:
parent
18da9a5978
commit
3fd4955faf
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using UnityEngine.Networking;
|
using UnityEngine.Networking;
|
||||||
|
|
||||||
@ -27,6 +28,8 @@ namespace MLAPI
|
|||||||
//Should only be used for dedicated servers and will require the servers RSA keypair being hard coded into clients in order to exchange a AES key
|
//Should only be used for dedicated servers and will require the servers RSA keypair being hard coded into clients in order to exchange a AES key
|
||||||
//TODO
|
//TODO
|
||||||
public bool EncryptMessages = false;
|
public bool EncryptMessages = false;
|
||||||
|
public bool UseUPnP = true;
|
||||||
|
public Action<bool, IPAddress> UPnPCompleteCallback;
|
||||||
|
|
||||||
//Cached config hash
|
//Cached config hash
|
||||||
private byte[] ConfigHash = null;
|
private byte[] ConfigHash = null;
|
||||||
|
86
MLAPI/Helper/UPnPHelper.cs
Normal file
86
MLAPI/Helper/UPnPHelper.cs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
using Open.Nat;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace MLAPI.Helper
|
||||||
|
{
|
||||||
|
public class UPnPHelper
|
||||||
|
{
|
||||||
|
internal static void AttemptPortMap(int port, Action<bool, IPAddress> callback)
|
||||||
|
{
|
||||||
|
bool invoked = false;
|
||||||
|
NatDiscoverer nat = new NatDiscoverer();
|
||||||
|
CancellationTokenSource cts = new CancellationTokenSource();
|
||||||
|
cts.CancelAfter(10000);
|
||||||
|
|
||||||
|
NatDevice device = null;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Task<NatDevice> natTask = nat.DiscoverDeviceAsync(PortMapper.Upnp, cts);
|
||||||
|
Mapping tcpMapping = new Mapping(Protocol.Tcp, port, port, 0, Application.productName + " (TCP)");
|
||||||
|
Mapping udpMapping = new Mapping(Protocol.Udp, port, port, 0, Application.productName + " (UDP)");
|
||||||
|
IPAddress publicIPAddress = null;
|
||||||
|
natTask.ContinueWith(tt =>
|
||||||
|
{
|
||||||
|
device = tt.Result;
|
||||||
|
device.GetExternalIPAsync()
|
||||||
|
.ContinueWith(task =>
|
||||||
|
{
|
||||||
|
publicIPAddress = task.Result;
|
||||||
|
return device.CreatePortMapAsync(udpMapping);
|
||||||
|
})
|
||||||
|
.Unwrap()
|
||||||
|
.ContinueWith(task =>
|
||||||
|
{
|
||||||
|
return device.CreatePortMapAsync(udpMapping);
|
||||||
|
})
|
||||||
|
.Unwrap()
|
||||||
|
.ContinueWith(task =>
|
||||||
|
{
|
||||||
|
return device.GetAllMappingsAsync();
|
||||||
|
})
|
||||||
|
.Unwrap()
|
||||||
|
.ContinueWith(task =>
|
||||||
|
{
|
||||||
|
Mapping[] mappings = task.Result.ToArray();
|
||||||
|
if(mappings.Length == 0)
|
||||||
|
{
|
||||||
|
if (!invoked)
|
||||||
|
callback(false, publicIPAddress);
|
||||||
|
invoked = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mappings.Length; i++)
|
||||||
|
{
|
||||||
|
if(mappings[i].PrivatePort == port)
|
||||||
|
{
|
||||||
|
if (!invoked)
|
||||||
|
callback(true, publicIPAddress);
|
||||||
|
invoked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
natTask.Wait();
|
||||||
|
}
|
||||||
|
catch (AggregateException e)
|
||||||
|
{
|
||||||
|
if (e.InnerException is NatDeviceNotFoundException)
|
||||||
|
{
|
||||||
|
if (!invoked)
|
||||||
|
callback(false, publicIPAddress);
|
||||||
|
invoked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,8 +32,14 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="Open.Nat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f22a6a4582336c76, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Open.NAT.2.1.0.0\lib\net35\Open.Nat.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Threading, Version=1.0.2856.102, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Open.NAT.2.1.0.0\lib\net35\System.Threading.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
@ -44,6 +50,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Helper\UPnPHelper.cs" />
|
||||||
<Compile Include="MonoBehaviours\Core\NetworkedBehaviour.cs" />
|
<Compile Include="MonoBehaviours\Core\NetworkedBehaviour.cs" />
|
||||||
<Compile Include="Data\NetworkedClient.cs" />
|
<Compile Include="Data\NetworkedClient.cs" />
|
||||||
<Compile Include="MonoBehaviours\Core\NetworkedObject.cs" />
|
<Compile Include="MonoBehaviours\Core\NetworkedObject.cs" />
|
||||||
@ -51,5 +58,8 @@
|
|||||||
<Compile Include="MonoBehaviours\Core\NetworkingManager.cs" />
|
<Compile Include="MonoBehaviours\Core\NetworkingManager.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using MLAPI.Helper;
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -344,6 +345,10 @@ namespace MLAPI
|
|||||||
Debug.LogWarning("MLAPI: No ConnectionApproval callback defined. Connection approval will timeout");
|
Debug.LogWarning("MLAPI: No ConnectionApproval callback defined. Connection approval will timeout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (NetworkConfig.UseUPnP)
|
||||||
|
{
|
||||||
|
UPnPHelper.AttemptPortMap(NetworkConfig.Port, NetworkConfig.UPnPCompleteCallback);
|
||||||
|
}
|
||||||
HostTopology hostTopology = new HostTopology(cConfig, NetworkConfig.MaxConnections);
|
HostTopology hostTopology = new HostTopology(cConfig, NetworkConfig.MaxConnections);
|
||||||
hostId = NetworkTransport.AddHost(hostTopology, NetworkConfig.Port);
|
hostId = NetworkTransport.AddHost(hostTopology, NetworkConfig.Port);
|
||||||
isServer = true;
|
isServer = true;
|
||||||
@ -373,6 +378,10 @@ namespace MLAPI
|
|||||||
Debug.LogWarning("MLAPI: No ConnectionApproval callback defined. Connection approval will timeout");
|
Debug.LogWarning("MLAPI: No ConnectionApproval callback defined. Connection approval will timeout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(NetworkConfig.UseUPnP)
|
||||||
|
{
|
||||||
|
UPnPHelper.AttemptPortMap(NetworkConfig.Port, NetworkConfig.UPnPCompleteCallback);
|
||||||
|
}
|
||||||
HostTopology hostTopology = new HostTopology(cConfig, NetworkConfig.MaxConnections);
|
HostTopology hostTopology = new HostTopology(cConfig, NetworkConfig.MaxConnections);
|
||||||
hostId = NetworkTransport.AddHost(hostTopology, NetworkConfig.Port, null);
|
hostId = NetworkTransport.AddHost(hostTopology, NetworkConfig.Port, null);
|
||||||
isServer = true;
|
isServer = true;
|
||||||
|
4
MLAPI/packages.config
Normal file
4
MLAPI/packages.config
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Open.NAT" version="2.1.0.0" targetFramework="net35" />
|
||||||
|
</packages>
|
22
README.md
22
README.md
@ -5,14 +5,8 @@ The project is WIP.
|
|||||||
|
|
||||||
It's licenced under the MIT licence :D
|
It's licenced under the MIT licence :D
|
||||||
|
|
||||||
## Features that are planned / done are:
|
|
||||||
* Object and player spawning (done)
|
## Planned features
|
||||||
* Connection approval (done)
|
|
||||||
* Message names (done)
|
|
||||||
* Replace the integer QOS with names. When you setup the networking you specify names that are associated with a channel. This makes it easier to manage. You can thus specify that a message should be sent on the "damage" channel which handles all damage related logic and is running on the AllCostDelivery channel. (done)
|
|
||||||
* ProtocolVersion to allow making different versions not talk to each other. (done)
|
|
||||||
* NetworkedBehaviours does not have to be on the root, it's simply just a class that implements the send methods etc. (done)
|
|
||||||
* Multiple messages processed every frame with the ability to specify a maximum to prevent freezes in the normal game logic (done)
|
|
||||||
* Built in lag compensation (going to be worked on when all base functionality is there)
|
* Built in lag compensation (going to be worked on when all base functionality is there)
|
||||||
* Area of interest (not working on ATM but it's on the TODO)
|
* Area of interest (not working on ATM but it's on the TODO)
|
||||||
* Core gameplay components similar to what the HLAPI offers (but hopefully of better quality)
|
* Core gameplay components similar to what the HLAPI offers (but hopefully of better quality)
|
||||||
@ -20,7 +14,19 @@ It's licenced under the MIT licence :D
|
|||||||
* Serializer (both for the library to speed up and to allow structs to be sent easily)
|
* Serializer (both for the library to speed up and to allow structs to be sent easily)
|
||||||
* SyncVars (allow variables to automatically be synced to new clients and current clients when it's changed)
|
* SyncVars (allow variables to automatically be synced to new clients and current clients when it's changed)
|
||||||
* Message compression
|
* Message compression
|
||||||
|
|
||||||
|
|
||||||
|
## Done features
|
||||||
* Host support (Client hosts the server) (done)
|
* Host support (Client hosts the server) (done)
|
||||||
|
* Port forwarding using Open.NAT using the UPnP protcol (done)
|
||||||
|
* Object and player spawning (done)
|
||||||
|
* Connection approval (done)
|
||||||
|
* Message names (done)
|
||||||
|
* Replace the integer QOS with names. When you setup the networking you specify names that are associated with a channel. This makes it easier to manage. You can thus specify that a message should be sent on the "damage" channel which handles all damage related logic and is running on the AllCostDelivery channel. (done)
|
||||||
|
* ProtocolVersion to allow making different versions not talk to each other. (done)
|
||||||
|
* NetworkedBehaviours does not have to be on the root, it's simply just a class that implements the send methods etc. (done)
|
||||||
|
* Multiple messages processed every frame with the ability to specify a maximum to prevent freezes in the normal game logic (done)
|
||||||
|
|
||||||
|
|
||||||
That's all I can think of right now. But there is more to come, especially if people show intrest in the project.
|
That's all I can think of right now. But there is more to come, especially if people show intrest in the project.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user