/* * 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 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; import net.md_5.bungee.api.plugin.Command; 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; public class SWCommand extends AbstractSWCommand { static { TypeUtils.init(); } private String permission; private Command command; private List defaultHelpMessages = new ArrayList<>(); protected SWCommand(String command) { this(command, null); } protected SWCommand(String command, String 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) { SWCommand.this.execute(commandSender, null, strings); } @Override public Iterable onTabComplete(CommandSender commandSender, String[] strings) { return SWCommand.this.tabComplete(commandSender, null, strings); } }; } private abstract static class TabCompletableCommand extends Command implements TabExecutor { public TabCompletableCommand(String name, String permission, String... aliases) { super(name, permission, aliases); } } @Override public void unregister() { if (command == null) return; CommandRegistering.unregister(this.command); } @Override public void register() { if (command == null) return; CommandRegistering.register(this.command); } @Override protected void commandSystemError(CommandSender sender, CommandFrameworkException e) { BungeeCore.get().getLogger().log(Level.SEVERE, e.getMessage(), e); ChatSender.of(sender).prefixless("COMMAND_SYSTEM_ERROR"); } @Override protected void commandSystemWarning(Supplier message) { BungeeCore.get().getLogger().log(Level.WARNING, message); } public void addDefaultHelpMessage(String message) { 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); try { chatSender.prefixless("COMMAND_HELP_HEAD", command.getName()); defaultHelpMessages.forEach(chatSender::prefixless); } catch (Exception e) { BungeeCore.get().getLogger().log(Level.WARNING, "Failed to send help message", e); return; } AtomicInteger atomicInteger = new AtomicInteger(); if (args.length != 0) { commandList.forEach(subCommand -> { List tabCompletes = subCommand.tabComplete(p, args); if (tabCompletes == null || tabCompletes.isEmpty()) { atomicInteger.incrementAndGet(); return; } boolean hasTabCompletes = tabCompletes.stream() .anyMatch(s -> s.toLowerCase().startsWith(args[args.length - 1].toLowerCase())); if (hasTabCompletes) { send(chatSender, subCommand); } else { atomicInteger.incrementAndGet(); } }); } if (args.length == 0 || atomicInteger.get() == commandList.size()) { commandList.forEach(subCommand -> { if (subCommand.guardChecker == null || subCommand.guardChecker.guard(p, GuardCheckType.TAB_COMPLETE, new String[0], null) == GuardResult.ALLOWED) { send(chatSender, subCommand); } }); } } private void send(ChatSender chatSender, SubCommand subCommand) { try { 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, 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); } } }