From a55e340cfe7ded0944ed3048288bc395a012b6b3 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sat, 28 Apr 2018 11:53:43 +0300 Subject: [PATCH 1/3] Flat world --- core/src/main/java/mc/core/world/Chunk.java | 6 + flat_world/README.MD | 19 +++ flat_world/build.gradle | 7 + .../main/java/mc/world/flat/FlatWorld.java | 28 ++++ .../main/java/mc/world/flat/SimpleChunk.java | 127 ++++++++++++++++++ .../proto_125/packets/ChunkDataPacket.java | 48 +++---- .../proto_125/netty/PacketHandler.java | 9 +- settings.gradle | 1 + 8 files changed, 209 insertions(+), 36 deletions(-) create mode 100644 flat_world/README.MD create mode 100644 flat_world/build.gradle create mode 100644 flat_world/src/main/java/mc/world/flat/FlatWorld.java create mode 100644 flat_world/src/main/java/mc/world/flat/SimpleChunk.java diff --git a/core/src/main/java/mc/core/world/Chunk.java b/core/src/main/java/mc/core/world/Chunk.java index cbc3957..e38fba2 100644 --- a/core/src/main/java/mc/core/world/Chunk.java +++ b/core/src/main/java/mc/core/world/Chunk.java @@ -7,20 +7,26 @@ package mc.core.world; /* 16x256x16 */ public interface Chunk { int getBlockType(int x, int y, int z); + int[] getBlockTypeAsArray(); void setBlockType(int x, int y, int z, int type); int getBlockMetadata(int x, int y, int z); + int[] getBlockMetadataAsArray(); void setBlockMetadata(int x, int y, int z, int metadata); int getBlockLight(int x, int y, int z); + int[] getBlockLightAsArray(); void setBlockLight(int x, int y, int z, int lightLevel); int getSkyLight(int x, int y, int z); + int[] getSkyLightAsArray(); void setSkyLight(int x, int y, int z, int lightLevel); int getAddition(int x, int y, int z); + int[] getAdditionAsArray(); void setAddition(int x, int y, int z, int value); int getBiome(int x, int y, int z); + int[] getBiomeAsArray(); void setBiome(int x, int y, int z, int value); } diff --git a/flat_world/README.MD b/flat_world/README.MD new file mode 100644 index 0000000..f48fe3b --- /dev/null +++ b/flat_world/README.MD @@ -0,0 +1,19 @@ +# Flat world + +Плоский мир + +## Spring bean + +```xml + + + + + + + + + +``` + +`spawn` - точка спавна diff --git a/flat_world/build.gradle b/flat_world/build.gradle new file mode 100644 index 0000000..a9ac8b6 --- /dev/null +++ b/flat_world/build.gradle @@ -0,0 +1,7 @@ +group 'mc' +version '1.0-SNAPSHOT' + +dependencies { + /* Core */ + compile_excludeCopy project(':core') +} diff --git a/flat_world/src/main/java/mc/world/flat/FlatWorld.java b/flat_world/src/main/java/mc/world/flat/FlatWorld.java new file mode 100644 index 0000000..8340979 --- /dev/null +++ b/flat_world/src/main/java/mc/world/flat/FlatWorld.java @@ -0,0 +1,28 @@ +/* + * DmitriyMX + * 2018-04-28 + */ +package mc.world.flat; + +import lombok.Getter; +import lombok.Setter; +import mc.core.Location; +import mc.core.world.Chunk; +import mc.core.world.World; + +public class FlatWorld implements World { + @Getter + @Setter + private Location spawn = new Location(0, 6, 0); + private Chunk chunk = new SimpleChunk(); + + @Override + public Chunk getChunk(int x, int z) { + return chunk; + } + + @Override + public void setChunk(int x, int z, Chunk chunk) { + throw new UnsupportedOperationException(); + } +} diff --git a/flat_world/src/main/java/mc/world/flat/SimpleChunk.java b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java new file mode 100644 index 0000000..65c61e7 --- /dev/null +++ b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java @@ -0,0 +1,127 @@ +/* + * DmitriyMX + * 2018-04-28 + */ +package mc.world.flat; + +import mc.core.world.Chunk; + +import java.util.Arrays; + +public class SimpleChunk implements Chunk { + private int[] blocktype = new int[4096]; + private int[] blockmeta = new int[2048]; + private int[] blocklight = new int[2048]; + private int[] skylight = new int[2048]; + private int[] addition = new int[2048]; + private int[] biometype = new int[256]; + + SimpleChunk() { + Arrays.fill(blocktype, 0, 256, 7); + Arrays.fill(blocktype, 256, 768, 3); + Arrays.fill(blocktype, 768, 1024, 2); + Arrays.fill(blocktype, 1024, 4096, 0); + + Arrays.fill(blockmeta, 0); + + Arrays.fill(blocklight, 0); + + Arrays.fill(skylight, 0, 512, 0); + Arrays.fill(skylight, 512, 2048, -1); + + Arrays.fill(addition, 0, 256, 1); + Arrays.fill(addition, 256, 2048, 0); + + Arrays.fill(biometype, 0); + } + + @Override + public int getBlockType(int x, int y, int z) { + return 0; + } + + @Override + public int[] getBlockTypeAsArray() { + return blocktype; + } + + @Override + public void setBlockType(int x, int y, int z, int type) { + + } + + @Override + public int getBlockMetadata(int x, int y, int z) { + return 0; + } + + @Override + public int[] getBlockMetadataAsArray() { + return blockmeta; + } + + @Override + public void setBlockMetadata(int x, int y, int z, int metadata) { + + } + + @Override + public int getBlockLight(int x, int y, int z) { + return 0; + } + + @Override + public int[] getBlockLightAsArray() { + return blocklight; + } + + @Override + public void setBlockLight(int x, int y, int z, int lightLevel) { + + } + + @Override + public int getSkyLight(int x, int y, int z) { + return 0; + } + + @Override + public int[] getSkyLightAsArray() { + return skylight; + } + + @Override + public void setSkyLight(int x, int y, int z, int lightLevel) { + + } + + @Override + public int getAddition(int x, int y, int z) { + return 0; + } + + @Override + public int[] getAdditionAsArray() { + return addition; + } + + @Override + public void setAddition(int x, int y, int z, int value) { + + } + + @Override + public int getBiome(int x, int y, int z) { + return 0; + } + + @Override + public int[] getBiomeAsArray() { + return biometype; + } + + @Override + public void setBiome(int x, int y, int z, int value) { + + } +} diff --git a/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java b/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java index ae8b9ad..b780644 100644 --- a/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java +++ b/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java @@ -8,55 +8,37 @@ import lombok.Setter; import lombok.ToString; import mc.core.network.SCPacket; import mc.core.network.proto_125.ByteArrayOutputNetStream; +import mc.core.world.Chunk; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; import java.util.Arrays; import java.util.zip.Deflater; @Setter @ToString public class ChunkDataPacket implements SCPacket { - private static byte[] compressData; + private static final int dataSize = 4096 + 2048 + 2048 + 2048 + 2048 + 256; private int x, z; private boolean needInitChunk; private int yMin,yMax; + private byte[] compressData; - static { - byte[] blocktype = new byte[4096]; - Arrays.fill(blocktype, 0, 256, (byte)7); - Arrays.fill(blocktype, 256, 768, (byte)3); - Arrays.fill(blocktype, 768, 1024, (byte)2); - Arrays.fill(blocktype, 1024, 4096, (byte)0); + public void setChunk(Chunk chunk) { + ByteBuffer chunkData = ByteBuffer.allocate(dataSize); - byte[] blockmeta = new byte[2048]; - Arrays.fill(blockmeta, (byte)0); - - byte[] blocklight = new byte[2048]; - Arrays.fill(blocklight, (byte)0); - - byte[] skylight = new byte[2048]; - Arrays.fill(skylight, 0, 512, (byte) 0); - Arrays.fill(skylight, 512, 2048, (byte)-1); - - byte[] addition = new byte[2048]; - Arrays.fill(addition, 0, 256, (byte)1); - Arrays.fill(addition, 256, 2048, (byte)0); - - byte[] biometype = new byte[256]; - Arrays.fill(biometype, (byte)0); - - byte[] chunkData = new byte[blocktype.length + blockmeta.length + blocklight.length + skylight.length + addition.length + biometype.length]; - System.arraycopy(blocktype, 0, chunkData, 0, blocktype.length); - System.arraycopy(blockmeta, 0, chunkData, blocktype.length, blockmeta.length); - System.arraycopy(blocklight, 0, chunkData, blockmeta.length, blocklight.length); - System.arraycopy(skylight, 0, chunkData, blocklight.length, skylight.length); - System.arraycopy(addition, 0, chunkData, skylight.length, addition.length); - System.arraycopy(biometype, 0, chunkData, addition.length, biometype.length); + Arrays.stream(chunk.getBlockTypeAsArray()).forEach(i -> chunkData.put((byte) i)); + Arrays.stream(chunk.getBlockMetadataAsArray()).forEach(i -> chunkData.put((byte) i)); + Arrays.stream(chunk.getBlockLightAsArray()).forEach(i -> chunkData.put((byte) i)); + Arrays.stream(chunk.getSkyLightAsArray()).forEach(i -> chunkData.put((byte) i)); + Arrays.stream(chunk.getAdditionAsArray()).forEach(i -> chunkData.put((byte) i)); + Arrays.stream(chunk.getBiomeAsArray()).forEach(i -> chunkData.put((byte) i)); Deflater zlib = new Deflater(Deflater.DEFAULT_COMPRESSION); - zlib.setInput(chunkData); + zlib.setInput(chunkData.array()); zlib.finish(); - byte[] preCompileData = new byte[chunkData.length]; + byte[] preCompileData = new byte[dataSize]; int compressSize = zlib.deflate(preCompileData); compressData = new byte[compressSize]; diff --git a/proto125_netty/src/main/java/mc/core/network/proto_125/netty/PacketHandler.java b/proto125_netty/src/main/java/mc/core/network/proto_125/netty/PacketHandler.java index c14ea9b..a886a6a 100644 --- a/proto125_netty/src/main/java/mc/core/network/proto_125/netty/PacketHandler.java +++ b/proto125_netty/src/main/java/mc/core/network/proto_125/netty/PacketHandler.java @@ -15,6 +15,7 @@ import mc.core.*; import mc.core.network.CSPacket; import mc.core.network.proto_125.netty.wrappers.WrapperNetChannel; import mc.core.network.proto_125.packets.*; +import mc.core.world.World; import org.springframework.beans.factory.annotation.Autowired; import java.lang.reflect.Method; @@ -28,6 +29,8 @@ public class PacketHandler extends SimpleChannelInboundHandler { private Config config; @Autowired private PlayerManager playerManager; + @Autowired + private World world; @Override public void channelInactive(ChannelHandlerContext context) throws Exception { @@ -66,7 +69,6 @@ public class PacketHandler extends SimpleChannelInboundHandler { } public void onLoginPacket(Channel channel, LoginPacket packet) { - final Location spawnLoc = new Location(0, 6, 0); Player player; Optional optPlayer = playerManager.getPlayer(packet.getPlayerName()); @@ -80,7 +82,7 @@ public class PacketHandler extends SimpleChannelInboundHandler { } } else { player = playerManager.createPlayer(packet.getPlayerName()); - player.setLocation(spawnLoc); + player.setLocation(world.getSpawn()); player.setLook(new Look(0f, 0f)); } @@ -95,7 +97,7 @@ public class PacketHandler extends SimpleChannelInboundHandler { // send Spawn position SpawnPositionPacket spawnPkt = new SpawnPositionPacket(); - spawnPkt.setLocation(spawnLoc); + spawnPkt.setLocation(world.getSpawn()); channel.write(spawnPkt); // send Player abilities @@ -124,6 +126,7 @@ public class PacketHandler extends SimpleChannelInboundHandler { ChunkDataPacket chDataPkt = new ChunkDataPacket(); chDataPkt.setX(0); chDataPkt.setZ(0); + chDataPkt.setChunk(world.getChunk(0, 0)); chDataPkt.setNeedInitChunk(true); chDataPkt.setYMin(1); chDataPkt.setYMax(0); diff --git a/settings.gradle b/settings.gradle index 1f59b9d..8636be1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,3 +3,4 @@ rootProject.name = 'mc-server' include('core') // Core include('proto125') // Protocol 1.2.5 include('proto125_netty') // Protocol 1.2.5 (Netty impl.) +include('flat_world') From ed22229bd2eb1d768cf48e5005f08ef45ea5c8d0 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sat, 28 Apr 2018 20:42:44 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20=D1=81=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=87=D0=B0=D0=BD=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/main/java/mc/core/world/Chunk.java | 12 +-- .../main/java/mc/world/flat/SimpleChunk.java | 70 ++------------- .../proto_125/packets/ChunkDataPacket.java | 86 +++++++++++++++++-- 3 files changed, 90 insertions(+), 78 deletions(-) diff --git a/core/src/main/java/mc/core/world/Chunk.java b/core/src/main/java/mc/core/world/Chunk.java index e38fba2..15ee0fa 100644 --- a/core/src/main/java/mc/core/world/Chunk.java +++ b/core/src/main/java/mc/core/world/Chunk.java @@ -4,29 +4,23 @@ */ package mc.core.world; -/* 16x256x16 */ +/* 16x16x16 */ public interface Chunk { int getBlockType(int x, int y, int z); - int[] getBlockTypeAsArray(); void setBlockType(int x, int y, int z, int type); int getBlockMetadata(int x, int y, int z); - int[] getBlockMetadataAsArray(); void setBlockMetadata(int x, int y, int z, int metadata); int getBlockLight(int x, int y, int z); - int[] getBlockLightAsArray(); void setBlockLight(int x, int y, int z, int lightLevel); int getSkyLight(int x, int y, int z); - int[] getSkyLightAsArray(); void setSkyLight(int x, int y, int z, int lightLevel); int getAddition(int x, int y, int z); - int[] getAdditionAsArray(); void setAddition(int x, int y, int z, int value); - int getBiome(int x, int y, int z); - int[] getBiomeAsArray(); - void setBiome(int x, int y, int z, int value); + int getBiome(int x, int z); + void setBiome(int x, int z, int value); } diff --git a/flat_world/src/main/java/mc/world/flat/SimpleChunk.java b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java index 65c61e7..5186615 100644 --- a/flat_world/src/main/java/mc/world/flat/SimpleChunk.java +++ b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java @@ -6,43 +6,13 @@ package mc.world.flat; import mc.core.world.Chunk; -import java.util.Arrays; - public class SimpleChunk implements Chunk { - private int[] blocktype = new int[4096]; - private int[] blockmeta = new int[2048]; - private int[] blocklight = new int[2048]; - private int[] skylight = new int[2048]; - private int[] addition = new int[2048]; - private int[] biometype = new int[256]; - - SimpleChunk() { - Arrays.fill(blocktype, 0, 256, 7); - Arrays.fill(blocktype, 256, 768, 3); - Arrays.fill(blocktype, 768, 1024, 2); - Arrays.fill(blocktype, 1024, 4096, 0); - - Arrays.fill(blockmeta, 0); - - Arrays.fill(blocklight, 0); - - Arrays.fill(skylight, 0, 512, 0); - Arrays.fill(skylight, 512, 2048, -1); - - Arrays.fill(addition, 0, 256, 1); - Arrays.fill(addition, 256, 2048, 0); - - Arrays.fill(biometype, 0); - } - @Override public int getBlockType(int x, int y, int z) { - return 0; - } - - @Override - public int[] getBlockTypeAsArray() { - return blocktype; + if (y == 0) return 7; + else if (y >= 1 && y <= 2) return 3; + else if (y == 3) return 2; + else return 0; } @Override @@ -55,11 +25,6 @@ public class SimpleChunk implements Chunk { return 0; } - @Override - public int[] getBlockMetadataAsArray() { - return blockmeta; - } - @Override public void setBlockMetadata(int x, int y, int z, int metadata) { @@ -70,11 +35,6 @@ public class SimpleChunk implements Chunk { return 0; } - @Override - public int[] getBlockLightAsArray() { - return blocklight; - } - @Override public void setBlockLight(int x, int y, int z, int lightLevel) { @@ -82,12 +42,8 @@ public class SimpleChunk implements Chunk { @Override public int getSkyLight(int x, int y, int z) { - return 0; - } - - @Override - public int[] getSkyLightAsArray() { - return skylight; + if (y <= 3) return 0; + else return 15; } @Override @@ -100,28 +56,18 @@ public class SimpleChunk implements Chunk { return 0; } - @Override - public int[] getAdditionAsArray() { - return addition; - } - @Override public void setAddition(int x, int y, int z, int value) { } @Override - public int getBiome(int x, int y, int z) { + public int getBiome(int x, int z) { return 0; } @Override - public int[] getBiomeAsArray() { - return biometype; - } - - @Override - public void setBiome(int x, int y, int z, int value) { + public void setBiome(int x, int z, int value) { } } diff --git a/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java b/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java index b780644..1ab5cd0 100644 --- a/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java +++ b/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java @@ -18,7 +18,13 @@ import java.util.zip.Deflater; @Setter @ToString public class ChunkDataPacket implements SCPacket { - private static final int dataSize = 4096 + 2048 + 2048 + 2048 + 2048 + 256; + private static final int blocktypeSize = 4096, + metadataSize = 2048, + blocklightSize = 2048, + skylightSize = 2048, + additionSize = 2048, + biomeSize = 256; + private static final int dataSize = blocktypeSize+metadataSize+blocklightSize+skylightSize+additionSize+biomeSize; private int x, z; private boolean needInitChunk; @@ -28,12 +34,78 @@ public class ChunkDataPacket implements SCPacket { public void setChunk(Chunk chunk) { ByteBuffer chunkData = ByteBuffer.allocate(dataSize); - Arrays.stream(chunk.getBlockTypeAsArray()).forEach(i -> chunkData.put((byte) i)); - Arrays.stream(chunk.getBlockMetadataAsArray()).forEach(i -> chunkData.put((byte) i)); - Arrays.stream(chunk.getBlockLightAsArray()).forEach(i -> chunkData.put((byte) i)); - Arrays.stream(chunk.getSkyLightAsArray()).forEach(i -> chunkData.put((byte) i)); - Arrays.stream(chunk.getAdditionAsArray()).forEach(i -> chunkData.put((byte) i)); - Arrays.stream(chunk.getBiomeAsArray()).forEach(i -> chunkData.put((byte) i)); + /* + * 0 - blocktype + * 1 - metadata + * 2 - blocklight + * 3 - skylight + * 4 - addition + * 5 - biome + */ + int[] idx = new int[6]; + + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++) { + // Block type + int offset = 0; + chunkData.put((idx[0]++), (byte) chunk.getBlockType(x, y, z)); + + // Block metadata + offset = offset+blocktypeSize; + if ((idx[1] % 2) > 0) { + int i = (int) ((((idx[1]++) + 1) / 2d) - 1d); + byte b = chunkData.get(offset+i); + b = (byte)((b << 4) | (byte)chunk.getBlockMetadata(x, y, z)); + chunkData.put(offset+i, b); + } else { + int i = (int) ((((idx[1]++) + 1) / 2d) - .5d); + chunkData.put(offset+i, (byte) chunk.getBlockMetadata(x, y, z)); + } + + // Block light + offset = offset+metadataSize; + if ((idx[2] % 2) > 0) { + int i = (int) ((((idx[2]++) + 1) / 2d) - 1d); + byte b = chunkData.get(offset+i); + b = (byte)((b << 4) | (byte)chunk.getBlockLight(x, y, z)); + chunkData.put(offset+i, b); + } else { + int i = (int) ((((idx[2]++) + 1) / 2d) - .5d); + chunkData.put(offset+i, (byte) chunk.getBlockLight(x, y, z)); + } + + // Sky light + offset = offset+blocklightSize; + if ((idx[3] % 2) > 0) { + int i = (int) ((((idx[3]++) + 1) / 2d) - 1d); + byte b = chunkData.get(offset+i); + b = (byte)((b << 4) | (byte)chunk.getSkyLight(x, y, z)); + chunkData.put(offset+i, b); + } else { + int i = (int) ((((idx[3]++) + 1) / 2d) - .5d); + chunkData.put(offset+i, (byte) chunk.getSkyLight(x, y, z)); + } + + // Addition + offset = offset+skylightSize; + if ((idx[4] % 2) > 0) { + int i = (int) ((((idx[4]++) + 1) / 2d) - 1d); + byte b = chunkData.get(offset+i); + b = (byte)((b << 4) | (byte)chunk.getAddition(x, y, z)); + chunkData.put(offset+i, b); + } else { + int i = (int) ((((idx[4]++) + 1) / 2d) - .5d); + chunkData.put(offset+i, (byte) chunk.getAddition(x, y, z)); + } + + // Biome + if (idx[5] == 256) continue; + offset = offset+additionSize; + chunkData.put(offset+(idx[5]++), (byte) chunk.getBiome(x, z)); + } + } + } Deflater zlib = new Deflater(Deflater.DEFAULT_COMPRESSION); zlib.setInput(chunkData.array()); From 47b4d662e5c6e64be7d7c0cc9d11a623e2a0028f Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 30 Apr 2018 00:25:38 +0300 Subject: [PATCH 3/3] fix: serialize metadata --- .../java/mc/core/network/proto_125/packets/ChunkDataPacket.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java b/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java index 1ab5cd0..8e026fd 100644 --- a/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java +++ b/proto125/src/main/java/mc/core/network/proto_125/packets/ChunkDataPacket.java @@ -56,7 +56,7 @@ public class ChunkDataPacket implements SCPacket { if ((idx[1] % 2) > 0) { int i = (int) ((((idx[1]++) + 1) / 2d) - 1d); byte b = chunkData.get(offset+i); - b = (byte)((b << 4) | (byte)chunk.getBlockMetadata(x, y, z)); + b = (byte)((chunk.getBlockMetadata(x, y, z) << 4) | b); chunkData.put(offset+i, b); } else { int i = (int) ((((idx[1]++) + 1) / 2d) - .5d);