1
0
mirror of https://github.com/lidgren/lidgren-network-gen3.git synced 2026-05-15 22:56:30 +09:00

First iteration improved multiplatform support

This commit is contained in:
Michael Lidgren
2015-03-24 13:26:55 +01:00
parent 8033a73e73
commit fa8b1e986d
25 changed files with 674 additions and 401 deletions

View File

@@ -7,30 +7,18 @@ namespace Lidgren.Network
public class NetAESEncryption : NetCryptoProviderBase
{
public NetAESEncryption(NetPeer peer)
#if UNITY_WEBPLAYER
: base(peer, new RijndaelManaged())
#else
: base(peer, new AesCryptoServiceProvider())
#endif
{
}
public NetAESEncryption(NetPeer peer, string key)
#if UNITY_WEBPLAYER
: base(peer, new RijndaelManaged())
#else
: base(peer, new AesCryptoServiceProvider())
#endif
{
SetKey(key);
}
public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count)
#if UNITY_WEBPLAYER
: base(peer, new RijndaelManaged())
#else
: base(peer, new AesCryptoServiceProvider())
#endif
{
SetKey(data, offset, count);
}

View File

@@ -0,0 +1,59 @@
using System;
using System.IO;
using System.Security.Cryptography;
namespace Lidgren.Network
{
public abstract class NetCryptoProviderEncryption : NetEncryption
{
public NetCryptoProviderEncryption(NetPeer peer)
: base(peer)
{
}
protected abstract CryptoStream GetEncryptStream(MemoryStream ms);
protected abstract CryptoStream GetDecryptStream(MemoryStream ms);
public override bool Encrypt(NetOutgoingMessage msg)
{
int unEncLenBits = msg.LengthBits;
var ms = new MemoryStream();
var cs = GetEncryptStream(ms);
cs.Write(msg.m_data, 0, msg.LengthBytes);
cs.Close();
// get results
var arr = ms.ToArray();
ms.Close();
msg.EnsureBufferSize((arr.Length + 4) * 8);
msg.LengthBits = 0; // reset write pointer
msg.Write((uint)unEncLenBits);
msg.Write(arr);
msg.LengthBits = (arr.Length + 4) * 8;
return true;
}
public override bool Decrypt(NetIncomingMessage msg)
{
int unEncLenBits = (int)msg.ReadUInt32();
var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4);
var cs = GetDecryptStream(ms);
var result = m_peer.GetStorage(unEncLenBits);
cs.Read(result, 0, NetUtility.BytesToHoldBits(unEncLenBits));
cs.Close();
// TODO: recycle existing msg
msg.m_data = result;
msg.m_bitLength = unEncLenBits;
return true;
}
}
}

View File

@@ -83,14 +83,14 @@ namespace Lidgren.Network
/// String to hash for key
/// </summary>
public NetXtea(NetPeer peer, string key)
: this(peer, NetUtility.CreateSHA1Hash(key), 32)
: this(peer, NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(key)), 32)
{
}
public override void SetKey(byte[] data, int offset, int length)
{
var key = NetUtility.CreateSHA1Hash(data, offset, length);
NetException.Assert(key.Length == 16);
var key = NetUtility.ComputeSHAHash(data, offset, length);
NetException.Assert(key.Length >= 16);
SetKey(key, 0, 16);
}

View File

@@ -136,6 +136,10 @@
<Compile Include="NetUnreliableUnorderedReceiver.cs" />
<Compile Include="NetUPnP.cs" />
<Compile Include="NetUtility.cs" />
<Compile Include="Platform\PlatformAndroid.cs" />
<Compile Include="Platform\PlatformConstrained.cs" />
<Compile Include="Platform\PlatformWin32.cs" />
<Compile Include="Platform\PlatformWinRT.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -2334,4 +2334,19 @@ namespace Lidgren.Network
return ((word >> (n % 32)) & 1) > 0;
}
}
#if WINDOWS_RUNTIME
internal sealed class Stack
{
private System.Collections.Generic.List<object> m_list = new System.Collections.Generic.List<object>();
public int Count { get { return m_list.Count; } }
public void Push(object item) { m_list.Add(item); }
public object Pop()
{
var item = m_list[m_list.Count - 1];
m_list.RemoveAt(m_list.Count - 1);
return item;
}
}
#endif
}

View File

@@ -4,6 +4,10 @@ using System.Text;
using System.Reflection;
using System.Net;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
/// <summary>
@@ -638,14 +642,14 @@ namespace Lidgren.Network
/// <summary>
/// Reads a stored IPv4 endpoint description
/// </summary>
public IPEndPoint ReadIPEndPoint()
public NetEndPoint ReadIPEndPoint()
{
byte len = ReadByte();
byte[] addressBytes = ReadBytes(len);
int port = (int)ReadUInt16();
IPAddress address = new IPAddress(addressBytes);
return new IPEndPoint(address, port);
var address = NetUtility.CreateAddressFromBytes(addressBytes);
return new NetEndPoint(address, port);
}
/// <summary>

View File

@@ -19,6 +19,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Net;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
/// <summary>
@@ -80,7 +84,7 @@ namespace Lidgren.Network
/// <param name="remoteEndPoint">The remote endpoint to connect to</param>
/// <param name="hailMessage">The hail message to pass</param>
/// <returns>server connection, or null if already connected</returns>
public override NetConnection Connect(IPEndPoint remoteEndPoint, NetOutgoingMessage hailMessage)
public override NetConnection Connect(NetEndPoint remoteEndPoint, NetOutgoingMessage hailMessage)
{
lock (m_connections)
{

View File

@@ -3,6 +3,10 @@ using System.Collections.Generic;
using System.Text;
using System.Threading;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
public partial class NetConnection
@@ -167,7 +171,7 @@ namespace Lidgren.Network
if (onLibraryThread)
m_peer.SendLibrary(om, m_remoteEndPoint);
else
m_peer.m_unsentUnconnectedMessages.Enqueue(new NetTuple<System.Net.IPEndPoint, NetOutgoingMessage>(m_remoteEndPoint, om));
m_peer.m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(m_remoteEndPoint, om));
m_lastHandshakeSendTime = now;
m_handshakeAttempts++;
@@ -189,7 +193,7 @@ namespace Lidgren.Network
if (onLibraryThread)
m_peer.SendLibrary(om, m_remoteEndPoint);
else
m_peer.m_unsentUnconnectedMessages.Enqueue(new NetTuple<System.Net.IPEndPoint, NetOutgoingMessage>(m_remoteEndPoint, om));
m_peer.m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(m_remoteEndPoint, om));
}
private void WriteLocalHail(NetOutgoingMessage om)

View File

@@ -3,6 +3,10 @@ using System.Net;
using System.Threading;
using System.Diagnostics;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
/// <summary>
@@ -18,7 +22,7 @@ namespace Lidgren.Network
internal NetPeerConfiguration m_peerConfiguration;
internal NetConnectionStatus m_status;
internal NetConnectionStatus m_visibleStatus;
internal IPEndPoint m_remoteEndPoint;
internal NetEndPoint m_remoteEndPoint;
internal NetSenderChannelBase[] m_sendChannels;
internal NetReceiverChannelBase[] m_receiveChannels;
internal NetOutgoingMessage m_localHailMessage;
@@ -57,7 +61,7 @@ namespace Lidgren.Network
/// <summary>
/// Gets the remote endpoint for the connection
/// </summary>
public IPEndPoint RemoteEndPoint { get { return m_remoteEndPoint; } }
public NetEndPoint RemoteEndPoint { get { return m_remoteEndPoint; } }
/// <summary>
/// Gets the unique identifier of the remote NetPeer for this connection
@@ -78,7 +82,7 @@ namespace Lidgren.Network
return 0.025 + (avgRtt * 2.1); // 25 ms + double rtt
}
internal NetConnection(NetPeer peer, IPEndPoint remoteEndPoint)
internal NetConnection(NetPeer peer, NetEndPoint remoteEndPoint)
{
m_peer = peer;
m_peerConfiguration = m_peer.Configuration;
@@ -97,7 +101,7 @@ namespace Lidgren.Network
/// <summary>
/// Change the internal endpoint to this new one. Used when, during handshake, a switch in port is detected (due to NAT)
/// </summary>
internal void MutateEndPoint(IPEndPoint endPoint)
internal void MutateEndPoint(NetEndPoint endPoint)
{
m_remoteEndPoint = endPoint;
}

View File

@@ -20,6 +20,10 @@ using System;
using System.Net;
using System.Diagnostics;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
/// <summary>
@@ -29,7 +33,7 @@ namespace Lidgren.Network
public sealed class NetIncomingMessage : NetBuffer
{
internal NetIncomingMessageType m_incomingMessageType;
internal IPEndPoint m_senderEndPoint;
internal NetEndPoint m_senderEndPoint;
internal NetConnection m_senderConnection;
internal int m_sequenceNumber;
internal NetMessageType m_receivedMessageType;
@@ -52,9 +56,9 @@ namespace Lidgren.Network
public int SequenceChannel { get { return (int)m_receivedMessageType - (int)NetUtility.GetDeliveryMethod(m_receivedMessageType); } }
/// <summary>
/// IPEndPoint of sender, if any
/// endpoint of sender, if any
/// </summary>
public IPEndPoint SenderEndPoint { get { return m_senderEndPoint; } }
public NetEndPoint SenderEndPoint { get { return m_senderEndPoint; } }
/// <summary>
/// NetConnection of sender, if any

View File

@@ -3,6 +3,10 @@ using System.Collections.Generic;
using System.Net;
using System.Threading;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
public partial class NetPeer
@@ -11,10 +15,10 @@ namespace Lidgren.Network
/// Send NetIntroduction to hostExternal and clientExternal; introducing client to host
/// </summary>
public void Introduce(
IPEndPoint hostInternal,
IPEndPoint hostExternal,
IPEndPoint clientInternal,
IPEndPoint clientExternal,
NetEndPoint hostInternal,
NetEndPoint hostExternal,
NetEndPoint clientInternal,
NetEndPoint clientExternal,
string token)
{
// send message to client
@@ -25,7 +29,7 @@ namespace Lidgren.Network
um.Write(hostExternal);
um.Write(token);
Interlocked.Increment(ref um.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(clientExternal, um));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(clientExternal, um));
// send message to host
um = CreateMessage(10 + token.Length + 1);
@@ -35,7 +39,7 @@ namespace Lidgren.Network
um.Write(clientExternal);
um.Write(token);
Interlocked.Increment(ref um.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(hostExternal, um));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(hostExternal, um));
}
/// <summary>
@@ -49,8 +53,8 @@ namespace Lidgren.Network
NetIncomingMessage tmp = SetupReadHelperMessage(ptr, 1000); // never mind length
byte hostByte = tmp.ReadByte();
IPEndPoint remoteInternal = tmp.ReadIPEndPoint();
IPEndPoint remoteExternal = tmp.ReadIPEndPoint();
NetEndPoint remoteInternal = tmp.ReadIPEndPoint();
NetEndPoint remoteExternal = tmp.ReadIPEndPoint();
string token = tmp.ReadString();
bool isHost = (hostByte != 0);
@@ -67,7 +71,7 @@ namespace Lidgren.Network
punch.Write(hostByte);
punch.Write(token);
Interlocked.Increment(ref punch.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(remoteInternal, punch));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(remoteInternal, punch));
LogDebug("NAT punch sent to " + remoteInternal);
// send external punch
@@ -76,7 +80,7 @@ namespace Lidgren.Network
punch.Write(hostByte);
punch.Write(token);
Interlocked.Increment(ref punch.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(remoteExternal, punch));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(remoteExternal, punch));
LogDebug("NAT punch sent to " + remoteExternal);
}
@@ -84,7 +88,7 @@ namespace Lidgren.Network
/// <summary>
/// Called when receiving a NatPunchMessage from a remote endpoint
/// </summary>
private void HandleNatPunch(int ptr, IPEndPoint senderEndPoint)
private void HandleNatPunch(int ptr, NetEndPoint senderEndPoint)
{
NetIncomingMessage tmp = SetupReadHelperMessage(ptr, 1000); // never mind length
@@ -100,7 +104,7 @@ namespace Lidgren.Network
LogDebug("NAT punch received from " + senderEndPoint + " we're client, so we've succeeded - token is " + token);
//
// Release punch success to client; enabling him to Connect() to msg.SenderIPEndPoint if token is ok
// Release punch success to client; enabling him to Connect() to msg.Sender if token is ok
//
NetIncomingMessage punchSuccess = CreateIncomingMessage(NetIncomingMessageType.NatIntroductionSuccess, 10);
punchSuccess.m_senderEndPoint = senderEndPoint;
@@ -113,7 +117,7 @@ namespace Lidgren.Network
punch.Write((byte)0);
punch.Write(token);
Interlocked.Increment(ref punch.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(senderEndPoint, punch));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(senderEndPoint, punch));
}
}
}

View File

@@ -2,6 +2,10 @@
using System.Net;
using System.Threading;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
public partial class NetPeer
@@ -14,7 +18,8 @@ namespace Lidgren.Network
NetOutgoingMessage um = CreateMessage(0);
um.m_messageType = NetMessageType.Discovery;
Interlocked.Increment(ref um.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(new IPEndPoint(IPAddress.Broadcast, serverPort), um));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(new NetEndPoint(NetUtility.GetBroadcastAddress(), serverPort), um));
}
/// <summary>
@@ -22,28 +27,28 @@ namespace Lidgren.Network
/// </summary>
public bool DiscoverKnownPeer(string host, int serverPort)
{
IPAddress address = NetUtility.Resolve(host);
var address = NetUtility.Resolve(host);
if (address == null)
return false;
DiscoverKnownPeer(new IPEndPoint(address, serverPort));
DiscoverKnownPeer(new NetEndPoint(address, serverPort));
return true;
}
/// <summary>
/// Emit a discovery signal to a single known host
/// </summary>
public void DiscoverKnownPeer(IPEndPoint endPoint)
public void DiscoverKnownPeer(NetEndPoint endPoint)
{
NetOutgoingMessage om = CreateMessage(0);
om.m_messageType = NetMessageType.Discovery;
om.m_recyclingCount = 1;
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(endPoint, om));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(endPoint, om));
}
/// <summary>
/// Send a discovery response message
/// </summary>
public void SendDiscoveryResponse(NetOutgoingMessage msg, IPEndPoint recipient)
public void SendDiscoveryResponse(NetOutgoingMessage msg, NetEndPoint recipient)
{
if (recipient == null)
throw new ArgumentNullException("recipient");
@@ -58,7 +63,7 @@ namespace Lidgren.Network
msg.m_messageType = NetMessageType.DiscoveryResponse;
Interlocked.Increment(ref msg.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(recipient, msg));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(recipient, msg));
}
}
}

View File

@@ -1,8 +1,4 @@
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER && !UNITY_ANDROID && !UNITY_IPHONE
#define IS_MAC_AVAILABLE
#endif
using System;
using System;
using System.Net;
using System.Threading;
using System.Diagnostics;
@@ -10,6 +6,10 @@ using System.Security.Cryptography;
using System.Net.Sockets;
using System.Collections.Generic;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
public partial class NetPeer
@@ -30,9 +30,9 @@ namespace Lidgren.Network
internal readonly NetPeerConfiguration m_configuration;
private readonly NetQueue<NetIncomingMessage> m_releasedIncomingMessages;
internal readonly NetQueue<NetTuple<IPEndPoint, NetOutgoingMessage>> m_unsentUnconnectedMessages;
internal readonly NetQueue<NetTuple<NetEndPoint, NetOutgoingMessage>> m_unsentUnconnectedMessages;
internal Dictionary<IPEndPoint, NetConnection> m_handshakes;
internal Dictionary<NetEndPoint, NetConnection> m_handshakes;
internal readonly NetPeerStatistics m_statistics;
internal long m_uniqueIdentifier;
@@ -133,7 +133,7 @@ namespace Lidgren.Network
m_socket.SendBufferSize = m_configuration.SendBufferSize;
m_socket.Blocking = false;
var ep = (EndPoint)new IPEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port);
var ep = (EndPoint)new NetEndPoint(m_configuration.LocalAddress, reBind ? m_listenPort : m_configuration.Port);
m_socket.Bind(ep);
try
@@ -148,7 +148,7 @@ namespace Lidgren.Network
// ignore; SIO_UDP_CONNRESET not supported on this platform
}
IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint;
var boundEp = m_socket.LocalEndPoint as NetEndPoint;
LogDebug("Socket bound to " + boundEp + ": " + m_socket.IsBound);
m_listenPort = boundEp.Port;
}
@@ -179,34 +179,14 @@ namespace Lidgren.Network
m_readHelperMessage = new NetIncomingMessage(NetIncomingMessageType.Error);
m_readHelperMessage.m_data = m_receiveBuffer;
byte[] macBytes = new byte[8];
MWCRandom.Instance.NextBytes(macBytes);
byte[] macBytes = NetUtility.GetMacAddressBytes();
#if IS_MAC_AVAILABLE
try
{
System.Net.NetworkInformation.PhysicalAddress pa = NetUtility.GetMacAddress();
if (pa != null)
{
macBytes = pa.GetAddressBytes();
LogVerbose("Mac address is " + NetUtility.ToHexString(macBytes));
}
else
{
LogWarning("Failed to get Mac address");
}
}
catch (NotSupportedException)
{
// not supported; lets just keep the random bytes set above
}
#endif
IPEndPoint boundEp = m_socket.LocalEndPoint as IPEndPoint;
var boundEp = m_socket.LocalEndPoint as NetEndPoint;
byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode());
byte[] combined = new byte[epBytes.Length + macBytes.Length];
Array.Copy(epBytes, 0, combined, 0, epBytes.Length);
Array.Copy(macBytes, 0, combined, epBytes.Length, macBytes.Length);
m_uniqueIdentifier = BitConverter.ToInt64(NetUtility.CreateSHA1Hash(combined), 0);
m_uniqueIdentifier = BitConverter.ToInt64(NetUtility.ComputeSHAHash(combined), 0);
m_status = NetPeerStatus.Running;
}
@@ -270,8 +250,8 @@ namespace Lidgren.Network
// one final heartbeat, will send stuff and do disconnect
Heartbeat();
Thread.Sleep(10);
NetUtility.Sleep(10);
lock (m_initializeLock)
{
try
@@ -393,7 +373,7 @@ namespace Lidgren.Network
m_executeFlushSendQueue = false;
// send unsent unconnected messages
NetTuple<IPEndPoint, NetOutgoingMessage> unsent;
NetTuple<NetEndPoint, NetOutgoingMessage> unsent;
while (m_unsentUnconnectedMessages.TryDequeue(out unsent))
{
NetOutgoingMessage om = unsent.Item2;
@@ -458,7 +438,7 @@ namespace Lidgren.Network
//LogVerbose("Received " + bytesReceived + " bytes");
IPEndPoint ipsender = (IPEndPoint)m_senderRemote;
var ipsender = (NetEndPoint)m_senderRemote;
if (m_upnp != null && now < m_upnp.m_discoveryResponseDeadline && bytesReceived > 32)
{
@@ -596,7 +576,7 @@ namespace Lidgren.Network
m_executeFlushSendQueue = true;
}
internal void HandleIncomingDiscoveryRequest(double now, IPEndPoint senderEndPoint, int ptr, int payloadByteLength)
internal void HandleIncomingDiscoveryRequest(double now, NetEndPoint senderEndPoint, int ptr, int payloadByteLength)
{
if (m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.DiscoveryRequest))
{
@@ -610,7 +590,7 @@ namespace Lidgren.Network
}
}
internal void HandleIncomingDiscoveryResponse(double now, IPEndPoint senderEndPoint, int ptr, int payloadByteLength)
internal void HandleIncomingDiscoveryResponse(double now, NetEndPoint senderEndPoint, int ptr, int payloadByteLength)
{
if (m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.DiscoveryResponse))
{
@@ -624,7 +604,7 @@ namespace Lidgren.Network
}
}
private void ReceivedUnconnectedLibraryMessage(double now, IPEndPoint senderEndPoint, NetMessageType tp, int ptr, int payloadByteLength)
private void ReceivedUnconnectedLibraryMessage(double now, NetEndPoint senderEndPoint, NetMessageType tp, int ptr, int payloadByteLength)
{
NetConnection shake;
if (m_handshakes.TryGetValue(senderEndPoint, out shake))

View File

@@ -25,6 +25,10 @@ using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
public partial class NetPeer
@@ -37,10 +41,10 @@ namespace Lidgren.Network
{
public byte[] Data;
public double DelayedUntil;
public IPEndPoint Target;
public NetEndPoint Target;
}
internal void SendPacket(int numBytes, IPEndPoint target, int numMessages, out bool connectionReset)
internal void SendPacket(int numBytes, NetEndPoint target, int numMessages, out bool connectionReset)
{
connectionReset = false;
@@ -128,13 +132,13 @@ namespace Lidgren.Network
catch { }
}
internal bool ActuallySendPacket(byte[] data, int numBytes, IPEndPoint target, out bool connectionReset)
internal bool ActuallySendPacket(byte[] data, int numBytes, NetEndPoint target, out bool connectionReset)
{
connectionReset = false;
try
{
// TODO: refactor this check outta here
if (target.Address == IPAddress.Broadcast)
if (target.Address == NetUtility.GetBroadcastAddress())
{
// Some networks do not allow
// a global broadcast so we use the BroadcastAddress from the configuration
@@ -177,7 +181,7 @@ namespace Lidgren.Network
return true;
}
internal bool SendMTUPacket(int numBytes, IPEndPoint target)
internal bool SendMTUPacket(int numBytes, NetEndPoint target)
{
try
{
@@ -213,7 +217,7 @@ namespace Lidgren.Network
return true;
}
#else
internal bool SendMTUPacket(int numBytes, IPEndPoint target)
internal bool SendMTUPacket(int numBytes, NetEndPoint target)
{
try
{
@@ -250,7 +254,7 @@ namespace Lidgren.Network
//
// Release - just send the packet straight away
//
internal void SendPacket(int numBytes, IPEndPoint target, int numMessages, out bool connectionReset)
internal void SendPacket(int numBytes, NetEndPoint target, int numMessages, out bool connectionReset)
{
#if USE_RELEASE_STATISTICS
m_statistics.PacketSent(numBytes, numMessages);
@@ -259,7 +263,7 @@ namespace Lidgren.Network
try
{
// TODO: refactor this check outta here
if (target.Address == IPAddress.Broadcast)
if (target.Address == NetUtility.GetBroadcastAddress())
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
int bytesSent = m_socket.SendTo(m_sendBuffer, 0, numBytes, SocketFlags.None, target);
@@ -288,7 +292,7 @@ namespace Lidgren.Network
}
finally
{
if (target.Address == IPAddress.Broadcast)
if (target.Address == NetUtility.GetBroadcastAddress())
m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
}
return;

View File

@@ -3,6 +3,10 @@ using System.Collections.Generic;
using System.Threading;
using System.Net;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
public partial class NetPeer
@@ -153,18 +157,18 @@ namespace Lidgren.Network
msg.m_isSent = true;
msg.m_messageType = NetMessageType.Unconnected;
IPAddress adr = NetUtility.Resolve(host);
var adr = NetUtility.Resolve(host);
if (adr == null)
throw new NetException("Failed to resolve " + host);
Interlocked.Increment(ref msg.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(new IPEndPoint(adr, port), msg));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(new NetEndPoint(adr, port), msg));
}
/// <summary>
/// Send a message to an unconnected host
/// </summary>
public void SendUnconnectedMessage(NetOutgoingMessage msg, IPEndPoint recipient)
public void SendUnconnectedMessage(NetOutgoingMessage msg, NetEndPoint recipient)
{
if (msg == null)
throw new ArgumentNullException("msg");
@@ -179,13 +183,13 @@ namespace Lidgren.Network
msg.m_isSent = true;
Interlocked.Increment(ref msg.m_recyclingCount);
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(recipient, msg));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(recipient, msg));
}
/// <summary>
/// Send a message to an unconnected host
/// </summary>
public void SendUnconnectedMessage(NetOutgoingMessage msg, IList<IPEndPoint> recipients)
public void SendUnconnectedMessage(NetOutgoingMessage msg, IList<NetEndPoint> recipients)
{
if (msg == null)
throw new ArgumentNullException("msg");
@@ -202,8 +206,8 @@ namespace Lidgren.Network
msg.m_isSent = true;
Interlocked.Add(ref msg.m_recyclingCount, recipients.Count);
foreach(IPEndPoint ep in recipients)
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(ep, msg));
foreach (NetEndPoint ep in recipients)
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(ep, msg));
}
/// <summary>
@@ -231,7 +235,7 @@ namespace Lidgren.Network
im.m_isFragment = false;
im.m_receiveTime = NetTime.Now;
im.m_senderConnection = null;
im.m_senderEndPoint = m_socket.LocalEndPoint as IPEndPoint;
im.m_senderEndPoint = m_socket.LocalEndPoint as NetEndPoint;
NetException.Assert(im.m_bitLength == om.LengthBits);
// recycle outgoing message

View File

@@ -3,6 +3,10 @@ using System.Threading;
using System.Collections.Generic;
using System.Net;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
/// <summary>
@@ -17,7 +21,7 @@ namespace Lidgren.Network
private object m_messageReceivedEventCreationLock = new object();
internal readonly List<NetConnection> m_connections;
private readonly Dictionary<IPEndPoint, NetConnection> m_connectionLookup;
private readonly Dictionary<NetEndPoint, NetConnection> m_connectionLookup;
private string m_shutdownReason;
@@ -113,11 +117,11 @@ namespace Lidgren.Network
m_configuration = config;
m_statistics = new NetPeerStatistics(this);
m_releasedIncomingMessages = new NetQueue<NetIncomingMessage>(4);
m_unsentUnconnectedMessages = new NetQueue<NetTuple<IPEndPoint, NetOutgoingMessage>>(2);
m_unsentUnconnectedMessages = new NetQueue<NetTuple<NetEndPoint, NetOutgoingMessage>>(2);
m_connections = new List<NetConnection>();
m_connectionLookup = new Dictionary<IPEndPoint, NetConnection>();
m_handshakes = new Dictionary<IPEndPoint, NetConnection>();
m_senderRemote = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
m_connectionLookup = new Dictionary<NetEndPoint, NetConnection>();
m_handshakes = new Dictionary<NetEndPoint, NetConnection>();
m_senderRemote = (EndPoint)new NetEndPoint(IPAddress.Any, 0);
m_status = NetPeerStatus.NotRunning;
m_receivedFragmentGroups = new Dictionary<NetConnection, Dictionary<int, ReceivedFragmentGroup>>();
}
@@ -156,13 +160,13 @@ namespace Lidgren.Network
m_upnp.Discover(this);
// allow some time for network thread to start up in case they call Connect() or UPnP calls immediately
Thread.Sleep(50);
NetUtility.Sleep(50);
}
/// <summary>
/// Get the connection, if any, for a certain remote endpoint
/// </summary>
public NetConnection GetConnection(IPEndPoint ep)
public NetConnection GetConnection(NetEndPoint ep)
{
NetConnection retval;
@@ -226,7 +230,7 @@ namespace Lidgren.Network
}
// send message immediately and recycle it
internal void SendLibrary(NetOutgoingMessage msg, IPEndPoint recipient)
internal void SendLibrary(NetOutgoingMessage msg, NetEndPoint recipient)
{
VerifyNetworkThread();
NetException.Assert(msg.m_isSent == false);
@@ -245,7 +249,7 @@ namespace Lidgren.Network
/// </summary>
public NetConnection Connect(string host, int port)
{
return Connect(new IPEndPoint(NetUtility.Resolve(host), port), null);
return Connect(new NetEndPoint(NetUtility.Resolve(host), port), null);
}
/// <summary>
@@ -253,13 +257,13 @@ namespace Lidgren.Network
/// </summary>
public NetConnection Connect(string host, int port, NetOutgoingMessage hailMessage)
{
return Connect(new IPEndPoint(NetUtility.Resolve(host), port), hailMessage);
return Connect(new NetEndPoint(NetUtility.Resolve(host), port), hailMessage);
}
/// <summary>
/// Create a connection to a remote endpoint
/// </summary>
public NetConnection Connect(IPEndPoint remoteEndPoint)
public NetConnection Connect(NetEndPoint remoteEndPoint)
{
return Connect(remoteEndPoint, null);
}
@@ -267,7 +271,7 @@ namespace Lidgren.Network
/// <summary>
/// Create a connection to a remote endpoint
/// </summary>
public virtual NetConnection Connect(IPEndPoint remoteEndPoint, NetOutgoingMessage hailMessage)
public virtual NetConnection Connect(NetEndPoint remoteEndPoint, NetOutgoingMessage hailMessage)
{
if (remoteEndPoint == null)
throw new ArgumentNullException("remoteEndPoint");
@@ -319,12 +323,8 @@ namespace Lidgren.Network
/// <summary>
/// Send raw bytes; only used for debugging
/// </summary>
#if DEBUG
public void RawSend(byte[] arr, int offset, int length, IPEndPoint destination)
#else
public void RawSend(byte[] arr, int offset, int length, IPEndPoint destination)
#endif
{
public void RawSend(byte[] arr, int offset, int length, NetEndPoint destination)
{
// wrong thread - this miiiight crash with network thread... but what's a boy to do.
Array.Copy(arr, offset, m_sendBuffer, 0, length);
bool unused;

View File

@@ -28,20 +28,18 @@ namespace Lidgren.Network
[CLSCompliant(false)]
public static ulong GetUInt64()
{
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER && !UNITY_ANDROID && !UNITY_IPHONE
ulong seed = (ulong)System.Diagnostics.Stopwatch.GetTimestamp();
seed ^= (ulong)Environment.WorkingSet;
ulong s2 = (ulong)Interlocked.Increment(ref m_seedIncrement);
s2 |= (((ulong)Guid.NewGuid().GetHashCode()) << 32);
seed ^= s2;
#else
ulong seed = (ulong)Environment.TickCount;
seed |= (((ulong)(new object().GetHashCode())) << 32);
ulong s2 = (ulong)Guid.NewGuid().GetHashCode();
s2 |= (((ulong)Interlocked.Increment(ref m_seedIncrement)) << 32);
seed ^= s2;
#endif
return seed;
var guidBytes = Guid.NewGuid().ToByteArray();
ulong seed =
((ulong)guidBytes[0] << (8 * 0)) |
((ulong)guidBytes[1] << (8 * 1)) |
((ulong)guidBytes[2] << (8 * 2)) |
((ulong)guidBytes[3] << (8 * 3)) |
((ulong)guidBytes[4] << (8 * 4)) |
((ulong)guidBytes[5] << (8 * 5)) |
((ulong)guidBytes[6] << (8 * 6)) |
((ulong)guidBytes[7] << (8 * 7));
return seed ^ NetUtility.GetPlatformSeed(m_seedIncrement);
}
}
}

View File

@@ -14,17 +14,7 @@ namespace Lidgren.Network
private static readonly NetBigInteger N = new NetBigInteger("0115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
private static readonly NetBigInteger g = NetBigInteger.Two;
private static readonly NetBigInteger k = ComputeMultiplier();
private static HashAlgorithm GetHashAlgorithm()
{
#if USE_SHA256
// this does not seem to work as of yet
return SHA256.Create();
#else
return SHA1.Create();
#endif
}
/// <summary>
/// Compute multiplier (k)
/// </summary>
@@ -36,9 +26,7 @@ namespace Lidgren.Network
string ccstr = one + two.PadLeft(one.Length, '0');
byte[] cc = NetUtility.ToByteArray(ccstr);
var sha = GetHashAlgorithm();
var ccHashed = sha.ComputeHash(cc);
var ccHashed = NetUtility.ComputeSHAHash(cc);
return new NetBigInteger(NetUtility.ToHexString(ccHashed), 16);
}
@@ -67,17 +55,15 @@ namespace Lidgren.Network
/// </summary>
public static byte[] ComputePrivateKey(string username, string password, byte[] salt)
{
var sha = GetHashAlgorithm();
byte[] tmp = Encoding.UTF8.GetBytes(username + ":" + password);
byte[] innerHash = sha.ComputeHash(tmp);
byte[] innerHash = NetUtility.ComputeSHAHash(tmp);
byte[] total = new byte[innerHash.Length + salt.Length];
Buffer.BlockCopy(salt, 0, total, 0, salt.Length);
Buffer.BlockCopy(innerHash, 0, total, salt.Length, innerHash.Length);
// x ie. H(salt || H(username || ":" || password))
return new NetBigInteger(NetUtility.ToHexString(sha.ComputeHash(total)), 16).ToByteArrayUnsigned();
return new NetBigInteger(NetUtility.ToHexString(NetUtility.ComputeSHAHash(total)), 16).ToByteArrayUnsigned();
}
/// <summary>
@@ -93,15 +79,6 @@ namespace Lidgren.Network
return serverVerifier.ToByteArrayUnsigned();
}
/// <summary>
/// SHA hash data
/// </summary>
public static byte[] Hash(byte[] data)
{
var sha = GetHashAlgorithm();
return sha.ComputeHash(data);
}
/// <summary>
/// Compute client public ephemeral value (A)
/// </summary>
@@ -144,8 +121,7 @@ namespace Lidgren.Network
byte[] cc = NetUtility.ToByteArray(ccstr);
var sha = GetHashAlgorithm();
var ccHashed = sha.ComputeHash(cc);
var ccHashed = NetUtility.ComputeSHAHash(cc);
return new NetBigInteger(NetUtility.ToHexString(ccHashed), 16).ToByteArrayUnsigned();
}
@@ -187,8 +163,7 @@ namespace Lidgren.Network
/// </summary>
public static NetXtea CreateEncryption(NetPeer peer, byte[] sessionValue)
{
var sha = GetHashAlgorithm();
var hash = sha.ComputeHash(sessionValue);
var hash = NetUtility.ComputeSHAHash(sessionValue);
var key = new byte[16];
for(int i=0;i<16;i++)

View File

@@ -17,8 +17,6 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define IS_STOPWATCH_AVAILABLE
using System;
using System.Collections.Generic;
using System.Text;
@@ -29,25 +27,8 @@ namespace Lidgren.Network
/// <summary>
/// Time service
/// </summary>
public static class NetTime
public static partial class NetTime
{
#if IS_STOPWATCH_AVAILABLE
private static readonly long s_timeInitialized = Stopwatch.GetTimestamp();
private static readonly double s_dInvFreq = 1.0 / (double)Stopwatch.Frequency;
/// <summary>
/// Get number of seconds since the application started
/// </summary>
public static double Now { get { return (double)(Stopwatch.GetTimestamp() - s_timeInitialized) * s_dInvFreq; } }
#else
private static readonly uint s_timeInitialized = (uint)Environment.TickCount;
/// <summary>
/// Get number of seconds since the application started
/// </summary>
public static double Now { get { return (double)((uint)Environment.TickCount - s_timeInitialized) / 1000.0; } }
#endif
/// <summary>
/// Given seconds it will output a human friendly readable string (milliseconds if less than 60 seconds)
/// </summary>

View File

@@ -5,6 +5,10 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network
{
/// <summary>
@@ -73,11 +77,11 @@ namespace Lidgren.Network
m_peer.LogDebug("Attempting UPnP discovery");
peer.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
peer.RawSend(arr, 0, arr.Length, new IPEndPoint(IPAddress.Broadcast, 1900));
peer.RawSend(arr, 0, arr.Length, new NetEndPoint(NetUtility.GetBroadcastAddress(), 1900));
peer.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
// allow some extra time for router to respond
// System.Threading.Thread.Sleep(50);
NetUtility.Sleep(50);
m_discoveryResponseDeadline = NetTime.Now + 6.0; // arbitrarily chosen number, router gets 6 seconds to respond
m_status = UPnPStatus.Discovering;
@@ -182,7 +186,7 @@ namespace Lidgren.Network
"AddPortMapping");
m_peer.LogDebug("Sent UPnP port forward request");
System.Threading.Thread.Sleep(50);
NetUtility.Sleep(50);
}
catch (Exception ex)
{

View File

@@ -16,17 +16,15 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRA
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !__ANDROID__ && !IOS && !UNITY_WEBPLAYER && !UNITY_ANDROID && !UNITY_IPHONE
#define IS_FULL_NET_AVAILABLE
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
using NetAddress = System.Net.IPAddress;
#endif
using System;
using System.Net;
#if IS_FULL_NET_AVAILABLE
using System.Net.NetworkInformation;
#endif
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
@@ -38,24 +36,24 @@ namespace Lidgren.Network
/// <summary>
/// Utility methods
/// </summary>
public static class NetUtility
public static partial class NetUtility
{
/// <summary>
/// Resolve endpoint callback
/// </summary>
public delegate void ResolveEndPointCallback(IPEndPoint endPoint);
public delegate void ResolveEndPointCallback(NetEndPoint endPoint);
/// <summary>
/// Resolve address callback
/// </summary>
public delegate void ResolveAddressCallback(IPAddress adr);
public delegate void ResolveAddressCallback(NetAddress adr);
/// <summary>
/// Get IPv4 endpoint from notation (xxx.xxx.xxx.xxx) or hostname and port number (asynchronous version)
/// </summary>
public static void ResolveAsync(string ipOrHost, int port, ResolveEndPointCallback callback)
{
ResolveAsync(ipOrHost, delegate(IPAddress adr)
ResolveAsync(ipOrHost, delegate(NetAddress adr)
{
if (adr == null)
{
@@ -63,7 +61,7 @@ namespace Lidgren.Network
}
else
{
callback(new IPEndPoint(adr, port));
callback(new NetEndPoint(adr, port));
}
});
}
@@ -71,10 +69,10 @@ namespace Lidgren.Network
/// <summary>
/// Get IPv4 endpoint from notation (xxx.xxx.xxx.xxx) or hostname and port number
/// </summary>
public static IPEndPoint Resolve(string ipOrHost, int port)
public static NetEndPoint Resolve(string ipOrHost, int port)
{
IPAddress adr = Resolve(ipOrHost);
return new IPEndPoint(adr, port);
var adr = Resolve(ipOrHost);
return new NetEndPoint(adr, port);
}
/// <summary>
@@ -87,8 +85,8 @@ namespace Lidgren.Network
ipOrHost = ipOrHost.Trim();
IPAddress ipAddress = null;
if (IPAddress.TryParse(ipOrHost, out ipAddress))
NetAddress ipAddress = null;
if (NetAddress.TryParse(ipOrHost, out ipAddress))
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
@@ -129,7 +127,7 @@ namespace Lidgren.Network
}
// check each entry for a valid IP address
foreach (IPAddress ipCurrent in entry.AddressList)
foreach (var ipCurrent in entry.AddressList)
{
if (ipCurrent.AddressFamily == AddressFamily.InterNetwork)
{
@@ -158,15 +156,15 @@ namespace Lidgren.Network
/// <summary>
/// Get IPv4 address from notation (xxx.xxx.xxx.xxx) or hostname
/// </summary>
public static IPAddress Resolve(string ipOrHost)
public static NetAddress Resolve(string ipOrHost)
{
if (string.IsNullOrEmpty(ipOrHost))
throw new ArgumentException("Supplied string must not be empty", "ipOrHost");
ipOrHost = ipOrHost.Trim();
IPAddress ipAddress = null;
if (IPAddress.TryParse(ipOrHost, out ipAddress))
NetAddress ipAddress = null;
if (NetAddress.TryParse(ipOrHost, out ipAddress))
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
return ipAddress;
@@ -200,56 +198,6 @@ namespace Lidgren.Network
}
}
#if IS_FULL_NET_AVAILABLE
private static NetworkInterface GetNetworkInterface()
{
IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
if (computerProperties == null)
return null;
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
if (nics == null || nics.Length < 1)
return null;
NetworkInterface best = null;
foreach (NetworkInterface adapter in nics)
{
if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback || adapter.NetworkInterfaceType == NetworkInterfaceType.Unknown)
continue;
if (!adapter.Supports(NetworkInterfaceComponent.IPv4))
continue;
if (best == null)
best = adapter;
if (adapter.OperationalStatus != OperationalStatus.Up)
continue;
// make sure this adapter has any ipv4 addresses
IPInterfaceProperties properties = adapter.GetIPProperties();
foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses)
{
if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{
// Yes it does, return this network interface.
return adapter;
}
}
}
return best;
}
/// <summary>
/// Returns the physical (MAC) address for the first usable network interface
/// </summary>
public static PhysicalAddress GetMacAddress()
{
NetworkInterface ni = GetNetworkInterface();
if (ni == null)
return null;
return ni.GetPhysicalAddress();
}
#endif
/// <summary>
/// Create a hex string from an Int64 value
/// </summary>
@@ -282,123 +230,11 @@ namespace Lidgren.Network
}
return new string(c);
}
/// <summary>
/// Gets the local broadcast address
/// </summary>
public static IPAddress GetBroadcastAddress()
{
#if __ANDROID__
try{
Android.Net.Wifi.WifiManager wifi = (Android.Net.Wifi.WifiManager)Android.App.Application.Context.GetSystemService(Android.App.Activity.WifiService);
if (wifi.IsWifiEnabled)
{
var dhcp = wifi.DhcpInfo;
int broadcast = (dhcp.IpAddress & dhcp.Netmask) | ~dhcp.Netmask;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
{
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
}
return new IPAddress(quads);
}
}
catch // Catch Access Denied Errors
{
return IPAddress.Broadcast;
}
#endif
#if IS_FULL_NET_AVAILABLE
try
{
NetworkInterface ni = GetNetworkInterface();
if (ni == null)
{
return null;
}
IPInterfaceProperties properties = ni.GetIPProperties();
foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses)
{
if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{
var mask = unicastAddress.IPv4Mask;
byte[] ipAdressBytes = unicastAddress.Address.GetAddressBytes();
byte[] subnetMaskBytes = mask.GetAddressBytes();
if (ipAdressBytes.Length != subnetMaskBytes.Length)
throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
byte[] broadcastAddress = new byte[ipAdressBytes.Length];
for (int i = 0; i < broadcastAddress.Length; i++)
{
broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255));
}
return new IPAddress(broadcastAddress);
}
}
}
catch // Catch any errors
{
return IPAddress.Broadcast;
}
#endif
return IPAddress.Broadcast;
}
/// <summary>
/// Gets my local IPv4 address (not necessarily external) and subnet mask
/// Returns true if the endpoint supplied is on the same subnet as this host
/// </summary>
public static IPAddress GetMyAddress(out IPAddress mask)
{
mask = null;
#if __ANDROID__
try
{
Android.Net.Wifi.WifiManager wifi = (Android.Net.Wifi.WifiManager)Android.App.Application.Context.GetSystemService(Android.App.Activity.WifiService);
if (!wifi.IsWifiEnabled) return null;
var dhcp = wifi.DhcpInfo;
int addr = dhcp.IpAddress;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
{
quads[k] = (byte) ((addr >> k * 8) & 0xFF);
}
return new IPAddress(quads);
}
catch // Catch Access Denied errors
{
return null;
}
#endif
#if IS_FULL_NET_AVAILABLE
NetworkInterface ni = GetNetworkInterface();
if (ni == null)
{
mask = null;
return null;
}
IPInterfaceProperties properties = ni.GetIPProperties();
foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses)
{
if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{
mask = unicastAddress.IPv4Mask;
return unicastAddress.Address;
}
}
#endif
return null;
}
/// <summary>
/// Returns true if the IPEndPoint supplied is on the same subnet as this host
/// </summary>
public static bool IsLocal(IPEndPoint endPoint)
public static bool IsLocal(NetEndPoint endPoint)
{
if (endPoint == null)
return false;
@@ -408,10 +244,10 @@ namespace Lidgren.Network
/// <summary>
/// Returns true if the IPAddress supplied is on the same subnet as this host
/// </summary>
public static bool IsLocal(IPAddress remote)
public static bool IsLocal(NetAddress remote)
{
IPAddress mask;
IPAddress local = GetMyAddress(out mask);
NetAddress mask;
var local = GetMyAddress(out mask);
if (mask == null)
return false;
@@ -602,31 +438,10 @@ namespace Lidgren.Network
return bdr.ToString();
}
/// <summary>
/// Create a SHA1 digest from a string
/// </summary>
public static byte[] CreateSHA1Hash(string key)
public static byte[] ComputeSHAHash(byte[] bytes)
{
using (var sha = new SHA1CryptoServiceProvider())
return sha.ComputeHash(Encoding.UTF8.GetBytes(key));
}
/// <summary>
/// Create a SHA1 digest from a byte buffer
/// </summary>
public static byte[] CreateSHA1Hash(byte[] data)
{
using (var sha = new SHA1CryptoServiceProvider())
return sha.ComputeHash(data);
}
/// <summary>
/// Create a SHA1 digest from a byte buffer
/// </summary>
public static byte[] CreateSHA1Hash(byte[] data, int offset, int count)
{
using (var sha = new SHA1CryptoServiceProvider())
return sha.ComputeHash(data, offset, count);
// this is defined in the platform specific files
return ComputeSHAHash(bytes, 0, bytes.Length);
}
}
}

View File

@@ -0,0 +1,87 @@
#if __ANDROID__
using System;
using System.Collections.Generic;
using System.Net;
namespace Lidgren.Network
{
public static partial class NetUtility
{
private static byte[] s_randomMacBytes;
static NetUtility()
{
s_randomMacBytes = new byte[8];
MWCRandom.Instance.NextBytes(s_randomMacBytes);
}
[CLSCompliant(false)]
public static ulong GetPlatformSeed(int seedInc)
{
ulong seed = (ulong)Environment.TickCount + (ulong)seedInc;
return seed ^ ((ulong)(new object().GetHashCode()) << 32);
}
/// <summary>
/// Gets my local IPv4 address (not necessarily external) and subnet mask
/// </summary>
public static IPAddress GetMyAddress(out IPAddress mask)
{
mask = null;
try
{
Android.Net.Wifi.WifiManager wifi = (Android.Net.Wifi.WifiManager)Android.App.Application.Context.GetSystemService(Android.App.Activity.WifiService);
if (!wifi.IsWifiEnabled)
return null;
var dhcp = wifi.DhcpInfo;
int addr = dhcp.IpAddress;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
quads[k] = (byte)((addr >> k * 8) & 0xFF);
return new IPAddress(quads);
}
catch // Catch Access Denied errors
{
return null;
}
}
public static byte[] GetMacAddressBytes()
{
return s_randomMacBytes;
}
public static void Sleep(int milliseconds)
{
System.Threading.Thread.Sleep(milliseconds);
}
public static IPAddress GetBroadcastAddress()
{
return IPAddress.Broadcast;
}
public static IPAddress CreateAddressFromBytes(byte[] bytes)
{
return new IPAddress(bytes);
}
private static readonly SHA1 s_sha = SHA1.Create();
public static byte[] ComputeSHAHash(byte[] bytes, int offset, int count)
{
return s_sha.ComputeHash(bytes, offset, count);
}
}
public static partial class NetTime
{
private static readonly long s_timeInitialized = Environment.TickCount;
/// <summary>
/// Get number of seconds since the application started
/// </summary>
public static double Now { get { return (double)((uint)Environment.TickCount - s_timeInitialized) / 1000.0; } }
}
}
#endif

View File

@@ -0,0 +1,72 @@
#if __CONSTRAINED__
using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography;
namespace Lidgren.Network
{
public static partial class NetUtility
{
private static byte[] s_randomMacBytes;
static NetUtility()
{
s_randomMacBytes = new byte[8];
MWCRandom.Instance.NextBytes(s_randomMacBytes);
}
[CLSCompliant(false)]
public static ulong GetPlatformSeed(int seedInc)
{
ulong seed = (ulong)Environment.TickCount + (ulong)seedInc;
return seed ^ ((ulong)(new object().GetHashCode()) << 32);
}
/// <summary>
/// Gets my local IPv4 address (not necessarily external) and subnet mask
/// </summary>
public static IPAddress GetMyAddress(out IPAddress mask)
{
mask = null;
return null;
}
public static byte[] GetMacAddressBytes()
{
return s_randomMacBytes;
}
public static IPAddress GetBroadcastAddress()
{
return IPAddress.Broadcast;
}
public static void Sleep(int milliseconds)
{
System.Threading.Thread.Sleep(milliseconds);
}
public static IPAddress CreateAddressFromBytes(byte[] bytes)
{
return new IPAddress(bytes);
}
private static readonly SHA1 s_sha = SHA1.Create();
public static byte[] ComputeSHAHash(byte[] bytes, int offset, int count)
{
return s_sha.ComputeHash(bytes, offset, count);
}
}
public static partial class NetTime
{
private static readonly long s_timeInitialized = Environment.TickCount;
/// <summary>
/// Get number of seconds since the application started
/// </summary>
public static double Now { get { return (double)((uint)Environment.TickCount - s_timeInitialized) / 1000.0; } }
}
}
#endif

View File

@@ -0,0 +1,156 @@
#if !__ANDROID__ && !__CONSTRAINED__ && !WINDOWS_RUNTIME
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security.Cryptography;
namespace Lidgren.Network
{
public static partial class NetUtility
{
private static readonly long s_timeInitialized = Stopwatch.GetTimestamp();
private static readonly double s_dInvFreq = 1.0 / (double)Stopwatch.Frequency;
[CLSCompliant(false)]
public static ulong GetPlatformSeed(int seedInc)
{
ulong seed = (ulong)System.Diagnostics.Stopwatch.GetTimestamp();
return seed ^ ((ulong)Environment.WorkingSet + (ulong)seedInc);
}
public static double Now { get { return (double)(Stopwatch.GetTimestamp() - s_timeInitialized) * s_dInvFreq; } }
private static NetworkInterface GetNetworkInterface()
{
var computerProperties = IPGlobalProperties.GetIPGlobalProperties();
if (computerProperties == null)
return null;
var nics = NetworkInterface.GetAllNetworkInterfaces();
if (nics == null || nics.Length < 1)
return null;
NetworkInterface best = null;
foreach (NetworkInterface adapter in nics)
{
if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback || adapter.NetworkInterfaceType == NetworkInterfaceType.Unknown)
continue;
if (!adapter.Supports(NetworkInterfaceComponent.IPv4))
continue;
if (best == null)
best = adapter;
if (adapter.OperationalStatus != OperationalStatus.Up)
continue;
// make sure this adapter has any ipv4 addresses
IPInterfaceProperties properties = adapter.GetIPProperties();
foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses)
{
if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{
// Yes it does, return this network interface.
return adapter;
}
}
}
return best;
}
/// <summary>
/// If available, returns the bytes of the physical (MAC) address for the first usable network interface
/// </summary>
public static byte[] GetMacAddressBytes()
{
var ni = GetNetworkInterface();
if (ni == null)
return null;
return ni.GetPhysicalAddress().GetAddressBytes();
}
public static IPAddress GetBroadcastAddress()
{
var ni = GetNetworkInterface();
if (ni == null)
return null;
var properties = ni.GetIPProperties();
foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses)
{
if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{
var mask = unicastAddress.IPv4Mask;
byte[] ipAdressBytes = unicastAddress.Address.GetAddressBytes();
byte[] subnetMaskBytes = mask.GetAddressBytes();
if (ipAdressBytes.Length != subnetMaskBytes.Length)
throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
byte[] broadcastAddress = new byte[ipAdressBytes.Length];
for (int i = 0; i < broadcastAddress.Length; i++)
{
broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255));
}
return new IPAddress(broadcastAddress);
}
}
return IPAddress.Broadcast;
}
/// <summary>
/// Gets my local IPv4 address (not necessarily external) and subnet mask
/// </summary>
public static IPAddress GetMyAddress(out IPAddress mask)
{
var ni = GetNetworkInterface();
if (ni == null)
{
mask = null;
return null;
}
IPInterfaceProperties properties = ni.GetIPProperties();
foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses)
{
if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork)
{
mask = unicastAddress.IPv4Mask;
return unicastAddress.Address;
}
}
mask = null;
return null;
}
public static void Sleep(int milliseconds)
{
System.Threading.Thread.Sleep(milliseconds);
}
public static IPAddress CreateAddressFromBytes(byte[] bytes)
{
return new IPAddress(bytes);
}
private static readonly SHA256 s_sha = SHA256.Create();
public static byte[] ComputeSHAHash(byte[] bytes, int offset, int count)
{
return s_sha.ComputeHash(bytes, offset, count);
}
}
public static partial class NetTime
{
private static readonly long s_timeInitialized = Stopwatch.GetTimestamp();
private static readonly double s_dInvFreq = 1.0 / (double)Stopwatch.Frequency;
/// <summary>
/// Get number of seconds since the application started
/// </summary>
public static double Now { get { return (double)(Stopwatch.GetTimestamp() - s_timeInitialized) * s_dInvFreq; } }
}
}
#endif

View File

@@ -0,0 +1,102 @@
#if WINDOWS_RUNTIME
//
//
//
// Completely broken right now
//
//
//
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Threading.Tasks;
namespace Lidgren.Network
{
public class NetAddress
{
public static readonly HostName Any = null;
}
public class NetEndPoint
{
public NetEndPoint(HostName hostname, int port) { HostName = hostname; Port = port; }
public NetEndPoint(HostName hostname, string port) { HostName = hostname; Port = int.Parse(port); }
public NetEndPoint(string hostname, int port) { HostName = (hostname == null) ? null : new HostName(hostname); Port = port; }
public HostName HostName;
public int Port;
public override string ToString() { return string.Format("{0}:{1}", HostName, Port); }
public override int GetHashCode()
{
return HostName.RawName.GetHashCode() + Port;
}
public override bool Equals(object obj)
{
var ep = obj as NetEndPoint;
if (ep == null) return false;
if (Port != ep.Port) return false;
return HostName.RawName.Equals(ep.HostName.RawName);
}
};
public static partial class NetUtility
{
[CLSCompliant(false)]
public static ulong GetPlatformSeed(int seedInc)
{
ulong seed = (ulong)Environment.TickCount + (ulong)seedInc;
return seed ^ ((ulong)(new object().GetHashCode()) << 32);
}
/// <summary>
/// Returns the physical (MAC) address for the first usable network interface
/// </summary>
public static PhysicalAddress GetMacAddress()
{
throw new NotImplementedException();
}
public static IPAddress GetBroadcastAddress()
{
throw new NotImplementedException();
}
/// <summary>
/// Gets my local IPv4 address (not necessarily external) and subnet mask
/// </summary>
public static IPAddress GetMyAddress(out IPAddress mask)
{
throw new NotImplementedException();
}
public static void Sleep(int milliseconds)
{
Task.Delay(50).Wait();
}
public static NetAddress CreateAddressFromBytes(byte[] bytes)
{
throw new NotImplementedException();
}
private static readonly SHA1CryptoServiceProvider s_sha = new SHA1CryptoServiceProvider();
public static byte[] ComputeSHAHash(byte[] bytes, int offset, int count)
{
return s_sha.ComputeHash(bytes, offset, count);
}
}
public static partial class NetTime
{
private static readonly long s_timeInitialized = Environment.TickCount;
/// <summary>
/// Get number of seconds since the application started
/// </summary>
public static double Now { get { return (double)((uint)Environment.TickCount - s_timeInitialized) / 1000.0; } }
}
}
#endif