From 8bcb7d33809bc3dfde33848527fc5b1caf860a7d Mon Sep 17 00:00:00 2001 From: XiaoMoMi <70987828+Xiao-MoMi@users.noreply.github.com> Date: Fri, 11 Oct 2024 05:30:24 +0800 Subject: [PATCH] to fix teams --- .../customnameplates/api/ConfigManager.java | 6 +++ backend/src/main/resources/config.yml | 1 + .../bukkit/BukkitCustomNameplates.java | 3 +- .../bukkit/BukkitPlatform.java | 52 +++++++++++++++---- .../bukkit/util/Reflections.java | 43 +++++++++++++-- .../common/util/UUIDUtils.java | 15 ++++++ gradle.properties | 2 +- 7 files changed, 106 insertions(+), 16 deletions(-) diff --git a/api/src/main/java/net/momirealms/customnameplates/api/ConfigManager.java b/api/src/main/java/net/momirealms/customnameplates/api/ConfigManager.java index b964aaf..bc1d358 100644 --- a/api/src/main/java/net/momirealms/customnameplates/api/ConfigManager.java +++ b/api/src/main/java/net/momirealms/customnameplates/api/ConfigManager.java @@ -67,6 +67,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable { protected boolean bubbleModule; protected boolean nameplateModule; protected boolean backgroundModule; + protected boolean hideTeamNames; protected int defaultPlaceholderRefreshInterval; protected int defaultConditionRefreshInterval; protected int delaySend; @@ -216,6 +217,7 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable { defaultConditionRefreshInterval = config.getInt("other-settings.ddefault-condition-refresh-interval", 1); catchOtherActionBar = config.getBoolean("other-settings.catch-other-plugin-actionbar", true); otherActionBarStayTime = config.getInt("other-settings.other-actionbar-stay-time", 3000); + hideTeamNames = config.getBoolean("other-settings.hide-team-names", true); } @Override @@ -267,6 +269,10 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable { return instance.initialChar; } + public static boolean hideTeamNames() { + return instance.hideTeamNames; + } + public static boolean actionbarModule() { return instance.actionbarModule; } diff --git a/backend/src/main/resources/config.yml b/backend/src/main/resources/config.yml index 4e8d2bf..ccf5bbc 100644 --- a/backend/src/main/resources/config.yml +++ b/backend/src/main/resources/config.yml @@ -62,6 +62,7 @@ other-settings: send-delay: 20 # Set actionbar/bossbar send delay (ticks) catch-other-plugin-actionbar: true # Capture actionbars from other plugins other-actionbar-stay-time: 3000 # How long does other actionsbars stay (ms) + hide-team-names: true # Hide the team name sent by other plugins or vanilla team system unsafe-chat-event: false # Listen for canceled(unsafe) chat events from unknown plugins default-condition-refresh-interval: 1 # Set default condition refresh interval default-placeholder-refresh-interval: 1 # Set default placeholder refresh interval diff --git a/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitCustomNameplates.java b/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitCustomNameplates.java index 539f877..b27f002 100644 --- a/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitCustomNameplates.java +++ b/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitCustomNameplates.java @@ -54,6 +54,7 @@ import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.player.*; @@ -325,7 +326,7 @@ public class BukkitCustomNameplates extends CustomNameplates implements Listener return instance; } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST) public void onJoin(PlayerJoinEvent event) { CNPlayer cnPlayer = new BukkitCNPlayer(this, event.getPlayer()); CNPlayer previous = onlinePlayerMap.put(cnPlayer.uuid(), cnPlayer); diff --git a/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitPlatform.java b/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitPlatform.java index 873e1c2..5fbbea8 100644 --- a/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitPlatform.java +++ b/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/BukkitPlatform.java @@ -280,6 +280,34 @@ public class BukkitPlatform implements Platform { CustomNameplates.getInstance().getPluginLogger().severe("Failed to handle ClientboundSetEntityDataPacket", e); } }, "ClientboundSetEntityDataPacket", "PacketPlayOutEntityMetadata"); + + registerPacketConsumer((player, event, packet) -> { + if (!ConfigManager.nametagModule()) return; + if (!ConfigManager.hideTeamNames()) return; + try { + int method = (int) Reflections.field$ClientboundSetPlayerTeamPacket$method.get(packet); + if (method == 0 || method == 2) { +// How to handle mixed entity team packs +// @SuppressWarnings("unchecked") +// Collection entities = (Collection) Reflections.field$ClientboundSetPlayerTeamPacket$players.get(packet); +// outer: { +// for (String entity : entities) { +// if (!UUIDUtils.isUUID(entity)) { +// break outer; +// } +// } +// } + @SuppressWarnings("unchecked") + Optional optionalParameters = (Optional) Reflections.field$ClientboundSetPlayerTeamPacket$parameters.get(packet); + if (optionalParameters.isPresent()) { + Object parameters = optionalParameters.get(); + Reflections.field$ClientboundSetPlayerTeamPacket$Parameters$nametagVisibility.set(parameters, "never"); + } + } + } catch (ReflectiveOperationException e) { + CustomNameplates.getInstance().getPluginLogger().severe("Failed to handle ClientboundSetPlayerTeamPacket", e); + } + }, "ClientboundSetPlayerTeamPacket", "PacketPlayOutScoreboardTeam"); } @Override @@ -512,25 +540,29 @@ public class BukkitPlatform implements Platform { } } - @SuppressWarnings("unchecked") @Override public void onPacketSend(CNPlayer player, PacketEvent event) { try { Object packet = event.getPacket(); - if (Reflections.clazz$ClientboundBundlePacket.isInstance(packet)) { - Iterable packets = (Iterable) Reflections.field$BundlePacket$packets.get(packet); - for (Object p : packets) { - handlePacket(player, event, p); - } - } else { - handlePacket(player, event, packet); - } + onPacketSend(player, event, packet); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } } - private void handlePacket(CNPlayer player, PacketEvent event, Object packet) throws ReflectiveOperationException { + @SuppressWarnings("unchecked") + private void onPacketSend(CNPlayer player, PacketEvent event, Object packet) throws ReflectiveOperationException { + if (Reflections.clazz$ClientboundBundlePacket.isInstance(packet)) { + Iterable packets = (Iterable) Reflections.field$BundlePacket$packets.get(packet); + for (Object p : packets) { + onPacketSend(player, event, p); + } + } else { + handlePacket(player, event, packet); + } + } + + private void handlePacket(CNPlayer player, PacketEvent event, Object packet) { Optional.ofNullable(packetFunctions.get(packet.getClass().getSimpleName())) .ifPresent(function -> function.accept(player, event, packet)); } diff --git a/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/util/Reflections.java index fa4058b..287e501 100644 --- a/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/customnameplates/bukkit/util/Reflections.java @@ -23,10 +23,7 @@ import net.momirealms.customnameplates.common.util.ReflectionUtils; import sun.misc.Unsafe; import java.lang.reflect.*; -import java.util.Collection; -import java.util.EnumSet; -import java.util.List; -import java.util.UUID; +import java.util.*; import static java.util.Objects.requireNonNull; @@ -988,4 +985,42 @@ public class Reflections { throw new RuntimeException(e); } } + + public static final Class clazz$ClientboundSetPlayerTeamPacket = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetPlayerTeamPacket"), + BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardTeam") + ) + ); + + public static final Field field$ClientboundSetPlayerTeamPacket$method = requireNonNull( + ReflectionUtils.getInstanceDeclaredField( + clazz$ClientboundSetPlayerTeamPacket, int.class, 0 + ) + ); + + public static final Field field$ClientboundSetPlayerTeamPacket$players = requireNonNull( + ReflectionUtils.getInstanceDeclaredField( + clazz$ClientboundSetPlayerTeamPacket, Collection.class, 0 + ) + ); + + public static final Field field$ClientboundSetPlayerTeamPacket$parameters = requireNonNull( + ReflectionUtils.getInstanceDeclaredField( + clazz$ClientboundSetPlayerTeamPacket, Optional.class, 0 + ) + ); + + public static final Class clazz$ClientboundSetPlayerTeamPacket$Parameters = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundSetPlayerTeamPacket$Parameters"), + BukkitReflectionUtils.assembleMCClass("network.protocol.game.PacketPlayOutScoreboardTeam$b") + ) + ); + + public static final Field field$ClientboundSetPlayerTeamPacket$Parameters$nametagVisibility = requireNonNull( + ReflectionUtils.getInstanceDeclaredField( + clazz$ClientboundSetPlayerTeamPacket$Parameters, String.class, 0 + ) + ); } diff --git a/common/src/main/java/net/momirealms/customnameplates/common/util/UUIDUtils.java b/common/src/main/java/net/momirealms/customnameplates/common/util/UUIDUtils.java index 66c43fd..d53996d 100644 --- a/common/src/main/java/net/momirealms/customnameplates/common/util/UUIDUtils.java +++ b/common/src/main/java/net/momirealms/customnameplates/common/util/UUIDUtils.java @@ -39,6 +39,21 @@ public class UUIDUtils { ); } + /** + * Check if the id is a UUID + * + * @param id id + * @return true if it's a UUID + */ + public static boolean isUUID(String id) { + try { + UUID.fromString(id); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + /** * Converts a {@link UUID} object to a string without dashes. * diff --git a/gradle.properties b/gradle.properties index 6dc0005..f6451b8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # Project settings # Rule: [major update].[feature update].[bug fix] project_version=3.0.1 -config_version=29 +config_version=30 project_group=net.momirealms # Dependency settings