diff --git a/pom.xml b/pom.xml index eb1f9c6..aea305f 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,10 @@ + + jitpack.io + https://jitpack.io + codemc-repo https://repo.codemc.io/repository/maven-public/ @@ -34,20 +38,16 @@ nms-repo https://repo.codemc.io/repository/nms/ - - jitpack.io - https://jitpack.io - refine-public - https://maven.refinedev.xyz/repository/public-repo/ + https://maven.refinedev.xyz/public-repo refine-releases - https://maven.refinedev.xyz/repository/maven-releases/ + https://maven.refinedev.xyz/maven-releases @@ -92,14 +92,13 @@ xyz.refinedev.api TablistAPI - 2.1 + 2.2 provided - - com.github.retrooper - packetevents-spigot - 2.4.0 + com.github.retrooper.packetevents + spigot + 2.3.0 provided @@ -110,6 +109,14 @@ org.jetbrains annotations + + com.github.retrooper.packetevents + api + + + com.github.retrooper.packetevents + netty-common + diff --git a/src/main/java/xyz/refinedev/api/nametag/NameTagHandler.java b/src/main/java/xyz/refinedev/api/nametag/NameTagHandler.java index bf2e5f5..88be047 100644 --- a/src/main/java/xyz/refinedev/api/nametag/NameTagHandler.java +++ b/src/main/java/xyz/refinedev/api/nametag/NameTagHandler.java @@ -27,7 +27,6 @@ import xyz.refinedev.api.nametag.listener.GlitchFixListener; import xyz.refinedev.api.nametag.listener.NameTagListener; import xyz.refinedev.api.nametag.update.impl.NameTagRemove; -import xyz.refinedev.api.nametag.util.packet.ScoreboardPacket; import xyz.refinedev.api.nametag.setup.NameTagTeam; import xyz.refinedev.api.nametag.update.impl.NameTagRefresh; import xyz.refinedev.api.nametag.thread.NameTagThread; @@ -36,6 +35,7 @@ import xyz.refinedev.api.nametag.util.VersionUtil; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; /** * This Project is property of Refine Development. @@ -62,11 +62,12 @@ public class NameTagHandler { *
Viewer -> Target -> {@link NameTagTeam}
*

*/ - private final Map> teamMap = new Object2ObjectOpenHashMap<>(); + private final Map> teamMap = new ConcurrentHashMap<>(); /** * All registered teams are stored here */ - private final List registeredTeams = new ObjectArrayList<>(); + private final Map teamCache = new ConcurrentHashMap<>(); + private static final String SEPARATOR = "::"; // Separator for prefix-suffix keys /** * The plugin registering this NameTag Handler */ @@ -86,7 +87,6 @@ public class NameTagHandler { public NameTagHandler(JavaPlugin plugin) { instance = this; this.plugin = plugin; - this.debugMode = Boolean.getBoolean("BDebug"); } /** @@ -96,10 +96,9 @@ public NameTagHandler(JavaPlugin plugin) { public void init(PacketEventsAPI packetEventsAPI) { this.packetEvents = packetEventsAPI; this.adapter = new DefaultNameTagAdapter(); - this.packetEvents.getEventManager().registerListener(new DisguiseListener(this)); - Bukkit.getPluginManager().registerEvents(new NameTagListener(this), this.plugin); + Bukkit.getPluginManager().registerEvents(new NameTagListener(this), this.plugin); try { Class.forName("xyz.refinedev.api.tablist.util.GlitchFixEvent"); Bukkit.getPluginManager().registerEvents(new GlitchFixListener(this), this.plugin); @@ -116,7 +115,7 @@ public void unload() { this.thread.stopExecuting(); for ( Player player : Bukkit.getOnlinePlayers() ) { - for ( NameTagTeam team : registeredTeams ) { + for ( NameTagTeam team : this.teamCache.values() ) { team.destroyFor(player); } } @@ -133,7 +132,6 @@ public void registerAdapter(NameTagAdapter adapter, long ticks) { } this.thread = new NameTagThread(this, ticks); - this.thread.start(); } /** @@ -157,12 +155,13 @@ public void createTeams(Player player) { public void initiatePlayer(Player player) { if (this.thread == null) return; - for ( NameTagTeam teamInfo : this.registeredTeams ) { - if (VersionUtil.MINOR_VERSION > 8) { - PacketUtil.sendPacket(player, teamInfo.getPECreatePacket()); - } else { - ScoreboardPacket.deliverPacket(player, teamInfo.getCreatePacket()); - } + if (this.teamCache.isEmpty()) { + this.adapter.fetchNameTag(player, player); + return; + } + + for ( NameTagTeam teamInfo : this.teamCache.values() ) { + PacketUtil.sendPacket(player, teamInfo.getCreatePacket()); } } @@ -174,7 +173,7 @@ public void initiatePlayer(Player player) { public void unloadPlayer(Player player) { if (this.thread == null) return; - for ( NameTagTeam team : registeredTeams ) { + for ( NameTagTeam team : this.teamCache.values() ) { team.destroyFor(player); } thread.addUpdate(new NameTagRemove(player.getUniqueId())); @@ -189,7 +188,7 @@ public void unloadPlayer(Player player) { public void reloadPlayer(Player toRefresh, Player refreshFor) { if (this.thread == null) return; - if (!Bukkit.isPrimaryThread()) { + if (Thread.currentThread().getName().contains("Bolt - NameTag")) { this.reloadPlayerInternal(toRefresh, refreshFor); return; } @@ -205,7 +204,7 @@ public void reloadPlayer(Player toRefresh, Player refreshFor) { public void reloadPlayer(Player toRefresh) { if (this.thread == null) return; - if (!Bukkit.isPrimaryThread()) { + if (Thread.currentThread().getName().contains("Bolt - NameTag")) { this.applyUpdate(new NameTagRefresh(toRefresh)); return; } @@ -221,7 +220,7 @@ public void reloadPlayer(Player toRefresh) { public void reloadOthersFor(Player refreshFor) { if (this.thread == null) return; - if (!Bukkit.isPrimaryThread()) { + if (Thread.currentThread().getName().contains("Bolt - NameTag")) { for (Player toRefresh : Bukkit.getOnlinePlayers()) { if (refreshFor == toRefresh) continue; this.reloadPlayerInternal(toRefresh, refreshFor); @@ -239,9 +238,6 @@ public void reloadOthersFor(Player refreshFor) { * @param nameTagRefresh {@link NameTagRefresh} update */ public void applyUpdate(NameTagRefresh nameTagRefresh) { - if (nameTagRefresh.getToRefresh() == null) return; - - Player toRefreshPlayer = Bukkit.getPlayer(nameTagRefresh.getToRefresh()); if (nameTagRefresh.isGlobal()) { Player refreshFor = Bukkit.getPlayer(nameTagRefresh.getRefreshFor()); for (Player player : Bukkit.getOnlinePlayers()) { @@ -250,6 +246,7 @@ public void applyUpdate(NameTagRefresh nameTagRefresh) { return; } + Player toRefreshPlayer = Bukkit.getPlayer(nameTagRefresh.getToRefresh()); if (toRefreshPlayer == null) { return; } @@ -271,15 +268,19 @@ public void reloadPlayerInternal(Player toRefresh, Player refreshFor) { NameTagTeam provided = this.adapter.fetchNameTag(toRefresh, refreshFor); if (provided == null) return; - //TODO: Sort Priority system, by sending remove packets!! - if (VersionUtil.MINOR_VERSION > 8) { - WrapperPlayServerTeams packet = new WrapperPlayServerTeams(provided.getName(), WrapperPlayServerTeams.TeamMode.ADD_ENTITIES, (WrapperPlayServerTeams.ScoreBoardTeamInfo) null, toRefresh.getName()); - PacketUtil.sendPacket(refreshFor, packet); - } else { - Object packet = ScoreboardPacket.additionPacket(provided.getName(), Collections.singletonList(toRefresh.getName())); - ScoreboardPacket.deliverPacket(refreshFor, packet); + Map teamInfoMap = this.teamMap.computeIfAbsent(refreshFor.getUniqueId(), (t) -> new HashMap<>()); + + // Don't spam repeat the same NameTag to the client + // Netty wakeup calls are expensive!! + String previousName = teamInfoMap.get(toRefresh.getUniqueId()); + NameTagTeam previous = previousName == null ? null : this.getByName(previousName); + if (previous != null && previous.getSuffix().equals(provided.getSuffix()) && previous.getPrefix().equals(provided.getPrefix())) { + return; } + WrapperPlayServerTeams packet = new WrapperPlayServerTeams(ColorUtil.color(provided.getName()), WrapperPlayServerTeams.TeamMode.ADD_ENTITIES, (WrapperPlayServerTeams.ScoreBoardTeamInfo) null, toRefresh.getName()); + PacketUtil.sendPacket(refreshFor, packet); + // In 1.16, the issue arises that hex color does not apply to the name of the player. // This is due to the ScoreboardTeam color being applied to the name, which is a plain enum with normal colors. // It does not support Hex Colors, for Teams, I get the nearest ChatColor to the hex color but for displaying in tablist, @@ -315,13 +316,10 @@ public void reloadPlayerInternal(Player toRefresh, Player refreshFor) { } // Update and store the new team for this target according to the viewer - Map teamInfoMap = this.teamMap.computeIfAbsent(refreshFor.getUniqueId(), (t) -> new HashMap<>()); - teamInfoMap.put(toRefresh.getUniqueId(), provided); + teamInfoMap.put(toRefresh.getUniqueId(), provided.getName()); this.teamMap.put(refreshFor.getUniqueId(), teamInfoMap); } - private NameTagTeam cachedTeam; - /** * Get a {@link NameTagTeam} associated with the given prefix and suffix. * If we don't have one for these prefixes and suffixes, then we make one and send it to everyone. @@ -335,32 +333,41 @@ public NameTagTeam getOrCreate(String prefix, String suffix) { log.info("[NameTagAPI-Debug] Trying to fetch a team with prefix {} and suffix {}", ColorUtil.getRaw(prefix), ColorUtil.getRaw(suffix)); } - if (cachedTeam != null && cachedTeam.getPrefix().equals(prefix) && cachedTeam.getSuffix().equals(suffix)) { - return (cachedTeam); - } + // Create the unique key for caching + String key = prefix + SEPARATOR + suffix; - for ( NameTagTeam teamInfo : registeredTeams) { - if (teamInfo.getPrefix().equals(prefix) && teamInfo.getSuffix().equals(suffix)) { - return (teamInfo); - } + // Attempt to get the team from the cache + NameTagTeam team = teamCache.get(key); + if (team != null) { + return team; } - TEAM_INDEX++; + // Team doesn't exist; create a new one + TEAM_INDEX++; NameTagTeam newTeam = new NameTagTeam("boltNT" + TEAM_INDEX, prefix, suffix, collisionEnabled); - cachedTeam = newTeam; + + // Cache the newly created team + teamCache.put(key, newTeam); if (debugMode) { log.info("[NameTagAPI-Debug] Creating Team with Name: {} with Prefix {} and Suffix {}", newTeam.getName(), ColorUtil.getRaw(newTeam.getPrefix()), ColorUtil.getRaw(newTeam.getSuffix())); } - this.registeredTeams.add(newTeam); - if (VersionUtil.MINOR_VERSION > 8) { - PacketUtil.broadcast(newTeam.getPECreatePacket()); - } else { - for ( Player target : Bukkit.getOnlinePlayers() ) { - ScoreboardPacket.deliverPacket(target, newTeam.getCreatePacket()); - } - } + PacketUtil.broadcast(newTeam.getCreatePacket()); + return newTeam; } + + /** + * Get a {@link NameTagTeam} by its name. + * + * @param name The name of the team to retrieve. + * @return The {@link NameTagTeam} with the specified name, or null if not found. + */ + public NameTagTeam getByName(String name) { + return teamCache.values().stream() + .filter(team -> team.getName().equals(name)) + .findFirst() + .orElse(null); + } } \ No newline at end of file diff --git a/src/main/java/xyz/refinedev/api/nametag/listener/NameTagListener.java b/src/main/java/xyz/refinedev/api/nametag/listener/NameTagListener.java index 80d67fa..978728b 100644 --- a/src/main/java/xyz/refinedev/api/nametag/listener/NameTagListener.java +++ b/src/main/java/xyz/refinedev/api/nametag/listener/NameTagListener.java @@ -12,6 +12,7 @@ import org.bukkit.event.player.PlayerQuitEvent; import xyz.refinedev.api.nametag.NameTagHandler; +import xyz.refinedev.api.nametag.update.impl.NameTagInitiate; import xyz.refinedev.api.nametag.util.VersionUtil; import java.util.concurrent.CompletableFuture; @@ -28,34 +29,20 @@ @RequiredArgsConstructor public final class NameTagListener implements Listener { - private static boolean firstJoin; private final NameTagHandler handler; - @EventHandler(priority = EventPriority.HIGH) public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - Runnable wrapper = () -> { - if (!NameTagListener.firstJoin) { - this.handler.createTeams(player); - NameTagListener.firstJoin = true; - } else { - this.handler.initiatePlayer(player); - } - this.handler.reloadPlayer(player); - this.handler.reloadOthersFor(player); - }; - - if (VersionUtil.MINOR_VERSION < 16) { - CompletableFuture.runAsync(wrapper); - } else { - // PacketEvents or maybe even bukkit is making first join - // miss the packets, they're getting sent before the player has logged in. - // So to counter this, we simply send the packets 2 ticks later (which should be enough). - Bukkit.getScheduler().runTaskLaterAsynchronously(this.handler.getPlugin(), wrapper, 20L); - } + // PacketEvents or maybe even bukkit is making first join + // miss the packets, they're getting sent before the player has logged in. + // So to counter this, we simply send the packets 2 ticks later (which should be enough). + Bukkit.getScheduler().runTaskLater(this.handler.getPlugin(), () -> { + NameTagInitiate initiate = new NameTagInitiate(player); + this.handler.getThread().addUpdate(initiate); + }, 20L); } @EventHandler diff --git a/src/main/java/xyz/refinedev/api/nametag/setup/NameTagTeam.java b/src/main/java/xyz/refinedev/api/nametag/setup/NameTagTeam.java index a4cfeaa..afdf485 100644 --- a/src/main/java/xyz/refinedev/api/nametag/setup/NameTagTeam.java +++ b/src/main/java/xyz/refinedev/api/nametag/setup/NameTagTeam.java @@ -7,7 +7,6 @@ import lombok.Setter; import org.bukkit.entity.Player; -import xyz.refinedev.api.nametag.util.packet.ScoreboardPacket; import xyz.refinedev.api.nametag.util.chat.ColorUtil; import xyz.refinedev.api.nametag.util.packet.PacketUtil; import xyz.refinedev.api.nametag.util.VersionUtil; @@ -20,31 +19,23 @@ public class NameTagTeam { private final String name; private final String prefix; private final String suffix; - private final Object createPacket; + private final PacketWrapper createPacket; public NameTagTeam(String name, String prefix, String suffix, boolean collide) { this.name = name; this.prefix = prefix; this.suffix = suffix; - if (VersionUtil.MINOR_VERSION > 8) { - WrapperPlayServerTeams.ScoreBoardTeamInfo info = new WrapperPlayServerTeams.ScoreBoardTeamInfo( - ColorUtil.translate(name), - ColorUtil.translate(prefix), - ColorUtil.translate(suffix), - WrapperPlayServerTeams.NameTagVisibility.ALWAYS, - collide ? WrapperPlayServerTeams.CollisionRule.ALWAYS : WrapperPlayServerTeams.CollisionRule.NEVER, - ColorUtil.getLastColor(prefix), - WrapperPlayServerTeams.OptionData.NONE); - - this.createPacket = new WrapperPlayServerTeams(name, WrapperPlayServerTeams.TeamMode.CREATE, info); - } else { - this.createPacket = ScoreboardPacket.creationPacket(name, ColorUtil.color(prefix), ColorUtil.color(suffix)); - } - } + WrapperPlayServerTeams.ScoreBoardTeamInfo info = new WrapperPlayServerTeams.ScoreBoardTeamInfo( + ColorUtil.translate(name), + ColorUtil.translate(prefix), + ColorUtil.translate(suffix), + WrapperPlayServerTeams.NameTagVisibility.ALWAYS, + collide ? WrapperPlayServerTeams.CollisionRule.ALWAYS : WrapperPlayServerTeams.CollisionRule.NEVER, + VersionUtil.MINOR_VERSION <= 12 ? null : ColorUtil.getLastColor(prefix), + WrapperPlayServerTeams.OptionData.NONE); - public PacketWrapper getPECreatePacket() { - return (PacketWrapper) createPacket; + this.createPacket = new WrapperPlayServerTeams(name, WrapperPlayServerTeams.TeamMode.CREATE, info); } public void destroyFor(Player player) { diff --git a/src/main/java/xyz/refinedev/api/nametag/thread/NameTagThread.java b/src/main/java/xyz/refinedev/api/nametag/thread/NameTagThread.java index 441f1bf..c419251 100644 --- a/src/main/java/xyz/refinedev/api/nametag/thread/NameTagThread.java +++ b/src/main/java/xyz/refinedev/api/nametag/thread/NameTagThread.java @@ -1,13 +1,16 @@ package xyz.refinedev.api.nametag.thread; +import com.google.common.util.concurrent.ThreadFactoryBuilder; + import lombok.Getter; import lombok.extern.log4j.Log4j2; import xyz.refinedev.api.nametag.NameTagHandler; import xyz.refinedev.api.nametag.update.NameTagUpdate; -import xyz.refinedev.api.nametag.util.collection.CachedSizeConcurrentLinkedQueue; +import java.util.Comparator; import java.util.Queue; +import java.util.concurrent.*; /** * This Project is property of Refine Development. @@ -18,20 +21,38 @@ * @since 9/12/2023 * @version NameTagAPI */ -@Getter @Log4j2 -public class NameTagThread extends Thread { +@Getter +@Log4j2 +public class NameTagThread { - private final Queue updatesQueue = new CachedSizeConcurrentLinkedQueue<>(); + private final Queue updatesQueue = new PriorityBlockingQueue<>(11, Comparator.comparingInt(NameTagUpdate::getPriority).reversed()); private volatile boolean running = true; private final NameTagHandler handler; private final long ticks; - public NameTagThread(NameTagHandler nameTagHandler, long ticks) { - super(nameTagHandler.getPlugin().getName() + " - NameTag Thread"); + // Executor services for scheduling and update processing + private final ScheduledExecutorService scheduler; + private final ExecutorService updateExecutor; + public NameTagThread(NameTagHandler nameTagHandler, long ticks) { this.handler = nameTagHandler; this.ticks = ticks; + + ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Bolt - NameTag-%d") + .setPriority(Thread.NORM_PRIORITY - 1) + .setDaemon(true) + .setUncaughtExceptionHandler((a, e) -> { + log.fatal("[{}] There was an error in the Thread {}.", handler.getPlugin().getName(), a.getName()); + log.error(e); + }) + .build(); + + this.scheduler = Executors.newSingleThreadScheduledExecutor(threadFactory); + this.updateExecutor = Executors.newFixedThreadPool(2, threadFactory); + + // Schedule the periodic task to process updates + scheduler.scheduleAtFixedRate(this::tick, 0, ticks * 50, TimeUnit.MILLISECONDS); } /** @@ -43,39 +64,31 @@ public void addUpdate(NameTagUpdate update) { this.updatesQueue.add(update); } - /** - * Tick this thread to start running the queued updates. - */ - private void tick() { - while (this.updatesQueue.size() > 0) { - NameTagUpdate pendingUpdate = this.updatesQueue.poll(); - - try { - pendingUpdate.update(handler); - } catch (Exception e) { - log.fatal("[{}] There was an error issuing NameTagUpdate.", handler.getPlugin().getName()); - log.error(e); - e.printStackTrace(); - } - } - } - /** * Stop executing this thread. */ public void stopExecuting() { this.running = false; + scheduler.shutdown(); + updateExecutor.shutdown(); } - @Override - public void run() { - while (running) { - try { - this.tick(); - Thread.sleep(ticks * 50); - } catch (InterruptedException e) { - this.stopExecuting(); + /** + * Tick this thread to start running the queued updates. + */ + private void tick() { + while (running && !updatesQueue.isEmpty()) { + NameTagUpdate pendingUpdate = updatesQueue.poll(); + if (pendingUpdate != null) { + updateExecutor.submit(() -> { + try { + pendingUpdate.update(handler); + } catch (Exception e) { + log.fatal("[{}] There was an error issuing NameTagUpdate.", handler.getPlugin().getName()); + log.error(e); + } + }); } } } -} \ No newline at end of file +} diff --git a/src/main/java/xyz/refinedev/api/nametag/update/NameTagUpdate.java b/src/main/java/xyz/refinedev/api/nametag/update/NameTagUpdate.java index 64b792d..031fdb5 100644 --- a/src/main/java/xyz/refinedev/api/nametag/update/NameTagUpdate.java +++ b/src/main/java/xyz/refinedev/api/nametag/update/NameTagUpdate.java @@ -20,4 +20,6 @@ public interface NameTagUpdate { */ void update(NameTagHandler nameTagHandler); + int getPriority(); + } diff --git a/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagInitiate.java b/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagInitiate.java new file mode 100644 index 0000000..9b17184 --- /dev/null +++ b/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagInitiate.java @@ -0,0 +1,38 @@ +package xyz.refinedev.api.nametag.update.impl; + +import lombok.RequiredArgsConstructor; +import org.bukkit.entity.Player; +import xyz.refinedev.api.nametag.NameTagHandler; +import xyz.refinedev.api.nametag.update.NameTagUpdate; + +/** + *

+ * This Project is property of Refine Development.
+ * Copyright © 2024, All Rights Reserved.
+ * Redistribution of this Project is not allowed.
+ *

+ * + * @author Drizzy + * @version NameTagAPI + * @since 9/16/2024 + */ + +@RequiredArgsConstructor +public class NameTagInitiate implements NameTagUpdate { + + private final Player target; + + /** + * Apply this name-tag update. + */ + public void update(NameTagHandler nameTagHandler) { + nameTagHandler.initiatePlayer(target); + nameTagHandler.reloadPlayer(target); + nameTagHandler.reloadOthersFor(target); + } + + @Override + public int getPriority() { + return 69; + } +} diff --git a/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRefresh.java b/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRefresh.java index 06a19c7..9411684 100644 --- a/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRefresh.java +++ b/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRefresh.java @@ -44,4 +44,8 @@ public NameTagRefresh(Player toRefresh, Player refreshFor) { public void update(NameTagHandler nameTagHandler) { nameTagHandler.applyUpdate(this); } + + public int getPriority() { + return 5; + } } \ No newline at end of file diff --git a/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRemove.java b/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRemove.java index 5ea6f69..af571e5 100644 --- a/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRemove.java +++ b/src/main/java/xyz/refinedev/api/nametag/update/impl/NameTagRemove.java @@ -29,4 +29,9 @@ public class NameTagRemove implements NameTagUpdate { public void update(NameTagHandler nameTagHandler) { nameTagHandler.getTeamMap().remove(toRemove); } + + @Override + public int getPriority() { + return 1; + } } diff --git a/src/main/java/xyz/refinedev/api/nametag/util/chat/ColorUtil.java b/src/main/java/xyz/refinedev/api/nametag/util/chat/ColorUtil.java index ac0fc56..a860f2f 100644 --- a/src/main/java/xyz/refinedev/api/nametag/util/chat/ColorUtil.java +++ b/src/main/java/xyz/refinedev/api/nametag/util/chat/ColorUtil.java @@ -148,7 +148,7 @@ public String color(String text) { * @return {@link Component} */ public Component translate(String string) { - return AdventureSerializer.fromLegacyFormat(color(string)); + return Component.text(color(string)); } public String getRaw(String string) { diff --git a/src/main/java/xyz/refinedev/api/nametag/util/collection/CachedSizeConcurrentLinkedQueue.java b/src/main/java/xyz/refinedev/api/nametag/util/collection/CachedSizeConcurrentLinkedQueue.java deleted file mode 100644 index 1734f3e..0000000 --- a/src/main/java/xyz/refinedev/api/nametag/util/collection/CachedSizeConcurrentLinkedQueue.java +++ /dev/null @@ -1,42 +0,0 @@ -package xyz.refinedev.api.nametag.util.collection; - -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.LongAdder; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class CachedSizeConcurrentLinkedQueue extends ConcurrentLinkedQueue { - - private final AtomicLong cachedSize = new AtomicLong(); - - @Override - public boolean add(@NotNull E e) { - boolean result = super.add(e); - if (result) { - cachedSize.incrementAndGet(); - } - return result; - } - - @Nullable - @Override - public E poll() { - E result = super.poll(); - if (result != null) { - cachedSize.decrementAndGet(); - } - return result; - } - - @Override - public int size() { - return cachedSize.intValue(); - } - - @Override - public void clear() { - super.clear(); - cachedSize.set(0); - } -} \ No newline at end of file diff --git a/src/main/java/xyz/refinedev/api/nametag/util/packet/ScoreboardPacket.java b/src/main/java/xyz/refinedev/api/nametag/util/packet/ScoreboardPacket.java deleted file mode 100644 index 2ef33af..0000000 --- a/src/main/java/xyz/refinedev/api/nametag/util/packet/ScoreboardPacket.java +++ /dev/null @@ -1,155 +0,0 @@ -package xyz.refinedev.api.nametag.util.packet; - -import lombok.Getter; - -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.minecraft.server.v1_8_R3.Packet; -import net.minecraft.server.v1_8_R3.PacketPlayOutScoreboardTeam; - -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; -import org.bukkit.entity.Player; - -import xyz.refinedev.api.nametag.util.chat.ColorUtil; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Field; -import java.util.Collection; - -/** - * This Project is property of Refine Development. - * Copyright © 2023, All Rights Reserved. - * Redistribution of this Project is not allowed. - * - * @author Drizzy - * @since 9/12/2023 - * @version NameTagAPI - */ - -@Getter -public class ScoreboardPacket { - - // 0 - create - // 1 - remove - // 2 - update - // 3 - add entities - // 4 - remove entities - - public static Object creationPacket(String name, String prefix, String suffix) { - if (prefix.length() > 16) { - prefix = prefix.substring(0, 16); - } - if (suffix.length() > 16) { - suffix = suffix.substring(0, 16); - } - - PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam(); - - try { - protocolValue.invokeExact(packet, 0); - - teamName.invokeExact(packet, name); - teamDisplayName.invokeExact(packet, name); - teamPrefix.invokeExact(packet, ColorUtil.color(prefix)); - teamSuffix.invokeExact(packet, ColorUtil.color(suffix)); - nameTagRule.invokeExact(packet, "always"); - optionData.invokeExact(packet, 1); - } catch (Throwable e) { - Bukkit.getLogger().info("[NameTagAPI] Failed to create packet for removing!"); - e.printStackTrace(); - } - - return packet; - } - - public static Object additionPacket(String name, Collection players) { - PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam(); - - try { - teamName.invokeExact(packet, name); - protocolValue.invokeExact(packet, 3); - playerNames.invokeExact(packet, players); - } catch (Throwable e) { - Bukkit.getLogger().info("[NameTagAPI] Failed to create packet for removing!"); - e.printStackTrace(); - } - - return packet; - } - - public static Object removalPacket(String name) { - PacketPlayOutScoreboardTeam packet = new PacketPlayOutScoreboardTeam(); - - try { - teamName.invokeExact(packet, name); - protocolValue.invoke(packet, 1); - } catch (Throwable e) { - Bukkit.getLogger().info("[NameTagAPI] Failed to create packet for removing!"); - e.printStackTrace(); - } - - return packet; - } - - public static void deliverPacket(Player target, Object object) { - if (!(object instanceof Packet)) { - throw new IllegalStateException("[NameTagAPI] Tried to send an invalid object as packet!"); - } - - EntityPlayer entityPlayer = ((CraftPlayer)target).getHandle(); - entityPlayer.playerConnection.sendPacket((Packet) object); - } - - private static final boolean SUPPORTED; - private static final Class PACKET_CLASS; - private static final MethodHandle protocolValue; - private static final MethodHandle teamName, teamDisplayName, teamPrefix, teamSuffix; - private static final MethodHandle nameTagRule, optionData; - private static final MethodHandle playerNames; - - static { - try { - PACKET_CLASS = PacketPlayOutScoreboardTeam.class; - - MethodHandles.Lookup lookup = MethodHandles.publicLookup(); - - Field name = PACKET_CLASS.getDeclaredField("a"); - name.setAccessible(true); - - Field displayName = PACKET_CLASS.getDeclaredField("b"); - displayName.setAccessible(true); - - Field prefix = PACKET_CLASS.getDeclaredField("c"); - prefix.setAccessible(true); - - Field suffix = PACKET_CLASS.getDeclaredField("d"); - suffix.setAccessible(true); - - Field nameTag = PACKET_CLASS.getDeclaredField("e"); - nameTag.setAccessible(true); - - Field protocol = PACKET_CLASS.getDeclaredField("h"); - protocol.setAccessible(true); - - Field list = PACKET_CLASS.getDeclaredField("g"); - list.setAccessible(true); - - Field data = PACKET_CLASS.getDeclaredField("i"); - data.setAccessible(true); - - teamName = lookup.unreflectSetter(name); - teamDisplayName = lookup.unreflectSetter(displayName); - teamPrefix = lookup.unreflectSetter(prefix); - teamSuffix = lookup.unreflectSetter(suffix); - nameTagRule = lookup.unreflectSetter(nameTag); - protocolValue = lookup.unreflectSetter(protocol); - playerNames = lookup.unreflectSetter(list); - optionData = lookup.unreflectSetter(data); - - SUPPORTED = true; - } catch (Exception e) { - throw new IllegalArgumentException(e); - } - } -}