From 7663f7d15f5900b909860c206c54554b95567648 Mon Sep 17 00:00:00 2001 From: Riley Park Date: Fri, 6 Nov 2020 20:17:33 -0800 Subject: [PATCH] title packet --- .../client/ClientPlaySessionHandler.java | 2 +- .../connection/client/ConnectedPlayer.java | 36 ++--- .../proxy/protocol/StateRegistry.java | 5 +- .../proxy/protocol/packet/TitlePacket.java | 151 +++++++++++------- 4 files changed, 110 insertions(+), 84 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java index d87060cd1..307a81870 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java @@ -368,7 +368,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler { // Clear any title from the previous server. if (player.getProtocolVersion().gte(MINECRAFT_1_8)) { player.getConnection() - .delayedWrite(TitlePacket.resetForProtocolVersion(player.getProtocolVersion())); + .delayedWrite(TitlePacket.reset(player.getProtocolVersion())); } // Flush everything diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index e16e6ea16..49e1a7669 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -50,7 +50,6 @@ import com.velocitypowered.proxy.protocol.util.PluginMessageUtil; import com.velocitypowered.proxy.server.VelocityRegisteredServer; import com.velocitypowered.proxy.tablist.VelocityTabList; import com.velocitypowered.proxy.tablist.VelocityTabListLegacy; -import com.velocitypowered.proxy.util.DurationUtils; import com.velocitypowered.proxy.util.collect.CappedSet; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; @@ -247,11 +246,10 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { ProtocolVersion playerVersion = getProtocolVersion(); if (playerVersion.gte(ProtocolVersion.MINECRAFT_1_11)) { // Use the title packet instead. - TitlePacket pkt = new TitlePacket(); - pkt.setAction(TitlePacket.SET_ACTION_BAR); - pkt.setComponent(ProtocolUtils.getJsonChatSerializer(playerVersion) - .serialize(message)); - connection.write(pkt); + connection.write(new TitlePacket( + TitlePacket.SET_ACTION_BAR, + ProtocolUtils.getJsonChatSerializer(playerVersion).serialize(message) + )); } else { // Due to issues with action bar packets, we'll need to convert the text message into a // legacy message and then inject the legacy text into a component... yuck! @@ -270,36 +268,32 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(this .getProtocolVersion()); - TitlePacket titlePkt = new TitlePacket(); - titlePkt.setAction(TitlePacket.SET_TITLE); - titlePkt.setComponent(serializer.serialize(title.title())); - connection.delayedWrite(titlePkt); + connection.delayedWrite(new TitlePacket( + TitlePacket.SET_TITLE, + serializer.serialize(title.title()) + )); - TitlePacket subtitlePkt = new TitlePacket(); - subtitlePkt.setAction(TitlePacket.SET_SUBTITLE); - subtitlePkt.setComponent(serializer.serialize(title.subtitle())); - connection.delayedWrite(subtitlePkt); + connection.delayedWrite(new TitlePacket( + TitlePacket.SET_SUBTITLE, + serializer.serialize(title.subtitle()) + )); - TitlePacket timesPkt = TitlePacket.timesForProtocolVersion(this.getProtocolVersion()); net.kyori.adventure.title.Title.Times times = title.times(); if (times != null) { - timesPkt.setFadeIn((int) DurationUtils.toTicks(times.fadeIn())); - timesPkt.setStay((int) DurationUtils.toTicks(times.stay())); - timesPkt.setFadeOut((int) DurationUtils.toTicks(times.fadeOut())); + connection.delayedWrite(TitlePacket.times(this.getProtocolVersion(), times)); } - connection.delayedWrite(timesPkt); connection.flush(); } @Override public void clearTitle() { - connection.write(TitlePacket.hideForProtocolVersion(this.getProtocolVersion())); + connection.write(TitlePacket.hide(this.getProtocolVersion())); } @Override public void resetTitle() { - connection.write(TitlePacket.resetForProtocolVersion(this.getProtocolVersion())); + connection.write(TitlePacket.reset(this.getProtocolVersion())); } @Override diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java index 7312aa17d..7cb2f947f 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java @@ -210,7 +210,7 @@ public enum StateRegistry { map(0x53, MINECRAFT_1_14, true), map(0x54, MINECRAFT_1_15, true), map(0x53, MINECRAFT_1_16, true)); - clientbound.register(TitlePacket.class, TitlePacket::new, + clientbound.registerNew(TitlePacket.class, TitlePacket.DECODER, map(0x45, MINECRAFT_1_8, true), map(0x45, MINECRAFT_1_9, true), map(0x47, MINECRAFT_1_12, true), @@ -416,7 +416,8 @@ public enum StateRegistry { return supplier.get(); } - public @Nullable Packet decodePacket(final int id, ByteBuf buf, ProtocolDirection direction, ProtocolVersion protocolVersion) { + public @Nullable Packet decodePacket(final int id, ByteBuf buf, ProtocolDirection direction, + ProtocolVersion protocolVersion) { final Packet.Decoder decoder = this.packetIdToDecoder.get(id); if (decoder == null) { return null; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java index 5e9e14d13..70b7dd9f0 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java @@ -1,34 +1,95 @@ package com.velocitypowered.proxy.protocol.packet; +import com.google.common.primitives.Ints; import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.Packet; import com.velocitypowered.proxy.protocol.ProtocolDirection; import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.util.DurationUtils; import io.netty.buffer.ByteBuf; +import java.util.Arrays; +import net.kyori.adventure.title.Title; import org.checkerframework.checker.nullness.qual.Nullable; public class TitlePacket implements Packet { + public static final Decoder DECODER = (buf, direction, version) -> { + throw new UnsupportedOperationException(); + }; + + public static TitlePacket hide(final ProtocolVersion version) { + return version.gte(ProtocolVersion.MINECRAFT_1_11) + ? Instances.HIDE + : Instances.HIDE_OLD; + } + + public static TitlePacket reset(final ProtocolVersion version) { + return version.gte(ProtocolVersion.MINECRAFT_1_11) + ? Instances.RESET + : Instances.RESET_OLD; + } + + public static TitlePacket times(final ProtocolVersion version, final Title.Times times) { + final int action = version.gte(ProtocolVersion.MINECRAFT_1_11) + ? SET_TIMES + : SET_TIMES_OLD; + return new TitlePacket( + action, + (int) DurationUtils.toTicks(times.fadeIn()), + (int) DurationUtils.toTicks(times.stay()), + (int) DurationUtils.toTicks(times.fadeOut()) + ); + } + public static final int SET_TITLE = 0; public static final int SET_SUBTITLE = 1; public static final int SET_ACTION_BAR = 2; public static final int SET_TIMES = 3; - public static final int SET_TIMES_OLD = 2; public static final int HIDE = 4; - public static final int HIDE_OLD = 3; public static final int RESET = 5; + + public static final int SET_TIMES_OLD = 2; + public static final int HIDE_OLD = 3; public static final int RESET_OLD = 4; - private int action; - private @Nullable String component; - private int fadeIn; - private int stay; - private int fadeOut; + private final int action; + private final @Nullable String component; + private final int fadeIn; + private final int stay; + private final int fadeOut; - @Override - public void decode(ByteBuf buf, ProtocolDirection direction, ProtocolVersion version) { - throw new UnsupportedOperationException(); // encode only + private TitlePacket(final int action) { + checkAction(action, HIDE, RESET, HIDE_OLD, RESET_OLD); + this.action = action; + this.component = null; + this.fadeIn = -1; + this.stay = -1; + this.fadeOut = -1; + } + + public TitlePacket(final int action, final String component) { + checkAction(action, SET_TITLE, SET_SUBTITLE, SET_ACTION_BAR); + this.action = action; + this.component = component; + this.fadeIn = -1; + this.stay = -1; + this.fadeOut = -1; + } + + public TitlePacket(final int action, final int fadeIn, final int stay, final int fadeOut) { + checkAction(action, SET_TIMES, SET_TIMES_OLD); + this.action = action; + this.component = null; + this.fadeIn = fadeIn; + this.stay = stay; + this.fadeOut = fadeOut; + } + + private static void checkAction(final int action, final int... validActions) { + if (!Ints.contains(validActions, action)) { + throw new IllegalArgumentException("Invalid action " + action + ", expected one of: " + Arrays.toString(validActions)); + } } @Override @@ -79,80 +140,50 @@ public class TitlePacket implements Packet { } } - public int getAction() { - return action; + @Override + public boolean handle(MinecraftSessionHandler handler) { + return handler.handle(this); } - public void setAction(int action) { - this.action = action; + public int getAction() { + return action; } public @Nullable String getComponent() { return component; } - public void setComponent(@Nullable String component) { - this.component = component; - } - public int getFadeIn() { return fadeIn; } - public void setFadeIn(int fadeIn) { - this.fadeIn = fadeIn; - } - public int getStay() { return stay; } - public void setStay(int stay) { - this.stay = stay; - } - public int getFadeOut() { return fadeOut; } - public void setFadeOut(int fadeOut) { - this.fadeOut = fadeOut; - } - - public static TitlePacket hideForProtocolVersion(ProtocolVersion version) { - TitlePacket packet = new TitlePacket(); - packet.setAction(version.gte(ProtocolVersion.MINECRAFT_1_11) ? TitlePacket.HIDE - : TitlePacket.HIDE_OLD); - return packet; - } - - public static TitlePacket resetForProtocolVersion(ProtocolVersion version) { - TitlePacket packet = new TitlePacket(); - packet.setAction(version.gte(ProtocolVersion.MINECRAFT_1_11) ? TitlePacket.RESET - : TitlePacket.RESET_OLD); - return packet; - } - - public static TitlePacket timesForProtocolVersion(ProtocolVersion version) { - TitlePacket packet = new TitlePacket(); - packet.setAction(version.gte(ProtocolVersion.MINECRAFT_1_11) ? TitlePacket.SET_TIMES - : TitlePacket.SET_TIMES_OLD); - return packet; - } - @Override public String toString() { return "TitlePacket{" - + "action=" + action - + ", component='" + component + '\'' - + ", fadeIn=" + fadeIn - + ", stay=" + stay - + ", fadeOut=" + fadeOut - + '}'; + + "action=" + action + + ", component='" + component + '\'' + + ", fadeIn=" + fadeIn + + ", stay=" + stay + + ", fadeOut=" + fadeOut + + '}'; } - @Override - public boolean handle(MinecraftSessionHandler handler) { - return handler.handle(this); + public static final class Instances { + public static final TitlePacket HIDE = new TitlePacket(TitlePacket.HIDE); + public static final TitlePacket RESET = new TitlePacket(TitlePacket.RESET); + + public static final TitlePacket HIDE_OLD = new TitlePacket(TitlePacket.HIDE_OLD); + public static final TitlePacket RESET_OLD = new TitlePacket(TitlePacket.RESET_OLD); + + private Instances() { + } } }