mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Trim
This commit is contained in:
parent
842c968220
commit
4757c4be53
8 changed files with 97 additions and 189 deletions
|
|
@ -8,31 +8,37 @@ using System.IO;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace MinecraftClient.Crypto.Streams
|
namespace MinecraftClient.Crypto
|
||||||
{
|
{
|
||||||
internal class AesCfb8Stream : Stream, IAesStream
|
public class AesCfb8Stream : Stream
|
||||||
{
|
{
|
||||||
public static readonly int blockSize = 16;
|
public static readonly int blockSize = 16;
|
||||||
|
|
||||||
private readonly Aes? Aes = null;
|
private readonly Aes? Aes = null;
|
||||||
|
private readonly FastAes? FastAes = null;
|
||||||
private readonly AesContext? FastAes = null;
|
|
||||||
|
public Stream BaseStream { get; set; }
|
||||||
public System.IO.Stream BaseStream { get; set; }
|
|
||||||
|
|
||||||
private bool inStreamEnded = false;
|
private bool inStreamEnded = false;
|
||||||
|
|
||||||
private byte[] ReadStreamIV = new byte[16];
|
private byte[] ReadStreamIV = new byte[16];
|
||||||
private byte[] WriteStreamIV = new byte[16];
|
private byte[] WriteStreamIV = new byte[16];
|
||||||
|
|
||||||
public AesCfb8Stream(System.IO.Stream stream, byte[] key)
|
public AesCfb8Stream(Stream stream, byte[] key)
|
||||||
{
|
{
|
||||||
BaseStream = stream;
|
BaseStream = stream;
|
||||||
|
|
||||||
if (System.Runtime.Intrinsics.X86.Sse2.IsSupported && System.Runtime.Intrinsics.X86.Aes.IsSupported)
|
if (FastAes.IsSupport())
|
||||||
FastAes = new AesContext(key);
|
FastAes = new FastAes(key);
|
||||||
else
|
else
|
||||||
Aes = GenerateAES(key);
|
{
|
||||||
|
Aes = Aes.Create();
|
||||||
|
Aes.BlockSize = 128;
|
||||||
|
Aes.KeySize = 128;
|
||||||
|
Aes.Key = key;
|
||||||
|
Aes.Mode = CipherMode.ECB;
|
||||||
|
Aes.Padding = PaddingMode.None;
|
||||||
|
}
|
||||||
|
|
||||||
Array.Copy(key, ReadStreamIV, 16);
|
Array.Copy(key, ReadStreamIV, 16);
|
||||||
Array.Copy(key, WriteStreamIV, 16);
|
Array.Copy(key, WriteStreamIV, 16);
|
||||||
|
|
@ -77,17 +83,37 @@ namespace MinecraftClient.Crypto.Streams
|
||||||
|
|
||||||
public override int ReadByte()
|
public override int ReadByte()
|
||||||
{
|
{
|
||||||
byte[] temp = new byte[1];
|
if (inStreamEnded)
|
||||||
Read(temp, 0, 1);
|
return -1;
|
||||||
return temp[0];
|
|
||||||
|
int inputBuf = BaseStream.ReadByte();
|
||||||
|
if (inputBuf == -1)
|
||||||
|
{
|
||||||
|
inStreamEnded = true;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Span<byte> blockOutput = stackalloc byte[blockSize];
|
||||||
|
if (FastAes != null)
|
||||||
|
FastAes.EncryptEcb(ReadStreamIV, blockOutput);
|
||||||
|
else
|
||||||
|
Aes!.EncryptEcb(ReadStreamIV, blockOutput, PaddingMode.None);
|
||||||
|
|
||||||
|
// Shift left
|
||||||
|
Array.Copy(ReadStreamIV, 1, ReadStreamIV, 0, blockSize - 1);
|
||||||
|
ReadStreamIV[blockSize - 1] = (byte)inputBuf;
|
||||||
|
|
||||||
|
return (byte)(blockOutput[0] ^ inputBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
public override int Read(byte[] buffer, int outOffset, int required)
|
public override int Read(byte[] buffer, int outOffset, int required)
|
||||||
{
|
{
|
||||||
if (this.inStreamEnded)
|
if (inStreamEnded)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Span<byte> blockOutput = FastAes != null ? stackalloc byte[blockSize] : null;
|
||||||
|
|
||||||
byte[] inputBuf = new byte[blockSize + required];
|
byte[] inputBuf = new byte[blockSize + required];
|
||||||
Array.Copy(ReadStreamIV, inputBuf, blockSize);
|
Array.Copy(ReadStreamIV, inputBuf, blockSize);
|
||||||
|
|
||||||
|
|
@ -96,25 +122,35 @@ namespace MinecraftClient.Crypto.Streams
|
||||||
curRead = BaseStream.Read(inputBuf, blockSize + readed, required - readed);
|
curRead = BaseStream.Read(inputBuf, blockSize + readed, required - readed);
|
||||||
if (curRead == 0)
|
if (curRead == 0)
|
||||||
{
|
{
|
||||||
this.inStreamEnded = true;
|
inStreamEnded = true;
|
||||||
return readed;
|
return readed;
|
||||||
}
|
}
|
||||||
|
|
||||||
OrderablePartitioner<Tuple<int, int>> rangePartitioner = (curRead <= 256) ?
|
int processEnd = readed + curRead;
|
||||||
Partitioner.Create(readed, readed + curRead, 32) : Partitioner.Create(readed, readed + curRead);
|
if (FastAes != null)
|
||||||
Parallel.ForEach(rangePartitioner, (range, loopState) =>
|
|
||||||
{
|
{
|
||||||
Span<byte> blockOutput = stackalloc byte[blockSize];
|
for (int idx = readed; idx < processEnd; idx++)
|
||||||
for (int idx = range.Item1; idx < range.Item2; idx++)
|
|
||||||
{
|
{
|
||||||
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
||||||
if (FastAes != null)
|
FastAes.EncryptEcb(blockInput, blockOutput);
|
||||||
FastAes.EncryptEcb(blockInput, blockOutput);
|
|
||||||
else
|
|
||||||
Aes!.EncryptEcb(blockInput, blockOutput, PaddingMode.None);
|
|
||||||
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OrderablePartitioner<Tuple<int, int>> rangePartitioner = curRead <= 256 ?
|
||||||
|
Partitioner.Create(readed, processEnd, 32) : Partitioner.Create(readed, processEnd);
|
||||||
|
Parallel.ForEach(rangePartitioner, (range, loopState) =>
|
||||||
|
{
|
||||||
|
Span<byte> blockOutput = stackalloc byte[blockSize];
|
||||||
|
for (int idx = range.Item1; idx < range.Item2; idx++)
|
||||||
|
{
|
||||||
|
ReadOnlySpan<byte> blockInput = new(inputBuf, idx, blockSize);
|
||||||
|
Aes!.EncryptEcb(blockInput, blockOutput, PaddingMode.None);
|
||||||
|
buffer[outOffset + idx] = (byte)(blockOutput[0] ^ inputBuf[idx + blockSize]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.Copy(inputBuf, required, ReadStreamIV, 0, blockSize);
|
Array.Copy(inputBuf, required, ReadStreamIV, 0, blockSize);
|
||||||
|
|
@ -122,7 +158,7 @@ namespace MinecraftClient.Crypto.Streams
|
||||||
return required;
|
return required;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
public override long Seek(long offset, SeekOrigin origin)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
@ -134,9 +170,23 @@ namespace MinecraftClient.Crypto.Streams
|
||||||
|
|
||||||
public override void WriteByte(byte b)
|
public override void WriteByte(byte b)
|
||||||
{
|
{
|
||||||
Write(new byte[] { b }, 0, 1);
|
Span<byte> blockOutput = stackalloc byte[blockSize];
|
||||||
|
|
||||||
|
if (FastAes != null)
|
||||||
|
FastAes.EncryptEcb(WriteStreamIV, blockOutput);
|
||||||
|
else
|
||||||
|
Aes!.EncryptEcb(WriteStreamIV, blockOutput, PaddingMode.None);
|
||||||
|
|
||||||
|
byte outputBuf = (byte)(blockOutput[0] ^ b);
|
||||||
|
|
||||||
|
BaseStream.WriteByte(outputBuf);
|
||||||
|
|
||||||
|
// Shift left
|
||||||
|
Array.Copy(WriteStreamIV, 1, WriteStreamIV, 0, blockSize - 1);
|
||||||
|
WriteStreamIV[blockSize - 1] = outputBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
public override void Write(byte[] input, int offset, int required)
|
public override void Write(byte[] input, int offset, int required)
|
||||||
{
|
{
|
||||||
byte[] outputBuf = new byte[blockSize + required];
|
byte[] outputBuf = new byte[blockSize + required];
|
||||||
|
|
@ -156,16 +206,5 @@ namespace MinecraftClient.Crypto.Streams
|
||||||
|
|
||||||
Array.Copy(outputBuf, required, WriteStreamIV, 0, blockSize);
|
Array.Copy(outputBuf, required, WriteStreamIV, 0, blockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Aes GenerateAES(byte[] key)
|
|
||||||
{
|
|
||||||
Aes aes = Aes.Create();
|
|
||||||
aes.BlockSize = 128;
|
|
||||||
aes.KeySize = 128;
|
|
||||||
aes.Key = key;
|
|
||||||
aes.Mode = CipherMode.ECB;
|
|
||||||
aes.Padding = PaddingMode.None;
|
|
||||||
return aes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,17 +8,24 @@ namespace MinecraftClient.Crypto
|
||||||
{
|
{
|
||||||
// Using the AES-NI instruction set
|
// Using the AES-NI instruction set
|
||||||
// https://gist.github.com/Thealexbarney/9f75883786a9f3100408ff795fb95d85
|
// https://gist.github.com/Thealexbarney/9f75883786a9f3100408ff795fb95d85
|
||||||
public class AesContext
|
public class FastAes
|
||||||
{
|
{
|
||||||
private Vector128<byte>[] RoundKeys { get; }
|
private Vector128<byte>[] RoundKeys { get; }
|
||||||
|
|
||||||
public byte[] Iv { get; } = new byte[0x10];
|
public FastAes(Span<byte> key)
|
||||||
|
|
||||||
public AesContext(Span<byte> key)
|
|
||||||
{
|
{
|
||||||
RoundKeys = KeyExpansion(key);
|
RoundKeys = KeyExpansion(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Detects if the required instruction set is supported
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Is it supported</returns>
|
||||||
|
public static bool IsSupport()
|
||||||
|
{
|
||||||
|
return Sse2.IsSupported && Aes.IsSupported;
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public void EncryptEcb(ReadOnlySpan<byte> plaintext, Span<byte> destination)
|
public void EncryptEcb(ReadOnlySpan<byte> plaintext, Span<byte> destination)
|
||||||
{
|
{
|
||||||
|
|
@ -88,10 +95,5 @@ namespace MinecraftClient.Crypto
|
||||||
|
|
||||||
keys[i] = Sse2.Xor(s, t);
|
keys[i] = Sse2.Xor(s, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetIv(Span<byte> iv)
|
|
||||||
{
|
|
||||||
iv.Slice(0, 0x10).CopyTo(Iv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,18 +193,5 @@ namespace MinecraftClient.Crypto
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a new AES-encrypted stream for wrapping a non-encrypted stream.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="underlyingStream">Stream to encrypt</param>
|
|
||||||
/// <param name="AesKey">Key to use</param>
|
|
||||||
/// <returns>Return an appropriate stream depending on the framework being used</returns>
|
|
||||||
|
|
||||||
public static IAesStream getAesStream(Stream underlyingStream, byte[] AesKey)
|
|
||||||
{
|
|
||||||
// return new Streams.RegularAesStream(underlyingStream, AesKey);
|
|
||||||
return new Streams.AesCfb8Stream(underlyingStream, AesKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace MinecraftClient.Crypto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interface for AES stream
|
|
||||||
/// Allows to use a different implementation depending on the framework being used.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public interface IAesStream
|
|
||||||
{
|
|
||||||
int Read(byte[] buffer, int offset, int count);
|
|
||||||
void Write(byte[] buffer, int offset, int count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace MinecraftClient.Crypto.Streams
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An encrypted stream using AES, used for encrypting network data on the fly using AES.
|
|
||||||
/// This is the regular AesStream class used with the regular .NET framework from Microsoft.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
public class RegularAesStream : Stream, IAesStream
|
|
||||||
{
|
|
||||||
CryptoStream enc;
|
|
||||||
CryptoStream dec;
|
|
||||||
public RegularAesStream(Stream stream, byte[] key)
|
|
||||||
{
|
|
||||||
BaseStream = stream;
|
|
||||||
enc = new CryptoStream(stream, GenerateAES(key).CreateEncryptor(), CryptoStreamMode.Write);
|
|
||||||
dec = new CryptoStream(stream, GenerateAES(key).CreateDecryptor(), CryptoStreamMode.Read);
|
|
||||||
}
|
|
||||||
public System.IO.Stream BaseStream { get; set; }
|
|
||||||
|
|
||||||
public override bool CanRead
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanSeek
|
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanWrite
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Flush()
|
|
||||||
{
|
|
||||||
BaseStream.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Length
|
|
||||||
{
|
|
||||||
get { throw new NotSupportedException(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Position
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int ReadByte()
|
|
||||||
{
|
|
||||||
return dec.ReadByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Read(byte[] buffer, int offset, int count)
|
|
||||||
{
|
|
||||||
return dec.Read(buffer, offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Seek(long offset, System.IO.SeekOrigin origin)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SetLength(long value)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void WriteByte(byte b)
|
|
||||||
{
|
|
||||||
enc.WriteByte(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Write(byte[] buffer, int offset, int count)
|
|
||||||
{
|
|
||||||
enc.Write(buffer, offset, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Aes GenerateAES(byte[] key)
|
|
||||||
{
|
|
||||||
Aes aes = Aes.Create();
|
|
||||||
aes.Mode = CipherMode.CFB;
|
|
||||||
aes.Padding = PaddingMode.None;
|
|
||||||
aes.KeySize = 128;
|
|
||||||
aes.FeedbackSize = 8;
|
|
||||||
aes.Key = key;
|
|
||||||
aes.IV = key;
|
|
||||||
return aes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
private bool encrypted = false;
|
private bool encrypted = false;
|
||||||
private int protocolversion;
|
private int protocolversion;
|
||||||
private Tuple<Thread, CancellationTokenSource>? netRead = null;
|
private Tuple<Thread, CancellationTokenSource>? netRead = null;
|
||||||
Crypto.IAesStream s;
|
Crypto.AesCfb8Stream s;
|
||||||
TcpClient c;
|
TcpClient c;
|
||||||
|
|
||||||
public Protocol16Handler(TcpClient Client, int ProtocolVersion, IMinecraftComHandler Handler)
|
public Protocol16Handler(TcpClient Client, int ProtocolVersion, IMinecraftComHandler Handler)
|
||||||
|
|
@ -568,7 +568,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
if (pid[0] == 0xFC)
|
if (pid[0] == 0xFC)
|
||||||
{
|
{
|
||||||
readData(4);
|
readData(4);
|
||||||
s = CryptoHandler.getAesStream(c.GetStream(), secretKey);
|
s = new AesCfb8Stream(c.GetStream(), secretKey);
|
||||||
encrypted = true;
|
encrypted = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
//using System.Linq;
|
//using System.Linq;
|
||||||
|
|
@ -34,6 +35,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
/// Reading the "Block states" field: consists of 4096 entries, representing all the blocks in the chunk section.
|
/// Reading the "Block states" field: consists of 4096 entries, representing all the blocks in the chunk section.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cache">Cache for reading data</param>
|
/// <param name="cache">Cache for reading data</param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
private Chunk? ReadBlockStatesField(Queue<byte> cache)
|
private Chunk? ReadBlockStatesField(Queue<byte> cache)
|
||||||
{
|
{
|
||||||
// read Block states (Type: Paletted Container)
|
// read Block states (Type: Paletted Container)
|
||||||
|
|
@ -142,6 +144,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
/// <param name="cache">Cache for reading chunk data</param>
|
/// <param name="cache">Cache for reading chunk data</param>
|
||||||
/// <param name="cancellationToken">token to cancel the task</param>
|
/// <param name="cancellationToken">token to cancel the task</param>
|
||||||
/// <returns>true if successfully loaded</returns>
|
/// <returns>true if successfully loaded</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
public bool ProcessChunkColumnData(int chunkX, int chunkZ, ulong[]? verticalStripBitmask, Queue<byte> cache, CancellationToken cancellationToken)
|
public bool ProcessChunkColumnData(int chunkX, int chunkZ, ulong[]? verticalStripBitmask, Queue<byte> cache, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
|
@ -243,6 +246,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
/// <param name="cache">Cache for reading chunk data</param>
|
/// <param name="cache">Cache for reading chunk data</param>
|
||||||
/// <param name="cancellationToken">token to cancel the task</param>
|
/// <param name="cancellationToken">token to cancel the task</param>
|
||||||
/// <returns>true if successfully loaded</returns>
|
/// <returns>true if successfully loaded</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
public bool ProcessChunkColumnData(int chunkX, int chunkZ, ushort chunkMask, ushort chunkMask2, bool hasSkyLight, bool chunksContinuous, int currentDimension, Queue<byte> cache, CancellationToken cancellationToken)
|
public bool ProcessChunkColumnData(int chunkX, int chunkZ, ushort chunkMask, ushort chunkMask2, bool hasSkyLight, bool chunksContinuous, int currentDimension, Queue<byte> cache, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
class SocketWrapper
|
class SocketWrapper
|
||||||
{
|
{
|
||||||
TcpClient c;
|
TcpClient c;
|
||||||
IAesStream s;
|
AesCfb8Stream s;
|
||||||
bool encrypted = false;
|
bool encrypted = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -49,7 +49,7 @@ namespace MinecraftClient.Protocol.Handlers
|
||||||
{
|
{
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
throw new InvalidOperationException("Stream is already encrypted!?");
|
throw new InvalidOperationException("Stream is already encrypted!?");
|
||||||
this.s = CryptoHandler.getAesStream(c.GetStream(), secretKey);
|
this.s = new AesCfb8Stream(c.GetStream(), secretKey);
|
||||||
this.encrypted = true;
|
this.encrypted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue