Added spawn position and dimension in condifgration. Added color codes conversion. PlayerInfo packet

This commit is contained in:
Nanit 2020-11-27 00:08:42 +02:00
parent e029336cf0
commit 8da830503a
8 changed files with 206 additions and 73 deletions

View File

@ -1,6 +1,8 @@
package ru.nanit.limbo; package ru.nanit.limbo;
import ru.nanit.limbo.protocol.packets.play.PacketBossBar; import ru.nanit.limbo.protocol.packets.play.PacketBossBar;
import ru.nanit.limbo.util.Colors;
import ru.nanit.limbo.util.Logger;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -12,6 +14,8 @@ public final class LimboConfig {
private static String host; private static String host;
private static int port; private static int port;
private static int maxPlayers; private static int maxPlayers;
private static String dimensionType;
private static SpawnPosition spawnPosition;
private static IpForwardingType ipForwardingType; private static IpForwardingType ipForwardingType;
private static long readTimeout; private static long readTimeout;
private static PingData pingData; private static PingData pingData;
@ -30,23 +34,36 @@ public final class LimboConfig {
port = Integer.parseInt(props.getProperty("port")); port = Integer.parseInt(props.getProperty("port"));
maxPlayers = Integer.parseInt(props.getProperty("max-players")); maxPlayers = Integer.parseInt(props.getProperty("max-players"));
dimensionType = props.getProperty("dimension");
String[] posData = props.getProperty("spawn-position").split(",");
if (posData.length != 3){
throw new IOException("Invalid spawn position. Check it in the settings.properties file");
}
spawnPosition = new SpawnPosition(Double.parseDouble(posData[0]),
Double.parseDouble(posData[1]),
Double.parseDouble(posData[2]));
ipForwardingType = IpForwardingType.valueOf(props.getProperty("ip-forwarding").toUpperCase()); ipForwardingType = IpForwardingType.valueOf(props.getProperty("ip-forwarding").toUpperCase());
readTimeout = Long.parseLong(props.getProperty("read-timeout")); readTimeout = Long.parseLong(props.getProperty("read-timeout"));
pingData = new PingData(); pingData = new PingData();
pingData.setVersion(props.getProperty("ping-version")); pingData.setVersion(props.getProperty("ping-version"));
pingData.setDescription(props.getProperty("ping-description")); pingData.setDescription(Colors.of(props.getProperty("ping-description")));
debugLevel = Integer.parseInt(props.getProperty("debug-level")); debugLevel = Integer.parseInt(props.getProperty("debug-level"));
joinMessages = new JoinMessages(); joinMessages = new JoinMessages();
if(props.containsKey("join-message")){ if(props.containsKey("join-message")){
joinMessages.setChatMessage(props.getProperty("join-message")); joinMessages.setChatMessage(Colors.of(props.getProperty("join-message")));
} }
if(props.containsKey("join-bossbar-text")){ if(props.containsKey("join-bossbar-text")){
joinMessages.setBossBarText(props.getProperty("join-bossbar-text")); joinMessages.setBossBarText(Colors.of(props.getProperty("join-bossbar-text")));
joinMessages.setBossBarHealth(Float.parseFloat(props.getProperty("join-bossbar-health"))); joinMessages.setBossBarHealth(Float.parseFloat(props.getProperty("join-bossbar-health")));
joinMessages.setBossBarColor(PacketBossBar.Color.valueOf( joinMessages.setBossBarColor(PacketBossBar.Color.valueOf(
props.getProperty("join-bossbar-color").toUpperCase())); props.getProperty("join-bossbar-color").toUpperCase()));
@ -67,6 +84,14 @@ public final class LimboConfig {
return maxPlayers; return maxPlayers;
} }
public static String getDimensionType() {
return dimensionType;
}
public static SpawnPosition getSpawnPosition() {
return spawnPosition;
}
public static IpForwardingType getIpForwardingType() { public static IpForwardingType getIpForwardingType() {
return ipForwardingType; return ipForwardingType;
} }
@ -93,6 +118,31 @@ public final class LimboConfig {
MODERN MODERN
} }
public static class SpawnPosition {
private final double x;
private final double y;
private final double z;
public SpawnPosition(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
}
public static class PingData { public static class PingData {
private String version; private String version;

View File

@ -38,6 +38,10 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
return uuid; return uuid;
} }
public String getUsername() {
return username;
}
public ClientConnection(Channel channel, LimboServer server){ public ClientConnection(Channel channel, LimboServer server){
this.server = server; this.server = server;
this.channel = channel; this.channel = channel;
@ -125,19 +129,26 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
joinGame.setWorldNames("minecraft:world"); joinGame.setWorldNames("minecraft:world");
joinGame.setHashedSeed(0); joinGame.setHashedSeed(0);
joinGame.setDimensionCodec(DimensionRegistry.getCodec()); joinGame.setDimensionCodec(DimensionRegistry.getCodec());
joinGame.setDimension(DimensionRegistry.getDimension()); joinGame.setDimension(DimensionRegistry.getDefaultDimension());
PacketPlayerPositionAndLook positionAndLook = new PacketPlayerPositionAndLook(); PacketPlayerPositionAndLook positionAndLook = new PacketPlayerPositionAndLook();
positionAndLook.setX(0.0); positionAndLook.setX(LimboConfig.getSpawnPosition().getX());
positionAndLook.setY(0.0); positionAndLook.setY(LimboConfig.getSpawnPosition().getY());
positionAndLook.setZ(0.0); positionAndLook.setZ(LimboConfig.getSpawnPosition().getZ());
positionAndLook.setYaw(90.0F); positionAndLook.setYaw(90.0F);
positionAndLook.setPitch(0.0F); positionAndLook.setPitch(0.0F);
positionAndLook.setTeleportId(ThreadLocalRandom.current().nextInt()); positionAndLook.setTeleportId(ThreadLocalRandom.current().nextInt());
PacketPlayerInfo info = new PacketPlayerInfo();
info.setConnection(this);
info.setGameMode(2);
sendPacket(joinGame); sendPacket(joinGame);
sendPacket(positionAndLook); sendPacket(positionAndLook);
sendPacket(info);
sendKeepAlive(); sendKeepAlive();
if (server.getJoinMessage() != null){ if (server.getJoinMessage() != null){

View File

@ -0,0 +1,35 @@
package ru.nanit.limbo.protocol.packets.play;
import ru.nanit.limbo.connection.ClientConnection;
import ru.nanit.limbo.protocol.ByteMessage;
import ru.nanit.limbo.protocol.PacketOut;
/**
* This packet wrapper used only for ADD_PLAYER action
*/
public class PacketPlayerInfo implements PacketOut {
private int gameMode;
private ClientConnection connection;
public void setConnection(ClientConnection connection) {
this.connection = connection;
}
public void setGameMode(int gameMode) {
this.gameMode = gameMode;
}
@Override
public void encode(ByteMessage msg) {
msg.writeVarInt(0);
msg.writeVarInt(1);
msg.writeUuid(connection.getUuid());
msg.writeString(connection.getUsername());
msg.writeVarInt(0);
msg.writeVarInt(gameMode);
msg.writeVarInt(60);
msg.writeBoolean(false);
}
}

View File

@ -42,6 +42,7 @@ public enum State {
clientBound.register(0x1F, PacketKeepAlive::new); clientBound.register(0x1F, PacketKeepAlive::new);
clientBound.register(0x0E, PacketChatMessage::new); clientBound.register(0x0E, PacketChatMessage::new);
clientBound.register(0x0C, PacketBossBar::new); clientBound.register(0x0C, PacketBossBar::new);
clientBound.register(0x32, PacketPlayerInfo::new);
} }
}; };
@ -86,54 +87,4 @@ public enum State {
} }
/*
Temporary don't needed
public static class PacketVersionRegistry {
private final Map<Version, PacketIdRegistry<?>> MAPPINGS = new HashMap<>();
public PacketIdRegistry<?> getRegistry(Version version){
PacketIdRegistry<?> registry = MAPPINGS.get(version);
return registry != null ? registry : MAPPINGS.get(version.getClosest(MAPPINGS.keySet()));
}
public <T extends Packet> void register(Version version, int packetId, Supplier<T> supplier){
PacketIdRegistry<T> registry = (PacketIdRegistry<T>) MAPPINGS.computeIfAbsent(version, PacketIdRegistry::new);
registry.register(packetId, supplier);
}
public static class PacketIdRegistry<T extends Packet> {
private final Version version;
private final Map<Integer, Supplier<T>> packetsById = new HashMap<>();
private final Map<Class<?>, Integer> packetIdByClass = new HashMap<>();
public PacketIdRegistry(Version version){
this.version = version;
}
public Version getVersion(){
return version;
}
public Packet getPacket(int packetId){
Supplier<T> supplier = packetsById.get(packetId);
return supplier == null ? null : supplier.get();
}
public int getPacketId(Class<?> packetClass){
return packetIdByClass.getOrDefault(packetClass, -1);
}
public void register(int packetId, Supplier<T> supplier){
packetsById.put(packetId, supplier);
packetIdByClass.put(supplier.get().getClass(), packetId);
}
}
}*/
} }

View File

@ -51,7 +51,7 @@ public final class LimboServer {
Logger.info("Starting server..."); Logger.info("Starting server...");
LimboConfig.load(Paths.get("./settings.properties")); LimboConfig.load(Paths.get("./settings.properties"));
DimensionRegistry.init(); DimensionRegistry.init(LimboConfig.getDimensionType());
initializeInGameData(); initializeInGameData();

View File

@ -0,0 +1,14 @@
package ru.nanit.limbo.util;
public final class Colors {
private static final char CHAR_FROM = '\u0026';
private static final char CHAR_TO = '\u00A7';
private Colors(){}
public static String of(String text){
return text.replace(CHAR_FROM, CHAR_TO);
}
}

View File

@ -2,14 +2,51 @@ package ru.nanit.limbo.world;
import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.ListBinaryTag; import net.kyori.adventure.nbt.ListBinaryTag;
import ru.nanit.limbo.util.Logger;
public final class DimensionRegistry { public final class DimensionRegistry {
private static CompoundBinaryTag CODEC; private static CompoundBinaryTag codec;
private static CompoundBinaryTag DIMENSION; private static CompoundBinaryTag defaultDimension;
public static void init(){ public static void init(String defaultDimensionName){
DIMENSION = CompoundBinaryTag.builder() CompoundBinaryTag overworld = CompoundBinaryTag.builder()
.putString("name", "minecraft:overworld")
.putByte("piglin_safe", (byte) 0)
.putByte("natural", (byte) 0)
.putFloat("ambient_light", 0.0F)
.putString("infiniburn", "minecraft:infiniburn_overworld")
.putByte("respawn_anchor_works", (byte) 0)
.putByte("has_skylight", (byte) 0)
.putByte("bed_works", (byte) 0)
.putString("effects", "minecraft:overworld")
.putLong("fixed_time", 6000L)
.putByte("has_raids", (byte) 1)
.putInt("logical_height", 256)
.putDouble("coordinate_scale", 1.0)
.putByte("ultrawarm", (byte) 0)
.putByte("has_ceiling", (byte) 0)
.build();
CompoundBinaryTag nether = CompoundBinaryTag.builder()
.putString("name", "minecraft:the_nether")
.putByte("piglin_safe", (byte) 0)
.putByte("natural", (byte) 0)
.putFloat("ambient_light", 0.0F)
.putString("infiniburn", "minecraft:infiniburn_nether")
.putByte("respawn_anchor_works", (byte) 0)
.putByte("has_skylight", (byte) 0)
.putByte("bed_works", (byte) 0)
.putString("effects", "minecraft:the_nether")
.putLong("fixed_time", 18000L)
.putByte("has_raids", (byte) 1)
.putInt("logical_height", 128)
.putDouble("coordinate_scale", 1.0)
.putByte("ultrawarm", (byte) 0)
.putByte("has_ceiling", (byte) 0)
.build();
CompoundBinaryTag theEnd = CompoundBinaryTag.builder()
.putString("name", "minecraft:the_end") .putString("name", "minecraft:the_end")
.putByte("piglin_safe", (byte) 0) .putByte("piglin_safe", (byte) 0)
.putByte("natural", (byte) 0) .putByte("natural", (byte) 0)
@ -27,10 +64,22 @@ public final class DimensionRegistry {
.putByte("has_ceiling", (byte) 0) .putByte("has_ceiling", (byte) 0)
.build(); .build();
CompoundBinaryTag dimensionData = CompoundBinaryTag.builder() CompoundBinaryTag overworldData = CompoundBinaryTag.builder()
.putString("name", "minecraft:overworld")
.putInt("id", 2)
.put("element", overworld)
.build();
CompoundBinaryTag netherData = CompoundBinaryTag.builder()
.putString("name", "minecraft:the_nether")
.putInt("id", 2)
.put("element", nether)
.build();
CompoundBinaryTag endData = CompoundBinaryTag.builder()
.putString("name", "minecraft:the_end") .putString("name", "minecraft:the_end")
.putInt("id", 2) .putInt("id", 2)
.put("element", DIMENSION) .put("element", theEnd)
.build(); .build();
CompoundBinaryTag plains = CompoundBinaryTag.builder() CompoundBinaryTag plains = CompoundBinaryTag.builder()
@ -58,11 +107,13 @@ public final class DimensionRegistry {
.build()) .build())
.build(); .build();
CODEC = CompoundBinaryTag.builder() codec = CompoundBinaryTag.builder()
.put("minecraft:dimension_type", CompoundBinaryTag.builder() .put("minecraft:dimension_type", CompoundBinaryTag.builder()
.putString("type", "minecraft:dimension_type") .putString("type", "minecraft:dimension_type")
.put("value", ListBinaryTag.builder() .put("value", ListBinaryTag.builder()
.add(dimensionData) .add(overworldData)
.add(netherData)
.add(endData)
.build()) .build())
.build()) .build())
.put("minecraft:worldgen/biome", CompoundBinaryTag.builder() .put("minecraft:worldgen/biome", CompoundBinaryTag.builder()
@ -72,14 +123,29 @@ public final class DimensionRegistry {
.build()) .build())
.build()) .build())
.build(); .build();
switch (defaultDimensionName.toLowerCase()){
case "overworld":
defaultDimension = overworld;
break;
case "nether":
defaultDimension = nether;
break;
case "the_end":
defaultDimension = theEnd;
break;
default:
defaultDimension = theEnd;
Logger.error("Undefined dimension type: '%s'. Using THE_END as default", defaultDimensionName);
break;
}
} }
public static CompoundBinaryTag getCodec(){ public static CompoundBinaryTag getCodec(){
return CODEC; return codec;
} }
public static CompoundBinaryTag getDimension(){ public static CompoundBinaryTag getDefaultDimension() {
return DIMENSION; return defaultDimension;
} }
} }

View File

@ -11,11 +11,17 @@ port=65535
# Max amount of players can join to server # Max amount of players can join to server
max-players=100 max-players=100
# Available dimensions: OVERWORLD, NETHER, THE_END
dimension=THE_END
# Spawn position in the world in format x,y,z
spawn-position=0.0,65.0,0.0
# Version string when client version is not compatible with server one # Version string when client version is not compatible with server one
ping-version=NanoLimbo ping-version=NanoLimbo
# Server's description component # Server's description component
ping-description={"text": "NanoLimbo"} ping-description={"text": "&9NanoLimbo"}
# Player info forwarding support. Available types: NONE, LEGACY, MODERN # Player info forwarding support. Available types: NONE, LEGACY, MODERN
# MODERN - Velocity native forwarding type. # MODERN - Velocity native forwarding type.
@ -40,7 +46,7 @@ debug-level=3
# ======= In-game Data ======= # # ======= In-game Data ======= #
# Message when player join to server. Comment this parameter to disable # Message when player join to server. Comment this parameter to disable
join-message={"text": "Welcome to the Limbo!"} join-message={"text": "&eWelcome to the Limbo!"}
# Bossbar text. Comment this parameter to disable bossbar # Bossbar text. Comment this parameter to disable bossbar
join-bossbar-text={"text": "Welcome to the Limbo!"} join-bossbar-text={"text": "Welcome to the Limbo!"}
@ -56,7 +62,7 @@ join-bossbar-health=1.0
# - YELLOW # - YELLOW
# - PURPLE # - PURPLE
# - WHITE # - WHITE
join-bossbar-color=RED join-bossbar-color=PINK
# Available bossbar divisions: # Available bossbar divisions:
# - SOLID # - SOLID