From 6350181dfc5bec700504bf4e8808813bc93a08f2 Mon Sep 17 00:00:00 2001 From: Nanit Date: Thu, 26 Nov 2020 21:31:41 +0200 Subject: [PATCH] Added join message and bossbar --- src/main/java/ru/nanit/limbo/LimboConfig.java | 91 +++++++++++++++++-- .../limbo/connection/ClientConnection.java | 12 ++- .../protocol/packets/play/PacketBossBar.java | 85 +++++++++++++++++ .../packets/play/PacketChatMessage.java | 48 ++++++++++ .../nanit/limbo/protocol/registry/State.java | 12 +-- .../ru/nanit/limbo/server/LimboServer.java | 33 +++++++ src/main/resources/settings.properties | 31 ++++++- 7 files changed, 293 insertions(+), 19 deletions(-) create mode 100644 src/main/java/ru/nanit/limbo/protocol/packets/play/PacketBossBar.java create mode 100644 src/main/java/ru/nanit/limbo/protocol/packets/play/PacketChatMessage.java diff --git a/src/main/java/ru/nanit/limbo/LimboConfig.java b/src/main/java/ru/nanit/limbo/LimboConfig.java index af28414..89e787d 100644 --- a/src/main/java/ru/nanit/limbo/LimboConfig.java +++ b/src/main/java/ru/nanit/limbo/LimboConfig.java @@ -1,5 +1,7 @@ package ru.nanit.limbo; +import ru.nanit.limbo.protocol.packets.play.PacketBossBar; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -14,27 +16,43 @@ public final class LimboConfig { private static long readTimeout; private static PingData pingData; private static int debugLevel = 3; + private static JoinMessages joinMessages; public static void load(Path file) throws IOException { if (!Files.exists(file)){ Files.copy(NanoLimbo.getResource("/settings.properties"), file); } - Properties properties = new Properties(); - properties.load(Files.newInputStream(file)); + Properties props = new Properties(); + props.load(Files.newInputStream(file)); - host = properties.getProperty("host"); - port = Integer.parseInt(properties.getProperty("port")); + host = props.getProperty("host"); + port = Integer.parseInt(props.getProperty("port")); - maxPlayers = Integer.parseInt(properties.getProperty("max-players")); - ipForwardingType = IpForwardingType.valueOf(properties.getProperty("ip-forwarding").toUpperCase()); - readTimeout = Long.parseLong(properties.getProperty("read-timeout")); + maxPlayers = Integer.parseInt(props.getProperty("max-players")); + ipForwardingType = IpForwardingType.valueOf(props.getProperty("ip-forwarding").toUpperCase()); + readTimeout = Long.parseLong(props.getProperty("read-timeout")); pingData = new PingData(); - pingData.setVersion(properties.getProperty("ping-version")); - pingData.setDescription(properties.getProperty("ping-description")); + pingData.setVersion(props.getProperty("ping-version")); + pingData.setDescription(props.getProperty("ping-description")); - debugLevel = Integer.parseInt(properties.getProperty("debug-level")); + debugLevel = Integer.parseInt(props.getProperty("debug-level")); + + joinMessages = new JoinMessages(); + + if(props.containsKey("join-message")){ + joinMessages.setChatMessage(props.getProperty("join-message")); + } + + if(props.containsKey("join-bossbar-text")){ + joinMessages.setBossBarText(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())); + joinMessages.setBossBarDivision(PacketBossBar.Division.valueOf( + props.getProperty("join-bossbar-division").toUpperCase())); + } } public static String getHost() { @@ -65,6 +83,10 @@ public final class LimboConfig { return debugLevel; } + public static JoinMessages getJoinMessages() { + return joinMessages; + } + public enum IpForwardingType { NONE, LEGACY, @@ -93,4 +115,53 @@ public final class LimboConfig { } } + public static class JoinMessages { + + private String chatMessage; + private String bossBarText; + private float bossBarHealth; + private PacketBossBar.Color bossBarColor; + private PacketBossBar.Division bossBarDivision; + + public String getChatMessage() { + return chatMessage; + } + + public void setChatMessage(String chatMessage) { + this.chatMessage = chatMessage; + } + + public String getBossBarText() { + return bossBarText; + } + + public void setBossBarText(String bossBarText) { + this.bossBarText = bossBarText; + } + + public float getBossBarHealth() { + return bossBarHealth; + } + + public void setBossBarHealth(float bossBarHealth) { + this.bossBarHealth = bossBarHealth; + } + + public PacketBossBar.Color getBossBarColor() { + return bossBarColor; + } + + public void setBossBarColor(PacketBossBar.Color bossBarColor) { + this.bossBarColor = bossBarColor; + } + + public PacketBossBar.Division getBossBarDivision() { + return bossBarDivision; + } + + public void setBossBarDivision(PacketBossBar.Division bossBarDivision) { + this.bossBarDivision = bossBarDivision; + } + } + } diff --git a/src/main/java/ru/nanit/limbo/connection/ClientConnection.java b/src/main/java/ru/nanit/limbo/connection/ClientConnection.java index d6a35e8..26a9d96 100644 --- a/src/main/java/ru/nanit/limbo/connection/ClientConnection.java +++ b/src/main/java/ru/nanit/limbo/connection/ClientConnection.java @@ -98,11 +98,11 @@ public class ClientConnection extends ChannelInboundHandlerAdapter { server.addConnection(this); Logger.info("Player %s connected", this.username); - startJoinProcess(); + sendJoinPackets(); } } - private void startJoinProcess(){ + private void sendJoinPackets(){ PacketJoinGame joinGame = new PacketJoinGame(); joinGame.setEntityId(0); @@ -133,6 +133,14 @@ public class ClientConnection extends ChannelInboundHandlerAdapter { sendPacket(joinGame); sendPacket(positionAndLook); sendKeepAlive(); + + if (server.getJoinMessage() != null){ + sendPacket(server.getJoinMessage()); + } + + if (server.getJoinBossBar() != null){ + sendPacket(server.getJoinBossBar()); + } } public void disconnect(String reason){ diff --git a/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketBossBar.java b/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketBossBar.java new file mode 100644 index 0000000..20da94c --- /dev/null +++ b/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketBossBar.java @@ -0,0 +1,85 @@ +package ru.nanit.limbo.protocol.packets.play; + +import ru.nanit.limbo.protocol.ByteMessage; +import ru.nanit.limbo.protocol.PacketOut; +import ru.nanit.limbo.protocol.registry.Version; + +import java.util.UUID; + +public class PacketBossBar implements PacketOut { + + private UUID uuid; + private String title; + private float health; + private Color color; + private Division division; + private int flags; + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setHealth(float health) { + this.health = health; + } + + public void setColor(Color color) { + this.color = color; + } + + public void setDivision(Division division) { + this.division = division; + } + + public void setFlags(int flags) { + this.flags = flags; + } + + @Override + public void encode(ByteMessage msg, Version version) { + msg.writeUuid(uuid); + msg.writeVarInt(0); // Create bossbar + msg.writeString(title); + msg.writeFloat(health); + msg.writeVarInt(color.index); + msg.writeVarInt(division.index); + msg.writeByte(flags); + } + + public enum Color { + + PINK(0), + BLUE(1), + RED(2), + GREEN(3), + YELLOW(4), + PURPLE(5), + WHITE(6); + + private final int index; + + Color(int index) { + this.index = index; + } + } + + public enum Division { + + SOLID(0), + DASHES_6(1), + DASHES_10(2), + DASHES_12(3), + DASHES_20(4); + + private final int index; + + Division(int index) { + this.index = index; + } + } + +} diff --git a/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketChatMessage.java b/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketChatMessage.java new file mode 100644 index 0000000..ece37c8 --- /dev/null +++ b/src/main/java/ru/nanit/limbo/protocol/packets/play/PacketChatMessage.java @@ -0,0 +1,48 @@ +package ru.nanit.limbo.protocol.packets.play; + +import ru.nanit.limbo.protocol.ByteMessage; +import ru.nanit.limbo.protocol.PacketOut; +import ru.nanit.limbo.protocol.registry.Version; + +import java.util.UUID; + +public class PacketChatMessage implements PacketOut { + + private String jsonData; + private Position position; + private UUID sender; + + public void setJsonData(String jsonData) { + this.jsonData = jsonData; + } + + public void setPosition(Position position) { + this.position = position; + } + + public void setSender(UUID sender) { + this.sender = sender; + } + + @Override + public void encode(ByteMessage msg, Version version) { + msg.writeString(jsonData); + msg.writeByte(position.index); + msg.writeUuid(sender); + } + + public enum Position { + + CHAT(0), + SYSTEM_MESSAGE(1), + ACTION_BAR(2); + + private final int index; + + Position(int index){ + this.index = index; + } + + } + +} diff --git a/src/main/java/ru/nanit/limbo/protocol/registry/State.java b/src/main/java/ru/nanit/limbo/protocol/registry/State.java index 9d60273..6472fcb 100644 --- a/src/main/java/ru/nanit/limbo/protocol/registry/State.java +++ b/src/main/java/ru/nanit/limbo/protocol/registry/State.java @@ -17,31 +17,31 @@ public enum State { HANDSHAKING(0){ { serverBound.register(Version.getMinimal(), 0x00, PacketHandshake::new); - - int[] i = new int[16 * 16 * 16]; } }, STATUS(1){ { - clientBound.register(Version.getMinimal(), 0x00, PacketStatusResponse::new); - clientBound.register(Version.getMinimal(), 0x01, PacketStatusPing::new); serverBound.register(Version.getMinimal(), 0x01, PacketStatusPing::new); serverBound.register(Version.getMinimal(), 0x00, PacketStatusRequest::new); + clientBound.register(Version.getMinimal(), 0x00, PacketStatusResponse::new); + clientBound.register(Version.getMinimal(), 0x01, PacketStatusPing::new); } }, LOGIN(2){ { + serverBound.register(Version.getMinimal(), 0x00, PacketLoginStart::new); clientBound.register(Version.getMinimal(), 0x00, PacketDisconnect::new); clientBound.register(Version.getMinimal(), 0x02, PacketLoginSuccess::new); - serverBound.register(Version.getMinimal(), 0x00, PacketLoginStart::new); } }, PLAY(3){ { + serverBound.register(Version.V1_16_4, 0x10, PacketKeepAlive::new); clientBound.register(Version.V1_16_4, 0x24, PacketJoinGame::new); clientBound.register(Version.V1_16_4, 0x34, PacketPlayerPositionAndLook::new); clientBound.register(Version.V1_16_4, 0x1F, PacketKeepAlive::new); - serverBound.register(Version.V1_16_4, 0x10, PacketKeepAlive::new); + clientBound.register(Version.V1_16_4, 0x0E, PacketChatMessage::new); + clientBound.register(Version.V1_16_4, 0x0C, PacketBossBar::new); } }; diff --git a/src/main/java/ru/nanit/limbo/server/LimboServer.java b/src/main/java/ru/nanit/limbo/server/LimboServer.java index f122a39..31a90cb 100644 --- a/src/main/java/ru/nanit/limbo/server/LimboServer.java +++ b/src/main/java/ru/nanit/limbo/server/LimboServer.java @@ -6,6 +6,8 @@ import io.netty.channel.socket.nio.NioServerSocketChannel; import ru.nanit.limbo.LimboConfig; import ru.nanit.limbo.connection.ClientChannelInitializer; import ru.nanit.limbo.connection.ClientConnection; +import ru.nanit.limbo.protocol.packets.play.PacketBossBar; +import ru.nanit.limbo.protocol.packets.play.PacketChatMessage; import ru.nanit.limbo.util.Logger; import ru.nanit.limbo.world.DimensionRegistry; @@ -22,6 +24,9 @@ public final class LimboServer { private final Map connections = new ConcurrentHashMap<>(); private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + private PacketChatMessage joinMessage; + private PacketBossBar joinBossBar; + public int getConnectionsCount(){ return connections.size(); } @@ -34,12 +39,22 @@ public final class LimboServer { connections.remove(connection.getUuid()); } + public PacketChatMessage getJoinMessage() { + return joinMessage; + } + + public PacketBossBar getJoinBossBar() { + return joinBossBar; + } + public void start() throws Exception { Logger.info("Starting server..."); LimboConfig.load(Paths.get("./settings.properties")); DimensionRegistry.init(); + initializeInGameData(); + executor.scheduleAtFixedRate(this::broadcastKeepAlive, 0L, 5L, TimeUnit.SECONDS); ServerBootstrap bootstrap = new ServerBootstrap() @@ -52,6 +67,24 @@ public final class LimboServer { Logger.info("Server started on %s:%d", LimboConfig.getHost(), LimboConfig.getPort()); } + private void initializeInGameData(){ + if (LimboConfig.getJoinMessages().getChatMessage() != null){ + joinMessage = new PacketChatMessage(); + joinMessage.setJsonData(LimboConfig.getJoinMessages().getChatMessage()); + joinMessage.setPosition(PacketChatMessage.Position.CHAT); + joinMessage.setSender(UUID.randomUUID()); + } + + if (LimboConfig.getJoinMessages().getBossBarText() != null){ + joinBossBar = new PacketBossBar(); + joinBossBar.setTitle(LimboConfig.getJoinMessages().getBossBarText()); + joinBossBar.setHealth(LimboConfig.getJoinMessages().getBossBarHealth()); + joinBossBar.setColor(LimboConfig.getJoinMessages().getBossBarColor()); + joinBossBar.setDivision(LimboConfig.getJoinMessages().getBossBarDivision()); + joinBossBar.setUuid(UUID.randomUUID()); + } + } + private void broadcastKeepAlive(){ connections.values().forEach(ClientConnection::sendKeepAlive); } diff --git a/src/main/resources/settings.properties b/src/main/resources/settings.properties index ec94fcd..112007a 100644 --- a/src/main/resources/settings.properties +++ b/src/main/resources/settings.properties @@ -33,4 +33,33 @@ read-timeout=30000 # 1 - Display only useful info # 2 - Display info and warnings # 3 - Display info, warnings, errors -debug-level=3 \ No newline at end of file +debug-level=3 + +# ======= In-game Data ======= # + +# Message when player join to server. Comment this parameter to disable +join-message={"text": "Welcome to the Limbo!"} + +# Bossbar text. Comment this parameter to disable bossbar +join-bossbar-text={"text": "Welcome to the Limbo!"} + +# Bossbar percentage between 0.0 and 1.0 inclusive +join-bossbar-health=1.0 + +# Available bossbar colors: +# - PINK +# - BLUE +# - RED +# - GREEN +# - YELLOW +# - PURPLE +# - WHITE +join-bossbar-color=RED + +# Available bossbar divisions: +# - SOLID +# - DASHES_6 +# - DASHES_10 +# - DASHES_12 +# - DASHES_20 +join-bossbar-division=SOLID \ No newline at end of file