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;
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.nio.file.Files;
@ -12,6 +14,8 @@ public final class LimboConfig {
private static String host;
private static int port;
private static int maxPlayers;
private static String dimensionType;
private static SpawnPosition spawnPosition;
private static IpForwardingType ipForwardingType;
private static long readTimeout;
private static PingData pingData;
@ -30,23 +34,36 @@ public final class LimboConfig {
port = Integer.parseInt(props.getProperty("port"));
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());
readTimeout = Long.parseLong(props.getProperty("read-timeout"));
pingData = new PingData();
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"));
joinMessages = new JoinMessages();
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")){
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.setBossBarColor(PacketBossBar.Color.valueOf(
props.getProperty("join-bossbar-color").toUpperCase()));
@ -67,6 +84,14 @@ public final class LimboConfig {
return maxPlayers;
}
public static String getDimensionType() {
return dimensionType;
}
public static SpawnPosition getSpawnPosition() {
return spawnPosition;
}
public static IpForwardingType getIpForwardingType() {
return ipForwardingType;
}
@ -93,6 +118,31 @@ public final class LimboConfig {
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 {
private String version;

View File

@ -38,6 +38,10 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
return uuid;
}
public String getUsername() {
return username;
}
public ClientConnection(Channel channel, LimboServer server){
this.server = server;
this.channel = channel;
@ -125,19 +129,26 @@ public class ClientConnection extends ChannelInboundHandlerAdapter {
joinGame.setWorldNames("minecraft:world");
joinGame.setHashedSeed(0);
joinGame.setDimensionCodec(DimensionRegistry.getCodec());
joinGame.setDimension(DimensionRegistry.getDimension());
joinGame.setDimension(DimensionRegistry.getDefaultDimension());
PacketPlayerPositionAndLook positionAndLook = new PacketPlayerPositionAndLook();
positionAndLook.setX(0.0);
positionAndLook.setY(0.0);
positionAndLook.setZ(0.0);
positionAndLook.setX(LimboConfig.getSpawnPosition().getX());
positionAndLook.setY(LimboConfig.getSpawnPosition().getY());
positionAndLook.setZ(LimboConfig.getSpawnPosition().getZ());
positionAndLook.setYaw(90.0F);
positionAndLook.setPitch(0.0F);
positionAndLook.setTeleportId(ThreadLocalRandom.current().nextInt());
PacketPlayerInfo info = new PacketPlayerInfo();
info.setConnection(this);
info.setGameMode(2);
sendPacket(joinGame);
sendPacket(positionAndLook);
sendPacket(info);
sendKeepAlive();
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(0x0E, PacketChatMessage::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...");
LimboConfig.load(Paths.get("./settings.properties"));
DimensionRegistry.init();
DimensionRegistry.init(LimboConfig.getDimensionType());
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.ListBinaryTag;
import ru.nanit.limbo.util.Logger;
public final class DimensionRegistry {
private static CompoundBinaryTag CODEC;
private static CompoundBinaryTag DIMENSION;
private static CompoundBinaryTag codec;
private static CompoundBinaryTag defaultDimension;
public static void init(){
DIMENSION = CompoundBinaryTag.builder()
public static void init(String defaultDimensionName){
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")
.putByte("piglin_safe", (byte) 0)
.putByte("natural", (byte) 0)
@ -27,10 +64,22 @@ public final class DimensionRegistry {
.putByte("has_ceiling", (byte) 0)
.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")
.putInt("id", 2)
.put("element", DIMENSION)
.put("element", theEnd)
.build();
CompoundBinaryTag plains = CompoundBinaryTag.builder()
@ -58,11 +107,13 @@ public final class DimensionRegistry {
.build())
.build();
CODEC = CompoundBinaryTag.builder()
codec = CompoundBinaryTag.builder()
.put("minecraft:dimension_type", CompoundBinaryTag.builder()
.putString("type", "minecraft:dimension_type")
.put("value", ListBinaryTag.builder()
.add(dimensionData)
.add(overworldData)
.add(netherData)
.add(endData)
.build())
.build())
.put("minecraft:worldgen/biome", CompoundBinaryTag.builder()
@ -72,14 +123,29 @@ public final class DimensionRegistry {
.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(){
return CODEC;
return codec;
}
public static CompoundBinaryTag getDimension(){
return DIMENSION;
public static CompoundBinaryTag getDefaultDimension() {
return defaultDimension;
}
}

View File

@ -11,11 +11,17 @@ port=65535
# Max amount of players can join to server
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
ping-version=NanoLimbo
# Server's description component
ping-description={"text": "NanoLimbo"}
ping-description={"text": "&9NanoLimbo"}
# Player info forwarding support. Available types: NONE, LEGACY, MODERN
# MODERN - Velocity native forwarding type.
@ -40,7 +46,7 @@ debug-level=3
# ======= In-game Data ======= #
# 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
join-bossbar-text={"text": "Welcome to the Limbo!"}
@ -56,7 +62,7 @@ join-bossbar-health=1.0
# - YELLOW
# - PURPLE
# - WHITE
join-bossbar-color=RED
join-bossbar-color=PINK
# Available bossbar divisions:
# - SOLID