diff --git a/src/main/java/me/youhavetrouble/notjustnameplates/nameplates/NameplateManager.java b/src/main/java/me/youhavetrouble/notjustnameplates/nameplates/NameplateManager.java index 8bdb1be..0048456 100644 --- a/src/main/java/me/youhavetrouble/notjustnameplates/nameplates/NameplateManager.java +++ b/src/main/java/me/youhavetrouble/notjustnameplates/nameplates/NameplateManager.java @@ -2,6 +2,7 @@ package me.youhavetrouble.notjustnameplates.nameplates; import me.youhavetrouble.notjustnameplates.NotJustNameplates; import me.youhavetrouble.notjustnameplates.displays.DisplayContent; +import me.youhavetrouble.notjustnameplates.packets.TeamPacketListener; import net.minecraft.world.phys.AABB; import org.bukkit.*; import org.bukkit.block.Block; @@ -40,6 +41,7 @@ public class NameplateManager implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPlayerJoin(PlayerJoinEvent event) { + TeamPacketListener.addPlayer(event.getPlayer()); UUID joinerUuid = event.getPlayer().getUniqueId(); DisplayContent displayContent = NotJustNameplates.getInstance().getDisplayContentForPlayerBasedOnPermission(event.getPlayer()); if (displayContent == null) return; @@ -102,6 +104,11 @@ public class NameplateManager implements Listener { event.setShouldRetry(true); } + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + TeamPacketListener.removePlayer(event.getPlayer()); + } + public void reloadNameplates() { this.nameplates.values().forEach(Nameplate::remove); this.nameplates.clear(); diff --git a/src/main/java/me/youhavetrouble/notjustnameplates/packets/PacketTeam.java b/src/main/java/me/youhavetrouble/notjustnameplates/packets/PacketTeam.java new file mode 100644 index 0000000..a9ad0cd --- /dev/null +++ b/src/main/java/me/youhavetrouble/notjustnameplates/packets/PacketTeam.java @@ -0,0 +1,29 @@ +package me.youhavetrouble.notjustnameplates.packets; + +import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.scores.PlayerTeam; +import net.minecraft.world.scores.Team; +import org.jetbrains.annotations.Nullable; + +public class PacketTeam extends PlayerTeam { + + private PacketTeam(String name, ClientboundSetPlayerTeamPacket.Parameters parameters) { + super(MinecraftServer.getServer().getScoreboard(), name); + if (parameters != null) { + Team.CollisionRule collisionRule = Team.CollisionRule.byName(parameters.getCollisionRule()); + if (collisionRule != null) setCollisionRule(collisionRule); + setColor(parameters.getColor()); + setPlayerPrefix(parameters.getPlayerPrefix()); + setPlayerSuffix(parameters.getPlayerSuffix()); + setDisplayName(parameters.getDisplayName()); + unpackOptions(parameters.getOptions()); + } + + setNameTagVisibility(Team.Visibility.NEVER); + } + + public static PacketTeam create(String name, @Nullable ClientboundSetPlayerTeamPacket.Parameters parameters) { + return new PacketTeam(name, parameters); + } +} diff --git a/src/main/java/me/youhavetrouble/notjustnameplates/packets/TeamPacketListener.java b/src/main/java/me/youhavetrouble/notjustnameplates/packets/TeamPacketListener.java new file mode 100644 index 0000000..9fe484a --- /dev/null +++ b/src/main/java/me/youhavetrouble/notjustnameplates/packets/TeamPacketListener.java @@ -0,0 +1,57 @@ +package me.youhavetrouble.notjustnameplates.packets; + +import io.netty.channel.*; +import me.youhavetrouble.notjustnameplates.NotJustNameplates; +import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Team; + +import java.util.Locale; + +public class TeamPacketListener extends ChannelDuplexHandler { + + public static final String HANDLER_NAME = "njn_team_packet_handler"; + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + if (!(msg instanceof ClientboundSetPlayerTeamPacket originalPacket)) { + super.write(ctx, msg, promise); + return; + } + // if nametag visibility is already never, no need to override the packet + if (originalPacket.getParameters().isPresent()) { + ClientboundSetPlayerTeamPacket.Parameters parameters = originalPacket.getParameters().get(); + Team.OptionStatus nametagVisibility = Team.OptionStatus.valueOf(parameters.getNametagVisibility().toUpperCase(Locale.ENGLISH)); + if (nametagVisibility == Team.OptionStatus.NEVER) { + super.write(ctx, msg, promise); + return; + } + } + + NotJustNameplates.getInstance().getLogger().info(msg.toString()); + PacketTeam packetTeam = PacketTeam.create(originalPacket.getName(), originalPacket.getParameters().orElse(null)); + ClientboundSetPlayerTeamPacket newPacket = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(packetTeam, true); + super.write(ctx, newPacket, promise); + } + + + public static void addPlayer(Player player) { + CraftPlayer craftPlayer = (CraftPlayer) player; + Channel channel = craftPlayer.getHandle().connection.connection.channel; + ChannelPipeline pipeline = channel.pipeline(); + if (pipeline.get(HANDLER_NAME) == null) { + pipeline.addBefore("packet_handler", HANDLER_NAME, new TeamPacketListener()); + } + } + + public static void removePlayer(Player player) { + CraftPlayer craftPlayer = (CraftPlayer) player; + Channel channel = craftPlayer.getHandle().connection.connection.channel; + ChannelPipeline pipeline = channel.pipeline(); + if (pipeline.get(HANDLER_NAME) != null) { + pipeline.remove(HANDLER_NAME); + } + } + +}