From bbeb41dd7eaf8e3754122e0378556119cc04aec6 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 2 May 2021 17:14:54 +0300 Subject: [PATCH] ClientSettingsPacket --- .../src/main/java/mc/protocol/ChatMode.java | 20 ++++ .../src/main/java/mc/protocol/MainHand.java | 18 ++++ protocol/src/main/java/mc/protocol/State.java | 3 +- .../packets/client/ClientSettingsPacket.java | 94 +++++++++++++++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 protocol/src/main/java/mc/protocol/ChatMode.java create mode 100644 protocol/src/main/java/mc/protocol/MainHand.java create mode 100644 protocol/src/main/java/mc/protocol/packets/client/ClientSettingsPacket.java diff --git a/protocol/src/main/java/mc/protocol/ChatMode.java b/protocol/src/main/java/mc/protocol/ChatMode.java new file mode 100644 index 0000000..33c7bcc --- /dev/null +++ b/protocol/src/main/java/mc/protocol/ChatMode.java @@ -0,0 +1,20 @@ +package mc.protocol; + +import javax.annotation.Nullable; + +public enum ChatMode { + FULL, + COMMANDS_ONLY, + HIDDEN; + + @Nullable + public static ChatMode valueById(int id) { + // а зачем усложнять? + //@formatter:off + if (id == 1) return FULL; + else if (id == 2) return COMMANDS_ONLY; + else if (id == 3) return HIDDEN; + else return null; + //@formatter:on + } +} diff --git a/protocol/src/main/java/mc/protocol/MainHand.java b/protocol/src/main/java/mc/protocol/MainHand.java new file mode 100644 index 0000000..15ea441 --- /dev/null +++ b/protocol/src/main/java/mc/protocol/MainHand.java @@ -0,0 +1,18 @@ +package mc.protocol; + +import javax.annotation.Nullable; + +public enum MainHand { + LEFT, + RIGHT; + + @Nullable + public static MainHand valueById(int id) { + // а зачем усложнять? + //@formatter:off + if (id == 0) return LEFT; + else if (id == 1) return RIGHT; + else return null; + //@formatter:on + } +} diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java index a4227dd..3f7db7b 100644 --- a/protocol/src/main/java/mc/protocol/State.java +++ b/protocol/src/main/java/mc/protocol/State.java @@ -6,6 +6,7 @@ import mc.protocol.packets.ClientSidePacket; import mc.protocol.packets.Packet; import mc.protocol.packets.PingPacket; import mc.protocol.packets.ServerSidePacket; +import mc.protocol.packets.client.ClientSettingsPacket; import mc.protocol.packets.client.HandshakePacket; import mc.protocol.packets.client.LoginStartPacket; import mc.protocol.packets.client.StatusServerRequestPacket; @@ -48,7 +49,7 @@ public enum State { ), PLAY(3, // server bound - Map.of(), + Map.of(0x04, ClientSettingsPacket.class), // client bound Map.of(JoinGamePacket.class, 0x23) ); diff --git a/protocol/src/main/java/mc/protocol/packets/client/ClientSettingsPacket.java b/protocol/src/main/java/mc/protocol/packets/client/ClientSettingsPacket.java new file mode 100644 index 0000000..680db2c --- /dev/null +++ b/protocol/src/main/java/mc/protocol/packets/client/ClientSettingsPacket.java @@ -0,0 +1,94 @@ +package mc.protocol.packets.client; + +import lombok.*; +import mc.protocol.ChatMode; +import mc.protocol.MainHand; +import mc.protocol.io.NetByteBuf; +import mc.protocol.packets.ClientSidePacket; + +/** + * Client settings packet. + * + *

Структура пакета

+ *
+ * | FIELD                | TYPE          | NOTES                                             |
+ * |--------------------  |---------------|---------------------------------------------------|
+ * | Locale               | String (16)   | например en_gb                                    |
+ * | View Distance        | Byte          | Дистанция отрисовки со стороны Клиента, в чанках. |
+ * | Chat Mode            | VarInt        | 0: enabled                                        |
+ * |                      |               | 1: commands only                                  |
+ * |                      |               | 2: hidden                                         |
+ * |                      |               | [1]                                               |
+ * | Chat Colors          | Boolean       | “Colors” multiplayer setting (???)                |
+ * | Displayed Skin Parts | Unsigned Byte | битовая маска отображения скина. См. ниже         |
+ * | Main Hand            | VarInt        | 0: Left                                           |
+ * |                      |               | 1: Right                                          |
+ *
+ * [1] - Processing chat
+ * 
+ * + *

Биты "Displayed Skin Parts"

+ *
+ * Bit 0 (0x01): Плащ (Cape)
+ * Bit 1 (0x02): Рубашка (Jacket)
+ * Bit 2 (0x04): Левый рукав (Left Sleeve)
+ * Bit 3 (0x08): Правый рукав (Right Sleeve)
+ * Bit 4 (0x10): Левая штанина (Left Pants Leg)
+ * Bit 5 (0x20): Правая штанина (Right Pants Leg)
+ * Bit 6 (0x40): Шлем (Hat)
+ * 
+ * + * @see Client Settings + */ +@NoArgsConstructor +@Getter +@EqualsAndHashCode +@ToString +public class ClientSettingsPacket implements ClientSidePacket { + + private String locale; + private int viewDistance; + private ChatMode chatMode; + private boolean chatColors; + @SuppressWarnings("java:S116") + private int $displayedSkinPartsBitMask; + private MainHand mainHand; + + @Override + public void readSelf(NetByteBuf netByteBuf) { + this.locale = netByteBuf.readString(16); + this.viewDistance = netByteBuf.readByte(); + this.chatMode = ChatMode.valueById(netByteBuf.readVarInt()); + this.chatColors = netByteBuf.readBoolean(); + this.$displayedSkinPartsBitMask = netByteBuf.readUnsignedByte(); + this.mainHand = MainHand.valueById(netByteBuf.readVarInt()); + } + + public boolean isCapeEnabled() { + return ($displayedSkinPartsBitMask & 0x01) > 0; + } + + public boolean isJacketEnabled() { + return ($displayedSkinPartsBitMask & 0x02) > 0; + } + + public boolean isLeftSleeveEnabled() { + return ($displayedSkinPartsBitMask & 0x04) > 0; + } + + public boolean isRightSleeveEnabled() { + return ($displayedSkinPartsBitMask & 0x08) > 0; + } + + public boolean isLeftPantsEnabled() { + return ($displayedSkinPartsBitMask & 0x10) > 0; + } + + public boolean isRightPantsEnabled() { + return ($displayedSkinPartsBitMask & 0x20) > 0; + } + + public boolean isHatEnabled() { + return ($displayedSkinPartsBitMask & 0x40) > 0; + } +}