mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Fix empty chunk encoding
This commit is contained in:
parent
8bf8b22d6b
commit
bd613987ce
5 changed files with 31 additions and 32 deletions
|
@ -99,6 +99,8 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||||
if (needsSpawnPacket) {
|
if (needsSpawnPacket) {
|
||||||
// The player has yet to spawn so let's do that using some of the information in this Java packet
|
// The player has yet to spawn so let's do that using some of the information in this Java packet
|
||||||
session.setDimension(newDimension);
|
session.setDimension(newDimension);
|
||||||
|
session.setDimensionType(dimensions.get(newDimension));
|
||||||
|
ChunkUtils.loadDimension(session);
|
||||||
session.connect();
|
session.connect();
|
||||||
|
|
||||||
// It is now safe to send these packets
|
// It is now safe to send these packets
|
||||||
|
@ -145,8 +147,5 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||||
// If the player is spawning into the "fake" nether, send them some fog
|
// If the player is spawning into the "fake" nether, send them some fog
|
||||||
session.sendFog("minecraft:fog_hell");
|
session.sendFog("minecraft:fog_hell");
|
||||||
}
|
}
|
||||||
|
|
||||||
session.setDimensionType(dimensions.get(newDimension));
|
|
||||||
ChunkUtils.loadDimension(session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
import org.geysermc.geyser.util.ChunkUtils;
|
|
||||||
import org.geysermc.geyser.util.DimensionUtils;
|
import org.geysermc.geyser.util.DimensionUtils;
|
||||||
|
|
||||||
@Translator(packet = ClientboundRespawnPacket.class)
|
@Translator(packet = ClientboundRespawnPacket.class)
|
||||||
|
@ -93,9 +92,6 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
|
||||||
}
|
}
|
||||||
session.setWorldName(packet.getWorldName());
|
session.setWorldName(packet.getWorldName());
|
||||||
DimensionUtils.switchDimension(session, newDimension);
|
DimensionUtils.switchDimension(session, newDimension);
|
||||||
|
|
||||||
session.setDimensionType(session.getDimensions().get(newDimension));
|
|
||||||
ChunkUtils.loadDimension(session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.nbt.NBTOutputStream;
|
import com.nukkitx.nbt.NBTOutputStream;
|
||||||
import com.nukkitx.nbt.NbtMap;
|
import com.nukkitx.nbt.NbtMap;
|
||||||
import com.nukkitx.nbt.NbtUtils;
|
import com.nukkitx.nbt.NbtUtils;
|
||||||
import com.nukkitx.network.VarInts;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
|
import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
@ -284,6 +283,9 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
}
|
}
|
||||||
sectionCount++;
|
sectionCount++;
|
||||||
|
|
||||||
|
// As of 1.18.30, the amount of biomes read is dependent on how high Bedrock thinks the dimension is
|
||||||
|
int biomeCount = bedrockDimension.height() >> 4;
|
||||||
|
|
||||||
// Estimate chunk size
|
// Estimate chunk size
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (int i = 0; i < sectionCount; i++) {
|
for (int i = 0; i < sectionCount; i++) {
|
||||||
|
@ -294,9 +296,8 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
size += SERIALIZED_CHUNK_DATA.length;
|
size += SERIALIZED_CHUNK_DATA.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size += ChunkUtils.EMPTY_CHUNK_DATA.length; // Consists only of biome data
|
size += ChunkUtils.EMPTY_BIOME_DATA.length * biomeCount;
|
||||||
size += 1; // Border blocks
|
size += 1; // Border blocks
|
||||||
size += 1; // Extra data length (always 0)
|
|
||||||
size += bedrockBlockEntities.size() * 64; // Conservative estimate of 64 bytes per tile entity
|
size += bedrockBlockEntities.size() * 64; // Conservative estimate of 64 bytes per tile entity
|
||||||
|
|
||||||
// Allocate output buffer
|
// Allocate output buffer
|
||||||
|
@ -310,8 +311,6 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As of 1.18.30, the amount of biomes read is dependent on how high Bedrock thinks the dimension is
|
|
||||||
int biomeCount = bedrockDimension.height() >> 4;
|
|
||||||
int dimensionOffset = bedrockDimension.minY() >> 4;
|
int dimensionOffset = bedrockDimension.minY() >> 4;
|
||||||
for (int i = 0; i < biomeCount; i++) {
|
for (int i = 0; i < biomeCount; i++) {
|
||||||
int biomeYOffset = dimensionOffset + i;
|
int biomeYOffset = dimensionOffset + i;
|
||||||
|
@ -331,7 +330,6 @@ public class JavaLevelChunkWithLightTranslator extends PacketTranslator<Clientbo
|
||||||
}
|
}
|
||||||
|
|
||||||
byteBuf.writeByte(0); // Border blocks - Edu edition only
|
byteBuf.writeByte(0); // Border blocks - Edu edition only
|
||||||
VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now
|
|
||||||
|
|
||||||
// Encode tile entities into buffer
|
// Encode tile entities into buffer
|
||||||
NBTOutputStream nbtStream = NbtUtils.createNetworkWriter(new ByteBufOutputStream(byteBuf));
|
NBTOutputStream nbtStream = NbtUtils.createNetworkWriter(new ByteBufOutputStream(byteBuf));
|
||||||
|
|
|
@ -31,6 +31,7 @@ import com.nukkitx.protocol.bedrock.packet.LevelChunkPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
import it.unimi.dsi.fastutil.ints.IntLists;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
@ -54,10 +55,6 @@ public class ChunkUtils {
|
||||||
* An empty subchunk.
|
* An empty subchunk.
|
||||||
*/
|
*/
|
||||||
public static final byte[] SERIALIZED_CHUNK_DATA;
|
public static final byte[] SERIALIZED_CHUNK_DATA;
|
||||||
/**
|
|
||||||
* An empty chunk that can be safely passed on to a LevelChunkPacket with subcounts set to 0.
|
|
||||||
*/
|
|
||||||
public static final byte[] EMPTY_CHUNK_DATA;
|
|
||||||
public static final byte[] EMPTY_BIOME_DATA;
|
public static final byte[] EMPTY_BIOME_DATA;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -81,20 +78,6 @@ public class ChunkUtils {
|
||||||
} finally {
|
} finally {
|
||||||
byteBuf.release();
|
byteBuf.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
byteBuf = Unpooled.buffer();
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < 32; i++) {
|
|
||||||
byteBuf.writeBytes(EMPTY_BIOME_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
byteBuf.writeByte(0); // Border
|
|
||||||
|
|
||||||
EMPTY_CHUNK_DATA = new byte[byteBuf.readableBytes()];
|
|
||||||
byteBuf.readBytes(EMPTY_CHUNK_DATA);
|
|
||||||
} finally {
|
|
||||||
byteBuf.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int indexYZXtoXZY(int yzx) {
|
public static int indexYZXtoXZY(int yzx) {
|
||||||
|
@ -185,11 +168,32 @@ public class ChunkUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendEmptyChunk(GeyserSession session, int chunkX, int chunkZ, boolean forceUpdate) {
|
public static void sendEmptyChunk(GeyserSession session, int chunkX, int chunkZ, boolean forceUpdate) {
|
||||||
|
BedrockDimension bedrockDimension = session.getChunkCache().getBedrockDimension();
|
||||||
|
int bedrockSubChunkCount = bedrockDimension.height() >> 4;
|
||||||
|
|
||||||
|
byte[] payload;
|
||||||
|
|
||||||
|
// Allocate output buffer
|
||||||
|
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(ChunkUtils.EMPTY_BIOME_DATA.length * bedrockSubChunkCount + 1); // Consists only of biome data and border blocks
|
||||||
|
try {
|
||||||
|
byteBuf.writeBytes(EMPTY_BIOME_DATA);
|
||||||
|
for (int i = 1; i < bedrockSubChunkCount; i++) {
|
||||||
|
byteBuf.writeByte((127 << 1) | 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
byteBuf.writeByte(0); // Border blocks - Edu edition only
|
||||||
|
|
||||||
|
payload = new byte[byteBuf.readableBytes()];
|
||||||
|
byteBuf.readBytes(payload);
|
||||||
|
} finally {
|
||||||
|
byteBuf.release();
|
||||||
|
}
|
||||||
|
|
||||||
LevelChunkPacket data = new LevelChunkPacket();
|
LevelChunkPacket data = new LevelChunkPacket();
|
||||||
data.setChunkX(chunkX);
|
data.setChunkX(chunkX);
|
||||||
data.setChunkZ(chunkZ);
|
data.setChunkZ(chunkZ);
|
||||||
data.setSubChunksLength(0);
|
data.setSubChunksLength(0);
|
||||||
data.setData(EMPTY_CHUNK_DATA);
|
data.setData(payload);
|
||||||
data.setCachingEnabled(false);
|
data.setCachingEnabled(false);
|
||||||
session.sendUpstreamPacket(data);
|
session.sendUpstreamPacket(data);
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,8 @@ public class DimensionUtils {
|
||||||
changeDimensionPacket.setPosition(pos);
|
changeDimensionPacket.setPosition(pos);
|
||||||
session.sendUpstreamPacket(changeDimensionPacket);
|
session.sendUpstreamPacket(changeDimensionPacket);
|
||||||
session.setDimension(javaDimension);
|
session.setDimension(javaDimension);
|
||||||
|
session.setDimensionType(session.getDimensions().get(javaDimension));
|
||||||
|
ChunkUtils.loadDimension(session);
|
||||||
player.setPosition(pos);
|
player.setPosition(pos);
|
||||||
session.setSpawned(false);
|
session.setSpawned(false);
|
||||||
session.setLastChunkPosition(null);
|
session.setLastChunkPosition(null);
|
||||||
|
|
Loading…
Reference in a new issue