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')