diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/External/ExternalSubServer.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/External/ExternalSubServer.java index 822a7dc7..09cfbf7c 100644 --- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/External/ExternalSubServer.java +++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/External/ExternalSubServer.java @@ -18,10 +18,7 @@ import java.io.IOException; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; +import java.util.*; /** * External SubServer Class @@ -212,7 +209,7 @@ public boolean command(UUID player, String command) { if (running) { SubSendCommandEvent event = new SubSendCommandEvent(player, this, command); host.plugin.getPluginManager().callEvent(event); - if (!event.isCancelled()) { + if (!event.isCancelled() && (player == null || !DISALLOWED_COMMANDS.matcher(command).find())) { history.add(new LoggedCommand(player, event.getCommand())); if (event.getCommand().equalsIgnoreCase(stopcmd)) { host.queue(new PacketExEditServer(this, PacketExEditServer.UpdateType.STOP)); diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Internal/InternalSubServer.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Internal/InternalSubServer.java index 0bbbe196..82693bcb 100644 --- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Internal/InternalSubServer.java +++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/Internal/InternalSubServer.java @@ -22,10 +22,7 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.jar.JarFile; import java.util.jar.JarInputStream; @@ -278,7 +275,7 @@ public boolean command(UUID player, String command) { if (thread != null && thread.isAlive()) { SubSendCommandEvent event = new SubSendCommandEvent(player, this, command); host.plugin.getPluginManager().callEvent(event); - if (!event.isCancelled()) { + if (!event.isCancelled() && (player == null || !DISALLOWED_COMMANDS.matcher(command).find())) { try { if (event.getCommand().equalsIgnoreCase(stopcmd)) allowrestart = false; history.add(new LoggedCommand(player, event.getCommand())); diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java index 4374547a..c9decd5b 100644 --- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java +++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Host/SubServerImpl.java @@ -12,11 +12,13 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import java.util.regex.Pattern; /** * SubServer Layout Class */ public abstract class SubServerImpl extends ServerImpl implements SubServer { + protected static final Pattern DISALLOWED_COMMANDS = Pattern.compile("^/?(?:[^\\s]+:)?sub(?:servers?)?(?:\\s|$)", Pattern.CASE_INSENSITIVE & Pattern.UNICODE_CASE); private List> incompatibilities = new ArrayList>(); private SubCreator.ServerTemplate templateV = null; private String templateS = null; diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/ConfigUpdater.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/ConfigUpdater.java index 0d0b50c8..bd8b5e01 100644 --- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/ConfigUpdater.java +++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/Library/ConfigUpdater.java @@ -318,7 +318,7 @@ public static void updateLang(File file) throws IOException { existing = updated.clone(); i++; - } if (was.compareTo(new Version("21w24h")) <= 0) { + } if (was.compareTo(new Version("21w27a")) <= 0) { //existing = updated.clone(); i++; @@ -446,6 +446,9 @@ public static void updateLang(File file) throws IOException { def.put("Command.Update.Template-Disabled", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c is not enabled"); def.put("Command.Update.Template-Invalid", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c does not support subserver updating"); def.put("Command.Update.Version-Required", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c requires a Minecraft version to be specified"); + def.put("Command.Delete.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared"); + def.put("Command.Delete.Running", "&cSubServers &4&l\\u00BB&c Cannot delete &4$str$&c while it is still running"); + def.put("Command.Delete", "&aSubServers &2&l\\u00BB&a Deleting &2$int$&a subserver(s)"); def.put("Command.Teleport", "&aSubServers &2&l\\u00BB&a Teleporting &2$str$&a to server"); def.put("Command.Teleport.Not-Running", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not running"); def.put("Interface.Generic.Back", "&cBack"); diff --git a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java index c7be19a5..2b83db37 100644 --- a/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java +++ b/SubServers.Bungee/src/net/ME1312/SubServers/Bungee/SubCommand.java @@ -638,7 +638,7 @@ public void execute(CommandSender sender, String[] args) { int success = 0; for (SubServer server : select.subservers) try { if (server.isRunning()) { - sender.sendMessage("SubServers > Subserver " + server.getName() + " is still running"); + sender.sendMessage("SubServers > Cannot delete " + server.getName() + " while it is still running"); } else if (server.getHost().recycleSubServer(server.getName())) { success++; } @@ -866,8 +866,8 @@ public List onTabComplete(CommandSender sender, String[] args) { return Collections.emptyList(); } else if (args.length <= 1) { List cmds = new ArrayList<>(); - cmds.addAll(Arrays.asList("help", "list", "info", "status", "version", "start", "restart", "stop", "kill", "terminate", "cmd", "command", "create", "update", "upgrade")); - if (!(sender instanceof ProxiedPlayer)) cmds.addAll(Arrays.asList("reload", "sudo", "screen", "remove", "delete", "restore")); + cmds.addAll(Arrays.asList("help", "list", "info", "status", "version", "start", "restart", "stop", "kill", "terminate", "cmd", "command", "create", "update", "upgrade", "restore")); + if (!(sender instanceof ProxiedPlayer)) cmds.addAll(Arrays.asList("reload", "sudo", "screen", "remove", "delete")); List list = new ArrayList(); for (String cmd : cmds) { if (cmd.startsWith(last)) list.add(Last + cmd.substring(last.length())); @@ -992,10 +992,10 @@ public List onTabComplete(CommandSender sender, String[] args) { args[0].equals("kill") || args[0].equals("terminate") || args[0].equals("cmd") || args[0].equals("command") || args[0].equals("update") || args[0].equals("upgrade") || + args[0].equals("remove") || args[0].equals("del") || args[0].equals("delete") || (!(sender instanceof ProxiedPlayer) && ( - args[0].equals("sudo") || args[0].equals("screen") || - args[0].equals("remove") || args[0].equals("del") || args[0].equals("delete") - ))) { + args[0].equals("sudo") || args[0].equals("screen") + ))) { List list = new ArrayList(); ServerSelection select = selectServers(null, args, 1, true); if (select.last != null) { @@ -1078,6 +1078,12 @@ public List onTabComplete(CommandSender sender, String[] args) { } else { return Collections.emptyList(); } + } else if (args[0].equals("restore")) { + if (args.length == 2) { + return Collections.singletonList(""); + } else { + return Collections.emptyList(); + } } else if (sender instanceof ProxiedPlayer && (args[0].equals("tp") || args[0].equals("teleport"))) { if (args.length == 2 || args.length == 3) { List list = new ArrayList(); diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java index ee11f2dc..e35afdc6 100644 --- a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java +++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/Library/ConfigUpdater.java @@ -56,6 +56,7 @@ public static void updateConfig(File file) throws IOException { YAMLSection settings = new YAMLSection(); settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString()); settings.set("API-Only-Mode", updated.getMap("Settings", new YAMLSection()).getBoolean("API-Only-Mode", false)); + settings.set("Allow-Deletion", updated.getMap("Settings", new YAMLSection()).getBoolean("Allow-Deletion", false)); settings.set("Show-Addresses", updated.getMap("Settings", new YAMLSection()).getBoolean("Show-Addresses", false)); settings.set("Use-Title-Messages", updated.getMap("Settings", new YAMLSection()).getBoolean("Use-Title-Messages", true)); settings.set("PlaceholderAPI-Ready", updated.getMap("Settings", new YAMLSection()).getBoolean("PlaceholderAPI-Ready", false)); diff --git a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java index 1a87301a..633fc05c 100644 --- a/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java +++ b/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubCommand.java @@ -51,7 +51,6 @@ public SubCommand(SubPlugin plugin, String name) { @Override public boolean execute(CommandSender sender, String label, String[] args) { - label = "/" + label; if (plugin.api.getSubDataNetwork()[0] == null || plugin.api.getSubDataNetwork()[0].isClosed()) { new IllegalStateException("SubData is not connected").printStackTrace(); if (!(sender instanceof ConsoleCommandSender)) sender.sendMessage(ChatColor.RED + "An exception has occurred while running this command"); @@ -59,6 +58,7 @@ public boolean execute(CommandSender sender, String label, String[] args) { new IllegalStateException("There are no lang options available at this time").printStackTrace(); if (!(sender instanceof ConsoleCommandSender)) sender.sendMessage(ChatColor.RED + "An exception has occurred while running this command"); } else { + label = "/" + label; if (sender.hasPermission("subservers.command")) { if (args.length > 0) { if (args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("?")) { @@ -730,6 +730,46 @@ public void run(ObjectMap json) { } else { sender.sendMessage(plugin.api.getLang("SubServers", "Command.Generic.Usage").replace("$str$", label.toLowerCase() + " " + args[0].toLowerCase() + " [[Template] ]")); } + } else if ((args[0].equalsIgnoreCase("remove") || args[0].equalsIgnoreCase("del") || args[0].equalsIgnoreCase("delete")) && plugin.config.get().getMap("Settings").getBoolean("Allow-Deletion", false)) { + if (args.length > 1) { + selectServers(sender, args, 1, true, "subservers.subserver.%.delete", select -> { + if (select.subservers.length > 0) { + Container success = new Container(0); + AsyncConsolidator merge = new AsyncConsolidator(() -> { + if (success.value > 0) sender.sendMessage(plugin.api.getLang("SubServers", "Command.Delete").replace("$int$", success.value.toString())); + }); + for (SubServer server : select.subservers) { + if (server.isRunning()) { + sender.sendMessage(plugin.api.getLang("SubServers", "Command.Delete.Running").replace("$str$", server.getName())); + } else { + server.getHost(host -> { + if (host == null) { + sender.sendMessage(plugin.api.getLang("SubServers", "Command.Delete.Disappeared").replace("$str$", server.getName())); + } else { + merge.reserve(); + host.recycleSubServer(server.getName(), response -> { + switch (response) { + case 3: + case 4: + sender.sendMessage(plugin.api.getLang("SubServers", "Command.Delete.Disappeared").replace("$str$", server.getName())); + break; + case 0: + success.value++; + break; + } + merge.release(); + }); + } + }); + } + } + } + }); + } else { + sender.sendMessage("Usage: " + label + " " + args[0].toLowerCase() + " "); + } + } else if (args[0].equalsIgnoreCase("restore")) { + // TODO } else if (args[0].equalsIgnoreCase("tp") || args[0].equalsIgnoreCase("teleport")) { executeTeleport(sender, label, args); } else if ((args[0].equalsIgnoreCase("view") || args[0].equalsIgnoreCase("open")) && sender instanceof Player) { diff --git a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Library/ConfigUpdater.java b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Library/ConfigUpdater.java index 2b774376..8558d1d7 100644 --- a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Library/ConfigUpdater.java +++ b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/Library/ConfigUpdater.java @@ -56,6 +56,7 @@ public static void updateConfig(File file) throws IOException { YAMLSection settings = new YAMLSection(); settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString()); settings.set("API-Only-Mode", updated.getMap("Settings", new YAMLSection()).getBoolean("API-Only-Mode", false)); + settings.set("Allow-Deletion", updated.getMap("Settings", new YAMLSection()).getBoolean("Allow-Deletion", false)); settings.set("Show-Addresses", updated.getMap("Settings", new YAMLSection()).getBoolean("Show-Addresses", false)); settings.set("Use-Title-Messages", updated.getMap("Settings", new YAMLSection()).getBoolean("Use-Title-Messages", true)); diff --git a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java index de4a3b56..1168c773 100644 --- a/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java +++ b/SubServers.Client/Sponge/src/net/ME1312/SubServers/Client/Sponge/SubCommand.java @@ -121,6 +121,11 @@ public CommandSpec spec() { .executor(new UPDATE()) .arguments(GenericArguments.optional(new ListArgument(Text.of("Subservers"))), GenericArguments.optional(GenericArguments.string(Text.of("Template"))), GenericArguments.optional(GenericArguments.string(Text.of("Version"))), GenericArguments.optional(GenericArguments.remainingJoinedStrings(Text.of("...")))) .build(), "update", "upgrade") + .child(CommandSpec.builder() + .description(Text.of("The SubServers Command - Delete")) + .executor(new DELETE()) + .arguments(GenericArguments.optional(new ListArgument(Text.of("Subservers"))), GenericArguments.optional(GenericArguments.remainingJoinedStrings(Text.of("...")))) + .build(), "remove", "del", "delete") .child(CommandSpec.builder() .description(Text.of("The SubServers Command - Teleport")) .executor(new TELEPORT()) @@ -1137,6 +1142,60 @@ public CommandResult execute(CommandSource sender, CommandContext args) throws C } } + public final class DELETE implements CommandExecutor { + public CommandResult execute(CommandSource sender, CommandContext args) throws CommandException { + if (plugin.config.get().getMap("Settings").getBoolean("Allow-Deletion", false)) { + if (canRun(sender)) { + Optional s = args.getOne(Text.of("Subservers")); + if (s.isPresent()) { + selectServers(sender, s.get(), true, "subservers.subserver.%.delete", select -> { + if (select.subservers.length > 0) { + Container success = new Container(0); + AsyncConsolidator merge = new AsyncConsolidator(() -> { + if (success.value > 0) sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Delete").replace("$int$", success.value.toString()))); + }); + for (SubServer server : select.subservers) { + if (server.isRunning()) { + sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Delete.Running").replace("$str$", server.getName()))); + } else { + server.getHost(host -> { + if (host == null) { + sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Delete.Disappeared").replace("$str$", server.getName()))); + } else { + merge.reserve(); + host.recycleSubServer(server.getName(), response -> { + switch (response) { + case 3: + case 4: + sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers", "Command.Delete.Disappeared").replace("$str$", server.getName()))); + break; + case 0: + success.value++; + break; + } + merge.release(); + }); + } + }); + } + } + } + }); + return CommandResult.builder().successCount(1).build(); + } else { + sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers","Command.Generic.Usage").replace("$str$", "/sub delete "))); + return CommandResult.builder().successCount(0).build(); + } + } else { + sender.sendMessage(ChatColor.convertColor(plugin.api.getLang("SubServers","Command.Generic.Invalid-Permission").replace("$str$", "subservers.command"))); + return CommandResult.builder().successCount(0).build(); + } + } else { + return CommandResult.builder().successCount(0).build(); + } + } + } + public final class TELEPORT implements CommandExecutor { public CommandResult execute(CommandSource sender, CommandContext args) throws CommandException { if (canRun(sender, true)) { diff --git a/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java b/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java index 0fa84c18..bad04478 100644 --- a/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java +++ b/SubServers.Host/src/net/ME1312/SubServers/Host/SubCommand.java @@ -927,13 +927,12 @@ public void command(CommandSender sender, String handle, String[] args) { selectServers(sender, args, 0, true, select -> { if (select.subservers.length > 0) { Container success = new Container(0); - Container running = new Container(0); AsyncConsolidator merge = new AsyncConsolidator(() -> { if (success.value > 0) sender.sendMessage("Removing " + success.value + " subserver"+((success.value == 1)?"":"s")); }); for (SubServer server : select.subservers) { if (server.isRunning()) { - sender.sendMessage("Subserver " + server.getName() + " is still running"); + sender.sendMessage("Cannot delete " + server.getName() + " while it is still running"); } else { server.getHost(host -> { if (host == null) { diff --git a/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java b/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java index 98be5e91..44c997a0 100644 --- a/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java +++ b/SubServers.Sync/src/net/ME1312/SubServers/Sync/SubCommand.java @@ -682,13 +682,12 @@ public void run() { selectServers(sender, args, 1, true, select -> { if (select.subservers.length > 0) { Container success = new Container(0); - Container running = new Container(0); AsyncConsolidator merge = new AsyncConsolidator(() -> { if (success.value > 0) sender.sendMessage("SubServers > Removing " + success.value + " subserver"+((success.value == 1)?"":"s")); }); for (SubServer server : select.subservers) { if (server.isRunning()) { - sender.sendMessage("SubServers > Subserver " + server.getName() + " is still running"); + sender.sendMessage("SubServers > Cannot delete " + server.getName() + " while it is still running"); } else { server.getHost(host -> { if (host == null) { @@ -968,8 +967,8 @@ public List onTabComplete(CommandSender sender, String[] args) { return Collections.emptyList(); } else if (args.length <= 1) { List cmds = new ArrayList<>(); - cmds.addAll(Arrays.asList("help", "list", "info", "status", "version", "start", "restart", "stop", "kill", "terminate", "cmd", "command", "create", "update", "upgrade")); - if (!(sender instanceof ProxiedPlayer)) cmds.addAll(Arrays.asList("reload", "sudo", "screen", "remove", "delete", "restore")); + cmds.addAll(Arrays.asList("help", "list", "info", "status", "version", "start", "restart", "stop", "kill", "terminate", "cmd", "command", "create", "update", "upgrade", "restore")); + if (!(sender instanceof ProxiedPlayer)) cmds.addAll(Arrays.asList("remove", "delete")); updateCache(); @@ -1074,24 +1073,13 @@ public List onTabComplete(CommandSender sender, String[] args) { } else { return Collections.emptyList(); } - } else if (!(sender instanceof ProxiedPlayer) && (args[0].equals("restore"))) { - /* if (args[0].equals("restore")) */ { - if (args.length == 2) { - return Collections.singletonList(""); - } else { - return Collections.emptyList(); - } - } } else if (args[0].equals("start") || args[0].equals("restart") || args[0].equals("stop") || args[0].equals("kill") || args[0].equals("terminate") || args[0].equals("cmd") || args[0].equals("command") || args[0].equals("update") || args[0].equals("upgrade") || - (!(sender instanceof ProxiedPlayer) && ( - args[0].equals("sudo") || args[0].equals("screen") || - args[0].equals("remove") || args[0].equals("del") || args[0].equals("delete") - ))) { + args[0].equals("remove") || args[0].equals("del") || args[0].equals("delete")) { List list = new ArrayList(); RawServerSelection select = selectRawServers(null, args, 1, true); if (select.last != null) { @@ -1175,6 +1163,12 @@ public List onTabComplete(CommandSender sender, String[] args) { } else { return Collections.emptyList(); } + } else if (args[0].equals("restore")) { + if (args.length == 2) { + return Collections.singletonList(""); + } else { + return Collections.emptyList(); + } } else if (sender instanceof ProxiedPlayer && (args[0].equals("tp") || args[0].equals("teleport"))) { if (args.length == 2 || args.length == 3) { List list = new ArrayList();