1
0
mirror of https://github.com/lidgren/lidgren-network-gen3.git synced 2026-05-16 23:26:32 +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 class NetAESEncryption : NetCryptoProviderBase
{ {
public NetAESEncryption(NetPeer peer) public NetAESEncryption(NetPeer peer)
#if UNITY_WEBPLAYER
: base(peer, new RijndaelManaged())
#else
: base(peer, new AesCryptoServiceProvider()) : base(peer, new AesCryptoServiceProvider())
#endif
{ {
} }
public NetAESEncryption(NetPeer peer, string key) public NetAESEncryption(NetPeer peer, string key)
#if UNITY_WEBPLAYER
: base(peer, new RijndaelManaged())
#else
: base(peer, new AesCryptoServiceProvider()) : base(peer, new AesCryptoServiceProvider())
#endif
{ {
SetKey(key); SetKey(key);
} }
public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count) public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count)
#if UNITY_WEBPLAYER
: base(peer, new RijndaelManaged())
#else
: base(peer, new AesCryptoServiceProvider()) : base(peer, new AesCryptoServiceProvider())
#endif
{ {
SetKey(data, offset, count); 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 /// String to hash for key
/// </summary> /// </summary>
public NetXtea(NetPeer peer, string key) 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) public override void SetKey(byte[] data, int offset, int length)
{ {
var key = NetUtility.CreateSHA1Hash(data, offset, length); var key = NetUtility.ComputeSHAHash(data, offset, length);
NetException.Assert(key.Length == 16); NetException.Assert(key.Length >= 16);
SetKey(key, 0, 16); SetKey(key, 0, 16);
} }

View File

@@ -136,6 +136,10 @@
<Compile Include="NetUnreliableUnorderedReceiver.cs" /> <Compile Include="NetUnreliableUnorderedReceiver.cs" />
<Compile Include="NetUPnP.cs" /> <Compile Include="NetUPnP.cs" />
<Compile Include="NetUtility.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" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -2334,4 +2334,19 @@ namespace Lidgren.Network
return ((word >> (n % 32)) & 1) > 0; 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.Reflection;
using System.Net; using System.Net;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network namespace Lidgren.Network
{ {
/// <summary> /// <summary>
@@ -638,14 +642,14 @@ namespace Lidgren.Network
/// <summary> /// <summary>
/// Reads a stored IPv4 endpoint description /// Reads a stored IPv4 endpoint description
/// </summary> /// </summary>
public IPEndPoint ReadIPEndPoint() public NetEndPoint ReadIPEndPoint()
{ {
byte len = ReadByte(); byte len = ReadByte();
byte[] addressBytes = ReadBytes(len); byte[] addressBytes = ReadBytes(len);
int port = (int)ReadUInt16(); int port = (int)ReadUInt16();
IPAddress address = new IPAddress(addressBytes); var address = NetUtility.CreateAddressFromBytes(addressBytes);
return new IPEndPoint(address, port); return new NetEndPoint(address, port);
} }
/// <summary> /// <summary>

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,6 +3,10 @@ using System.Collections.Generic;
using System.Net; using System.Net;
using System.Threading; using System.Threading;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network namespace Lidgren.Network
{ {
public partial class NetPeer public partial class NetPeer
@@ -11,10 +15,10 @@ namespace Lidgren.Network
/// Send NetIntroduction to hostExternal and clientExternal; introducing client to host /// Send NetIntroduction to hostExternal and clientExternal; introducing client to host
/// </summary> /// </summary>
public void Introduce( public void Introduce(
IPEndPoint hostInternal, NetEndPoint hostInternal,
IPEndPoint hostExternal, NetEndPoint hostExternal,
IPEndPoint clientInternal, NetEndPoint clientInternal,
IPEndPoint clientExternal, NetEndPoint clientExternal,
string token) string token)
{ {
// send message to client // send message to client
@@ -25,7 +29,7 @@ namespace Lidgren.Network
um.Write(hostExternal); um.Write(hostExternal);
um.Write(token); um.Write(token);
Interlocked.Increment(ref um.m_recyclingCount); 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 // send message to host
um = CreateMessage(10 + token.Length + 1); um = CreateMessage(10 + token.Length + 1);
@@ -35,7 +39,7 @@ namespace Lidgren.Network
um.Write(clientExternal); um.Write(clientExternal);
um.Write(token); um.Write(token);
Interlocked.Increment(ref um.m_recyclingCount); 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> /// <summary>
@@ -49,8 +53,8 @@ namespace Lidgren.Network
NetIncomingMessage tmp = SetupReadHelperMessage(ptr, 1000); // never mind length NetIncomingMessage tmp = SetupReadHelperMessage(ptr, 1000); // never mind length
byte hostByte = tmp.ReadByte(); byte hostByte = tmp.ReadByte();
IPEndPoint remoteInternal = tmp.ReadIPEndPoint(); NetEndPoint remoteInternal = tmp.ReadIPEndPoint();
IPEndPoint remoteExternal = tmp.ReadIPEndPoint(); NetEndPoint remoteExternal = tmp.ReadIPEndPoint();
string token = tmp.ReadString(); string token = tmp.ReadString();
bool isHost = (hostByte != 0); bool isHost = (hostByte != 0);
@@ -67,7 +71,7 @@ namespace Lidgren.Network
punch.Write(hostByte); punch.Write(hostByte);
punch.Write(token); punch.Write(token);
Interlocked.Increment(ref punch.m_recyclingCount); 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); LogDebug("NAT punch sent to " + remoteInternal);
// send external punch // send external punch
@@ -76,7 +80,7 @@ namespace Lidgren.Network
punch.Write(hostByte); punch.Write(hostByte);
punch.Write(token); punch.Write(token);
Interlocked.Increment(ref punch.m_recyclingCount); 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); LogDebug("NAT punch sent to " + remoteExternal);
} }
@@ -84,7 +88,7 @@ namespace Lidgren.Network
/// <summary> /// <summary>
/// Called when receiving a NatPunchMessage from a remote endpoint /// Called when receiving a NatPunchMessage from a remote endpoint
/// </summary> /// </summary>
private void HandleNatPunch(int ptr, IPEndPoint senderEndPoint) private void HandleNatPunch(int ptr, NetEndPoint senderEndPoint)
{ {
NetIncomingMessage tmp = SetupReadHelperMessage(ptr, 1000); // never mind length 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); 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); NetIncomingMessage punchSuccess = CreateIncomingMessage(NetIncomingMessageType.NatIntroductionSuccess, 10);
punchSuccess.m_senderEndPoint = senderEndPoint; punchSuccess.m_senderEndPoint = senderEndPoint;
@@ -113,7 +117,7 @@ namespace Lidgren.Network
punch.Write((byte)0); punch.Write((byte)0);
punch.Write(token); punch.Write(token);
Interlocked.Increment(ref punch.m_recyclingCount); 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.Net;
using System.Threading; using System.Threading;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network namespace Lidgren.Network
{ {
public partial class NetPeer public partial class NetPeer
@@ -14,7 +18,8 @@ namespace Lidgren.Network
NetOutgoingMessage um = CreateMessage(0); NetOutgoingMessage um = CreateMessage(0);
um.m_messageType = NetMessageType.Discovery; um.m_messageType = NetMessageType.Discovery;
Interlocked.Increment(ref um.m_recyclingCount); 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> /// <summary>
@@ -22,28 +27,28 @@ namespace Lidgren.Network
/// </summary> /// </summary>
public bool DiscoverKnownPeer(string host, int serverPort) public bool DiscoverKnownPeer(string host, int serverPort)
{ {
IPAddress address = NetUtility.Resolve(host); var address = NetUtility.Resolve(host);
if (address == null) if (address == null)
return false; return false;
DiscoverKnownPeer(new IPEndPoint(address, serverPort)); DiscoverKnownPeer(new NetEndPoint(address, serverPort));
return true; return true;
} }
/// <summary> /// <summary>
/// Emit a discovery signal to a single known host /// Emit a discovery signal to a single known host
/// </summary> /// </summary>
public void DiscoverKnownPeer(IPEndPoint endPoint) public void DiscoverKnownPeer(NetEndPoint endPoint)
{ {
NetOutgoingMessage om = CreateMessage(0); NetOutgoingMessage om = CreateMessage(0);
om.m_messageType = NetMessageType.Discovery; om.m_messageType = NetMessageType.Discovery;
om.m_recyclingCount = 1; om.m_recyclingCount = 1;
m_unsentUnconnectedMessages.Enqueue(new NetTuple<IPEndPoint, NetOutgoingMessage>(endPoint, om)); m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(endPoint, om));
} }
/// <summary> /// <summary>
/// Send a discovery response message /// Send a discovery response message
/// </summary> /// </summary>
public void SendDiscoveryResponse(NetOutgoingMessage msg, IPEndPoint recipient) public void SendDiscoveryResponse(NetOutgoingMessage msg, NetEndPoint recipient)
{ {
if (recipient == null) if (recipient == null)
throw new ArgumentNullException("recipient"); throw new ArgumentNullException("recipient");
@@ -58,7 +63,7 @@ namespace Lidgren.Network
msg.m_messageType = NetMessageType.DiscoveryResponse; msg.m_messageType = NetMessageType.DiscoveryResponse;
Interlocked.Increment(ref msg.m_recyclingCount); 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 using System;
#define IS_MAC_AVAILABLE
#endif
using System;
using System.Net; using System.Net;
using System.Threading; using System.Threading;
using System.Diagnostics; using System.Diagnostics;
@@ -10,6 +6,10 @@ using System.Security.Cryptography;
using System.Net.Sockets; using System.Net.Sockets;
using System.Collections.Generic; using System.Collections.Generic;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network namespace Lidgren.Network
{ {
public partial class NetPeer public partial class NetPeer
@@ -30,9 +30,9 @@ namespace Lidgren.Network
internal readonly NetPeerConfiguration m_configuration; internal readonly NetPeerConfiguration m_configuration;
private readonly NetQueue<NetIncomingMessage> m_releasedIncomingMessages; 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 readonly NetPeerStatistics m_statistics;
internal long m_uniqueIdentifier; internal long m_uniqueIdentifier;
@@ -133,7 +133,7 @@ namespace Lidgren.Network
m_socket.SendBufferSize = m_configuration.SendBufferSize; m_socket.SendBufferSize = m_configuration.SendBufferSize;
m_socket.Blocking = false; 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); m_socket.Bind(ep);
try try
@@ -148,7 +148,7 @@ namespace Lidgren.Network
// ignore; SIO_UDP_CONNRESET not supported on this platform // 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); LogDebug("Socket bound to " + boundEp + ": " + m_socket.IsBound);
m_listenPort = boundEp.Port; m_listenPort = boundEp.Port;
} }
@@ -179,34 +179,14 @@ namespace Lidgren.Network
m_readHelperMessage = new NetIncomingMessage(NetIncomingMessageType.Error); m_readHelperMessage = new NetIncomingMessage(NetIncomingMessageType.Error);
m_readHelperMessage.m_data = m_receiveBuffer; m_readHelperMessage.m_data = m_receiveBuffer;
byte[] macBytes = new byte[8]; byte[] macBytes = NetUtility.GetMacAddressBytes();
MWCRandom.Instance.NextBytes(macBytes);
#if IS_MAC_AVAILABLE var boundEp = m_socket.LocalEndPoint as NetEndPoint;
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;
byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode()); byte[] epBytes = BitConverter.GetBytes(boundEp.GetHashCode());
byte[] combined = new byte[epBytes.Length + macBytes.Length]; byte[] combined = new byte[epBytes.Length + macBytes.Length];
Array.Copy(epBytes, 0, combined, 0, epBytes.Length); Array.Copy(epBytes, 0, combined, 0, epBytes.Length);
Array.Copy(macBytes, 0, combined, epBytes.Length, macBytes.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; m_status = NetPeerStatus.Running;
} }
@@ -270,8 +250,8 @@ namespace Lidgren.Network
// one final heartbeat, will send stuff and do disconnect // one final heartbeat, will send stuff and do disconnect
Heartbeat(); Heartbeat();
Thread.Sleep(10); NetUtility.Sleep(10);
lock (m_initializeLock) lock (m_initializeLock)
{ {
try try
@@ -393,7 +373,7 @@ namespace Lidgren.Network
m_executeFlushSendQueue = false; m_executeFlushSendQueue = false;
// send unsent unconnected messages // send unsent unconnected messages
NetTuple<IPEndPoint, NetOutgoingMessage> unsent; NetTuple<NetEndPoint, NetOutgoingMessage> unsent;
while (m_unsentUnconnectedMessages.TryDequeue(out unsent)) while (m_unsentUnconnectedMessages.TryDequeue(out unsent))
{ {
NetOutgoingMessage om = unsent.Item2; NetOutgoingMessage om = unsent.Item2;
@@ -458,7 +438,7 @@ namespace Lidgren.Network
//LogVerbose("Received " + bytesReceived + " bytes"); //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) if (m_upnp != null && now < m_upnp.m_discoveryResponseDeadline && bytesReceived > 32)
{ {
@@ -596,7 +576,7 @@ namespace Lidgren.Network
m_executeFlushSendQueue = true; 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)) 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)) 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; NetConnection shake;
if (m_handshakes.TryGetValue(senderEndPoint, out shake)) if (m_handshakes.TryGetValue(senderEndPoint, out shake))

View File

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

View File

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

View File

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

View File

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

View File

@@ -14,17 +14,7 @@ namespace Lidgren.Network
private static readonly NetBigInteger N = new NetBigInteger("0115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); private static readonly NetBigInteger N = new NetBigInteger("0115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
private static readonly NetBigInteger g = NetBigInteger.Two; private static readonly NetBigInteger g = NetBigInteger.Two;
private static readonly NetBigInteger k = ComputeMultiplier(); 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> /// <summary>
/// Compute multiplier (k) /// Compute multiplier (k)
/// </summary> /// </summary>
@@ -36,9 +26,7 @@ namespace Lidgren.Network
string ccstr = one + two.PadLeft(one.Length, '0'); string ccstr = one + two.PadLeft(one.Length, '0');
byte[] cc = NetUtility.ToByteArray(ccstr); byte[] cc = NetUtility.ToByteArray(ccstr);
var sha = GetHashAlgorithm(); var ccHashed = NetUtility.ComputeSHAHash(cc);
var ccHashed = sha.ComputeHash(cc);
return new NetBigInteger(NetUtility.ToHexString(ccHashed), 16); return new NetBigInteger(NetUtility.ToHexString(ccHashed), 16);
} }
@@ -67,17 +55,15 @@ namespace Lidgren.Network
/// </summary> /// </summary>
public static byte[] ComputePrivateKey(string username, string password, byte[] salt) public static byte[] ComputePrivateKey(string username, string password, byte[] salt)
{ {
var sha = GetHashAlgorithm();
byte[] tmp = Encoding.UTF8.GetBytes(username + ":" + password); 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]; byte[] total = new byte[innerHash.Length + salt.Length];
Buffer.BlockCopy(salt, 0, total, 0, salt.Length); Buffer.BlockCopy(salt, 0, total, 0, salt.Length);
Buffer.BlockCopy(innerHash, 0, total, salt.Length, innerHash.Length); Buffer.BlockCopy(innerHash, 0, total, salt.Length, innerHash.Length);
// x ie. H(salt || H(username || ":" || password)) // 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> /// <summary>
@@ -93,15 +79,6 @@ namespace Lidgren.Network
return serverVerifier.ToByteArrayUnsigned(); return serverVerifier.ToByteArrayUnsigned();
} }
/// <summary>
/// SHA hash data
/// </summary>
public static byte[] Hash(byte[] data)
{
var sha = GetHashAlgorithm();
return sha.ComputeHash(data);
}
/// <summary> /// <summary>
/// Compute client public ephemeral value (A) /// Compute client public ephemeral value (A)
/// </summary> /// </summary>
@@ -144,8 +121,7 @@ namespace Lidgren.Network
byte[] cc = NetUtility.ToByteArray(ccstr); byte[] cc = NetUtility.ToByteArray(ccstr);
var sha = GetHashAlgorithm(); var ccHashed = NetUtility.ComputeSHAHash(cc);
var ccHashed = sha.ComputeHash(cc);
return new NetBigInteger(NetUtility.ToHexString(ccHashed), 16).ToByteArrayUnsigned(); return new NetBigInteger(NetUtility.ToHexString(ccHashed), 16).ToByteArrayUnsigned();
} }
@@ -187,8 +163,7 @@ namespace Lidgren.Network
/// </summary> /// </summary>
public static NetXtea CreateEncryption(NetPeer peer, byte[] sessionValue) public static NetXtea CreateEncryption(NetPeer peer, byte[] sessionValue)
{ {
var sha = GetHashAlgorithm(); var hash = NetUtility.ComputeSHAHash(sessionValue);
var hash = sha.ComputeHash(sessionValue);
var key = new byte[16]; var key = new byte[16];
for(int i=0;i<16;i++) 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. USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#define IS_STOPWATCH_AVAILABLE
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@@ -29,25 +27,8 @@ namespace Lidgren.Network
/// <summary> /// <summary>
/// Time service /// Time service
/// </summary> /// </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> /// <summary>
/// Given seconds it will output a human friendly readable string (milliseconds if less than 60 seconds) /// Given seconds it will output a human friendly readable string (milliseconds if less than 60 seconds)
/// </summary> /// </summary>

View File

@@ -5,6 +5,10 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
#if !__NOIPENDPOINT__
using NetEndPoint = System.Net.IPEndPoint;
#endif
namespace Lidgren.Network namespace Lidgren.Network
{ {
/// <summary> /// <summary>
@@ -73,11 +77,11 @@ namespace Lidgren.Network
m_peer.LogDebug("Attempting UPnP discovery"); m_peer.LogDebug("Attempting UPnP discovery");
peer.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); 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); peer.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
// allow some extra time for router to respond // 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_discoveryResponseDeadline = NetTime.Now + 6.0; // arbitrarily chosen number, router gets 6 seconds to respond
m_status = UPnPStatus.Discovering; m_status = UPnPStatus.Discovering;
@@ -182,7 +186,7 @@ namespace Lidgren.Network
"AddPortMapping"); "AddPortMapping");
m_peer.LogDebug("Sent UPnP port forward request"); m_peer.LogDebug("Sent UPnP port forward request");
System.Threading.Thread.Sleep(50); NetUtility.Sleep(50);
} }
catch (Exception ex) 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 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE. 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 #endif
using System; using System;
using System.Net; using System.Net;
#if IS_FULL_NET_AVAILABLE
using System.Net.NetworkInformation;
#endif
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -38,24 +36,24 @@ namespace Lidgren.Network
/// <summary> /// <summary>
/// Utility methods /// Utility methods
/// </summary> /// </summary>
public static class NetUtility public static partial class NetUtility
{ {
/// <summary> /// <summary>
/// Resolve endpoint callback /// Resolve endpoint callback
/// </summary> /// </summary>
public delegate void ResolveEndPointCallback(IPEndPoint endPoint); public delegate void ResolveEndPointCallback(NetEndPoint endPoint);
/// <summary> /// <summary>
/// Resolve address callback /// Resolve address callback
/// </summary> /// </summary>
public delegate void ResolveAddressCallback(IPAddress adr); public delegate void ResolveAddressCallback(NetAddress adr);
/// <summary> /// <summary>
/// Get IPv4 endpoint from notation (xxx.xxx.xxx.xxx) or hostname and port number (asynchronous version) /// Get IPv4 endpoint from notation (xxx.xxx.xxx.xxx) or hostname and port number (asynchronous version)
/// </summary> /// </summary>
public static void ResolveAsync(string ipOrHost, int port, ResolveEndPointCallback callback) public static void ResolveAsync(string ipOrHost, int port, ResolveEndPointCallback callback)
{ {
ResolveAsync(ipOrHost, delegate(IPAddress adr) ResolveAsync(ipOrHost, delegate(NetAddress adr)
{ {
if (adr == null) if (adr == null)
{ {
@@ -63,7 +61,7 @@ namespace Lidgren.Network
} }
else else
{ {
callback(new IPEndPoint(adr, port)); callback(new NetEndPoint(adr, port));
} }
}); });
} }
@@ -71,10 +69,10 @@ namespace Lidgren.Network
/// <summary> /// <summary>
/// Get IPv4 endpoint from notation (xxx.xxx.xxx.xxx) or hostname and port number /// Get IPv4 endpoint from notation (xxx.xxx.xxx.xxx) or hostname and port number
/// </summary> /// </summary>
public static IPEndPoint Resolve(string ipOrHost, int port) public static NetEndPoint Resolve(string ipOrHost, int port)
{ {
IPAddress adr = Resolve(ipOrHost); var adr = Resolve(ipOrHost);
return new IPEndPoint(adr, port); return new NetEndPoint(adr, port);
} }
/// <summary> /// <summary>
@@ -87,8 +85,8 @@ namespace Lidgren.Network
ipOrHost = ipOrHost.Trim(); ipOrHost = ipOrHost.Trim();
IPAddress ipAddress = null; NetAddress ipAddress = null;
if (IPAddress.TryParse(ipOrHost, out ipAddress)) if (NetAddress.TryParse(ipOrHost, out ipAddress))
{ {
if (ipAddress.AddressFamily == AddressFamily.InterNetwork) if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{ {
@@ -129,7 +127,7 @@ namespace Lidgren.Network
} }
// check each entry for a valid IP address // 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) if (ipCurrent.AddressFamily == AddressFamily.InterNetwork)
{ {
@@ -158,15 +156,15 @@ namespace Lidgren.Network
/// <summary> /// <summary>
/// Get IPv4 address from notation (xxx.xxx.xxx.xxx) or hostname /// Get IPv4 address from notation (xxx.xxx.xxx.xxx) or hostname
/// </summary> /// </summary>
public static IPAddress Resolve(string ipOrHost) public static NetAddress Resolve(string ipOrHost)
{ {
if (string.IsNullOrEmpty(ipOrHost)) if (string.IsNullOrEmpty(ipOrHost))
throw new ArgumentException("Supplied string must not be empty", "ipOrHost"); throw new ArgumentException("Supplied string must not be empty", "ipOrHost");
ipOrHost = ipOrHost.Trim(); ipOrHost = ipOrHost.Trim();
IPAddress ipAddress = null; NetAddress ipAddress = null;
if (IPAddress.TryParse(ipOrHost, out ipAddress)) if (NetAddress.TryParse(ipOrHost, out ipAddress))
{ {
if (ipAddress.AddressFamily == AddressFamily.InterNetwork) if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
return ipAddress; 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> /// <summary>
/// Create a hex string from an Int64 value /// Create a hex string from an Int64 value
/// </summary> /// </summary>
@@ -282,123 +230,11 @@ namespace Lidgren.Network
} }
return new string(c); 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> /// <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> /// </summary>
public static IPAddress GetMyAddress(out IPAddress mask) public static bool IsLocal(NetEndPoint endPoint)
{
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)
{ {
if (endPoint == null) if (endPoint == null)
return false; return false;
@@ -408,10 +244,10 @@ namespace Lidgren.Network
/// <summary> /// <summary>
/// Returns true if the IPAddress supplied is on the same subnet as this host /// Returns true if the IPAddress supplied is on the same subnet as this host
/// </summary> /// </summary>
public static bool IsLocal(IPAddress remote) public static bool IsLocal(NetAddress remote)
{ {
IPAddress mask; NetAddress mask;
IPAddress local = GetMyAddress(out mask); var local = GetMyAddress(out mask);
if (mask == null) if (mask == null)
return false; return false;
@@ -602,31 +438,10 @@ namespace Lidgren.Network
return bdr.ToString(); return bdr.ToString();
} }
/// <summary> public static byte[] ComputeSHAHash(byte[] bytes)
/// Create a SHA1 digest from a string
/// </summary>
public static byte[] CreateSHA1Hash(string key)
{ {
using (var sha = new SHA1CryptoServiceProvider()) // this is defined in the platform specific files
return sha.ComputeHash(Encoding.UTF8.GetBytes(key)); return ComputeSHAHash(bytes, 0, bytes.Length);
}
/// <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);
} }
} }
} }

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