diff --git a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java index 57543952b..d61d1159d 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java @@ -38,6 +38,7 @@ import com.github.steveice10.packetlib.tcp.TcpSessionFactory; import com.nukkitx.math.GenericMath; import com.nukkitx.math.TrigMath; import com.nukkitx.math.vector.Vector2f; +import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3i; import com.nukkitx.nbt.tag.CompoundTag; @@ -102,6 +103,8 @@ public class GeyserSession implements CommandSender { private DataCache javaPacketCache; + @Setter + private Vector2i lastChunkPosition = null; private int renderDistance; private boolean loggedIn; diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java index 0f56bc935..cfeb2371f 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/entity/player/JavaPlayerPositionRotationTranslator.java @@ -30,6 +30,7 @@ import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.utils.ChunkUtils; import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket; @@ -86,6 +87,8 @@ public class JavaPlayerPositionRotationTranslator extends PacketTranslator { try { - if (packet.getColumn().getBiomeData() != null) { //Full chunk - ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(packet.getColumn()); - ByteBuf byteBuf = Unpooled.buffer(32); - ChunkSection[] sections = chunkData.sections; + ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(packet.getColumn()); + ByteBuf byteBuf = Unpooled.buffer(32); + ChunkSection[] sections = chunkData.sections; - int sectionCount = sections.length - 1; - while (sectionCount >= 0 && sections[sectionCount].isEmpty()) { - sectionCount--; - } - sectionCount++; - - for (int i = 0; i < sectionCount; i++) { - ChunkSection section = chunkData.sections[i]; - section.writeToNetwork(byteBuf); - } - - byte[] bedrockBiome = BiomeTranslator.toBedrockBiome(packet.getColumn().getBiomeData()); - - byteBuf.writeBytes(bedrockBiome); // Biomes - 256 bytes - byteBuf.writeByte(0); // Border blocks - Edu edition only - VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now - - ByteBufOutputStream stream = new ByteBufOutputStream(Unpooled.buffer()); - NBTOutputStream nbtStream = NbtUtils.createNetworkWriter(stream); - for (CompoundTag blockEntity : chunkData.blockEntities) { - nbtStream.write(blockEntity); - } - - byteBuf.writeBytes(stream.buffer()); - - byte[] payload = new byte[byteBuf.writerIndex()]; - byteBuf.readBytes(payload); - - LevelChunkPacket levelChunkPacket = new LevelChunkPacket(); - levelChunkPacket.setSubChunksLength(sectionCount); - levelChunkPacket.setCachingEnabled(false); - levelChunkPacket.setChunkX(packet.getColumn().getX()); - levelChunkPacket.setChunkZ(packet.getColumn().getZ()); - levelChunkPacket.setData(payload); - session.getUpstream().sendPacket(levelChunkPacket); - - // Signs have to be sent after the chunk since in later versions they aren't included in the block entities - for (Int2ObjectMap.Entry blockEntityEntry : chunkData.signs.int2ObjectEntrySet()) { - int x = blockEntityEntry.getValue().getInt("x"); - int y = blockEntityEntry.getValue().getInt("y"); - int z = blockEntityEntry.getValue().getInt("z"); - - ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntKey()), new Position(x, y, z)); - } - - for (Int2ObjectMap.Entry blockEntityEntry: chunkData.beds.int2ObjectEntrySet()) { - int x = blockEntityEntry.getValue().getInt("x"); - int y = blockEntityEntry.getValue().getInt("y"); - int z = blockEntityEntry.getValue().getInt("z"); - - ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntKey()), new Position(x, y, z)); - } - chunkData.signs.clear(); - chunkData.beds.clear(); - } else { - final int xOffset = packet.getColumn().getX() << 4; - final int zOffset = packet.getColumn().getZ() << 4; - Chunk[] chunks = packet.getColumn().getChunks(); - for (int i = 0; i < chunks.length; i++) { - Chunk chunk = chunks[i]; - if (chunk == null) continue; - final int yOffset = i * 16; - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - BlockState blockState = chunk.get(x, y, z); - Vector3i pos = Vector3i.from( - x + xOffset, - y + yOffset, - z + zOffset); - ChunkUtils.updateBlock(session, blockState, pos); - } - } - } - } + int sectionCount = sections.length - 1; + while (sectionCount >= 0 && sections[sectionCount].isEmpty()) { + sectionCount--; } + sectionCount++; + + for (int i = 0; i < sectionCount; i++) { + ChunkSection section = chunkData.sections[i]; + section.writeToNetwork(byteBuf); + } + + byte[] bedrockBiome = BiomeTranslator.toBedrockBiome(packet.getColumn().getBiomeData()); + + byteBuf.writeBytes(bedrockBiome); // Biomes - 256 bytes + byteBuf.writeByte(0); // Border blocks - Edu edition only + VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now + + ByteBufOutputStream stream = new ByteBufOutputStream(Unpooled.buffer()); + NBTOutputStream nbtStream = NbtUtils.createNetworkWriter(stream); + for (CompoundTag blockEntity : chunkData.blockEntities) { + nbtStream.write(blockEntity); + } + + byteBuf.writeBytes(stream.buffer()); + + byte[] payload = new byte[byteBuf.writerIndex()]; + byteBuf.readBytes(payload); + + LevelChunkPacket levelChunkPacket = new LevelChunkPacket(); + levelChunkPacket.setSubChunksLength(sectionCount); + levelChunkPacket.setCachingEnabled(false); + levelChunkPacket.setChunkX(packet.getColumn().getX()); + levelChunkPacket.setChunkZ(packet.getColumn().getZ()); + levelChunkPacket.setData(payload); + session.getUpstream().sendPacket(levelChunkPacket); + + // Signs have to be sent after the chunk since in later versions they aren't included in the block entities + for (Int2ObjectMap.Entry blockEntityEntry : chunkData.signs.int2ObjectEntrySet()) { + int x = blockEntityEntry.getValue().getInt("x"); + int y = blockEntityEntry.getValue().getInt("y"); + int z = blockEntityEntry.getValue().getInt("z"); + + ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntKey()), new Position(x, y, z)); + } + + for (Int2ObjectMap.Entry blockEntityEntry: chunkData.beds.int2ObjectEntrySet()) { + int x = blockEntityEntry.getValue().getInt("x"); + int y = blockEntityEntry.getValue().getInt("y"); + int z = blockEntityEntry.getValue().getInt("z"); + + ChunkUtils.updateBlock(session, new BlockState(blockEntityEntry.getIntKey()), new Position(x, y, z)); + } + chunkData.signs.clear(); + chunkData.beds.clear(); } catch (Exception ex) { ex.printStackTrace(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateViewPositionTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateViewPositionTranslator.java index 452e86e4f..63ade1533 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateViewPositionTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateViewPositionTranslator.java @@ -28,6 +28,7 @@ package org.geysermc.connector.network.translators.java.world; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; +import org.geysermc.connector.utils.ChunkUtils; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateViewPositionPacket; import com.nukkitx.math.vector.Vector3i; @@ -38,9 +39,8 @@ public class JavaUpdateViewPositionTranslator extends PacketTranslator> 4, position.getZ() >> 4); + + if (chunkPos == null || !chunkPos.equals(newChunkPos)) { + NetworkChunkPublisherUpdatePacket chunkPublisherUpdatePacket = new NetworkChunkPublisherUpdatePacket(); + chunkPublisherUpdatePacket.setPosition(position); + chunkPublisherUpdatePacket.setRadius(session.getRenderDistance() << 4); + session.getUpstream().sendPacket(chunkPublisherUpdatePacket); + + session.setLastChunkPosition(newChunkPos); + } + } + public static void updateBlock(GeyserSession session, BlockState blockState, Position position) { Vector3i pos = Vector3i.from(position.getX(), position.getY(), position.getZ()); updateBlock(session, blockState, pos); diff --git a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java index c7ecaafb4..199c5a5c6 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/DimensionUtils.java @@ -52,6 +52,7 @@ public class DimensionUtils { player.setDimension(bedrockDimension); player.setPosition(pos.toFloat()); session.setSpawned(false); + session.setLastChunkPosition(null); //let java server handle portal travel sound StopSoundPacket stopSoundPacket = new StopSoundPacket();