From 92a54da42fc89089dacd15a1bf4edf5dffc44ba4 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 25 Jul 2018 14:28:14 -0400 Subject: [PATCH] Properly calculate the size of INewChunk#getIntBiomeArray This array is written to the PacketBuffer using PacketBuffer#writeVarIntArray, which writes both the array size and individual array elements as VarInts. However, JEID's calculation of the array size was leaving out the array length prefix, and assuming that each array element was exactly four bytes. Since a VarInt-encoded integer can range from 1 to 5 bytes, the calculation of the array size could end up being smaller than the actual number of bytes written, causing a crash. This commit makes JEID properly calculate the size of getIntBiomeArray, ensuring that the allocated buffer size always matches the number of bytes written. --- .../mixin/core/MixinSPacketChunkData.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/dimdev/jeid/mixin/core/MixinSPacketChunkData.java b/src/main/java/org/dimdev/jeid/mixin/core/MixinSPacketChunkData.java index aa866b3..00d81f9 100644 --- a/src/main/java/org/dimdev/jeid/mixin/core/MixinSPacketChunkData.java +++ b/src/main/java/org/dimdev/jeid/mixin/core/MixinSPacketChunkData.java @@ -29,9 +29,25 @@ public boolean getIsFullChunk(SPacketChunkData packet) { return false; } - @Redirect(method = "calculateChunkSize", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/Chunk;getBiomeArray()[B")) - private byte[] getBiomeArray(Chunk chunk) { - INewChunk newChunk = (INewChunk) chunk; - return new byte[newChunk.getIntBiomeArray().length * 4]; + @Inject(method = "calculateChunkSize", at = @At(value = "RETURN"), cancellable = true) + public void onReturn(Chunk chunkIn, boolean p_189556_2_, int p_189556_3_, CallbackInfoReturnable ci) { + if (this.isFullChunk()) { + int size = ci.getReturnValue(); + + // First, we subtract off the length added by Vanilla (the line 'i += chunkIn.getBiomeArray().length;') + size -= chunkIn.getBiomeArray().length; + + // Now, we add on the actual length of the VarIntArray we're going to be writing in extractChunkData + size += this.getVarIntArraySize(((INewChunk) chunkIn).getIntBiomeArray()); + ci.setReturnValue(size); + } + } + + private int getVarIntArraySize(int[] array) { + int size = PacketBuffer.getVarIntSize(array.length); + for (int i: array) { + size += PacketBuffer.getVarIntSize(i); + } + return size; } }