diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_8.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_8.java index c2c9c9838..73f680d93 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_8.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_8.java @@ -22,15 +22,19 @@ */ package com.viaversion.viaversion.api.type.types.chunk; +import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.minecraft.Environment; import com.viaversion.viaversion.api.minecraft.chunks.BaseChunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.version.Types1_8; +import com.viaversion.viaversion.util.ChunkUtil; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; + import java.util.ArrayList; +import java.util.logging.Level; public class ChunkType1_8 extends Type { @@ -62,7 +66,12 @@ public class ChunkType1_8 extends Type { return new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], null, new ArrayList<>()); } - return deserialize(chunkX, chunkZ, fullChunk, hasSkyLight, bitmask, data); + try { + return deserialize(chunkX, chunkZ, fullChunk, hasSkyLight, bitmask, data); + } catch (Throwable e) { + Via.getPlatform().getLogger().log(Level.WARNING, "The server sent an invalid chunk data packet, returning an empty chunk instead", e); + return ChunkUtil.createEmptyChunk(chunkX, chunkZ); + } } @Override diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_1.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_1.java index 77b110319..4012739b4 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_1.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_1.java @@ -22,15 +22,19 @@ */ package com.viaversion.viaversion.api.type.types.chunk; +import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.minecraft.Environment; import com.viaversion.viaversion.api.minecraft.chunks.BaseChunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.version.Types1_9; +import com.viaversion.viaversion.util.ChunkUtil; import io.netty.buffer.ByteBuf; + import java.util.ArrayList; import java.util.BitSet; +import java.util.logging.Level; public class ChunkType1_9_1 extends Type { @@ -56,31 +60,36 @@ public class ChunkType1_9_1 extends Type { int primaryBitmask = Type.VAR_INT.readPrimitive(input); ByteBuf data = input.readSlice(Type.VAR_INT.readPrimitive(input)); - BitSet usedSections = new BitSet(16); ChunkSection[] sections = new ChunkSection[16]; - // Calculate section count from bitmask - for (int i = 0; i < 16; i++) { - if ((primaryBitmask & (1 << i)) != 0) { - usedSections.set(i); - } - } - - // Read sections - for (int i = 0; i < 16; i++) { - if (!usedSections.get(i)) continue; // Section not set - ChunkSection section = Types1_9.CHUNK_SECTION.read(data); - sections[i] = section; - section.getLight().readBlockLight(data); - if (hasSkyLight) { - section.getLight().readSkyLight(data); - } - } - int[] biomeData = groundUp ? new int[256] : null; - if (groundUp) { - for (int i = 0; i < 256; i++) { - biomeData[i] = data.readByte() & 0xFF; + try { + BitSet usedSections = new BitSet(16); + // Calculate section count from bitmask + for (int i = 0; i < 16; i++) { + if ((primaryBitmask & (1 << i)) != 0) { + usedSections.set(i); + } } + + // Read sections + for (int i = 0; i < 16; i++) { + if (!usedSections.get(i)) continue; // Section not set + ChunkSection section = Types1_9.CHUNK_SECTION.read(data); + sections[i] = section; + section.getLight().readBlockLight(data); + if (hasSkyLight) { + section.getLight().readSkyLight(data); + } + } + + if (groundUp) { + for (int i = 0; i < 256; i++) { + biomeData[i] = data.readByte() & 0xFF; + } + } + } catch (Throwable e) { + Via.getPlatform().getLogger().log(Level.WARNING, "The server sent an invalid chunk data packet, returning an empty chunk instead", e); + return ChunkUtil.createEmptyChunk(chunkX, chunkZ); } return new BaseChunk(chunkX, chunkZ, groundUp, false, primaryBitmask, sections, biomeData, new ArrayList<>()); diff --git a/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_3.java b/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_3.java index ad4da233f..e6e31f5f8 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_3.java +++ b/api/src/main/java/com/viaversion/viaversion/api/type/types/chunk/ChunkType1_9_3.java @@ -30,10 +30,13 @@ import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.version.Types1_9; +import com.viaversion.viaversion.util.ChunkUtil; import io.netty.buffer.ByteBuf; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.logging.Level; public class ChunkType1_9_3 extends Type { @@ -59,24 +62,29 @@ public class ChunkType1_9_3 extends Type { int primaryBitmask = Type.VAR_INT.readPrimitive(input); ByteBuf data = input.readSlice(Type.VAR_INT.readPrimitive(input)); - // Read sections ChunkSection[] sections = new ChunkSection[16]; - for (int i = 0; i < 16; i++) { - if ((primaryBitmask & (1 << i)) == 0) continue; // Section not set - - ChunkSection section = Types1_9.CHUNK_SECTION.read(data); - sections[i] = section; - section.getLight().readBlockLight(data); - if (hasSkyLight) { - section.getLight().readSkyLight(data); - } - } - int[] biomeData = fullChunk ? new int[256] : null; - if (fullChunk) { - for (int i = 0; i < 256; i++) { - biomeData[i] = data.readByte() & 0xFF; + try { + // Read sections + for (int i = 0; i < 16; i++) { + if ((primaryBitmask & (1 << i)) == 0) continue; // Section not set + + ChunkSection section = Types1_9.CHUNK_SECTION.read(data); + sections[i] = section; + section.getLight().readBlockLight(data); + if (hasSkyLight) { + section.getLight().readSkyLight(data); + } } + + if (fullChunk) { + for (int i = 0; i < 256; i++) { + biomeData[i] = data.readByte() & 0xFF; + } + } + } catch (Throwable e) { + Via.getPlatform().getLogger().log(Level.WARNING, "The server sent an invalid chunk data packet, returning an empty chunk instead", e); + return ChunkUtil.createEmptyChunk(chunkX, chunkZ); } List nbtData = new ArrayList<>(Arrays.asList(Type.NAMED_COMPOUND_TAG_ARRAY.read(input))); @@ -119,4 +127,4 @@ public class ChunkType1_9_3 extends Type { // Write Block Entities Type.NAMED_COMPOUND_TAG_ARRAY.write(output, chunk.getBlockEntities().toArray(new CompoundTag[0])); } -} \ No newline at end of file +} diff --git a/api/src/main/java/com/viaversion/viaversion/util/ChunkUtil.java b/api/src/main/java/com/viaversion/viaversion/util/ChunkUtil.java new file mode 100644 index 000000000..66da48ae7 --- /dev/null +++ b/api/src/main/java/com/viaversion/viaversion/util/ChunkUtil.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion + * Copyright (C) 2023 ViaVersion and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.viaversion.viaversion.util; + +import com.viaversion.viaversion.api.minecraft.chunks.*; + +import java.util.ArrayList; + +public class ChunkUtil { + + public static Chunk createEmptyChunk(final int chunkX, final int chunkZ) { + final ChunkSection[] airSections = new ChunkSection[16]; + for (int i = 0; i < airSections.length; i++) { + airSections[i] = new ChunkSectionImpl(true); + airSections[i].palette(PaletteType.BLOCKS).addId(0); + } + return new BaseChunk(chunkX, chunkZ, true, false, 0xFFFF, airSections, new int[256], new ArrayList<>()); + } + +}