diff --git a/CommonCore b/CommonCore index 47bd9af0..9df92595 160000 --- a/CommonCore +++ b/CommonCore @@ -1 +1 @@ -Subproject commit 47bd9af03eb987f94777f3b13f6ae6c30f153393 +Subproject commit 9df92595b2f344585bd3e1639cedc761680b7761 diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index 5660af13..e319ed69 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -61,11 +61,7 @@ public class BungeeCore extends Plugin { public static boolean MAIN_SERVER; public static String CHAT_PREFIX; - public static String WORLD_FOLDER; - public static String BAUWELT_PROTOTYP; public static String LOBBY_SERVER; - public static String USERWORLDS15; - public static String BAUWELT15; public static boolean EVENT_MODE; private static BungeeCore instance; @@ -73,6 +69,7 @@ public class BungeeCore extends Plugin { public static final Map serverPermissions = new HashMap<>(); public static final Map commands = new HashMap<>(); + public static Node local; private ErrorLogger errorLogger; private TablistManager tablistManager; @@ -114,9 +111,8 @@ public class BungeeCore extends Plugin { new Fabric(); new SubserverProtocolFixer(); - new Node.LocalNode(); + local = new Node.LocalNode(); //new Node.RemoteNode("lx"); - //new Node.RemoteNode("az"); commands.put("/tp", null); commands.put("/bc", null); @@ -154,6 +150,7 @@ public class BungeeCore extends Plugin { new RankCommand(); new LocalCommand(); new SetLocaleCommand(); + new BuilderCloudCommand(); // Punishment Commands: new PunishmentCommand("ban", Punishment.PunishmentType.Ban); @@ -168,7 +165,7 @@ public class BungeeCore extends Plugin { if(!EVENT_MODE){ new BauCommand(); - new WebregisterCommand(); + new WebpasswordCommand(); new FightCommand(); new ChallengeCommand(); new HistoricCommand(); @@ -299,11 +296,7 @@ public class BungeeCore extends Plugin { } CHAT_PREFIX = config.getString("prefix"); - WORLD_FOLDER = config.getString("worldfolder"); - BAUWELT_PROTOTYP = config.getString("bauweltprototyp"); LOBBY_SERVER = config.getString("lobbyserver"); - USERWORLDS15 = config.getString("userworlds15"); - BAUWELT15 = config.getString("bauwelt15"); EVENT_MODE = config.getBoolean("eventmode"); Broadcaster.setBroadCastMsgs(config.getStringList("broadcasts").toArray(new String[1])); PollSystem.init(config.getString("poll.question"), config.getStringList("poll.answers")); diff --git a/src/de/steamwar/bungeecore/ErrorLogger.java b/src/de/steamwar/bungeecore/ErrorLogger.java index c60d7aa9..2ac83aee 100644 --- a/src/de/steamwar/bungeecore/ErrorLogger.java +++ b/src/de/steamwar/bungeecore/ErrorLogger.java @@ -33,7 +33,6 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; public class ErrorLogger extends Handler { - private int ddosRate = 0; ErrorLogger(){ Logger.getLogger("").addHandler(this); @@ -57,12 +56,7 @@ public class ErrorLogger extends Handler { if(logRecord.getThrown() != null) logRecord.getThrown().printStackTrace(new PrintStream(stacktraceOutput)); String stacktrace = stacktraceOutput.toString(); - if(stacktrace.contains("Cannot request protocol")) { - if(++ddosRate % 1000 == 0) { - SWException.log("Bungee", "DDOS", ddosRate + ""); - } - return; - } else if (stacktrace.contains("ErrorLogger")) { + if (stacktrace.contains("ErrorLogger")) { return; } @@ -86,10 +80,12 @@ public class ErrorLogger extends Handler { List contains = new ArrayList<>(); contains.add("Error authenticating "); contains.add("read timed out"); + contains.add("could not decode packet"); contains.add("Connection reset by peer"); contains.add("No client connected for pending server"); contains.add("Error occurred processing connection for"); contains.add("Server is online mode!"); + contains.add(" took "); ignoreContains = Collections.unmodifiableList(contains); } } diff --git a/src/de/steamwar/bungeecore/Node.java b/src/de/steamwar/bungeecore/Node.java index f07293aa..6c221200 100644 --- a/src/de/steamwar/bungeecore/Node.java +++ b/src/de/steamwar/bungeecore/Node.java @@ -19,6 +19,7 @@ package de.steamwar.bungeecore; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.ProxyServer; import java.io.*; @@ -30,7 +31,6 @@ import java.util.logging.Level; public abstract class Node { private static final List OPENJ9_ARGS = Arrays.asList("-Xgc:excessiveGCratio=80", "-Xsyslog:none", "-Xtrace:none", "-Xdisableexplicitgc", "-XX:+AlwaysPreTouch", "-XX:+CompactStrings", "-XX:-HeapDumpOnOutOfMemory", "-XX:+ExitOnOutOfMemoryError", "-Dlog4j.configurationFile=log4j2.xml"); - private static final double MIN_FREE_MEM = 4.0 * 1024 * 1024; // 4 GiB private static final Set JAVA_8 = new HashSet<>(); static { JAVA_8.add("paper-1.8.8.jar"); @@ -40,43 +40,57 @@ public abstract class Node { JAVA_8.add("spigot-1.10.2.jar"); } + private static final long MIN_FREE_MEM = 4 * 1024 * 1024L; // 4 GiB + private static final double MAX_LOAD = 0.8; + private static final List nodes = new ArrayList<>(); - public static Node local = null; public static Node getNode() { - Node node = local; - double minLoad = local.getLoad(); - if(minLoad < 0.5) - return local; - - synchronized (nodes) { - Iterator it = nodes.iterator(); - while(it.hasNext()) { - Node n = it.next(); - double load = n.getLoad(); - if (load < minLoad) { - minLoad = load; - node = n; - } else if (load == Double.POSITIVE_INFINITY) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Removing " + n.getName() + " due to infinite load!"); - it.remove(); - } - } + for(Node node : nodes) { + if(node.belowLoadLimit) + return node; } - return node; + return null; } public static void forEach(Consumer consumer) { - consumer.accept(local); - synchronized (nodes) { - nodes.forEach(consumer); - } + nodes.forEach(consumer); } public abstract ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams); - public abstract void execute(String... command); - public abstract String getName(); - public abstract double getLoad(); + + protected abstract ProcessBuilder prepareExecution(String... command); + protected abstract void calcLoadLimit(); + + protected final String hostname; + protected volatile boolean belowLoadLimit = true; + + private long previousCpuLoaded = 0; + private long previousCpuTotal = 0; + + protected Node(String hostname) { + this.hostname = hostname; + nodes.add(this); + BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), this::calcLoadLimit, 1, 2, TimeUnit.SECONDS); + } + + public void execute(String... command) { + try { + prepareExecution(command).start().waitFor(); + } catch (IOException e) { + throw new SecurityException("Could not execute command", e); + } catch (InterruptedException e) { + ProxyServer.getInstance().getLogger().log(Level.SEVERE, "Interrupted during execution", e); + Thread.currentThread().interrupt(); + } + } + + public boolean belowLoadLimit() { + return belowLoadLimit; + } + public String getName() { + return hostname; + } protected void constructServerstart(File directory, List cmd, String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams) { if (JAVA_8.contains(serverJar)) @@ -106,26 +120,31 @@ public abstract class Node { cmd.add("nogui"); } - protected void execute(ProcessBuilder builder) { - try { - builder.start().waitFor(); - } catch (IOException e) { - throw new SecurityException("Could not execute command", e); - } catch (InterruptedException e) { - ProxyServer.getInstance().getLogger().log(Level.SEVERE, "Interrupted during execution", e); - Thread.currentThread().interrupt(); + protected void calcLoadLimit(BufferedReader stat, BufferedReader meminfo) throws IOException { + String[] cpuline = stat.readLine().split(" "); // 0-1: prefix, 2: user, 3: nice, 4: system, 5: idle, 6: iowait, 7: irq, 8: softirq, 9: steal, 10: guest, 11: guest_nice + long cpuLoaded = Long.parseLong(cpuline[2]) + Long.parseLong(cpuline[4]) + Long.parseLong(cpuline[6]) + Long.parseLong(cpuline[7]) + Long.parseLong(cpuline[8]) + Long.parseLong(cpuline[9]) + Long.parseLong(cpuline[10]) + Long.parseLong(cpuline[11]); + long cpuTotal = cpuLoaded + Long.parseLong(cpuline[3]) + Long.parseLong(cpuline[5]); + + cpuLoaded -= previousCpuLoaded; + cpuTotal -= previousCpuTotal; + previousCpuLoaded += cpuLoaded; + previousCpuTotal += cpuTotal; + + String line = meminfo.readLine(); + while(!line.startsWith("MemAvailable")) { + line = meminfo.readLine(); } + + long availableMem = Long.parseLong(line.replaceAll(" +", " ").split(" ")[1]); + belowLoadLimit = cpuLoaded / (double)cpuTotal <= MAX_LOAD && availableMem >= MIN_FREE_MEM; } public static class LocalNode extends Node { - private static final File meminfo = new File("/proc/meminfo"); - private static final File loadavg = new File("/proc/loadavg"); - - private final int cores; + private static final File MEMINFO = new File("/proc/meminfo"); + private static final File STAT = new File("/proc/stat"); public LocalNode() { - this.cores = Runtime.getRuntime().availableProcessors(); - local = this; + super("sw"); } @Override @@ -138,74 +157,28 @@ public abstract class Node { } @Override - public void execute(String... command) { - execute(new ProcessBuilder(command)); + protected void calcLoadLimit() { + try (BufferedReader loadavg = new BufferedReader(new InputStreamReader(new FileInputStream(STAT)))) { + try (BufferedReader meminfo = new BufferedReader(new InputStreamReader(new FileInputStream(MEMINFO)))) { + calcLoadLimit(loadavg, meminfo); + } + } catch (IOException e) { + BungeeCore.get().getLogger().log(Level.SEVERE, "Could not read local load", e); + belowLoadLimit = false; + } } @Override - public String getName() { - return "local"; - } - - @Override - public double getLoad() { - double totalMem; - double freeMem; - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(meminfo)))) { - totalMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]); - bufferedReader.readLine(); - freeMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]); - } catch (IOException e) { - throw new SecurityException("Could not read local memory", e); - } - - double cpuLoad; - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(loadavg)))) { - cpuLoad = Double.parseDouble(bufferedReader.readLine().split(" ")[0]); - } catch (IOException e) { - throw new SecurityException("Could not read local cpu", e); - } - - return cpuLoad / cores + (freeMem > MIN_FREE_MEM ? 0 : ((totalMem - freeMem) / totalMem)); + protected ProcessBuilder prepareExecution(String... command) { + return new ProcessBuilder(command); } } public static class RemoteNode extends Node { - private final int cores; - private final String remote; - public RemoteNode(String remote) { - this.remote = remote; - - //Determine core count - Process process; - try { - process = new ProcessBuilder("ssh", remote, "nproc").start(); - if(!process.waitFor(5, TimeUnit.SECONDS)) - throw new IOException("Timeout of " + remote + " on init"); - } catch (IOException e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Could not initialize " + remote); - cores = 1; - return; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - cores = 1; - return; - } - - int c; - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - c = Integer.parseInt(bufferedReader.readLine()); - } catch (IOException | NumberFormatException e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Could not read cores of" + remote, e); - c = 1; - } - cores = c; - BungeeCore.get().getLogger().log(Level.INFO, "Adding node " + remote + " with " + cores + " cores."); - - synchronized (nodes) { - nodes.add(this); - } + public RemoteNode(String hostname) { + super(hostname); + BungeeCore.get().getLogger().log(Level.INFO, "Added node " + hostname); } @Override @@ -214,7 +187,7 @@ public abstract class Node { cmd.add("ssh"); cmd.add("-L"); cmd.add(port + ":localhost:" + port); - cmd.add(remote); + cmd.add(hostname); cmd.add("cd"); cmd.add(directory.getPath()); cmd.add(";"); @@ -223,43 +196,30 @@ public abstract class Node { } @Override - public void execute(String... command) { + protected ProcessBuilder prepareExecution(String... command) { List cmd = new ArrayList<>(); cmd.add("ssh"); - cmd.add(remote); + cmd.add(hostname); cmd.addAll(Arrays.asList(command)); - execute(new ProcessBuilder(cmd)); + return new ProcessBuilder(cmd); } @Override - public String getName() { - return remote; - } - - @Override - public double getLoad() { - Process process; + protected void calcLoadLimit() { try { - process = new ProcessBuilder("ssh", remote, "cat /proc/loadavg;cat /proc/meminfo").start(); - if(!process.waitFor(1, TimeUnit.SECONDS)) - return Double.POSITIVE_INFINITY; + Process process = prepareExecution("cat /proc/stat /proc/meminfo").start(); + if(process.waitFor(1, TimeUnit.SECONDS)) + throw new IOException(hostname + " timeout"); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + calcLoadLimit(reader, reader); + } } catch (IOException e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Could starting process to read load", e); - return Double.POSITIVE_INFINITY; + if(belowLoadLimit) + BungeeCore.get().getLogger().log(Level.SEVERE, "Could read remote load", e); + belowLoadLimit = false; } catch (InterruptedException e) { Thread.currentThread().interrupt(); - return Double.POSITIVE_INFINITY; - } - - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - double cpuLoad = Double.parseDouble(bufferedReader.readLine().split(" ")[0]); - double totalMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]); - bufferedReader.readLine(); - double freeMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]); - return cpuLoad / cores + (freeMem > MIN_FREE_MEM ? 0 : ((totalMem - freeMem) / totalMem)); - } catch (IOException e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Could read load", e); - return Double.POSITIVE_INFINITY; + belowLoadLimit = false; } } } diff --git a/src/de/steamwar/bungeecore/ServerStarter.java b/src/de/steamwar/bungeecore/ServerStarter.java index c6bdca04..9373b57f 100644 --- a/src/de/steamwar/bungeecore/ServerStarter.java +++ b/src/de/steamwar/bungeecore/ServerStarter.java @@ -4,10 +4,13 @@ import de.steamwar.bungeecore.sql.EventFight; import de.steamwar.bungeecore.sql.SteamwarUser; import de.steamwar.bungeecore.sql.Team; import de.steamwar.bungeecore.sql.Tutorial; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.io.File; +import java.io.IOException; import java.net.InetSocketAddress; +import java.nio.file.Files; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.BooleanSupplier; @@ -19,12 +22,16 @@ public class ServerStarter { private static final Portrange BAU_PORTS = BungeeCore.MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200); private static final Portrange ARENA_PORTS = BungeeCore.MAIN_SERVER ? new Portrange(3000, 3100) : (BungeeCore.EVENT_MODE ? new Portrange(4000, 5000) : BAU_PORTS); - private static final String BACKBONE = System.getProperty("user.home") + "/"; - private static final String SERVER_PATH = BACKBONE + "server/"; - private static final String EVENT_PATH = BACKBONE + "event/"; - public static final String TEMP_WORLD_PATH = BACKBONE + "arenaserver/"; - public static final String TUTORIAL_PATH = BACKBONE + "tutorials/"; - public static final String WORLDS19_PATH = BACKBONE + "userworlds19/"; + private static final String SERVER_PATH = "/servers/"; + private static final String USER_HOME = System.getProperty("user.home") + "/"; + private static final String EVENT_PATH = USER_HOME + "event/"; + public static final String TEMP_WORLD_PATH = USER_HOME + "arenaserver/"; + public static final String TUTORIAL_PATH = USER_HOME + "tutorials/"; + public static final String WORLDS12_PATH = USER_HOME + "userworlds/"; + public static final String WORLDS15_PATH = USER_HOME + "userworlds15/"; + public static final String WORLDS19_PATH = USER_HOME + "userworlds19/"; + + public static final String BUILDER_BASE_PATH = USER_HOME + "builder"; private File directory = null; private String worldDir = null; @@ -61,7 +68,7 @@ public class ServerStarter { public ServerStarter event(EventFight eventFight) { arena(eventFight.getSpielmodus(), eventFight.getMap()); - node = Node.local; + node = BungeeCore.local; worldDir = EVENT_PATH; worldCleanup = () -> {}; arguments.put("fightID", String.valueOf(eventFight.getFightID())); @@ -109,7 +116,7 @@ public class ServerStarter { public ServerStarter build19(UUID owner) { directory = new File(SERVER_PATH, "Bau19"); - serverJar = "paper-1.19.1.jar"; + serverJar = "paper-1.19.2.jar"; worldDir = WORLDS19_PATH; worldName = String.valueOf(SteamwarUser.get(owner).getId()); buildWithWorld(owner, new File(directory, "Bauwelt").getPath()); @@ -118,19 +125,19 @@ public class ServerStarter { public ServerStarter build15(UUID owner) { directory = new File(SERVER_PATH, "Bau15"); - worldDir = BungeeCore.USERWORLDS15; + worldDir = WORLDS15_PATH; worldName = String.valueOf(SteamwarUser.get(owner).getId()); - buildWithWorld(owner, BungeeCore.BAUWELT15); + buildWithWorld(owner, new File(directory, "Bauwelt").getPath()); return this; } public ServerStarter build12(UUID owner) { - directory = new File(SERVER_PATH, "UserBau"); + directory = new File(SERVER_PATH, "Bau12"); serverJar = "spigot-1.12.2.jar"; xmx = "256M"; - worldDir = BungeeCore.WORLD_FOLDER; + worldDir = WORLDS12_PATH; worldName = owner.toString(); - buildWithWorld(owner, BungeeCore.BAUWELT_PROTOTYP); + buildWithWorld(owner, new File(directory, "Bauwelt").getPath()); return this; } @@ -194,6 +201,40 @@ public class ServerStarter { serverNameProvider = port -> bauServerName(SteamwarUser.get(owner)); } + public ServerStarter builder(Version version, String map, File generator) { + serverJar = version.getServerJar(); + directory = version.getServerDirectory("Builder"); + worldDir = version.getWorldFolder(BUILDER_BASE_PATH); + worldName = map; + serverNameProvider = port -> "⛏" + map; + constructor = (serverName, port, builder, shutdownCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback); + + // Send players to existing server + startCondition = () -> { + for(Subserver subserver : Subserver.getServerList()) { + if(subserver.getType() == Servertype.BUILDER && ((Builderserver)subserver).getMap().equals(worldName)) { + for(ProxiedPlayer p : playersToSend) + SubserverSystem.sendPlayer(subserver, p); + return false; + } + } + return true; + }; + + if(generator != null) { + worldSetup = () -> { + File leveldat = new File(new File(worldDir, worldName), "level.dat"); + try { + Files.copy(generator.toPath(), leveldat.toPath()); + } catch (IOException e) { + throw new SecurityException(e); + } + }; + } + + return this; + } + public ServerStarter send(ProxiedPlayer player) { playersToSend.add(player); return this; @@ -206,8 +247,15 @@ public class ServerStarter { int port = portrange.freePort(); String serverName = serverNameProvider.apply(port); - if(node == null) + if(node == null) { node = Node.getNode(); + if(node == null) { + for (ProxiedPlayer p : playersToSend) + ChatSender.of(p).system("SERVER_START_OVERLOAD"); + + return null; + } + } if(worldName == null) worldName = serverToWorldName(serverName); @@ -285,4 +333,30 @@ public class ServerStarter { return result; } } -} + + public enum Version { + SPIGOT_12("spigot-1.12.2.jar", 12), + SPIGOT_15("spigot-1.15.2.jar", 15), + PAPER_19("paper-1.19.2.jar", 19); + + private final String serverJar; + private final int versionSuffix; + + Version(String serverJar, int versionSuffix) { + this.serverJar = serverJar; + this.versionSuffix = versionSuffix; + } + + public String getServerJar() { + return serverJar; + } + + public String getWorldFolder(String base) { + return base + versionSuffix + "/"; + } + + public File getServerDirectory(String base) { + return new File(SERVER_PATH, base + versionSuffix); + } + } +} \ No newline at end of file diff --git a/src/de/steamwar/bungeecore/commands/BauCommand.java b/src/de/steamwar/bungeecore/commands/BauCommand.java index 6a4e4a63..dbfa4238 100644 --- a/src/de/steamwar/bungeecore/commands/BauCommand.java +++ b/src/de/steamwar/bungeecore/commands/BauCommand.java @@ -257,8 +257,8 @@ public class BauCommand extends BasicCommand { SteamwarUser user = SteamwarUser.get(p.getUniqueId()); versionSelector(p, args, 1, () -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS19_PATH + user.getId())), - () -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.USERWORLDS15 + user.getId())), - () -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.WORLD_FOLDER + p.getUniqueId().toString())), + () -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS15_PATH + user.getId())), + () -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS12_PATH + p.getUniqueId().toString())), () -> HelpCommand.sendBauHelp(ChatSender.of(p))); } @@ -282,7 +282,7 @@ public class BauCommand extends BasicCommand { break; } } - SubserverSystem.deleteFolder(Node.local, world); + SubserverSystem.deleteFolder(BungeeCore.local, world); Message.send("BAU_DELETE_DELETED", player); }); } diff --git a/src/de/steamwar/bungeecore/commands/BuilderCloudCommand.java b/src/de/steamwar/bungeecore/commands/BuilderCloudCommand.java new file mode 100644 index 00000000..54369197 --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/BuilderCloudCommand.java @@ -0,0 +1,121 @@ +package de.steamwar.bungeecore.commands; + +import de.steamwar.bungeecore.ServerStarter; +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeMapper; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +public class BuilderCloudCommand extends SWCommand { + + private final Map versionMap = new HashMap<>(); + + public BuilderCloudCommand() { + super("buildercloud", "bungeecore.server.team"); + + versionMap.put("15", ServerStarter.Version.SPIGOT_15); + versionMap.put("1.15", ServerStarter.Version.SPIGOT_15); + versionMap.put("1.15.2", ServerStarter.Version.SPIGOT_15); + versionMap.put("19", ServerStarter.Version.PAPER_19); + versionMap.put("1.19", ServerStarter.Version.PAPER_19); + versionMap.put("1.19.2", ServerStarter.Version.PAPER_19); + } + + @Register(description = "BUILDERCLOUD_USAGE") + public void genericCommand(ProxiedPlayer player, @ErrorMessage("BUILDERCLOUD_VERSION") ServerStarter.Version version, @Mapper("map") String map, @OptionalValue("") @Mapper("generator") @AllowNull File generator) { + new ServerStarter().builder(version, map, generator).send(player).start(); + } + + @ClassMapper(value = ServerStarter.Version.class, local = true) + private TypeMapper versionTypeMapper() { + return new TypeMapper() { + @Override + public ServerStarter.Version map(CommandSender commandSender, String[] previousArguments, String s) { + return versionMap.get(s); + } + + @Override + public Collection tabCompletes(CommandSender sender, String[] previousArguments, String s) { + return versionMap.keySet(); + } + }; + } + + @Cached(global = true) + @Mapper(value = "map", local = true) + private TypeMapper mapTypeMapper() { + + return new TypeMapper() { + @Override + public String map(CommandSender commandSender, String[] previousArguments, String s) { + File folder = getWorldFolder(previousArguments, 1); + + if(folder == null) + return null; + + File map = new File(folder, s); + if(!map.exists() && !map.mkdir()) + return null; + + return map.getName(); + } + + @Override + public Collection tabCompletes(CommandSender sender, String[] previousArguments, String s) { + File folder = getWorldFolder(previousArguments, 1); + + String[] files; + if(folder == null || (files = folder.list()) == null) + return Collections.emptyList(); + + return Arrays.stream(files).filter(file -> new File(folder, file).isDirectory()).collect(Collectors.toList()); + } + }; + } + + @Cached(global = true) + @Mapper(value = "generator", local = true) + private TypeMapper generatorTypeMapper() { + + return new TypeMapper() { + @Override + public File map(CommandSender commandSender, String[] previousArguments, String s) { + if(s.equals("")) + return null; + + File folder = getWorldFolder(previousArguments, 2); + + if(folder == null) + throw new SecurityException(); + + File generator = new File(folder, s + ".dat"); + if(!generator.exists() || !generator.isFile()) + throw new SecurityException(); + + return generator; + } + + @Override + public Collection tabCompletes(CommandSender sender, String[] previousArguments, String s) { + File folder = getWorldFolder(previousArguments, 2); + + String[] files; + if(folder == null || (files = folder.list()) == null) + return Collections.emptyList(); + + return Arrays.stream(files).filter(file -> new File(folder, file).isFile()).filter(file -> file.endsWith(".dat")).map(file -> file.substring(0, file.length() - 4)).collect(Collectors.toList()); + } + }; + } + + private File getWorldFolder(String[] previousArguments, int offset) { + ServerStarter.Version v = versionMap.get(previousArguments[previousArguments.length - offset]); + if(v == null) + return null; + return new File(v.getWorldFolder(ServerStarter.BUILDER_BASE_PATH)); + } +} diff --git a/src/de/steamwar/bungeecore/commands/ChallengeCommand.java b/src/de/steamwar/bungeecore/commands/ChallengeCommand.java index 92fa0a72..6f050ac9 100644 --- a/src/de/steamwar/bungeecore/commands/ChallengeCommand.java +++ b/src/de/steamwar/bungeecore/commands/ChallengeCommand.java @@ -20,88 +20,75 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.*; -import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker; import de.steamwar.bungeecore.sql.IgnoreSystem; -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.ProxyServer; +import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeValidator; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.connection.ProxiedPlayer; -import java.util.ArrayList; import java.util.LinkedList; import static de.steamwar.bungeecore.Storage.challenges; -public class ChallengeCommand extends BasicCommand { +public class ChallengeCommand extends SWCommand { public ChallengeCommand() { - super("challenge", ""); + super("challenge"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(args.length < 1){ - Message.send("CHALLENGE_USAGE", sender); - return; - } - - if (!(sender instanceof ProxiedPlayer)) - return; - - if(ModLoaderBlocker.isFabric((ProxiedPlayer) sender)) { - Message.send("MODLOADER_DENIED", sender); - return; - } - - ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]); - if(target == null){ - Message.send("CHALLENGE_OFFLINE", sender); - return; - }else if(target == sender){ - Message.send("CHALLENGE_SELF", sender); - return; - }else if (IgnoreSystem.isIgnored(target, (ProxiedPlayer) sender)) { - Message.send("CHALLENGE_IGNORED", sender); - return; - } - - Subserver subserver = Subserver.getSubserver(target); - if(subserver != null && subserver.getType() == Servertype.ARENA){ - Message.send("CHALLENGE_INARENA", sender); - return; - } - - FightCommand.createArena(sender, "/challenge " + target.getName() + " ", false, args, 1, false, (player, mode, map) -> { - if(challenges.containsKey(target) && challenges.get(target).contains(player)){ + @Register(description = "CHALLENGE_USAGE") + public void challenge(@Validator("arenaPlayer") ProxiedPlayer player, @Validator("target") ProxiedPlayer target, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) { + FightCommand.createArena(player, "/challenge " + target.getName() + " ", false, arenaMode, map, false, (p, mode, m) -> { + if(challenges.containsKey(target) && challenges.get(target).contains(p)){ challenges.remove(target); - challenges.remove(player); + challenges.remove(p); Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).redLeader(target).start(); - Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER", - new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName(), target.getName()); + if(arena != null) { + Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER", + new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName(), target.getName()); + } }else{ - if(!challenges.containsKey(player)){ - challenges.put(player, new LinkedList<>()); + if(!challenges.containsKey(p)){ + challenges.put(p, new LinkedList<>()); } - challenges.get(player).add(target); + challenges.get(p).add(target); - Message.send("CHALLENGE_CHALLENGED", player, target.getName(), mode.getDisplayName()); - Message.send("CHALLENGE_CHALLENGED_TARGET", target, player.getName(), mode.getDisplayName(), mode.getMaps().size()!=1?Message.parse("CHALLENGE_CHALLENGED_MAP", target, map):""); + Message.send("CHALLENGE_CHALLENGED", p, target.getName(), mode.getDisplayName()); + Message.send("CHALLENGE_CHALLENGED_TARGET", target, p.getName(), mode.getDisplayName(), mode.getMaps().size() != 1 ? Message.parse("CHALLENGE_CHALLENGED_MAP", target, m) : ""); - Message.send("CHALLENGE_ACCEPT", target, Message.parse("CHALLENGE_ACCEPT_HOVER", target), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/challenge " + player.getName() + " " + mode.getChatName() + " " + map)); + Message.send("CHALLENGE_ACCEPT", target, Message.parse("CHALLENGE_ACCEPT_HOVER", target), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/challenge " + p.getName() + " " + mode.getChatName() + " " + m)); } }); } + @Validator(value = "target", local = true) + public TypeValidator targetValidator() { + return (sender, value, messageSender) -> { + if (value == null) { + messageSender.send("CHALLENGE_OFFLINE"); + return false; + } + if (sender == value) { + messageSender.send("CHALLENGE_SELF"); + return false; + } + if (IgnoreSystem.isIgnored(value, (ProxiedPlayer) sender)) { + messageSender.send("CHALLENGE_IGNORED"); + return false; + } + + Subserver subserver = Subserver.getSubserver(value); + if (subserver != null && subserver.getType() == Servertype.ARENA) { + messageSender.send("CHALLENGE_INARENA"); + return false; + } + return true; + }; + } + public static void remove(ProxiedPlayer player){ challenges.remove(player); } - - @Override - public Iterable onTabComplete(CommandSender commandSender, String[] args) { - if(args.length == 2) - return ArenaMode.getAllChatNames(false); - return new ArrayList<>(); - } } diff --git a/src/de/steamwar/bungeecore/commands/DevCommand.java b/src/de/steamwar/bungeecore/commands/DevCommand.java index 4f064084..5858a49e 100644 --- a/src/de/steamwar/bungeecore/commands/DevCommand.java +++ b/src/de/steamwar/bungeecore/commands/DevCommand.java @@ -19,6 +19,7 @@ package de.steamwar.bungeecore.commands; +import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.Punishment; import de.steamwar.bungeecore.sql.SteamwarUser; import de.steamwar.command.*; @@ -42,7 +43,7 @@ public class DevCommand extends SWCommand { } @Register - public void simpleCommand(@Guard ProxiedPlayer player) { + public void simpleCommand(@Validator ProxiedPlayer player) { updateDevServers(); ChatSender sender = ChatSender.of(player); if (devServers.isEmpty()) { @@ -63,7 +64,7 @@ public class DevCommand extends SWCommand { } @Register - public void selectedCommand(@Guard ProxiedPlayer player, @Mapper("dev") String name) { + public void selectedCommand(@Validator ProxiedPlayer player, @Mapper("dev") String name) { updateDevServers(); ChatSender sender = ChatSender.of(player); ServerInfo info = devServers.get(name.toLowerCase()); @@ -75,20 +76,16 @@ public class DevCommand extends SWCommand { player.connect(info); } - @ClassGuard(value = ProxiedPlayer.class, local = true) - public GuardChecker punishmentGuardChecker() { - return (commandSender, guardCheckType, previousArguments, s) -> { - ChatSender sender = ChatSender.of(commandSender); - if (guardCheckType == GuardCheckType.COMMAND) { - if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoDevServer)) { - return GuardResult.DENIED; - } - } else { - if (sender.user().isPunished(Punishment.PunishmentType.NoDevServer)) { - return GuardResult.DENIED; - } + @ClassValidator(value = ProxiedPlayer.class, local = true) + public TypeValidator punishmentGuardChecker() { + return (sender, value, messageSender) -> { + SteamwarUser user = SteamwarUser.get(value); + if (user.isPunished(Punishment.PunishmentType.NoDevServer)) { + Message message = user.punishmentMessage(Punishment.PunishmentType.NoDevServer); + messageSender.send(message.getFormat(), message.getParams()); + return false; } - return GuardResult.ALLOWED; + return true; }; } diff --git a/src/de/steamwar/bungeecore/commands/FightCommand.java b/src/de/steamwar/bungeecore/commands/FightCommand.java index 32730168..ad6b08af 100644 --- a/src/de/steamwar/bungeecore/commands/FightCommand.java +++ b/src/de/steamwar/bungeecore/commands/FightCommand.java @@ -24,6 +24,7 @@ import de.steamwar.bungeecore.inventory.SWInventory; import de.steamwar.bungeecore.inventory.SWItem; import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker; import de.steamwar.bungeecore.sql.Punishment; +import de.steamwar.command.SWCommand; import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatMessageType; @@ -34,8 +35,6 @@ import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.hover.content.Text; import net.md_5.bungee.api.connection.ProxiedPlayer; -import java.util.LinkedList; - /** * Jeder Fightcommand (auch bau testarena und challenge) haben folgende Optionskette: * @@ -45,7 +44,7 @@ import java.util.LinkedList; * Sollte die Map fehlen, kann sie mit getMap() bestimmt werden. */ -public class FightCommand extends BasicCommand { +public class FightCommand extends SWCommand { public FightCommand() { super("fight", "", "f"); @@ -98,7 +97,7 @@ public class FightCommand extends BasicCommand { String command = precommand + mode.getChatName() + " Random"; start.setBold(true); start.setColor(ChatColor.GRAY); - start.setText(sender.parseToLegacy("FIGHT_ARENA_RANDOM") + " "); + start.setText(sender.parseToPlain("FIGHT_ARENA_RANDOM") + " "); start.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§e" + command))); start.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command)); current = new TextComponent(); @@ -129,6 +128,35 @@ public class FightCommand extends BasicCommand { return false; } + static void createArena(ProxiedPlayer player, String precommand, boolean allowMerging, ArenaMode arenaMode, String map, boolean historic, FightCallback callback) { + ChatSender sender = ChatSender.of(player); + + if(alreadyInArena(player)) + return; + + if (arenaMode == null) { + getModes(sender, precommand, historic); + return; + } + + if (map == null) { + if (arenaMode.getMaps().size() == 1) { + map = arenaMode.getRandomMap(); + } else { + getMaps(sender, precommand, arenaMode); + return; + } + } else if (map.equalsIgnoreCase("random")) { + map = arenaMode.getRandomMap(); + } + + if (!allowMerging) { + callback.run(player, arenaMode, map); + } else { + suggestMerging(player, arenaMode, map, callback); + } + } + static void createArena(CommandSender s, String precommand, boolean allowMerging, String[] args, int startArg, boolean historic, FightCallback callback){ if(!(s instanceof ProxiedPlayer)) return; @@ -216,28 +244,17 @@ public class FightCommand extends BasicCommand { inventory.open(); } - @Override - public void execute(CommandSender sender, String[] args) { - createArena(sender, "/fight ", true, args, 0, false, (player, mode, map) -> { - Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).start(); - Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER" - , new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName()); + @Register + public void fight(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) { + createArena(player, "/fight ", true, arenaMode, map, false, (p, mode, m) -> { + Subserver arena = new ServerStarter().arena(mode, m).blueLeader(p).start(); + if(arena != null) { + Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER" + , new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName()); + } }); } - @Override - public Iterable onTabComplete(CommandSender commandSender, String[] args) { - if(args.length == 1){ - return ArenaMode.getAllChatNames(false); - }else if(args.length == 2){ - ArenaMode mode = ArenaMode.getByChat(args[1]); - if(mode == null) - return new LinkedList<>(); - return mode.getMaps(); - } - return new LinkedList<>(); - } - /** * Is called when arena parameters are clear. */ diff --git a/src/de/steamwar/bungeecore/commands/HelpCommand.java b/src/de/steamwar/bungeecore/commands/HelpCommand.java index 87bfe363..d3fb3fec 100644 --- a/src/de/steamwar/bungeecore/commands/HelpCommand.java +++ b/src/de/steamwar/bungeecore/commands/HelpCommand.java @@ -36,17 +36,17 @@ public class HelpCommand extends BasicCommand { if (args.length < 1) { printPage(sender, ClickEvent.Action.RUN_COMMAND, "HELP_LOBBY", "/l", - "HELP_BAU", "/bau", - "HELP_BAUSERVER", "/help bau", + "HELP_BAU", "/build", + "HELP_BAUSERVER", "/help build", "HELP_FIGHT", "/fight", "HELP_CHALLENGE", "/challenge", "HELP_HISTORIC", "/historic", "HELP_TEAM", "/team", "HELP_JOIN", "/join", "HELP_LOCAL", "/local"); - }else if (args[0].equalsIgnoreCase("bauserver")) { + }else if (args[0].equalsIgnoreCase("buildserver")) { sendBauHelp(sender); - }else if (args[0].equalsIgnoreCase("bau")) { + }else if (args[0].equalsIgnoreCase("build")) { bauHelpGroup(sender, args); } } @@ -86,24 +86,24 @@ public class HelpCommand extends BasicCommand { private static void sendBauHelpGroup(ChatSender sender) { printPage(sender, ClickEvent.Action.RUN_COMMAND, - "HELP_BAU_GROUP_ADMIN", "/help bau admin", - "HELP_BAU_GROUP_WORLD", "/help bau world", - "HELP_BAU_GROUP_PLAYER", "/help bau player", - "HELP_BAU_GROUP_WE", "/help bau we", - "HELP_BAU_GROUP_OTHER", "/help bau other"); + "HELP_BAU_GROUP_ADMIN", "/help build admin", + "HELP_BAU_GROUP_WORLD", "/help build world", + "HELP_BAU_GROUP_PLAYER", "/help build player", + "HELP_BAU_GROUP_WE", "/help build we", + "HELP_BAU_GROUP_OTHER", "/help build other"); } static void sendBauHelp(ChatSender sender) { printPage(sender, ClickEvent.Action.SUGGEST_COMMAND, - "HELP_BAU_TP", "/bau tp ", - "HELP_BAU_ADDMEMBER", "/bau addmember ", - "HELP_BAU_DELMEMBER", "/bau delmember ", - "HELP_BAU_TOGGLEWE", "/bau togglewe ", - "HELP_BAU_TOGGLEWORLD", "/bau toggleworld ", - "HELP_BAU_DELETE", "/bau delete ", - "HELP_BAU_TESTARENA", "/bau testarena ", - "HELP_BAU_LOCK", "/bau lock", - "HELP_BAU_UNLOCK", "/bau unlock"); + "HELP_BAU_TP", "/build tp ", + "HELP_BAU_ADDMEMBER", "/build addmember ", + "HELP_BAU_DELMEMBER", "/build delmember ", + "HELP_BAU_TOGGLEWE", "/build togglewe ", + "HELP_BAU_TOGGLEWORLD", "/build toggleworld ", + "HELP_BAU_DELETE", "/build delete ", + "HELP_BAU_TESTARENA", "/build testarena ", + "HELP_BAU_LOCK", "/build lock ", + "HELP_BAU_UNLOCK", "/build unlock"); } private static void printPage(ChatSender sender, ClickEvent.Action action, String... args) { diff --git a/src/de/steamwar/bungeecore/commands/HistoricCommand.java b/src/de/steamwar/bungeecore/commands/HistoricCommand.java index b056c917..03e7abbb 100644 --- a/src/de/steamwar/bungeecore/commands/HistoricCommand.java +++ b/src/de/steamwar/bungeecore/commands/HistoricCommand.java @@ -23,35 +23,23 @@ import de.steamwar.bungeecore.ArenaMode; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.ServerStarter; import de.steamwar.bungeecore.Subserver; -import net.md_5.bungee.api.CommandSender; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.connection.ProxiedPlayer; -import java.util.LinkedList; - -public class HistoricCommand extends BasicCommand { +public class HistoricCommand extends SWCommand { public HistoricCommand() { super("historic", null); } - @Override - public void execute(CommandSender sender, String[] args) { - FightCommand.createArena(sender, "/historic ", true, args, 0, true, (player, mode, map) -> { - Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).start(); - Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER" - , new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName()); + @Register + public void historic(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) { + FightCommand.createArena(player, "/historic ", true, arenaMode, map, true, (p, mode, m) -> { + Subserver arena = new ServerStarter().arena(mode, m).blueLeader(p).start(); + if(arena != null) { + Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER", + new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName()); + } }); } - - @Override - public Iterable onTabComplete(CommandSender commandSender, String[] args) { - if(args.length == 1){ - return ArenaMode.getAllChatNames(true); - }else if(args.length == 2){ - ArenaMode mode = ArenaMode.getByChat(args[1]); - if(mode == null) - return new LinkedList<>(); - return mode.getMaps(); - } - return new LinkedList<>(); - } } diff --git a/src/de/steamwar/bungeecore/commands/JoinmeCommand.java b/src/de/steamwar/bungeecore/commands/JoinmeCommand.java index 105063c0..e897ba0e 100644 --- a/src/de/steamwar/bungeecore/commands/JoinmeCommand.java +++ b/src/de/steamwar/bungeecore/commands/JoinmeCommand.java @@ -69,6 +69,10 @@ public class JoinmeCommand extends BasicCommand { SubserverSystem.sendDeniedMessage(player, bauserver.getOwner()); Message.send("JOIN_PLAYER_BLOCK", player); } + } else if(type == Servertype.BUILDER && !player.hasPermission("bungeecore.server.team")) { + Message.send("JOIN_PLAYER_BLOCK", player); + } else { + SubserverSystem.sendPlayer(subserver, player); } }else if(serverPerm != null && !player.hasPermission(serverPerm)){ Message.send("JOIN_PLAYER_BLOCK", player); diff --git a/src/de/steamwar/bungeecore/commands/PollCommand.java b/src/de/steamwar/bungeecore/commands/PollCommand.java index e6fb7550..5e179cda 100644 --- a/src/de/steamwar/bungeecore/commands/PollCommand.java +++ b/src/de/steamwar/bungeecore/commands/PollCommand.java @@ -23,11 +23,8 @@ import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.listeners.PollSystem; import de.steamwar.bungeecore.sql.PollAnswer; import de.steamwar.bungeecore.sql.SteamwarUser; -import de.steamwar.command.GuardCheckType; -import de.steamwar.command.GuardChecker; -import de.steamwar.command.GuardResult; import de.steamwar.command.SWCommand; -import net.md_5.bungee.api.CommandSender; +import de.steamwar.command.TypeValidator; import net.md_5.bungee.api.connection.ProxiedPlayer; public class PollCommand extends SWCommand { @@ -37,12 +34,12 @@ public class PollCommand extends SWCommand { } @Register - public void genericCommand(@Guard ProxiedPlayer player) { + public void genericCommand(ProxiedPlayer player) { PollSystem.sendPoll(player); } @Register(noTabComplete = true) - public void answerPoll(@Guard ProxiedPlayer player, String answerString) { + public void answerPoll(@Validator ProxiedPlayer player, String answerString) { int answer; try { answer = Integer.parseUnsignedInt(answerString); @@ -62,16 +59,14 @@ public class PollCommand extends SWCommand { pollAnswer.setAnswer(answer); } - @ClassGuard(value = ProxiedPlayer.class, local = true) - public GuardChecker noPoll() { - return (commandSender, guardCheckType, previousArguments, s) -> { + @ClassValidator(value = ProxiedPlayer.class, local = true) + public TypeValidator noPoll() { + return (sender, value, messageSender) -> { if(PollSystem.noCurrentPoll()){ - if (guardCheckType == GuardCheckType.COMMAND) { - Message.send("POLL_NO_POLL", commandSender); - } - return GuardResult.DENIED; + messageSender.send("POLL_NO_POLL"); + return false; } - return GuardResult.ALLOWED; + return true; }; } } diff --git a/src/de/steamwar/bungeecore/commands/PollresultCommand.java b/src/de/steamwar/bungeecore/commands/PollresultCommand.java index 4011f4c7..554efcce 100644 --- a/src/de/steamwar/bungeecore/commands/PollresultCommand.java +++ b/src/de/steamwar/bungeecore/commands/PollresultCommand.java @@ -22,10 +22,8 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.listeners.PollSystem; import de.steamwar.bungeecore.sql.PollAnswer; -import de.steamwar.command.GuardCheckType; -import de.steamwar.command.GuardChecker; -import de.steamwar.command.GuardResult; import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeValidator; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.Map; @@ -37,7 +35,7 @@ public class PollresultCommand extends SWCommand { } @Register - public void genericCommand(@Guard ProxiedPlayer player) { + public void genericCommand(@Validator ProxiedPlayer player) { Map voted = PollAnswer.getCurrentResults(); Message.send("POLLRESULT_HEADER", player, voted.values().stream().reduce(Integer::sum).orElse(0), PollSystem.getQuestion()); for (Map.Entry e: voted.entrySet()) { @@ -45,16 +43,14 @@ public class PollresultCommand extends SWCommand { } } - @ClassGuard(value = ProxiedPlayer.class, local = true) - public GuardChecker noPoll() { - return (commandSender, guardCheckType, previousArguments, s) -> { - if(PollSystem.noCurrentPoll()){ - if (guardCheckType == GuardCheckType.COMMAND) { - Message.send("POLL_NO_POLL", commandSender); - } - return GuardResult.DENIED; + @ClassValidator(value = ProxiedPlayer.class, local = true) + public TypeValidator noPoll() { + return (sender, value, messageSender) -> { + if (PollSystem.noCurrentPoll()) { + messageSender.send("POLL_NO_POLL"); + return false; } - return GuardResult.ALLOWED; + return true; }; } } diff --git a/src/de/steamwar/bungeecore/commands/RegelnCommand.java b/src/de/steamwar/bungeecore/commands/RegelnCommand.java index 2721b732..63731a53 100644 --- a/src/de/steamwar/bungeecore/commands/RegelnCommand.java +++ b/src/de/steamwar/bungeecore/commands/RegelnCommand.java @@ -21,13 +21,12 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.command.SWCommand; -import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.connection.ProxiedPlayer; public class RegelnCommand extends SWCommand { public RegelnCommand() { - super("regeln"); + super("regeln", null, "rules"); } @Register diff --git a/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java b/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java index ea4ce9f2..e22c68fd 100644 --- a/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java +++ b/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java @@ -31,13 +31,7 @@ public class ServerTeamchatCommand extends SWCommand { } @Register(description = "STC_USAGE") - public void genericCommand(CommandSender commandSender, String... message) { - ChatSender sender = ChatSender.of(commandSender); - if(message.length == 0) { - sender.system("STC_USAGE"); - return; - } - - ChatListener.sendChat(sender, ChatSender.serverteamReceivers(), "CHAT_SERVERTEAM", null, String.join(" ", message)); + public void genericCommand(CommandSender commandSender, @ErrorMessage(value = "STC_USAGE", allowEAs = false) String... message) { + ChatListener.sendChat(ChatSender.of(commandSender), ChatSender.serverteamReceivers(), "CHAT_SERVERTEAM", null, String.join(" ", message)); } } diff --git a/src/de/steamwar/bungeecore/commands/StatCommand.java b/src/de/steamwar/bungeecore/commands/StatCommand.java index 753f2537..ffae1687 100644 --- a/src/de/steamwar/bungeecore/commands/StatCommand.java +++ b/src/de/steamwar/bungeecore/commands/StatCommand.java @@ -52,6 +52,6 @@ public class StatCommand extends SWCommand { throw new SecurityException(e.getMessage(), e); } - Node.forEach(node -> Message.send("STAT_SERVER", sender, node.getName(), node.getLoad(), serverCount.getOrDefault(node.getName(), 0))); + Node.forEach(node -> Message.send("STAT_SERVER", sender, node.getName(), node.belowLoadLimit(), serverCount.getOrDefault(node.getName(), 0))); } } diff --git a/src/de/steamwar/bungeecore/commands/TpCommand.java b/src/de/steamwar/bungeecore/commands/TpCommand.java index a31cd783..1ac1a224 100644 --- a/src/de/steamwar/bungeecore/commands/TpCommand.java +++ b/src/de/steamwar/bungeecore/commands/TpCommand.java @@ -102,6 +102,8 @@ public class TpCommand extends BasicCommand { sender.system("JOIN_PLAYER_BLOCK"); } + } else if(subserver instanceof Builderserver && !player.hasPermission("bungeecore.server.team")) { + sender.system("JOIN_PLAYER_BLOCK"); } else if (serverPerm != null && !player.hasPermission(serverPerm)) { sender.system("JOIN_PLAYER_BLOCK"); } else if (serverPerm == null && !player.getGroups().contains("team")) { diff --git a/src/de/steamwar/bungeecore/commands/TutorialCommand.java b/src/de/steamwar/bungeecore/commands/TutorialCommand.java index e5e3134d..30cc2961 100644 --- a/src/de/steamwar/bungeecore/commands/TutorialCommand.java +++ b/src/de/steamwar/bungeecore/commands/TutorialCommand.java @@ -26,9 +26,8 @@ import de.steamwar.bungeecore.inventory.SWListInv; import de.steamwar.bungeecore.inventory.SWStreamInv; import de.steamwar.bungeecore.sql.SteamwarUser; import de.steamwar.bungeecore.sql.Tutorial; -import de.steamwar.command.GuardChecker; -import de.steamwar.command.GuardResult; import de.steamwar.command.SWCommand; +import de.steamwar.command.TypeValidator; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -78,22 +77,14 @@ public class TutorialCommand extends SWCommand { } @Register("unreleased") - public void unreleased(@Guard("unreleased") ProxiedPlayer player) { + public void unreleased(@Validator("unreleased") ProxiedPlayer player) { openInventory(player, false, false); } - @Guard("unreleased") - public GuardChecker unreleasedChecker() { - return (commandSender, guardCheckType, previousArguments, s) -> { - if (commandSender instanceof ProxiedPlayer) { - if (SteamwarUser.get(((ProxiedPlayer) commandSender).getUniqueId()).getUserGroup().isTeamGroup()) { - return GuardResult.ALLOWED; - } else { - return GuardResult.DENIED_WITH_HELP; - } - } else { - return GuardResult.ALLOWED; - } + @Validator("unreleased") + public TypeValidator unreleasedChecker() { + return (sender, value, messageSender) -> { + return (SteamwarUser.get((value).getUniqueId()).getUserGroup().isTeamGroup()); }; } @@ -165,8 +156,8 @@ public class TutorialCommand extends SWCommand { File tutorialWorld = tutorial.world(); if (tutorialWorld.exists()) - SubserverSystem.deleteFolder(Node.local, tutorialWorld.getPath()); - ServerStarter.copyWorld(Node.local, tempWorld.getPath(), tutorialWorld.getPath()); + SubserverSystem.deleteFolder(BungeeCore.local, tutorialWorld.getPath()); + ServerStarter.copyWorld(BungeeCore.local, tempWorld.getPath(), tutorialWorld.getPath()); Message.send("TUTORIAL_CREATED", player); }, 1, TimeUnit.SECONDS); } diff --git a/src/de/steamwar/bungeecore/commands/TypeMappers.java b/src/de/steamwar/bungeecore/commands/TypeMappers.java new file mode 100644 index 00000000..94b27e4a --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/TypeMappers.java @@ -0,0 +1,98 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bungeecore.commands; + +import de.steamwar.bungeecore.ArenaMode; +import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker; +import de.steamwar.bungeecore.sql.Punishment; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import de.steamwar.command.TypeValidator; +import de.steamwar.messages.ChatSender; +import lombok.experimental.UtilityClass; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@UtilityClass +public class TypeMappers { + + public static void init() { + SWCommandUtils.addValidator("arenaPlayer", arenaPlayer()); + SWCommandUtils.addMapper("nonHistoricArenaMode", arenaModeTypeMapper(false)); + SWCommandUtils.addMapper("historicArenaMode", arenaModeTypeMapper(true)); + SWCommandUtils.addMapper("arenaMap", arenaMapTypeMapper()); + } + + private static TypeValidator arenaPlayer() { + return (sender, value, messageSender) -> { + ChatSender player = ChatSender.of(value); + if (player.user().isPunishedWithMessage(player, Punishment.PunishmentType.NoFightServer)) { + return false; + } + + if (ModLoaderBlocker.isFabric(value)) { + messageSender.send("MODLOADER_DENIED"); + return false; + } + return true; + }; + } + + private static TypeMapper arenaModeTypeMapper(boolean historic) { + return new TypeMapper() { + @Override + public ArenaMode map(CommandSender commandSender, String[] previousArguments, String s) { + return ArenaMode.getByChat(s); + } + + @Override + public Collection tabCompletes(CommandSender sender, String[] previousArguments, String s) { + return ArenaMode.getAllChatNames(historic); + } + }; + } + + private static TypeMapper arenaMapTypeMapper() { + return new TypeMapper() { + @Override + public String map(CommandSender commandSender, String[] previousArguments, String s) { + if (previousArguments.length == 0) return null; + if (s.equalsIgnoreCase("random")) return "random"; + ArenaMode arenaMode = ArenaMode.getByChat(previousArguments[previousArguments.length - 1]); + if (arenaMode.getMaps().contains(s)) return s; + return null; + } + + @Override + public Collection tabCompletes(CommandSender sender, String[] previousArguments, String s) { + if (previousArguments.length == 0) return null; + ArenaMode arenaMode = ArenaMode.getByChat(previousArguments[previousArguments.length - 1]); + if (arenaMode == null) return null; + List stringList = new ArrayList<>(arenaMode.getMaps()); + stringList.add("random"); + return stringList; + } + }; + } +} diff --git a/src/de/steamwar/bungeecore/commands/WebregisterCommand.java b/src/de/steamwar/bungeecore/commands/WebpasswordCommand.java similarity index 55% rename from src/de/steamwar/bungeecore/commands/WebregisterCommand.java rename to src/de/steamwar/bungeecore/commands/WebpasswordCommand.java index 6197f0ff..2e45c274 100644 --- a/src/de/steamwar/bungeecore/commands/WebregisterCommand.java +++ b/src/de/steamwar/bungeecore/commands/WebpasswordCommand.java @@ -19,58 +19,45 @@ package de.steamwar.bungeecore.commands; -import de.steamwar.bungeecore.Message; -import de.steamwar.bungeecore.sql.SWException; import de.steamwar.command.SWCommand; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -public class WebregisterCommand extends SWCommand { +public class WebpasswordCommand extends SWCommand { - public WebregisterCommand() { - super("webregister", null, "web", "webpw"); + public WebpasswordCommand() { + super("webpassword", null, "webpw", "web"); } + @Register(description = "WEB_USAGE") - public void genericCommand(ProxiedPlayer player, String email) { - ProcessBuilder pb = new ProcessBuilder("php", "/var/www/register.php", player.getName(), email); + public void genericCommand(ProxiedPlayer player, String password) { + if(password.length() < 8) { + ChatSender.of(player).system("WEB_PASSWORD_LENGTH"); + return; + } + + ProcessBuilder pb = new ProcessBuilder("php", "/var/www/register.php", player.getName(), password); pb.redirectErrorStream(true); try { Process regProcess = pb.start(); BufferedReader reader = new BufferedReader(new InputStreamReader(regProcess.getInputStream())); String errorLine; - boolean error = false; - while((errorLine = reader.readLine()) != null){ - switch(errorLine){ - case "username_exists": - Message.send("WEB_ALREADY", player); - break; - case "email_exists": - Message.send("WEB_ALREADY_EMAIL", player); - // SWException.log("Bungee", "Duplicate E-Mail", player.getName() + " " + args[0]); - break; - case "invalid_email": - Message.send("WEB_NOT_EMAIL", player); - break; - case "email_updated": - Message.send("WEB_EMAIL_REFRESH", player); - break; - default: - Message.send("WEB_INTERNAL_ERROR", player); - SWException.log("Bungee", "Unknown Wordpress User Creation Error", errorLine); + if((errorLine = reader.readLine()) != null) { + if ("updated".equals(errorLine)) { + ChatSender.of(player).system("WEB_UPDATED"); + return; + } else { + throw new SecurityException("Could not create webaccount " + errorLine); } - error = true; } - if(error) - return; - - Message.send("WEB_EMAIL_SEND", player); + ChatSender.of(player).system("WEB_CREATED"); } catch (IOException e) { - Message.send("WEB_INTERNAL_ERROR", player); throw new SecurityException("Could not create webaccount", e); } } diff --git a/src/de/steamwar/bungeecore/commands/WhoisCommand.java b/src/de/steamwar/bungeecore/commands/WhoisCommand.java index 83caa0f6..9e25ad25 100644 --- a/src/de/steamwar/bungeecore/commands/WhoisCommand.java +++ b/src/de/steamwar/bungeecore/commands/WhoisCommand.java @@ -44,7 +44,7 @@ public class WhoisCommand extends SWCommand { } @Register(description = "WHOIS_USAGE") - public void genericCommand(ProxiedPlayer player, @Mapper("player") String target, @OptionalValue("") @StaticValue({"-all", "-a", ""}) String displayAll) { + public void genericCommand(ProxiedPlayer player, @Mapper("player") String target, @OptionalValue("") @StaticValue(value = {"", "-all", "-a"}, allowISE = true) boolean all) { SteamwarUser user = SteamwarUser.get(target); if (user == null) { try { @@ -64,11 +64,9 @@ public class WhoisCommand extends SWCommand { if (user == null) { Message.send("UNKNOWN_PLAYER", player); - return; + } else { + sendUserinfo(player, user, all); } - - boolean all = displayAll.contains("-"); - sendUserinfo(player, user, all); } @Mapper(value = "player", local = true) diff --git a/src/de/steamwar/bungeecore/listeners/ChatListener.java b/src/de/steamwar/bungeecore/listeners/ChatListener.java index df006f97..827fe3eb 100644 --- a/src/de/steamwar/bungeecore/listeners/ChatListener.java +++ b/src/de/steamwar/bungeecore/listeners/ChatListener.java @@ -56,31 +56,43 @@ public class ChatListener extends BasicListener { ProxiedPlayer player = (ProxiedPlayer) e.getSender(); String message = e.getMessage(); + e.setCancelled(true); + if (message.contains("jndi:ldap")) { - e.setCancelled(true); SteamwarUser.get(player).punishPerma(Punishment.PunishmentType.Ban, "Versuchte Exploit-Ausnutzung", 0); return; } - message = sanitize7(message); + if (isCommand(player, message)) + return; - if (message.startsWith("/")) { - if(filteredCommand((CommandSender) e.getSender(), message)) - e.setCancelled(true); + Subserver subserver = Subserver.getSubserver(player); + if(subserver != null && subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getServer().getInfo()) { + localChat(player, message); + } else if (message.startsWith("+")) { + localChat(player, message.substring(1)); } else { - e.setCancelled(true); - - Subserver subserver = Subserver.getSubserver(player); - if(subserver != null && subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getServer().getInfo()) { - localChat(player, message); - } else if (message.startsWith("+")) { - localChat(player, message.substring(1)); - } else { - sendChat(ChatSender.of(player), ChatSender.globalReceivers(), "CHAT_GLOBAL", null, message); - } + sendChat(ChatSender.of(player), ChatSender.globalReceivers(), "CHAT_GLOBAL", null, message); } } + private static boolean isCommand(ProxiedPlayer player, String message) { + String command = message.substring(1); + boolean isCommand = message.startsWith("/") || (message.startsWith("7") && command.split(" ", 2)[0].matches("[7/]?[A-Za-z]+")); + if(isCommand && !ProxyServer.getInstance().getPluginManager().dispatchCommand(player, command)) { + if(command.startsWith("7")) + command = "/" + command.substring(1); + message = "/" + command; + + if(filteredCommand(player, message)) + return true; + + Chat19.chat(player, message); + } + + return isCommand; + } + public static void sendChat(ChatSender sender, Stream receivers, String format, ChatSender msgReceiver, String message) { SteamwarUser user = sender.user(); final String coloredMessage = (user.getUserGroup() != UserGroup.Member || coloredTeams.contains(user.getTeam())) ? ChatColor.translateAlternateColorCodes('&', message) : message; @@ -114,8 +126,6 @@ public class ChatListener extends BasicListener { return; } - message = sanitize7(message); - if(ChatListener.filteredCommand(player, message)) return; @@ -167,17 +177,6 @@ public class ChatListener extends BasicListener { group.getChatColorCode())); } - private static String sanitize7(String message) { - String begin = message.split(" ", 2)[0]; - if(begin.startsWith("7") && begin.substring(1).matches("[A-Za-z]+")){ - message = "/" + message.substring(1); - }else if((begin.startsWith("77") || begin.startsWith("7/") || begin.startsWith("/7")) && begin.substring(2).matches("[A-Za-z]+")){ - message = "//" + message.substring(2); - } - - return message; - } - private static boolean filteredCommand(CommandSender sender, String message) { String command = message.split(" ", 2)[0]; if(command.startsWith("/") && command.contains(":")) { diff --git a/src/de/steamwar/bungeecore/listeners/ConnectionListener.java b/src/de/steamwar/bungeecore/listeners/ConnectionListener.java index 95f6a89c..44bba9fe 100644 --- a/src/de/steamwar/bungeecore/listeners/ConnectionListener.java +++ b/src/de/steamwar/bungeecore/listeners/ConnectionListener.java @@ -105,6 +105,9 @@ public class ConnectionListener extends BasicListener { @EventHandler public void onServerKickEvent(ServerKickEvent ev) { + if(!ev.getPlayer().isConnected()) + return; + ServerInfo kickedFrom; if (ev.getPlayer().getServer() != null){ diff --git a/src/de/steamwar/bungeecore/listeners/mods/Fabric.java b/src/de/steamwar/bungeecore/listeners/mods/Fabric.java index b2b949f7..c244de2c 100644 --- a/src/de/steamwar/bungeecore/listeners/mods/Fabric.java +++ b/src/de/steamwar/bungeecore/listeners/mods/Fabric.java @@ -41,7 +41,6 @@ import java.nio.charset.UnsupportedCharsetException; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.logging.Level; -import java.util.stream.Collectors; public class Fabric extends BasicListener { @@ -124,12 +123,14 @@ public class Fabric extends BasicListener { mods.add(Mod.get(mod.getAsString(), Mod.Platform.FABRIC)); } + /* boolean isSorted = isSortedAlphabetically(mods); if(!isSorted) { banPlayer(user, player, "Mods are not sorted alphabetically: " + mods.stream().map(Mod::getModName).collect(Collectors.joining(", "))); return; } + */ if(!neededModsContained(mods)) { banPlayer(user, player, "Needed mods are not contained"); diff --git a/src/de/steamwar/bungeecore/network/NetworkReceiver.java b/src/de/steamwar/bungeecore/network/NetworkReceiver.java index d3de8c86..f01bf446 100644 --- a/src/de/steamwar/bungeecore/network/NetworkReceiver.java +++ b/src/de/steamwar/bungeecore/network/NetworkReceiver.java @@ -22,6 +22,7 @@ package de.steamwar.bungeecore.network; import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.commands.TeamCommand; import de.steamwar.bungeecore.listeners.BasicListener; +import de.steamwar.bungeecore.sql.SWException; import de.steamwar.network.packets.NetworkPacket; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.Server; @@ -31,8 +32,8 @@ import net.md_5.bungee.event.EventPriority; import java.net.InetSocketAddress; import java.util.Arrays; +import java.util.Base64; import java.util.List; -import java.util.logging.Level; public class NetworkReceiver extends BasicListener { @@ -41,7 +42,7 @@ public class NetworkReceiver extends BasicListener { @EventHandler(priority = EventPriority.HIGHEST) public void onPluginMessage(PluginMessageEvent event) { if (blockedTags.contains(event.getTag()) && !TeamCommand.isLocalhost(((InetSocketAddress) event.getSender().getSocketAddress()).getAddress())) { - BungeeCore.log(Level.SEVERE, ((InetSocketAddress) event.getSender().getSocketAddress()).getHostString() + " tried to send a plugin message with tag " + event.getTag()); + SWException.log("Bungee", ((InetSocketAddress) event.getSender().getSocketAddress()).getHostString() + " tried to send a plugin message with tag " + event.getTag(), Base64.getEncoder().encodeToString(event.getData())); event.setCancelled(true); return; } diff --git a/src/de/steamwar/bungeecore/sql/SteamwarUser.java b/src/de/steamwar/bungeecore/sql/SteamwarUser.java index 96c92d54..a5cb6058 100644 --- a/src/de/steamwar/bungeecore/sql/SteamwarUser.java +++ b/src/de/steamwar/bungeecore/sql/SteamwarUser.java @@ -22,7 +22,7 @@ package de.steamwar.bungeecore.sql; import com.google.gson.JsonParser; import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.Message; -import de.steamwar.bungeecore.commands.WebregisterCommand; +import de.steamwar.bungeecore.commands.WebpasswordCommand; import de.steamwar.bungeecore.listeners.ConnectionListener; import de.steamwar.bungeecore.network.NetworkSender; import de.steamwar.messages.ChatSender; @@ -121,7 +121,7 @@ public class SteamwarUser { String userName = connection.getName(); if (!user.userName.equals(userName)) { updateName.update(userName, user.id); - WebregisterCommand.changeUsername(user.userName, userName); + WebpasswordCommand.changeUsername(user.userName, userName); user.userName = userName; } } else { diff --git a/src/de/steamwar/bungeecore/sql/Tutorial.java b/src/de/steamwar/bungeecore/sql/Tutorial.java index 75916f2e..7c82f066 100644 --- a/src/de/steamwar/bungeecore/sql/Tutorial.java +++ b/src/de/steamwar/bungeecore/sql/Tutorial.java @@ -19,7 +19,7 @@ package de.steamwar.bungeecore.sql; -import de.steamwar.bungeecore.Node; +import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.ServerStarter; import de.steamwar.bungeecore.SubserverSystem; @@ -124,7 +124,7 @@ public class Tutorial { public void delete() { delete.update(id); - SubserverSystem.deleteFolder(Node.local, world().getPath()); + SubserverSystem.deleteFolder(BungeeCore.local, world().getPath()); } public File world() { diff --git a/src/de/steamwar/bungeecore/tablist/Tablist.java b/src/de/steamwar/bungeecore/tablist/Tablist.java index b9acc96e..ad400cb7 100644 --- a/src/de/steamwar/bungeecore/tablist/Tablist.java +++ b/src/de/steamwar/bungeecore/tablist/Tablist.java @@ -62,7 +62,7 @@ public class Tablist extends MessageToMessageDecoder { this.player = player; this.viewer = ChatSender.of(player); this.directTabItems = Storage.directTabItems.computeIfAbsent(player, p -> new HashMap<>()); - onServerSwitch(); + injection(); } public void update(TablistPart global, int seconds) { @@ -145,12 +145,17 @@ public class Tablist extends MessageToMessageDecoder { } public void onServerSwitch() { - connection = (ServerConnection) player.getServer(); + injection(); + synchronized (directTabItems) { sendNpcPacket(npcs.stream().map(npc -> directTabItems.get(npc).getUsername()).collect(Collectors.toList()), true); directTabItems.clear(); npcs.clear(); } + } + + private void injection() { + connection = (ServerConnection) player.getServer(); if(connection != null) { ChannelPipeline pipeline = connection.getCh().getHandle().pipeline(); diff --git a/src/de/steamwar/bungeecore/tablist/TablistManager.java b/src/de/steamwar/bungeecore/tablist/TablistManager.java index 0f02f559..b6e78754 100644 --- a/src/de/steamwar/bungeecore/tablist/TablistManager.java +++ b/src/de/steamwar/bungeecore/tablist/TablistManager.java @@ -51,7 +51,9 @@ public class TablistManager extends BasicListener { public TablistManager() { ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateTablist, 1, 1, TimeUnit.SECONDS); - ProxyServer.getInstance().getPlayers().forEach(player -> tablists.put(player, new Tablist(player))); + synchronized (tablists) { + ProxyServer.getInstance().getPlayers().forEach(player -> tablists.put(player, new Tablist(player))); + } } @EventHandler diff --git a/src/de/steamwar/command/GuardChecker.java b/src/de/steamwar/command/GuardChecker.java deleted file mode 100644 index 06c91101..00000000 --- a/src/de/steamwar/command/GuardChecker.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.command; - -import net.md_5.bungee.api.CommandSender; - -@FunctionalInterface -public interface GuardChecker extends AbstractGuardChecker { - /** - * While guarding the first parameter of the command the parameter s of this method is {@code null} - */ - GuardResult guard(CommandSender commandSender, GuardCheckType guardCheckType, String[] previousArguments, String s); -} diff --git a/src/de/steamwar/command/SWCommand.java b/src/de/steamwar/command/SWCommand.java index f8c36473..3938c61f 100644 --- a/src/de/steamwar/command/SWCommand.java +++ b/src/de/steamwar/command/SWCommand.java @@ -149,7 +149,7 @@ public class SWCommand extends AbstractSWCommand { } if (args.length == 0 || atomicInteger.get() == commandList.size()) { commandList.forEach(subCommand -> { - if (subCommand.guardChecker == null || subCommand.guardChecker.guard(p, GuardCheckType.TAB_COMPLETE, new String[0], null) == GuardResult.ALLOWED) { + if (subCommand.validator == null || subCommand.validator.validate(p, p, (s, args1) -> {})) { send(chatSender, subCommand); } }); diff --git a/src/de/steamwar/command/TypeUtils.java b/src/de/steamwar/command/TypeUtils.java index df779d93..833cd4b3 100644 --- a/src/de/steamwar/command/TypeUtils.java +++ b/src/de/steamwar/command/TypeUtils.java @@ -19,6 +19,7 @@ package de.steamwar.command; +import de.steamwar.bungeecore.commands.TypeMappers; import de.steamwar.bungeecore.sql.SteamwarUser; import lombok.experimental.UtilityClass; import net.md_5.bungee.BungeeCord; @@ -32,5 +33,7 @@ public class TypeUtils { static void init() { SWCommandUtils.addMapper(ProxiedPlayer.class, SWCommandUtils.createMapper(BungeeCord.getInstance()::getPlayer, (s) -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()))); SWCommandUtils.addMapper(SteamwarUser.class, SWCommandUtils.createMapper(SteamwarUser::get, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()))); + + TypeMappers.init(); } } diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index 1c0839d7..7169c940 100644 --- a/src/de/steamwar/messages/BungeeCore.properties +++ b/src/de/steamwar/messages/BungeeCore.properties @@ -18,6 +18,8 @@ DEV_UNKNOWN_SERVER=§cPlease specify a dev server. DISABLED=§cCurrently disabled. +SERVER_START_OVERLOAD=§cServer start cancelled due to overload. Please try again later. + #ModLoader blocker MODLOADER_INSTALLED=§7You play with §e{0} §7client. Therefore you can't join arenas. MODLOADER_INSTALLED_FABRIC=§7You play with §e{0} §7client. You can join arenas only with the FabricModSender https://steamwar.de/downloads installed. @@ -116,7 +118,7 @@ MOD_YELLOW_PLUR=§7Deactivate the mods\n§e{0}\n§7to continue playing on §eSte #Various commands ALERT=§f{0} -STAT_SERVER=§7Server §e{0}§8: §7Load §e{1} §7Server count §e{2} +STAT_SERVER=§7Server §e{0}§8: §7Below limit §e{1} §7Server count §e{2} #Ban&Mute-Command PUNISHMENT_USAGE=§8/§7{0} §8[§eplayer§8] [§edd§8.§emm§8.§eyyyy §7or §edd§8.§emm§8.§eyyyy§8_§ehh§8:§emm §7or §eperma§8] [§ereason§8] @@ -507,13 +509,10 @@ UNIGNORE_NOT_IGNORED=§cYou are not ignoring this player. UNIGNORE_UNIGNORED=§7You ignored §e{0}§8. #WebregisterCommand -WEB_USAGE=§8/§7webregister §8[§eE-Mail§8] -WEB_ALREADY=§cYou already have a webaccount. -WEB_ALREADY_EMAIL=§cYou already used this E-Mail address on another account... -WEB_NOT_EMAIL=§c[E-Mail], not [free text]! -WEB_EMAIL_REFRESH=§aYour E-Mail was updated. -WEB_INTERNAL_ERROR=§cAn internal error occurred, please contact a developer. -WEB_EMAIL_SEND=§aAn E-Mail to reset your password has been sent. +WEB_USAGE=§8/§7webpassword §8[§epassword§8] +WEB_UPDATED=§7Your password was updated. +WEB_CREATED=§7Your webaccount was created. +WEB_PASSWORD_LENGTH=§cYour password is shorter than 8 characters. #ChatListener CHAT_LIXFEL_ACTION_BAR=§4§lTechnical problems? @@ -641,4 +640,8 @@ FIGHT_MERGE_OFFLINE=§7The proposed arena has been terminated in the meantime, a FIGHT_MERGE_INFO=§e{0}§8: §e{1} #Locale Locking -LOCK_LOCALE_CHANGED=§aLanguage saved \ No newline at end of file +LOCK_LOCALE_CHANGED=§aLanguage saved + +#Builder Cloud +BUILDERCLOUD_USAGE=§8/§7buildercloud §8[§eversion§8] §8[§emap§8] §8<§7generator§8> +BUILDERCLOUD_VERSION=§cUnknown version. \ No newline at end of file diff --git a/src/de/steamwar/messages/BungeeCore_de.properties b/src/de/steamwar/messages/BungeeCore_de.properties index 1a1725af..068c7df4 100644 --- a/src/de/steamwar/messages/BungeeCore_de.properties +++ b/src/de/steamwar/messages/BungeeCore_de.properties @@ -14,6 +14,8 @@ DEV_UNKNOWN_SERVER=§cBitte gib einen DevServer an. DISABLED=§cDerzeit deaktiviert. +SERVER_START_OVERLOAD=§cDer Serverstart wurde aufgrund von Überlastung abgebrochen. Versuche es später erneut. + #ModLoader blocker MODLOADER_INSTALLED=§7Du spielst mit §e{0} §7Client. Daher kannst du keinen Arenen beitreten. MODLOADER_INSTALLED_FABRIC=§7Du spielst mit §e{0} §7Client. Nur mit dem FabricModSender https://steamwar.de/downloads kannst du Arenen beitreten. @@ -101,7 +103,7 @@ MOD_YELLOW_SING=§7Deaktiviere den Mod §e{0}§7, um weiter auf §eSteam§8War MOD_YELLOW_PLUR=§7Deaktiviere die Mods\n§e{0}\n§7um weiter auf §eSteam§8War §7spielen zu können. #Various commands -STAT_SERVER=§7Server §e{0}§8: §7Load §e{1} §7Serveranzahl §e{2} +STAT_SERVER=§7Server §e{0}§8: §7Startfähig §e{1} §7Serveranzahl §e{2} #Ban&Mute-Command PUNISHMENT_USAGE=§8/§7{0} §8[§eSpieler§8] [§edd§8.§emm§8.§eyyyy §7oder §edd§8.§emm§8.§eyyyy§8_§ehh§8:§emm §7oder §eperma§8] [§eGrund§8] @@ -486,13 +488,10 @@ UNIGNORE_NOT_IGNORED=§cDu ignorierst diesen Spieler nicht. UNIGNORE_UNIGNORED=§7Du empfängst nun wieder Nachrichten von §e{0}§8. #WebregisterCommand -WEB_USAGE=§8/§7webregister §8[§eE-Mail§8] -WEB_ALREADY=§cDu hast bereits einen Webaccount. -WEB_ALREADY_EMAIL=§cDie E-Mail hast du bereits für einen anderen Account verwendet... -WEB_NOT_EMAIL=§c[E-Mail], nicht [Freitext]! -WEB_EMAIL_REFRESH=§aDeine E-Mail-Adresse wurde aktualisiert. -WEB_INTERNAL_ERROR=§cEin interner Fehler ist aufgetreten, bitte wende dich an einen Developer. -WEB_EMAIL_SEND=§aEine E-Mail zum Setzen des Passworts wurde gesendet. +WEB_USAGE=§8/§7webpassword §8[§ePasswort§8] +WEB_UPDATED=§7Dein Passwort wurde aktualisiert. +WEB_CREATED=§7Dein Webaccount wurde erstellt. +WEB_PASSWORD_LENGTH=§cDein Passwort ist kürzer als 8 Zeichen. #ChatListener CHAT_LIXFEL_ACTION_BAR=§4§lTechnische Probleme? @@ -619,4 +618,8 @@ FIGHT_MERGE_INFO_LORE_1=§8Von: §e{0} FIGHT_MERGE_OFFLINE=§7Die vorgeschlagene Arena wurde in der Zwischenzeit beendet, es wird eine neue Arena gestartet. #Locale Locking -LOCK_LOCALE_CHANGED=§aSprache gespeichert \ No newline at end of file +LOCK_LOCALE_CHANGED=§aSprache gespeichert + +#Builder Cloud +BUILDERCLOUD_USAGE=§8/§7buildercloud §8[§eVersion§8] §8[§eWelt§8] §8<§7Generator§8> +BUILDERCLOUD_VERSION=§cUnbekannte Version. \ No newline at end of file diff --git a/src/de/steamwar/messages/ChatSender.java b/src/de/steamwar/messages/ChatSender.java index 6879505f..5b79204f 100644 --- a/src/de/steamwar/messages/ChatSender.java +++ b/src/de/steamwar/messages/ChatSender.java @@ -107,6 +107,14 @@ public interface ChatSender { return new TextComponent(parse(prefixed, message)); } + default String parseToPlain(String format, Object... params) { + return parseToPlain(new Message(format, params)); + } + + default String parseToPlain(Message message) { + return parseToComponent(false, message).toPlainText(); + } + default String parseToLegacy(String format, Object... params) { return parseToLegacy(new Message(format, params)); }