package net.ME1312.SubServers.Bungee; import net.ME1312.Galaxi.Library.Container.ContainedPair; import net.ME1312.Galaxi.Library.Container.Pair; import net.ME1312.Galaxi.Library.Map.ObjectMap; import net.ME1312.Galaxi.Library.Platform; import net.ME1312.Galaxi.Library.Try; import net.ME1312.Galaxi.Library.Util; import net.ME1312.Galaxi.Library.Version.Version; import net.ME1312.SubData.Server.ClientHandler; import net.ME1312.SubData.Server.SubDataClient; import net.ME1312.SubServers.Bungee.Host.*; import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger; import net.ME1312.SubServers.Bungee.Network.Packet.PacketCheckPermission; import com.google.gson.Gson; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.plugin.Command; import net.md_5.bungee.api.plugin.TabExecutor; import net.md_5.bungee.command.ConsoleCommandSender; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; /** * Plugin Command Class */ @SuppressWarnings("deprecation") public final class SubCommand extends Command implements TabExecutor { static HashMap>> players = new HashMap>>(); private static Thread reload; private SubProxy plugin; private String label; SubCommand(SubProxy plugin, String command) { super(command); this.plugin = plugin; this.label = '/' + command; } /** * Load /sub in console * * @param sender Sender * @param args Arguments */ @SuppressWarnings("unchecked") public void execute(CommandSender sender, String[] args) { if (!(sender instanceof ProxiedPlayer)) { if (args.length > 0) { if (args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("?")) { sender.sendMessages(printHelp()); } else if (args[0].equalsIgnoreCase("version") || args[0].equalsIgnoreCase("ver")) { sender.sendMessage("SubServers > These are the platforms and versions that are running SubServers.Bungee:"); sender.sendMessage(" " + Platform.getSystemName() + ' ' + Platform.getSystemVersion() + ((Platform.getSystemBuild() != null)?" (" + Platform.getSystemBuild() + ')':"") + ((!Platform.getSystemArchitecture().equals("unknown"))?" [" + Platform.getSystemArchitecture() + ']':"") + ','); sender.sendMessage(" Java " + Platform.getJavaVersion() + ((!Platform.getJavaArchitecture().equals("unknown"))?" [" + Platform.getJavaArchitecture() + ']':"") + ','); sender.sendMessage(" " + plugin.getBungeeName() + ' ' + plugin.getVersion() + ((plugin.isPatched)?" [Patched]":"") + ','); sender.sendMessage(" SubServers.Bungee v" + SubProxy.version.toExtendedString() + ((plugin.api.getWrapperBuild() != null)?" (" + plugin.api.getWrapperBuild() + ')':"")); sender.sendMessage(""); new Thread(() -> { try { ObjectMap tags = new ObjectMap(new Gson().fromJson("{\"tags\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://api.github.com/repos/ME1312/SubServers-2/git/refs/tags").openStream(), Charset.forName("UTF-8")))) + '}', Map.class)); List versions = new LinkedList(); Version updversion = plugin.version; int updcount = 0; for (ObjectMap tag : tags.getMapList("tags")) versions.add(Version.fromString(tag.getString("ref").substring(10))); Collections.sort(versions); for (Version version : versions) { if (version.compareTo(updversion) > 0) { updversion = version; updcount++; } } if (updcount == 0) { sender.sendMessage("You are on the latest version."); } else { sender.sendMessage("SubServers.Bungee v" + updversion + " is available. You are " + updcount + " version" + ((updcount == 1)?"":"s") + " behind."); } } catch (Exception e) {} }, "SubServers.Bungee::Update_Check").start(); } else if (args[0].equalsIgnoreCase("reload")) { if (reload == null || !reload.isAlive()) (reload = new Thread(() -> { if (args.length > 1) { switch (args[1].toLowerCase()) { case "hard": case "system": case "subdata": case "network": plugin.stopListeners(); plugin.getLogger().info("Closing player connections"); for (ProxiedPlayer player : plugin.getPlayers()) { Try.all.run(() -> player.disconnect(plugin.getTranslation("restart"))); } plugin.shutdown(); case "*": case "all": case "soft": case "bungee": case "bungeecord": case "plugin": case "plugins": plugin.getPluginManager().dispatchCommand(ConsoleCommandSender.getInstance(), "greload"); break; case "host": case "hosts": case "server": case "servers": case "subserver": case "subservers": case "config": case "configs": try { plugin.reload(); } catch (IOException e) { e.printStackTrace(); } break; case "creator": case "creators": case "subcreator": case "subcreators": case "template": case "templates": for (Host host : plugin.api.getHosts().values()) { host.getCreator().reload(); } sender.sendMessage("SubServers > SubCreator instances reloaded"); break; default: sender.sendMessage("SubServers > Unknown reload type: " + args[1]); } } else { try { plugin.reload(); } catch (IOException e) { e.printStackTrace(); } } }, "SubServers.Bungee::Reload_Command_Handler")).start(); } else if (args[0].equalsIgnoreCase("list")) { String div = ChatColor.RESET + ", "; int i = 0; boolean sent = false; if (plugin.api.getGroups().keySet().size() > 0) { sender.sendMessage("SubServers > Group/Server List:"); for (String group : plugin.api.getGroups().keySet()) { String message = " "; message += ChatColor.GOLD + group + ChatColor.RESET + ": "; List names = new ArrayList(); Map servers = plugin.api.getServers(); for (Server server : plugin.api.getGroup(group).value()) names.add(server.getName()); Collections.sort(names); for (String name : names) { if (i != 0) message += div; Server server = servers.get(name.toLowerCase()); if (!(servers.get(name.toLowerCase()) instanceof SubServer)) { message += ChatColor.WHITE; } else if (((SubServer) server).isRunning()) { if (((SubServer) server).getStopAction() == SubServer.StopAction.REMOVE_SERVER || ((SubServer) server).getStopAction() == SubServer.StopAction.RECYCLE_SERVER || ((SubServer) server).getStopAction() == SubServer.StopAction.DELETE_SERVER) { message += ChatColor.AQUA; } else { message += ChatColor.GREEN; } } else if (((SubServer) server).getHost().isAvailable() && ((SubServer) server).getHost().isEnabled() && ((SubServer) server).isAvailable() && ((SubServer) server).isEnabled() && ((SubServer) server).getCurrentIncompatibilities().size() == 0) { message += ChatColor.YELLOW; } else { message += ChatColor.RED; } message += server.getDisplayName() + ((server.getName().equals(server.getDisplayName()))?"":" ["+server.getName()+']'); i++; } if (i == 0) message += ChatColor.RESET + "(none)"; sender.sendMessage(message); i = 0; sent = true; } if (!sent) sender.sendMessage(ChatColor.RESET + "(none)"); sent = false; } sender.sendMessage("SubServers > Host/SubServer List:"); for (Host host : plugin.api.getHosts().values()) { String message = " "; if (host.isAvailable() && host.isEnabled()) { message += ChatColor.AQUA; } else { message += ChatColor.RED; } message += host.getDisplayName() + " [" + ((host.getName().equals(host.getDisplayName()))?"":host.getName()+ChatColor.stripColor(div)) + host.getAddress().getHostAddress() + "]" + ChatColor.RESET + ": "; for (SubServer subserver : host.getSubServers().values()) { if (i != 0) message += div; if (subserver.isRunning()) { if (subserver.getStopAction() == SubServer.StopAction.REMOVE_SERVER || subserver.getStopAction() == SubServer.StopAction.RECYCLE_SERVER || subserver.getStopAction() == SubServer.StopAction.DELETE_SERVER) { message += ChatColor.AQUA; } else { message += ChatColor.GREEN; } } else if (subserver.getHost().isAvailable() && subserver.getHost().isEnabled() && subserver.isAvailable() && subserver.isEnabled() && subserver.getCurrentIncompatibilities().size() == 0) { message += ChatColor.YELLOW; } else { message += ChatColor.RED; } message += subserver.getDisplayName() + " [" + ((subserver.getName().equals(subserver.getDisplayName()))?"":subserver.getName()+ChatColor.stripColor(div)) + subserver.getAddress().getPort() + "]"; i++; } if (i == 0) message += ChatColor.RESET + "(none)"; sender.sendMessage(message); i = 0; sent = true; } if (!sent) sender.sendMessage(ChatColor.RESET + "(none)"); sender.sendMessage("SubServers > Server List:"); String message = " "; for (Server server : plugin.api.getServers().values()) { if (!(server instanceof SubServer)) { if (i != 0) message += div; message += ChatColor.WHITE + server.getDisplayName() + " [" + ((server.getName().equals(server.getDisplayName()))?"":server.getName()+ChatColor.stripColor(div)) + server.getAddress().getAddress().getHostAddress() + ':' + server.getAddress().getPort() + "]"; i++; } } if (i == 0) message += ChatColor.RESET + "(none)"; sender.sendMessage(message); if (plugin.api.getProxies().keySet().size() > 0) { sender.sendMessage("SubServers > Proxy List:"); message = " (master)"; for (Proxy proxy : plugin.api.getProxies().values()) { message += div; if (proxy.getSubData()[0] != null) { message += ChatColor.AQUA; } else { message += ChatColor.RED; } message += proxy.getDisplayName() + ((proxy.getName().equals(proxy.getDisplayName()))?"":" ["+proxy.getName()+']'); } sender.sendMessage(message); } } else if (args[0].equalsIgnoreCase("info") || args[0].equalsIgnoreCase("status")) { if (args.length > 1) { String type = (args.length > 2)?args[1]:null; String name = args[(type != null)?2:1]; Runnable getPlayer = () -> { RemotePlayer player = plugin.api.getRemotePlayer(name); if (player != null) { sender.sendMessage("SubServers > Info on player: " + ChatColor.WHITE + player.getName()); if (player.getProxy() != null) sender.sendMessage(" -> Proxy: " + ChatColor.WHITE + player.getProxy().getName()); if (player.getServer() != null) sender.sendMessage(" -> Server: " + ChatColor.WHITE + player.getServer().getName()); if (player.getAddress() != null) sender.sendMessage(" -> Address: " + ChatColor.WHITE + player.getAddress().getAddress().getHostAddress() + ':' + player.getAddress().getPort()); sender.sendMessage(" -> UUID: " + ChatColor.AQUA + player.getUniqueId()); } else { if (type == null) { sender.sendMessage("SubServers > There is no object with that name"); } else { sender.sendMessage("SubServers > There is no player with that name"); } } }; Runnable getServer = () -> { Server server = plugin.api.getServer(name); if (server != null) { sender.sendMessage("SubServers > Info on " + ((server instanceof SubServer)?"sub":"") + "server: " + ChatColor.WHITE + server.getDisplayName()); if (!server.getName().equals(server.getDisplayName())) sender.sendMessage(" -> System Name: " + ChatColor.WHITE + server.getName()); if (server instanceof SubServer) { sender.sendMessage(" -> Available: " + ((((SubServer) server).isAvailable())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); sender.sendMessage(" -> Enabled: " + ((((SubServer) server).isEnabled())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); if (!((SubServer) server).isEditable()) sender.sendMessage(" -> Editable: " + ChatColor.RED + "no"); sender.sendMessage(" -> Host: " + ChatColor.WHITE + ((SubServer) server).getHost().getName()); if (((SubServer) server).getTemplate() != null) sender.sendMessage(" -> Template: " + ChatColor.WHITE + ((SubServer) server).getTemplate().getName()); } if (server.getGroups().size() > 0) sender.sendMessage(" -> Group" + ((server.getGroups().size() > 1)?"s:":": " + ChatColor.WHITE + server.getGroups().get(0))); if (server.getGroups().size() > 1) for (String group : server.getGroups()) sender.sendMessage(" - " + ChatColor.WHITE + group); sender.sendMessage(" -> Address: " + ChatColor.WHITE + server.getAddress().getAddress().getHostAddress()+':'+server.getAddress().getPort()); if (server instanceof SubServer) sender.sendMessage(" -> " + ((((SubServer) server).isOnline())?"Online":"Running") + ": " + ((((SubServer) server).isRunning())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); if (!(server instanceof SubServer) || ((SubServer) server).isRunning()) { sender.sendMessage(" -> Connected: " + ((server.getSubData()[0] != null)?ChatColor.GREEN+"yes"+((server.getSubData().length > 1)?ChatColor.AQUA+" +"+(server.getSubData().length-1)+" subchannel"+((server.getSubData().length == 2)?"":"s"):""):ChatColor.RED+"no")); sender.sendMessage(" -> Players: " + ChatColor.AQUA + server.getRemotePlayers().size() + " online"); } sender.sendMessage(" -> MOTD: " + ChatColor.WHITE + ChatColor.stripColor(server.getMotd())); if (server instanceof SubServer && ((SubServer) server).getStopAction() != SubServer.StopAction.NONE) sender.sendMessage(" -> Stop Action: " + ChatColor.WHITE + ((SubServer) server).getStopAction().toString()); sender.sendMessage(" -> Signature: " + ChatColor.AQUA + server.getSignature()); if (server instanceof SubServer) sender.sendMessage(" -> Logging: " + ((((SubServer) server).isLogging())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); sender.sendMessage(" -> Restricted: " + ((server.isRestricted())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); if (server instanceof SubServer && ((SubServer) server).getIncompatibilities().size() > 0) { List current = new ArrayList(); for (SubServer other : ((SubServer) server).getCurrentIncompatibilities()) current.add(other.getName().toLowerCase()); sender.sendMessage(" -> Incompatibilities:"); for (SubServer other : ((SubServer) server).getIncompatibilities()) sender.sendMessage(" - " + ((current.contains(other.getName().toLowerCase()))?ChatColor.WHITE:ChatColor.GRAY) + other); } sender.sendMessage(" -> Hidden: " + ((server.isHidden())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); } else { if (type == null) { getPlayer.run(); } else { sender.sendMessage("SubServers > There is no server with that name"); } } }; Runnable getGroup = () -> { Pair> group = plugin.api.getGroup(name); if (group != null) { sender.sendMessage("SubServers > Info on group: " + ChatColor.WHITE + group.key()); sender.sendMessage(" -> Servers: " + ((group.value().size() <= 0)?ChatColor.GRAY + "(none)":ChatColor.AQUA.toString() + group.value().size())); for (Server server : group.value()) sender.sendMessage(" - " + ChatColor.WHITE + server.getDisplayName() + ((server.getName().equals(server.getDisplayName()))?"":" ["+server.getName()+']')); } else { if (type == null) { getServer.run(); } else { sender.sendMessage("SubServers > There is no group with that name"); } } }; Runnable getHost = () -> { Host host = plugin.api.getHost(name); if (host != null) { sender.sendMessage("SubServers > Info on host: " + ChatColor.WHITE + host.getDisplayName()); if (!host.getName().equals(host.getDisplayName())) sender.sendMessage(" -> System Name: " + ChatColor.WHITE + host.getName()); sender.sendMessage(" -> Available: " + ((host.isAvailable())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); sender.sendMessage(" -> Enabled: " + ((host.isEnabled())?ChatColor.GREEN+"yes":ChatColor.RED+"no")); sender.sendMessage(" -> Address: " + ChatColor.WHITE + host.getAddress().getHostAddress()); if (host instanceof ClientHandler) sender.sendMessage(" -> Connected: " + ((((ClientHandler) host).getSubData()[0] != null)?ChatColor.GREEN+"yes"+((((ClientHandler) host).getSubData().length > 1)?ChatColor.AQUA+" +"+(((ClientHandler) host).getSubData().length-1)+" subchannel"+((((ClientHandler) host).getSubData().length == 2)?"":"s"):""):ChatColor.RED+"no")); sender.sendMessage(" -> SubServers: " + ((host.getSubServers().keySet().size() <= 0)?ChatColor.GRAY + "(none)":ChatColor.AQUA.toString() + host.getSubServers().keySet().size())); for (SubServer subserver : host.getSubServers().values()) sender.sendMessage(" - " + ((subserver.isEnabled())?ChatColor.WHITE:ChatColor.GRAY) + subserver.getDisplayName() + ((subserver.getName().equals(subserver.getDisplayName()))?"":" ["+subserver.getName()+']')); sender.sendMessage(" -> Templates: " + ((host.getCreator().getTemplates().keySet().size() <= 0)?ChatColor.GRAY + "(none)":ChatColor.AQUA.toString() + host.getCreator().getTemplates().keySet().size())); for (SubCreator.ServerTemplate template : host.getCreator().getTemplates().values()) sender.sendMessage(" - " + ((template.isEnabled())?ChatColor.WHITE:ChatColor.GRAY) + template.getDisplayName() + ((template.getName().equals(template.getDisplayName()))?"":" ["+template.getName()+']')); sender.sendMessage(" -> Signature: " + ChatColor.AQUA + host.getSignature()); } else { if (type == null) { getGroup.run(); } else { sender.sendMessage("SubServers > There is no host with that name"); } } }; Runnable getProxy = () -> { Proxy proxy = plugin.api.getProxy(name); if (proxy != null) { sender.sendMessage("SubServers > Info on proxy: " + ChatColor.WHITE + proxy.getDisplayName()); if (!proxy.getName().equals(proxy.getDisplayName())) sender.sendMessage(" -> System Name: " + ChatColor.WHITE + proxy.getName()); if (!proxy.isMaster()) sender.sendMessage(" -> Connected: " + ((proxy.getSubData()[0] != null)?ChatColor.GREEN+"yes"+((proxy.getSubData().length > 1)?ChatColor.AQUA+" +"+(proxy.getSubData().length-1)+" subchannel"+((proxy.getSubData().length == 2)?"":"s"):""):ChatColor.RED+"no")); else if (!proxy.getDisplayName().toLowerCase().contains("master")) sender.sendMessage(" -> Type: " + ChatColor.WHITE + "Master"); sender.sendMessage(" -> Players: " + ChatColor.AQUA + proxy.getPlayers().size() + " online"); sender.sendMessage(" -> Signature: " + ChatColor.AQUA + proxy.getSignature()); } else { if (type == null) { getHost.run(); } else { sender.sendMessage("SubServers > There is no proxy with that name"); } } }; if (type == null) { getProxy.run(); } else { switch (type.toLowerCase()) { case "p": case "proxy": getProxy.run(); break; case "h": case "host": getHost.run(); break; case "g": case "group": getGroup.run(); break; case "s": case "server": case "subserver": getServer.run(); break; case "u": case "user": case "player": getPlayer.run(); break; default: sender.sendMessage("SubServers > There is no object type with that name"); } } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + " [proxy|host|group|server|player] "); } } else if (args[0].equalsIgnoreCase("start")) { if (args.length > 1) { ServerSelection select = selectServers(sender, args, 1, true); if (select.subservers.length > 0) { int success = 0, running = 0; for (SubServer server : select.subservers) { if (!server.getHost().isAvailable()) { sender.sendMessage("SubServers > The host for " + server.getName() + " is not available"); } else if (!server.getHost().isEnabled()) { sender.sendMessage("SubServers > The host for " + server.getName() + " is not enabled"); } else if (!server.isAvailable()) { sender.sendMessage("SubServers > Subserver " + server.getName() + " is not available"); } else if (!server.isEnabled()) { sender.sendMessage("SubServers > SubServer " + server.getName() + " is not enabled"); } else if (server.isRunning()) { running++; } else if (server.getCurrentIncompatibilities().size() != 0) { String list = ""; List others = server.getCurrentIncompatibilities(); for (SubServer other : others) { if (list.length() != 0) list += ", "; list += other.getName(); } sender.sendMessages("SubServers > Subserver " + server.getName() + " cannot start while these server"+((others.size() == 1)?"":"s")+" are running:", list); } else if (server.start()) { success++; } } if (running > 0) sender.sendMessage("SubServers > " + running + " subserver"+((running == 1)?" was":"s were") + " already running"); if (success > 0) sender.sendMessage("SubServers > Started " + success + " subserver"+((success == 1)?"":"s")); } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + " "); } } else if (args[0].equalsIgnoreCase("restart")) { if (args.length > 1) { ServerSelection select = selectServers(sender, args, 1, true); if (select.subservers.length > 0) { Consumer starter = server -> { Map servers = plugin.api.getServers(); if (!servers.keySet().contains(server.getName().toLowerCase()) || !(servers.get(server.getName().toLowerCase()) instanceof SubServer)) { sender.sendMessage("SubServers > Could not restart server: Subserver " + server.getName() + " has disappeared"); } else if (!(server = (SubServer) servers.get(server.getName().toLowerCase())).isRunning()) { if (!server.getHost().isAvailable()) { sender.sendMessage("SubServers > Could not restart server: The host for " + server.getName() + " is no longer available"); } else if (!server.getHost().isEnabled()) { sender.sendMessage("SubServers > Could not restart server: The host for " + server.getName() + " is no longer enabled"); } else if (!server.isAvailable()) { sender.sendMessage("SubServers > Could not restart server: Subserver " + server.getName() + " is no longer available"); } else if (!server.isEnabled()) { sender.sendMessage("SubServers > Could not restart server: Subserver " + server.getName() + " is no longer enabled"); } else if (server.getCurrentIncompatibilities().size() != 0) { String list = ""; List others = server.getCurrentIncompatibilities(); for (SubServer other : others) { if (list.length() != 0) list += ", "; list += other.getName(); } sender.sendMessages("Could not restart server: Subserver " + server.getName() + " cannot start while these server"+((others.size() == 1)?"":"s")+" are running:", list); } else { server.start(); } } }; int success = 0; for (SubServer server : select.subservers) { if (server.isRunning()) { if (server.stop()) { new Thread(() -> { try { server.waitFor(); Thread.sleep(100); starter.accept(server); } catch (Exception e) { e.printStackTrace(); } }, "SubServers.Bungee::Server_Restart_Command_Handler(" + server.getName() + ')').start(); success++; } } else { starter.accept(server); success++; } } if (success > 0) sender.sendMessage("SubServers > Restarting " + success + " subserver"+((success == 1)?"":"s")); } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + " "); } } else if (args[0].equalsIgnoreCase("stop")) { if (args.length > 1) { ServerSelection select = selectServers(sender, args, 1, true); if (select.subservers.length > 0) { int success = 0, running = 0; for (SubServer server : select.subservers) { if (!server.isRunning()) { running++; } else if (server.stop()) { success++; } } if (running > 0) sender.sendMessage("SubServers > " + running + " subserver"+((running == 1)?" was":"s were") + " already offline"); if (success > 0) sender.sendMessage("SubServers > Stopping " + success + " subserver"+((success == 1)?"":"s")); } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + " "); } } else if (args[0].equalsIgnoreCase("kill") || args[0].equalsIgnoreCase("terminate")) { if (args.length > 1) { ServerSelection select = selectServers(sender, args, 1, true); if (select.subservers.length > 0) { int success = 0, running = 0; for (SubServer server : select.subservers) { if (!server.isRunning()) { running++; } else if (server.terminate()) { success++; } } if (running > 0) sender.sendMessage("SubServers > " + running + " subserver"+((running == 1)?" was":"s were") + " already offline"); if (success > 0) sender.sendMessage("SubServers > Terminated " + success + " subserver"+((success == 1)?"":"s")); } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + " "); } } else if (args[0].equalsIgnoreCase("cmd") || args[0].equalsIgnoreCase("command")) { if (args.length > 1) { ServerSelection select = selectServers(sender, args, 1, true); if (select.subservers.length > 0) { if (select.args.length > 2) { StringBuilder builder = new StringBuilder(select.args[2]); for (int i = 3; i < select.args.length; i++) { builder.append(' '); builder.append(select.args[i]); } int success = 0, running = 0; String command = builder.toString(); for (SubServer server : select.subservers) { if (!server.isRunning()) { running++; } else if (server.command(command)) { success++; } } if (running > 0) sender.sendMessage("SubServers > " + running + " subserver"+((running == 1)?" was":"s were") + " offline"); if (success > 0) sender.sendMessage("SubServers > Sent command to " + success + " subserver"+((success == 1)?"":"s")); } else { sender.sendMessage("SubServers > No command was entered"); } } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + " [Args...]"); } } else if (args[0].equalsIgnoreCase("sudo") || args[0].equalsIgnoreCase("screen")) { if (plugin.canSudo) { if (args.length > 1) { Map servers = plugin.api.getServers(); if (!servers.keySet().contains(args[1].toLowerCase()) || !(servers.get(args[1].toLowerCase()) instanceof SubServer)) { sender.sendMessage("SubServers > There is no subserver with that name"); } else if (!((SubServer) servers.get(args[1].toLowerCase())).isRunning()) { sender.sendMessage("SubServers > That subserver is not running"); } else { plugin.sudo = (SubServer) servers.get(args[1].toLowerCase()); Logger.get("SubServers").info("Now forwarding commands to " + plugin.sudo.getDisplayName() + ". Type \"exit\" to return."); } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + " "); } } else { sender.sendMessage("SubServers > The BungeeCord library provided does not support console sudo."); } } else if (args[0].equalsIgnoreCase("create")) { if (args.length > 3) { if (plugin.api.getSubServers().keySet().contains(args[1].toLowerCase()) || SubCreator.isReserved(args[1])) { sender.sendMessage("SubServers > There is already a subserver with that name"); } else if (!plugin.hosts.keySet().contains(args[2].toLowerCase())) { sender.sendMessage("SubServers > There is no host with that name"); } else if (!plugin.hosts.get(args[2].toLowerCase()).isAvailable()) { sender.sendMessage("SubServers > That host is not available"); } else if (!plugin.hosts.get(args[2].toLowerCase()).isEnabled()) { sender.sendMessage("SubServers > That host is not enabled"); } else if (!plugin.hosts.get(args[2].toLowerCase()).getCreator().getTemplates().keySet().contains(args[3].toLowerCase())) { sender.sendMessage("SubServers > There is no template with that name"); } else if (!plugin.hosts.get(args[2].toLowerCase()).getCreator().getTemplate(args[3].toLowerCase()).isEnabled()) { sender.sendMessage("SubServers > That template is not enabled"); } else if (args.length <= 4 && plugin.hosts.get(args[2].toLowerCase()).getCreator().getTemplate(args[3].toLowerCase()).requiresVersion()) { sender.sendMessage("SubServers > That template requires a Minecraft version to be specified"); } else if (args.length > 5 && (!Try.all.run(() -> Integer.parseInt(args[5])) || Integer.parseInt(args[5]) <= 0 || Integer.parseInt(args[5]) > 65535)) { sender.sendMessage("SubServers > Invalid port number"); } else { plugin.hosts.get(args[2].toLowerCase()).getCreator().create(args[1], plugin.hosts.get(args[2].toLowerCase()).getCreator().getTemplate(args[3].toLowerCase()), (args.length > 4)?new Version(args[4]):null, (args.length > 5)?Integer.parseInt(args[5]):null); sender.sendMessage("SubServers > Creating subserver " + args[1]); } } else { sender.sendMessage("SubServers > Usage: " + label + " " + args[0].toLowerCase() + "