From 5da085d82f9cd7a91a4b8d44f6dc94dc3383b173 Mon Sep 17 00:00:00 2001 From: Riley Park Date: Sun, 6 Dec 2020 17:50:57 -0800 Subject: [PATCH 1/3] Adventure 4.3.0: Player list header/footer --- api/build.gradle | 11 +++--- .../com/velocitypowered/api/proxy/Player.java | 14 ++++++++ .../api/proxy/player/TabList.java | 2 ++ build.gradle | 2 +- proxy/build.gradle | 4 ++- .../connection/client/ConnectedPlayer.java | 36 +++++++++++++++++-- .../protocol/packet/HeaderAndFooter.java | 12 ++----- .../proxy/tablist/VelocityTabList.java | 33 ++++++++++------- .../proxy/tablist/VelocityTabListLegacy.java | 8 +++-- 9 files changed, 89 insertions(+), 33 deletions(-) diff --git a/api/build.gradle b/api/build.gradle index 8361c827e..b98bd6ea6 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -32,11 +32,12 @@ dependencies { // DEPRECATED: Will be removed in Velocity 2.0.0 api 'com.moandjiezana.toml:toml4j:0.7.2' - api "net.kyori:adventure-api:${adventureVersion}" - api "net.kyori:adventure-text-serializer-gson:${adventureVersion}" - api "net.kyori:adventure-text-serializer-legacy:${adventureVersion}" - api "net.kyori:adventure-text-serializer-plain:${adventureVersion}" - api "net.kyori:adventure-text-serializer-legacy-text3:${adventurePlatformVersion}" + api(platform("net.kyori:adventure-bom:${adventureVersion}")) + api("net.kyori:adventure-api") + api("net.kyori:adventure-text-serializer-gson") + api("net.kyori:adventure-text-serializer-legacy") + api("net.kyori:adventure-text-serializer-plain") + api("net.kyori:adventure-text-serializer-legacy-text3:${adventurePlatformVersion}") // adventure-platform api "org.slf4j:slf4j-api:${slf4jVersion}" api 'com.google.inject:guice:4.2.3' diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index 598cb07a6..e5654a67e 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -146,6 +146,20 @@ public interface Player extends CommandSource, Identified, InboundConnection, @Deprecated void clearHeaderAndFooter(); + /** + * Returns the player's player list header. + * + * @return this player's player list header + */ + Component getPlayerListHeader(); + + /** + * Returns the player's player list footer. + * + * @return this player's tab list + */ + Component getPlayerListFooter(); + /** * Returns the player's tab list. * diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java b/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java index 0b862147c..59d8930be 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/player/TabList.java @@ -28,7 +28,9 @@ public interface TabList { * * @param header the header component * @param footer the footer component + * @deprecated Use {@link Player#sendPlayerListHeaderAndFooter(Component, Component)} instead */ + @Deprecated void setHeaderAndFooter(Component header, Component footer); /** diff --git a/build.gradle b/build.gradle index ffa860d6c..5ed54ddff 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ allprojects { ext { // dependency versions textVersion = '3.0.4' - adventureVersion = '4.2.0' + adventureVersion = '4.3.0' adventurePlatformVersion = '4.0.0-SNAPSHOT' junitVersion = '5.7.0' slf4jVersion = '1.7.30' diff --git a/proxy/build.gradle b/proxy/build.gradle index ff2e1fe0a..a345d4a2e 100644 --- a/proxy/build.gradle +++ b/proxy/build.gradle @@ -66,7 +66,9 @@ dependencies { implementation 'it.unimi.dsi:fastutil:8.4.1' implementation 'net.kyori:event-method-asm:4.0.0-SNAPSHOT' - implementation 'net.kyori:adventure-nbt:4.0.0-SNAPSHOT' + + implementation(platform("net.kyori:adventure-bom:${adventureVersion}")) + implementation("net.kyori:adventure-nbt") implementation 'org.asynchttpclient:async-http-client:2.12.1' 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 f635babf5..22b88fbca 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 @@ -45,6 +45,7 @@ import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.packet.Chat; import com.velocitypowered.proxy.protocol.packet.ClientSettings; import com.velocitypowered.proxy.protocol.packet.Disconnect; +import com.velocitypowered.proxy.protocol.packet.HeaderAndFooter; import com.velocitypowered.proxy.protocol.packet.KeepAlive; import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest; @@ -61,6 +62,7 @@ import java.net.InetSocketAddress; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -105,6 +107,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { private @Nullable VelocityServerConnection connectionInFlight; private @Nullable PlayerSettings settings; private @Nullable ModInfo modInfo; + private Component playerListHeader = Component.empty(); + private Component playerListFooter = Component.empty(); private final VelocityTabList tabList; private final VelocityServer server; private ClientConnectionPhase connectionPhase; @@ -116,9 +120,9 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { @Nullable InetSocketAddress virtualHost, boolean onlineMode) { this.server = server; if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) { - this.tabList = new VelocityTabList(connection); + this.tabList = new VelocityTabList(this); } else { - this.tabList = new VelocityTabListLegacy(connection); + this.tabList = new VelocityTabListLegacy(this); } this.profile = profile; this.connection = connection; @@ -301,6 +305,33 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { } } + @Override + public Component getPlayerListHeader() { + return this.playerListHeader; + } + + @Override + public Component getPlayerListFooter() { + return this.playerListFooter; + } + + @Override + public void sendPlayerListHeader(@NonNull final Component header) { + this.sendPlayerListHeaderAndFooter(header, this.playerListFooter); + } + + @Override + public void sendPlayerListFooter(@NonNull final Component footer) { + this.sendPlayerListHeaderAndFooter(this.playerListHeader, footer); + } + + @Override + public void sendPlayerListHeaderAndFooter(final Component header, final Component footer) { + this.playerListHeader = Objects.requireNonNull(header, "header"); + this.playerListFooter = Objects.requireNonNull(footer, "footer"); + this.connection.write(HeaderAndFooter.create(header, footer, this.getProtocolVersion())); + } + @Override public void showTitle(net.kyori.adventure.title.@NonNull Title title) { GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(this @@ -363,6 +394,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { this.profile = profile.withProperties(Preconditions.checkNotNull(properties)); } + @Deprecated @Override public void setHeaderAndFooter(net.kyori.text.Component header, net.kyori.text.Component footer) { tabList.setHeaderAndFooter(header, footer); diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java index 93ceaed62..34f8d6098 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/HeaderAndFooter.java @@ -8,6 +8,7 @@ import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.ProtocolUtils; import io.netty.buffer.ByteBuf; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; public class HeaderAndFooter implements MinecraftPacket { @@ -51,15 +52,8 @@ public class HeaderAndFooter implements MinecraftPacket { return handler.handle(this); } - public static HeaderAndFooter create(net.kyori.text.Component header, - net.kyori.text.Component footer) { - return new HeaderAndFooter( - net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE.serialize(header), - net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE.serialize(footer)); - } - - public static HeaderAndFooter create(net.kyori.adventure.text.Component header, - net.kyori.adventure.text.Component footer, ProtocolVersion protocolVersion) { + public static HeaderAndFooter create(Component header, + Component footer, ProtocolVersion protocolVersion) { GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(protocolVersion); return new HeaderAndFooter(serializer.serialize(header), serializer.serialize(footer)); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java index 5611a7761..1cae947fa 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabList.java @@ -5,6 +5,7 @@ import com.velocitypowered.api.proxy.player.TabList; import com.velocitypowered.api.proxy.player.TabListEntry; import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.proxy.connection.MinecraftConnection; +import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.protocol.packet.HeaderAndFooter; import com.velocitypowered.proxy.protocol.packet.PlayerListItem; import java.util.ArrayList; @@ -15,31 +16,39 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import net.kyori.text.Component; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacytext3.LegacyText3ComponentSerializer; import org.checkerframework.checker.nullness.qual.Nullable; public class VelocityTabList implements TabList { + protected final ConnectedPlayer player; protected final MinecraftConnection connection; protected final Map entries = new ConcurrentHashMap<>(); - public VelocityTabList(MinecraftConnection connection) { - this.connection = connection; + public VelocityTabList(final ConnectedPlayer player) { + this.player = player; + this.connection = player.getConnection(); } + @Deprecated + @Override + public void setHeaderAndFooter(net.kyori.text.Component header, + net.kyori.text.Component footer) { + Preconditions.checkNotNull(header, "header"); + Preconditions.checkNotNull(footer, "footer"); + this.player.sendPlayerListHeaderAndFooter( + LegacyText3ComponentSerializer.get().deserialize(header), + LegacyText3ComponentSerializer.get().deserialize(footer) + ); + } + + @Deprecated @Override public void setHeaderAndFooter(Component header, Component footer) { Preconditions.checkNotNull(header, "header"); Preconditions.checkNotNull(footer, "footer"); - connection.write(HeaderAndFooter.create(header, footer)); - } - - @Override - public void setHeaderAndFooter(net.kyori.adventure.text.Component header, - net.kyori.adventure.text.Component footer) { - Preconditions.checkNotNull(header, "header"); - Preconditions.checkNotNull(footer, "footer"); - connection.write(HeaderAndFooter.create(header, footer, connection.getProtocolVersion())); + this.player.sendPlayerListHeaderAndFooter(header, footer); } @Override diff --git a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListLegacy.java b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListLegacy.java index 305564ea7..95966c6b4 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListLegacy.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListLegacy.java @@ -3,7 +3,7 @@ package com.velocitypowered.proxy.tablist; import com.google.common.collect.ImmutableList; import com.velocitypowered.api.proxy.player.TabListEntry; import com.velocitypowered.api.util.GameProfile; -import com.velocitypowered.proxy.connection.MinecraftConnection; +import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.protocol.packet.PlayerListItem; import com.velocitypowered.proxy.protocol.packet.PlayerListItem.Item; import java.util.Collections; @@ -18,14 +18,16 @@ public class VelocityTabListLegacy extends VelocityTabList { private final Map nameMapping = new ConcurrentHashMap<>(); - public VelocityTabListLegacy(MinecraftConnection connection) { - super(connection); + public VelocityTabListLegacy(final ConnectedPlayer player) { + super(player); } + @Deprecated @Override public void setHeaderAndFooter(net.kyori.text.Component header, net.kyori.text.Component footer) { } + @Deprecated @Override public void setHeaderAndFooter(Component header, Component footer) { } From 2a5bb1e48747f4e43d8eec3eb128248c21c6788c Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Mon, 7 Dec 2020 02:28:03 -0500 Subject: [PATCH 2/3] Fix tab list clearing bug. Fixes regression introduced in 5da085d --- .../proxy/connection/client/ConnectedPlayer.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) 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 22b88fbca..653325c5f 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 @@ -119,11 +119,6 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection, @Nullable InetSocketAddress virtualHost, boolean onlineMode) { this.server = server; - if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) { - this.tabList = new VelocityTabList(this); - } else { - this.tabList = new VelocityTabListLegacy(this); - } this.profile = profile; this.connection = connection; this.virtualHost = virtualHost; @@ -131,6 +126,12 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { this.connectionPhase = connection.getType().getInitialClientPhase(); this.knownChannels = CappedSet.create(MAX_PLUGIN_CHANNELS); this.onlineMode = onlineMode; + + if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) { + this.tabList = new VelocityTabList(this); + } else { + this.tabList = new VelocityTabListLegacy(this); + } } @Override From aef0e4a825f57186b8f1442fe1a2280a1f4ada8b Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Wed, 9 Dec 2020 22:25:06 -0500 Subject: [PATCH 3/3] Update Netty to 4.1.55.Final. --- build.gradle | 2 +- proxy/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 5ed54ddff..6aa4819d9 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,7 @@ allprojects { junitVersion = '5.7.0' slf4jVersion = '1.7.30' log4jVersion = '2.13.3' - nettyVersion = '4.1.54.Final' + nettyVersion = '4.1.55.Final' guavaVersion = '25.1-jre' checkerFrameworkVersion = '3.6.1' configurateVersion = '3.7.1' diff --git a/proxy/build.gradle b/proxy/build.gradle index a345d4a2e..1b35443cf 100644 --- a/proxy/build.gradle +++ b/proxy/build.gradle @@ -51,7 +51,7 @@ dependencies { implementation "io.netty:netty-handler:${nettyVersion}" implementation "io.netty:netty-transport-native-epoll:${nettyVersion}" implementation "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64" - implementation "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-aarch64" + implementation "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-aarch_64" implementation "io.netty:netty-resolver-dns:${nettyVersion}" implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"