From fb87de1ff5977de469afa1b7e6d60a7b9bccf418 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 25 Oct 2015 11:51:53 -0700 Subject: [PATCH] Fix compatability with Feed The Beast servers More percisely, use varshorts for the length of the 3F packet, as forge makes it longer. Only really matters if a bazillion mods are installed, which they are with FTB. --- .../Protocol/Handlers/Protocol18.cs | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index e8dd5adf..8eeef8cc 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -214,9 +214,17 @@ namespace MinecraftClient.Protocol.Handlers String channel = readNextString(ref packetData); if (protocolversion < MC18Version) { - // 1.7 and lower prefix plugin channel packets with the length. - // We can skip it, though. - readNextShort(ref packetData); + if (forgeInfo == null) + { + // 1.7 and lower prefix plugin channel packets with the length. + // We can skip it, though. + readNextShort(ref packetData); + } + else + { + // Forge does something even weirder with the length. + readNextVarShort(ref packetData); + } } if (forgeInfo != null) { @@ -269,9 +277,12 @@ namespace MinecraftClient.Protocol.Handlers if (discriminator != FMLHandshakeDiscriminator.ModList) return false; + Thread.Sleep(2000); + ConsoleIO.WriteLineFormatted("ยง8Accepting server mod list..."); // Tell the server that yes, we are OK with the mods it has // even though we don't actually care what mods it has. + SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck, new byte[] { (byte)FMLHandshakeClientState.WAITINGSERVERDATA }); @@ -461,6 +472,18 @@ namespace MinecraftClient.Protocol.Handlers return BitConverter.ToInt16(rawValue, 0); } + /// + /// Read an unsigned short integer from a cache of bytes and remove it from the cache + /// + /// The unsigned short integer value + + private static ushort readNextUShort(ref byte[] cache) + { + byte[] rawValue = readData(2, ref cache); + Array.Reverse(rawValue); //Endianness + return BitConverter.ToUInt16(rawValue, 0); + } + /// /// Read a uuid from a cache of bytes and remove it from the cache /// @@ -531,6 +554,26 @@ namespace MinecraftClient.Protocol.Handlers return i; } + /// + /// Read an "extended short", which is actually an int of some kind, from the cache of bytes. + /// This is only done with forge. It looks like it's a normal short, except that if the high + /// bit is set, it has an extra byte. + /// + /// Cache of bytes to read from + /// The int + + private static int readNextVarShort(ref byte[] cache) + { + ushort low = readNextUShort(ref cache); + byte high = 0; + if ((low & 0x8000) != 0) + { + low &= 0x7FFF; + high = readNextByte(ref cache); + } + return ((high & 0xFF) << 15) | low; + } + /// /// Read a single byte from a cache of bytes and remove it from the cache ///