diff --git a/src/main/java/de/strifel/VTools/VTools.java b/src/main/java/de/strifel/VTools/VTools.java index 2496e5f..9ff6658 100644 --- a/src/main/java/de/strifel/VTools/VTools.java +++ b/src/main/java/de/strifel/VTools/VTools.java @@ -5,6 +5,7 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.proxy.ProxyServer; import de.strifel.VTools.commands.*; +import de.strifel.VTools.listeners.*; import net.kyori.adventure.text.format.TextColor; import org.slf4j.Logger; @@ -28,11 +29,17 @@ public class VTools { public void onProxyInitialization(ProxyInitializeEvent event) { server.getCommandManager().register("send", new CommandSend(server)); server.getCommandManager().register("broadcast", new CommandBroadcast(server), "bc", "alert"); + server.getCommandManager().register("globalchat", new CommandGlobalChat(server), "global", "g"); server.getCommandManager().register("find", new CommandFind(server), "search"); server.getCommandManager().register("staffchat", new CommandStaffChat(server), "sc"); server.getCommandManager().register("restart", new CommandRestart(server)); server.getCommandManager().register("tps", new CommandTp(server), "jump"); server.getCommandManager().register("servers", new CommandServers(server), "allservers"); + new PlayerStatus(this).register(); + } + + public ProxyServer getServer() { + return server; } } diff --git a/src/main/java/de/strifel/VTools/commands/CommandGlobalChat.java b/src/main/java/de/strifel/VTools/commands/CommandGlobalChat.java new file mode 100644 index 0000000..f7e0cda --- /dev/null +++ b/src/main/java/de/strifel/VTools/commands/CommandGlobalChat.java @@ -0,0 +1,64 @@ +package de.strifel.VTools.commands; + +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.command.SimpleCommand; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.server.RegisteredServer; +import net.kyori.adventure.text.Component; + +import java.util.ArrayList; +import java.util.List; + +import static de.strifel.VTools.VTools.COLOR_RED; + +public class CommandGlobalChat implements SimpleCommand { + private final ProxyServer server; + + public CommandGlobalChat(ProxyServer server) { + this.server = server; + } + + @Override + public void execute(Invocation invocation) { + CommandSource commandSource = invocation.source(); + String[] strings = invocation.arguments(); + if (strings.length > 0) { + String commandSourceName = "console"; + RegisteredServer senderServer = null; + if (commandSource instanceof Player) { + Player player = (Player) commandSource; + commandSourceName = player.getUsername(); + if (player.getCurrentServer().isPresent()) { + senderServer = player.getCurrentServer().get().getServer(); + } + } + String message = String.join(" ", strings).replace("&", "ยง"); + for (Player player : server.getAllPlayers()) { + RegisteredServer receiverServer = null; + if (player.getCurrentServer().isPresent()) { + receiverServer = player.getCurrentServer().get().getServer(); + } + if (senderServer != null && senderServer.equals(receiverServer)) { + player.sendMessage(Component.text(String.format("[global] <%s> %s", commandSourceName, message))); + } + else { + String s = senderServer == null ? "?" : senderServer.getServerInfo().getName(); + player.sendMessage(Component.text(String.format("[global] [%s] <%s> %s", s, commandSourceName, message))); + } + } + } else { + commandSource.sendMessage(Component.text("Usage: /globalchat ").color(COLOR_RED)); + } + } + + @Override + public List suggest(Invocation invocation) { + return new ArrayList(); + } + + @Override + public boolean hasPermission(Invocation invocation) { + return invocation.source().hasPermission("vtools.globalchat"); + } +} diff --git a/src/main/java/de/strifel/VTools/listeners/PlayerStatus.java b/src/main/java/de/strifel/VTools/listeners/PlayerStatus.java new file mode 100644 index 0000000..7c6911b --- /dev/null +++ b/src/main/java/de/strifel/VTools/listeners/PlayerStatus.java @@ -0,0 +1,69 @@ +package de.strifel.VTools.listeners; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.DisconnectEvent; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import de.strifel.VTools.VTools; +import de.strifel.VTools.listeners.utils.GlistUtil; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.format.NamedTextColor; + +public class PlayerStatus { + private final VTools plugin; + private final ProxyServer server; + + public PlayerStatus(VTools plugin) { + this.plugin = plugin; + this.server = plugin.getServer(); + } + + public void register() { + server.getEventManager().register(plugin, this); + } + + @Subscribe + public void onServerConnected(ServerConnectedEvent event) { + if (event.getPreviousServer().isEmpty()) { + if (event.getPlayer().hasPermission("vtools.listener.playerstatus.atlogin")) { + (new GlistUtil(server)).serverCount(event.getPlayer()); + } + } + for (Player player : server.getAllPlayers()) { + if (player.hasPermission("vtools.listener.playerstatus")) { + if (event.getPreviousServer().isEmpty()) { + String serverName = event.getServer().getServerInfo().getName(); + player.sendMessage(Component.empty() + .append(Component.text("[velocity] ").color(NamedTextColor.YELLOW)) + .append(Component.text(String.format("%s joined into ", event.getPlayer().getUsername()))) + .append(Component.text(serverName).clickEvent(ClickEvent.runCommand("/server " + serverName)).color(NamedTextColor.GRAY))); + } + else { + if (player.hasPermission("vtools.listener.playerstatus.move")) { + String serverName1 = event.getServer().getServerInfo().getName(); + String serverName0 = event.getPreviousServer().get().getServerInfo().getName(); + player.sendMessage(Component.empty() + .append(Component.text("[velocity] ").color(NamedTextColor.YELLOW)) + .append(Component.text(String.format("%s moved from ", event.getPlayer().getUsername()))) + .append(Component.text(serverName0).clickEvent(ClickEvent.runCommand("/server " + serverName0)).color(NamedTextColor.GRAY)) + .append(Component.text(" to ")) + .append(Component.text(serverName1).clickEvent(ClickEvent.runCommand("/server " + serverName1)).color(NamedTextColor.GRAY))); + } + } + } + } + } + + @Subscribe + public void onDisconnect(DisconnectEvent event) { + for (Player player : server.getAllPlayers()) { + if (player.getUniqueId() != event.getPlayer().getUniqueId() && player.hasPermission("vtools.listener.playerstatus")) { + player.sendMessage(Component.empty() + .append(Component.text("[velocity] ").color(NamedTextColor.YELLOW)) + .append(Component.text(String.format("%s left the proxy", event.getPlayer().getUsername())))); + } + } + } +} diff --git a/src/main/java/de/strifel/VTools/listeners/utils/GlistUtil.java b/src/main/java/de/strifel/VTools/listeners/utils/GlistUtil.java new file mode 100644 index 0000000..f1d9ac9 --- /dev/null +++ b/src/main/java/de/strifel/VTools/listeners/utils/GlistUtil.java @@ -0,0 +1,72 @@ +package de.strifel.VTools.listeners.utils; + +import com.google.common.collect.ImmutableList; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.server.RegisteredServer; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.TranslatableComponent; +import net.kyori.adventure.text.format.NamedTextColor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class GlistUtil { + private final ProxyServer server; + public GlistUtil(ProxyServer server) { + this.server = server; + } + + // https://github.com/PaperMC/Velocity/blob/7f776abf550001186a1f11f4e5ff760dd66e3b04/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/BuiltinCommandUtil.java#L33 + public static List sortedServerList(ProxyServer proxy) { + List servers = new ArrayList<>(proxy.getAllServers()); + servers.sort(Comparator.comparing(RegisteredServer::getServerInfo)); + return Collections.unmodifiableList(servers); + } + + // https://github.com/PaperMC/Velocity/blob/7f776abf550001186a1f11f4e5ff760dd66e3b04/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/GlistCommand.java + + public void serverCount(final Player source) { + sendTotalProxyCount(source); + for (RegisteredServer server : sortedServerList(server)) { + sendServerPlayers(source, server, true); + } + } + + private void sendTotalProxyCount(Player target) { + int online = server.getPlayerCount() - 1; + TranslatableComponent msg = online <= 1 + ? Component.translatable("velocity.command.glist-player-singular") + : Component.translatable("velocity.command.glist-player-plural"); + target.sendMessage(msg.color(NamedTextColor.YELLOW) + .args(Component.text(Integer.toString(online), NamedTextColor.GREEN))); + } + + private void sendServerPlayers(Player target, RegisteredServer server, boolean fromAll) { + List onServer = ImmutableList.copyOf(server.getPlayersConnected()); + if (onServer.isEmpty() && fromAll) { + return; + } + + TextComponent.Builder builder = Component.text() + .append(Component.text("[" + server.getServerInfo().getName() + "] ", + NamedTextColor.DARK_AQUA)) + .append(Component.text("(" + onServer.size() + ")", NamedTextColor.GRAY)) + .append(Component.text(": ")) + .resetStyle(); + + for (int i = 0; i < onServer.size(); i++) { + Player player = onServer.get(i); + builder.append(Component.text(player.getUsername())); + + if (i + 1 < onServer.size()) { + builder.append(Component.text(", ")); + } + } + + target.sendMessage(builder.build()); + } +}