diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java index 77c2f0dd4..51d1c766b 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/Plan.java @@ -157,7 +157,7 @@ public class Plan extends BukkitPlugin implements PlanPlugin { logger.warn("Attempted to register '" + name + "'-command, but it is not in plugin.yml!"); continue; } - registering.setExecutor(new BukkitCommand(command)); + registering.setExecutor(new BukkitCommand(runnableFactory, command)); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCMDSender.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCMDSender.java index 2d95073b1..3be5c3ffe 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCMDSender.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCMDSender.java @@ -53,4 +53,9 @@ public class BukkitCMDSender implements CMDSender { public void send(String msg) { sender.sendMessage(msg); } + + @Override + public ChatFormatter getFormatter() { + return new ConsoleChatFormatter(); + } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCommand.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCommand.java index 75694490c..daaaab1e7 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCommand.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitCommand.java @@ -17,6 +17,8 @@ package com.djrapitops.plan.commands.use; import com.djrapitops.plan.commands.Arguments; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -24,19 +26,26 @@ import org.bukkit.entity.Player; public class BukkitCommand implements CommandExecutor { + private final RunnableFactory runnableFactory; private final Subcommand command; - public BukkitCommand(Subcommand command) { + public BukkitCommand(RunnableFactory runnableFactory, Subcommand command) { + this.runnableFactory = runnableFactory; this.command = command; } @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - if (sender instanceof Player) { - command.getExecutor().accept(new BukkitPlayerCMDSender((Player) sender), new Arguments(args)); - } else { - command.getExecutor().accept(new BukkitCMDSender(sender), new Arguments(args)); - } + runnableFactory.create("", new AbsRunnable() { + @Override + public void run() { + if (sender instanceof Player) { + command.getExecutor().accept(new BukkitPlayerCMDSender((Player) sender), new Arguments(args)); + } else { + command.getExecutor().accept(new BukkitCMDSender(sender), new Arguments(args)); + } + } + }).runTaskAsynchronously(); return true; } } \ No newline at end of file diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitPlayerCMDSender.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitPlayerCMDSender.java index 22f2b7988..d7ca9a035 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitPlayerCMDSender.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/commands/use/BukkitPlayerCMDSender.java @@ -44,4 +44,9 @@ public class BukkitPlayerCMDSender extends BukkitCMDSender { public Optional getUUID() { return Optional.of(player.getUniqueId()); } + + @Override + public ChatFormatter getFormatter() { + return new PlayerChatFormatter(); + } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java index 292623481..c3a4e6f5e 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/PlanCommand.java @@ -59,6 +59,7 @@ public class PlanCommand { .alias("plan") .colorScheme(colors) .subcommand(serverCommand()) + .subcommand(serversCommand()) .subcommand(playerCommand()) .subcommand(playersCommand()) .subcommand(networkCommand()) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/subcommands/LinkCommands.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/subcommands/LinkCommands.java index dd2476839..dc6ef0206 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/subcommands/LinkCommands.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/subcommands/LinkCommands.java @@ -18,7 +18,6 @@ package com.djrapitops.plan.commands.subcommands; import com.djrapitops.plan.commands.Arguments; import com.djrapitops.plan.commands.use.CMDSender; -import com.djrapitops.plan.commands.use.MessageBuilder; import com.djrapitops.plan.delivery.rendering.html.Html; import com.djrapitops.plan.delivery.webserver.Addresses; import com.djrapitops.plan.identification.Identifiers; @@ -135,14 +134,18 @@ public class LinkCommands { public void onServersCommand(CMDSender sender, Arguments arguments) { String m = colors.getMainColor(); + String s = colors.getSecondaryColor(); String t = colors.getTertiaryColor(); String serversListed = dbSystem.getDatabase() .query(ServerQueries.fetchPlanServerInformationCollection()) .stream().sorted() - .map(server -> server.getId() + ":" + server.getName() + ":" + server.getUuid() + "\n") + .map(server -> m + server.getId() + ":" + t + server.getName() + ":" + s + server.getUuid() + "\n") .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) .toString(); - String table = ChatFormatter - MessageBuilder message = sender.buildMessage().addPart(t + '>' + m + " Servers; id : name : uuid").newLine(); + sender.buildMessage() + .addPart(t + '>' + m + " Servers").newLine() + .addPart(sender.getFormatter().table( + t + "id:name:uuid\n" + serversListed, ":")) + .send(); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CMDSender.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CMDSender.java index a68b08630..bc1d702b8 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CMDSender.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CMDSender.java @@ -44,4 +44,6 @@ public interface CMDSender { void send(String message); + ChatFormatter getFormatter(); + } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/ChatFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/ChatFormatter.java new file mode 100644 index 000000000..da17be52a --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/ChatFormatter.java @@ -0,0 +1,84 @@ +package com.djrapitops.plan.commands.use; + +import com.djrapitops.plan.utilities.analysis.Maximum; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public abstract class ChatFormatter { + + public abstract int getWidth(String part); + + public String table(String message, String separator) { + String[] lines = StringUtils.split(message, '\n'); + List rows = new ArrayList<>(); + Maximum.ForInteger rowWidth = new Maximum.ForInteger(0); + for (String line : lines) { + String[] row = StringUtils.split(line, separator); + rowWidth.add(row.length); + rows.add(row); + } + int columns = rowWidth.getMaxAndReset(); + int[] maxWidths = findMaxWidths(rows, columns); + int compensates = getWidth(" "); + + StringBuilder table = new StringBuilder(); + for (String[] row : rows) { + for (int i = 0; i < row.length; i++) { + int width = getWidth(row[i]); + table.append(row[i]); + while (maxWidths[i] > width) { + table.append(" "); + width += compensates; + } + } + table.append('\n'); + } + return table.toString(); + } + + public List tableAsParts(String message, String separator) { + String[] lines = StringUtils.split(message, '\n'); + List rows = new ArrayList<>(); + Maximum.ForInteger rowWidth = new Maximum.ForInteger(0); + for (String line : lines) { + String[] row = StringUtils.split(line, separator); + rowWidth.add(row.length); + rows.add(row); + } + int columns = rowWidth.getMaxAndReset(); + int[] maxWidths = findMaxWidths(rows, columns); + int compensates = getWidth(" "); + + List table = new ArrayList<>(); + for (String[] row : rows) { + List rowAsParts = new ArrayList<>(); + for (int i = 0; i < row.length; i++) { + StringBuilder part = new StringBuilder(row[i]); + int width = getWidth(row[i]); + while (maxWidths[i] > width) { + part.append(" "); + width += compensates; + } + rowAsParts.add(part.toString()); + } + table.add(rowAsParts.toArray(new String[0])); + } + return table; + } + + private int[] findMaxWidths(List rows, int columns) { + int[] maxWidths = new int[columns]; + for (String[] row : rows) { + for (int i = 0; i < row.length; i++) { + int width = getWidth(row[i]) + 1; + if (maxWidths[i] < width) { + maxWidths[i] = width; + } + } + } + return maxWidths; + } + +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java index 671a05e82..62a48aada 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/CommandWithSubcommands.java @@ -45,9 +45,11 @@ public class CommandWithSubcommands extends Subcommand { public void onHelp(CMDSender sender, Arguments arguments) { List hasPermissionFor = subcommands.stream().filter(sender::hasAllPermissionsFor).collect(Collectors.toList()); sender.buildMessage() - .addPart("Header").newLine().newLine() - .apply(new HelpFormatter(colors, getPrimaryAlias(), hasPermissionFor)::addSubcommands) - .newLine().addPart("Footer") + .addPart("Header") + .newLine().newLine() + .apply(new HelpFormatter(sender, colors, getPrimaryAlias(), hasPermissionFor)::addSubcommands) + .newLine().newLine() + .addPart("Footer") .send(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/ConsoleChatFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/ConsoleChatFormatter.java new file mode 100644 index 000000000..89789fbbf --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/ConsoleChatFormatter.java @@ -0,0 +1,11 @@ +package com.djrapitops.plan.commands.use; + +import org.apache.commons.lang3.StringUtils; + +public class ConsoleChatFormatter extends ChatFormatter { + + @Override + public int getWidth(String part) { + return part.length() - (StringUtils.countMatches(part, 'ยง') * 2); + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/HelpFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/HelpFormatter.java index 20a38825d..d83181e6d 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/HelpFormatter.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/HelpFormatter.java @@ -25,28 +25,44 @@ import java.util.Set; public class HelpFormatter { + private final CMDSender sender; private final ColorScheme colors; private final String mainCommand; private final List subcommands; public HelpFormatter( - ColorScheme colors, String mainCommand, List subcommands + CMDSender sender, ColorScheme colors, String mainCommand, List subcommands ) { + this.sender = sender; this.colors = colors; this.mainCommand = mainCommand; this.subcommands = subcommands; } public MessageBuilder addSubcommands(MessageBuilder message) { - for (Subcommand subcommand : subcommands) { - String alias = subcommand.getPrimaryAlias(); - message.addPart(colors.getMainColor() + mainCommand + " " + alias + "---") - .hover(argumentsAndAliases(subcommand.getArguments(), subcommand.getAliases())); - message.addPart(colors.getSecondaryColor() + subcommand.getDescription()) - .hover(subcommand.getInDepthDescription()); - message.tabular("---"); + MessageBuilder toReturn = message; + String m = colors.getMainColor(); + String s = colors.getSecondaryColor(); + String asString = subcommands.stream() + .map(cmd -> + m + mainCommand + " " + cmd.getPrimaryAlias() + + (sender.getPlayerName().isPresent() ? "" : " " + cmd.getArgumentsAsString()) + "--" + + s + cmd.getDescription() + "\n" + ).collect(StringBuilder::new, StringBuilder::append, StringBuilder::append) + .toString(); + List table = sender.getFormatter().tableAsParts(asString, "--"); + + for (int i = 0; i < table.size(); i++) { + Subcommand subcommand = subcommands.get(i); + String[] row = table.get(i); + toReturn = toReturn.addPart(row[0]) + .hover(argumentsAndAliases(subcommand.getArguments(), subcommand.getAliases())) + .addPart(row[1]) + .hover(subcommand.getInDepthDescription()) + .newLine(); } - return message; + + return toReturn; } private List argumentsAndAliases(List descriptors, Set aliases) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/MessageBuilder.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/MessageBuilder.java index 8de87f092..be5a2bf70 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/MessageBuilder.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/MessageBuilder.java @@ -23,6 +23,13 @@ public interface MessageBuilder { MessageBuilder addPart(String msg); + default MessageBuilder addEach(Iterable iterable) { + for (String part : iterable) { + addPart(part); + } + return this; + } + MessageBuilder newLine(); MessageBuilder link(String address); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/PlayerChatFormatter.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/PlayerChatFormatter.java new file mode 100644 index 000000000..4a30feef8 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/PlayerChatFormatter.java @@ -0,0 +1,9 @@ +package com.djrapitops.plan.commands.use; + +public class PlayerChatFormatter extends ChatFormatter { + + @Override + public int getWidth(String part) { + return part.length(); // TODO + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/Subcommand.java b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/Subcommand.java index 84347706b..8b2041c57 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/commands/use/Subcommand.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/commands/use/Subcommand.java @@ -76,6 +76,16 @@ public class Subcommand { return argumentResolver; } + public String getArgumentsAsString() { + StringBuilder builder = new StringBuilder(); + for (ArgumentDescriptor argument : getArguments()) { + builder.append(argument.required ? '<' + argument.name + '>' : '[' + argument.name + ']') + .append(' '); + } + return builder.toString().trim(); + } + + @SuppressWarnings("unchecked") public static class Builder implements SubcommandBuilder { private final Subcommand subcommand;