From 2217e8a5c9232dfc86bbed0a17d7ec23c068ef90 Mon Sep 17 00:00:00 2001 From: Gabik21 Date: Tue, 7 Apr 2020 12:17:02 +0200 Subject: [PATCH] Fix 1.7 tablist behaving weird with colored names The 1.7 tablist packet only contains three types of information: - Name of the tablist entry (limited to 16 characters including colors) - Ping of the entry - If this entry needs to be added or removed (client accepts duplicates as 'ping update') The previous logic was trying to preserve parity with GameProfile#getName returning a stripped down name to have a 'real' username. That is fundamentally broken, because entries with duplicate content, but different colors are very common, especially with custom tablists. For packets coming from a native 1.7 server we just won't define the displayname anymore, as there is no such thing as a 'displayname', because tablist entries are not bound to any player. Using the Velocity Tablist API to modify existing entries will work, though the backend server will completely loose control over the entry. Custom entries added over the Velocity Tablist API will work, but are cut off by the 16 character limitation. This commit only fixes the bug, where entries are incorrectly handled with their stripped name, a lot of the things explained above were already implemented correctly. --- .../proxy/tablist/VelocityTabListLegacy.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) 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 b1e5c2610..3eabf11e8 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListLegacy.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/tablist/VelocityTabListLegacy.java @@ -60,29 +60,25 @@ public class VelocityTabListLegacy extends VelocityTabList { Item item = packet.getItems().get(0); // Only one item per packet in 1.7 - Component displayName = LegacyComponentSerializer.legacy().deserialize(item.getName()); - String strippedName = PlainComponentSerializer.INSTANCE.serialize(displayName); - switch (packet.getAction()) { case PlayerListItem.ADD_PLAYER: - if (nameMapping.containsKey(strippedName)) { // ADD_PLAYER also used for updating ping - VelocityTabListEntry entry = entries.get(nameMapping.get(strippedName)); + if (nameMapping.containsKey(item.getName())) { // ADD_PLAYER also used for updating ping + VelocityTabListEntry entry = entries.get(nameMapping.get(item.getName())); if (entry != null) { entry.setLatency(item.getLatency()); } } else { UUID uuid = UUID.randomUUID(); // Use a fake uuid to preserve function of custom entries - nameMapping.put(strippedName, uuid); + nameMapping.put(item.getName(), uuid); entries.put(uuid, (VelocityTabListEntry) TabListEntry.builder() .tabList(this) - .profile(new GameProfile(uuid, strippedName, ImmutableList.of())) - .displayName(displayName) + .profile(new GameProfile(uuid, item.getName(), ImmutableList.of())) .latency(item.getLatency()) .build()); } break; case PlayerListItem.REMOVE_PLAYER: - UUID removedUuid = nameMapping.remove(strippedName); + UUID removedUuid = nameMapping.remove(item.getName()); if (removedUuid != null) { entries.remove(removedUuid); }