commit 441ded118b0eb13fb08b83a491ad75cd2faa1181 Author: Elias Müller Date: Sat Nov 27 23:06:48 2021 +0100 initial commit diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/artifacts/BungeeQueue_jar.xml b/.idea/artifacts/BungeeQueue_jar.xml new file mode 100644 index 0000000..b33c59d --- /dev/null +++ b/.idea/artifacts/BungeeQueue_jar.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/out/artifacts/BungeeQueue_jar + + + + + \ No newline at end of file diff --git a/.idea/libraries/waterfall_1_17_451.xml b/.idea/libraries/waterfall_1_17_451.xml new file mode 100644 index 0000000..d25e01c --- /dev/null +++ b/.idea/libraries/waterfall_1_17_451.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..6b02fc2 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..5258986 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/BungeeQueue.iml b/BungeeQueue.iml new file mode 100644 index 0000000..9c3cf1a --- /dev/null +++ b/BungeeQueue.iml @@ -0,0 +1,21 @@ + + + + + + + WATERFALL + + + + + + + + + + + + + + \ No newline at end of file diff --git a/out/artifacts/BungeeQueue_jar/BungeeQueue.jar b/out/artifacts/BungeeQueue_jar/BungeeQueue.jar new file mode 100644 index 0000000..69bb975 Binary files /dev/null and b/out/artifacts/BungeeQueue_jar/BungeeQueue.jar differ diff --git a/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/BungeeQueue.class b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/BungeeQueue.class new file mode 100644 index 0000000..7773d13 Binary files /dev/null and b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/BungeeQueue.class differ diff --git a/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers$1.class b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers$1.class new file mode 100644 index 0000000..072b048 Binary files /dev/null and b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers$1.class differ diff --git a/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers.class b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers.class new file mode 100644 index 0000000..f7004e0 Binary files /dev/null and b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers.class differ diff --git a/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/listener/PlayerJoin.class b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/listener/PlayerJoin.class new file mode 100644 index 0000000..75ee954 Binary files /dev/null and b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/listener/PlayerJoin.class differ diff --git a/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/MoveToTarget.class b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/MoveToTarget.class new file mode 100644 index 0000000..3802aca Binary files /dev/null and b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/MoveToTarget.class differ diff --git a/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/PlayersWaitingCheck.class b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/PlayersWaitingCheck.class new file mode 100644 index 0000000..5a03e40 Binary files /dev/null and b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/PlayersWaitingCheck.class differ diff --git a/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/QueueInfoMessager.class b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/QueueInfoMessager.class new file mode 100644 index 0000000..052d84b Binary files /dev/null and b/out/production/BungeeQueue/eu/mhsl/minecraft/bungeequeue/scheduler/QueueInfoMessager.class differ diff --git a/out/production/BungeeQueue/plugin.yml b/out/production/BungeeQueue/plugin.yml new file mode 100644 index 0000000..86d0427 --- /dev/null +++ b/out/production/BungeeQueue/plugin.yml @@ -0,0 +1,3 @@ +name: BungeeQueue +main: eu.mhsl.minecraft.bungeequeue.BungeeQueue +version: 0.1 \ No newline at end of file diff --git a/src/eu/mhsl/minecraft/bungeequeue/BungeeQueue.java b/src/eu/mhsl/minecraft/bungeequeue/BungeeQueue.java new file mode 100644 index 0000000..0070374 --- /dev/null +++ b/src/eu/mhsl/minecraft/bungeequeue/BungeeQueue.java @@ -0,0 +1,47 @@ +package eu.mhsl.minecraft.bungeequeue; + +import eu.mhsl.minecraft.bungeequeue.command.MaxPlayers; +import eu.mhsl.minecraft.bungeequeue.listener.PlayerJoin; +import eu.mhsl.minecraft.bungeequeue.scheduler.MoveToTarget; +import eu.mhsl.minecraft.bungeequeue.scheduler.PlayersWaitingCheck; +import eu.mhsl.minecraft.bungeequeue.scheduler.QueueInfoMessager; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +public class BungeeQueue extends Plugin { + public static Plugin plugin; + public static ServerInfo queueServer; + public static ServerInfo targetServer; + + public static int maxPlayers = 1; //mutable per command + + public static List list = new ArrayList<>(); + + @Override + public void onEnable() { + plugin = this; + ProxyServer instance = ProxyServer.getInstance(); + + queueServer = instance.getServerInfo("queue"); + targetServer = instance.getServerInfo("server"); + + instance.getPluginManager().registerListener(this, new PlayerJoin()); + instance.getPluginManager().registerCommand(this, new MaxPlayers()); + + instance.getScheduler().schedule(this, new MoveToTarget(), 5, 1, TimeUnit.SECONDS); + instance.getScheduler().schedule(this, new QueueInfoMessager(), 5, 2, TimeUnit.SECONDS); + instance.getScheduler().schedule(this, new PlayersWaitingCheck(), 10, 10, TimeUnit.SECONDS); + + } + + public void onDisable() { + + } + +} diff --git a/src/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers.java b/src/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers.java new file mode 100644 index 0000000..daaddb6 --- /dev/null +++ b/src/eu/mhsl/minecraft/bungeequeue/command/MaxPlayers.java @@ -0,0 +1,95 @@ +package eu.mhsl.minecraft.bungeequeue.command; + +import eu.mhsl.minecraft.bungeequeue.BungeeQueue; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +public class MaxPlayers extends Command { + public MaxPlayers() { + super("maxplayers", "bungeequeue.queue"); + } + + @Override + public void execute(CommandSender p, String[] strings) { + if(strings.length >= 1) { + switch (strings[0]) { + case "set": + if(strings.length == 2) { + BungeeQueue.maxPlayers = Integer.parseInt(strings[1]); + p.sendMessage(new ComponentBuilder("Die Maximale Spieleranzahl wurde auf " + strings[1] + " gesetzt.").color(ChatColor.GREEN).create()); + } else p.sendMessage(new ComponentBuilder("Bitte definiere die maximale Spieleranzahl: /maxplayers set ").color(ChatColor.RED).create()); + break; + case "query": + p.sendMessage(new ComponentBuilder("Die aktuelle Spielerzahl ist " + BungeeQueue.maxPlayers).color(ChatColor.GREEN) + .append("\n... davon belegt " + BungeeQueue.targetServer.getPlayers().size()).color(ChatColor.GREEN) + .append("\ndu kannst 'enforce' nutzen, um eine Überbelegung zu verhindern.").color(ChatColor.RED) + .create() + ); + break; + case "enforce": + if(enforceMaxPlayer(strings.length == 2 ? Integer.parseInt(strings[1]) : 30)) + p.sendMessage(new ComponentBuilder("Die maximale Spielerzahl wird durchgesetzt...").color(ChatColor.GREEN).create()); + else + p.sendMessage(new ComponentBuilder("Die maximale Spielerzahl ist nicht erreicht und kann somit auch nicht durchgesetzt werden!").color(ChatColor.RED).create()); + break; + case "bypass": + if(strings.length > 2) { + p.sendMessage(new ComponentBuilder("Bitte definiere nur einen Nutzernamen").color(ChatColor.RED).create()); + } else if(strings.length == 2) { + ProxiedPlayer targetPlayer = ProxyServer.getInstance().getPlayer(strings[1]); + targetPlayer.connect(BungeeQueue.targetServer); + p.sendMessage(new ComponentBuilder(targetPlayer.getName() + " wurde an der Queue vorbeigelassen!").color(ChatColor.GREEN).create()); + targetPlayer.sendMessage(new ComponentBuilder("Du wurdest von einem Administrator vorzeitig auf den Server verschoben!").color(ChatColor.GREEN).create()); + } else { + ((ProxiedPlayer) p).connect(BungeeQueue.targetServer); + p.sendMessage(new ComponentBuilder("Du wurdest per Befehl von der Queue befreit!").color(ChatColor.GREEN).create()); + } + break; + default: + p.sendMessage(new ComponentBuilder("Invalide Command-Syntax, valide argumente sind | enforce>").color(ChatColor.RED).create()); + } + } else p.sendMessage(new ComponentBuilder("Die Syntax des commands ist /maxplayers | enforce>").color(ChatColor.RED).create()); + } + + private boolean enforceMaxPlayer(int timeout) { + List evaluatedPlayers = new ArrayList<>(); + + int leftOver = BungeeQueue.targetServer.getPlayers().size() - BungeeQueue.maxPlayers; + if(leftOver <= 0) return false; + + List players = new ArrayList<>(BungeeQueue.targetServer.getPlayers()); + Collections.shuffle(players); + for (int i = 0; i < leftOver; i++) { + evaluatedPlayers.add(players.get(i)); + + players.get(i).sendMessage(new ComponentBuilder("\n\n>> Achtung >> \n").bold(true).color(ChatColor.RED) + .append("Aufgrund eines zu hohen Spieleraufkommens werden zufällige Spieler vom Server gekickt.\n Begebe dich an einen sicheren Ort.\n").color(ChatColor.GOLD) + .append("Du wirst in " + timeout + " sekunden in die Queue verschoben!\n\n").color(ChatColor.RED) + .create() + ); + } + + ProxyServer.getInstance().getScheduler().schedule(BungeeQueue.plugin, new Runnable() { + @Override + public void run() { + for(ProxiedPlayer p : evaluatedPlayers) { + p.connect(BungeeQueue.queueServer); + p.sendMessage(new ComponentBuilder("Du wurdest wie angekündigt aufgrund einer zu hohen Spielerzahl zurück in die Queue versetzt. Die Auswahl dich zu verschieben war Zufällig. Sorry - gönn dir eine Pause!").color(ChatColor.GOLD).create()); + } + } + }, timeout, TimeUnit.SECONDS); + + return true; + } +} diff --git a/src/eu/mhsl/minecraft/bungeequeue/listener/PlayerJoin.java b/src/eu/mhsl/minecraft/bungeequeue/listener/PlayerJoin.java new file mode 100644 index 0000000..b1e423d --- /dev/null +++ b/src/eu/mhsl/minecraft/bungeequeue/listener/PlayerJoin.java @@ -0,0 +1,16 @@ +package eu.mhsl.minecraft.bungeequeue.listener; + +import eu.mhsl.minecraft.bungeequeue.BungeeQueue; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +public class PlayerJoin implements Listener { + @EventHandler + public void onPlayerJoin(PostLoginEvent e) { + e.getPlayer().sendMessage(new ComponentBuilder("Du wurdest zur Queue hinzugefügt!").color(ChatColor.DARK_AQUA).create()); + BungeeQueue.list.add(e.getPlayer()); + } +} diff --git a/src/eu/mhsl/minecraft/bungeequeue/scheduler/MoveToTarget.java b/src/eu/mhsl/minecraft/bungeequeue/scheduler/MoveToTarget.java new file mode 100644 index 0000000..372fc30 --- /dev/null +++ b/src/eu/mhsl/minecraft/bungeequeue/scheduler/MoveToTarget.java @@ -0,0 +1,36 @@ +package eu.mhsl.minecraft.bungeequeue.scheduler; + +import eu.mhsl.minecraft.bungeequeue.BungeeQueue; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public class MoveToTarget implements Runnable { + private boolean targetIsOnline = false; + + @Override + public void run() { + //check if people are in Queue + if(BungeeQueue.list.size() == 0) return; + + //check target-server reachable + BungeeQueue.targetServer.ping((result, error) -> { + targetIsOnline = (error == null); + if(!targetIsOnline) ProxyServer.getInstance().getLogger().warning(error.getMessage()); + }); + if(!targetIsOnline) { + ProxyServer.getInstance().getLogger().warning("Target-Server seems Offline! Cancelling Queue-Movement..."); + return; + } + + + + //test if target-server has free Space - move Players + if(BungeeQueue.targetServer.getPlayers().size() < BungeeQueue.maxPlayers) { + ProxiedPlayer p = BungeeQueue.list.remove(0); + p.sendMessage(new ComponentBuilder("Teleportiere zum Zielserver...").color(ChatColor.GRAY).append("\nViel Spaß!").color(ChatColor.GREEN).create()); + p.connect(BungeeQueue.targetServer); + } + } +} diff --git a/src/eu/mhsl/minecraft/bungeequeue/scheduler/PlayersWaitingCheck.java b/src/eu/mhsl/minecraft/bungeequeue/scheduler/PlayersWaitingCheck.java new file mode 100644 index 0000000..58c1c56 --- /dev/null +++ b/src/eu/mhsl/minecraft/bungeequeue/scheduler/PlayersWaitingCheck.java @@ -0,0 +1,29 @@ +package eu.mhsl.minecraft.bungeequeue.scheduler; + +import eu.mhsl.minecraft.bungeequeue.BungeeQueue; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public class PlayersWaitingCheck implements Runnable { + @Override + public void run() { + + for(ProxiedPlayer p : BungeeQueue.queueServer.getPlayers()) { + //check if there are players on queue but not registered by the Plugin + if(!BungeeQueue.list.contains(p)) { + ProxyServer.getInstance().getLogger().warning("Added missing Player " + p.getName() + " to Queue!"); + BungeeQueue.list.add(p); + } + } + + for(ProxiedPlayer p : BungeeQueue.list) { + //check if players not connected anymore in queue + if(!BungeeQueue.queueServer.getPlayers().contains(p)) { + ProxyServer.getInstance().getLogger().warning("Removed missing Player " + p.getName() + " from Queue!"); + BungeeQueue.list.remove(p); + } + } + + } +} diff --git a/src/eu/mhsl/minecraft/bungeequeue/scheduler/QueueInfoMessager.java b/src/eu/mhsl/minecraft/bungeequeue/scheduler/QueueInfoMessager.java new file mode 100644 index 0000000..936ee7f --- /dev/null +++ b/src/eu/mhsl/minecraft/bungeequeue/scheduler/QueueInfoMessager.java @@ -0,0 +1,26 @@ +package eu.mhsl.minecraft.bungeequeue.scheduler; + +import eu.mhsl.minecraft.bungeequeue.BungeeQueue; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public class QueueInfoMessager implements Runnable { + @Override + public void run() { + for(ProxiedPlayer p : BungeeQueue.list) { + p.sendMessage( + ChatMessageType.ACTION_BAR, + new ComponentBuilder("Warteschlange platz ").color(ChatColor.DARK_GREEN) + .append((BungeeQueue.list.indexOf(p)+1)+"").bold(true).color(ChatColor.GREEN) + .append(" / ").bold(false).color(ChatColor.DARK_GREEN) + .append(BungeeQueue.list.size()+"").bold(true).color(ChatColor.GREEN) + .append(" - (").color(ChatColor.GRAY) + .append("" + ((BungeeQueue.list.indexOf(p) / BungeeQueue.list.size()) * 100)) + .append("%)") + .create() + ); + } + } +} diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100644 index 0000000..86d0427 --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,3 @@ +name: BungeeQueue +main: eu.mhsl.minecraft.bungeequeue.BungeeQueue +version: 0.1 \ No newline at end of file