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
This commit is contained in:
DaPorkchop_ 2020-10-13 17:11:52 +02:00 committed by GitHub
parent 191777773c
commit 73bec588fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 7 deletions

View file

@ -66,11 +66,11 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
return; return;
} }
// Non-full chunks don't have all the chunk data, and Bedrock won't accept that
final boolean isNonFullChunk = (packet.getColumn().getBiomeData() == null);
GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> { GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> {
try { 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); ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(session, packet.getColumn(), isNonFullChunk);
ByteBuf byteBuf = Unpooled.buffer(32); ByteBuf byteBuf = Unpooled.buffer(32);
ChunkSection[] sections = chunkData.sections; ChunkSection[] sections = chunkData.sections;

View file

@ -25,12 +25,14 @@
package org.geysermc.connector.network.translators.world; 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.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty; import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.session.cache.ChunkCache;
import org.geysermc.connector.utils.GameRule; import org.geysermc.connector.utils.GameRule;
public class GeyserWorldManager extends WorldManager { public class GeyserWorldManager extends WorldManager {
@ -39,14 +41,25 @@ public class GeyserWorldManager extends WorldManager {
@Override @Override
public int getBlockAt(GeyserSession session, int x, int y, int z) { 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 @Override
public int[] getBiomeDataAt(GeyserSession session, int x, int z) { public int[] getBiomeDataAt(GeyserSession session, int x, int z) {
if (!session.getConnector().getConfig().isCacheChunks()) if (session.getConnector().getConfig().isCacheChunks()) {
return new int[1024]; ChunkCache chunkCache = session.getChunkCache();
return session.getChunkCache().getChunk(x, z).getBiomeData(); 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 @Override