diff --git a/src/main/java/net/william278/velocitab/config/Settings.java b/src/main/java/net/william278/velocitab/config/Settings.java index d2f4c8c..4d8755e 100644 --- a/src/main/java/net/william278/velocitab/config/Settings.java +++ b/src/main/java/net/william278/velocitab/config/Settings.java @@ -59,7 +59,7 @@ public class Settings { @Getter @YamlKey("server_display_names") @YamlComment("Define custom names to be shown in the TAB list for specific server names.\n" + - "If no custom display name is provided for a server, its original name will be used.") + "If no custom display name is provided for a server, its original name will be used.") private Map serverDisplayNames = Map.of("very-long-server-name", "VLSN"); @YamlKey("enable_papi_hook") @@ -77,7 +77,8 @@ public class Settings { ); @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.") + @YamlComment("How often in milliseconds to periodically update the TAB list, including header and footer, for all users.\n" + + "If set to 0, TAB will be updated on player join/leave instead. (1s = 1000ms)") private int updateRate = 0; public Settings(@NotNull Velocitab plugin) { @@ -92,14 +93,16 @@ public class Settings { @NotNull public String getHeader(@NotNull String serverGroup, int index) { - return StringEscapeUtils.unescapeJava( - headers.getOrDefault(serverGroup, List.of("")).get(index)); + final List groupHeaders = headers.getOrDefault(serverGroup, List.of("")); + return groupHeaders.isEmpty() ? "" : StringEscapeUtils.unescapeJava(groupHeaders + .get(Math.max(0, Math.min(index, getHeaderListSize(serverGroup) - 1)))); } @NotNull public String getFooter(@NotNull String serverGroup, int index) { - return StringEscapeUtils.unescapeJava( - footers.getOrDefault(serverGroup, List.of("")).get(index)); + final List groupFooters = footers.getOrDefault(serverGroup, List.of("")); + return groupFooters.isEmpty() ? "" : StringEscapeUtils.unescapeJava(groupFooters + .get(Math.max(0, Math.min(index, getFooterListSize(serverGroup) - 1)))); } public int getHeaderListSize(@NotNull String serverGroup) { @@ -137,7 +140,8 @@ public class Settings { public String getServerGroup(String serverName) { return serverGroups.entrySet().stream() .filter(entry -> entry.getValue().contains(serverName)).findFirst() - .map(Map.Entry::getKey).orElse(fallbackGroup); + .map(Map.Entry::getKey) + .orElse(fallbackGroup); } public boolean isPapiHookEnabled() { diff --git a/src/main/java/net/william278/velocitab/player/TabPlayer.java b/src/main/java/net/william278/velocitab/player/TabPlayer.java index a2c4a81..649ccce 100644 --- a/src/main/java/net/william278/velocitab/player/TabPlayer.java +++ b/src/main/java/net/william278/velocitab/player/TabPlayer.java @@ -17,6 +17,8 @@ public final class TabPlayer implements Comparable { private final Player player; private final Role role; private final int highestWeight; + private int headerIndex = 0; + private int footerIndex = 0; public TabPlayer(@NotNull Player player, @NotNull Role role, int highestWeight) { this.player = player; @@ -47,6 +49,16 @@ public final class TabPlayer implements Comparable { .orElse("unknown"); } + /** + * Get the TAB server group this player is connected to + * @param plugin instance of the {@link Velocitab} plugin + * @return the name of the server group the player is on + */ + @NotNull + public String getServerGroup(@NotNull Velocitab plugin) { + return plugin.getSettings().getServerGroup(this.getServerName()); + } + /** * Get the display name of the server the player is currently on. * Affected by server aliases defined in the config. @@ -79,6 +91,30 @@ public final class TabPlayer implements Comparable { .thenAccept(footer -> player.sendPlayerListHeaderAndFooter(header, footer))); } + public int getHeaderIndex() { + return headerIndex; + } + + public void incrementHeaderIndex(@NotNull Velocitab plugin) { + if (headerIndex >= plugin.getSettings().getHeaderListSize(getServerGroup(plugin))) { + headerIndex = 0; + return; + } + headerIndex++; + } + + public int getFooterIndex() { + return footerIndex; + } + + public void incrementFooterIndex(@NotNull Velocitab plugin) { + if (footerIndex >= plugin.getSettings().getFooterListSize(getServerGroup(plugin))) { + footerIndex = 0; + return; + } + footerIndex++; + } + @Override public int compareTo(@NotNull TabPlayer o) { final int roleDifference = role.compareTo(o.role); diff --git a/src/main/java/net/william278/velocitab/tab/PlayerTabList.java b/src/main/java/net/william278/velocitab/tab/PlayerTabList.java index 1d265ea..df98fe3 100644 --- a/src/main/java/net/william278/velocitab/tab/PlayerTabList.java +++ b/src/main/java/net/william278/velocitab/tab/PlayerTabList.java @@ -26,8 +26,6 @@ public class PlayerTabList { private final Velocitab plugin; private final ConcurrentLinkedQueue players; private final ConcurrentLinkedQueue fallbackServers; - private int headerIndex = 0; - private int footerIndex = 0; public PlayerTabList(@NotNull Velocitab plugin) { this.plugin = plugin; @@ -77,7 +75,7 @@ public class PlayerTabList { for (TabPlayer player : players) { // Skip players on other servers if the setting is enabled if (plugin.getSettings().isOnlyListPlayersInSameGroup() && serversInGroup.isPresent() - && !serversInGroup.get().contains(player.getServerName())) { + && !serversInGroup.get().contains(player.getServerName())) { continue; } @@ -157,6 +155,7 @@ public class PlayerTabList { if (!tabPlayer.getPlayer().isActive()) { return; } + players.forEach(player -> tabPlayer.getDisplayName(plugin).thenAccept(displayName -> { player.getPlayer().getTabList().getEntries().stream() .filter(e -> e.getProfile().getId().equals(tabPlayer.getPlayer().getUniqueId())).findFirst() @@ -167,27 +166,19 @@ public class PlayerTabList { } public CompletableFuture getHeader(@NotNull TabPlayer player) { - if (headerIndex >= plugin.getSettings().getHeaderListSize(plugin.getSettings().getServerGroup(player.getServerName()))){ - headerIndex = 0; - } - CompletableFuture headerComponent = Placeholder.replace(plugin.getSettings().getHeader( - plugin.getSettings().getServerGroup(player.getServerName()), headerIndex), plugin, player) - .thenApply(header -> plugin.getFormatter().format(header, player, plugin)); - headerIndex++; - return headerComponent; + final String header = plugin.getSettings().getHeader(player.getServerGroup(plugin), player.getHeaderIndex()); + player.incrementHeaderIndex(plugin); + return Placeholder.replace(header, plugin, player) + .thenApply(replaced -> plugin.getFormatter().format(replaced, player, plugin)); } public CompletableFuture getFooter(@NotNull TabPlayer player) { - if (footerIndex >= plugin.getSettings().getFooterListSize(plugin.getSettings().getServerGroup(player.getServerName()))){ - footerIndex = 0; - } - CompletableFuture footerComponent = Placeholder.replace(plugin.getSettings().getFooter( - plugin.getSettings().getServerGroup(player.getServerName()), footerIndex), plugin, player) - .thenApply(footer -> plugin.getFormatter().format(footer, player, plugin)); - footerIndex++; - return footerComponent; + final String footer = plugin.getSettings().getFooter(player.getServerGroup(plugin), player.getFooterIndex()); + player.incrementFooterIndex(plugin); + return Placeholder.replace(footer, plugin, player) + .thenApply(replaced -> plugin.getFormatter().format(replaced, player, plugin)); } // Update the tab list periodically