From 06714423a3280801949091d67a57abb2aaff7164 Mon Sep 17 00:00:00 2001 From: eulertour0 Date: Sat, 23 May 2020 21:41:37 +0900 Subject: [PATCH] Replace List to Queue --- .../Protocol/Handlers/DataTypes.cs | 70 +++++++++++-------- .../Protocol/Handlers/Protocol18.cs | 27 +++---- .../Protocol/Handlers/Protocol18Forge.cs | 6 +- .../Protocol/Handlers/Protocol18Terrain.cs | 2 +- 4 files changed, 58 insertions(+), 47 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 45ce6ac7..07aa4fe2 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -34,10 +34,11 @@ namespace MinecraftClient.Protocol.Handlers /// Amount of bytes to read /// Cache of bytes to read from /// The data read from the cache as an array - public byte[] ReadData(int offset, List cache) + public byte[] ReadData(int offset, Queue cache) { byte[] result = cache.Take(offset).ToArray(); - cache.RemoveRange(0, offset); + for (int i = 0; i < offset; i++) + cache.Dequeue(); return result; } @@ -46,7 +47,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Cache of bytes to read from /// The string - public string ReadNextString(List cache) + public string ReadNextString(Queue cache) { int length = ReadNextVarInt(cache); if (length > 0) @@ -60,7 +61,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read a boolean from a cache of bytes and remove it from the cache /// /// The boolean value - public bool ReadNextBool(List cache) + public bool ReadNextBool(Queue cache) { return ReadNextByte(cache) != 0x00; } @@ -69,7 +70,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read a short integer from a cache of bytes and remove it from the cache /// /// The short integer value - public short ReadNextShort(List cache) + public short ReadNextShort(Queue cache) { byte[] rawValue = ReadData(2, cache); Array.Reverse(rawValue); //Endianness @@ -80,7 +81,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read an integer from a cache of bytes and remove it from the cache /// /// The integer value - public int ReadNextInt(List cache) + public int ReadNextInt(Queue cache) { byte[] rawValue = ReadData(4, cache); Array.Reverse(rawValue); //Endianness @@ -91,7 +92,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read a long integer from a cache of bytes and remove it from the cache /// /// The unsigned long integer value - public long ReadNextLong(List cache) + public long ReadNextLong(Queue cache) { byte[] rawValue = ReadData(8, cache); Array.Reverse(rawValue); //Endianness @@ -102,7 +103,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read an unsigned short integer from a cache of bytes and remove it from the cache /// /// The unsigned short integer value - public ushort ReadNextUShort(List cache) + public ushort ReadNextUShort(Queue cache) { byte[] rawValue = ReadData(2, cache); Array.Reverse(rawValue); //Endianness @@ -113,7 +114,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read an unsigned long integer from a cache of bytes and remove it from the cache /// /// The unsigned long integer value - public ulong ReadNextULong(List cache) + public ulong ReadNextULong(Queue cache) { byte[] rawValue = ReadData(8, cache); Array.Reverse(rawValue); //Endianness @@ -124,7 +125,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read a Location encoded as an ulong field and remove it from the cache /// /// The Location value - public Location ReadNextLocation(List cache) + public Location ReadNextLocation(Queue cache) { ulong locEncoded = ReadNextULong(cache); int x, y, z; @@ -153,7 +154,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read several little endian unsigned short integers at once from a cache of bytes and remove them from the cache /// /// The unsigned short integer value - public ushort[] ReadNextUShortsLittleEndian(int amount, List cache) + public ushort[] ReadNextUShortsLittleEndian(int amount, Queue cache) { byte[] rawValues = ReadData(2 * amount, cache); ushort[] result = new ushort[amount]; @@ -167,7 +168,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Cache of bytes to read from /// The uuid - public Guid ReadNextUUID(List cache) + public Guid ReadNextUUID(Queue cache) { byte[] javaUUID = ReadData(16, cache); Guid guid; @@ -199,7 +200,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Cache of bytes to read from /// The byte array - public byte[] ReadNextByteArray(List cache) + public byte[] ReadNextByteArray(Queue cache) { int len = protocolversion >= Protocol18Handler.MC18Version ? ReadNextVarInt(cache) @@ -211,7 +212,7 @@ namespace MinecraftClient.Protocol.Handlers /// Reads a length-prefixed array of unsigned long integers and removes it from the cache /// /// The unsigned long integer values - public ulong[] ReadNextULongArray(List cache) + public ulong[] ReadNextULongArray(Queue cache) { int len = ReadNextVarInt(cache); ulong[] result = new ulong[len]; @@ -224,7 +225,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read a double from a cache of bytes and remove it from the cache /// /// The double value - public double ReadNextDouble(List cache) + public double ReadNextDouble(Queue cache) { byte[] rawValue = ReadData(8, cache); Array.Reverse(rawValue); //Endianness @@ -235,7 +236,7 @@ namespace MinecraftClient.Protocol.Handlers /// Read a float from a cache of bytes and remove it from the cache /// /// The float value - public float ReadNextFloat(List cache) + public float ReadNextFloat(Queue cache) { byte[] rawValue = ReadData(4, cache); Array.Reverse(rawValue); //Endianness @@ -266,7 +267,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Cache of bytes to read from /// The integer - public int ReadNextVarInt(List cache) + public int ReadNextVarInt(Queue cache) { string rawData = BitConverter.ToString(cache.ToArray()); int i = 0; @@ -289,7 +290,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Cache of bytes to read from /// The int - public int ReadNextVarShort(List cache) + public int ReadNextVarShort(Queue cache) { ushort low = ReadNextUShort(cache); byte high = 0; @@ -305,17 +306,16 @@ namespace MinecraftClient.Protocol.Handlers /// Read a single byte from a cache of bytes and remove it from the cache /// /// The byte that was read - public byte ReadNextByte(List cache) + public byte ReadNextByte(Queue cache) { - byte result = cache[0]; - cache.RemoveAt(0); + byte result = cache.Dequeue(); return result; } /// /// Read an uncompressed Named Binary Tag blob and remove it from the cache /// - public Dictionary ReadNextNbt(List cache) + public Dictionary ReadNextNbt(Queue cache) { return ReadNextNbt(cache, true); } @@ -325,7 +325,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Item /// The item that was read or NULL for an empty slot - public Item ReadNextItemSlot(List cache) + public Item ReadNextItemSlot(Queue cache) { List slotData = new List(); if (protocolversion > Protocol18Handler.MC113Version) @@ -357,15 +357,15 @@ namespace MinecraftClient.Protocol.Handlers /// /// Read an uncompressed Named Binary Tag blob and remove it from the cache (internal) /// - private Dictionary ReadNextNbt(List cache, bool root) + private Dictionary ReadNextNbt(Queue cache, bool root) { Dictionary NbtData = new Dictionary(); if (root) { - if (cache[0] == 0) // TAG_End + if (cache.Peek() == 0) // TAG_End return NbtData; - if (cache[0] != 10) // TAG_Compound + if (cache.Peek() != 10) // TAG_Compound throw new System.IO.InvalidDataException("Failed to decode NBT: Does not start with TAG_Compound"); ReadNextByte(cache); // Tag type (TAG_Compound) @@ -394,7 +394,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Read a single Named Binary Tag field of the specified type and remove it from the cache /// - private object ReadNbtField(List cache, int fieldType) + private object ReadNbtField(Queue cache, int fieldType) { switch (fieldType) { @@ -424,11 +424,19 @@ namespace MinecraftClient.Protocol.Handlers case 10: // TAG_Compound return ReadNextNbt(cache, false); case 11: // TAG_Int_Array - cache.Insert(0, 3); // List type = TAG_Int - return ReadNbtField(cache, 9); // Read as TAG_List + listType = 3; + listLength = ReadNextInt(cache); + listItems = new object[listLength]; + for (int i = 0; i < listLength; i++) + listItems[i] = ReadNbtField(cache, listType); + return listItems; case 12: // TAG_Long_Array - cache.Insert(0, 4); // List type = TAG_Long - return ReadNbtField(cache, 9); // Read as TAG_List + listType = 4; + listLength = ReadNextInt(cache); + listItems = new object[listLength]; + for (int i = 0; i < listLength; i++) + listItems[i] = ReadNbtField(cache, listType); + return listItems; default: throw new System.IO.InvalidDataException("Failed to decode NBT: Unknown field type " + fieldType); } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index e95fd60d..df8639f0 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -130,9 +130,9 @@ namespace MinecraftClient.Protocol.Handlers while (socketWrapper.HasDataAvailable()) { int packetID = 0; - List packetData = new List(); + Queue packetData = new Queue(); ReadNextPacket(ref packetID, packetData); - HandlePacket(packetID, new List(packetData)); + HandlePacket(packetID, new Queue(packetData)); } } catch (System.IO.IOException) { return false; } @@ -146,11 +146,13 @@ namespace MinecraftClient.Protocol.Handlers /// /// will contain packet ID /// will contain raw packet Data - internal void ReadNextPacket(ref int packetID, List packetData) + internal void ReadNextPacket(ref int packetID, Queue packetData) { packetData.Clear(); int size = dataTypes.ReadNextVarIntRAW(socketWrapper); //Packet size - packetData.AddRange(socketWrapper.ReadDataRAW(size)); //Packet contents + byte[] rawpacket = socketWrapper.ReadDataRAW(size);//Packet contents + for (int i = 0; i < rawpacket.Length; i++) + packetData.Enqueue(rawpacket[i]); //Handle packet decompression if (protocolversion >= MC18Version @@ -162,7 +164,8 @@ namespace MinecraftClient.Protocol.Handlers byte[] toDecompress = packetData.ToArray(); byte[] uncompressed = ZlibUtils.Decompress(toDecompress, sizeUncompressed); packetData.Clear(); - packetData.AddRange(uncompressed); + for (int i = 0; i < uncompressed.Length; i++) + packetData.Enqueue(uncompressed[i]); } } @@ -175,7 +178,7 @@ namespace MinecraftClient.Protocol.Handlers /// Packet ID /// Packet contents /// TRUE if the packet was processed, FALSE if ignored or unknown - internal bool HandlePacket(int packetID, List packetData) + internal bool HandlePacket(int packetID, Queue packetData) { try { @@ -290,7 +293,7 @@ namespace MinecraftClient.Protocol.Handlers int compressedDataSize = dataTypes.ReadNextInt(packetData); byte[] compressed = dataTypes.ReadData(compressedDataSize, packetData); byte[] decompressed = ZlibUtils.Decompress(compressed); - pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, addBitmap, currentDimension == 0, chunksContinuous, currentDimension, new List(decompressed)); + pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, addBitmap, currentDimension == 0, chunksContinuous, currentDimension, new Queue(decompressed)); } else { @@ -358,7 +361,7 @@ namespace MinecraftClient.Protocol.Handlers { int chunkCount; bool hasSkyLight; - List chunkData = packetData; + Queue chunkData = packetData; //Read global fields if (protocolversion < MC18Version) @@ -368,7 +371,7 @@ namespace MinecraftClient.Protocol.Handlers hasSkyLight = dataTypes.ReadNextBool(packetData); byte[] compressed = dataTypes.ReadData(compressedDataSize, packetData); byte[] decompressed = ZlibUtils.Decompress(compressed); - chunkData = new List(decompressed); + chunkData = new Queue(decompressed); } else { @@ -841,7 +844,7 @@ namespace MinecraftClient.Protocol.Handlers SendPacket(0x00, login_packet); int packetID = -1; - List packetData = new List(); + Queue packetData = new Queue(); while (true) { ReadNextPacket(ref packetID, packetData); @@ -909,7 +912,7 @@ namespace MinecraftClient.Protocol.Handlers //Process the next packet int packetID = -1; - List packetData = new List(); + Queue packetData = new Queue(); while (true) { ReadNextPacket(ref packetID, packetData); @@ -1217,7 +1220,7 @@ namespace MinecraftClient.Protocol.Handlers int packetLength = dataTypes.ReadNextVarIntRAW(socketWrapper); if (packetLength > 0) //Read Response length { - List packetData = new List(socketWrapper.ReadDataRAW(packetLength)); + Queue packetData = new Queue(socketWrapper.ReadDataRAW(packetLength)); if (dataTypes.ReadNextVarInt(packetData) == 0x00) //Read Packet ID { string result = dataTypes.ReadNextString(packetData); //Get the Json data diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs b/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs index facc7b65..291944c0 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Forge.cs @@ -57,7 +57,7 @@ namespace MinecraftClient.Protocol.Handlers if (ForgeEnabled()) { int packetID = -1; - List packetData = new List(); + Queue packetData = new Queue(); while (fmlHandshakeState != FMLHandshakeClientState.DONE) { @@ -83,7 +83,7 @@ namespace MinecraftClient.Protocol.Handlers /// /// Packet data to read from /// Length from packet data - public int ReadNextVarShort(List packetData) + public int ReadNextVarShort(Queue packetData) { if (ForgeEnabled()) { @@ -104,7 +104,7 @@ namespace MinecraftClient.Protocol.Handlers /// Plugin message data /// Current world dimension /// TRUE if the plugin message was recognized and handled - public bool HandlePluginMessage(string channel, List packetData, ref int currentDimension) + public bool HandlePluginMessage(string channel, Queue packetData, ref int currentDimension) { if (ForgeEnabled() && fmlHandshakeState != FMLHandshakeClientState.DONE) { diff --git a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs index 65b56657..4d74ab1e 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18Terrain.cs @@ -38,7 +38,7 @@ namespace MinecraftClient.Protocol.Handlers /// Are the chunk continuous /// Current dimension type (0 = overworld) /// Cache for reading chunk data - public void ProcessChunkColumnData(int chunkX, int chunkZ, ushort chunkMask, ushort chunkMask2, bool hasSkyLight, bool chunksContinuous, int currentDimension, List cache) + public void ProcessChunkColumnData(int chunkX, int chunkZ, ushort chunkMask, ushort chunkMask2, bool hasSkyLight, bool chunksContinuous, int currentDimension, Queue cache) { if (protocolversion >= Protocol18Handler.MC19Version) {