diff --git a/core/src/main/java/mc/core/world/Chunk.java b/core/src/main/java/mc/core/world/Chunk.java index cbc3957..15ee0fa 100644 --- a/core/src/main/java/mc/core/world/Chunk.java +++ b/core/src/main/java/mc/core/world/Chunk.java @@ -4,7 +4,7 @@ */ package mc.core.world; -/* 16x256x16 */ +/* 16x16x16 */ public interface Chunk { int getBlockType(int x, int y, int z); void setBlockType(int x, int y, int z, int type); @@ -21,6 +21,6 @@ public interface Chunk { int getAddition(int x, int y, int z); void setAddition(int x, int y, int z, int value); - int getBiome(int x, int y, int z); - 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/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..5186615 --- /dev/null +++ b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java @@ -0,0 +1,73 @@ +/* + * DmitriyMX + * 2018-04-28 + */ +package mc.world.flat; + +import mc.core.world.Chunk; + +public class SimpleChunk implements Chunk { + @Override + public int getBlockType(int x, int y, int z) { + if (y == 0) return 7; + else if (y >= 1 && y <= 2) return 3; + else if (y == 3) return 2; + else return 0; + } + + @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 void setBlockMetadata(int x, int y, int z, int metadata) { + + } + + @Override + public int getBlockLight(int x, int y, int z) { + return 0; + } + + @Override + public void setBlockLight(int x, int y, int z, int lightLevel) { + + } + + @Override + public int getSkyLight(int x, int y, int z) { + if (y <= 3) return 0; + else return 15; + } + + @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 void setAddition(int x, int y, int z, int value) { + + } + + @Override + public int getBiome(int x, int z) { + return 0; + } + + @Override + 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 ae8b9ad..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 @@ -8,55 +8,109 @@ 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 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; 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); + /* + * 0 - blocktype + * 1 - metadata + * 2 - blocklight + * 3 - skylight + * 4 - addition + * 5 - biome + */ + int[] idx = new int[6]; - byte[] blocklight = new byte[2048]; - Arrays.fill(blocklight, (byte)0); + 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)); - byte[] skylight = new byte[2048]; - Arrays.fill(skylight, 0, 512, (byte) 0); - Arrays.fill(skylight, 512, 2048, (byte)-1); + // 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)((chunk.getBlockMetadata(x, y, z) << 4) | b); + chunkData.put(offset+i, b); + } else { + int i = (int) ((((idx[1]++) + 1) / 2d) - .5d); + chunkData.put(offset+i, (byte) chunk.getBlockMetadata(x, y, z)); + } - byte[] addition = new byte[2048]; - Arrays.fill(addition, 0, 256, (byte)1); - Arrays.fill(addition, 256, 2048, (byte)0); + // 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)); + } - byte[] biometype = new byte[256]; - Arrays.fill(biometype, (byte)0); + // 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)); + } - 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); + // 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); + 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 97fbcbd..3c95794 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 @@ -13,16 +13,15 @@ import io.netty.util.AttributeKey; import lombok.extern.slf4j.Slf4j; import mc.core.*; import mc.core.network.CSPacket; -import mc.core.network.NetChannel; import mc.core.network.proto_125.netty.wrappers.WrapperNetChannel; import mc.core.network.proto_125.packets.*; import org.slf4j.Marker; import org.slf4j.helpers.BasicMarkerFactory; +import mc.core.world.World; import org.springframework.beans.factory.annotation.Autowired; import java.lang.reflect.Method; import java.util.Arrays; -import java.util.List; import java.util.Optional; @Slf4j @@ -33,6 +32,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 { @@ -71,7 +72,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()); @@ -85,7 +85,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)); } @@ -100,7 +100,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 @@ -122,6 +122,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); @@ -147,16 +148,6 @@ public class PacketHandler extends SimpleChannelInboundHandler { channel.attr(ATTR_PLAYER).set(player); player.setChannel(new WrapperNetChannel(channel)); playerManager.joinServer(player); - - // send Player info - List players = playerManager.getPlayers(); - players.forEach(pl -> { - PlayerInfoPacket infoPkt = new PlayerInfoPacket(); - infoPkt.setPlayerName(pl.getName()); - infoPkt.setOnline(true); - infoPkt.setPing(4); - playerManager.getBroadcastChannel().writeAndFlush(infoPkt); - }); } public void onKickPacket(Channel channel, KickPacket packet) { 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')