From e17acb812b98d4eebb022c331c9e5aacac50cb37 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 16 Aug 2018 11:40:04 +0300 Subject: [PATCH] =?UTF-8?q?=D1=83=D1=82=D0=BE=D1=87=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC?= =?UTF-8?q?=D0=B0=20=D1=81=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8=20=D1=87=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=20(Ch?= =?UTF-8?q?unkDataPacket)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/main/java/mc/core/GameLoop.java | 30 +++++----- .../mc/core/embedded/FakePlayerManager.java | 2 + .../mc/core/world/chunk/ChunkSection.java | 3 + .../mc/world/flat/SimpleChunkSection.java | 11 +++- .../proto_1_12_2/packets/ChunkDataPacket.java | 60 +++++++++++++++++-- .../proto_1_12_2/packets/DummyWorld.java | 5 ++ .../netty/handlers/LoginHandler.java | 10 ++-- 7 files changed, 95 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/mc/core/GameLoop.java b/core/src/main/java/mc/core/GameLoop.java index 27843e9..da9cc1c 100644 --- a/core/src/main/java/mc/core/GameLoop.java +++ b/core/src/main/java/mc/core/GameLoop.java @@ -13,7 +13,8 @@ import mc.core.events.SC_ChunkLoadEvent; import mc.core.player.PlayerManager; import mc.core.time.TimeProcessor; import mc.core.utils.CompactedCoords; -import mc.core.world.chunk.ChunkSection; +import mc.core.world.World; +import mc.core.world.chunk.Chunk; import org.springframework.beans.factory.annotation.Autowired; @Slf4j @@ -49,27 +50,28 @@ public class GameLoop extends Thread { log.trace("(GameLoop) playerMoveEventHandler()"); event.getPlayer().getLocation().setXYZ(event.getNewLocation()); - ChunkSection chunkSection = event.getNewLocation().getChunkSection(); - int ncX = chunkSection.getX(); - int ncZ = chunkSection.getZ(); - chunkSection = event.getPlayer().getLocation().getChunkSection(); - int ccX = chunkSection.getX(); - int ccZ = chunkSection.getZ(); + Chunk chunk = event.getNewLocation().getChunk(); // Next chunk + int ncX = chunk.getX(); + int ncZ = chunk.getZ(); + chunk = event.getPlayer().getLocation().getChunk(); // Current chunk + int ccX = chunk.getX(); + int ccZ = chunk.getZ(); if (event.isRecalcChunk() || (ncX != ccX && ncZ != ccZ)) { - /* FIXME заменить "8" на актуальный view distance */ - final int viewDistance = 8; - int cMinX = chunkSection.getX() - viewDistance; - int cMaxX = chunkSection.getX() + viewDistance; - int cMinZ = chunkSection.getZ() - viewDistance; - int cMaxZ = chunkSection.getZ() + viewDistance; + final int viewDistance = event.getPlayer().getSettings().getViewDistance(); + int cMinX = chunk.getX() - viewDistance; + int cMaxX = chunk.getX() + viewDistance; + int cMinZ = chunk.getZ() - viewDistance; + int cMaxZ = chunk.getZ() + viewDistance; SC_ChunkLoadEvent eventChunkLoad = new SC_ChunkLoadEvent(event.getPlayer()); for (int cZ = cMinZ; cZ <= cMaxZ; cZ++) { for (int cX = cMinX; cX <= cMaxX; cX++) { int compressXZ = CompactedCoords.compressXZ(cX, cZ); if (!event.getPlayer().getLoadedChunks().contains(compressXZ)) { - eventChunkLoad.getNeedLoadChunks().add(compressXZ); + if (!event.getPlayer().getLoadedChunks().contains(compressXZ)) { + eventChunkLoad.getNeedLoadChunks().add(compressXZ); + } } } } diff --git a/core/src/main/java/mc/core/embedded/FakePlayerManager.java b/core/src/main/java/mc/core/embedded/FakePlayerManager.java index d3e4f55..612de62 100644 --- a/core/src/main/java/mc/core/embedded/FakePlayerManager.java +++ b/core/src/main/java/mc/core/embedded/FakePlayerManager.java @@ -12,6 +12,8 @@ import mc.core.player.Player; import mc.core.player.PlayerManager; import mc.core.text.Text; import mc.core.text.Title; +import mc.core.world.chunk.Chunk; +import mc.core.world.chunk.ChunkSection; import java.util.Collections; import java.util.List; diff --git a/core/src/main/java/mc/core/world/chunk/ChunkSection.java b/core/src/main/java/mc/core/world/chunk/ChunkSection.java index 97433d2..3c10125 100644 --- a/core/src/main/java/mc/core/world/chunk/ChunkSection.java +++ b/core/src/main/java/mc/core/world/chunk/ChunkSection.java @@ -4,6 +4,7 @@ */ package mc.core.world.chunk; +import mc.core.world.Biome; import mc.core.world.World; import mc.core.world.block.Block; @@ -22,5 +23,7 @@ public interface ChunkSection { int getAddition(int x, int y, int z); void setAddition(int x, int y, int z, int value); + Biome getBiome(int localX, int localZ); + World getWorld(); } diff --git a/flat_world/src/main/java/mc/world/flat/SimpleChunkSection.java b/flat_world/src/main/java/mc/world/flat/SimpleChunkSection.java index c70ec87..414cbb4 100644 --- a/flat_world/src/main/java/mc/world/flat/SimpleChunkSection.java +++ b/flat_world/src/main/java/mc/world/flat/SimpleChunkSection.java @@ -4,12 +4,17 @@ */ package mc.world.flat; +import mc.core.world.Biome; import mc.core.world.World; import mc.core.world.block.Block; import mc.core.world.block.BlockFactory; import mc.core.world.block.BlockType; +import mc.core.world.chunk.Chunk; import mc.core.world.chunk.ChunkSection; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; + public class SimpleChunkSection implements ChunkSection { @Override public int getSkyLight(int x, int y, int z) { @@ -19,7 +24,6 @@ public class SimpleChunkSection implements ChunkSection { @Override public void setSkyLight(int x, int y, int z, int lightLevel) { - } @Override @@ -29,7 +33,11 @@ public class SimpleChunkSection implements ChunkSection { @Override public void setAddition(int x, int y, int z, int value) { + } + @Override + public Biome getBiome(int localX, int localZ) { + return Biome.PLAINS; } @Override @@ -49,7 +57,6 @@ public class SimpleChunkSection implements ChunkSection { @Override public void setBlock(Block block) { - } @Override diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java index 2dd9414..b3d6cd7 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/ChunkDataPacket.java @@ -17,6 +17,8 @@ import mc.core.world.chunk.Chunk; import mc.core.world.chunk.ChunkSection; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /* @@ -77,26 +79,74 @@ public class ChunkDataPacket implements SCPacket { private int z; @Setter private boolean initChunk = true; // "Ground-Up Continuous" - @Setter private Chunk chunk; + private List sectionList; private int serializeBlockState(BlockType blockType) { return (blockType.getId() << 4) | blockType.getMeta(); } + public void setChunk(Chunk chunk) { + this.sectionList = null; + this.chunk = chunk; + } + + public void setChunkSectionList(List sectionList) { + this.chunk = null; + this.sectionList = sectionList; + } + @Override public void writeSelf(NetOutputStream netStream) { netStream.writeInt(x); // Chunk X netStream.writeInt(z); // Chunk Y netStream.writeBoolean(initChunk); // Init Chunk - netStream.writeVarInt(0b00000001); // Primary Bit Mask + + if (sectionList == null && chunk != null) { + int bitMask = 0; + for (int h = 15; h >= 0; h--) { + bitMask = bitMask << 1; + ChunkSection chunkSection = chunk.getChunkSection(h); + if (chunkSection != null && chunkSection.getY() == h) { + bitMask |= 0x01; + } else { + bitMask |= 0x00; + } + } + + netStream.writeVarInt(bitMask); // Primary Bit Mask + } else if (sectionList != null && chunk == null) { + sectionList.sort(Comparator.comparingInt(ChunkSection::getY)); + int bitMask = 0; + for (int h = 15, i = 0; h >= 0; h--) { + bitMask = bitMask << 1; + ChunkSection chunkSection = sectionList.get(i); + if (chunkSection != null && chunkSection.getY() == h) { + bitMask |= 0x01; + } else { + bitMask |= 0x00; + } + } + + netStream.writeVarInt(bitMask); // Primary Bit Mask + } else { + log.warn("Empty chunk data"); + return; + } final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream(); int dataItems = 0; final int airBlockPalette = serializeBlockState(BlockType.AIR); - for (int h = 0; h < 1/*потому что у нас пока только единичная сейция*/; h++) { - ChunkSection chunkSection = chunk.getChunkSection(h); + for (int h = 0; h < 16; h++) { + ChunkSection chunkSection = null; + + if (chunk != null) { + chunkSection = chunk.getChunkSection(h); + } else if (sectionList != null) { + chunkSection = sectionList.remove(0); + } + if (chunkSection == null) { continue; } @@ -156,7 +206,7 @@ public class ChunkDataPacket implements SCPacket { } if (!biomeFinally) { - biomes.writeByte(chunk.getBiome(x, z).getId()); + biomes.writeByte(chunkSection.getBiome(x, z).getId()); if (x == 15 && z == 15) { biomeFinally = true; } diff --git a/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/DummyWorld.java b/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/DummyWorld.java index f485394..52e8a88 100644 --- a/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/DummyWorld.java +++ b/proto_1.12.2/src/test/java/mc/core/network/proto_1_12_2/packets/DummyWorld.java @@ -31,6 +31,11 @@ public class DummyWorld implements World { public void setAddition(int x, int y, int z, int value) { } + @Override + public Biome getBiome(int localX, int localZ) { + return Biome.PLAINS; + } + @Override public int getX() { return 0; diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java index b2a0a76..15cf04b 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java @@ -64,7 +64,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand pkt1.setMode(PlayerMode.CREATIVE); pkt1.setDimension(0/*Overworld*/); pkt1.setDifficulty(0/*Peaceful*/); - pkt1.setLevelType("flat"); //FIXME + pkt1.setLevelType(world.getWorldType().getName()); channel.write(pkt1); // Spawn Position @@ -81,11 +81,11 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand channel.write(pkt3); channel.flush(); - // One Chunk + // First Chunk ChunkDataPacket pkt8 = new ChunkDataPacket(); - pkt8.setX(0); - pkt8.setZ(0); - pkt8.setChunk(world.getChunk(0, 0)); + pkt8.setX(player.getLocation().getChunk().getX()); + pkt8.setZ(player.getLocation().getChunk().getZ()); + pkt8.setChunk(player.getLocation().getChunk()); pkt8.setInitChunk(true); channel.writeAndFlush(pkt8); player.getLoadedChunks().add(CompactedCoords.compressXZ(0, 0));