From 73bec588fa1930f7d4e47b9b6590398aee6934ad Mon Sep 17 00:00:00 2001 From: DaPorkchop_ Date: Tue, 13 Oct 2020 17:11:52 +0200 Subject: [PATCH] fix some NPEs caused by race conditions in chunk conversion (#1396) * fix some NPEs caused by race conditions in chunk conversion tbh the whole session should be read-write locked for every operation * fix code style issues --- .../java/world/JavaChunkDataTranslator.java | 6 +++--- .../translators/world/GeyserWorldManager.java | 21 +++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java index 6dae9b4d..ddd5e004 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaChunkDataTranslator.java @@ -66,11 +66,11 @@ public class JavaChunkDataTranslator extends PacketTranslator { try { + // Non-full chunks don't have all the chunk data, and Bedrock won't accept that + final boolean isNonFullChunk = (packet.getColumn().getBiomeData() == null); + ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(session, packet.getColumn(), isNonFullChunk); ByteBuf byteBuf = Unpooled.buffer(32); ChunkSection[] sections = chunkData.sections; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/GeyserWorldManager.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/GeyserWorldManager.java index 983e42b7..6972d77b 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/GeyserWorldManager.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/GeyserWorldManager.java @@ -25,12 +25,14 @@ package org.geysermc.connector.network.translators.world; +import com.github.steveice10.mc.protocol.data.game.chunk.Column; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket; import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.geysermc.connector.network.session.GeyserSession; +import org.geysermc.connector.network.session.cache.ChunkCache; import org.geysermc.connector.utils.GameRule; public class GeyserWorldManager extends WorldManager { @@ -39,14 +41,25 @@ public class GeyserWorldManager extends WorldManager { @Override public int getBlockAt(GeyserSession session, int x, int y, int z) { - return session.getChunkCache().getBlockAt(x, y, z); + ChunkCache chunkCache = session.getChunkCache(); + if (chunkCache != null) { // Chunk cache can be null if the session is closed asynchronously + return chunkCache.getBlockAt(x, y, z); + } + return 0; } @Override public int[] getBiomeDataAt(GeyserSession session, int x, int z) { - if (!session.getConnector().getConfig().isCacheChunks()) - return new int[1024]; - return session.getChunkCache().getChunk(x, z).getBiomeData(); + if (session.getConnector().getConfig().isCacheChunks()) { + ChunkCache chunkCache = session.getChunkCache(); + if (chunkCache != null) { // Chunk cache can be null if the session is closed asynchronously + Column column = chunkCache.getChunk(x, z); + if (column != null) { // Column can be null if the server sent a partial chunk update before the first ground-up-continuous one + return column.getBiomeData(); + } + } + } + return new int[1024]; } @Override