From 67382a9d76df7371191ed1fbcac676407dedeaef Mon Sep 17 00:00:00 2001 From: bierdosenhalter <529651+bierdosenhalter@users.noreply.github.com> Date: Mon, 7 Oct 2024 09:59:10 +0200 Subject: [PATCH] component logger and kick notification --- gradle.properties | 2 +- run/proxy/velocity.toml | 2 +- .../zeroBzeroT/anarchyqueue/Components.java | 13 +++ .../org/zeroBzeroT/anarchyqueue/Main.java | 18 ++-- .../org/zeroBzeroT/anarchyqueue/Queue.java | 89 +++++++++---------- 5 files changed, 68 insertions(+), 56 deletions(-) create mode 100644 src/main/java/org/zeroBzeroT/anarchyqueue/Components.java diff --git a/gradle.properties b/gradle.properties index e50e804..9393d37 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -plugin_version=3.0.3-INDEV +plugin_version=3.0.4-INDEV velocity_api_version=3.3.0-SNAPSHOT minecraft_version=1.20.6 diff --git a/run/proxy/velocity.toml b/run/proxy/velocity.toml index b1dac78..31df91a 100644 --- a/run/proxy/velocity.toml +++ b/run/proxy/velocity.toml @@ -40,7 +40,7 @@ player-info-forwarding-mode = "MODERN" # The file is expected to be UTF-8 encoded and not empty. forwarding-secret-file = "forwarding.secret" -# Announce whether or not your server supports Forge. If you run a modded server, we +# Announce whether your server supports Forge. If you run a modded server, we # suggest turning this on. # # If your network runs one modpack consistently, consider using ping-passthrough = "mods" diff --git a/src/main/java/org/zeroBzeroT/anarchyqueue/Components.java b/src/main/java/org/zeroBzeroT/anarchyqueue/Components.java new file mode 100644 index 0000000..ccf718d --- /dev/null +++ b/src/main/java/org/zeroBzeroT/anarchyqueue/Components.java @@ -0,0 +1,13 @@ +package org.zeroBzeroT.anarchyqueue; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; + +/** + * helper method because the MiniMessage syntax is too verbose + */ +public final class Components { + public static Component mm(String miniMessageString) { // mm, short for MiniMessage + return MiniMessage.miniMessage().deserialize(miniMessageString); + } +} diff --git a/src/main/java/org/zeroBzeroT/anarchyqueue/Main.java b/src/main/java/org/zeroBzeroT/anarchyqueue/Main.java index 7338311..5d3c0c0 100644 --- a/src/main/java/org/zeroBzeroT/anarchyqueue/Main.java +++ b/src/main/java/org/zeroBzeroT/anarchyqueue/Main.java @@ -7,30 +7,30 @@ import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.ProxyServer; -import org.slf4j.Logger; +import net.kyori.adventure.text.logger.slf4j.ComponentLogger; import java.nio.file.Path; @Plugin( - id = "anarchyqueue", - name = "AnarchyQueue", - version = BuildConstants.VERSION, - description = "velocity queue system for anarchy servers", - url = "https://github.com/zeroBzeroT/AnarchyQueue", - authors = {"bierdosenhalter", "nothub"} + id = "anarchyqueue", + name = "AnarchyQueue", + version = BuildConstants.VERSION, + description = "velocity queue system for anarchy servers", + url = "https://github.com/zeroBzeroT/AnarchyQueue", + authors = {"bierdosenhalter", "nothub"} ) public class Main { private static Main instance; - public final Logger log; + public final ComponentLogger log; private final ProxyServer server; private final Path dataDir; @Inject - public Main(ProxyServer server, CommandManager commandManager, Logger logger, @DataDirectory final Path dataDir) { + public Main(ProxyServer server, CommandManager commandManager, ComponentLogger logger, @DataDirectory final Path dataDir) { this.server = server; this.log = logger; this.dataDir = dataDir; diff --git a/src/main/java/org/zeroBzeroT/anarchyqueue/Queue.java b/src/main/java/org/zeroBzeroT/anarchyqueue/Queue.java index 74fe28e..d5cfe4c 100644 --- a/src/main/java/org/zeroBzeroT/anarchyqueue/Queue.java +++ b/src/main/java/org/zeroBzeroT/anarchyqueue/Queue.java @@ -1,39 +1,38 @@ package org.zeroBzeroT.anarchyqueue; import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.player.KickedFromServerEvent; import com.velocitypowered.api.event.player.ServerConnectedEvent; import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.server.RegisteredServer; -import net.kyori.adventure.identity.Identity; import net.kyori.adventure.text.Component; -import org.slf4j.Logger; +import net.kyori.adventure.text.logger.slf4j.ComponentLogger; import java.time.Duration; import java.time.Instant; -import java.util.List; +import java.util.Deque; +import java.util.LinkedList; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.Semaphore; +import static org.zeroBzeroT.anarchyqueue.Components.mm; + // velocity api event docs: // https://jd.papermc.io/velocity/3.3.0/com/velocitypowered/api/event/package-summary.html public class Queue { - private final Logger log; + private final ComponentLogger log; private final ProxyServer proxyServer; private final Semaphore queueSemaphore = new Semaphore(1); - /** - * We don't use ConcurrentLinkedQueue for this because we want index-based access to players. - */ - private final List queuedPlayers = new CopyOnWriteArrayList<>(); + private final Deque queuedPlayers = new LinkedList<>(); /** - * Initializes a queue + * Initializes the queue. */ public Queue(ProxyServer proxyServer) { this.log = Main.getInstance().log; @@ -48,24 +47,23 @@ public Queue(ProxyServer proxyServer) { } /** - * This event is called once a connection to a server is fully operational. - * Add a Player to the queue if they join the queue server. + * This event is fired once the player has successfully connected to the + * target server and the connection to the previous server has been de-established. */ @Subscribe - public void onServerConnectedEvent(ServerConnectedEvent e) { - if (!e.getServer().getServerInfo().getName().equals(Config.serverQueue)) + public void onServerConnected(ServerConnectedEvent event) { + if (!event.getServer().getServerInfo().getName().equals(Config.serverQueue)) return; - var queuedPlayer = new QueuedPlayer(e.getPlayer(), System.currentTimeMillis()); - - if (queuedPlayers.contains(queuedPlayer)) + // stop adding the player several times + if (queuedPlayers.stream().anyMatch(p -> p.player() == event.getPlayer())) return; // Add Player to queue try { queueSemaphore.acquire(); - queuedPlayers.add(queuedPlayer); - log.info("\u00A7f" + e.getPlayer().getUsername() + "\u00A73 was added to the §dplayer queue\u00A73. Queue count is " + queuedPlayers.size() + "."); + queuedPlayers.add(new QueuedPlayer(event.getPlayer(), System.currentTimeMillis())); + log.info(mm("" + event.getPlayer().getUsername() + " was added to the queue. Queue count is " + queuedPlayers.size() + ".")); } catch (InterruptedException e1) { e1.printStackTrace(); } finally { @@ -74,9 +72,21 @@ public void onServerConnectedEvent(ServerConnectedEvent e) { } /** - * Try to connect one player to the server + * Fired when a player is kicked from a server. + */ + @Subscribe + public void onKickedFromServer(KickedFromServerEvent event) { + log.info(mm("" + event.getPlayer().getUsername() + " was kicked from " + event.getServer().getServerInfo().getName() + " for ").append(event.getServerKickReason().isPresent() ? event.getServerKickReason().get() : mm("")).append(mm("."))); + } + + /** + * Try to connect one player to the server. */ public void flushQueue() { + // Ignore if queue is empty + if (queuedPlayers.isEmpty()) + return; + // check queue server reachability final RegisteredServer serverQueue; @@ -87,10 +97,6 @@ public void flushQueue() { return; } - // Ignore if queue is empty - if (queuedPlayers.isEmpty()) - return; - // check the main server reachability final RegisteredServer serverMain; @@ -98,11 +104,9 @@ public void flushQueue() { serverMain = getServer(Config.serverMain); } catch (ServerNotReachableException e) { if (Instant.now().getEpochSecond() % 10 == 0) { - serverQueue.getPlayersConnected().forEach(queuedPlayer -> - queuedPlayer.sendMessage(Identity.nil(), Component.text( - Config.messageOffline - ))); + serverQueue.getPlayersConnected().forEach(queuedPlayer -> queuedPlayer.sendMessage(Component.text(Config.messageOffline))); } + return; } @@ -145,21 +149,21 @@ public void flushQueue() { serverQueue.getPlayersConnected().stream() .filter(p -> p.getUniqueId().equals(uuid)) .findAny().ifPresentOrElse(p -> { - p.sendMessage(Identity.nil(), Component.text(Config.messageConnecting)); + p.sendMessage(Component.text(Config.messageConnecting)); try { if (p.createConnectionRequest(serverMain).connect().get().isSuccessful()) { queuedPlayers.removeFirst(); - log.info("\u00A7f" + p.getUsername() + "\u00A73 connected to server §b" + serverMain.getServerInfo().getName() + "\u00A73. Queue count is " + serverQueue.getPlayersConnected().size() + ". Main count is " + (serverMain.getPlayersConnected().size()) + " of " + Config.maxPlayers + "."); + log.info(mm("" + p.getUsername() + " connected to server " + serverMain.getServerInfo().getName() + ". Queue count is " + serverQueue.getPlayersConnected().size() + ". Main count is " + (serverMain.getPlayersConnected().size()) + " of " + Config.maxPlayers + ".")); } } catch (InterruptedException | ExecutionException e) { - log.error("\u00A7f" + p.getUsername() + "s\u00A7c connection to server §b" + Config.serverMain + "\u00A7c failed: " + e.getMessage()); + log.error(mm("" + p.getUsername() + "s connection to server " + Config.serverMain + " failed: " + e.getMessage())); // FIXME: requeue queuedPlayers.removeFirst(); queuedPlayers.add(new QueuedPlayer(finalCurrPlayer.player(), System.currentTimeMillis())); } }, () -> { - log.error("\u00A7f" + finalCurrPlayer.player().getUsername() + "s\u00A7c connection to server §b" + Config.serverMain + "\u00A7c failed: player is not connected to " + serverQueue.getServerInfo().getName()); + log.error(mm("" + finalCurrPlayer.player().getUsername() + "s connection to server " + Config.serverMain + " failed: player is not connected to " + serverQueue.getServerInfo().getName())); queuedPlayers.removeFirst(); } ); @@ -171,25 +175,20 @@ public void flushQueue() { } private void sendInfo(RegisteredServer serverQueue, boolean full) { - for (int i = 0; i < queuedPlayers.size(); i++) { - queuedPlayers - .get(i) - .player() - .sendMessage(Identity.nil(), Component.text( - Config.messagePosition + (i + 1) + "/" + queuedPlayers.size() - )); + int i = 1; + + for (QueuedPlayer player : queuedPlayers) { + player.player().sendMessage(Component.text(Config.messagePosition + (i + 1) + "/" + queuedPlayers.size())); + i++; } if (full) { - serverQueue.getPlayersConnected().forEach(queuedPlayer -> - queuedPlayer.sendMessage(Identity.nil(), Component.text( - Config.messageFull - ))); + serverQueue.getPlayersConnected().forEach(queuedPlayer -> queuedPlayer.sendMessage(Component.text(Config.messageFull))); } } private RegisteredServer getServer(String name) throws ServerNotReachableException { - // get server configured in velocity.toml by name + // Get server configured in velocity.toml by name Optional serverOpt = proxyServer.getServer(name); if (serverOpt.isEmpty()) { @@ -198,7 +197,7 @@ private RegisteredServer getServer(String name) throws ServerNotReachableExcepti final RegisteredServer server = serverOpt.get(); - // test server availability by pinging + // Test server availability by pinging try { server.ping().get(); } catch (InterruptedException | ExecutionException e) {