diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java index e6e265475..bba7a593b 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_13.java @@ -5,6 +5,7 @@ import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; public class ChunkSectionType1_13 extends Type { + private static final int GLOBAL_PALETTE = 14; public ChunkSectionType1_13() { super("Chunk Section Type", ChunkSection.class); @@ -16,18 +17,15 @@ public class ChunkSectionType1_13 extends Type { // Reaad bits per block int bitsPerBlock = buffer.readUnsignedByte(); + int originalBitsPerBlock = bitsPerBlock; + + if (bitsPerBlock == 0 || bitsPerBlock > 8) { + bitsPerBlock = GLOBAL_PALETTE; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; - if (bitsPerBlock == 0) { - bitsPerBlock = 14; - } - if (bitsPerBlock < 4) { - bitsPerBlock = 4; - } - if (bitsPerBlock > 8) { - bitsPerBlock = 14; - } - int paletteLength = bitsPerBlock == 14 ? 0 : Type.VAR_INT.read(buffer); + int paletteLength = bitsPerBlock == GLOBAL_PALETTE ? 0 : Type.VAR_INT.read(buffer); // Read palette chunkSection.clearPalette(); for (int i = 0; i < paletteLength; i++) { @@ -37,6 +35,11 @@ public class ChunkSectionType1_13 extends Type { // Read blocks long[] blockData = new long[Type.VAR_INT.read(buffer)]; if (blockData.length > 0) { + int expectedLength = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + if (blockData.length != expectedLength) { + throw new IllegalStateException("Block data length (" + blockData.length + ") does not match expected length (" + expectedLength + ")! bitsPerBlock=" + bitsPerBlock + ", originalBitsPerBlock=" + originalBitsPerBlock); + } + for (int i = 0; i < blockData.length; i++) { blockData[i] = buffer.readLong(); } @@ -53,7 +56,7 @@ public class ChunkSectionType1_13 extends Type { val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); } - if (bitsPerBlock == 14) { + if (bitsPerBlock == GLOBAL_PALETTE) { chunkSection.setFlatBlock(i, val); } else { chunkSection.setPaletteIndex(i, val); @@ -72,15 +75,14 @@ public class ChunkSectionType1_13 extends Type { } if (bitsPerBlock > 8) { - bitsPerBlock = 14; + bitsPerBlock = GLOBAL_PALETTE; } long maxEntryValue = (1L << bitsPerBlock) - 1; buffer.writeByte(bitsPerBlock); - // Write pallet (or not) - if (bitsPerBlock != 14) { + if (bitsPerBlock != GLOBAL_PALETTE) { Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); for (int i = 0; i < chunkSection.getPaletteSize(); i++) { Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); @@ -91,7 +93,7 @@ public class ChunkSectionType1_13 extends Type { Type.VAR_INT.write(buffer, length); long[] data = new long[length]; for (int index = 0; index < ChunkSection.SIZE; index++) { - int value = bitsPerBlock == 14 ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); + int value = bitsPerBlock == GLOBAL_PALETTE ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); int bitIndex = index * bitsPerBlock; int startIndex = bitIndex / 64; int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; diff --git a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java index 8a596e24a..8d11a517b 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java +++ b/common/src/main/java/us/myles/ViaVersion/api/type/types/version/ChunkSectionType1_9.java @@ -1,11 +1,11 @@ package us.myles.ViaVersion.api.type.types.version; -import com.google.common.collect.BiMap; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection; import us.myles.ViaVersion.api.type.Type; public class ChunkSectionType1_9 extends Type { + private static final int GLOBAL_PALETTE = 13; public ChunkSectionType1_9() { super("Chunk Section Type", ChunkSection.class); @@ -17,22 +17,23 @@ public class ChunkSectionType1_9 extends Type { // Reaad bits per block int bitsPerBlock = buffer.readUnsignedByte(); + int originalBitsPerBlock = bitsPerBlock; long maxEntryValue = (1L << bitsPerBlock) - 1; if (bitsPerBlock == 0) { - bitsPerBlock = 13; + bitsPerBlock = GLOBAL_PALETTE; } if (bitsPerBlock < 4) { bitsPerBlock = 4; } if (bitsPerBlock > 8) { - bitsPerBlock = 13; + bitsPerBlock = GLOBAL_PALETTE; } int paletteLength = Type.VAR_INT.read(buffer); // Read palette chunkSection.clearPalette(); for (int i = 0; i < paletteLength; i++) { - if (bitsPerBlock != 13) { + if (bitsPerBlock != GLOBAL_PALETTE) { chunkSection.addPaletteEntry(Type.VAR_INT.read(buffer)); } else { Type.VAR_INT.read(buffer); @@ -42,6 +43,11 @@ public class ChunkSectionType1_9 extends Type { // Read blocks long[] blockData = new long[Type.VAR_INT.read(buffer)]; if (blockData.length > 0) { + int expectedLength = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); + if (blockData.length != expectedLength) { + throw new IllegalStateException("Block data length (" + blockData.length + ") does not match expected length (" + expectedLength + ")! bitsPerBlock=" + bitsPerBlock + ", originalBitsPerBlock=" + originalBitsPerBlock); + } + for (int i = 0; i < blockData.length; i++) { blockData[i] = buffer.readLong(); } @@ -58,7 +64,7 @@ public class ChunkSectionType1_9 extends Type { val = (int) ((blockData[startIndex] >>> startBitSubIndex | blockData[endIndex] << endBitSubIndex) & maxEntryValue); } - if (bitsPerBlock == 13) { + if (bitsPerBlock == GLOBAL_PALETTE) { chunkSection.setBlock(i, val >> 4, val & 0xF); } else { chunkSection.setPaletteIndex(i, val); @@ -75,20 +81,29 @@ public class ChunkSectionType1_9 extends Type { while (chunkSection.getPaletteSize() > 1 << bitsPerBlock) { bitsPerBlock += 1; } + + if (bitsPerBlock > 8) { + bitsPerBlock = GLOBAL_PALETTE; + } + long maxEntryValue = (1L << bitsPerBlock) - 1; buffer.writeByte(bitsPerBlock); - // Write pallet - Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); - for (int i = 0; i < chunkSection.getPaletteSize(); i++) { - Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); + // Write pallet (or not) + if (bitsPerBlock != GLOBAL_PALETTE) { + Type.VAR_INT.write(buffer, chunkSection.getPaletteSize()); + for (int i = 0; i < chunkSection.getPaletteSize(); i++) { + Type.VAR_INT.write(buffer, chunkSection.getPaletteEntry(i)); + } + } else { + Type.VAR_INT.write(buffer, 0); } int length = (int) Math.ceil(ChunkSection.SIZE * bitsPerBlock / 64.0); Type.VAR_INT.write(buffer, length); long[] data = new long[length]; for (int index = 0; index < ChunkSection.SIZE; index++) { - int value = chunkSection.getPaletteIndex(index); + int value = bitsPerBlock == GLOBAL_PALETTE ? chunkSection.getFlatBlock(index) : chunkSection.getPaletteIndex(index); int bitIndex = index * bitsPerBlock; int startIndex = bitIndex / 64; int endIndex = ((index + 1) * bitsPerBlock - 1) / 64; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java index c225439f3..08938366a 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java @@ -131,6 +131,7 @@ public class ChatRewriter { } private static void processTranslate(BaseComponent component) { + if (component == null) return; if (component instanceof TranslatableComponent) { String oldTranslate = ((TranslatableComponent) component).getTranslate(); String newTranslate; diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java index 1b689571a..a6766d2a6 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java @@ -1,7 +1,12 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets; import com.github.steveice10.opennbt.conversion.ConverterRegistry; -import com.github.steveice10.opennbt.tag.builtin.*; +import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.IntTag; +import com.github.steveice10.opennbt.tag.builtin.ListTag; +import com.github.steveice10.opennbt.tag.builtin.ShortTag; +import com.github.steveice10.opennbt.tag.builtin.StringTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import com.google.common.base.Joiner; import com.google.common.base.Optional; import com.google.common.primitives.Ints; @@ -721,7 +726,8 @@ public class InventoryPackets { return null; // Not valid } int separatorIndex = newId.indexOf(':'); - if (separatorIndex == -1 || separatorIndex == 0) { // Vanilla parses ``:`` and ```` as ``minecraft:`` + // Vanilla parses ``:`` and ```` as ``minecraft:`` (also ensure there's enough space) + if ((separatorIndex == -1 || separatorIndex == 0) && newId.length() <= 10) { newId = "minecraft:" + newId; } switch (newId) { @@ -748,7 +754,7 @@ public class InventoryPackets { case "wdl:request": return "WDL|REQUEST"; default: - return newId; + return newId.length() > 20 ? newId.substring(0, 20) : newId; } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/InventoryNameRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/InventoryNameRewriter.java index 253cae5b1..0d810f7c7 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/InventoryNameRewriter.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_14to1_13_2/InventoryNameRewriter.java @@ -18,6 +18,7 @@ public class InventoryNameRewriter { } private static void processTranslate(BaseComponent component) { + if (component == null) return; if (component instanceof TranslatableComponent) { String oldTranslate = ((TranslatableComponent) component).getTranslate();