diff --git a/protocol/src/main/java/mc/protocol/State.java b/protocol/src/main/java/mc/protocol/State.java index 6159b43..386bd87 100644 --- a/protocol/src/main/java/mc/protocol/State.java +++ b/protocol/src/main/java/mc/protocol/State.java @@ -54,6 +54,7 @@ public enum State { ), // client bound Map.of( + BossBarPacket.class, 0x0C, PingPacket.class, 0x1F, JoinGamePacket.class, 0x23, SpawnPositionPacket.class, 0x46, diff --git a/protocol/src/main/java/mc/protocol/packets/server/BossBarPacket.java b/protocol/src/main/java/mc/protocol/packets/server/BossBarPacket.java new file mode 100644 index 0000000..07ec41e --- /dev/null +++ b/protocol/src/main/java/mc/protocol/packets/server/BossBarPacket.java @@ -0,0 +1,117 @@ +package mc.protocol.packets.server; + +import lombok.Data; +import mc.protocol.io.NetByteBuf; +import mc.protocol.model.text.Text; +import mc.protocol.packets.ServerSidePacket; +import mc.protocol.serializer.TextSerializer; +import mc.protocol.utils.BossBarAction; +import mc.protocol.utils.BossBarColor; +import mc.protocol.utils.BossBarDivision; + +import java.util.UUID; + +/** + * Boss bar packet. + * + *
Управление босс-баром.
+ * + *Структура пакета
+ *+ * | FIELD | TYPE | NOTES | + * |-------------|--------|----------------------------------| + * | UUID | String | Уникальный ID для бара | + * | Action | VarInt | Код действия | + * | Data fields | - | Зависит от значния поля "Action" | + *+ * + *
Варианты "Action" и поля в "Data action"
+ *+ * | ACTION | DATA FIELD | TYPE | NOTES | + * | VALUE | DESCRIPTION | | | | + * |-------|------------- |------------|---------------|--------------------------------------------------------| + * | 0 | add | Title | Text | Название бара | + * | | | Health | Float | Число от 0 до 1. Определяет процент заполненности бара | + * | | | Color | VarInt | Цвет бара. См. ниже значения | + * | | | Division | VarInt | Тип делений. См. ниже значения | + * | | | Flags | Unsigned Byte | Битовая маска: | + * | | | | | 0x01 - затемняет небо | + * | | | | | 0x02 - является босс-баром Ender Dragon | + * | | | | | (используется для воспроизведения музыки) | + * | 1 | remove | - | - | Не имеет дополнительных полей. Удаляет текущий бар. | + * | 2 | update health | Health | Float | (см. выше) | + * | 3 | update title | Title | Text | (см. выше) | + * | 4 | update style | Color | VarInt | (см. выше) | + * | | | Division | VarInt | (см. выше) | + * | 5 | update flags | Flags | Unsigned Byte | (см. выше) | + *+ * + *
Варианты цветов бара
+ *+ * | CODE | COLOR | + * |------|--------| + * | 0 | Pink | + * | 1 | Blue | + * | 2 | Red | + * | 3 | Green | + * | 4 | Yellow | + * | 5 | Purple | + * | 6 | White | + *+ * + *
Типы делений бара
+ *+ * | CODE | DIVISION | + * |------|-------------| + * | 0 | Нет делений | + * | 1 | 6 делений | + * | 2 | 10 делений | + * | 3 | 12 делений | + * | 4 | 20 делений | + *+ * + * @see Boss bar + */ +@Data +public class BossBarPacket implements ServerSidePacket { + + private UUID uuid; + private BossBarAction action; + + private Text title; + private Float health; + private BossBarColor color; + private BossBarDivision division; + + @Override + public void writeSelf(NetByteBuf netByteBuf) { + netByteBuf.writeUUID(this.uuid); + netByteBuf.writeVarInt(this.action.getCode()); + + switch (this.action) { + case ADD: + netByteBuf.writeString(TextSerializer.toJsonObject(this.title).toString()); + netByteBuf.writeFloat(this.health); + netByteBuf.writeVarInt(this.color.getCode()); + netByteBuf.writeVarInt(this.division.getCode()); + netByteBuf.writeUnsignedByte(0x00); // Flags + break; + case UPDATE_HEALTH: + netByteBuf.writeFloat(this.health); + break; + case UPDATE_TITLE: + netByteBuf.writeString(TextSerializer.toJsonObject(this.title).toString()); + break; + case UPDATE_STYLE: + netByteBuf.writeVarInt(this.color.getCode()); + netByteBuf.writeVarInt(this.division.getCode()); + break; + case UPDATE_FLAGS: + netByteBuf.writeUnsignedByte(0x00); // Flags + break; + case REMOVE: + default: + break; + } + } +} diff --git a/protocol/src/main/java/mc/protocol/utils/BossBarAction.java b/protocol/src/main/java/mc/protocol/utils/BossBarAction.java new file mode 100644 index 0000000..aeb4ee7 --- /dev/null +++ b/protocol/src/main/java/mc/protocol/utils/BossBarAction.java @@ -0,0 +1,17 @@ +package mc.protocol.utils; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum BossBarAction { + ADD(0), + REMOVE(1), + UPDATE_HEALTH(2), + UPDATE_TITLE(3), + UPDATE_STYLE(4), + UPDATE_FLAGS(5); + + @Getter + private final int code; +} diff --git a/protocol/src/main/java/mc/protocol/utils/BossBarColor.java b/protocol/src/main/java/mc/protocol/utils/BossBarColor.java new file mode 100644 index 0000000..7be0065 --- /dev/null +++ b/protocol/src/main/java/mc/protocol/utils/BossBarColor.java @@ -0,0 +1,18 @@ +package mc.protocol.utils; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum BossBarColor { + PINK(0), + BLUE(1), + RED(2), + GREEN(3), + YELLOW(4), + PURPLE(5), + WHITE(6); + + @Getter + private final int code; +} diff --git a/protocol/src/main/java/mc/protocol/utils/BossBarDivision.java b/protocol/src/main/java/mc/protocol/utils/BossBarDivision.java new file mode 100644 index 0000000..ff02cb3 --- /dev/null +++ b/protocol/src/main/java/mc/protocol/utils/BossBarDivision.java @@ -0,0 +1,17 @@ +package mc.protocol.utils; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@SuppressWarnings("java:S115") +public enum BossBarDivision { + NONE(0), + _6(1), + _10(2), + _12(3), + _20(4); + + @Getter + private final int code; +} diff --git a/server/src/main/java/mc/server/PacketHandler.java b/server/src/main/java/mc/server/PacketHandler.java index bf35af9..3f34719 100644 --- a/server/src/main/java/mc/server/PacketHandler.java +++ b/server/src/main/java/mc/server/PacketHandler.java @@ -7,15 +7,14 @@ import mc.protocol.api.ConnectionContext; import mc.protocol.model.Location; import mc.protocol.model.Look; import mc.protocol.model.ServerInfo; +import mc.protocol.model.text.Text; import mc.protocol.packets.PingPacket; import mc.protocol.packets.client.HandshakePacket; import mc.protocol.packets.client.LoginStartPacket; import mc.protocol.packets.client.StatusServerRequestPacket; import mc.protocol.packets.server.*; import mc.protocol.serializer.TextSerializer; -import mc.protocol.utils.Difficulty; -import mc.protocol.utils.GameMode; -import mc.protocol.utils.LevelType; +import mc.protocol.utils.*; import mc.server.config.Config; import org.apache.commons.io.IOUtils; @@ -122,6 +121,18 @@ public class PacketHandler { context.send(pingPacket); context.flushSending(); + + // -- Эксперименты -- // + + BossBarPacket boss1 = new BossBarPacket(); + boss1.setUuid(UUID.randomUUID()); + boss1.setAction(BossBarAction.ADD); + boss1.setTitle(Text.of("BOSS-1")); + boss1.setHealth(1.0f); + boss1.setColor(BossBarColor.RED); + boss1.setDivision(BossBarDivision.NONE); + + context.sendNow(boss1); } private static String faviconToBase64(Path iconPath) {