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

Added NetConnection.CanSendImmediately() to determine if the sliding window is full

Recycle outgoing dropped messages
Encryption using CryptoProviders refactored 
Added NetUnreliableSizeBehaviour to configure behaviour for unreliable messages above MTU
Debug stats show number of received fragments
This commit is contained in:
lidgren
2014-10-10 15:25:54 +00:00
parent 7822a14526
commit 0d2955637d
26 changed files with 217 additions and 680 deletions

View File

@@ -1,180 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// AES encryption
/// </summary>
public class NetAESEncryption : NetEncryption
public class NetAESEncryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> s_keysizes;
private static readonly List<int> s_blocksizes;
static NetAESEncryption()
public NetAESEncryption(NetPeer peer)
: base(peer, new AesCryptoServiceProvider())
{
#if !IOS && !__ANDROID__ && !UNITY_4_5
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in aes.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in aes.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_blocksizes = temp;
#endif
}
/// <summary>
/// NetAESEncryption constructor
/// </summary>
public NetAESEncryption(NetPeer peer, byte[] key, byte[] iv)
: base(peer)
{
if (!s_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
if (!s_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetAESEncryption constructor
/// </summary>
public NetAESEncryption(NetPeer peer, string key, int bitsize)
: base(peer)
{
if (!s_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[s_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetAESEncryption constructor
/// </summary>
public NetAESEncryption(NetPeer peer, string key)
: this(peer, key, s_keysizes[0])
: base(peer, new AesCryptoServiceProvider())
{
SetKey(key);
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public override bool Encrypt(NetOutgoingMessage msg)
public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new AesCryptoServiceProvider())
{
#if !IOS && !__ANDROID__ && !UNITY_4_5
try
{
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch(Exception ex)
{
m_peer.LogWarning("Encryption failed: " + ex);
return false;
}
return true;
#else
return false;
#endif
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public override bool Decrypt(NetIncomingMessage msg)
{
#if !IOS && !__ANDROID__ && !UNITY_4_5
try
{
// nested usings are fun!
using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch (Exception ex)
{
m_peer.LogWarning("Decryption failed: " + ex);
return false;
}
return true;
#else
return false;
#endif
SetKey(data, offset, count);
}
}
}

View File

@@ -1,170 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// DES encryption
/// </summary>
public class NetDESEncryption : NetEncryption
public class NetDESEncryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> s_keysizes;
private static readonly List<int> s_blocksizes;
static NetDESEncryption()
public NetDESEncryption(NetPeer peer)
: base(peer, new DESCryptoServiceProvider())
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in des.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in des.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_blocksizes = temp;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(NetPeer peer, byte[] key, byte[] iv)
: base(peer)
{
if (!s_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
if (!s_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(NetPeer peer, string key, int bitsize)
: base(peer)
{
if (!s_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[s_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(NetPeer peer, string key)
: this(peer, key, s_keysizes[0])
: base(peer, new DESCryptoServiceProvider())
{
SetKey(key);
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public override bool Encrypt(NetOutgoingMessage msg)
public NetDESEncryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new DESCryptoServiceProvider())
{
try
{
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch (Exception ex)
{
m_peer.LogWarning("Encryption failed: " + ex);
return false;
}
return true;
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public override bool Decrypt(NetIncomingMessage msg)
{
try
{
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch (Exception ex)
{
m_peer.LogWarning("Decryption failed: " + ex);
return false;
}
return true;
SetKey(data, offset, count);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace Lidgren.Network
{
@@ -23,6 +24,14 @@ namespace Lidgren.Network
m_peer = peer;
}
public void SetKey(string str)
{
var bytes = System.Text.Encoding.ASCII.GetBytes(str);
SetKey(bytes, 0, bytes.Length);
}
public abstract void SetKey(byte[] data, int offset, int count);
/// <summary>
/// Encrypt an outgoing message in place
/// </summary>

View File

@@ -1,173 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// RC2 encryption
/// </summary>
public class NetRC2Encryption : NetEncryption
public class NetRC2Encryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> s_keysizes;
private static readonly List<int> s_blocksizes;
static NetRC2Encryption()
public NetRC2Encryption(NetPeer peer)
: base(peer, new RC2CryptoServiceProvider())
{
RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in rc2.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in rc2.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_blocksizes = temp;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
public NetRC2Encryption(NetPeer peer, byte[] key, byte[] iv)
: base(peer)
{
if (!s_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
if (!s_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
public NetRC2Encryption(NetPeer peer, string key, int bitsize)
: base(peer)
{
if (!s_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[s_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
/// <param name="peer"></param>
/// <param name="key"></param>
public NetRC2Encryption(NetPeer peer, string key)
: this(peer, key, s_keysizes[0])
: base(peer, new RC2CryptoServiceProvider())
{
SetKey(key);
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public override bool Encrypt(NetOutgoingMessage msg)
public NetRC2Encryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new RC2CryptoServiceProvider())
{
try
{
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch (Exception ex)
{
m_peer.LogWarning("Encryption failed: " + ex);
return false;
}
return true;
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public override bool Decrypt(NetIncomingMessage msg)
{
try
{
// nested usings are fun!
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch (Exception ex)
{
m_peer.LogWarning("Decryption failed: " + ex);
return false;
}
return true;
SetKey(data, offset, count);
}
}
}
}

View File

@@ -1,170 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// Triple DES encryption
/// </summary>
public class NetTripleDESEncryption : NetEncryption
public class NetTripleDESEncryption : NetCryptoProviderBase
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> s_keysizes;
private static readonly List<int> s_blocksizes;
static NetTripleDESEncryption()
public NetTripleDESEncryption(NetPeer peer)
: base(peer, new TripleDESCryptoServiceProvider())
{
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in tripleDES.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in tripleDES.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
s_blocksizes = temp;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(NetPeer peer, byte[] key, byte[] iv)
: base(peer)
{
if (!s_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
if (!s_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(NetPeer peer, string key, int bitsize)
: base(peer)
{
if (!s_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(s_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[s_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(NetPeer peer, string key)
: this(peer, key, s_keysizes[0])
: base(peer, new TripleDESCryptoServiceProvider())
{
SetKey(key);
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public override bool Encrypt(NetOutgoingMessage msg)
public NetTripleDESEncryption(NetPeer peer, byte[] data, int offset, int count)
: base(peer, new TripleDESCryptoServiceProvider())
{
try
{
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch (Exception ex)
{
m_peer.LogWarning("Encryption failed: " + ex);
return false;
}
return true;
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public override bool Decrypt(NetIncomingMessage msg)
{
try
{
// nested usings are fun!
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
var memoryStream = new MemoryStream();
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
cryptoStream.Close();
m_peer.Recycle(msg.m_data);
var arr = memoryStream.ToArray();
msg.m_data = arr;
msg.m_bitLength = arr.Length * 8;
}
}
}
}
catch (Exception ex)
{
m_peer.LogWarning("Decryption failed: " + ex);
return false;
}
return true;
SetKey(data, offset, count);
}
}
}
}

View File

@@ -20,6 +20,12 @@ namespace Lidgren.Network
m_key = key;
}
public override void SetKey(byte[] data, int offset, int count)
{
m_key = new byte[count];
Array.Copy(data, offset, m_key, 0, count);
}
/// <summary>
/// NetXorEncryption constructor
/// </summary>

View File

@@ -87,6 +87,13 @@ namespace Lidgren.Network
{
}
public override void SetKey(byte[] data, int offset, int length)
{
var key = NetUtility.CreateSHA1Hash(data, offset, length);
NetException.Assert(key.Length == 16);
SetKey(key, 0, 16);
}
/// <summary>
/// Encrypts a block of bytes
/// </summary>