This commit is contained in:
BruceChen 2022-08-28 14:57:44 +08:00
parent 4757c4be53
commit d10ad138f1
14 changed files with 110 additions and 56 deletions

View file

@ -16,14 +16,14 @@ namespace MinecraftClient.Crypto
private readonly Aes? Aes = null;
private readonly FastAes? FastAes = null;
public Stream BaseStream { get; set; }
private bool inStreamEnded = false;
private byte[] ReadStreamIV = new byte[16];
private byte[] WriteStreamIV = new byte[16];
public Stream BaseStream { get; set; }
public AesCfb8Stream(Stream stream, byte[] key)
{
BaseStream = stream;

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using MinecraftClient.Mapping.BlockPalettes;
@ -106,6 +107,7 @@ namespace MinecraftClient.Mapping
/// Get a block of the specified type and metadata OR block state
/// </summary>
/// <param name="typeAndMeta">Type and metadata packed in the same value OR block state</param>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public Block(ushort typeAndMeta)
{
this.blockIdAndMeta = typeAndMeta;

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
@ -60,6 +61,7 @@ namespace MinecraftClient.Mapping
/// <param name="blockY">Block Y</param>
/// <param name="blockZ">Block Z</param>
/// <param name="block">Block</param>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public void SetWithoutCheck(int blockX, int blockY, int blockZ, Block block)
{
blocks[blockX, blockY, blockZ] = block;

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
namespace MinecraftClient.Mapping
@ -54,6 +55,7 @@ namespace MinecraftClient.Mapping
/// <param name="blockX">Location of the block into the chunk</param>
/// <param name="blockY">Location of the block into the world</param>
/// <param name="blockZ">Location of the block into the chunk</param>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public Location(int chunkX, int chunkZ, int blockX, int blockY, int blockZ)
{
X = chunkX * Chunk.SizeX + blockX;

View file

@ -63,6 +63,8 @@
using System;
using System.Runtime.CompilerServices;
namespace Ionic.Zlib
{
sealed class InflateBlocks
@ -140,6 +142,7 @@ namespace Ionic.Zlib
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
internal int Process(int r)
{
int t; // temporary storage
@ -673,6 +676,7 @@ namespace Ionic.Zlib
}
// copy as much as possible from the sliding window to the output area
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
internal int Flush(int r)
{
int nBytes;
@ -799,6 +803,7 @@ namespace Ionic.Zlib
tree = null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
internal int Process(InflateBlocks blocks, int r)
{
int j; // temporary storage
@ -1160,6 +1165,7 @@ namespace Ionic.Zlib
// (the maximum string length) and number of input bytes available
// at least ten. The ten bytes are six bytes for the longest length/
// distance pair plus four bytes for overloading the bit buffer.
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z)
{
@ -1509,6 +1515,7 @@ namespace Ionic.Zlib
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
internal int Inflate(FlushType flush)
{
int b;

View file

@ -89,6 +89,7 @@
using System;
using System.Runtime.CompilerServices;
using Interop=System.Runtime.InteropServices;
namespace Ionic.Zlib
@ -491,6 +492,7 @@ namespace Ionic.Zlib
/// adler = Adler.Adler32(adler, buffer, index, length);
/// </code>
/// </example>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static uint Adler32(uint adler, byte[] buf, int index, int len)
{
if (buf == null)

View file

@ -26,6 +26,7 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
namespace Ionic.Zlib
{
@ -170,6 +171,7 @@ namespace Ionic.Zlib
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private void finish()
{
if (_z == null) return;
@ -299,6 +301,7 @@ namespace Ionic.Zlib
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public override void Close()
{
if (_stream == null) return;
@ -413,7 +416,7 @@ namespace Ionic.Zlib
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count)
{
// According to MS documentation, any implementation of the IO.Stream.Read function must:

View file

@ -65,6 +65,7 @@
using System;
using System.Runtime.CompilerServices;
using Interop=System.Runtime.InteropServices;
namespace Ionic.Zlib
@ -351,6 +352,7 @@ namespace Ionic.Zlib
/// </example>
/// <param name="flush">The flush to use when inflating.</param>
/// <returns>Z_OK if everything goes well.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public int Inflate(FlushType flush)
{
if (istate == null)

View file

@ -27,6 +27,7 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
namespace Ionic.Zlib
{
@ -409,6 +410,7 @@ namespace Ionic.Zlib
/// <param name="disposing">
/// indicates whether the Dispose method was invoked by user code.
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
protected override void Dispose(bool disposing)
{
try
@ -543,6 +545,7 @@ namespace Ionic.Zlib
/// <param name="count">the number of bytes to read.</param>
///
/// <returns>the number of bytes read</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public override int Read(byte[] buffer, int offset, int count)
{
if (_disposed) throw new ObjectDisposedException("ZlibStream");

View file

@ -8,6 +8,7 @@ using MinecraftClient.Crypto;
using MinecraftClient.Inventory;
using MinecraftClient.Mapping.EntityPalettes;
using MinecraftClient.Inventory.ItemPalettes;
using System.Runtime.CompilerServices;
namespace MinecraftClient.Protocol.Handlers
{
@ -36,6 +37,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <param name="offset">Amount of bytes to read</param>
/// <param name="cache">Cache of bytes to read from</param>
/// <returns>The data read from the cache as an array</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public byte[] ReadData(int offset, Queue<byte> cache)
{
byte[] result = new byte[offset];
@ -44,11 +46,24 @@ namespace MinecraftClient.Protocol.Handlers
return result;
}
/// <summary>
/// Remove some data from the cache
/// </summary>
/// <param name="offset">Amount of bytes to drop</param>
/// <param name="cache">Cache of bytes to drop</param>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public void DropData(int offset, Queue<byte> cache)
{
while (offset-- > 0)
cache.Dequeue();
}
/// <summary>
/// Read a string from a cache of bytes and remove it from the cache
/// </summary>
/// <param name="cache">Cache of bytes to read from</param>
/// <returns>The string</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public string ReadNextString(Queue<byte> cache)
{
int length = ReadNextVarInt(cache);
@ -63,6 +78,7 @@ namespace MinecraftClient.Protocol.Handlers
/// Read a boolean from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The boolean value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public bool ReadNextBool(Queue<byte> cache)
{
return ReadNextByte(cache) != 0x00;
@ -72,55 +88,65 @@ namespace MinecraftClient.Protocol.Handlers
/// Read a short integer from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The short integer value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public short ReadNextShort(Queue<byte> cache)
{
byte[] rawValue = ReadData(2, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToInt16(rawValue, 0);
Span<byte> rawValue = stackalloc byte[2];
for (int i = (2 - 1); i >= 0; --i) //Endianness
rawValue[i] = cache.Dequeue();
return BitConverter.ToInt16(rawValue);
}
/// <summary>
/// Read an integer from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The integer value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public int ReadNextInt(Queue<byte> cache)
{
byte[] rawValue = ReadData(4, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToInt32(rawValue, 0);
Span<byte> rawValue = stackalloc byte[4];
for (int i = (4 - 1); i >= 0; --i) //Endianness
rawValue[i] = cache.Dequeue();
return BitConverter.ToInt32(rawValue);
}
/// <summary>
/// Read a long integer from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The unsigned long integer value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public long ReadNextLong(Queue<byte> cache)
{
byte[] rawValue = ReadData(8, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToInt64(rawValue, 0);
Span<byte> rawValue = stackalloc byte[8];
for (int i = (8 - 1); i >= 0; --i) //Endianness
rawValue[i] = cache.Dequeue();
return BitConverter.ToInt64(rawValue);
}
/// <summary>
/// Read an unsigned short integer from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The unsigned short integer value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public ushort ReadNextUShort(Queue<byte> cache)
{
byte[] rawValue = ReadData(2, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToUInt16(rawValue, 0);
Span<byte> rawValue = stackalloc byte[2];
for (int i = (2 - 1); i >= 0; --i) //Endianness
rawValue[i] = cache.Dequeue();
return BitConverter.ToUInt16(rawValue);
}
/// <summary>
/// Read an unsigned long integer from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The unsigned long integer value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public ulong ReadNextULong(Queue<byte> cache)
{
byte[] rawValue = ReadData(8, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToUInt64(rawValue, 0);
Span<byte> rawValue = stackalloc byte[8];
for (int i = (8 - 1); i >= 0; --i) //Endianness
rawValue[i] = cache.Dequeue();
return BitConverter.ToUInt64(rawValue);
}
/// <summary>
@ -172,7 +198,9 @@ namespace MinecraftClient.Protocol.Handlers
/// <returns>The uuid</returns>
public Guid ReadNextUUID(Queue<byte> cache)
{
byte[] javaUUID = ReadData(16, cache);
Span<byte> javaUUID = stackalloc byte[16];
for (int i = 0; i < 16; ++i)
javaUUID[i] = cache.Dequeue();
Guid guid = new Guid(javaUUID);
if (BitConverter.IsLittleEndian)
guid = guid.ToLittleEndian();
@ -184,6 +212,7 @@ namespace MinecraftClient.Protocol.Handlers
/// </summary>
/// <param name="cache">Cache of bytes to read from</param>
/// <returns>The byte array</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public byte[] ReadNextByteArray(Queue<byte> cache)
{
int len = protocolversion >= Protocol18Handler.MC_1_8_Version
@ -196,6 +225,7 @@ namespace MinecraftClient.Protocol.Handlers
/// Reads a length-prefixed array of unsigned long integers and removes it from the cache
/// </summary>
/// <returns>The unsigned long integer values</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public ulong[] ReadNextULongArray(Queue<byte> cache)
{
int len = ReadNextVarInt(cache);
@ -209,28 +239,33 @@ namespace MinecraftClient.Protocol.Handlers
/// Read a double from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The double value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public double ReadNextDouble(Queue<byte> cache)
{
byte[] rawValue = ReadData(8, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToDouble(rawValue, 0);
Span<byte> rawValue = stackalloc byte[8];
for (int i = (8 - 1); i >= 0; --i) //Endianness
rawValue[i] = cache.Dequeue();
return BitConverter.ToDouble(rawValue);
}
/// <summary>
/// Read a float from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The float value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public float ReadNextFloat(Queue<byte> cache)
{
byte[] rawValue = ReadData(4, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToSingle(rawValue, 0);
Span<byte> rawValue = stackalloc byte[4];
for (int i = (4 - 1); i >= 0; --i) //Endianness
rawValue[i] = cache.Dequeue();
return BitConverter.ToSingle(rawValue);
}
/// <summary>
/// Read an integer from the network
/// </summary>
/// <returns>The integer</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReadNextVarIntRAW(SocketWrapper socket)
{
int i = 0;
@ -251,6 +286,7 @@ namespace MinecraftClient.Protocol.Handlers
/// </summary>
/// <param name="cache">Cache of bytes to read from</param>
/// <returns>The integer</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public int ReadNextVarInt(Queue<byte> cache)
{
int i = 0;
@ -269,13 +305,12 @@ namespace MinecraftClient.Protocol.Handlers
/// Skip a VarInt from a cache of bytes with better performance
/// </summary>
/// <param name="cache">Cache of bytes to read from</param>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public void SkipNextVarInt(Queue<byte> cache)
{
while (true)
{
if ((ReadNextByte(cache) & 0x80) != 128)
break;
}
}
/// <summary>
@ -326,6 +361,7 @@ namespace MinecraftClient.Protocol.Handlers
/// Read a single byte from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The byte that was read</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public byte ReadNextByte(Queue<byte> cache)
{
byte result = cache.Dequeue();

View file

@ -218,9 +218,8 @@ namespace MinecraftClient.Protocol.Handlers
while (socketWrapper.HasDataAvailable())
{
int packetID = 0;
Queue<byte> packetData = new Queue<byte>();
ReadNextPacket(ref packetID, packetData);
HandlePacket(packetID, new Queue<byte>(packetData));
Queue<byte> packetData = ReadNextPacket(ref packetID);
HandlePacket(packetID, packetData);
}
}
catch (System.IO.IOException) { return false; }
@ -235,14 +234,10 @@ namespace MinecraftClient.Protocol.Handlers
/// </summary>
/// <param name="packetID">will contain packet ID</param>
/// <param name="packetData">will contain raw packet Data</param>
internal void ReadNextPacket(ref int packetID, Queue<byte> packetData)
internal Queue<byte> ReadNextPacket(ref int packetID)
{
packetData.Clear();
int size = dataTypes.ReadNextVarIntRAW(socketWrapper); //Packet size
byte[] rawpacket = socketWrapper.ReadDataRAW(size); //Packet contents
for (int i = 0; i < rawpacket.Length; i++)
packetData.Enqueue(rawpacket[i]);
Queue<byte> packetData = new(socketWrapper.ReadDataRAW(size)); //Packet contents
//Handle packet decompression
if (protocolversion >= MC_1_8_Version
@ -253,9 +248,7 @@ namespace MinecraftClient.Protocol.Handlers
{
byte[] toDecompress = packetData.ToArray();
byte[] uncompressed = ZlibUtils.Decompress(toDecompress, sizeUncompressed);
packetData.Clear();
for (int i = 0; i < uncompressed.Length; i++)
packetData.Enqueue(uncompressed[i]);
packetData = new(uncompressed);
}
}
@ -266,6 +259,8 @@ namespace MinecraftClient.Protocol.Handlers
List<byte> clone = packetData.ToList();
handler.OnNetworkPacket(packetID, clone, login_phase, true);
}
return packetData;
}
/// <summary>
@ -609,7 +604,7 @@ namespace MinecraftClient.Protocol.Handlers
dataTypes.SkipNextVarInt(packetData);
}
}
else dataTypes.ReadData(1024 * 4, packetData); // Biomes - 1.15 and above
else dataTypes.DropData(1024 * 4, packetData); // Biomes - 1.15 and above
}
int dataSize = dataTypes.ReadNextVarInt(packetData);
Parallel.Invoke(() =>
@ -1561,10 +1556,9 @@ namespace MinecraftClient.Protocol.Handlers
SendPacket(0x00, fullLoginPacket);
int packetID = -1;
Queue<byte> packetData = new Queue<byte>();
while (true)
{
ReadNextPacket(ref packetID, packetData);
Queue<byte> packetData = ReadNextPacket(ref packetID);
if (packetID == 0x00) //Login rejected
{
handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(dataTypes.ReadNextString(packetData)));
@ -1670,8 +1664,7 @@ namespace MinecraftClient.Protocol.Handlers
while (true)
{
int packetID = -1;
Queue<byte> packetData = new Queue<byte>();
ReadNextPacket(ref packetID, packetData);
Queue<byte> packetData = ReadNextPacket(ref packetID);
if (packetID < 0 || loopPrevention-- < 0) // Failed to read packet or too many iterations (issue #1150)
{
handler.OnConnectionLost(ChatBot.DisconnectReason.ConnectionLost, Translations.Get("error.invalid_encrypt"));

View file

@ -57,11 +57,10 @@ namespace MinecraftClient.Protocol.Handlers
if (ForgeEnabled() && forgeInfo.Version == FMLVersion.FML)
{
int packetID = -1;
Queue<byte> packetData = new Queue<byte>();
while (fmlHandshakeState != FMLHandshakeClientState.DONE)
{
protocol18.ReadNextPacket(ref packetID, packetData);
Queue<byte> packetData = protocol18.ReadNextPacket(ref packetID);
if (packetID == 0x40) // Disconnect
{

View file

@ -222,7 +222,7 @@ namespace MinecraftClient.Protocol.Handlers
dataTypes.SkipNextVarInt(cache); // Palette
}
int dataArrayLength = dataTypes.ReadNextVarInt(cache); // Data Array Length
dataTypes.ReadData(dataArrayLength * 8, cache); // Data Array
dataTypes.DropData(dataArrayLength * 8, cache); // Data Array
}
}
}
@ -394,12 +394,12 @@ namespace MinecraftClient.Protocol.Handlers
if (protocolversion < Protocol18Handler.MC_1_14_Version)
{
//Skip block light
dataTypes.ReadData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
dataTypes.DropData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
//Skip sky light
if (currentDimension == 0)
// Sky light is not sent in the nether or the end
dataTypes.ReadData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
dataTypes.DropData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
}
}
}
@ -456,17 +456,17 @@ namespace MinecraftClient.Protocol.Handlers
if ((chunkMask & (1 << chunkY)) != 0)
{
//Skip block light
dataTypes.ReadData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
dataTypes.DropData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
//Skip sky light
if (hasSkyLight)
dataTypes.ReadData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
dataTypes.DropData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ) / 2, cache);
}
}
//Skip biome metadata
if (chunksContinuous)
dataTypes.ReadData(Chunk.SizeX * Chunk.SizeZ, cache);
dataTypes.DropData(Chunk.SizeX * Chunk.SizeZ, cache);
}
}
else
@ -505,12 +505,12 @@ namespace MinecraftClient.Protocol.Handlers
}
//Skip data we don't need
dataTypes.ReadData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ * sectionCount) / 2, cache); //Block light
dataTypes.DropData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ * sectionCount) / 2, cache); //Block light
if (hasSkyLight)
dataTypes.ReadData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ * sectionCount) / 2, cache); //Sky light
dataTypes.ReadData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ * addDataSectionCount) / 2, cache); //BlockAdd
dataTypes.DropData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ * sectionCount) / 2, cache); //Sky light
dataTypes.DropData((Chunk.SizeX * Chunk.SizeY * Chunk.SizeZ * addDataSectionCount) / 2, cache); //BlockAdd
if (chunksContinuous)
dataTypes.ReadData(Chunk.SizeX * Chunk.SizeZ, cache); //Biomes
dataTypes.DropData(Chunk.SizeX * Chunk.SizeZ, cache); //Biomes
//Load chunk data
int maxChunkY = sizeof(int) * 8 - 1 - BitOperations.LeadingZeroCount(chunkMask);

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using Ionic.Zlib;
@ -39,6 +40,7 @@ namespace MinecraftClient.Protocol.Handlers
/// <param name="to_decompress">Data to decompress</param>
/// <param name="size_uncompressed">Size of the data once decompressed</param>
/// <returns>Decompressed data as a byte array</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static byte[] Decompress(byte[] to_decompress, int size_uncompressed)
{
ZlibStream stream = new ZlibStream(new System.IO.MemoryStream(to_decompress, false), CompressionMode.Decompress);
@ -53,6 +55,7 @@ namespace MinecraftClient.Protocol.Handlers
/// </summary>
/// <param name="to_decompress">Data to decompress</param>
/// <returns>Decompressed data as byte array</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static byte[] Decompress(byte[] to_decompress)
{
ZlibStream stream = new ZlibStream(new System.IO.MemoryStream(to_decompress, false), CompressionMode.Decompress);