Archived
0

Merge branch 'dev/world' into develop

This commit is contained in:
2021-05-09 18:48:54 +03:00
13 changed files with 182 additions and 15 deletions

View File

@@ -9,4 +9,16 @@ public class Location {
private double x; private double x;
private double y; private double y;
private double z; private double z;
public int getIntX() {
return (int) x;
}
public int getIntZ() {
return (int) z;
}
public Location toChunkXZ() {
return new Location(this.getIntX() >> 4, 0d, this.getIntZ() >> 4);
}
} }

View File

@@ -28,13 +28,17 @@ import mc.protocol.packets.ServerSidePacket;
@Data @Data
public class ChunkDataPacket implements ServerSidePacket { public class ChunkDataPacket implements ServerSidePacket {
private static NetByteBuf voidData;
private int x; private int x;
private int z; private int z;
@SuppressWarnings("java:S125")
@Override @Override
public void writeSelf(NetByteBuf netByteBuf) { public void writeSelf(NetByteBuf netByteBuf) {
netByteBuf.writeInt(x); netByteBuf.writeInt(x);
netByteBuf.writeInt(z); netByteBuf.writeInt(z);
/* Временное отключение кода
netByteBuf.writeBoolean(true); // Is Full chunk netByteBuf.writeBoolean(true); // Is Full chunk
netByteBuf.writeVarInt(0b11111111); // Available Sections netByteBuf.writeVarInt(0b11111111); // Available Sections
@@ -64,6 +68,41 @@ public class ChunkDataPacket implements ServerSidePacket {
netByteBuf.writeVarInt(data.readableBytes()); // Size of Data netByteBuf.writeVarInt(data.readableBytes()); // Size of Data
netByteBuf.writeBytes(data); // Data netByteBuf.writeBytes(data); // Data
netByteBuf.writeVarInt(0); // Number of block entities netByteBuf.writeVarInt(0); // Number of block entities
/* write NBT's */ // write NBT's
*/
netByteBuf.writeBytes(voidData);
voidData.resetReaderIndex();
voidData.resetWriterIndex();
}
static {
voidData = new NetByteBuf(Unpooled.buffer());
voidData.writeBoolean(true); // Is Full chunk
voidData.writeVarInt(0b11111111); // Available Sections
NetByteBuf data = new NetByteBuf(Unpooled.buffer());
for (int i = 0; i < 16; i++) {
NetByteBuf dataBuff = new NetByteBuf(Unpooled.wrappedBuffer(new byte[4096]));
NetByteBuf blockLight = new NetByteBuf(Unpooled.wrappedBuffer(new byte[2048]));
NetByteBuf skyLight = new NetByteBuf(Unpooled.wrappedBuffer(new byte[2048]));
NetByteBuf biomes = new NetByteBuf(Unpooled.wrappedBuffer(new byte[256]));
data.writeUnsignedByte(13);
data.writeUnsignedByte(0);
data.writeVarInt(dataBuff.readableBytes());
data.writeBytes(dataBuff);
data.writeBytes(blockLight);
data.writeBytes(skyLight);
data.writeBytes(biomes);
}
voidData.writeVarInt(data.readableBytes());
voidData.writeBytes(data);
voidData.writeVarInt(0);
voidData.markReaderIndex();
voidData.markWriterIndex();
} }
} }

View File

@@ -0,0 +1,7 @@
package mc.protocol.world;
public interface Chunk {
int getX();
int getZ();
}

View File

@@ -0,0 +1,13 @@
package mc.protocol.world;
import mc.protocol.model.Location;
import mc.protocol.utils.LevelType;
public interface World {
LevelType getLevelType();
Location getSpawn();
Chunk getChunk(int x, int z);
}

View File

@@ -15,7 +15,8 @@ import mc.protocol.packets.server.*;
import mc.protocol.serializer.TextSerializer; import mc.protocol.serializer.TextSerializer;
import mc.protocol.utils.Difficulty; import mc.protocol.utils.Difficulty;
import mc.protocol.utils.GameMode; import mc.protocol.utils.GameMode;
import mc.protocol.utils.LevelType; import mc.protocol.world.Chunk;
import mc.protocol.world.World;
import mc.server.config.Config; import mc.server.config.Config;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@@ -34,6 +35,7 @@ public class PacketHandler {
private final Random random = new Random(System.currentTimeMillis()); private final Random random = new Random(System.currentTimeMillis());
private final Config config; private final Config config;
private final World world;
public void onHandshake(ConnectionContext context, HandshakePacket packet) { public void onHandshake(ConnectionContext context, HandshakePacket packet) {
context.setState(packet.getNextState()); context.setState(packet.getNextState());
@@ -75,6 +77,7 @@ public class PacketHandler {
context.sendNow(response); context.sendNow(response);
} }
@SuppressWarnings("java:S2589")
public void onLoginStart(ConnectionContext context, LoginStartPacket loginStartPacket) { public void onLoginStart(ConnectionContext context, LoginStartPacket loginStartPacket) {
var loginSuccessPacket = new LoginSuccessPacket(); var loginSuccessPacket = new LoginSuccessPacket();
loginSuccessPacket.setUuid(UUID.randomUUID()); loginSuccessPacket.setUuid(UUID.randomUUID());
@@ -88,14 +91,12 @@ public class PacketHandler {
joinGamePacket.setGameMode(GameMode.SURVIVAL); joinGamePacket.setGameMode(GameMode.SURVIVAL);
joinGamePacket.setDimension(0/*Overworld*/); joinGamePacket.setDimension(0/*Overworld*/);
joinGamePacket.setDifficulty(Difficulty.PEACEFUL); joinGamePacket.setDifficulty(Difficulty.PEACEFUL);
joinGamePacket.setLevelType(LevelType.FLAT); joinGamePacket.setLevelType(world.getLevelType());
context.send(joinGamePacket); context.send(joinGamePacket);
Location spawnLocation = new Location(7d, 130d, 7d);
var spawnPositionPacket = new SpawnPositionPacket(); var spawnPositionPacket = new SpawnPositionPacket();
spawnPositionPacket.setSpawn(spawnLocation); spawnPositionPacket.setSpawn(world.getSpawn());
context.send(spawnPositionPacket); context.send(spawnPositionPacket);
@@ -111,14 +112,38 @@ public class PacketHandler {
context.flushSending(); context.flushSending();
var chunkDataPacket = new ChunkDataPacket(); Location chunkLocation = world.getSpawn().toChunkXZ();
chunkDataPacket.setX(0); Chunk chunk = world.getChunk(chunkLocation.getIntX(), chunkLocation.getIntZ());
chunkDataPacket.setZ(0);
context.sendNow(chunkDataPacket); var chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.setX(chunk.getX());
chunkDataPacket.setZ(chunk.getZ());
context.send(chunkDataPacket);
for (int i = 1; i <= config.world().viewDistance(); i++) {
int minX = chunkLocation.getIntX() - i;
int minZ = chunkLocation.getIntZ() - i;
int maxX = chunkLocation.getIntX() + i;
int maxZ = chunkLocation.getIntZ() + i;
for (int z = minZ; z <= maxZ; z++) {
for (int x = minX; x <= maxX; x++) {
if ((z == minZ || z == maxZ) || (x == minX || x == maxX)) {
chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.setX(x);
chunkDataPacket.setZ(z);
context.send(chunkDataPacket);
}
}
}
}
context.flushSending();
var playerPositionAndLookPacket = new SPlayerPositionAndLookPacket(); var playerPositionAndLookPacket = new SPlayerPositionAndLookPacket();
playerPositionAndLookPacket.setPosition(spawnLocation); playerPositionAndLookPacket.setPosition(world.getSpawn());
playerPositionAndLookPacket.setLook(new Look(0f, 0f)); playerPositionAndLookPacket.setLook(new Look(0f, 0f));
playerPositionAndLookPacket.setTeleportId(random.nextInt()); playerPositionAndLookPacket.setTeleportId(random.nextInt());

View File

@@ -15,6 +15,7 @@ public class Config {
private final Server server = new Server(); private final Server server = new Server();
private final Players players = new Players(); private final Players players = new Players();
private final World world = new World();
private String motd; private String motd;
private String disconnectReason; private String disconnectReason;
@@ -35,4 +36,11 @@ public class Config {
private int maxOnlile; private int maxOnlile;
private int onlile; private int onlile;
} }
@Getter
@Setter
@ToString
public static class World {
private int viewDistance;
}
} }

View File

@@ -31,6 +31,7 @@ public class ConfigModule {
config.disconnectReason(fromYamlPath("disconnect-reason", map, "")); config.disconnectReason(fromYamlPath("disconnect-reason", map, ""));
config.players().maxOnlile(fromYamlPath("players/max-online", map, 0)); config.players().maxOnlile(fromYamlPath("players/max-online", map, 0));
config.players().onlile(fromYamlPath("players/online", map, 0)); config.players().onlile(fromYamlPath("players/online", map, 0));
config.world().viewDistance(fromYamlPath("world/view-distance", map, 0));
if (Boolean.TRUE.equals(fromYamlPath("icon/enable", map, false))) { if (Boolean.TRUE.equals(fromYamlPath("icon/enable", map, false))) {
config.iconPath(Paths.get(fromYamlPath("icon/path", map, "favicon.png"))); config.iconPath(Paths.get(fromYamlPath("icon/path", map, "favicon.png")));

View File

@@ -2,6 +2,7 @@ package mc.server.di;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import mc.protocol.world.World;
import mc.server.PacketHandler; import mc.server.PacketHandler;
import mc.server.config.Config; import mc.server.config.Config;
@@ -9,7 +10,7 @@ import mc.server.config.Config;
public class PacketHandlerModule { public class PacketHandlerModule {
@Provides @Provides
public PacketHandler providePacketHandler(Config config) { public PacketHandler providePacketHandler(Config config, World world) {
return new PacketHandler(config); return new PacketHandler(config, world);
} }
} }

View File

@@ -1,12 +1,14 @@
package mc.server.di; package mc.server.di;
import dagger.Component; import dagger.Component;
import mc.protocol.di.ServerScope;
import mc.server.PacketHandler; import mc.server.PacketHandler;
import mc.server.config.Config; import mc.server.config.Config;
@Component(modules = { @Component(modules = {
ConfigModule.class, PacketHandlerModule.class ConfigModule.class, PacketHandlerModule.class, WorldModule.class
}) })
@ServerScope
public interface ServerComponent { public interface ServerComponent {
Config getConfig(); Config getConfig();

View File

@@ -0,0 +1,17 @@
package mc.server.di;
import dagger.Module;
import dagger.Provides;
import mc.protocol.di.ServerScope;
import mc.protocol.world.World;
import mc.server.world.VoidWorld;
@Module
public class WorldModule {
@Provides
@ServerScope
public World provideWorld() {
return new VoidWorld();
}
}

View File

@@ -0,0 +1,13 @@
package mc.server.world;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import mc.protocol.world.Chunk;
@RequiredArgsConstructor
@Getter
public class VoidChunk implements Chunk {
private final int x;
private final int z;
}

View File

@@ -0,0 +1,26 @@
package mc.server.world;
import mc.protocol.model.Location;
import mc.protocol.utils.LevelType;
import mc.protocol.world.Chunk;
import mc.protocol.world.World;
public class VoidWorld implements World {
private static final Location spawn = new Location(7d, 130d, 7d);
@Override
public LevelType getLevelType() {
return LevelType.FLAT;
}
@Override
public Location getSpawn() {
return VoidWorld.spawn;
}
@Override
public Chunk getChunk(int x, int z) {
return new VoidChunk(x, z);
}
}

View File

@@ -16,3 +16,6 @@ players:
icon: icon:
enable: false enable: false
path: favicon.png path: favicon.png
world:
view-distance: 1