diff --git a/Lidgren.Network/Lidgren.Network.csproj b/Lidgren.Network/Lidgren.Network.csproj index e85c410..4b0713a 100644 --- a/Lidgren.Network/Lidgren.Network.csproj +++ b/Lidgren.Network/Lidgren.Network.csproj @@ -3,7 +3,7 @@ Debug AnyCPU - 9.0.21022 + 9.0.30729 2.0 {FA245447-5F23-4AA1-BD5F-8D2DDF33CFBD} Library @@ -65,6 +65,7 @@ + diff --git a/Lidgren.Network/NetIncomingMessage.Write.cs b/Lidgren.Network/NetIncomingMessage.Write.cs index dfae042..6e9aa48 100644 --- a/Lidgren.Network/NetIncomingMessage.Write.cs +++ b/Lidgren.Network/NetIncomingMessage.Write.cs @@ -446,7 +446,6 @@ namespace Lidgren.Network /// /// Writes an endpoint description /// - /// internal void Write(IPEndPoint endPoint) { byte[] bytes = endPoint.Address.GetAddressBytes(); diff --git a/Lidgren.Network/NetIncomingMessageType.cs b/Lidgren.Network/NetIncomingMessageType.cs index c4b3414..c2f39e5 100644 --- a/Lidgren.Network/NetIncomingMessageType.cs +++ b/Lidgren.Network/NetIncomingMessageType.cs @@ -41,5 +41,6 @@ namespace Lidgren.Network DebugMessage = 1 << 8, // Data (string) WarningMessage = 1 << 9, // Data (string) ErrorMessage = 1 << 10, // Data (string) + NatIntroduction = 1 << 11, // IPEndPoint } } diff --git a/Lidgren.Network/NetMessageType.cs b/Lidgren.Network/NetMessageType.cs index 7a726af..55ff633 100644 --- a/Lidgren.Network/NetMessageType.cs +++ b/Lidgren.Network/NetMessageType.cs @@ -48,7 +48,8 @@ namespace Lidgren.Network Disconnect = 8, Discovery = 9, DiscoveryResponse = 10, - NatIntroduction = 11, + NatPunchMessage = 11, + NatIntroduction = 12, } internal enum NetMessageType : byte diff --git a/Lidgren.Network/NetNatIntroduction.cs b/Lidgren.Network/NetNatIntroduction.cs new file mode 100644 index 0000000..31d3938 --- /dev/null +++ b/Lidgren.Network/NetNatIntroduction.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Net; + +namespace Lidgren.Network +{ + public partial class NetPeer + { + public void Introduce(IPEndPoint host, IPEndPoint client) + { + // send message to client + NetOutgoingMessage msg = CreateMessage(10); + msg.Write(false); + msg.WritePadBits(); + msg.Write(host); + SendUnconnectedLibraryMessage(msg, NetMessageLibraryType.NatIntroduction, client); + + // send message to host + msg = CreateMessage(10); + msg.Write(true); + msg.WritePadBits(); + msg.Write(client); + SendUnconnectedLibraryMessage(msg, NetMessageLibraryType.NatIntroduction, host); + } + + private void HandleNatIntroduction(int ptr, IPEndPoint senderEndpoint) + { + VerifyNetworkThread(); + + // read intro + NetIncomingMessage tmp = new NetIncomingMessage(m_receiveBuffer, 1000); // never mind length + tmp.Position = (ptr * 8); + bool isHost = (tmp.ReadByte() == 0 ? false : true); + IPEndPoint ep = tmp.ReadIPEndpoint(); + + // quickly; send nat punch + NetOutgoingMessage punch = CreateMessage(0); + SendUnconnectedLibraryMessage(punch, NetMessageLibraryType.NatPunchMessage, ep); + + if (!isHost) + { + NetIncomingMessage intro = CreateIncomingMessage(NetIncomingMessageType.NatIntroduction, 10); + intro.Write(ep); + intro.m_senderEndpoint = senderEndpoint; + ReleaseMessage(intro); + } + } + } +} diff --git a/Lidgren.Network/NetOutgoingMessage.Write.cs b/Lidgren.Network/NetOutgoingMessage.Write.cs index 474a8cb..b626e53 100644 --- a/Lidgren.Network/NetOutgoingMessage.Write.cs +++ b/Lidgren.Network/NetOutgoingMessage.Write.cs @@ -509,8 +509,7 @@ namespace Lidgren.Network /// /// Writes an endpoint description /// - /// - internal void Write(IPEndPoint endPoint) + public void Write(IPEndPoint endPoint) { byte[] bytes = endPoint.Address.GetAddressBytes(); Write((byte)bytes.Length); diff --git a/Lidgren.Network/NetPeer.Internal.cs b/Lidgren.Network/NetPeer.Internal.cs index f960f6a..a5da5d6 100644 --- a/Lidgren.Network/NetPeer.Internal.cs +++ b/Lidgren.Network/NetPeer.Internal.cs @@ -418,6 +418,12 @@ namespace Lidgren.Network int payloadLengthBytes = NetUtility.BytesToHoldBits(payloadLengthBits); + // + // Handle nat introduction + // + if (libType == NetMessageLibraryType.NatIntroduction) + HandleNatIntroduction(ptr, senderEndpoint); + // // Handle Discovery // diff --git a/Samples/MasterServerSample/MasterServer/MasterServer.csproj b/Samples/MasterServerSample/MasterServer/MasterServer.csproj new file mode 100644 index 0000000..0130f57 --- /dev/null +++ b/Samples/MasterServerSample/MasterServer/MasterServer.csproj @@ -0,0 +1,65 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {47E2AC9A-F375-47A7-A4E6-9814D3A2954B} + Exe + Properties + MasterServer + MasterServer + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + {FA245447-5F23-4AA1-BD5F-8D2DDF33CFBD} + Lidgren.Network + + + + + \ No newline at end of file diff --git a/Samples/MasterServerSample/MasterServer/Program.cs b/Samples/MasterServerSample/MasterServer/Program.cs new file mode 100644 index 0000000..02b3706 --- /dev/null +++ b/Samples/MasterServerSample/MasterServer/Program.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using Lidgren.Network; +using System.Net; + +namespace MasterServer +{ + public enum MasterServerMessageType + { + RegisterHost, + RequestHostList, + RequestIntroduction, + } + + public class Program + { + static void Main(string[] args) + { + List registeredHosts = new List(); + + NetPeerConfiguration config = new NetPeerConfiguration("masterserver"); + + NetPeer peer = new NetPeer(config); + peer.Start(); + + // keep going until ESCAPE is pressed + Console.WriteLine("Press ESC to quit"); + while (!Console.KeyAvailable || Console.ReadKey().Key != ConsoleKey.Escape) + { + NetIncomingMessage msg; + while((msg = peer.ReadMessage()) != null) + { + switch (msg.MessageType) + { + case NetIncomingMessageType.UnconnectedData: + // + // We've received a message from a client or a host + // + + // by design, the first byte always indicates action + switch ((MasterServerMessageType)msg.ReadByte()) + { + case MasterServerMessageType.RegisterHost: + // It's a host wanting to register its presence + registeredHosts.Add(msg.SenderEndpoint); + break; + + case MasterServerMessageType.RequestHostList: + // It's a client wanting a list of registered hosts + foreach (IPEndPoint ep in registeredHosts) + { + // send registered host to client + NetOutgoingMessage om = peer.CreateMessage(); + om.Write(ep); + peer.SendUnconnectedMessage(om, msg.SenderEndpoint); + } + + break; + case MasterServerMessageType.RequestIntroduction: + // It's a client wanting to connect to a specific host + IPEndPoint rh = msg.ReadIPEndpoint(); + peer.Introduce(rh, msg.SenderEndpoint); + break; + } + break; + + case NetIncomingMessageType.DebugMessage: + case NetIncomingMessageType.VerboseDebugMessage: + case NetIncomingMessageType.WarningMessage: + case NetIncomingMessageType.ErrorMessage: + // print diagnostics message + Console.WriteLine(msg.ReadString()); + break; + } + } + } + + peer.Shutdown("shutting down"); + } + } +} diff --git a/Samples/MasterServerSample/MasterServer/Properties/AssemblyInfo.cs b/Samples/MasterServerSample/MasterServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cc65acb --- /dev/null +++ b/Samples/MasterServerSample/MasterServer/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MasterServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("MasterServer")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("649338d3-b80b-4710-b801-21e593935c21")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Samples/MasterServerSample/MasterServerSample.sln b/Samples/MasterServerSample/MasterServerSample.sln new file mode 100644 index 0000000..1d6b9d4 --- /dev/null +++ b/Samples/MasterServerSample/MasterServerSample.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterServer", "MasterServer\MasterServer.csproj", "{47E2AC9A-F375-47A7-A4E6-9814D3A2954B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lidgren.Network", "..\..\Lidgren.Network\Lidgren.Network.csproj", "{FA245447-5F23-4AA1-BD5F-8D2DDF33CFBD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {47E2AC9A-F375-47A7-A4E6-9814D3A2954B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47E2AC9A-F375-47A7-A4E6-9814D3A2954B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47E2AC9A-F375-47A7-A4E6-9814D3A2954B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47E2AC9A-F375-47A7-A4E6-9814D3A2954B}.Release|Any CPU.Build.0 = Release|Any CPU + {FA245447-5F23-4AA1-BD5F-8D2DDF33CFBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA245447-5F23-4AA1-BD5F-8D2DDF33CFBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA245447-5F23-4AA1-BD5F-8D2DDF33CFBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA245447-5F23-4AA1-BD5F-8D2DDF33CFBD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/MasterServerSample/MasterServerSample.suo b/Samples/MasterServerSample/MasterServerSample.suo new file mode 100644 index 0000000..7778c0f Binary files /dev/null and b/Samples/MasterServerSample/MasterServerSample.suo differ