From f616a5e08a12111bd13df66e4b433aad2182af5a Mon Sep 17 00:00:00 2001 From: William Date: Mon, 20 Feb 2023 02:23:25 +0000 Subject: [PATCH] Fix weight sort order, team color, CME when updating players, players not updating via LP --- .../net/william278/velocitab/Velocitab.java | 5 +-- .../velocitab/luckperms/LuckPermsHook.java | 31 +++++++++++++--- .../velocitab/packet/UpdateTeamsPacket.java | 2 +- .../net/william278/velocitab/player/Role.java | 24 ++++++++++--- .../velocitab/player/TabPlayer.java | 6 ++-- .../velocitab/tab/PlayerTabList.java | 36 ++++++++++--------- 6 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/main/java/net/william278/velocitab/Velocitab.java b/src/main/java/net/william278/velocitab/Velocitab.java index 34090a5..e2296e7 100644 --- a/src/main/java/net/william278/velocitab/Velocitab.java +++ b/src/main/java/net/william278/velocitab/Velocitab.java @@ -92,7 +92,6 @@ public class Velocitab { // If LuckPerms is present, load the hook try { luckPerms = new LuckPermsHook(this); - server.getEventManager().register(this, luckPerms); logger.info("Successfully hooked into LuckPerms"); } catch (IllegalArgumentException e) { logger.warn("LuckPerms was not loaded: " + e.getMessage(), e); @@ -116,7 +115,7 @@ public class Velocitab { private void prepareTabList() { this.tabList = new PlayerTabList(this); - server.getEventManager().register(this, new PlayerTabList(this)); + server.getEventManager().register(this, tabList); } @NotNull @@ -126,6 +125,8 @@ public class Velocitab { getLuckPerms().map(hook -> hook.getPlayerRole(player)) .orElse(Role.DEFAULT_ROLE), getLuckPerms().map(LuckPermsHook::getHighestWeight) + .orElse(0), + getLuckPerms().map(LuckPermsHook::getLowestWeight) .orElse(0)); } diff --git a/src/main/java/net/william278/velocitab/luckperms/LuckPermsHook.java b/src/main/java/net/william278/velocitab/luckperms/LuckPermsHook.java index 1aba5de..06501b2 100644 --- a/src/main/java/net/william278/velocitab/luckperms/LuckPermsHook.java +++ b/src/main/java/net/william278/velocitab/luckperms/LuckPermsHook.java @@ -1,6 +1,5 @@ package net.william278.velocitab.luckperms; -import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.proxy.Player; import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPermsProvider; @@ -10,6 +9,7 @@ import net.luckperms.api.model.group.Group; import net.luckperms.api.model.user.User; import net.william278.velocitab.Velocitab; import net.william278.velocitab.player.Role; +import net.william278.velocitab.player.TabPlayer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,17 +19,23 @@ import java.util.UUID; public class LuckPermsHook { private int highestWeight = Role.DEFAULT_WEIGHT; + private int lowestWeight = Role.DEFAULT_WEIGHT; private final Velocitab plugin; private final LuckPerms api; public LuckPermsHook(@NotNull Velocitab plugin) throws IllegalStateException { this.plugin = plugin; this.api = LuckPermsProvider.get(); + api.getEventBus().subscribe(plugin, UserDataRecalculateEvent.class, this::onLuckPermsGroupUpdate); } @NotNull public Role getPlayerRole(@NotNull Player player) { - final CachedMetaData metaData = getUser(player.getUniqueId()).getCachedData().getMetaData(); + return getRoleFromMetadata(getUser(player.getUniqueId()).getCachedData().getMetaData()); + } + + @NotNull + private Role getRoleFromMetadata(@NotNull CachedMetaData metaData) { if (metaData.getPrimaryGroup() == null) { return Role.DEFAULT_ROLE; } @@ -41,10 +47,14 @@ public class LuckPermsHook { ); } - @Subscribe public void onLuckPermsGroupUpdate(@NotNull UserDataRecalculateEvent event) { plugin.getServer().getPlayer(event.getUser().getUniqueId()) - .ifPresent(player -> plugin.getTabList().updatePlayer(plugin.getTabPlayer(player))); + .ifPresent(player -> plugin.getTabList().updatePlayer(new TabPlayer( + player, + getRoleFromMetadata(event.getData().getMetaData()), + getHighestWeight(), + getLowestWeight() + ))); } private OptionalInt getWeight(@Nullable String groupName) { @@ -67,9 +77,22 @@ public class LuckPermsHook { return highestWeight; } + public int getLowestWeight() { + if (lowestWeight == Role.DEFAULT_WEIGHT) { + api.getGroupManager().getLoadedGroups().forEach(group -> { + final OptionalInt weight = group.getWeight(); + if (weight.isPresent() && weight.getAsInt() < lowestWeight) { + lowestWeight = weight.getAsInt(); + } + }); + } + return lowestWeight; + } + private User getUser(@NotNull UUID uuid) { return api.getUserManager().getUser(uuid); } + } diff --git a/src/main/java/net/william278/velocitab/packet/UpdateTeamsPacket.java b/src/main/java/net/william278/velocitab/packet/UpdateTeamsPacket.java index 71c53ba..0465164 100644 --- a/src/main/java/net/william278/velocitab/packet/UpdateTeamsPacket.java +++ b/src/main/java/net/william278/velocitab/packet/UpdateTeamsPacket.java @@ -55,7 +55,7 @@ public class UpdateTeamsPacket extends AbstractPacket { updateTeamsPacket.friendlyFlags(List.of(FriendlyFlag.CAN_HURT_FRIENDLY)); updateTeamsPacket.nameTagVisibility(NameTagVisibility.ALWAYS); updateTeamsPacket.collisionRule(CollisionRule.ALWAYS); - updateTeamsPacket.color(0); + updateTeamsPacket.color(15); updateTeamsPacket.prefix(getChatString("")); updateTeamsPacket.suffix(getChatString("")); updateTeamsPacket.entities(List.of(member)); diff --git a/src/main/java/net/william278/velocitab/player/Role.java b/src/main/java/net/william278/velocitab/player/Role.java index 65b6a53..4ee731a 100644 --- a/src/main/java/net/william278/velocitab/player/Role.java +++ b/src/main/java/net/william278/velocitab/player/Role.java @@ -40,9 +40,25 @@ public class Role implements Comparable { return Optional.ofNullable(name); } - @NotNull - public String getStringComparableWeight(int highestWeight) { - return String.format("%0" + (highestWeight + "").length() + "d", weight); - //return String.format("%0" + (highestWeight + "").length() + "d", highestWeight - weight); + public String getStringComparableWeight(int maximumPossibleWeight, int lowestPossibleWeight) { + // Calculate the weight range and the ratio of the input weight to the weight range + int weightRange = maximumPossibleWeight - lowestPossibleWeight; + double weightRatio = (double) (maximumPossibleWeight - weight) / weightRange; + + // Convert the weight ratio to a string with 3 decimal places and remove the decimal point + String weightString = String.format("%.3f", weightRatio).replace(".", ""); + + // Pad the weight string with leading zeros to a length of 6 characters + weightString = String.format("%6s", weightString).replace(' ', '0'); + + // Prepend a minus sign for negative weights + if (weight < 0) { + weightString = "-" + weightString.substring(1); + } else { + // Reverse the weight string for non-negative weights + weightString = new StringBuilder(weightString).reverse().toString(); + } + + return weightString; } } diff --git a/src/main/java/net/william278/velocitab/player/TabPlayer.java b/src/main/java/net/william278/velocitab/player/TabPlayer.java index 844831f..2aa2bd0 100644 --- a/src/main/java/net/william278/velocitab/player/TabPlayer.java +++ b/src/main/java/net/william278/velocitab/player/TabPlayer.java @@ -12,11 +12,13 @@ public final class TabPlayer implements Comparable { private final Player player; private final Role role; private final int highestWeight; + private final int lowestWeight; - public TabPlayer(@NotNull Player player, @NotNull Role role, int highestWeight) { + public TabPlayer(@NotNull Player player, @NotNull Role role, int highestWeight, int lowestWeight) { this.player = player; this.role = role; this.highestWeight = highestWeight; + this.lowestWeight = lowestWeight; } @NotNull @@ -43,7 +45,7 @@ public final class TabPlayer implements Comparable { @NotNull public String getTeamName() { - return role.getStringComparableWeight(highestWeight) + "-" + getServerName() + "-" + player.getUsername(); + return role.getStringComparableWeight(highestWeight, lowestWeight) + "-" + getServerName() + "-" + player.getUsername(); } public void sendHeaderAndFooter(@NotNull PlayerTabList tabList) { diff --git a/src/main/java/net/william278/velocitab/tab/PlayerTabList.java b/src/main/java/net/william278/velocitab/tab/PlayerTabList.java index ee53e03..d634b7f 100644 --- a/src/main/java/net/william278/velocitab/tab/PlayerTabList.java +++ b/src/main/java/net/william278/velocitab/tab/PlayerTabList.java @@ -1,5 +1,6 @@ package net.william278.velocitab.tab; +import com.google.common.collect.ImmutableList; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.player.ServerPostConnectEvent; @@ -46,36 +47,39 @@ public class PlayerTabList { players.removeIf(player -> player.getPlayer().getUniqueId().equals(event.getPlayer().getUniqueId())); // Remove the player from the tab list of all other players - plugin.getScoreboardManager().removeTeam(event.getPlayer()); - plugin.getServer().getAllPlayers().forEach(player -> { - if (player.getTabList().containsEntry(event.getPlayer().getUniqueId())) { - player.getTabList().removeEntry(event.getPlayer().getUniqueId()); - } - }); + plugin.getServer().getAllPlayers().forEach(player -> player.getTabList().removeEntry(event.getPlayer().getUniqueId())); // Update the tab list of all players - plugin.getServer().getScheduler().buildTask(plugin, this::updateList) + plugin.getServer().getScheduler().buildTask(plugin, () -> { + plugin.getScoreboardManager().removeTeam(event.getPlayer()); + updateList(); + }) .delay(500, TimeUnit.MILLISECONDS) .schedule(); } public void updatePlayer(@NotNull TabPlayer tabPlayer) { - // Remove the existing player from the tracking list - players.removeIf(player -> player.getPlayer().getUniqueId().equals(tabPlayer.getPlayer().getUniqueId())); + plugin.getServer().getScheduler() + .buildTask(plugin, () -> { + // Remove the existing player from the tracking list + players.replaceAll(player -> { + if (player.getPlayer().getUniqueId().equals(tabPlayer.getPlayer().getUniqueId())) { + return tabPlayer; + } + return player; + }); - // Add the player to the tracking list - players.add(tabPlayer); + // Update the player's team sorting + plugin.getScoreboardManager().setPlayerTeam(tabPlayer); - // Update the player's team sorting - plugin.getScoreboardManager().removeTeam(tabPlayer.getPlayer()); - - // Update the tab list of all players - plugin.getServer().getScheduler().buildTask(plugin, this::updateList) + updateList(); + }) .delay(500, TimeUnit.MILLISECONDS) .schedule(); } private void updateList() { + final ImmutableList players = ImmutableList.copyOf(this.players); players.forEach(player -> { player.sendHeaderAndFooter(this); player.getPlayer().getTabList().getEntries()