From 918620a7dcf65fbff91675a1674991f47e921e69 Mon Sep 17 00:00:00 2001 From: NEZNAMY Date: Thu, 31 Oct 2024 20:46:51 +0100 Subject: [PATCH] [Bukkit & Fabric] Update to 24w44a (predicted on Bukkit) --- build.gradle.kts | 3 +- .../platforms/paper/PaperPacketTabList.java | 19 ++-- .../bukkit/tablist/BukkitTabList.java | 7 +- .../bukkit/tablist/PacketTabList1193.java | 45 +++++++--- .../bukkit/tablist/PacketTabList17.java | 9 +- .../bukkit/tablist/PacketTabList18.java | 21 +++-- .../bungeecord/tablist/BungeeTabList.java | 5 +- .../bungeecord/tablist/BungeeTabList1193.java | 71 ++++++++------- .../bungeecord/tablist/BungeeTabList17.java | 9 +- .../bungeecord/tablist/BungeeTabList18.java | 9 +- fabric/build.gradle.kts | 2 +- .../platforms/fabric/FabricMultiVersion.java | 9 +- .../tab/platforms/fabric/FabricTabList.java | 25 ++++-- .../fabric/loader/Loader_Latest.java | 25 +++--- fabric/src/main/resources/fabric.mod.json | 2 +- .../resources/resources/tab.accesswidener | 3 - fabric/v1_21_3/build.gradle.kts | 33 +++++++ .../fabric/loader/Loader_1_21_3.java | 90 +++++++++++++++++++ jar/build.gradle.kts | 3 +- settings.gradle.kts | 1 + .../neznamy/tab/shared/ProtocolVersion.java | 3 +- .../globalplayerlist/GlobalPlayerList.java | 5 +- .../tab/shared/features/layout/FixedSlot.java | 3 +- .../shared/features/layout/LayoutView.java | 3 +- .../shared/features/layout/PlayerSlot.java | 6 +- .../neznamy/tab/shared/platform/TabList.java | 18 +++- .../platform/decorators/TrackedTabList.java | 7 +- .../tab/platforms/sponge7/SpongeTabList.java | 7 +- .../tab/platforms/sponge8/SpongeTabList.java | 9 +- .../platforms/velocity/VelocityTabList.java | 12 ++- 30 files changed, 353 insertions(+), 111 deletions(-) create mode 100644 fabric/v1_21_3/build.gradle.kts create mode 100644 fabric/v1_21_3/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_1_21_3.java diff --git a/build.gradle.kts b/build.gradle.kts index 636dfc333..bcb6ed375 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,8 @@ val platforms = setOf( projects.fabric, projects.fabric.v1144, projects.fabric.v1182, - projects.fabric.v1203 + projects.fabric.v1203, + projects.fabric.v1213 ).map { it.dependencyProject } val special = setOf( diff --git a/bukkit/paper/src/main/java/me/neznamy/tab/platforms/paper/PaperPacketTabList.java b/bukkit/paper/src/main/java/me/neznamy/tab/platforms/paper/PaperPacketTabList.java index 0df31cef2..6c106fc66 100644 --- a/bukkit/paper/src/main/java/me/neznamy/tab/platforms/paper/PaperPacketTabList.java +++ b/bukkit/paper/src/main/java/me/neznamy/tab/platforms/paper/PaperPacketTabList.java @@ -29,11 +29,11 @@ @SuppressWarnings("unused") // Used via reflection public class PaperPacketTabList extends TabListBase { - private final EnumSet updateDisplayName = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); - private final EnumSet updateLatency = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY); - private final EnumSet updateGameMode = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE); - private final EnumSet updateListed = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED); - private final EnumSet addPlayer = EnumSet.allOf(ClientboundPlayerInfoUpdatePacket.Action.class); + private static final EnumSet updateDisplayName = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME); + private static final EnumSet updateLatency = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY); + private static final EnumSet updateGameMode = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE); + private static final EnumSet updateListed = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED); + private static final EnumSet addPlayer = EnumSet.allOf(ClientboundPlayerInfoUpdatePacket.Action.class); private static final Field entries; @@ -93,13 +93,18 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // TODO update module to 1.21.2 when it comes out } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // TODO update module to 1.21.4 when it comes out + } + @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable Component displayName, int listOrder) { + int gameMode, @Nullable Component displayName, int listOrder, boolean showHat) { sendPacket(new ClientboundPlayerInfoUpdatePacket(addPlayer, new ClientboundPlayerInfoUpdatePacket.Entry( id, createProfile(id, name, skin), listed, latency, GameType.byId(gameMode), displayName, null ))); - // TODO update module to 1.21.2 when it comes out + // TODO update module to 1.21.4 when it comes out } @Override diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/BukkitTabList.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/BukkitTabList.java index 4f04b8ae7..2097505d4 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/BukkitTabList.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/BukkitTabList.java @@ -57,9 +57,14 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // Shrug } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // Shrug + } + @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable String displayName, int listOrder) { + int gameMode, @Nullable String displayName, int listOrder, boolean showHat) { // Shrug } diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList1193.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList1193.java index a53e0d7ea..0ae1e09c2 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList1193.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList1193.java @@ -25,6 +25,7 @@ public class PacketTabList1193 extends PacketTabList18 { private static final Map> actionToEnumSet = new EnumMap<>(Action.class); private static boolean v1_21_2Plus; + private static boolean v1_21_4Plus; private static Enum actionAddPlayer; private static Enum actionUpdateDisplayName; @@ -35,6 +36,7 @@ public class PacketTabList1193 extends PacketTabList18 { private static Field PlayerInfoData_UUID; private static Field PlayerInfoData_GameMode; private static Field PlayerInfoData_Listed; + private static Field PlayerInfoData_ShowHat; private static Field PlayerInfoData_ListOrder; private static Field PlayerInfoData_RemoteChatSession; @@ -74,7 +76,7 @@ public static void loadNew() throws ReflectiveOperationException { loadSharedContent(playerInfoDataClass, EnumGamemodeClass); - PlayerInfoData_Listed = ReflectionUtils.getOnlyField(playerInfoDataClass, boolean.class); + PlayerInfoData_Listed = ReflectionUtils.getFields(playerInfoDataClass, boolean.class).get(0); PlayerInfoData_GameMode = ReflectionUtils.getOnlyField(playerInfoDataClass, EnumGamemodeClass); PlayerInfoData_RemoteChatSession = ReflectionUtils.getOnlyField(playerInfoDataClass, RemoteChatSession$Data); PlayerInfoData_UUID = ReflectionUtils.getOnlyField(playerInfoDataClass, UUID.class); @@ -91,10 +93,20 @@ public static void loadNew() throws ReflectiveOperationException { actionToEnumSet.put(Action.UPDATE_LISTED, EnumSet.of(Enum.valueOf(ActionClass, Action.UPDATE_LISTED.name()))); try { actionToEnumSet.put(Action.UPDATE_LIST_ORDER, EnumSet.of(Enum.valueOf(ActionClass, Action.UPDATE_LIST_ORDER.name()))); - newPlayerInfoData = playerInfoDataClass.getConstructor(UUID.class, GameProfile.class, boolean.class, int.class, - EnumGamemodeClass, IChatBaseComponent, int.class, RemoteChatSession$Data); PlayerInfoData_ListOrder = ReflectionUtils.getFields(playerInfoDataClass, int.class).get(1); v1_21_2Plus = true; + try { + // 1.21.4+ + actionToEnumSet.put(Action.UPDATE_HAT, EnumSet.of(Enum.valueOf(ActionClass, Action.UPDATE_HAT.name()))); + PlayerInfoData_ShowHat = ReflectionUtils.getFields(playerInfoDataClass, boolean.class).get(1); + newPlayerInfoData = playerInfoDataClass.getConstructor(UUID.class, GameProfile.class, boolean.class, int.class, + EnumGamemodeClass, IChatBaseComponent, boolean.class, int.class, RemoteChatSession$Data); + v1_21_4Plus = true; + } catch (Exception ignored) { + // 1.21.2 - 1.21.3 + newPlayerInfoData = playerInfoDataClass.getConstructor(UUID.class, GameProfile.class, boolean.class, int.class, + EnumGamemodeClass, IChatBaseComponent, int.class, RemoteChatSession$Data); + } } catch (Exception ignored) { // 1.21.1-, should have a better check newPlayerInfoData = playerInfoDataClass.getConstructor(UUID.class, GameProfile.class, boolean.class, int.class, @@ -111,14 +123,22 @@ public void removeEntry(@NonNull UUID entry) { @Override public void updateListed(@NonNull UUID entry, boolean listed) { packetSender.sendPacket(player, - createPacket(Action.UPDATE_LISTED, entry, "", null, listed, 0, 0, null, 0)); + createPacket(Action.UPDATE_LISTED, entry, "", null, listed, 0, 0, null, 0, false)); } @Override public void updateListOrder(@NonNull UUID entry, int listOrder) { if (player.getPlatform().getServerVersion().getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId()) { packetSender.sendPacket(player, - createPacket(Action.UPDATE_LIST_ORDER, entry, "", null, false, 0, 0, null, listOrder)); + createPacket(Action.UPDATE_LIST_ORDER, entry, "", null, false, 0, 0, null, listOrder, false)); + } + } + + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + if (player.getPlatform().getServerVersion().getNetworkId() >= ProtocolVersion.V1_21_4.getNetworkId()) { + packetSender.sendPacket(player, + createPacket(Action.UPDATE_HAT, entry, "", null, false, 0, 0, null, 0, showHat)); } } @@ -126,7 +146,7 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { @NotNull @Override public Object createPacket(@NonNull Action action, @NonNull UUID id, @NonNull String name, @Nullable Skin skin, - boolean listed, int latency, int gameMode, @Nullable Object displayName, int listOrder) { + boolean listed, int latency, int gameMode, @Nullable Object displayName, int listOrder, boolean showHat) { Object packet = newPlayerInfo.newInstance(actionToEnumSet.get(action), Collections.emptyList()); PLAYERS.set(packet, Collections.singletonList(newPlayerInfoData( id, @@ -135,6 +155,7 @@ public Object createPacket(@NonNull Action action, @NonNull UUID id, @NonNull St latency, gameModes[gameMode], displayName, + showHat, listOrder, null ))); @@ -155,6 +176,7 @@ public void onPacketSend(@NonNull Object packet) { Object displayName = PlayerInfoData_DisplayName.get(nmsData); int latency = PlayerInfoData_Latency.getInt(nmsData); int listOrder = v1_21_2Plus ? PlayerInfoData_ListOrder.getInt(nmsData) : 0; + boolean showHat = v1_21_4Plus && PlayerInfoData_ShowHat.getBoolean(nmsData); if (actions.contains(actionUpdateDisplayName)) { Object expectedName = getExpectedDisplayNames().get(id); if (expectedName != null && expectedName != displayName) { @@ -180,6 +202,7 @@ public void onPacketSend(@NonNull Object packet) { latency, PlayerInfoData_GameMode.get(nmsData), displayName, + showHat, listOrder, PlayerInfoData_RemoteChatSession.get(nmsData)) : nmsData); } @@ -189,11 +212,13 @@ public void onPacketSend(@NonNull Object packet) { @NotNull @SneakyThrows private static Object newPlayerInfoData(@NotNull UUID id, @Nullable GameProfile profile, boolean listed, int latency, - @Nullable Object gameMode, @Nullable Object displayName, int listOrder, @Nullable Object chatSession) { - if (v1_21_2Plus) { - return newPlayerInfoData.newInstance(id, profile, listed, latency, gameMode, displayName, listOrder, chatSession); + @Nullable Object gameMode, @Nullable Object displayName, boolean showHat, int listOrder, @Nullable Object chatSession) { + if (v1_21_4Plus) { + return newPlayerInfoData.newInstance(id, profile, listed, latency, gameMode, displayName, showHat, listOrder, chatSession); + } else if (v1_21_2Plus) { + return newPlayerInfoData.newInstance(id, profile, listed, latency, gameMode, displayName, listOrder, chatSession); } else { - return newPlayerInfoData.newInstance(id, profile, listed, latency, gameMode, displayName, chatSession); + return newPlayerInfoData.newInstance(id, profile, listed, latency, gameMode, displayName, chatSession); } } } diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList17.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList17.java index f47b5a256..05206d3e1 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList17.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList17.java @@ -86,7 +86,7 @@ public void removeEntry(@NonNull UUID entry) { public void updateDisplayName(@NonNull UUID entry, @Nullable String displayName) { if (!displayNames.containsKey(entry)) return; // Entry not tracked by TAB packetSender.sendPacket(player, newPacket.apply(displayNames.get(entry), false, 0)); - addEntry(entry, userNames.get(entry), null, false, 0, 0, displayName, 0); + addEntry(entry, userNames.get(entry), null, false, 0, 0, displayName, 0, false); } @Override @@ -111,10 +111,15 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // Added in 1.21.2 } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // Added in 1.21.4 + } + @Override @SneakyThrows public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable String displayName, int listOrder) { + int gameMode, @Nullable String displayName, int listOrder, boolean showHat) { String display = displayName == null ? name : displayName; packetSender.sendPacket(player, newPacket.apply(display, true, latency)); userNames.put(id, name); diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java index c7b0247f4..a590b512a 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/tablist/PacketTabList18.java @@ -112,25 +112,25 @@ protected static void loadSharedContent(Class infoData, Class gameMode) @Override public void removeEntry(@NonNull UUID entry) { packetSender.sendPacket(player, - createPacket(Action.REMOVE_PLAYER, entry, "", null, false, 0, 0, null, 0)); + createPacket(Action.REMOVE_PLAYER, entry, "", null, false, 0, 0, null, 0, false)); } @Override public void updateDisplayName(@NonNull UUID entry, @Nullable Object displayName) { packetSender.sendPacket(player, - createPacket(Action.UPDATE_DISPLAY_NAME, entry, "", null, false, 0, 0, displayName, 0)); + createPacket(Action.UPDATE_DISPLAY_NAME, entry, "", null, false, 0, 0, displayName, 0, false)); } @Override public void updateLatency(@NonNull UUID entry, int latency) { packetSender.sendPacket(player, - createPacket(Action.UPDATE_LATENCY, entry, "", null, false, latency, 0, null, 0)); + createPacket(Action.UPDATE_LATENCY, entry, "", null, false, latency, 0, null, 0, false)); } @Override public void updateGameMode(@NonNull UUID entry, int gameMode) { packetSender.sendPacket(player, - createPacket(Action.UPDATE_GAME_MODE, entry, "", null, false, 0, gameMode, null, 0)); + createPacket(Action.UPDATE_GAME_MODE, entry, "", null, false, 0, gameMode, null, 0, false)); } @Override @@ -143,11 +143,16 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // Added in 1.21.2 } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // Added in 1.21.4 + } + @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable Object displayName, int listOrder) { + int gameMode, @Nullable Object displayName, int listOrder, boolean showHat) { packetSender.sendPacket(player, - createPacket(Action.ADD_PLAYER, id, name, skin, listed, latency, gameMode, displayName, listOrder)); + createPacket(Action.ADD_PLAYER, id, name, skin, listed, latency, gameMode, displayName, listOrder, showHat)); } /** @@ -171,12 +176,14 @@ public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin * Entry display name * @param listOrder * Entry list order + * @param showHat + * Show hat flag * @return Packet from given parameters */ @SneakyThrows @NotNull public Object createPacket(@NonNull Action action, @NonNull UUID id, @NonNull String name, @Nullable Skin skin, - boolean listed, int latency, int gameMode, @Nullable Object displayName, int listOrder) { + boolean listed, int latency, int gameMode, @Nullable Object displayName, int listOrder, boolean showHat) { Object packet = newPlayerInfo.newInstance(Enum.valueOf(ActionClass, action.name()), Collections.emptyList()); List parameters = new ArrayList<>(); if (newPlayerInfoData.getParameterTypes()[0] == PlayerInfoClass) { diff --git a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList.java b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList.java index 676b5dd6a..bbfd41d3c 100644 --- a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList.java +++ b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList.java @@ -81,11 +81,13 @@ public Item item(@NonNull UUID id) { * Entry display name * @param listOrder * Entry list order + * @param showHat + * Show hat flag * @return Converted item from parameters */ @NotNull public Item entryToItem(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable BaseComponent displayName, int listOrder) { + int gameMode, @Nullable BaseComponent displayName, int listOrder, boolean showHat) { Item item = item(id); item.setUsername(name); item.setDisplayName(displayName); @@ -98,6 +100,7 @@ public Item entryToItem(@NonNull UUID id, @NonNull String name, @Nullable Skin s item.setProperties(new Property[0]); } item.setListOrder(listOrder); + // TODO showHat once BungeeCord adds it return item; } diff --git a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList1193.java b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList1193.java index 2b2739780..adaec1fd7 100644 --- a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList1193.java +++ b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList1193.java @@ -17,25 +17,30 @@ */ public class BungeeTabList1193 extends BungeeTabList { - /** Map of actions to prevent creating new EnumSet on each packet send */ - private static final Map> actions = new EnumMap<>(Action.class); - - private static final EnumSet allActions = EnumSet.allOf(PlayerListItemUpdate.Action.class); - - static { - // Do not use allOf because <1.21.2 does not support UPDATE_LIST_ORDER - actions.put(Action.ADD_PLAYER, EnumSet.of( - PlayerListItemUpdate.Action.ADD_PLAYER, - PlayerListItemUpdate.Action.UPDATE_GAMEMODE, - PlayerListItemUpdate.Action.UPDATE_LISTED, - PlayerListItemUpdate.Action.UPDATE_LATENCY, - PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME - )); - actions.put(Action.UPDATE_GAME_MODE, EnumSet.of(PlayerListItemUpdate.Action.UPDATE_GAMEMODE)); - actions.put(Action.UPDATE_DISPLAY_NAME, EnumSet.of(PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME)); - actions.put(Action.UPDATE_LATENCY, EnumSet.of(PlayerListItemUpdate.Action.UPDATE_LATENCY)); - actions.put(Action.UPDATE_LISTED, EnumSet.of(PlayerListItemUpdate.Action.UPDATE_LISTED)); - } + private static final EnumSet updateDisplayName = EnumSet.of(PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME); + private static final EnumSet updateLatency = EnumSet.of(PlayerListItemUpdate.Action.UPDATE_LATENCY); + private static final EnumSet updateGameMode = EnumSet.of(PlayerListItemUpdate.Action.UPDATE_GAMEMODE); + private static final EnumSet updateListed = EnumSet.of(PlayerListItemUpdate.Action.UPDATE_LISTED); + private static final EnumSet updateListOrder = EnumSet.of(PlayerListItemUpdate.Action.UPDATE_LIST_ORDER); + + // All actions for 1.19.3 - 1.21.1 + private static final EnumSet addPlayer_1_21_1 = EnumSet.of( + PlayerListItemUpdate.Action.ADD_PLAYER, + PlayerListItemUpdate.Action.UPDATE_GAMEMODE, + PlayerListItemUpdate.Action.UPDATE_LISTED, + PlayerListItemUpdate.Action.UPDATE_LATENCY, + PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME + ); + + // All actions for 1.21.2 - 1.21.3 + private static final EnumSet addPlayer_1_21_2 = EnumSet.of( + PlayerListItemUpdate.Action.ADD_PLAYER, + PlayerListItemUpdate.Action.UPDATE_GAMEMODE, + PlayerListItemUpdate.Action.UPDATE_LISTED, + PlayerListItemUpdate.Action.UPDATE_LATENCY, + PlayerListItemUpdate.Action.UPDATE_DISPLAY_NAME, + PlayerListItemUpdate.Action.UPDATE_LIST_ORDER + ); /** * Constructs new instance with given parameter. @@ -59,28 +64,28 @@ public void removeEntry(@NonNull UUID entry) { public void updateDisplayName(@NonNull UUID entry, @Nullable BaseComponent displayName) { Item item = item(entry); item.setDisplayName(displayName); - sendPacket(Action.UPDATE_DISPLAY_NAME, item); + sendPacket(updateDisplayName, item); } @Override public void updateLatency(@NonNull UUID entry, int latency) { Item item = item(entry); item.setPing(latency); - sendPacket(Action.UPDATE_LATENCY, item); + sendPacket(updateLatency, item); } @Override public void updateGameMode(@NonNull UUID entry, int gameMode) { Item item = item(entry); item.setGamemode(gameMode); - sendPacket(Action.UPDATE_GAME_MODE, item); + sendPacket(updateGameMode, item); } @Override public void updateListed(@NonNull UUID entry, boolean listed) { Item item = item(entry); item.setListed(listed); - sendPacket(Action.UPDATE_LISTED, item); + sendPacket(updateListed, item); } @Override @@ -88,23 +93,25 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { if (player.getVersion().getNetworkId() < ProtocolVersion.V1_21_2.getNetworkId()) return; Item item = item(entry); item.setListOrder(listOrder); - sendPacket(Action.UPDATE_LIST_ORDER, item); + sendPacket(updateListOrder, item); + } + + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + //TODO once BungeeCord adds it } @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable BaseComponent displayName, int listOrder) { + int gameMode, @Nullable BaseComponent displayName, int listOrder, boolean showHat) { addUuid(id); - sendPacket(Action.ADD_PLAYER, entryToItem(id, name, skin, listed, latency, gameMode, displayName, listOrder)); + sendPacket(player.getVersion().getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId() ? addPlayer_1_21_2 : addPlayer_1_21_1, + entryToItem(id, name, skin, listed, latency, gameMode, displayName, listOrder, showHat)); } - private void sendPacket(@NonNull Action action, @NonNull Item item) { + private void sendPacket(@NonNull EnumSet actions, @NonNull Item item) { PlayerListItemUpdate packet = new PlayerListItemUpdate(); - if (player.getVersion().getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId() && action == Action.ADD_PLAYER) { - packet.setActions(allActions); - } else { - packet.setActions(actions.get(action)); - } + packet.setActions(actions); packet.setItems(new Item[]{item}); player.sendPacket(packet); } diff --git a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList17.java b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList17.java index 89884bec5..f7b64e22e 100644 --- a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList17.java +++ b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList17.java @@ -57,7 +57,7 @@ public void removeEntry(@NonNull UUID entry) { public void updateDisplayName(@NonNull UUID entry, @Nullable BaseComponent displayName) { if (!displayNames.containsKey(entry)) return; // Entry not tracked by TAB update(PlayerListItem.Action.REMOVE_PLAYER, createItem(null, displayNames.get(entry), 0)); - addEntry(entry, userNames.get(entry), null, false, 0, 0, displayName, 0); + addEntry(entry, userNames.get(entry), null, false, 0, 0, displayName, 0, false); } @Override @@ -81,9 +81,14 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // Added in 1.21.2 } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // Added in 1.21.4 + } + @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable BaseComponent displayName, int listOrder) { + int gameMode, @Nullable BaseComponent displayName, int listOrder, boolean showHat) { addUuid(id); update(PlayerListItem.Action.ADD_PLAYER, createItem(name, displayName == null ? new TextComponent(name) : displayName, latency)); diff --git a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList18.java b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList18.java index 274de0d06..8d0187fcf 100644 --- a/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList18.java +++ b/bungeecord/src/main/java/me/neznamy/tab/platforms/bungeecord/tablist/BungeeTabList18.java @@ -62,11 +62,16 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // Added in 1.21.2 } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // Added in 1.21.4 + } + @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable BaseComponent displayName, int listOrder) { + int gameMode, @Nullable BaseComponent displayName, int listOrder, boolean showHat) { addUuid(id); - sendPacket(PlayerListItem.Action.ADD_PLAYER, entryToItem(id, name, skin, listed, latency, gameMode, displayName, listOrder)); + sendPacket(PlayerListItem.Action.ADD_PLAYER, entryToItem(id, name, skin, listed, latency, gameMode, displayName, listOrder, showHat)); } private void sendPacket(@NonNull PlayerListItem.Action action, @NonNull Item item) { diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 0f3a6262f..61b39ab99 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -13,7 +13,7 @@ repositories { dependencies { api(projects.shared) - minecraft("com.mojang:minecraft:1.21.3") + minecraft("com.mojang:minecraft:24w44a") mappings(loom.officialMojangMappings()) modImplementation("me.lucko:fabric-permissions-api:0.2-SNAPSHOT") modImplementation("eu.pb4:placeholder-api:2.5.0+1.21.2") diff --git a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricMultiVersion.java b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricMultiVersion.java index 4bf9be893..27678e67d 100644 --- a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricMultiVersion.java +++ b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricMultiVersion.java @@ -35,6 +35,9 @@ public class FabricMultiVersion { /** Method loader using latest supported MC version */ private static final Loader loaderLatest = new Loader_Latest(); + /** Method loader using 1.21.2 - 1.21.3 */ + private static final Loader loader1_21_3 = createLoader("1_21_3"); + /** Method loader using 1.20.3 - 1.21.1 */ private static final Loader loader1_20_3 = createLoader("1_20_3"); @@ -256,7 +259,8 @@ public static boolean isPlayerInfo(@NotNull Packet packet) { * Received packet */ public static void onPlayerInfo(@NotNull TabPlayer receiver, @NotNull Object packet) { - if (serverVersion.getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId()) loaderLatest.onPlayerInfo(receiver, packet); + if (serverVersion.getNetworkId() >= ProtocolVersion.V1_21_4.getNetworkId()) loaderLatest.onPlayerInfo(receiver, packet); + else if (serverVersion.getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId()) loader1_21_3.onPlayerInfo(receiver, packet); else if (serverVersion.getNetworkId() >= ProtocolVersion.V1_19_3.getNetworkId()) loader1_20_3.onPlayerInfo(receiver, packet); else if (serverVersion.getMinorVersion() >= 17) loader1_18_2.onPlayerInfo(receiver, packet); else loader1_14_4.onPlayerInfo(receiver, packet); @@ -273,7 +277,8 @@ public static void onPlayerInfo(@NotNull TabPlayer receiver, @NotNull Object pac */ @NotNull public static Packet buildTabListPacket(@NotNull TabList.Action action, @NotNull FabricTabList.Builder builder) { - if (serverVersion.getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId()) return loaderLatest.buildTabListPacket(action, builder); + if (serverVersion.getNetworkId() >= ProtocolVersion.V1_21_4.getNetworkId()) return loaderLatest.buildTabListPacket(action, builder); + if (serverVersion.getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId()) return loader1_21_3.buildTabListPacket(action, builder); if (serverVersion.getNetworkId() >= ProtocolVersion.V1_19_3.getNetworkId()) return loader1_20_3.buildTabListPacket(action, builder); if (serverVersion.getMinorVersion() >= 17) return loader1_18_2.buildTabListPacket(action, builder); return loader1_14_4.buildTabListPacket(action, builder); diff --git a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricTabList.java b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricTabList.java index 2aa96cc65..b57e5def1 100644 --- a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricTabList.java +++ b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/FabricTabList.java @@ -32,32 +32,32 @@ public FabricTabList(@NotNull FabricTabPlayer player) { @Override public void removeEntry(@NonNull UUID entry) { player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.REMOVE_PLAYER, - new Builder(entry, "", null, false, 0, 0, null, 0))); + new Builder(entry, "", null, false, 0, 0, null, 0, false))); } @Override public void updateDisplayName(@NonNull UUID entry, @Nullable Component displayName) { player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.UPDATE_DISPLAY_NAME, - new Builder(entry, "", null, false, 0, 0, displayName, 0))); + new Builder(entry, "", null, false, 0, 0, displayName, 0, false))); } @Override public void updateLatency(@NonNull UUID entry, int latency) { player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.UPDATE_LATENCY, - new Builder(entry, "", null, false, latency, 0, null, 0))); + new Builder(entry, "", null, false, latency, 0, null, 0, false))); } @Override public void updateGameMode(@NonNull UUID entry, int gameMode) { player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.UPDATE_GAME_MODE, - new Builder(entry, "", null, false, 0, gameMode, null, 0))); + new Builder(entry, "", null, false, 0, gameMode, null, 0, false))); } @Override public void updateListed(@NonNull UUID entry, boolean listed) { if (player.getPlatform().getServerVersion().getNetworkId() >= ProtocolVersion.V1_19_3.getNetworkId()) { player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.UPDATE_LISTED, - new Builder(entry, "", null, listed, 0, 0, null, 0))); + new Builder(entry, "", null, listed, 0, 0, null, 0, false))); } } @@ -65,15 +65,23 @@ public void updateListed(@NonNull UUID entry, boolean listed) { public void updateListOrder(@NonNull UUID entry, int listOrder) { if (player.getPlatform().getServerVersion().getNetworkId() >= ProtocolVersion.V1_21_2.getNetworkId()) { player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.UPDATE_LIST_ORDER, - new Builder(entry, "", null, false, 0, 0, null, listOrder))); + new Builder(entry, "", null, false, 0, 0, null, listOrder, false))); + } + } + + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + if (player.getPlatform().getServerVersion().getNetworkId() >= ProtocolVersion.V1_21_4.getNetworkId()) { + player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.UPDATE_HAT, + new Builder(entry, "", null, false, 0, 0, null, 0, showHat))); } } @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable Component displayName, int listOrder) { + int gameMode, @Nullable Component displayName, int listOrder, boolean showHat) { player.sendPacket(FabricMultiVersion.buildTabListPacket(Action.ADD_PLAYER, - new Builder(id, name, skin, listed, latency, gameMode, displayName, listOrder))); + new Builder(id, name, skin, listed, latency, gameMode, displayName, listOrder, showHat))); } @Override @@ -108,6 +116,7 @@ public static class Builder { private int gameMode; @Nullable private Component displayName; private int listOrder; + private boolean showHat; /** * Creates profile of this entry. diff --git a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_Latest.java b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_Latest.java index 58fea4ec9..38fd9f6cf 100644 --- a/fabric/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_Latest.java +++ b/fabric/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_Latest.java @@ -73,19 +73,14 @@ public Style convertModifier(@NotNull ChatModifier modifier, boolean modern) { color = TextColor.fromRgb(modifier.getColor().getLegacyColor().getRgb()); } } - - return new Style( - color, - modifier.isBold(), - modifier.isItalic(), - modifier.isUnderlined(), - modifier.isStrikethrough(), - modifier.isObfuscated(), - null, - null, - null, - modifier.getFont() == null ? null : ResourceLocation.tryParse(modifier.getFont()) - ); + return Style.EMPTY + .withColor(color) + .withBold(modifier.isBold()) + .withItalic(modifier.isItalic()) + .withUnderlined(modifier.isUnderlined()) + .withStrikethrough(modifier.isStrikethrough()) + .withObfuscated(modifier.isObfuscated()) + .withFont(modifier.getFont() == null ? null : ResourceLocation.tryParse(modifier.getFont())); } @Override @@ -160,7 +155,7 @@ public void onPlayerInfo(@NotNull TabPlayer receiver, @NotNull Object packet0) { TAB.getInstance().getFeatureManager().onEntryAdd(receiver, nmsData.profileId(), profile.getName()); } updatedList.add(new ClientboundPlayerInfoUpdatePacket.Entry(nmsData.profileId(), profile, nmsData.listed(), - latency, nmsData.gameMode(), displayName, nmsData.listOrder(), nmsData.chatSession())); + latency, nmsData.gameMode(), displayName, nmsData.showHat(), nmsData.listOrder(), nmsData.chatSession())); } packet.entries = updatedList; } @@ -179,6 +174,7 @@ public Packet buildTabListPacket(@NotNull TabList.Action action, @NotNull Fab entry.getLatency(), GameType.byId(entry.getGameMode()), entry.getDisplayName(), + entry.isShowHat(), entry.getListOrder(), null )); @@ -295,6 +291,7 @@ private static Map (Lnet/minecraft/network/chat/TextColor;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Lnet/minecraft/network/chat/ClickEvent;Lnet/minecraft/network/chat/HoverEvent;Ljava/lang/String;Lnet/minecraft/resources/ResourceLocation;)V - # Team packet (1.17+) accessible field net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket method I accessible field net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket players Ljava/util/Collection; diff --git a/fabric/v1_21_3/build.gradle.kts b/fabric/v1_21_3/build.gradle.kts new file mode 100644 index 000000000..edf97db9d --- /dev/null +++ b/fabric/v1_21_3/build.gradle.kts @@ -0,0 +1,33 @@ +plugins { + id("fabric-loom") +} + +repositories { + // Gradle doesn't support combining settings and project repositories, so we have to re-declare all the settings repos we need + maven("https://jitpack.io") // YamlAssist + maven("https://repo.opencollab.dev/maven-snapshots/") + maven("https://repo.viaversion.com/") + maven("https://oss.sonatype.org/content/repositories/snapshots") + maven("https://maven.nucleoid.xyz/") +} + +dependencies { + implementation(projects.fabric) + minecraft("com.mojang:minecraft:1.21.3") + mappings(loom.officialMojangMappings()) + modImplementation("net.fabricmc:fabric-loader:0.15.9") // Not required, but causes warn if not present +} + +loom { + accessWidenerPath.set(file("../src/main/resources/resources/tab.accesswidener")) +} + +tasks { + compileJava { + options.release.set(17) + } + + validateAccessWidener { + enabled = false // Disable validation because the file is made for latest version, so some fields will throw error (the one we need has not changed) + } +} diff --git a/fabric/v1_21_3/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_1_21_3.java b/fabric/v1_21_3/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_1_21_3.java new file mode 100644 index 000000000..28f8529cb --- /dev/null +++ b/fabric/v1_21_3/src/main/java/me/neznamy/tab/platforms/fabric/loader/Loader_1_21_3.java @@ -0,0 +1,90 @@ +package me.neznamy.tab.platforms.fabric.loader; + +import com.mojang.authlib.GameProfile; +import lombok.RequiredArgsConstructor; +import me.neznamy.tab.platforms.fabric.FabricTabList; +import me.neznamy.tab.shared.ProtocolVersion; +import me.neznamy.tab.shared.TAB; +import me.neznamy.tab.shared.platform.TabList; +import me.neznamy.tab.shared.platform.TabPlayer; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; +import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; +import net.minecraft.world.level.GameType; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * Implementation containing some methods that have changed multiple times + * throughout the versions and need a separate module. This module implements + * a few methods in the state of Minecraft 1.21.2 - 1.21.3. + */ +@SuppressWarnings("unused") // Actually used, just via reflection +@RequiredArgsConstructor +public class Loader_1_21_3 implements Loader { + + private final ProtocolVersion serverVersion; + + @Override + public void onPlayerInfo(@NotNull TabPlayer receiver, @NotNull Object packet0) { + ClientboundPlayerInfoUpdatePacket packet = (ClientboundPlayerInfoUpdatePacket) packet0; + EnumSet actions = packet.actions(); + List updatedList = new ArrayList<>(); + for (ClientboundPlayerInfoUpdatePacket.Entry nmsData : packet.entries()) { + GameProfile profile = nmsData.profile(); + Component displayName = nmsData.displayName(); + int latency = nmsData.latency(); + if (actions.contains(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)) { + Component expectedDisplayName = ((FabricTabList)receiver.getTabList()).getExpectedDisplayNames().get(nmsData.profileId()); + if (expectedDisplayName != null) displayName = expectedDisplayName; + } + if (actions.contains(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY)) { + latency = TAB.getInstance().getFeatureManager().onLatencyChange(receiver, nmsData.profileId(), latency); + } + if (actions.contains(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER)) { + TAB.getInstance().getFeatureManager().onEntryAdd(receiver, nmsData.profileId(), profile.getName()); + } + updatedList.add(new ClientboundPlayerInfoUpdatePacket.Entry(nmsData.profileId(), profile, nmsData.listed(), + latency, nmsData.gameMode(), displayName, nmsData.listOrder(), nmsData.chatSession())); + } + packet.entries = updatedList; + } + + @Override + @NotNull + public Packet buildTabListPacket(@NotNull TabList.Action action, @NotNull FabricTabList.Builder entry) { + if (action == TabList.Action.REMOVE_PLAYER) { + return new ClientboundPlayerInfoRemovePacket(Collections.singletonList(entry.getId())); + } + ClientboundPlayerInfoUpdatePacket packet = new ClientboundPlayerInfoUpdatePacket(Register1_19_3.actionMap.get(action), Collections.emptyList()); + packet.entries = Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.Entry( + entry.getId(), + action == TabList.Action.ADD_PLAYER ? entry.createProfile() : null, + entry.isListed(), + entry.getLatency(), + GameType.byId(entry.getGameMode()), + entry.getDisplayName(), + entry.getListOrder(), + null + )); + return packet; + } + + private static class Register1_19_3 { + + static final Map> actionMap = createActionMap(); + + private static Map> createActionMap() { + Map> actions = new EnumMap<>(TabList.Action.class); + actions.put(TabList.Action.ADD_PLAYER, EnumSet.allOf(ClientboundPlayerInfoUpdatePacket.Action.class)); + actions.put(TabList.Action.UPDATE_GAME_MODE, EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE)); + actions.put(TabList.Action.UPDATE_DISPLAY_NAME, EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)); + actions.put(TabList.Action.UPDATE_LATENCY, EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY)); + actions.put(TabList.Action.UPDATE_LISTED, EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED)); + actions.put(TabList.Action.UPDATE_LIST_ORDER, EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LIST_ORDER)); + return actions; + } + } +} diff --git a/jar/build.gradle.kts b/jar/build.gradle.kts index 0d1844366..6b4c9f572 100644 --- a/jar/build.gradle.kts +++ b/jar/build.gradle.kts @@ -17,7 +17,8 @@ val fabrics = setOf( rootProject.projects.fabric, rootProject.projects.fabric.v1144, rootProject.projects.fabric.v1182, - rootProject.projects.fabric.v1203 + rootProject.projects.fabric.v1203, + rootProject.projects.fabric.v1213 ).map { it.dependencyProject } tasks { diff --git a/settings.gradle.kts b/settings.gradle.kts index 80e95d7f7..fae4e66e9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -38,4 +38,5 @@ include(":fabric") include(":fabric:v1_14_4") include(":fabric:v1_18_2") include(":fabric:v1_20_3") +include(":fabric:v1_21_3") include(":jar") \ No newline at end of file diff --git a/shared/src/main/java/me/neznamy/tab/shared/ProtocolVersion.java b/shared/src/main/java/me/neznamy/tab/shared/ProtocolVersion.java index 22ac78ea1..f0313a96e 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/ProtocolVersion.java +++ b/shared/src/main/java/me/neznamy/tab/shared/ProtocolVersion.java @@ -11,6 +11,7 @@ public enum ProtocolVersion { UNKNOWN, + V1_21_4 (769), // Predicted PVN V1_21_3 (768), V1_21_2 (768), V1_21_1 (767), @@ -85,7 +86,7 @@ public enum ProtocolVersion { private static final ProtocolVersion[] VALUES = values(); /** Newest MC version this plugin jar knows */ - public static final ProtocolVersion LATEST_KNOWN_VERSION = VALUES[1]; + public static final ProtocolVersion LATEST_KNOWN_VERSION = V1_21_3; /** Version's network id found at wiki.vg */ private final int networkId; diff --git a/shared/src/main/java/me/neznamy/tab/shared/features/globalplayerlist/GlobalPlayerList.java b/shared/src/main/java/me/neznamy/tab/shared/features/globalplayerlist/GlobalPlayerList.java index 02064e083..c9bec7b57 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/features/globalplayerlist/GlobalPlayerList.java +++ b/shared/src/main/java/me/neznamy/tab/shared/features/globalplayerlist/GlobalPlayerList.java @@ -240,7 +240,8 @@ public TabList.Entry getAddInfoData(@NotNull TabPlayer p, @NotNull TabPlayer vie configuration.updateLatency ? p.getPing() : 0, gameMode, viewer.getVersion().getMinorVersion() >= 8 ? format : null, - 0 + 0, + true ); } @@ -296,7 +297,7 @@ private boolean shouldSee(@NotNull TabPlayer viewer, @NotNull RedisPlayer target @NotNull private TabList.Entry getEntry(@NotNull RedisPlayer player) { - return new TabList.Entry(player.getUniqueId(), player.getNickname(), player.getSkin(), true, 0, 0, player.getTabFormat(), 0); + return new TabList.Entry(player.getUniqueId(), player.getNickname(), player.getSkin(), true, 0, 0, player.getTabFormat(), 0, true); } // ------------------ diff --git a/shared/src/main/java/me/neznamy/tab/shared/features/layout/FixedSlot.java b/shared/src/main/java/me/neznamy/tab/shared/features/layout/FixedSlot.java index 04304cffb..51deaf006 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/features/layout/FixedSlot.java +++ b/shared/src/main/java/me/neznamy/tab/shared/features/layout/FixedSlot.java @@ -74,7 +74,8 @@ public TabList.Entry createEntry(@NotNull TabPlayer viewer) { ping, 0, cache.get(viewer.layoutData.currentLayout.fixedSlotTexts.get(this).updateAndGet()), - Integer.MAX_VALUE - manager.getConfiguration().direction.translateSlot(slot) + Integer.MAX_VALUE - manager.getConfiguration().direction.translateSlot(slot), + true ); } diff --git a/shared/src/main/java/me/neznamy/tab/shared/features/layout/LayoutView.java b/shared/src/main/java/me/neznamy/tab/shared/features/layout/LayoutView.java index ab53fc1cb..4cd954d61 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/features/layout/LayoutView.java +++ b/shared/src/main/java/me/neznamy/tab/shared/features/layout/LayoutView.java @@ -57,7 +57,8 @@ public void send() { manager.getConfiguration().emptySlotPing, 0, new SimpleComponent(""), - Integer.MAX_VALUE - manager.getConfiguration().direction.translateSlot(slot) + Integer.MAX_VALUE - manager.getConfiguration().direction.translateSlot(slot), + true )); } tick(); diff --git a/shared/src/main/java/me/neznamy/tab/shared/features/layout/PlayerSlot.java b/shared/src/main/java/me/neznamy/tab/shared/features/layout/PlayerSlot.java index 6695a4334..ce7c3b756 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/features/layout/PlayerSlot.java +++ b/shared/src/main/java/me/neznamy/tab/shared/features/layout/PlayerSlot.java @@ -45,7 +45,8 @@ public void setPlayer(@Nullable TabPlayer newPlayer) { layout.getManager().getPingSpoof() != null ? layout.getManager().getPingSpoof().getConfiguration().value : player.getPing(), 0, playerList == null || player.tablistData.disabled.get() ? new SimpleComponent(player.getName()) : playerList.getTabFormat(player, viewer), - Integer.MAX_VALUE - layout.getManager().getConfiguration().direction.translateSlot(slot) + Integer.MAX_VALUE - layout.getManager().getConfiguration().direction.translateSlot(slot), + true ); } else { data = new TabList.Entry( @@ -56,7 +57,8 @@ public void setPlayer(@Nullable TabPlayer newPlayer) { layout.getManager().getConfiguration().emptySlotPing, 0, new SimpleComponent(text), - Integer.MAX_VALUE - layout.getManager().getConfiguration().direction.translateSlot(slot) + Integer.MAX_VALUE - layout.getManager().getConfiguration().direction.translateSlot(slot), + true ); } return data; diff --git a/shared/src/main/java/me/neznamy/tab/shared/platform/TabList.java b/shared/src/main/java/me/neznamy/tab/shared/platform/TabList.java index 4d1183289..282d74ef0 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/platform/TabList.java +++ b/shared/src/main/java/me/neznamy/tab/shared/platform/TabList.java @@ -73,6 +73,16 @@ public interface TabList { */ void updateListOrder(@NonNull UUID entry, int listOrder); + /** + * Updates show hat flag of specified entry (1.21.4+). + * + * @param entry + * Entry to update + * @param showHat + * New show hat flag value + */ + void updateHat(@NonNull UUID entry, boolean showHat); + /** * Adds specified entry into the TabList. * @@ -124,7 +134,10 @@ enum Action { UPDATE_DISPLAY_NAME, /** Updates list order (1.21.2+) */ - UPDATE_LIST_ORDER + UPDATE_LIST_ORDER, + + /** Updates hat flag (1.21.4+) */ + UPDATE_HAT } /** @@ -161,6 +174,9 @@ class Entry { /** Player list weight */ private int listOrder; + + /** Show hat flag */ + private boolean showHat; } /** diff --git a/shared/src/main/java/me/neznamy/tab/shared/platform/decorators/TrackedTabList.java b/shared/src/main/java/me/neznamy/tab/shared/platform/decorators/TrackedTabList.java index 029d720fd..1dcae8669 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/platform/decorators/TrackedTabList.java +++ b/shared/src/main/java/me/neznamy/tab/shared/platform/decorators/TrackedTabList.java @@ -42,7 +42,8 @@ public void updateDisplayName(@NonNull UUID entry, @Nullable TabComponent displa public void addEntry(@NonNull Entry entry) { C component = entry.getDisplayName() == null ? null : toComponent(entry.getDisplayName()); if (antiOverride) expectedDisplayNames.put(entry.getUniqueId(), component); - addEntry(entry.getUniqueId(), entry.getName(), entry.getSkin(), entry.isListed(), entry.getLatency(), entry.getGameMode(), component, entry.getListOrder()); + addEntry(entry.getUniqueId(), entry.getName(), entry.getSkin(), entry.isListed(), entry.getLatency(), + entry.getGameMode(), component, entry.getListOrder(), entry.isShowHat()); if (player.getVersion().getMinorVersion() == 8) { // Compensation for 1.8.0 client sided bug updateDisplayName(entry.getUniqueId(), component); @@ -109,7 +110,9 @@ public C toComponent(@NonNull TabComponent component) { * Entry display name * @param listOrder * Entry list order + * @param showHat + * Show hat flag */ public abstract void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, - boolean listed, int latency, int gameMode, @Nullable C displayName, int listOrder); + boolean listed, int latency, int gameMode, @Nullable C displayName, int listOrder, boolean showHat); } diff --git a/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongeTabList.java b/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongeTabList.java index 6dcc5c4ec..c2417500b 100644 --- a/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongeTabList.java +++ b/sponge7/src/main/java/me/neznamy/tab/platforms/sponge7/SpongeTabList.java @@ -64,9 +64,14 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // Added in 1.21.2 } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // Added in 1.21.4 + } + @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable Text displayName, int listOrder) { + int gameMode, @Nullable Text displayName, int listOrder, boolean showHat) { GameProfile profile = GameProfile.of(id, name); if (skin != null) profile.getPropertyMap().put(TEXTURES_PROPERTY, ProfileProperty.of( TEXTURES_PROPERTY, skin.getValue(), skin.getSignature())); diff --git a/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongeTabList.java b/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongeTabList.java index 24c58fa3f..00ae12e68 100644 --- a/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongeTabList.java +++ b/sponge8/src/main/java/me/neznamy/tab/platforms/sponge8/SpongeTabList.java @@ -64,13 +64,18 @@ public void updateListOrder(@NonNull UUID entry, int listOrder) { // TODO } + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // TODO + } + @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable Component displayName, int listOrder) { + int gameMode, @Nullable Component displayName, int listOrder, boolean showHat) { GameProfile profile = GameProfile.of(id, name); if (skin != null) profile = profile.withProperty(ProfileProperty.of( TEXTURES_PROPERTY, skin.getValue(), skin.getSignature())); - //TODO listed, listOrder + //TODO listed, listOrder, showHat TabListEntry tabListEntry = TabListEntry.builder() .list(player.getPlayer().tabList()) .profile(profile) diff --git a/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityTabList.java b/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityTabList.java index 36af0e06d..c391a4e8e 100644 --- a/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityTabList.java +++ b/velocity/src/main/java/me/neznamy/tab/platforms/velocity/VelocityTabList.java @@ -55,12 +55,17 @@ public void updateListed(@NonNull UUID entry, boolean listed) { @Override public void updateListOrder(@NonNull UUID entry, int listOrder) { - // TODO + // TODO once velocity adds it + } + + @Override + public void updateHat(@NonNull UUID entry, boolean showHat) { + // TODO once velocity adds it } @Override public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin, boolean listed, int latency, - int gameMode, @Nullable Component displayName, int listOrder) { + int gameMode, @Nullable Component displayName, int listOrder, boolean showHat) { GameProfile profile = new GameProfile(id, name, skin == null ? Collections.emptyList() : Collections.singletonList( new GameProfile.Property(TEXTURES_PROPERTY, skin.getValue(), Objects.requireNonNull(skin.getSignature())))); TabListEntry e = TabListEntry.builder() @@ -71,7 +76,8 @@ public void addEntry(@NonNull UUID id, @NonNull String name, @Nullable Skin skin .gameMode(gameMode) .listed(listed) .build(); - // TODO listOrder + // TODO listOrder once velocity adds it + // TODO showHat once velocity adds it // Remove entry because: // #1 - If player is 1.8 - 1.19.2, KeyedVelocityTabList#addEntry will throw IllegalArgumentException