diff --git a/src/main/java/net/william278/velocitab/config/Placeholder.java b/src/main/java/net/william278/velocitab/config/Placeholder.java index 6153108..8007f65 100644 --- a/src/main/java/net/william278/velocitab/config/Placeholder.java +++ b/src/main/java/net/william278/velocitab/config/Placeholder.java @@ -28,7 +28,7 @@ public enum Placeholder { PREFIX((plugin, player) -> player.getRole().getPrefix().orElse("")), SUFFIX((plugin, player) -> player.getRole().getSuffix().orElse("")), ROLE((plugin, player) -> player.getRole().getName().orElse("")), - DEBUG_TEAM_NAME((plugin, player) -> plugin.getFormatter().escape(player.getTeamName())); + DEBUG_TEAM_NAME((plugin, player) -> plugin.getFormatter().escape(player.getTeamName(plugin))); /** * Function to replace placeholders with a real value diff --git a/src/main/java/net/william278/velocitab/config/Settings.java b/src/main/java/net/william278/velocitab/config/Settings.java index 8e8f764..35b929c 100644 --- a/src/main/java/net/william278/velocitab/config/Settings.java +++ b/src/main/java/net/william278/velocitab/config/Settings.java @@ -1,11 +1,11 @@ package net.william278.velocitab.config; - import lombok.Getter; import net.william278.annotaml.YamlComment; import net.william278.annotaml.YamlFile; import net.william278.annotaml.YamlKey; import net.william278.velocitab.Velocitab; +import net.william278.velocitab.player.TabPlayer; import org.apache.commons.text.StringEscapeUtils; import org.jetbrains.annotations.NotNull; @@ -56,6 +56,13 @@ public class Settings { @YamlComment("If you are using MINIMESSAGE formatting, enable this to support MiniPlaceholders in formatting.") private boolean enableMiniPlaceholdersHook = true; + @YamlKey("sort_players_by") + @YamlComment("Ordered list of elements by which players should be sorted. (ROLE_WEIGHT, ROLE_NAME and SERVER are supported)") + private List sortPlayersBy = List.of( + TabPlayer.SortableElement.ROLE_WEIGHT, + TabPlayer.SortableElement.ROLE_NAME + ); + @YamlKey("update_rate") @YamlComment("How often to periodically update the TAB list, including header and footer, for all users.\nWill only update on player join/leave if set to 0.") private int updateRate = 0; @@ -109,6 +116,11 @@ public class Settings { return enableMiniPlaceholdersHook; } + @NotNull + public List getSortingElementList() { + return sortPlayersBy; + } + public int getUpdateRate() { return updateRate; } diff --git a/src/main/java/net/william278/velocitab/player/TabPlayer.java b/src/main/java/net/william278/velocitab/player/TabPlayer.java index 75f54d2..5f71a77 100644 --- a/src/main/java/net/william278/velocitab/player/TabPlayer.java +++ b/src/main/java/net/william278/velocitab/player/TabPlayer.java @@ -8,6 +8,8 @@ import net.william278.velocitab.tab.PlayerTabList; import org.jetbrains.annotations.NotNull; import java.util.concurrent.CompletableFuture; +import java.util.function.BiFunction; +import java.util.stream.Collectors; public final class TabPlayer implements Comparable { private final Player player; @@ -34,7 +36,7 @@ public final class TabPlayer implements Comparable { public String getServerName() { return player.getCurrentServer() .map(serverConnection -> serverConnection.getServerInfo().getName()) - .orElse("Unknown"); + .orElse("unknown"); } @NotNull @@ -46,8 +48,10 @@ public final class TabPlayer implements Comparable { } @NotNull - public String getTeamName() { - return role.getWeightString(highestWeight) + role.getName().map(name -> "-" + name).orElse(""); + public String getTeamName(@NotNull Velocitab plugin) { + return plugin.getSettings().getSortingElementList().stream() + .map(element -> element.resolve(this, plugin)) + .collect(Collectors.joining("-")); } public void sendHeaderAndFooter(@NotNull PlayerTabList tabList) { @@ -68,4 +72,28 @@ public final class TabPlayer implements Comparable { public boolean equals(Object obj) { return obj instanceof TabPlayer other && player.getUniqueId().equals(other.player.getUniqueId()); } + + /** + * Elements for sorting players + */ + @SuppressWarnings("unused") + public enum SortableElement { + ROLE_WEIGHT((player, plugin) -> player.getRole().getWeightString(player.highestWeight)), + ROLE_NAME((player, plugin) -> player.getRole().getName() + .map(name -> name.length() > 3 ? name.substring(0, 3) : name) + .orElse("")), + SERVER_NAME((player, plugin) -> player.getServerName()); + + private final BiFunction elementResolver; + + SortableElement(@NotNull BiFunction elementResolver) { + this.elementResolver = elementResolver; + } + + @NotNull + private String resolve(@NotNull TabPlayer tabPlayer, @NotNull Velocitab plugin) { + return elementResolver.apply(tabPlayer, plugin); + } + } + } diff --git a/src/main/java/net/william278/velocitab/tab/PlayerTabList.java b/src/main/java/net/william278/velocitab/tab/PlayerTabList.java index 2261a72..bec082b 100644 --- a/src/main/java/net/william278/velocitab/tab/PlayerTabList.java +++ b/src/main/java/net/william278/velocitab/tab/PlayerTabList.java @@ -76,7 +76,7 @@ public class PlayerTabList { if (serversInGroup.isPresent() && !serversInGroup.get().contains(player.getServerName())) { continue; // Skip players on other servers } - playerRoles.put(player.getPlayer().getUsername(), player.getTeamName()); + playerRoles.put(player.getPlayer().getUsername(), player.getTeamName(plugin)); tabList.getEntries().stream() .filter(e -> e.getProfile().getId().equals(player.getPlayer().getUniqueId())).findFirst() .ifPresentOrElse( @@ -118,7 +118,7 @@ public class PlayerTabList { ); plugin.getScoreboardManager().updateRoles( player.getPlayer(), - newPlayer.getTeamName(), + newPlayer.getTeamName(plugin), newPlayer.getPlayer().getUsername() ); } @@ -147,7 +147,7 @@ public class PlayerTabList { .filter(e -> e.getProfile().getId().equals(tabPlayer.getPlayer().getUniqueId())).findFirst() .ifPresent(entry -> entry.setDisplayName(displayName)); plugin.getScoreboardManager().updateRoles(player.getPlayer(), - tabPlayer.getTeamName(), tabPlayer.getPlayer().getUsername()); + tabPlayer.getTeamName(plugin), tabPlayer.getPlayer().getUsername()); })); }