diff --git a/core/src/main/java/mc/core/network/BroadcastNetChannel.java b/core/src/main/java/mc/core/network/BroadcastNetChannel.java index ba22156..3f5e7bb 100644 --- a/core/src/main/java/mc/core/network/BroadcastNetChannel.java +++ b/core/src/main/java/mc/core/network/BroadcastNetChannel.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; import mc.core.chat.MessageType; import mc.core.player.Player; import mc.core.text.Text; +import mc.core.text.Title; import java.util.stream.Stream; @@ -30,6 +31,11 @@ public class BroadcastNetChannel implements NetChannel { playerStream.forEach(player -> player.getChannel().sendChatMessage(text, type)); } + @Override + public void sendTitle(final Title title) { + playerStream.forEach(player -> player.getChannel().sendTitle(title)); + } + @Override public void writeAndFlush(final SCPacket pkt) { playerStream.forEach(player -> player.getChannel().writeAndFlush(pkt)); diff --git a/core/src/main/java/mc/core/network/NetChannel.java b/core/src/main/java/mc/core/network/NetChannel.java index 7ea1654..69c05c7 100644 --- a/core/src/main/java/mc/core/network/NetChannel.java +++ b/core/src/main/java/mc/core/network/NetChannel.java @@ -6,6 +6,7 @@ package mc.core.network; import mc.core.chat.MessageType; import mc.core.text.Text; +import mc.core.text.Title; public interface NetChannel { void sendKeepAlive(); @@ -14,6 +15,7 @@ public interface NetChannel { sendChatMessage(text, MessageType.CHAT_MESSAGE); } void sendChatMessage(Text text, MessageType type); + void sendTitle(Title title); void writeAndFlush(SCPacket pkt); void write(SCPacket pkt); diff --git a/core/src/main/java/mc/core/text/Title.java b/core/src/main/java/mc/core/text/Title.java new file mode 100644 index 0000000..7715b4c --- /dev/null +++ b/core/src/main/java/mc/core/text/Title.java @@ -0,0 +1,34 @@ +/* + * DmitriyMX + * 2018-06-24 + */ +package mc.core.text; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class Title { + private Text title = null; + private Text subtitle = null; + private Text textActionBar = null; + private Integer fadeInTime = null; + private Integer stayTime = null; + private Integer fadeOutTime = null; + private Boolean hide = null; + private Boolean reset = null; + + public void clear() { + this.title = null; + this.subtitle = null; + this.textActionBar = null; + this.fadeInTime = null; + this.stayTime = null; + this.fadeOutTime = null; + this.hide = null; + this.reset = null; + } +} diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java index 815b081..3d51506 100644 --- a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/State.java @@ -62,6 +62,7 @@ public enum State { .put(JoinGamePacket.class, 0x23) .put(SpawnPositionPacket.class, 0x46) .put(TimeUpdatePacket.class, 0x47) + .put(TitlePacket.class, 0x48) .put(PlayerAbilitiesPacket.class, 0x2C) .put(PlayerPositionAndLookPacket.class, 0x2F) .build() diff --git a/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/TitlePacket.java b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/TitlePacket.java new file mode 100644 index 0000000..3cd4256 --- /dev/null +++ b/proto_1.12.2/src/main/java/mc/core/network/proto_1_12_2/packets/TitlePacket.java @@ -0,0 +1,109 @@ +/* + * DmitriyMX + * 2018-06-24 + */ +package mc.core.network.proto_1_12_2.packets; + +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import mc.core.network.NetStream; +import mc.core.network.SCPacket; +import mc.core.network.proto_1_12_2.serializers.TextSerializer; +import mc.core.text.Text; + +@RequiredArgsConstructor +@Setter +@ToString +public class TitlePacket implements SCPacket { + private static final int TICKS_PER_SEC = 20, + MIN_MS = (1000 / TICKS_PER_SEC); + public static final int SET_TITLE = 0, + SET_SUBTITLE = 1, + SET_ACTION_BAR = 2, + SET_DISPLAY_TIME = 3, + HIDE = 4, + RESET = 5; + + private final int action; + private Text text = null; + private Integer fadeInTime = null; + private Integer stayTime = null; + private Integer fadeOutTime = null; + + public TitlePacket(int action, Object... values) { + if (values.length == 0 && (action != HIDE && action != RESET)) { + this.action = HIDE; + return; + } + + this.action = action; + + switch (this.action) { + case SET_TITLE: + case SET_SUBTITLE: + case SET_ACTION_BAR: + if (values[0] == null) { + this.text = Text.of(); + } else if (values[0] instanceof Text) { + this.text = (Text) values[0]; + } else { + this.text = Text.of(values[0].toString()); + } + break; + case SET_DISPLAY_TIME: + if (values.length < 3) { + this.fadeInTime = 0; + this.stayTime = 0; + this.fadeOutTime = 0; + } else { + if (values[0] instanceof Integer) { + if (((Integer) values[0]) < MIN_MS) { + this.fadeInTime = 1; + } else { + this.fadeInTime = ((Integer) values[0]) / MIN_MS; + } + } else { + this.fadeInTime = 0; + } + + if (values[1] instanceof Integer) { + if (((Integer) values[1]) < MIN_MS) { + this.stayTime = 1; + } else { + this.stayTime = ((Integer) values[1]) / MIN_MS; + } + } else { + this.stayTime = 0; + } + + if (values[2] instanceof Integer) { + if (((Integer) values[2]) < MIN_MS) { + this.fadeOutTime = 1; + } else { + this.fadeOutTime = ((Integer) values[2]) / MIN_MS; + } + } else { + this.fadeOutTime = 0; + } + } + } + } + + @Override + public void writeSelf(NetStream netStream) { + netStream.writeVarInt(this.action); + + switch (this.action) { + case SET_TITLE: + case SET_SUBTITLE: + case SET_ACTION_BAR: + netStream.writeString(TextSerializer.serialize(this.text).toString()); + break; + case SET_DISPLAY_TIME: + netStream.writeInt(this.fadeInTime); + netStream.writeInt(this.stayTime); + netStream.writeInt(this.fadeOutTime); + } + } +} diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java index de8f0c5..50427e8 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java @@ -12,7 +12,9 @@ import mc.core.network.SCPacket; import mc.core.network.proto_1_12_2.packets.ChatMessageServerPacket; import mc.core.network.proto_1_12_2.packets.KeepAlivePacket; import mc.core.network.proto_1_12_2.packets.TimeUpdatePacket; +import mc.core.network.proto_1_12_2.packets.TitlePacket; import mc.core.text.Text; +import mc.core.text.Title; import java.util.Random; @@ -36,6 +38,33 @@ public class WrapperNetChannel implements NetChannel { writeAndFlush(new ChatMessageServerPacket(text, type)); } + @Override + public void sendTitle(Title title) { + Text text = title.getTitle(); + if (text != null) write(new TitlePacket(TitlePacket.SET_TITLE, text)); + + text = title.getSubtitle(); + if (text != null) write(new TitlePacket(TitlePacket.SET_SUBTITLE, text)); + + text = title.getTextActionBar(); + if (text != null) write(new TitlePacket(TitlePacket.SET_ACTION_BAR, text)); + + Integer fadeIn = title.getFadeInTime(); + Integer stay = title.getStayTime(); + Integer fadeOut = title.getFadeOutTime(); + if (fadeIn != null && stay != null && fadeOut != null) { + write(new TitlePacket(TitlePacket.SET_DISPLAY_TIME, fadeIn, stay, fadeOut)); + } + + Boolean bool = title.getHide(); + if (bool != null && bool) write(new TitlePacket(TitlePacket.HIDE)); + + bool = title.getReset(); + if (bool != null && bool) write(new TitlePacket(TitlePacket.RESET)); + + flush(); + } + @Override public void writeAndFlush(SCPacket pkt) { channel.writeAndFlush(pkt);