diff --git a/MinecraftClient/Mapping/Location.cs b/MinecraftClient/Mapping/Location.cs index 02ee3c23..c5232330 100644 --- a/MinecraftClient/Mapping/Location.cs +++ b/MinecraftClient/Mapping/Location.cs @@ -55,7 +55,7 @@ namespace MinecraftClient.Mapping /// Location of the block into the chunk /// Location of the block into the world /// Location of the block into the chunk - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Location(int chunkX, int chunkZ, int blockX, int blockY, int blockZ) { X = chunkX * Chunk.SizeX + blockX; diff --git a/MinecraftClient/Protocol/Handlers/Compression/Inflate.cs b/MinecraftClient/Protocol/Handlers/Compression/Inflate.cs index eaf0f909..f81e49fe 100644 --- a/MinecraftClient/Protocol/Handlers/Compression/Inflate.cs +++ b/MinecraftClient/Protocol/Handlers/Compression/Inflate.cs @@ -141,8 +141,6 @@ namespace Ionic.Zlib return oldCheck; } - - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal int Process(int r) { int t; // temporary storage @@ -676,7 +674,6 @@ 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; @@ -803,7 +800,7 @@ namespace Ionic.Zlib tree = null; } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + internal int Process(InflateBlocks blocks, int r) { int j; // temporary storage @@ -1165,8 +1162,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)] - + [MethodImpl(MethodImplOptions.AggressiveOptimization)] internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z) { int t; // temporary pointer @@ -1515,7 +1511,6 @@ namespace Ionic.Zlib } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] internal int Inflate(FlushType flush) { int b; diff --git a/MinecraftClient/Protocol/Handlers/Compression/ZlibBaseStream.cs b/MinecraftClient/Protocol/Handlers/Compression/ZlibBaseStream.cs index e4879481..a02c46a8 100644 --- a/MinecraftClient/Protocol/Handlers/Compression/ZlibBaseStream.cs +++ b/MinecraftClient/Protocol/Handlers/Compression/ZlibBaseStream.cs @@ -171,7 +171,6 @@ namespace Ionic.Zlib - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private void finish() { if (_z == null) return; @@ -301,7 +300,6 @@ namespace Ionic.Zlib } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public override void Close() { if (_stream == null) return; @@ -416,7 +414,6 @@ 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: diff --git a/MinecraftClient/Protocol/Handlers/Compression/ZlibCodec.cs b/MinecraftClient/Protocol/Handlers/Compression/ZlibCodec.cs index 97b5882c..e6b7299e 100644 --- a/MinecraftClient/Protocol/Handlers/Compression/ZlibCodec.cs +++ b/MinecraftClient/Protocol/Handlers/Compression/ZlibCodec.cs @@ -352,7 +352,6 @@ namespace Ionic.Zlib /// /// The flush to use when inflating. /// Z_OK if everything goes well. - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public int Inflate(FlushType flush) { if (istate == null) diff --git a/MinecraftClient/Protocol/Handlers/Compression/ZlibStream.cs b/MinecraftClient/Protocol/Handlers/Compression/ZlibStream.cs index 27cead91..fb1a85d9 100644 --- a/MinecraftClient/Protocol/Handlers/Compression/ZlibStream.cs +++ b/MinecraftClient/Protocol/Handlers/Compression/ZlibStream.cs @@ -410,7 +410,6 @@ namespace Ionic.Zlib /// /// indicates whether the Dispose method was invoked by user code. /// - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] protected override void Dispose(bool disposing) { try @@ -545,10 +544,9 @@ namespace Ionic.Zlib /// the number of bytes to read. /// /// the number of bytes read - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public override int Read(byte[] buffer, int offset, int count) { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); + if (_disposed) throw new ObjectDisposedException("ZlibStream"); return _baseStream.Read(buffer, offset, count); } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 914a0156..6f273df8 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -20,6 +20,7 @@ using System.Threading.Tasks; using MinecraftClient.Protocol.Keys; using System.Text.RegularExpressions; using MinecraftClient.Protocol.Session; +using System.Collections.Concurrent; namespace MinecraftClient.Protocol.Handlers { @@ -65,6 +66,7 @@ namespace MinecraftClient.Protocol.Handlers private bool login_phase = true; private int protocolversion; private int currentDimension; + private readonly BlockingCollection>> packetQueue = new(); Protocol18Forge pForge; Protocol18Terrain pTerrain; @@ -211,30 +213,54 @@ namespace MinecraftClient.Protocol.Handlers private bool Update() { handler.OnUpdate(); - if (!socketWrapper.IsConnected()) + + if (packetQueue.IsAddingCompleted) return false; - try + + while (packetQueue.TryTake(out Tuple>? packetInfo)) { - while (socketWrapper.HasDataAvailable()) + (int packetID, Queue packetData) = packetInfo; + + HandlePacket(packetID, packetData); + + if (handler.GetNetworkPacketCaptureEnabled()) { - int packetID = 0; - Queue packetData = ReadNextPacket(ref packetID); - HandlePacket(packetID, packetData); + List clone = packetData.ToList(); + handler.OnNetworkPacket(packetID, clone, login_phase, true); } } - catch (System.IO.IOException) { return false; } - catch (SocketException) { return false; } - catch (NullReferenceException) { return false; } - catch (Ionic.Zlib.ZlibException) { return false; } + return true; } + /// + /// Read and decompress packets. + /// + internal void PacketReader() + { + while (socketWrapper.IsConnected()) + { + try + { + while (socketWrapper.HasDataAvailable()) + packetQueue.Add(ReadNextPacket()); + } + catch (System.IO.IOException) { break; } + catch (SocketException) { break; } + catch (NullReferenceException) { break; } + catch (Ionic.Zlib.ZlibException) { break; } + + Thread.Sleep(10); + } + packetQueue.CompleteAdding(); + } + /// /// Read the next packet from the network /// /// will contain packet ID /// will contain raw packet Data - internal Queue ReadNextPacket(ref int packetID) + internal Tuple> ReadNextPacket() { int size = dataTypes.ReadNextVarIntRAW(socketWrapper); //Packet size Queue packetData = new(socketWrapper.ReadDataRAW(size)); //Packet contents @@ -252,7 +278,7 @@ namespace MinecraftClient.Protocol.Handlers } } - packetID = dataTypes.ReadNextVarInt(packetData); //Packet ID + int packetID = dataTypes.ReadNextVarInt(packetData); //Packet ID if (handler.GetNetworkPacketCaptureEnabled()) { @@ -260,7 +286,7 @@ namespace MinecraftClient.Protocol.Handlers handler.OnNetworkPacket(packetID, clone, login_phase, true); } - return packetData; + return new(packetID, packetData); } /// @@ -1447,6 +1473,7 @@ namespace MinecraftClient.Protocol.Handlers /// private void StartUpdating() { + new Thread(new ThreadStart(PacketReader)).Start(); netRead = new Tuple(new Thread(new ParameterizedThreadStart(Updater)), new CancellationTokenSource()); netRead.Item1.Name = "ProtocolPacketHandler"; @@ -1552,10 +1579,9 @@ namespace MinecraftClient.Protocol.Handlers } SendPacket(0x00, fullLoginPacket); - int packetID = -1; while (true) { - Queue packetData = ReadNextPacket(ref packetID); + (int packetID, Queue packetData) = ReadNextPacket(); if (packetID == 0x00) //Login rejected { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); @@ -1660,8 +1686,7 @@ namespace MinecraftClient.Protocol.Handlers int loopPrevention = UInt16.MaxValue; while (true) { - int packetID = -1; - Queue packetData = ReadNextPacket(ref packetID); + (int packetID, Queue packetData) = ReadNextPacket(); 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")); diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs b/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs index bfa401a0..f3aa5634 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs @@ -56,11 +56,9 @@ namespace MinecraftClient.Protocol.Handlers { if (ForgeEnabled() && forgeInfo.Version == FMLVersion.FML) { - int packetID = -1; - while (fmlHandshakeState != FMLHandshakeClientState.DONE) { - Queue packetData = protocol18.ReadNextPacket(ref packetID); + (int packetID, Queue packetData) = protocol18.ReadNextPacket(); if (packetID == 0x40) // Disconnect { diff --git a/MinecraftClient/Protocol/Handlers/ZlibUtils.cs b/MinecraftClient/Protocol/Handlers/ZlibUtils.cs index f4822f16..e7936b50 100644 --- a/MinecraftClient/Protocol/Handlers/ZlibUtils.cs +++ b/MinecraftClient/Protocol/Handlers/ZlibUtils.cs @@ -40,7 +40,6 @@ namespace MinecraftClient.Protocol.Handlers /// Data to decompress /// Size of the data once decompressed /// Decompressed data as a byte array - [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); @@ -55,7 +54,6 @@ namespace MinecraftClient.Protocol.Handlers /// /// Data to decompress /// Decompressed data as byte array - [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);