diff --git a/.gitignore b/.gitignore index 36e1257..793d15d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,4 @@ steamwar.properties # IntelliJ IDEA .idea -*.iml - -# Other -lib \ No newline at end of file +*.iml \ No newline at end of file diff --git a/BUILDING.md b/BUILDING.md deleted file mode 100644 index 7083919..0000000 --- a/BUILDING.md +++ /dev/null @@ -1,23 +0,0 @@ -# Building - -Building SteamWar.de software requires certain libraries, -which cannot be provided over traditional ways (like maven) -due to copyright issues with compiled Spigot packages. -For building these libraries have to be named in a lib -directory named like in the following list. -A subset of the following libraries is required to build this software -(this is the list for being able to build all SteamWar.de software): - - - BungeeCord.jar https://ci.md-5.net/job/BungeeCord/ - - BungeeTabListPlus.jar https://www.spigotmc.org/resources/bungeetablistplus.313/ - - PersistentBungeeCore.jar https://steamwar.de/devlabs/SteamWar/PersistentBungeeCore - - ProtocolLib.jar https://www.spigotmc.org/resources/protocollib.1997/ - - Spigot-1.8.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.8.9) - - Spigot-1.9.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.9.4) - - Spigot-1.10.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.10.2) - - Spigot-1.12.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.12.2) - - Spigot-1.14.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.14.4) - - Spigot-1.15.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.15.2) - - SpigotCore.jar https://steamwar.de/devlabs/SteamWar/SpigotCore - - WorldEdit-1.12.jar https://dev.bukkit.org/projects/worldedit/files (6.1.9) - - WorldEdit-1.15.jar https://dev.bukkit.org/projects/worldedit/files (newest) \ No newline at end of file diff --git a/CommonCore b/CommonCore index 8dbab5b..21e77c5 160000 --- a/CommonCore +++ b/CommonCore @@ -1 +1 @@ -Subproject commit 8dbab5b132d2fd84db202d691fd1f817f91579d6 +Subproject commit 21e77c55f023261d3a63d5c6200d28b2f6f6fc4c diff --git a/build.gradle b/build.gradle index 7b1f796..dd9ed88 100644 --- a/build.gradle +++ b/build.gradle @@ -18,9 +18,8 @@ */ -import org.apache.tools.ant.taskdefs.condition.Os -import java.util.function.BiConsumer +import org.apache.tools.ant.taskdefs.condition.Os plugins { // Adding the base plugin fixes the following gradle warnings in IntelliJ: @@ -84,6 +83,10 @@ repositories { maven { url 'https://m2.dv8tion.net/releases' } + + maven { + url = uri('https://steamwar.de/maven') + } } dependencies { @@ -92,9 +95,8 @@ dependencies { annotationProcessor 'org.projectlombok:lombok:1.18.22' testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' - compileOnly files("${projectDir}/lib/BungeeCord.jar") - compileOnly files("${projectDir}/lib/PersistentBungeeCore.jar") - compileOnly files("${projectDir}/lib/BungeeTabListPlus.jar") + compileOnly 'de.steamwar:waterfall:RELEASE' + compileOnly 'de.steamwar:persistentbungeecore:RELEASE' implementation("net.dv8tion:JDA:4.3.0_299") { exclude module: 'opus-java' } diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index 8336ea7..8518c97 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -27,9 +27,12 @@ import de.steamwar.bungeecore.listeners.mods.*; import de.steamwar.bungeecore.network.BungeeNetworkHandler; import de.steamwar.bungeecore.network.NetworkReceiver; import de.steamwar.bungeecore.sql.*; +import de.steamwar.bungeecore.tablist.TablistManager; import de.steamwar.command.SWCommandUtils; import de.steamwar.command.SWTypeMapperCreator; +import de.steamwar.command.TabCompletionCache; import de.steamwar.command.TypeMapper; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; @@ -68,6 +71,7 @@ public class BungeeCore extends Plugin { public static final Map commands = new HashMap<>(); private ErrorLogger errorLogger; + private TablistManager tablistManager; @Override public void onEnable(){ @@ -82,6 +86,7 @@ public class BungeeCore extends Plugin { return tabCompleter.apply(sender, s); } }); + BungeeCord.getInstance().getScheduler().schedule(this, TabCompletionCache::invalidateOldEntries, 1, 1, TimeUnit.SECONDS); getProxy().registerChannel("sw:bridge"); getProxy().registerChannel("fabricmodsender:mods"); @@ -175,7 +180,7 @@ public class BungeeCore extends Plugin { new SessionManager(); new NetworkReceiver(); BungeeNetworkHandler.register(); - new TablistManager(); + tablistManager = new TablistManager(); new SettingsChangedListener(); getProxy().getScheduler().schedule(this, () -> { @@ -203,6 +208,8 @@ public class BungeeCore extends Plugin { } } + if(tablistManager != null) + tablistManager.disable(); errorLogger.unregister(); Statement.closeAll(); } diff --git a/src/de/steamwar/bungeecore/commands/AlertCommand.java b/src/de/steamwar/bungeecore/commands/AlertCommand.java index a271cf8..9eb32d3 100644 --- a/src/de/steamwar/bungeecore/commands/AlertCommand.java +++ b/src/de/steamwar/bungeecore/commands/AlertCommand.java @@ -21,49 +21,28 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.bot.SteamwarDiscordBot; +import de.steamwar.command.SWCommand; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.CommandSender; -public class AlertCommand extends BasicCommand { +public class AlertCommand extends SWCommand { public AlertCommand() { super("alert", "bungeecore.alert", "broadcast", "bbc"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(args.length == 0){ - Message.send("USAGE_ALERT", sender); + @Register(description = "USAGE_ALERT") + public void broadcast(CommandSender sender, @OptionalValue("") @StaticValue("-discord") String sendToDiscord, String... message) { + if (message.length == 0) { + ChatSender.of(sender).system(new Message("USAGE_ALERT")); return; } - String s; - boolean discordAnnounce = false; - if (args[0].equals("-discord")) { - if (args.length == 1) { - Message.send("USAGE_ALERT", sender); - return; - } - discordAnnounce = true; - s = join(1, args); - } else { - s = join(0, args); - } - + String s = String.join(" ", message); Message.broadcast("ALERT", ChatColor.translateAlternateColorCodes('&', s)); - if (discordAnnounce && SteamwarDiscordBot.instance() != null) { + if ("-discord".equals(sendToDiscord) && SteamwarDiscordBot.instance() != null) { SteamwarDiscordBot.instance().getAnnouncementListener().announce(s); } } - - private String join(int startIndex, String... strings) { - StringBuilder st = new StringBuilder(); - for (int i = startIndex; i < strings.length; i++) { - if (i != startIndex) { - st.append(" "); - } - st.append(strings[i]); - } - return st.toString(); - } } diff --git a/src/de/steamwar/bungeecore/commands/BauCommand.java b/src/de/steamwar/bungeecore/commands/BauCommand.java index fb28fd8..ee6181a 100644 --- a/src/de/steamwar/bungeecore/commands/BauCommand.java +++ b/src/de/steamwar/bungeecore/commands/BauCommand.java @@ -25,6 +25,7 @@ import de.steamwar.bungeecore.inventory.SWItem; import de.steamwar.bungeecore.network.NetworkSender; import de.steamwar.bungeecore.sql.BauweltMember; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.bungeecore.util.Chat19; import de.steamwar.messages.ChatSender; import de.steamwar.network.packets.server.BaumemberUpdatePacket; import net.md_5.bungee.api.CommandSender; @@ -60,7 +61,7 @@ public class BauCommand extends BasicCommand { teleport(p, args); break; case "info": - p.chat("/bauinfo"); + Chat19.chat(p, "/bauinfo"); break; case "togglewe": togglewe(p, args); diff --git a/src/de/steamwar/bungeecore/commands/BugCommand.java b/src/de/steamwar/bungeecore/commands/BugCommand.java index 2f60785..9648423 100644 --- a/src/de/steamwar/bungeecore/commands/BugCommand.java +++ b/src/de/steamwar/bungeecore/commands/BugCommand.java @@ -19,27 +19,22 @@ package de.steamwar.bungeecore.commands; -import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.SWException; import de.steamwar.bungeecore.sql.SteamwarUser; -import net.md_5.bungee.api.CommandSender; +import de.steamwar.command.SWCommand; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.connection.ProxiedPlayer; -public class BugCommand extends BasicCommand { +public class BugCommand extends SWCommand { public BugCommand() { super("bug", null); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - - ProxiedPlayer player = (ProxiedPlayer) sender; + @Register + public void bugMessage(ProxiedPlayer player, String... message) { String server = player.getServer().getInfo().getName(); - String message = String.join(" ", args); SteamwarUser user = SteamwarUser.get(player.getUniqueId()); - SWException.log(server, message, player.getName() + " " + user.getId()); - Message.send("BUG_MESSAGE", player); + SWException.log(server, String.join(" ", message), player.getName() + " " + user.getId()); + ChatSender.of(player).system("BUG_MESSAGE"); } } diff --git a/src/de/steamwar/bungeecore/commands/CheckCommand.java b/src/de/steamwar/bungeecore/commands/CheckCommand.java index ec5b5cb..02fc7a8 100644 --- a/src/de/steamwar/bungeecore/commands/CheckCommand.java +++ b/src/de/steamwar/bungeecore/commands/CheckCommand.java @@ -26,6 +26,7 @@ import de.steamwar.bungeecore.sql.CheckedSchematic; import de.steamwar.bungeecore.sql.SchematicNode; import de.steamwar.bungeecore.sql.SchematicType; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; @@ -41,7 +42,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.logging.Level; -public class CheckCommand extends BasicCommand { +public class CheckCommand extends SWCommand { private static Map> checkQuestions = new HashMap<>(); private static Map> ranks = new HashMap<>(); @@ -77,55 +78,8 @@ public class CheckCommand extends BasicCommand { Message.send("CHECK_REMINDER", player, Message.parse("CHECK_REMINDER_HOVER", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size()); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - ProxiedPlayer player = (ProxiedPlayer) sender; - - if(args.length == 0){ - help(sender); - return; - } - - switch(args[0].toLowerCase()){ - case "list": - list(player); - break; - case "schematic": - schematic(player, args[1]); - break; - case "next": - case "accept": - next(player, args); - break; - case "cancel": - abort(player); - break; - case "decline": - decline(player, args); - break; - default: - help(player); - } - } - - public static List getSchemsToCheck(){ - List schematicList = new LinkedList<>(); - - for (SchematicType type : SchematicType.values()) { - if (type.check()) - schematicList.addAll(SchematicNode.getAllSchematicsOfType(type.toDB())); - } - return schematicList; - } - - public static String getChecker(SchematicNode schematic) { - if (currentSchems.get(schematic.getId()) == null) return null; - return currentSchems.get(schematic.getId()).checker.getName(); - } - - private void list(ProxiedPlayer player) { + @Register(value = "list", description = "CHECK_HELP_LIST") + public void list(ProxiedPlayer player) { List schematicList = getSchemsToCheck(); Message.sendPrefixless("CHECK_LIST_HEADER", player, schematicList.size()); @@ -153,7 +107,8 @@ public class CheckCommand extends BasicCommand { } } - private void schematic(ProxiedPlayer player, String schemID){ + @Register(value = "schematic", noTabComplete = true) + public void schematic(ProxiedPlayer player, String schemID) { if(isChecking(player)){ Message.send("CHECK_SCHEMATIC_ALREADY_CHECKING", player); return; @@ -171,6 +126,57 @@ public class CheckCommand extends BasicCommand { new CheckSession(player, schem); } + @Register(value = "cancel", description = "CHECK_HELP_CANCEL") + @Register("abort") + public void abortCommand(ProxiedPlayer player) { + abort(player); + } + + public static void abort(ProxiedPlayer player) { + if(notChecking(player)) + return; + + Message.send("CHECK_ABORT", player); + currentCheckers.get(player.getUniqueId()).abort(); + } + + @Register(value = "next", description = "CHECK_HELP_NEXT") + public void next(ProxiedPlayer player) { + next(player, new String[0]); + } + + @Register(value = "accept") + public void accept(ProxiedPlayer player, @OptionalValue("") String rank) { + if (rank.equals("")) { + next(player, new String[0]); + } else { + next(player, new String[]{rank}); + } + } + + @Register(value = "decline", description = "CHECK_HELP_DECLINE") + public void decline(ProxiedPlayer player, String... message) { + if(notChecking(player)) + return; + + currentCheckers.get(player.getUniqueId()).decline(String.join(" ", message)); + } + + public static List getSchemsToCheck(){ + List schematicList = new LinkedList<>(); + + for (SchematicType type : SchematicType.values()) { + if (type.check()) + schematicList.addAll(SchematicNode.getAllSchematicsOfType(type.toDB())); + } + return schematicList; + } + + public static String getChecker(SchematicNode schematic) { + if (currentSchems.get(schematic.getId()) == null) return null; + return currentSchems.get(schematic.getId()).checker.getName(); + } + private static boolean notChecking(ProxiedPlayer player){ if(!isChecking(player)){ Message.send("CHECK_NOT_CHECKING", player); @@ -184,9 +190,9 @@ public class CheckCommand extends BasicCommand { return; int rank = 0; - if(args.length > 1){ + if(args.length > 0){ try{ - rank = Integer.parseInt(args[1]); + rank = Integer.parseInt(args[0]); }catch(NumberFormatException e){ Message.send("CHECK_INVALID_RANK", player); return; @@ -196,37 +202,6 @@ public class CheckCommand extends BasicCommand { currentCheckers.get(player.getUniqueId()).next(rank); } - public static void abort(ProxiedPlayer player){ - if(notChecking(player)) - return; - - Message.send("CHECK_ABORT", player); - currentCheckers.get(player.getUniqueId()).abort(); - } - - private void decline(ProxiedPlayer player, String[] args){ - if(notChecking(player)) - return; - - if(args.length < 2) { - help(player); - return; - } - - StringBuilder message = new StringBuilder(); - for (int i = 1; i < args.length; i++) - message.append(args[i]).append(" "); - - currentCheckers.get(player.getUniqueId()).decline(message.toString()); - } - - private void help(CommandSender sender){ - Message.sendPrefixless("CHECK_HELP_LIST", sender); - Message.sendPrefixless("CHECK_HELP_NEXT", sender); - Message.sendPrefixless("CHECK_HELP_DECLINE", sender); - Message.sendPrefixless("CHECK_HELP_CANCEL", sender); - } - private static class CheckSession{ private final ProxiedPlayer checker; private final SchematicNode schematic; diff --git a/src/de/steamwar/bungeecore/commands/DevCommand.java b/src/de/steamwar/bungeecore/commands/DevCommand.java index 753fdc4..4f06408 100644 --- a/src/de/steamwar/bungeecore/commands/DevCommand.java +++ b/src/de/steamwar/bungeecore/commands/DevCommand.java @@ -21,89 +21,98 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.sql.Punishment; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.command.*; import de.steamwar.messages.ChatSender; -import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.io.File; import java.net.InetSocketAddress; -import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.stream.Collectors; -public class DevCommand extends BasicCommand { +public class DevCommand extends SWCommand { private final File devServerDir = new File("/configs/DevServer"); private final Map devServers = new HashMap<>(); public DevCommand() { - super("dev", ""); + super("dev"); } - @Override - public void execute(CommandSender s, String[] args) { - if (!(s instanceof ProxiedPlayer)) - return; - ProxiedPlayer player = (ProxiedPlayer) s; - - ChatSender sender = ChatSender.of(player); - if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoDevServer)) { - return; - } - + @Register + public void simpleCommand(@Guard ProxiedPlayer player) { updateDevServers(); - if(devServers.isEmpty()) { + ChatSender sender = ChatSender.of(player); + if (devServers.isEmpty()) { sender.system("DEV_NO_SERVER"); + return; } else if (devServers.size() == 1) { player.connect(devServers.values().stream().findAny().get()); - } else if (args.length == 0) { - ServerInfo info = devServers.get(player.getName().toLowerCase()); - if (info == null) { - sender.system("DEV_UNKNOWN_SERVER"); - return; - } - - player.connect(info); - } else { - ServerInfo info = devServers.get(args[0].toLowerCase()); - if (info == null) { - sender.system("DEV_NO_SERVER"); - return; - } - - player.connect(info); + return; } + + ServerInfo info = devServers.get(player.getName().toLowerCase()); + if (info == null) { + sender.system("DEV_UNKNOWN_SERVER"); + return; + } + + player.connect(info); } - @Override - public Iterable onTabComplete(CommandSender sender, String[] args) { - if (!(sender instanceof ProxiedPlayer) || args.length > 1) { - return Collections.emptyList(); + @Register + public void selectedCommand(@Guard ProxiedPlayer player, @Mapper("dev") String name) { + updateDevServers(); + ChatSender sender = ChatSender.of(player); + ServerInfo info = devServers.get(name.toLowerCase()); + if (info == null) { + sender.system("DEV_NO_SERVER"); + return; } - updateDevServers(); - return devServers.keySet().stream().filter(s -> { - if (args.length == 0) return true; - return s.startsWith(args[0].toLowerCase()); - }).collect(Collectors.toList()); + 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; + } + } + return GuardResult.ALLOWED; + }; + } + + @Mapper(value = "dev", local = true) + public TypeMapper devServers() { + return SWCommandUtils.createMapper(s -> s, s -> { + updateDevServers(); + return devServers.keySet(); + }); } private void updateDevServers() { String[] serverFiles = devServerDir.list(); Map devServerFiles = new HashMap<>(); - if(serverFiles != null) { - for(String serverFile : serverFiles) { + if (serverFiles != null) { + for (String serverFile : serverFiles) { String[] server = serverFile.split("\\."); devServerFiles.put(server[0], Integer.parseInt(server[1])); } } devServers.entrySet().removeIf(entry -> { - if(!devServerFiles.containsKey(entry.getKey())) { + if (!devServerFiles.containsKey(entry.getKey())) { ProxyServer.getInstance().getServers().remove(entry.getValue().getName()); return true; } diff --git a/src/de/steamwar/bungeecore/commands/EventCommand.java b/src/de/steamwar/bungeecore/commands/EventCommand.java index c6ed448..75f718f 100644 --- a/src/de/steamwar/bungeecore/commands/EventCommand.java +++ b/src/de/steamwar/bungeecore/commands/EventCommand.java @@ -20,10 +20,7 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.*; -import de.steamwar.bungeecore.sql.Event; -import de.steamwar.bungeecore.sql.EventFight; -import de.steamwar.bungeecore.sql.Team; -import de.steamwar.bungeecore.sql.TeamTeilnahme; +import de.steamwar.bungeecore.sql.*; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -84,6 +81,13 @@ public class EventCommand extends BasicCommand { if(now.isBefore(e.getDeadline().toInstant())) { Message.send("EVENT_COMING_DEADLINE", player, e.getDeadline()); } + String schemType = e.getSchemType(); + if (schemType != null) { + SchematicType schematicType = SchematicType.fromDB(schemType); + if (schematicType != null && schematicType.deadline() != null && now.isBefore(schematicType.deadline().toInstant())) { + Message.send("EVENT_COMING_SCHEM_DEADLINE", player, e.getDeadline()); + } + } if(!teams.isEmpty()){ StringBuilder tline = new StringBuilder(); for(Team t : teams){ diff --git a/src/de/steamwar/bungeecore/commands/EventRescheduleCommand.java b/src/de/steamwar/bungeecore/commands/EventRescheduleCommand.java index 06934f3..bc7465c 100644 --- a/src/de/steamwar/bungeecore/commands/EventRescheduleCommand.java +++ b/src/de/steamwar/bungeecore/commands/EventRescheduleCommand.java @@ -23,35 +23,29 @@ import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.Event; import de.steamwar.bungeecore.sql.EventFight; import de.steamwar.bungeecore.sql.Team; +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.sql.Timestamp; +import java.util.Collection; import java.util.Date; import java.util.List; import java.util.ListIterator; +import java.util.stream.Collectors; +import java.util.stream.Stream; -public class EventRescheduleCommand extends BasicCommand { +public class EventRescheduleCommand extends SWCommand { public EventRescheduleCommand() { super("eventreschedule", "bungeecore.softreload"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - ProxiedPlayer player = (ProxiedPlayer) sender; - - if(args.length != 2){ - Message.send("EVENTRESCHEDULE_USAGE", player); - return; - } - - Team teamBlue = Team.get(args[0]); - Team teamRed = Team.get(args[1]); + @Register + public void reschedule(ProxiedPlayer player, Team teamBlue, Team teamRed) { Event event = Event.get(); - if(teamBlue == null || teamRed == null || event == null){ + if(event == null){ Message.send("EVENTRESCHEDULE_UNKNOWN_TEAM", player); return; } @@ -74,4 +68,22 @@ public class EventRescheduleCommand extends BasicCommand { Message.send("EVENTRESCHEDULE_NO_FIGHT", player); } + + @Register + public TypeMapper teamTypeMapper() { + return new TypeMapper() { + @Override + public Team map(CommandSender commandSender, String[] previousArguments, String s) { + return Team.get(s); + } + + @Override + public Collection tabCompletes(CommandSender sender, String[] previousArguments, String s) { + Event event = Event.get(); + if (event == null) return null; + List fights = EventFight.getEvent(event.getEventID()); + return fights.stream().flatMap(fight -> Stream.of(fight.getTeamBlue(), fight.getTeamRed())).map(Team::get).map(Team::getTeamKuerzel).distinct().collect(Collectors.toList()); + } + }; + } } diff --git a/src/de/steamwar/bungeecore/commands/EventreloadCommand.java b/src/de/steamwar/bungeecore/commands/EventreloadCommand.java index 239b9de..9d5008a 100644 --- a/src/de/steamwar/bungeecore/commands/EventreloadCommand.java +++ b/src/de/steamwar/bungeecore/commands/EventreloadCommand.java @@ -20,15 +20,16 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.sql.EventFight; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.CommandSender; -public class EventreloadCommand extends BasicCommand { +public class EventreloadCommand extends SWCommand { public EventreloadCommand() { super("eventreload", "bungeecore.softreload"); } - @Override - public void execute(CommandSender sender, String[] args) { + @Register + public void execute(CommandSender sender) { EventFight.loadAllComingFights(); } } diff --git a/src/de/steamwar/bungeecore/commands/GDPRQuery.java b/src/de/steamwar/bungeecore/commands/GDPRQuery.java index 444a22c..671d5a2 100644 --- a/src/de/steamwar/bungeecore/commands/GDPRQuery.java +++ b/src/de/steamwar/bungeecore/commands/GDPRQuery.java @@ -4,6 +4,7 @@ import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.Statement; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.command.SWCommand; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -12,19 +13,20 @@ import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -public class GDPRQuery extends BasicCommand { +public class GDPRQuery extends SWCommand { public GDPRQuery() { super("gdprquery", "bungeecore.softreload"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; + @Register + public void generate(ProxiedPlayer player) { + generate(player, player); + } - ProxiedPlayer player = (ProxiedPlayer) sender; - SteamwarUser user = args.length == 0 ? SteamwarUser.get(player.getUniqueId()) : SteamwarUser.get(args[0]); + @Register + public void generate(ProxiedPlayer player, ProxiedPlayer forPlayer) { + SteamwarUser user = SteamwarUser.get(forPlayer); if(user == null) { Message.send("UNKNOWN_PLAYER", player); return; diff --git a/src/de/steamwar/bungeecore/commands/IgnoreCommand.java b/src/de/steamwar/bungeecore/commands/IgnoreCommand.java index 9151fde..0c11ee0 100644 --- a/src/de/steamwar/bungeecore/commands/IgnoreCommand.java +++ b/src/de/steamwar/bungeecore/commands/IgnoreCommand.java @@ -22,28 +22,26 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.IgnoreSystem; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; -public class IgnoreCommand extends BasicCommand { +import java.util.stream.Collectors; + +public class IgnoreCommand extends SWCommand { public IgnoreCommand() { super("ignore", null); } - @Override - public void execute(CommandSender sender, String[] args) { - if(args.length < 1) { - Message.send("USAGE_IGNORE", sender); - return; - } - - if (!(sender instanceof ProxiedPlayer)) - return; - ProxiedPlayer p = (ProxiedPlayer) sender; + @Register(description = "USAGE_IGNORE") + public void genericCommand(ProxiedPlayer p, @Mapper("player") String toIgnore) { SteamwarUser user = SteamwarUser.get(p.getUniqueId()); - SteamwarUser target = SteamwarUser.get(args[0]); + SteamwarUser target = SteamwarUser.get(toIgnore); if(target == null){ Message.send("UNKNOWN_PLAYER", p); return; @@ -60,4 +58,9 @@ public class IgnoreCommand extends BasicCommand { IgnoreSystem.ignore(user, target); Message.send("IGNORE_MESSAGE", p, target.getUserName()); } + + @Mapper(value = "player", local = true) + public TypeMapper playerTypeMapper() { + return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList())); + } } diff --git a/src/de/steamwar/bungeecore/commands/KickCommand.java b/src/de/steamwar/bungeecore/commands/KickCommand.java index cb27fab..54a2e49 100644 --- a/src/de/steamwar/bungeecore/commands/KickCommand.java +++ b/src/de/steamwar/bungeecore/commands/KickCommand.java @@ -21,48 +21,40 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.Message; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; -import java.util.ArrayList; +import java.util.stream.Collectors; -public class KickCommand extends BasicCommand { +public class KickCommand extends SWCommand { public KickCommand() { super("kick", "bungeecore.kick"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(args.length == 0){ - Message.send("KICK_USAGE", sender); - return; - } - - ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]); + @Register(description = "KICK_USAGE") + public void genericCommand(CommandSender sender, @Mapper("player") String player, String... message) { + ProxiedPlayer target = ProxyServer.getInstance().getPlayer(player); if(target == null){ Message.send("KICK_OFFLINE", sender); return; } - if(args.length == 1){ + if (message.length == 0) { target.disconnect(Message.parseToComponent("KICK_NORMAL", true, target)); - }else{ - StringBuilder msgBuilder = new StringBuilder(); - msgBuilder.append(BungeeCore.CHAT_PREFIX).append("§c"); - for (int i = 1; i < args.length; i++){ - msgBuilder.append(args[i]).append(" "); - } - target.disconnect(BungeeCore.stringToText(msgBuilder.toString())); + } else { + target.disconnect(BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + "§c" + String.join(" ", message))); } Message.send("KICK_CONFIRM", sender, target.getName()); } - @Override - public Iterable onTabComplete(CommandSender commandSender, String[] args) { - if(args.length == 1) - return allPlayers(args[0]); - return new ArrayList<>(); + @Mapper(value = "player", local = true) + public TypeMapper playerTypeMapper() { + return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList())); } } diff --git a/src/de/steamwar/bungeecore/commands/ListCommand.java b/src/de/steamwar/bungeecore/commands/ListCommand.java index 631f408..6caa4a1 100644 --- a/src/de/steamwar/bungeecore/commands/ListCommand.java +++ b/src/de/steamwar/bungeecore/commands/ListCommand.java @@ -22,6 +22,7 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.Servertype; import de.steamwar.bungeecore.Subserver; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; @@ -33,7 +34,7 @@ import java.util.List; import java.util.TreeMap; import java.util.stream.Collectors; -public class ListCommand extends BasicCommand { +public class ListCommand extends SWCommand { public ListCommand() { super("list", ""); @@ -60,8 +61,8 @@ public class ListCommand extends BasicCommand { return playerMap; } - @Override - public void execute(CommandSender commandSender, String[] strings) { + @Register + public void genericCommand(CommandSender commandSender) { TreeMap> playerMap = getCustomTablist(); for (String server : playerMap.navigableKeySet()) { String serverName = server; diff --git a/src/de/steamwar/bungeecore/commands/LocalCommand.java b/src/de/steamwar/bungeecore/commands/LocalCommand.java index 28717f7..ab77eb3 100644 --- a/src/de/steamwar/bungeecore/commands/LocalCommand.java +++ b/src/de/steamwar/bungeecore/commands/LocalCommand.java @@ -20,20 +20,18 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.listeners.ChatListener; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; -public class LocalCommand extends BasicCommand { +public class LocalCommand extends SWCommand { public LocalCommand() { super("local", null, "bc", "bauchat"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - - ChatListener.localChat((ProxiedPlayer) sender, String.join(" ", args)); + @Register + public void genericCommand(ProxiedPlayer player, String... message) { + ChatListener.localChat(player, String.join(" ", message)); } } diff --git a/src/de/steamwar/bungeecore/commands/MsgCommand.java b/src/de/steamwar/bungeecore/commands/MsgCommand.java index 0107b78..8dd8e50 100644 --- a/src/de/steamwar/bungeecore/commands/MsgCommand.java +++ b/src/de/steamwar/bungeecore/commands/MsgCommand.java @@ -21,34 +21,23 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.listeners.ChatListener; import de.steamwar.bungeecore.sql.IgnoreSystem; +import de.steamwar.command.SWCommand; import de.steamwar.messages.ChatSender; -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; -import java.util.ArrayList; -import java.util.Arrays; import java.util.stream.Stream; import static de.steamwar.bungeecore.Storage.lastChats; -public class MsgCommand extends BasicCommand { +public class MsgCommand extends SWCommand { public MsgCommand() { super("msg", "", "w", "tell"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - - if (args.length < 2) { - ChatSender.of(sender).system("MSG_USAGE"); - return; - } - - msg((ProxiedPlayer) sender, ProxyServer.getInstance().getPlayer(args[0]), Arrays.copyOfRange(args, 1, args.length)); + @Register(description = "MSG_USAGE") + public void genericCommand(ProxiedPlayer sender, ProxiedPlayer target, @ErrorMessage(value = "MSG_USAGE", allowEAs = false) String... message) { + msg(sender, target, message); } public static void msg(ProxiedPlayer player, ProxiedPlayer target, String[] args) { @@ -69,14 +58,6 @@ public class MsgCommand extends BasicCommand { lastChats.put(target, player); } - @Override - public Iterable onTabComplete(CommandSender commandSender, String[] args) { - if(args.length == 1){ - return allPlayers(args[0]); - } - return new ArrayList<>(); - } - public static void remove(ProxiedPlayer player){ lastChats.remove(player); } diff --git a/src/de/steamwar/bungeecore/commands/PingCommand.java b/src/de/steamwar/bungeecore/commands/PingCommand.java index 014a6df..04c22fa 100644 --- a/src/de/steamwar/bungeecore/commands/PingCommand.java +++ b/src/de/steamwar/bungeecore/commands/PingCommand.java @@ -20,20 +20,17 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; -import net.md_5.bungee.api.CommandSender; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.connection.ProxiedPlayer; -public class PingCommand extends BasicCommand { +public class PingCommand extends SWCommand { public PingCommand() { - super("ping", ""); + super("ping"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(sender instanceof ProxiedPlayer){ - ProxiedPlayer player = (ProxiedPlayer) sender; - Message.send("PING_RESPONSE", player, player.getPing()); - } + @Register + public void genericCommand(ProxiedPlayer player) { + Message.send("PING_RESPONSE", player, player.getPing()); } } diff --git a/src/de/steamwar/bungeecore/commands/PlaytimeCommand.java b/src/de/steamwar/bungeecore/commands/PlaytimeCommand.java index 23e16a0..c9c3850 100644 --- a/src/de/steamwar/bungeecore/commands/PlaytimeCommand.java +++ b/src/de/steamwar/bungeecore/commands/PlaytimeCommand.java @@ -21,6 +21,7 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; import org.apache.commons.lang3.LocaleUtils; @@ -29,21 +30,18 @@ import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Locale; -public class PlaytimeCommand extends BasicCommand{ +public class PlaytimeCommand extends SWCommand { public PlaytimeCommand() { - super("playtime", null); + super("playtime"); } - @Override - public void execute(CommandSender sender, String[] strings) { - if(!(sender instanceof ProxiedPlayer)) - return; - - NumberFormat format = NumberFormat.getNumberInstance(((ProxiedPlayer)sender).getLocale()); + @Register + public void genericCommand(ProxiedPlayer player) { + NumberFormat format = NumberFormat.getNumberInstance((player).getLocale()); format.setMaximumFractionDigits(2); - String formattedText = format.format((SteamwarUser.get((ProxiedPlayer) sender).getOnlinetime() / (double) 3600)); + String formattedText = format.format((SteamwarUser.get(player).getOnlinetime() / (double) 3600)); - Message.send("HOURS_PLAYED", sender, formattedText); + Message.send("HOURS_PLAYED", player, formattedText); } } diff --git a/src/de/steamwar/bungeecore/commands/PollCommand.java b/src/de/steamwar/bungeecore/commands/PollCommand.java index 3a84f50..e6fb755 100644 --- a/src/de/steamwar/bungeecore/commands/PollCommand.java +++ b/src/de/steamwar/bungeecore/commands/PollCommand.java @@ -23,35 +23,29 @@ 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 net.md_5.bungee.api.connection.ProxiedPlayer; -public class PollCommand extends BasicCommand { +public class PollCommand extends SWCommand { public PollCommand() { - super("poll", ""); + super("poll"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - - ProxiedPlayer player = (ProxiedPlayer) sender; - - if(PollSystem.noCurrentPoll()){ - Message.send("POLL_NO_POLL", player); - return; - } - - if(args.length == 0){ - PollSystem.sendPoll(player); - return; - } + @Register + public void genericCommand(@Guard ProxiedPlayer player) { + PollSystem.sendPoll(player); + } + @Register(noTabComplete = true) + public void answerPoll(@Guard ProxiedPlayer player, String answerString) { int answer; try { - answer = Integer.parseUnsignedInt(args[0]); + answer = Integer.parseUnsignedInt(answerString); if(answer < 1 || answer > PollSystem.answers()) throw new NumberFormatException(); }catch(NumberFormatException e){ @@ -67,4 +61,17 @@ public class PollCommand extends BasicCommand { pollAnswer.setAnswer(answer); } + + @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; + } + return GuardResult.ALLOWED; + }; + } } diff --git a/src/de/steamwar/bungeecore/commands/PollresultCommand.java b/src/de/steamwar/bungeecore/commands/PollresultCommand.java index df77cb8..4011f4c 100644 --- a/src/de/steamwar/bungeecore/commands/PollresultCommand.java +++ b/src/de/steamwar/bungeecore/commands/PollresultCommand.java @@ -22,33 +22,39 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.listeners.PollSystem; import de.steamwar.bungeecore.sql.PollAnswer; -import net.md_5.bungee.api.CommandSender; +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.connection.ProxiedPlayer; import java.util.Map; -public class PollresultCommand extends BasicCommand { +public class PollresultCommand extends SWCommand { public PollresultCommand() { super("pollresult", "bungeecore.pollresults"); } - @Override - public void execute(CommandSender sender, String[] strings) { - if(!(sender instanceof ProxiedPlayer)) - return; - - if(PollSystem.noCurrentPoll()) { - Message.send("POLLRESULT_NOPOLL", sender); - return; - } - - ProxiedPlayer player = (ProxiedPlayer) sender; - + @Register + public void genericCommand(@Guard 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()) { - Message.send("POLLRESULT_LIST", sender, e.getKey(), e.getValue()); + Message.send("POLLRESULT_LIST", player, e.getKey(), e.getValue()); } } + + @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; + } + return GuardResult.ALLOWED; + }; + } } diff --git a/src/de/steamwar/bungeecore/commands/PunishmentCommand.java b/src/de/steamwar/bungeecore/commands/PunishmentCommand.java index a02b48f..888e43c 100644 --- a/src/de/steamwar/bungeecore/commands/PunishmentCommand.java +++ b/src/de/steamwar/bungeecore/commands/PunishmentCommand.java @@ -22,6 +22,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.SWCommand; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -34,65 +35,67 @@ import java.util.Date; public class PunishmentCommand { public PunishmentCommand(String command, Punishment.PunishmentType punishmentType) { - new BasicCommand(command, "bungeecore.ban") { - @Override - public void execute(CommandSender sender, String[] args) { - if (punishmentType.isNeedsAdmin() && !SteamwarUser.get((ProxiedPlayer) sender).getUserGroup().isAdminGroup()) { - return; - } - if (args.length < 3) { - Message.send("PUNISHMENT_USAGE", sender, command); + new SWCommand(command, "bungeecore.ban") { + @Register(description = "PUNISHMENT_USAGE") + public void genericCommand(ProxiedPlayer player, String toPunish, String date, String... message) { + if (punishmentType.isNeedsAdmin() && !SteamwarUser.get(player).getUserGroup().isAdminGroup()) { return; } - SteamwarUser target = unsafeUser(sender, args[0]); + SteamwarUser target = unsafeUser(player, toPunish); if (target == null) return; - Timestamp banTime = parseTime(sender, args[1]); + Timestamp banTime = parseTime(player, date); if (banTime == null) return; - StringBuilder reason = new StringBuilder(); - for (int i = 2; i < args.length; i++) { - reason.append(args[i]).append(" "); - } - boolean isPerma = args[1].equalsIgnoreCase("perma"); - String msg = reason.toString(); - target.punish(punishmentType, banTime, msg, SteamwarUser.get(sender.getName()).getId(), isPerma); - Message.team(punishmentType.getTeamMessage(), new Message("PREFIX"), target.getUserName(), sender.getName(), new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg); + boolean isPerma = date.equalsIgnoreCase("perma"); + String msg = String.join(" ", message); + target.punish(punishmentType, banTime, msg, SteamwarUser.get(player.getName()).getId(), isPerma); + Message.team(punishmentType.getTeamMessage(), new Message("PREFIX"), target.getUserName(), player.getName(), new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg); } }; if (punishmentType.getUnpunishmentMessage() == null) { return; } String antiCommand = "un" + command; - new BasicCommand(antiCommand, "bungeecore.ban") { - @Override - public void execute(CommandSender sender, String[] args) { - if (punishmentType.isNeedsAdmin() && !SteamwarUser.get((ProxiedPlayer) sender).getUserGroup().isAdminGroup()) { - return; - } - if (args.length < 1) { - Message.send("UNPUNISHMENT_USAGE", sender, antiCommand); + new SWCommand(antiCommand, "bungeecore.ban") { + @Register(description = "PUNISHMENT_USAGE") + public void genericCommand(ProxiedPlayer player, String toUnpunish) { + if (punishmentType.isNeedsAdmin() && !SteamwarUser.get(player).getUserGroup().isAdminGroup()) { return; } - SteamwarUser target = existingUser(sender, args[0]); + SteamwarUser target = existingUser(player, toUnpunish); if (target == null) return; if (!target.isPunished(punishmentType)) { - Message.send(punishmentType.getUsageNotPunished(), sender); + Message.send(punishmentType.getUsageNotPunished(), player); return; } - Message.send(punishmentType.getUnpunishmentMessage(), sender, target.getUserName()); - target.punish(punishmentType, Timestamp.from(new Date().toInstant()), antiCommand, SteamwarUser.get(sender.getName()).getId(), false); + Message.send(punishmentType.getUnpunishmentMessage(), player, target.getUserName()); + target.punish(punishmentType, Timestamp.from(new Date().toInstant()), antiCommand, SteamwarUser.get(player.getName()).getId(), false); } }; } + protected SteamwarUser existingUser(CommandSender sender, String arg){ + SteamwarUser target = SteamwarUser.get(arg); + if(target == null) + Message.send("UNKNOWN_PLAYER", sender); + return target; + } + + protected SteamwarUser unsafeUser(CommandSender sender, String arg){ + SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(arg); + if(target == null) + Message.send("UNKNOWN_PLAYER", sender); + return target; + } + public static Timestamp parseTime(CommandSender sender, String arg) { if (arg.equalsIgnoreCase("perma")) { return Punishment.PERMA_TIME; diff --git a/src/de/steamwar/bungeecore/commands/RCommand.java b/src/de/steamwar/bungeecore/commands/RCommand.java index 62e5af8..c7d3d3f 100644 --- a/src/de/steamwar/bungeecore/commands/RCommand.java +++ b/src/de/steamwar/bungeecore/commands/RCommand.java @@ -19,28 +19,19 @@ package de.steamwar.bungeecore.commands; -import de.steamwar.messages.ChatSender; -import net.md_5.bungee.api.CommandSender; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.connection.ProxiedPlayer; import static de.steamwar.bungeecore.Storage.lastChats; -public class RCommand extends BasicCommand { +public class RCommand extends SWCommand { public RCommand() { super("r", "", "reply"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - - if(args.length == 0){ - ChatSender.of(sender).system("R_USAGE"); - return; - } - - MsgCommand.msg((ProxiedPlayer) sender, lastChats.get(sender), args); + @Register(description = "R_USAGE") + public void genericCommand(ProxiedPlayer player, @ErrorMessage(value = "R_USAGE", allowEAs = false) String... message) { + MsgCommand.msg(player, lastChats.get(player), message); } } diff --git a/src/de/steamwar/bungeecore/commands/RankCommand.java b/src/de/steamwar/bungeecore/commands/RankCommand.java index f76932e..eca5518 100644 --- a/src/de/steamwar/bungeecore/commands/RankCommand.java +++ b/src/de/steamwar/bungeecore/commands/RankCommand.java @@ -23,32 +23,36 @@ import de.steamwar.bungeecore.ArenaMode; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.SteamwarUser; import de.steamwar.bungeecore.sql.UserElo; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.Optional; +import java.util.stream.Collectors; -public class RankCommand extends BasicCommand { +public class RankCommand extends SWCommand { public RankCommand() { - super("rank", null); + super("rank"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; + @Register + public void ownRank(ProxiedPlayer player) { + rank(player, player.getName()); + } - ProxiedPlayer player = (ProxiedPlayer) sender; - SteamwarUser user = SteamwarUser.get(player.getUniqueId()); - if (args.length > 0) { - SteamwarUser nUser = SteamwarUser.get(args[0]); - if (nUser == null) { - Message.send("RANK_PLAYER_NOT_FOUND", player); - return; - } - Message.send("RANK_PLAYER_FOUND", player, nUser.getUserName()); - user = nUser; + @Register + public void rank(ProxiedPlayer player, @Mapper("player") String s) { + SteamwarUser user = SteamwarUser.get(s); + if (user == null) { + Message.send("RANK_PLAYER_NOT_FOUND", player); + return; + } + if (!player.getName().equals(s)) { + Message.send("RANK_PLAYER_FOUND", player, user.getUserName()); } for(ArenaMode mode : ArenaMode.getAllModes()) { if (!mode.isRanked()) @@ -67,4 +71,9 @@ public class RankCommand extends BasicCommand { Message.send("RANK_EMBLEM", player, UserElo.getEmblemProgression(player, mode.getChatName(), user.getId())); } } + + @Mapper(value = "player", local = true) + public TypeMapper playerTypeMapper() { + return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList())); + } } diff --git a/src/de/steamwar/bungeecore/commands/RegelnCommand.java b/src/de/steamwar/bungeecore/commands/RegelnCommand.java index 37755f4..2721b73 100644 --- a/src/de/steamwar/bungeecore/commands/RegelnCommand.java +++ b/src/de/steamwar/bungeecore/commands/RegelnCommand.java @@ -20,21 +20,18 @@ 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 BasicCommand { +public class RegelnCommand extends SWCommand { public RegelnCommand() { - super("regeln", null); + super("regeln"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - ProxiedPlayer player = (ProxiedPlayer) sender; - + @Register + public void genericCommand(ProxiedPlayer player) { Message.send("REGELN_RULES", player); Message.sendPrefixless("REGELN_AS", player, Message.parse("REGELN_AS_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_AS_URL", player))); Message.sendPrefixless("REGELN_MWG", player, Message.parse("REGELN_MWG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_MWG_URL", player))); diff --git a/src/de/steamwar/bungeecore/commands/ReplayCommand.java b/src/de/steamwar/bungeecore/commands/ReplayCommand.java index ef6e5c0..1130108 100644 --- a/src/de/steamwar/bungeecore/commands/ReplayCommand.java +++ b/src/de/steamwar/bungeecore/commands/ReplayCommand.java @@ -27,6 +27,7 @@ import de.steamwar.bungeecore.sql.Fight; import de.steamwar.bungeecore.sql.Punishment; import de.steamwar.bungeecore.sql.SchematicType; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.command.SWCommand; import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -35,18 +36,14 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -public class ReplayCommand extends BasicCommand { +public class ReplayCommand extends SWCommand { public ReplayCommand() { - super("replay", null); + super("replay"); } - @Override - public void execute(CommandSender s, String[] args) { - if(!(s instanceof ProxiedPlayer)) - return; - ProxiedPlayer player = (ProxiedPlayer) s; - + @Register + public void genericCommand(ProxiedPlayer player, @OptionalValue("") String optionalMap) { ChatSender sender = ChatSender.of(player); if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer)) return; @@ -57,8 +54,8 @@ public class ReplayCommand extends BasicCommand { ServerStarter starter = new ServerStarter().replay(fight.getFightID()).blueLeader(player); String map = mode.getRandomMap(); - if (args.length > 0) { - String tMap = mode.hasMap(args[0]); + if (!optionalMap.equals("")) { + String tMap = mode.hasMap(optionalMap); if (tMap != null) map = tMap; } diff --git a/src/de/steamwar/bungeecore/commands/ServerSwitchCommand.java b/src/de/steamwar/bungeecore/commands/ServerSwitchCommand.java index 7fef900..19974fd 100644 --- a/src/de/steamwar/bungeecore/commands/ServerSwitchCommand.java +++ b/src/de/steamwar/bungeecore/commands/ServerSwitchCommand.java @@ -19,12 +19,13 @@ package de.steamwar.bungeecore.commands; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; -public class ServerSwitchCommand extends BasicCommand { +public class ServerSwitchCommand extends SWCommand { private String serverName; @@ -33,12 +34,9 @@ public class ServerSwitchCommand extends BasicCommand { serverName = name; } - @Override - public void execute(CommandSender sender, String[] strings) { - if(sender instanceof ProxiedPlayer){ - ProxiedPlayer player = (ProxiedPlayer) sender; - ServerInfo target = ProxyServer.getInstance().getServerInfo(serverName); - player.connect(target); - } + @Register + public void genericCommand(ProxiedPlayer player) { + ServerInfo target = ProxyServer.getInstance().getServerInfo(serverName); + player.connect(target); } } diff --git a/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java b/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java index 26b4db1..ea4ce9f 100644 --- a/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java +++ b/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java @@ -20,23 +20,24 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.listeners.ChatListener; +import de.steamwar.command.SWCommand; import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; -public class ServerTeamchatCommand extends BasicCommand { +public class ServerTeamchatCommand extends SWCommand { public ServerTeamchatCommand() { super("stc", "bungeecore.teamchat","serverteamchat"); } - @Override - public void execute(CommandSender s, String[] args) { - ChatSender sender = ChatSender.of(s); - if(args.length == 0) { + @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(" ", args)); + ChatListener.sendChat(sender, ChatSender.serverteamReceivers(), "CHAT_SERVERTEAM", null, String.join(" ", message)); } } diff --git a/src/de/steamwar/bungeecore/commands/SetLocaleCommand.java b/src/de/steamwar/bungeecore/commands/SetLocaleCommand.java index 9ffbcbc..798a58c 100644 --- a/src/de/steamwar/bungeecore/commands/SetLocaleCommand.java +++ b/src/de/steamwar/bungeecore/commands/SetLocaleCommand.java @@ -19,25 +19,22 @@ package de.steamwar.bungeecore.commands; +import de.steamwar.command.SWCommand; import de.steamwar.messages.ChatSender; -import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.Objects; -public class SetLocaleCommand extends BasicCommand { +public class SetLocaleCommand extends SWCommand { public SetLocaleCommand() { super("setlocale", null, "setlanguage"); } - @Override - public void execute(CommandSender s, String[] strings) { - if (!(s instanceof ProxiedPlayer)) - return; - - ChatSender sender = ChatSender.of(s); - sender.user().setLocale(Objects.requireNonNull(((ProxiedPlayer) s).getLocale()), true); + @Register + public void genericCommand(ProxiedPlayer player) { + ChatSender sender = ChatSender.of(player); + sender.user().setLocale(Objects.requireNonNull(player.getLocale()), true); sender.system("LOCK_LOCALE_CHANGED"); } } diff --git a/src/de/steamwar/bungeecore/commands/StatCommand.java b/src/de/steamwar/bungeecore/commands/StatCommand.java index b633fb5..753f253 100644 --- a/src/de/steamwar/bungeecore/commands/StatCommand.java +++ b/src/de/steamwar/bungeecore/commands/StatCommand.java @@ -21,6 +21,7 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.Node; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.CommandSender; import java.io.BufferedReader; @@ -28,14 +29,14 @@ import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; -public class StatCommand extends BasicCommand { +public class StatCommand extends SWCommand { public StatCommand() { super("stat", "bungeecore.softreload", "stats"); } - @Override - public void execute(CommandSender sender, String[] args) { + @Register + public void genericCommand(CommandSender sender) { Map serverCount = new HashMap<>(); try { Process process = new ProcessBuilder("ps", "x").start(); @@ -53,5 +54,4 @@ public class StatCommand extends BasicCommand { Node.forEach(node -> Message.send("STAT_SERVER", sender, node.getName(), node.getLoad(), serverCount.getOrDefault(node.getName(), 0))); } - } diff --git a/src/de/steamwar/bungeecore/commands/TeamCommand.java b/src/de/steamwar/bungeecore/commands/TeamCommand.java index a6d814c..9ae3799 100644 --- a/src/de/steamwar/bungeecore/commands/TeamCommand.java +++ b/src/de/steamwar/bungeecore/commands/TeamCommand.java @@ -564,11 +564,6 @@ public class TeamCommand extends BasicCommand { } private void tp(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){ - if (!user.getUserGroup().isAdminGroup()) { - Message.send("DISABLED", player); - return; - } - if(args.length == 1){ if(notInTeam(player, user)) return; @@ -615,11 +610,6 @@ public class TeamCommand extends BasicCommand { } private void server(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){ - if (!user.getUserGroup().isAdminGroup()) { - Message.send("DISABLED", player); - return; - } - if(notLeader(player, user, team)) return; if (user.isPunishedWithMessage(ChatSender.of(player), Punishment.PunishmentType.NoTeamServer)) { diff --git a/src/de/steamwar/bungeecore/commands/TpCommand.java b/src/de/steamwar/bungeecore/commands/TpCommand.java index 3961f8c..04cbb02 100644 --- a/src/de/steamwar/bungeecore/commands/TpCommand.java +++ b/src/de/steamwar/bungeecore/commands/TpCommand.java @@ -52,13 +52,18 @@ public class TpCommand extends BasicCommand { return; } - ServerInfo server = getTarget(player, args[0]); + ServerInfo server = getTarget(args[0]); + boolean onTeamServer = Storage.teamServers.containsValue(player.getServer().getInfo()); //Give control of teleport command to server - if(server == null) { + if (server == player.getServer().getInfo() || onTeamServer) { Chat19.chat(player, "/tp " + String.join(" ", args)); return; } + if(server == null) { + sender.system("JOINME_PLAYER_OFFLINE"); + return; + } teleport(player, server); } @@ -110,7 +115,7 @@ public class TpCommand extends BasicCommand { } } - private static ServerInfo getTarget(ProxiedPlayer player, String arg) { + private static ServerInfo getTarget(String arg) { ServerInfo server = null; //Get target player server @@ -128,9 +133,6 @@ public class TpCommand extends BasicCommand { } } - if(server == player.getServer().getInfo()) - server = null; - return server; } } diff --git a/src/de/steamwar/bungeecore/commands/TutorialCommand.java b/src/de/steamwar/bungeecore/commands/TutorialCommand.java index 4f55742..e5e3134 100644 --- a/src/de/steamwar/bungeecore/commands/TutorialCommand.java +++ b/src/de/steamwar/bungeecore/commands/TutorialCommand.java @@ -26,7 +26,9 @@ 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 net.md_5.bungee.api.CommandSender; +import de.steamwar.command.GuardChecker; +import de.steamwar.command.GuardResult; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -38,66 +40,61 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.stream.Collectors; -public class TutorialCommand extends BasicCommand { +public class TutorialCommand extends SWCommand { public TutorialCommand() { super("tutorial", null); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - ProxiedPlayer player = (ProxiedPlayer) sender; + @Register + public void genericCommand(ProxiedPlayer player) { + openInventory(player, true, false); + } - if(args.length == 0) { - openInventory(player, true, false); + @Register("rate") + public void rate(ProxiedPlayer player) { + player.chat("/tutorial rate"); + } + + @Register("rate") + public void rate(ProxiedPlayer player, int id) { + Tutorial tutorial = Tutorial.get(id); + if(tutorial == null) { + BungeeCore.get().getLogger().log(Level.SEVERE, "rate executed with nonexistent id: " + id); return; } - switch(args[0].toLowerCase()) { - case "rate": - if(args.length < 2) { - player.chat("/tutorial rate"); - return; - } + rate(player, tutorial); + } - int id; - try { - id = Integer.parseInt(args[1]); - } catch (NumberFormatException e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "rate executed with non number: " + args[1]); - return; - } + @Register(value = "create", description = "TUTORIAL_CREATE_HELP") + public void create(ProxiedPlayer player, String material, String... name) { + create(player, String.join(" ", name), material.toUpperCase()); + } - Tutorial tutorial = Tutorial.get(id); - if(tutorial == null) { - BungeeCore.get().getLogger().log(Level.SEVERE, "rate executed with nonexistent id: " + id); - return; - } + @Register("own") + public void own(ProxiedPlayer player) { + openInventory(player, false, true); + } - rate(player, tutorial); - break; - case "create": - if(args.length < 3) { - Message.send("TUTORIAL_CREATE_HELP", player); - return; - } + @Register("unreleased") + public void unreleased(@Guard("unreleased") ProxiedPlayer player) { + openInventory(player, false, false); + } - create(player, Arrays.stream(args).skip(2).collect(Collectors.joining(" ")), args[1].toUpperCase()); - break; - case "own": - openInventory(player, false, true); - break; - case "unreleased": - if (SteamwarUser.get(player.getUniqueId()).getUserGroup().isTeamGroup()) { - openInventory(player, false, false); - break; + @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; } - default: - Message.send("TUTORIAL_CREATE_HELP", player); - Message.send("TUTORIAL_OWN_HELP", player); - } + } else { + return GuardResult.ALLOWED; + } + }; } private void openInventory(ProxiedPlayer player, boolean released, boolean own) { diff --git a/src/de/steamwar/bungeecore/commands/UnIgnoreCommand.java b/src/de/steamwar/bungeecore/commands/UnIgnoreCommand.java index d7350ff..d0755bd 100644 --- a/src/de/steamwar/bungeecore/commands/UnIgnoreCommand.java +++ b/src/de/steamwar/bungeecore/commands/UnIgnoreCommand.java @@ -22,28 +22,20 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.IgnoreSystem; import de.steamwar.bungeecore.sql.SteamwarUser; -import net.md_5.bungee.api.CommandSender; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.connection.ProxiedPlayer; -public class UnIgnoreCommand extends BasicCommand { +public class UnIgnoreCommand extends SWCommand { public UnIgnoreCommand() { - super("unignore", null); + super("unignore"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(args.length < 1) { - Message.send("UNIGNORE_USAGE", sender); - return; - } - - if (!(sender instanceof ProxiedPlayer)) - return; - ProxiedPlayer p = (ProxiedPlayer) sender; + @Register(description = "UNIGNORE_USAGE") + public void genericCommand(ProxiedPlayer p, String toUnIgnore) { SteamwarUser user = SteamwarUser.get(p.getUniqueId()); - SteamwarUser target = SteamwarUser.get(args[0]); + SteamwarUser target = SteamwarUser.get(toUnIgnore); if(target == null){ Message.send("UNIGNORE_NOT_PLAYER", p); return; @@ -55,5 +47,4 @@ public class UnIgnoreCommand extends BasicCommand { IgnoreSystem.unIgnore(user, target); Message.send("UNIGNORE_UNIGNORED", p, target.getUserName()); } - } diff --git a/src/de/steamwar/bungeecore/commands/VerifyCommand.java b/src/de/steamwar/bungeecore/commands/VerifyCommand.java index cbc5430..08aee06 100644 --- a/src/de/steamwar/bungeecore/commands/VerifyCommand.java +++ b/src/de/steamwar/bungeecore/commands/VerifyCommand.java @@ -23,27 +23,23 @@ import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.bot.AuthManager; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.command.SWCommand; import net.dv8tion.jda.api.entities.Member; -import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.Base64; -public class VerifyCommand extends BasicCommand { +public class VerifyCommand extends SWCommand { public VerifyCommand() { - super("verify", ""); + super("verify"); } - @Override - public void execute(CommandSender sender, String[] strings) { - if(strings.length < 1) { - Message.send("VERIFY_USAGE", sender); - return; - } - + @Register(description = "VERIFY_USAGE") + public void genericCommand(ProxiedPlayer sender, String code) { byte[] bytes; try { - bytes = Base64.getDecoder().decode(strings[0]); + bytes = Base64.getDecoder().decode(code); } catch (IllegalArgumentException e) { Message.send("VERIFY_INVALID", sender); return; @@ -54,7 +50,7 @@ public class VerifyCommand extends BasicCommand { return; } if(bytes[0] == 'D' && bytes[1] == 'C') { - Member member = AuthManager.connectAuth(SteamwarUser.get(sender.getName()), strings[0]); + Member member = AuthManager.connectAuth(SteamwarUser.get(sender.getName()), code); if(member != null) { BungeeCore.log(sender.getName() + " Verified with Discorduser: " + member.getIdLong()); Message.send("VERIFY_SUCCESS", sender, member.getUser().getAsTag()); diff --git a/src/de/steamwar/bungeecore/commands/WebregisterCommand.java b/src/de/steamwar/bungeecore/commands/WebregisterCommand.java index b26883c..6197f0f 100644 --- a/src/de/steamwar/bungeecore/commands/WebregisterCommand.java +++ b/src/de/steamwar/bungeecore/commands/WebregisterCommand.java @@ -21,31 +21,22 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.SWException; -import net.md_5.bungee.api.CommandSender; +import de.steamwar.command.SWCommand; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -public class WebregisterCommand extends BasicCommand { +public class WebregisterCommand extends SWCommand { public WebregisterCommand() { super("webregister", null, "web", "webpw"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - - ProxiedPlayer player = (ProxiedPlayer) sender; - if(args.length != 1){ - Message.send("WEB_USAGE", player); - return; - } - - ProcessBuilder pb = new ProcessBuilder("php", "/var/www/register.php", player.getName(), args[0]); + @Register(description = "WEB_USAGE") + public void genericCommand(ProxiedPlayer player, String email) { + ProcessBuilder pb = new ProcessBuilder("php", "/var/www/register.php", player.getName(), email); pb.redirectErrorStream(true); try { Process regProcess = pb.start(); diff --git a/src/de/steamwar/bungeecore/commands/WhoisCommand.java b/src/de/steamwar/bungeecore/commands/WhoisCommand.java index 1303059..83caa0f 100644 --- a/src/de/steamwar/bungeecore/commands/WhoisCommand.java +++ b/src/de/steamwar/bungeecore/commands/WhoisCommand.java @@ -23,6 +23,10 @@ import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.Punishment; import de.steamwar.bungeecore.sql.SteamwarUser; import de.steamwar.bungeecore.sql.Team; +import de.steamwar.command.SWCommand; +import de.steamwar.command.SWCommandUtils; +import de.steamwar.command.TypeMapper; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -32,52 +36,46 @@ import java.text.DecimalFormat; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; -public class WhoisCommand extends BasicCommand { - public WhoisCommand(){ +public class WhoisCommand extends SWCommand { + public WhoisCommand() { super("whois", "bungeecore.teamchat"); } - @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) - return; - ProxiedPlayer player = (ProxiedPlayer) sender; - - if(args.length == 0){ - Message.send("WHOIS_USAGE", player); - return; - } - - SteamwarUser user = SteamwarUser.get(args[0]); - if(user == null){ + @Register(description = "WHOIS_USAGE") + public void genericCommand(ProxiedPlayer player, @Mapper("player") String target, @OptionalValue("") @StaticValue({"-all", "-a", ""}) String displayAll) { + SteamwarUser user = SteamwarUser.get(target); + if (user == null) { try { - int id = Integer.parseInt(args[0]); + int id = Integer.parseInt(target); user = SteamwarUser.get(id); - }catch (NumberFormatException ignored) {} + } catch (NumberFormatException ignored) { + } } if (user == null) { try { - long id = Long.parseLong(args[0]); + long id = Long.parseLong(target); user = SteamwarUser.get(id); } catch (NumberFormatException ignored) { // Ignored } } - if(user == null) { + if (user == null) { Message.send("UNKNOWN_PLAYER", player); return; } - boolean all = false; - if(args.length > 1 && args[1].startsWith("-")) { - all = args[1].contains("a"); - } - + boolean all = displayAll.contains("-"); sendUserinfo(player, user, all); } + @Mapper(value = "player", local = true) + public TypeMapper playerTypeMapper() { + return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList())); + } + private static void sendUserinfo(ProxiedPlayer player, SteamwarUser user, boolean all) { Message.send("WHOIS_USERNAME", player, user.getUserName()); Message.send("WHOIS_UUID", player, Message.parse("WHOIS_UUID_HOVER", player), new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, user.getUuid().toString()), user.getUuid().toString()); @@ -86,7 +84,7 @@ public class WhoisCommand extends BasicCommand { Message.send("WHOIS_DISCORD_ID", player, user.getDiscordId()); } Timestamp firstJoin = user.getFirstjoin(); - if(firstJoin == null) + if (firstJoin == null) Message.send("WHOIS_JOINED_FIRST", player, "0000-00-00 00:00:00"); else Message.send("WHOIS_JOINED_FIRST", player, firstJoin.toString()); diff --git a/src/de/steamwar/bungeecore/listeners/ChatListener.java b/src/de/steamwar/bungeecore/listeners/ChatListener.java index a815f6a..df006f9 100644 --- a/src/de/steamwar/bungeecore/listeners/ChatListener.java +++ b/src/de/steamwar/bungeecore/listeners/ChatListener.java @@ -82,27 +82,26 @@ public class ChatListener extends BasicListener { } public static void sendChat(ChatSender sender, Stream receivers, String format, ChatSender msgReceiver, String message) { - String finalMessage = modifyFilter(sender, message); - if(finalMessage == null) - return; - SteamwarUser user = sender.user(); + final String coloredMessage = (user.getUserGroup() != UserGroup.Member || coloredTeams.contains(user.getTeam())) ? ChatColor.translateAlternateColorCodes('&', message) : message; + if(chatFilter(sender, coloredMessage)) + return; AtomicBoolean noReceiver = new AtomicBoolean(true); receivers.filter(ChatSender::chatShown).forEach(player -> { if(sender.user().getId() != player.user().getId()) noReceiver.set(false); - chatToReciever(player, msgReceiver, user, format, finalMessage); + chatToReciever(player, msgReceiver, user, format, coloredMessage); }); - chatToReciever(ChatSender.console(), msgReceiver, user, format, finalMessage); + chatToReciever(ChatSender.console(), msgReceiver, user, format, coloredMessage); if(format.equals("CHAT_GLOBAL")) { if (SteamwarDiscordBot.instance() != null) - chatToReciever(ChatSender.discordChannel(SteamwarDiscordBot.instance().getIngameChatListener()), msgReceiver, user, format, finalMessage); + chatToReciever(ChatSender.discordChannel(SteamwarDiscordBot.instance().getIngameChatListener()), msgReceiver, user, format, coloredMessage); } else if (format.equals("CHAT_SERVERTEAM")) { if (SteamwarDiscordBot.instance() != null) - chatToReciever(ChatSender.discordChannel(SteamwarDiscordBot.instance().getServerTeamChatListener()), msgReceiver, user, format, finalMessage); + chatToReciever(ChatSender.discordChannel(SteamwarDiscordBot.instance().getServerTeamChatListener()), msgReceiver, user, format, coloredMessage); } else if (noReceiver.get()) { sender.system("CHAT_NO_RECEIVER"); } @@ -119,40 +118,40 @@ public class ChatListener extends BasicListener { if(ChatListener.filteredCommand(player, message)) return; - if(!message.startsWith("/")) { - message = modifyFilter(sender, message); - if(message == null) - return; - } + + if(!message.startsWith("/") && chatFilter(sender, message)) + return; Chat19.chat(player, message); } - private static String modifyFilter(ChatSender sender, String message) { + private static boolean chatFilter(ChatSender sender, String message) { if(!sender.chatShown()) { sender.system("CHAT_RECEIVE"); - return null; + return true; + } + + if(message.replace("§[a-f0-9klmno]", "").trim().isEmpty()) { + sender.system("CHAT_EMPTY"); + return true; } SteamwarUser user = sender.user(); UserGroup group = user.getUserGroup(); if(!group.isTeamGroup() && (message.contains("http:") || message.contains("https:") || message.contains("www."))){ sender.system("CHAT_NO_LINKS"); - return null; + return true; } if (user.isPunishedWithMessage(sender, Punishment.PunishmentType.Mute)) - return null; - - if(group != UserGroup.Member || coloredTeams.contains(user.getTeam())) - message = ChatColor.translateAlternateColorCodes('&', message); + return true; if (message.contains("LIXFEL")) specialAlert(sender, "Lixfel", "CHAT_LIXFEL_", 3, 6, 11, 12, 15); if (message.contains("YOYONOW")) specialAlert(sender, "YoyoNow", "CHAT_YOYONOW_", 3, 6, 11, 12); - return message; + return false; } private static void chatToReciever(ChatSender receiver, ChatSender msgReceiver, SteamwarUser sender, String format, String message) { diff --git a/src/de/steamwar/bungeecore/listeners/TablistManager.java b/src/de/steamwar/bungeecore/listeners/TablistManager.java deleted file mode 100644 index e1c3325..0000000 --- a/src/de/steamwar/bungeecore/listeners/TablistManager.java +++ /dev/null @@ -1,335 +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.bungeecore.listeners; - -import codecrafter47.bungeetablistplus.api.bungee.BungeeTabListPlusAPI; -import codecrafter47.bungeetablistplus.api.bungee.Icon; -import codecrafter47.bungeetablistplus.tablist.DefaultCustomTablist; -import de.steamwar.bungeecore.BungeeCore; -import de.steamwar.bungeecore.Message; -import de.steamwar.bungeecore.Servertype; -import de.steamwar.bungeecore.Subserver; -import de.steamwar.bungeecore.sql.SteamwarUser; -import de.steamwar.bungeecore.sql.UserGroup; -import net.md_5.bungee.BungeeCord; -import de.steamwar.network.packets.common.FightInfoPacket; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.config.ServerInfo; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.PlayerDisconnectEvent; -import net.md_5.bungee.api.event.PostLoginEvent; -import net.md_5.bungee.event.EventHandler; - -import javax.imageio.ImageIO; -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.TimeUnit; - -public class TablistManager extends BasicListener { - - private static final Map tablists = new HashMap<>(); - - @EventHandler - public synchronized void onJoin(PostLoginEvent e){ - BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> { - if (e.getPlayer().isConnected()) { - tablists.put(e.getPlayer(), new Tablist(e.getPlayer())); - } - }, 1, TimeUnit.SECONDS); - } - - @EventHandler - public synchronized void onLeave(PlayerDisconnectEvent e){ - tablists.remove(e.getPlayer()); - } - - - private static final Map fightInfos = new HashMap<>(); - - public static synchronized void newFightInfo(ServerInfo info, FightInfoPacket packet) { - fightInfos.put(info, packet); - fightInfos.keySet().removeIf(serverInfo -> serverInfo.getPlayers().isEmpty()); - } - - - private static Icon darkGray; - private static Icon gray; - - private int seconds = 0; - private int size; - private TablistGroup tablist; - - public TablistManager(){ - ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateTablist, 1, 1, TimeUnit.SECONDS); - try{ - BungeeTabListPlusAPI.createIcon(ImageIO.read(new File("/configs/BungeeTabListPlus/heads/colors/dark_gray.png")), (icon) -> darkGray = icon); - BungeeTabListPlusAPI.createIcon(ImageIO.read(new File("/configs/BungeeTabListPlus/heads/colors/gray.png")), (icon) -> gray = icon); - }catch(IOException e){ - throw new SecurityException("Could not load icons", e); - } - - ProxyServer.getInstance().getPlayers().forEach(p -> tablists.put(p, new Tablist(p))); - } - - private synchronized void updateTablist(){ - //Calculate server-player-map - tablist = new TablistGroup(true, ""); - TablistGroup bau = new TablistGroup(false, "Bau"); - for (ServerInfo server : new ArrayList<>(ProxyServer.getInstance().getServers().values())){ - if(server.getPlayers().isEmpty()) - continue; - - Subserver subserver = Subserver.getSubserver(server); - if(subserver != null && subserver.getType() == Servertype.BAUSERVER) - bau.addSubTablist(new TablistServer(server)); - else if(fightInfos.containsKey(server)) - tablist.addSubTablist(new TablistServer(server, fightInfos.get(server))); - else - tablist.addSubTablist(new TablistServer(server)); - } - if(bau.size() > 0) - tablist.addSubTablist(bau); - - size = (int) Math.ceil((tablist.size() - 1) / 20.0); - tablists.values().forEach(Tablist::refresh); - seconds++; - } - - private class Tablist extends DefaultCustomTablist { - private final ProxiedPlayer player; - private int pos = 0; - - private Tablist(ProxiedPlayer player){ - this.player = player; - BungeeTabListPlusAPI.setCustomTabList(player, this); - } - - private String header(){ - int phase = (seconds % 16) / 3; - switch(phase){ - case 0: - return Message.parse("TABLIST_PHASE_1", player); - case 1: - return Message.parse("TABLIST_PHASE_2", player); - case 2: - default: - return Message.parse("TABLIST_PHASE_DEFAULT", player); - } - } - - private String ping(){ - int ping = player.getPing(); - if(ping < 50){ - return "§a" + ping; - }else if(ping < 150){ - return "§e" + ping; - }else{ - return "§c" + ping; - } - } - - private void refresh(){ - if (player.getServer() == null) { - return; - } - pos = 0; - setHeader(header()); - setFooter(Message.parse("TABLIST_FOOTER", player, player.getServer().getInfo().getName(), ping(), ProxyServer.getInstance().getPlayers().size())); - int currentSize = size > 4 ? tablist.slimSize(player) : size; - setSize(currentSize, 20); - - tablist.print(this, size > 4); - - while (pos < currentSize*20){ - setSlot(darkGray, "", 1000); - } - } - - private void setSlot(Icon icon, String name, int ping){ - if(pos / 20 >= getColumns()) - return; - - setSlot(pos % 20, pos / 20, icon, name, ping); - pos++; - } - } - - private interface TablistPart { - int size(); - int slimSize(ProxiedPlayer viewer); - String name(); - void print(Tablist viewer, boolean slim); - } - - private static class TablistGroup implements TablistPart { - - private final boolean withHeaders; - private final String orderName; - private final List subTablists = new ArrayList<>(); - - private TablistGroup(boolean withHeaders, String orderName) { - this.withHeaders = withHeaders; - this.orderName = orderName; - } - - private void addSubTablist(TablistPart tablist){ - subTablists.add(tablist); - subTablists.sort((t1, t2) -> t1.name().compareToIgnoreCase(t2.name())); - } - - @Override - public int size() { - return slimSize(null); - } - - @Override - public int slimSize(ProxiedPlayer viewer) { - return subTablists.stream().mapToInt(tPart -> viewer == null ? tPart.size() : tPart.slimSize(viewer)).map(size -> { - size += withHeaders ? 1 : 0; // Space for header - size += withHeaders && size > 1 ? 1 : 0; // Space for footer - return size; - }).sum(); - } - - @Override - public String name() { - return orderName; - } - - @Override - public void print(Tablist viewer, boolean slim) { - for (int i = 0; i < subTablists.size(); i++) { - TablistPart tPart = subTablists.get(i); - String name = tPart.name(); - if (name.equals("Bau")) { - name = Message.parse("TABLIST_BAU", viewer.player); - } - boolean withoutFooter = i == subTablists.size() - 1; - if (withHeaders) { - if (slim) { - int slimSize = tPart.slimSize(viewer.player); - int size = tPart.size(); - if (size == slimSize) { - viewer.setSlot(gray, "§7§l" + name, 1000); - } else if (slimSize == 0) { - viewer.setSlot(gray, "§7§l" + name + " §8(§7" + size + "§8)", 1000); - withoutFooter = true; - } else { - viewer.setSlot(gray, "§7§l" + name + " §8(§7+" + (size - slimSize) + "§8)", 1000); - } - } else { - viewer.setSlot(gray, "§7§l" + name, 1000); - } - } - tPart.print(viewer, slim); - if (withHeaders && !withoutFooter) { - viewer.setSlot(darkGray, "", 1000); - } - } - } - } - - private static class TablistServer implements TablistPart { - private static class TablistPlayer { - private final ProxiedPlayer player; - private final String defaultName; - - private TablistPlayer(ProxiedPlayer player, String defaultName) { - this.player = player; - this.defaultName = defaultName; - } - } - private final List players = new ArrayList<>(); - private final ServerInfo info; - private final Subserver subserver; - - private TablistServer(ServerInfo info, FightInfoPacket packet){ - this.info = info; - subserver = Subserver.getSubserver(info); - Collection onlinePlayers = info.getPlayers(); - addPlayers(packet.getBlueName().substring(0, 2), packet.getBluePlayers(), onlinePlayers); - addPlayers(packet.getRedName().substring(0, 2), packet.getRedPlayers(), onlinePlayers); - addPlayers("§7", packet.getSpectators(), onlinePlayers); - } - - private void addPlayers(String prefix, List teamPlayers, Collection onlinePlayers){ - teamPlayers.stream().map(SteamwarUser::get).map( - user -> onlinePlayers.stream().filter(player -> player.getUniqueId().equals(user.getUuid())).findAny() - ).filter(Optional::isPresent).map(Optional::get).sorted( - (p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName()) - ).forEachOrdered(player -> players.add(new TablistPlayer(player, prefix + player.getName()))); - } - - private TablistServer(ServerInfo info) { - this.info = info; - subserver = Subserver.getSubserver(info); - info.getPlayers().forEach(player -> players.add(new TablistPlayer(player, SteamwarUser.get(player.getUniqueId()).getUserGroup().getColorCode() + player.getName()))); - players.sort((tp1, tp2) -> tp1.player.getName().compareToIgnoreCase(tp2.player.getName())); - } - - private boolean displaySlim(ProxiedPlayer viewer, ProxiedPlayer player){ - if(viewer.getServer().getInfo() == info) - return true; - - if(subserver != null && subserver.getType() == Servertype.ARENA && info.getPlayers().size() == 1) - return true; - - SteamwarUser user = SteamwarUser.get(player); - if(user.getUserGroup() != UserGroup.Member) - return true; - - return user.getTeam() != 0 && SteamwarUser.get(viewer).getTeam() == user.getTeam(); - } - - @Override - public int size() { - return players.size(); - } - - @Override - public int slimSize(ProxiedPlayer viewer) { - if(viewer.getServer().getInfo() == info) - return size(); - - return players.stream().mapToInt(player -> displaySlim(viewer, player.player) ? 1 : 0).sum(); - } - - @Override - public String name() { - return info.getName(); - } - - @Override - public void print(Tablist viewer, boolean slim) { - boolean sameServer = viewer.player.getServer().getInfo() == info; - - SteamwarUser user = SteamwarUser.get(viewer.player.getUniqueId()); - for(TablistPlayer player : players){ - if(slim && !displaySlim(viewer.player, player.player)) - continue; - - int ping = sameServer ? 1 : 1000; - String name = player.defaultName.startsWith("§7") && user.getTeam() != 0 && user.getTeam() == SteamwarUser.get(player.player.getUniqueId()).getTeam() ? "§f" + player.player.getName() : player.defaultName; - viewer.setSlot(BungeeTabListPlusAPI.getIconFromPlayer(player.player), name, ping); - } - } - } -} diff --git a/src/de/steamwar/bungeecore/network/NetworkReceiver.java b/src/de/steamwar/bungeecore/network/NetworkReceiver.java index b089141..d3de8c8 100644 --- a/src/de/steamwar/bungeecore/network/NetworkReceiver.java +++ b/src/de/steamwar/bungeecore/network/NetworkReceiver.java @@ -23,6 +23,7 @@ import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.commands.TeamCommand; import de.steamwar.bungeecore.listeners.BasicListener; import de.steamwar.network.packets.NetworkPacket; +import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.Server; import net.md_5.bungee.api.event.PluginMessageEvent; import net.md_5.bungee.event.EventHandler; @@ -51,6 +52,6 @@ public class NetworkReceiver extends BasicListener { if(!(event.getSender() instanceof Server)) return; - NetworkPacket.handle(new ServerMetaInfo(((Server) event.getSender()).getInfo()), event.getData()); + ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> NetworkPacket.handle(new ServerMetaInfo(((Server) event.getSender()).getInfo()), event.getData())); } } diff --git a/src/de/steamwar/bungeecore/network/handlers/FightInfoHandler.java b/src/de/steamwar/bungeecore/network/handlers/FightInfoHandler.java index 2c98de0..3f4bff2 100644 --- a/src/de/steamwar/bungeecore/network/handlers/FightInfoHandler.java +++ b/src/de/steamwar/bungeecore/network/handlers/FightInfoHandler.java @@ -19,10 +19,9 @@ package de.steamwar.bungeecore.network.handlers; -import de.steamwar.bungeecore.listeners.TablistManager; -import de.steamwar.bungeecore.network.NetworkReceiver; import de.steamwar.bungeecore.network.NetworkSender; import de.steamwar.bungeecore.network.ServerMetaInfo; +import de.steamwar.bungeecore.tablist.TablistManager; import de.steamwar.network.packets.PacketHandler; import de.steamwar.network.packets.common.FightInfoPacket; import net.md_5.bungee.api.config.ServerInfo; diff --git a/src/de/steamwar/bungeecore/sql/Event.java b/src/de/steamwar/bungeecore/sql/Event.java index 93fd211..ab4cede 100644 --- a/src/de/steamwar/bungeecore/sql/Event.java +++ b/src/de/steamwar/bungeecore/sql/Event.java @@ -41,6 +41,7 @@ public class Event { private final boolean publicSchemsOnly; private final boolean spectateSystem; private final Timestamp deadline; + private final String schemType; private static Event current = null; @@ -53,6 +54,7 @@ public class Event { this.publicSchemsOnly = rs.getBoolean("PublicSchemsOnly"); this.spectateSystem = rs.getBoolean("SpectateSystem"); this.deadline = rs.getTimestamp("Deadline"); + this.schemType = rs.getString("SchemType"); } public static Event get(){ @@ -123,4 +125,7 @@ public class Event { public Timestamp getDeadline() { return deadline; } + public String getSchemType() { + return schemType; + } } diff --git a/src/de/steamwar/bungeecore/sql/SchematicType.java b/src/de/steamwar/bungeecore/sql/SchematicType.java index 978ab94..9592070 100644 --- a/src/de/steamwar/bungeecore/sql/SchematicType.java +++ b/src/de/steamwar/bungeecore/sql/SchematicType.java @@ -27,10 +27,12 @@ import net.md_5.bungee.config.YamlConfiguration; import java.io.File; import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.*; public class SchematicType { - public static final SchematicType Normal = new SchematicType("Normal", "", null, Type.NORMAL, null); //Has to stay publicly availible + public static final SchematicType Normal = new SchematicType("Normal", "", null, Type.NORMAL, null, null); //Has to stay publicly availible private static final Map fromDB; private static final Map fightType; @@ -68,13 +70,26 @@ public class SchematicType { SchematicType checktype = null; if(!config.getStringList("CheckQuestions").isEmpty()) { - checktype = new SchematicType("C" + type, "C" + shortcut, material, Type.CHECK_TYPE, null); + checktype = new SchematicType("C" + type, "C" + shortcut, material, Type.CHECK_TYPE, null, null); tmpTypes.add(checktype); tmpFromDB.put(checktype.toDB(), checktype); CheckCommand.setCheckQuestions(checktype, config); } - SchematicType current = new SchematicType(type, shortcut, material, config.getKeys().contains("Server") ? Type.FIGHT_TYPE : Type.NORMAL, checktype); + Date deadline; + String deadlineString = config.getString("deadline", null); + if (deadlineString != null) { + try { + SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm"); + deadline = dateFormat.parse(deadlineString); + } catch (ParseException e) { + throw new SecurityException(e.getMessage(), e); + } + } else { + deadline = null; + } + + SchematicType current = new SchematicType(type, shortcut, material, config.getKeys().contains("Server") ? Type.FIGHT_TYPE : Type.NORMAL, checktype, deadline); if(checktype != null) tmpFightType.put(checktype, current); tmpFromDB.put(type.toLowerCase(), current); @@ -91,13 +106,15 @@ public class SchematicType { private final String material; private final Type type; private final SchematicType checkType; + private final Date deadline; - private SchematicType(String name, String kuerzel, String material, Type type, SchematicType checkType){ + private SchematicType(String name, String kuerzel, String material, Type type, SchematicType checkType, Date deadline){ this.name = name; this.kuerzel = kuerzel; this.material = material != null && !"".equals(material) ? material : "STONE_BUTTON"; this.type = type; this.checkType = checkType; + this.deadline = deadline; } public boolean isAssignable(){ @@ -140,6 +157,10 @@ public class SchematicType { return name.toLowerCase(); } + public Date deadline() { + return deadline; + } + public static SchematicType fromDB(String input){ return fromDB.getOrDefault(input.toLowerCase(), null); } diff --git a/src/de/steamwar/bungeecore/tablist/Tablist.java b/src/de/steamwar/bungeecore/tablist/Tablist.java new file mode 100644 index 0000000..417629d --- /dev/null +++ b/src/de/steamwar/bungeecore/tablist/Tablist.java @@ -0,0 +1,273 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.tablist; + +import de.steamwar.bungeecore.Storage; +import de.steamwar.messages.ChatSender; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPipeline; +import io.netty.handler.codec.MessageToMessageDecoder; +import net.md_5.bungee.ServerConnection; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.chat.ComponentSerializer; +import net.md_5.bungee.netty.PipelineUtils; +import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.PacketWrapper; +import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; +import net.md_5.bungee.protocol.packet.PlayerListItem; +import net.md_5.bungee.protocol.packet.Team; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@ChannelHandler.Sharable +public class Tablist extends MessageToMessageDecoder { + + private static final UUID[] uuids = IntStream.range(0, 80).mapToObj(i -> UUID.randomUUID()).toArray(UUID[]::new); + private static final String[] names = IntStream.range(0, 80).mapToObj(i -> " »SW« " + String.format("%02d", i)).toArray(String[]::new); + private static final String TAB_TEAM = "»SW-Tab"; + private static final Team teamPacket = new Team(TAB_TEAM, (byte) 0, ComponentSerializer.toString(TextComponent.fromLegacyText("")), ComponentSerializer.toString(TextComponent.fromLegacyText("")), ComponentSerializer.toString(TextComponent.fromLegacyText("")), "always", "always", 21, (byte)0x00, names); + + private final Map directTabItems; + private final Set npcs = new HashSet<>(); + private final List current = new ArrayList<>(); + + private final ProxiedPlayer player; + private final ChatSender viewer; + private ServerConnection connection; + + public Tablist(ProxiedPlayer player) { + this.player = player; + this.viewer = ChatSender.of(player); + this.directTabItems = Storage.directTabItems.computeIfAbsent(player, p -> new HashMap<>()); + onServerSwitch(); + } + + public void update(TablistPart global, int seconds) { + if (connection == null) + return; + + player.unsafe().sendPacket(new PlayerListHeaderFooter( + ComponentSerializer.toString(header(viewer, seconds)), + ComponentSerializer.toString(viewer.parse(false, "TABLIST_FOOTER", connection.getInfo().getName(), ping(), ProxyServer.getInstance().getPlayers().size())) + )); + + List tablist = new ArrayList<>(); + List direct = new ArrayList<>(); + global.print(viewer, player, tablist, direct); + + // NPC handling + List addNpc = new ArrayList<>(); + List removeNpc = new ArrayList<>(); + List update = new ArrayList<>(); + Set nonNPCs = direct.stream().map(TablistPart.Item::getUuid).collect(Collectors.toSet()); + synchronized (directTabItems) { + for (TablistPart.Item item : direct) { + PlayerListItem.Item tabItem = directTabItems.get(item.getUuid()); + + if(npcs.remove(item.getUuid())) + removeNpc.add(tabItem.getUsername()); + + if(tabItem == null) { + tablist.add(0, item); + } else if(!tabItem.getDisplayName().equals(item.getDisplayName())) { + tabItem.setDisplayName(item.getDisplayName()); + update.add(tabItem); + } + } + for(PlayerListItem.Item item : directTabItems.values()) { + if(!nonNPCs.contains(item.getUuid()) && !npcs.contains(item.getUuid())) { + npcs.add(item.getUuid()); + addNpc.add(item.getUsername()); + } + } + } + sendNpcPacket(addNpc, false); + sendNpcPacket(removeNpc, true); + + // Main list handling + int i = 0; + List add = new ArrayList<>(); + for (; i < tablist.size() && i < 80; i++) { + PlayerListItem.Item tabItem; + if(current.size() > i) { + tabItem = current.get(i); + } else { + tabItem = new PlayerListItem.Item(); + tabItem.setUuid(uuids[i]); + tabItem.setUsername(names[i]); + tabItem.setGamemode(1); + tabItem.setPing(1000); + current.add(tabItem); + } + + TablistPart.Item item = tablist.get(i); + if(!Arrays.equals(tabItem.getProperties(), item.getProperties())) { + tabItem.setProperties(item.getProperties()); + tabItem.setDisplayName(item.getDisplayName()); + add.add(tabItem); + } else if(!item.getDisplayName().equals(tabItem.getDisplayName())) { + tabItem.setDisplayName(item.getDisplayName()); + update.add(tabItem); + } + } + sendTabPacket(update, PlayerListItem.Action.UPDATE_DISPLAY_NAME); + sendTabPacket(add, PlayerListItem.Action.ADD_PLAYER); + + // Excess removal + List remove = new ArrayList<>(); + while(i < current.size()) { + remove.add(current.remove(i)); + } + sendTabPacket(remove, PlayerListItem.Action.REMOVE_PLAYER); + } + + public void onServerSwitch() { + connection = (ServerConnection) player.getServer(); + synchronized (directTabItems) { + sendNpcPacket(npcs.stream().map(npc -> directTabItems.get(npc).getUsername()).collect(Collectors.toList()), true); + directTabItems.clear(); + npcs.clear(); + } + + if(connection != null) { + ChannelPipeline pipeline = connection.getCh().getHandle().pipeline(); + if(pipeline.get("steamwar-tablist") != null) //Catch unclean exit + pipeline.remove("steamwar-tablist"); + + pipeline.addBefore(PipelineUtils.BOSS_HANDLER, "steamwar-tablist", this); + player.unsafe().sendPacket(teamPacket); + } + } + + public void disable() { + sendTabPacket(current, PlayerListItem.Action.REMOVE_PLAYER); + current.clear(); + synchronized (directTabItems) { + sendNpcPacket(npcs.stream().map(npc -> directTabItems.get(npc).getUsername()).collect(Collectors.toList()), true); + npcs.clear(); + } + + if(connection != null) + connection.getCh().getHandle().pipeline().remove(this); + } + + @Override + protected void decode(ChannelHandlerContext ctx, PacketWrapper packetWrapper, List out) { + if(!connection.isObsolete()) { + DefinedPacket packet = packetWrapper.packet; + + if(packet instanceof PlayerListHeaderFooter) { + packetWrapper.trySingleRelease(); + return; + } + + if(packet instanceof PlayerListItem) { + PlayerListItem list = (PlayerListItem) packet; + PlayerListItem.Action action = list.getAction(); + + switch(action) { + case UPDATE_LATENCY: + case UPDATE_DISPLAY_NAME: + packetWrapper.trySingleRelease(); + return; + case UPDATE_GAMEMODE: + for (PlayerListItem.Item item : list.getItems()) { + ProxiedPlayer p = ProxyServer.getInstance().getPlayer(item.getUuid()); + if(p != null && p != player && item.getGamemode() == 3) { + item.setGamemode(1); + } + } + break; + case ADD_PLAYER: + for (PlayerListItem.Item item : list.getItems()) { + item.setPing(1); + item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText(""))); + if(!player.getUniqueId().equals(item.getUuid()) && item.getGamemode() == 3) + item.setGamemode(1); + + synchronized (directTabItems) { + directTabItems.put(item.getUuid(), item); + } + } + break; + case REMOVE_PLAYER: + List names = new ArrayList<>(); + for(PlayerListItem.Item item : list.getItems()) { + synchronized (directTabItems) { + PlayerListItem.Item directItem = directTabItems.remove(item.getUuid()); + if(npcs.remove(item.getUuid())) + names.add(directItem.getUsername()); + } + } + sendNpcPacket(names, true); + break; + } + } + } + out.add(packetWrapper); + } + + private void sendTabPacket(List items, PlayerListItem.Action action) { + if(!items.isEmpty()) { + PlayerListItem packet = new PlayerListItem(); + packet.setAction(action); + packet.setItems(items.toArray(new PlayerListItem.Item[0])); + player.unsafe().sendPacket(packet); + } + } + + private void sendNpcPacket(List names, boolean remove) { + if(!names.isEmpty()) { + Team packet = new Team(TAB_TEAM); + packet.setMode((byte) (remove ? 4 : 3)); + packet.setPlayers(names.toArray(new String[0])); + player.unsafe().sendPacket(packet); + } + } + + private BaseComponent[] header(ChatSender p, int seconds) { + int phase = (seconds % 16) / 3; + switch (phase) { + case 0: + return p.parse(false, "TABLIST_PHASE_1"); + case 1: + return p.parse(false, "TABLIST_PHASE_2"); + default: + return p.parse(false, "TABLIST_PHASE_DEFAULT"); + } + } + + private String ping() { + int ping = player.getPing(); + if (ping < 50) { + return "§a" + ping; + } else if (ping < 150) { + return "§e" + ping; + } else { + return "§c" + ping; + } + } +} diff --git a/src/de/steamwar/bungeecore/tablist/TablistBuild.java b/src/de/steamwar/bungeecore/tablist/TablistBuild.java new file mode 100644 index 0000000..dcb8f67 --- /dev/null +++ b/src/de/steamwar/bungeecore/tablist/TablistBuild.java @@ -0,0 +1,69 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.tablist; + +import de.steamwar.bungeecore.Servertype; +import de.steamwar.bungeecore.Subserver; +import de.steamwar.messages.ChatSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class TablistBuild implements TablistPart { + + private final List servers = new ArrayList<>(); + private final Map> players = new HashMap<>(); + + public TablistBuild() { + for (ServerInfo server : ProxyServer.getInstance().getServersCopy().values()){ + Subserver subserver = Subserver.getSubserver(server); + if(server.getPlayers().isEmpty() || subserver == null || subserver.getType() != Servertype.BAUSERVER) + continue; + + servers.add(server); + players.put(server, server.getPlayers().stream().sorted(((p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName()))).map(Item::new).collect(Collectors.toList())); + } + servers.sort((s1, s2) -> s1.getName().compareToIgnoreCase(s2.getName())); + } + + @Override + public String sortKey() { + return "Build"; + } + + @Override + public void print(ChatSender viewer, ProxiedPlayer player, List tablist, List direct) { + ServerInfo server = player.getServer().getInfo(); + if(players.keySet().stream().anyMatch(info -> server != info)) { + tablist.add(new Item(null, "", TablistServer.GRAY)); + tablist.add(new Item(null, viewer.parseToLegacy("TABLIST_BAU"), TablistServer.LIGHT_GRAY)); + } + + for(ServerInfo info : servers) { + (server == info ? direct : tablist).addAll(players.get(info)); + } + } +} diff --git a/src/de/steamwar/bungeecore/tablist/TablistGroup.java b/src/de/steamwar/bungeecore/tablist/TablistGroup.java new file mode 100644 index 0000000..fdb227a --- /dev/null +++ b/src/de/steamwar/bungeecore/tablist/TablistGroup.java @@ -0,0 +1,45 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.tablist; + +import de.steamwar.messages.ChatSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.List; + +public class TablistGroup implements TablistPart { + private final List sublists; + + public TablistGroup(List sublists) { + this.sublists = sublists; + } + + @Override + public String sortKey() { + return ""; + } + + @Override + public void print(ChatSender viewer, ProxiedPlayer player, List tablist, List direct) { + for (TablistPart sublist : sublists) { + sublist.print(viewer, player, tablist, direct); + } + } +} diff --git a/src/de/steamwar/bungeecore/tablist/TablistManager.java b/src/de/steamwar/bungeecore/tablist/TablistManager.java new file mode 100644 index 0000000..0f02f55 --- /dev/null +++ b/src/de/steamwar/bungeecore/tablist/TablistManager.java @@ -0,0 +1,107 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.tablist; + +import de.steamwar.bungeecore.BungeeCore; +import de.steamwar.bungeecore.Servertype; +import de.steamwar.bungeecore.Storage; +import de.steamwar.bungeecore.Subserver; +import de.steamwar.bungeecore.listeners.BasicListener; +import de.steamwar.network.packets.common.FightInfoPacket; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.event.ServerSwitchEvent; +import net.md_5.bungee.event.EventHandler; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class TablistManager extends BasicListener { + + private static final Map fightInfos = new HashMap<>(); + + public static synchronized void newFightInfo(ServerInfo info, FightInfoPacket packet) { + fightInfos.put(info, packet); + fightInfos.keySet().removeIf(serverInfo -> serverInfo.getPlayers().isEmpty()); + } + + private final Map tablists = new HashMap<>(); + + private int seconds = 0; + + 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))); + } + + @EventHandler + public void onJoin(PostLoginEvent event) { + synchronized (tablists) { + tablists.put(event.getPlayer(), new Tablist(event.getPlayer())); + } + } + + @EventHandler + public void onServerConnection(ServerSwitchEvent event) { + synchronized (tablists) { + tablists.get(event.getPlayer()).onServerSwitch(); + } + } + + @EventHandler + public void onLeave(PlayerDisconnectEvent event) { + synchronized (tablists) { + tablists.remove(event.getPlayer()); + Storage.directTabItems.remove(event.getPlayer()); + } + } + + public void disable() { + synchronized (tablists) { + tablists.forEach((player, tablist) -> tablist.disable()); + tablists.clear(); + } + } + + private void updateTablist() { + List subservers = new ArrayList<>(); + for (ServerInfo server : ProxyServer.getInstance().getServersCopy().values()){ + if(server.getPlayers().isEmpty()) + continue; + + Subserver subserver = Subserver.getSubserver(server); + if(fightInfos.containsKey(server)) + subservers.add(new TablistServer(server, fightInfos.get(server))); + else if(subserver == null || subserver.getType() != Servertype.BAUSERVER) + subservers.add(new TablistServer(server)); + } + subservers.add(new TablistBuild()); + subservers.sort((s1, s2) -> s1.sortKey().compareToIgnoreCase(s2.sortKey())); + TablistPart global = new TablistGroup(subservers); + + synchronized (tablists) { + tablists.forEach((player, tablist) -> tablist.update(global, seconds)); + } + seconds++; + } +} diff --git a/src/de/steamwar/bungeecore/tablist/TablistPart.java b/src/de/steamwar/bungeecore/tablist/TablistPart.java new file mode 100644 index 0000000..2388116 --- /dev/null +++ b/src/de/steamwar/bungeecore/tablist/TablistPart.java @@ -0,0 +1,75 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.tablist; + +import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.messages.ChatSender; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.chat.ComponentSerializer; +import net.md_5.bungee.connection.InitialHandler; +import net.md_5.bungee.protocol.Property; + +import java.util.List; +import java.util.UUID; + +interface TablistPart { + String sortKey(); + void print(ChatSender viewer, ProxiedPlayer player, List tablist, List direct); + + class Item { + + public static Property[] playerProperties(ProxiedPlayer player) { + return ((InitialHandler) player.getPendingConnection()).getLoginProfile().getProperties(); + } + + private final UUID uuid; + private final String displayName; + private final Property[] properties; + + public Item(UUID uuid, String displayName, Property[] properties) { + this.uuid = uuid; + this.displayName = reformat(displayName); + this.properties = properties; + } + + public Item(ProxiedPlayer player) { + this.uuid = player.getUniqueId(); + this.displayName = reformat(SteamwarUser.get(player.getUniqueId()).getUserGroup().getColorCode() + player.getName()); + this.properties = playerProperties(player); + } + + public UUID getUuid() { + return uuid; + } + + public String getDisplayName() { + return displayName; + } + + public Property[] getProperties() { + return properties; + } + + private String reformat(String string) { + return ComponentSerializer.toString(TextComponent.fromLegacyText(string)); + } + } +} diff --git a/src/de/steamwar/bungeecore/tablist/TablistServer.java b/src/de/steamwar/bungeecore/tablist/TablistServer.java new file mode 100644 index 0000000..0a95a48 --- /dev/null +++ b/src/de/steamwar/bungeecore/tablist/TablistServer.java @@ -0,0 +1,86 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 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.tablist; + +import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.messages.ChatSender; +import de.steamwar.network.packets.common.FightInfoPacket; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.protocol.Property; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class TablistServer implements TablistPart { + + public static final Property[] GRAY = new Property[]{new Property("textures", "eyJ0aW1lc3RhbXAiOjE0NTU1NzQxMTk0MzMsInByb2ZpbGVJZCI6ImIzYjE4MzQ1MzViZjRiNzU4ZTBjZGJmMGY4MjA2NTZlIiwicHJvZmlsZU5hbWUiOiIxMDExMTEiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzZlNzJkMzE0NzczMmQ5NzFkZWZhZTIzMWIzOGQ5NDI0MTRiMDU3YTcxNTFjNTNjNWZkNjI5NmEzYjllZGEwYWIifX19", "ro/ZKHt7278yhCr+CFTcPp/q6wAUlef//85k2DzkfRaZqy0CtGgwisDs2U4pVKvQ2pfXvitzWgbJvD0bLeQ12xWi4c1Fc29LCArosVJoFmrJDHz7N2MlstHT+ynQROb9d2aiFA6uOXfLjPKb1noUZ/YQoZjqcPIvD5oFZtD5DHV5O4hYz0IvgHbIjDqjz6ITsTcKiBlbxNg2loTFxSlW1ZfnNCO+kcAmeyB5NFY3j0e+/AqVANiNoiC3OKsECM/yEx/acf+vKWcT8mQn4wRoIGtxfEU7ZjNtgdh73NvXXBygW+K9AiJ242g8Y06Xxuk8kaNEGmT6H/mM7nbwjZmQQXpi/Pao2gYqyeIofeCPfr8RsGXoDX3nXDAw8/LyhTCHgx+sp6IQYSfGcSMJtoNeTJ0liIFxqn1V9/zKmzOZAPzR6qrQPOjoRFljLAlv7rfzotaEqh/1ldd40GdS8tstczn7f29OQerNDaqvbDb00Gy0STdUr1bVyCDptA54XKjT9WFv7QpBikEculxqSppAXPxD2Fb/ZmphbZx8WEGfG6bVFhf6fQdDAUXlcv8BxjElNPwlolF86M2KJd5VquLluhrCjwID7OK/pffNultAVH+Lxw4QOAXmJqjUrA1KHgyG1S0Cwj/f4E2hdxZJBvkfVtq9qPkd9nignhEoTCTOHf0=")}; + public static final Property[] LIGHT_GRAY = new Property[]{new Property("textures", "eyJ0aW1lc3RhbXAiOjE0NTU2MjU1OTM5NjIsInByb2ZpbGVJZCI6ImIzYjE4MzQ1MzViZjRiNzU4ZTBjZGJmMGY4MjA2NTZlIiwicHJvZmlsZU5hbWUiOiIxMDExMTEiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzc4Y2I3ZmMyMDhiMzM4NTUwNGE4MTQ0MjA0NDI4ZmRjZDYzMjRiZWIzMWNhMmNlODZjYzQyNGI5NjNkODVjIn19fQ==", "R/wZUZRC1dishRdM9a2SSxxW3oYa0XSb/MxHbQpEUA791HxyqjaKLDu0wFX2r2a8ZTeVjzXpNzkg3+PkrA11o8h7lt86MTD1pi/rQqj/WRuoqf2LP+ypbssKV+LU15cYez2cj3QQVcJDXgWEnfSLNuBv6NG8BDUpUAjTWldvu99NCJHUoD0jNMHxY/fu4k5vCgOjaBaKgkjVk2bmUhegusmtMwco+3pYx+y8+gUW8ptx5SnePG+dOwTqLyBFiOt2AQ+gSvbU/jP9aAXgxOwz/b1pMaBWtzVhFU865NHlIdSpIHg/sh3uNah3a7gTgtTvxPQv1OzM/KtqYKiamsrRzAQMzRcs4A7Tp0GakLuxEaz401IwvQ7UGVYLFzGUVLB2MyqtPgifiqQSQxZpiqj9sM5QadhsUw00nfX7mTdW46U0MtNIbby1rLrvgQKoj08zt6LJlhI3yjyawy4iZkgF4oc+PCNwZc93GIbVL9LJaGkXk3RVA+JpGwfMJrGVbL7hl8ibbAcUv7uCEWdkAgZCd6w75jEE4tlhDSPDD4rXbn+FeTZRg2n/PGKtnoTZRzbniiFaNoSAHDZSVRG39xvBDFvtmL3SPaKhzKaifiYrgNn453WtR3kymqdAtPf1GN9d1VltGZ/+vMPwqPJb6thcrlcU64UGHbg1olRkiyZHvY8=")}; + + private final ServerInfo server; + private final List players; + + public TablistServer(ServerInfo server) { + this(server, server.getPlayers().stream().sorted((p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName())).map(TablistPart.Item::new).collect(Collectors.toList())); + } + + public TablistServer(ServerInfo server, FightInfoPacket info) { + this(server, new ArrayList<>()); + + Collection onlinePlayers = server.getPlayers(); + addPlayers(info.getBlueName().substring(0, 2), info.getBluePlayers(), onlinePlayers); + addPlayers(info.getRedName().substring(0, 2), info.getRedPlayers(), onlinePlayers); + addPlayers("§7", info.getSpectators(), onlinePlayers); + } + + public TablistServer(ServerInfo server, List players) { + this.server = server; + this.players = players; + } + + @Override + public String sortKey() { + return server.getName(); + } + + @Override + public void print(ChatSender viewer, ProxiedPlayer player, List tablist, List direct) { + boolean onServer = player.getServer().getInfo() == server; + List items = onServer ? direct : tablist; + + if(!onServer) { + items.add(new Item(null, "", GRAY)); + items.add(new Item(null, "§7§l" + server.getName(), LIGHT_GRAY)); + } + + items.addAll(players); + } + + private void addPlayers(String prefix, List teamPlayers, Collection onlinePlayers){ + teamPlayers.stream().map(SteamwarUser::get).map( + user -> onlinePlayers.stream().filter(player -> player.getUniqueId().equals(user.getUuid())).findAny() + ).filter(Optional::isPresent).map(Optional::get).sorted( + (p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName()) + ).forEachOrdered(player -> players.add(new Item(player.getUniqueId(), prefix + player.getName(), Item.playerProperties(player)))); + } +} diff --git a/src/de/steamwar/command/SWCommand.java b/src/de/steamwar/command/SWCommand.java index 242ef4d..f8c3647 100644 --- a/src/de/steamwar/command/SWCommand.java +++ b/src/de/steamwar/command/SWCommand.java @@ -20,7 +20,9 @@ package de.steamwar.command; import de.steamwar.bungeecore.BungeeCore; +import de.steamwar.bungeecore.Message; import de.steamwar.messages.ChatSender; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -29,6 +31,7 @@ import net.md_5.bungee.api.plugin.TabExecutor; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import java.util.logging.Level; @@ -49,17 +52,23 @@ public class SWCommand extends AbstractSWCommand { } protected SWCommand(String command, String permission) { - super(CommandSender.class, command); - this.permission = permission; + this(command, permission, new String[0]); } protected SWCommand(String command, String permission, String... aliases) { super(CommandSender.class, command, aliases); this.permission = permission; + create = true; + createAndSafeCommand(command, aliases); + unregister(); + register(); } + private boolean create = false; + @Override protected void createAndSafeCommand(String command, String[] aliases) { + if (!create) return; this.command = new TabCompletableCommand(command, permission, aliases) { @Override public void execute(CommandSender commandSender, String[] strings) { @@ -81,11 +90,13 @@ public class SWCommand extends AbstractSWCommand { @Override public void unregister() { + if (command == null) return; CommandRegistering.unregister(this.command); } @Override public void register() { + if (command == null) return; CommandRegistering.register(this.command); } @@ -104,6 +115,11 @@ public class SWCommand extends AbstractSWCommand { defaultHelpMessages.add(message); } + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + ChatSender.of(sender).system(message, args); + } + @Register(help = true) private void internalHelp(ProxiedPlayer p, String... args) { ChatSender chatSender = ChatSender.of(p); @@ -145,7 +161,7 @@ public class SWCommand extends AbstractSWCommand { for (String s : subCommand.description) { String hover = "§8/§e" + command.getName() + " " + String.join(" ", subCommand.subCommand); String suggest = "/" + command.getName() + " " + String.join(" ", subCommand.subCommand); - chatSender.prefixless(s, hover, new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, suggest)); + chatSender.prefixless(s, new Message("PLAIN_STRING", hover), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, suggest)); } } catch (Exception e) { BungeeCore.get().getLogger().log(Level.WARNING, "Failed to send description of registered method '" + subCommand.method + "' with description '" + subCommand.description + "'", e); diff --git a/src/de/steamwar/command/TypeValidator.java b/src/de/steamwar/command/TypeValidator.java new file mode 100644 index 0000000..6bb76f6 --- /dev/null +++ b/src/de/steamwar/command/TypeValidator.java @@ -0,0 +1,25 @@ +/* + * 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; + +public interface TypeValidator extends AbstractValidator { +} diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index 45a4f05..58633d2 100644 --- a/src/de/steamwar/messages/BungeeCore.properties +++ b/src/de/steamwar/messages/BungeeCore.properties @@ -238,6 +238,7 @@ EVENT_NO_CURRENT=§cThere is no event taking place currently EVENT_COMING=§eUpcoming events§8: EVENT_COMING_EVENT=§7{0}§8-§7{1}§8: §e{2} EVENT_COMING_DEADLINE=§7 Registration deadline§8: §7{0} +EVENT_COMING_SCHEM_DEADLINE=§7 Submission deadline§8: §7{0} EVENT_COMING_TEAMS=§7 With§8:{0} EVENT_COMING_TEAM= §{0}{1} EVENT_CURRENT_EVENT=§e§l{0} @@ -520,6 +521,7 @@ CHAT_RECEIVE=§cTo be able to send chat messages, you must also receive them! CHAT_NO_LINKS=§cYou may not send links. CHAT_BC_USAGE=§8/§7bc §8[§emessage§8] CHAT_NO_RECEIVER=§cNobody receives your message +CHAT_EMPTY=§cDon't write meaningless empty messages. CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2} CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2} @@ -552,7 +554,7 @@ TABLIST_PHASE_1=§8Teamspeak: §eSteam§8War.de TABLIST_PHASE_2=§8Discord: §8https://§eSteam§8War.de/discord TABLIST_PHASE_DEFAULT=§8Website: https://§eSteam§8War.de TABLIST_FOOTER=§e{0} {1}§8ms §ePlayers§8: §7{2} -TABLIST_BAU=Build +TABLIST_BAU=§7§lBuild LIST_COMMAND=§e{0}§8: §7{1} #EventStarter diff --git a/src/de/steamwar/messages/BungeeCore_de.properties b/src/de/steamwar/messages/BungeeCore_de.properties index 21a7a55..0c93d45 100644 --- a/src/de/steamwar/messages/BungeeCore_de.properties +++ b/src/de/steamwar/messages/BungeeCore_de.properties @@ -222,6 +222,7 @@ EVENT_NO_CURRENT=§cDerzeit findet kein Event statt EVENT_COMING=§eKommende Events§8: EVENT_COMING_EVENT=§7{0}§8-§7{1}§8: §e{2} EVENT_COMING_DEADLINE=§7 Anmeldeschluss§8: §7{0} +EVENT_COMING_SCHEM_DEADLINE=§7 Einsendeschluss§8: §7{0} EVENT_COMING_TEAMS=§7 Mit§8:{0} EVENT_COMING_TEAM= §{0}{1} EVENT_CURRENT_EVENT=§e§l{0} @@ -499,6 +500,7 @@ CHAT_RECEIVE=§cUm Chatnachrichten versenden zu können, musst du auch welche em CHAT_NO_LINKS=§cDu darfst keine Links versenden. CHAT_BC_USAGE=§8/§7bc §8[§eNachricht§8] CHAT_NO_RECEIVER=§cNiemand empfängt deine Nachricht +CHAT_EMPTY=§cSchreibe keine inhaltslosen Nachrichten. CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2} CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2} @@ -531,7 +533,7 @@ TABLIST_PHASE_1=§8Teamspeak: §eSteam§8War.de TABLIST_PHASE_2=§8Discord: §8https://§eSteam§8War.de/discord TABLIST_PHASE_DEFAULT=§8Website: https://§eSteam§8War.de TABLIST_FOOTER=§e{0} {1}§8ms §eSpieler§8: §7{2} -TABLIST_BAU=Bau +TABLIST_BAU=§7§lBau LIST_COMMAND=§e{0}§8: §7{1} #EventStarter diff --git a/src/de/steamwar/messages/ChatSender.java b/src/de/steamwar/messages/ChatSender.java index 582fd6f..6879505 100644 --- a/src/de/steamwar/messages/ChatSender.java +++ b/src/de/steamwar/messages/ChatSender.java @@ -115,6 +115,10 @@ public interface ChatSender { return parseToComponent(false, message).toLegacyText(); } + default BaseComponent[] parse(boolean prefixed, String format, Object... params) { + return parse(prefixed, new Message(format, params)); + } + default BaseComponent[] parse(boolean prefixed, Message message) { Locale locale = getLocale(); ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale); diff --git a/src/de/steamwar/messages/SteamwarResourceBundle.java b/src/de/steamwar/messages/SteamwarResourceBundle.java index c2e71ab..2252609 100644 --- a/src/de/steamwar/messages/SteamwarResourceBundle.java +++ b/src/de/steamwar/messages/SteamwarResourceBundle.java @@ -35,7 +35,7 @@ public class SteamwarResourceBundle extends PropertyResourceBundle { return getResourceBundle(locale.toString(), getResourceBundle(locale.getLanguage(), getResourceBundle( "", null))); } - private static ResourceBundle getResourceBundle(String locale, ResourceBundle parent) { + private static synchronized ResourceBundle getResourceBundle(String locale, ResourceBundle parent) { return bundles.computeIfAbsent(locale, locale1 -> { InputStream inputStream = Message.class.getResourceAsStream(BASE_PATH + ("".equals(locale) ? "" : "_" + locale) + ".properties"); if(inputStream == null) diff --git a/src/plugin.yml b/src/plugin.yml index 85fafe1..5bb14e0 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -2,4 +2,5 @@ name: BungeeCore main: de.steamwar.bungeecore.BungeeCore version: 1.0 author: Lixfel -depends: [PersistentBungeeCore, BungeeTabListPlus] \ No newline at end of file +depends: + - PersistentBungeeCore \ No newline at end of file diff --git a/steamwarci.yml b/steamwarci.yml index 21e3e3e..97af6d9 100644 --- a/steamwarci.yml +++ b/steamwarci.yml @@ -1,5 +1,4 @@ build: - - "ln -s /home/gitea/lib" - "cp ~/gradle.properties ." - "./gradlew buildProject"