Server groups, formatting based on server groups (#6)

This commit is contained in:
Emibergo02 2023-03-08 13:22:15 +01:00 committed by GitHub
parent f790378182
commit f0c5ebe5a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 110 additions and 32 deletions

View File

@ -78,7 +78,10 @@ public class Velocitab {
private void loadSettings() { private void loadSettings() {
try { try {
settings = Annotaml.create(new File(dataDirectory.toFile(), "config.yml"), Settings.class).get(); settings = Annotaml.create(
new File(dataDirectory.toFile(), "config.yml"),
new Settings(this)
).get();
} catch (IOException | InvocationTargetException | InstantiationException | IllegalAccessException e) { } catch (IOException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
logger.error("Failed to load config file: " + e.getMessage(), e); logger.error("Failed to load config file: " + e.getMessage(), e);
} }

View File

@ -1,13 +1,17 @@
package net.william278.velocitab.config; package net.william278.velocitab.config;
import lombok.Getter;
import net.william278.annotaml.YamlComment; import net.william278.annotaml.YamlComment;
import net.william278.annotaml.YamlFile; import net.william278.annotaml.YamlFile;
import net.william278.annotaml.YamlKey; import net.william278.annotaml.YamlKey;
import net.william278.velocitab.BuildConstants; import net.william278.velocitab.BuildConstants;
import net.william278.velocitab.Velocitab;
import org.apache.commons.text.StringEscapeUtils; import org.apache.commons.text.StringEscapeUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.List;
import java.util.Map;
@YamlFile(header = """ @YamlFile(header = """
@ -17,40 +21,66 @@ import java.util.ArrayList;
Placeholders: %players_online%, %max_players_online%, %local_players_online%, %current_date%, %current_time%, %username%, %server%, %ping%, %prefix%, %suffix%, %role%""") Placeholders: %players_online%, %max_players_online%, %local_players_online%, %current_date%, %current_time%, %username%, %server%, %ping%, %prefix%, %suffix%, %role%""")
public class Settings { public class Settings {
@YamlKey("header")
private String header = "&rainbow&Running Velocitab v" + BuildConstants.VERSION + " by William278"; @YamlKey("headers")
@YamlKey("footer") private Map<String, String> headers = Map.of("default", "&rainbow&Running Velocitab v" + BuildConstants.VERSION + " by William278");
private String footer = "[There are currently %players_online%/%max_players_online% players online](gray)"; @YamlKey("footers")
@YamlKey("format") private Map<String, String> footers = Map.of("default", "[There are currently %players_online%/%max_players_online% players online](gray)");
private String format = "&7[%server%] &f%prefix%%username%"; @YamlKey("formats")
@YamlComment("Enable the PlaceholderAPI hook (requires PAPIProxyBridge to be installed on proxy & spigot servers)") private Map<String, String> formats = Map.of("default", "&7[%server%] &f%prefix%%username%");
@Getter
@YamlKey("server_groups")
@YamlComment("The servers in each group of servers")
private Map<String, List<String>> serverGroups = Map.of("default", List.of("lobby1", "lobby2", "lobby3"));
@Getter
@YamlKey("fallback_enabled")
@YamlComment("All servers which are not in other groups will be put in the fallback group.\n\"false\" will exclude them from Velocitab.")
private boolean fallbackEnabled = true;
@Getter
@YamlKey("fallback_group")
@YamlComment("The format to use for the fallback group.")
private String fallbackGroup = "default";
@YamlKey("enable_papi_hook") @YamlKey("enable_papi_hook")
private boolean enablePapiHook = true; private boolean enablePapiHook = true;
@YamlKey("excluded_servers")
private ArrayList<String> excludedServers = new ArrayList<>();
@YamlKey(("update_rate")) @YamlKey(("update_rate"))
private int updateRate = 0; private int updateRate = 0;
private Settings() { public Settings(@NotNull Velocitab plugin) {
this.serverGroups = Map.of("default",
plugin.getServer().getAllServers().stream().map(server -> server.getServerInfo().getName()).toList()
);
}
@SuppressWarnings("unused")
public Settings(){}
@NotNull
public String getHeader(String serverGroup) {
return StringEscapeUtils.unescapeJava(
headers.getOrDefault(serverGroup, "&rainbow&Running Velocitab v" + BuildConstants.VERSION + " by William278"));
} }
@NotNull @NotNull
public String getHeader() { public String getFooter(String serverGroup) {
return StringEscapeUtils.unescapeJava(header); return StringEscapeUtils.unescapeJava(
footers.getOrDefault(serverGroup, "[There are currently %players_online%/%max_players_online% players online](gray)"));
} }
@NotNull @NotNull
public String getFooter() { public String getFormat(String serverGroup) {
return StringEscapeUtils.unescapeJava(footer); return StringEscapeUtils.unescapeJava(
formats.getOrDefault(serverGroup, "&7[%server%] &f%prefix%%username%"));
} }
@NotNull /**
public String getFormat() { * Get the server group that a server is in
return StringEscapeUtils.unescapeJava(format); *
} * @param serverName The name of the server
* @return The server group that the server is in, or "default" if the server is not in a group
public boolean isServerExcluded(@NotNull String serverName) { */
return excludedServers.contains(serverName); public String getServerGroup(String serverName) {
return serverGroups.entrySet().stream()
.filter(entry -> entry.getValue().contains(serverName)).findFirst()
.map(Map.Entry::getKey).orElse(fallbackGroup);
} }
public boolean isPapiHookEnabled() { public boolean isPapiHookEnabled() {

View File

@ -40,8 +40,11 @@ public final class TabPlayer implements Comparable<TabPlayer> {
@NotNull @NotNull
public CompletableFuture<Component> getDisplayName(@NotNull Velocitab plugin) { public CompletableFuture<Component> getDisplayName(@NotNull Velocitab plugin) {
return Placeholder.format(plugin.getSettings().getFormat(), plugin, this) return Placeholder.format(plugin.getSettings().getFormat(
plugin.getSettings().getServerGroup(getServerName())
), plugin, this)
.thenApply(formatted -> new MineDown(formatted).toComponent()); .thenApply(formatted -> new MineDown(formatted).toComponent());
} }
@NotNull @NotNull

View File

@ -16,7 +16,9 @@ import net.william278.velocitab.player.TabPlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -24,10 +26,12 @@ import java.util.concurrent.TimeUnit;
public class PlayerTabList { public class PlayerTabList {
private final Velocitab plugin; private final Velocitab plugin;
private final ConcurrentLinkedQueue<TabPlayer> players; private final ConcurrentLinkedQueue<TabPlayer> players;
private final ConcurrentLinkedQueue<String> fallbackServers;
public PlayerTabList(@NotNull Velocitab plugin) { public PlayerTabList(@NotNull Velocitab plugin) {
this.plugin = plugin; this.plugin = plugin;
this.players = new ConcurrentLinkedQueue<>(); this.players = new ConcurrentLinkedQueue<>();
this.fallbackServers = new ConcurrentLinkedQueue<>();
// If the update time is set to 0 do not schedule the updater // If the update time is set to 0 do not schedule the updater
if (plugin.getSettings().getUpdateRate() > 0) { if (plugin.getSettings().getUpdateRate() > 0) {
@ -46,11 +50,16 @@ public class PlayerTabList {
players.removeIf(player -> player.getPlayer().getUniqueId().equals(joined.getUniqueId())); players.removeIf(player -> player.getPlayer().getUniqueId().equals(joined.getUniqueId()));
} }
// Don't set their list if they are on an excluded server // Get the servers in the group from the joined server name
if (plugin.getSettings().isServerExcluded(joined.getCurrentServer() // If the server is not in a group, use fallback
Optional<List<String>> serversInGroup = getSiblings(joined.getCurrentServer()
.map(ServerConnection::getServerInfo) .map(ServerConnection::getServerInfo)
.map(ServerInfo::getName) .map(ServerInfo::getName)
.orElse("?"))) { .orElse("?"));
// If the server is not in a group, use fallback.
// If fallback is disabled, permit the player to switch excluded servers without header or footer override
if (serversInGroup.isEmpty() && !this.fallbackServers.contains(event.getPreviousServer().getServerInfo().getName())) {
event.getPlayer().sendPlayerListHeaderAndFooter(Component.empty(), Component.empty());
return; return;
} }
@ -63,7 +72,11 @@ public class PlayerTabList {
.buildTask(plugin, () -> { .buildTask(plugin, () -> {
final TabList tabList = joined.getTabList(); final TabList tabList = joined.getTabList();
final Map<String, String> playerRoles = new HashMap<>(); final Map<String, String> playerRoles = new HashMap<>();
players.forEach(player -> {
for (TabPlayer player : players) {
if (!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());
tabList.getEntries().stream() tabList.getEntries().stream()
.filter(e -> e.getProfile().getId().equals(player.getPlayer().getUniqueId())).findFirst() .filter(e -> e.getProfile().getId().equals(player.getPlayer().getUniqueId())).findFirst()
@ -73,7 +86,8 @@ public class PlayerTabList {
); );
addPlayerToTabList(player, tabPlayer); addPlayerToTabList(player, tabPlayer);
player.sendHeaderAndFooter(this); player.sendHeaderAndFooter(this);
}); }
plugin.getScoreboardManager().setRoles(joined, playerRoles); plugin.getScoreboardManager().setRoles(joined, playerRoles);
}) })
.delay(500, TimeUnit.MILLISECONDS) .delay(500, TimeUnit.MILLISECONDS)
@ -142,14 +156,17 @@ public class PlayerTabList {
} }
public CompletableFuture<Component> getHeader(@NotNull TabPlayer player) { public CompletableFuture<Component> getHeader(@NotNull TabPlayer player) {
return Placeholder.format(plugin.getSettings().getHeader(), plugin, player) return Placeholder.format(plugin.getSettings().getHeader(
plugin.getSettings().getServerGroup(player.getServerName())), plugin, player)
.thenApply(header -> new MineDown(header).toComponent()); .thenApply(header -> new MineDown(header).toComponent());
} }
public CompletableFuture<Component> getFooter(@NotNull TabPlayer player) { public CompletableFuture<Component> getFooter(@NotNull TabPlayer player) {
return Placeholder.format(plugin.getSettings().getFooter(), plugin, player) return Placeholder.format(plugin.getSettings().getFooter(
plugin.getSettings().getServerGroup(player.getServerName())), plugin, player)
.thenApply(header -> new MineDown(header).toComponent()); .thenApply(header -> new MineDown(header).toComponent());
} }
private void updateTimer(int updateRate) { private void updateTimer(int updateRate) {
@ -162,4 +179,29 @@ public class PlayerTabList {
.repeat(updateRate, TimeUnit.MILLISECONDS) .repeat(updateRate, TimeUnit.MILLISECONDS)
.schedule(); .schedule();
} }
/**
* Get the servers in the same group as the given server
* If the server is not in a group, use fallback
* If fallback is disabled, return empty
*
* @param serverName The server name
* @return The servers in the same group as the given server, empty if the server is not in a group and fallback is disabled
*/
@NotNull
public Optional<List<String>> getSiblings(String serverName) {
return plugin.getSettings().getServerGroups().values().stream()
.filter(servers -> servers.contains(serverName))
.findFirst()
.or(() -> {
if (!plugin.getSettings().isFallbackEnabled()) {
return Optional.empty();
}
if (!this.fallbackServers.contains(serverName)) {
this.fallbackServers.add(serverName);
}
return Optional.of(this.fallbackServers.stream().toList());
});
}
} }