Table Formatter for console

This commit is contained in:
Risto Lahtela 2020-05-13 19:11:18 +03:00
parent 03bfe28762
commit c91d4f410b
14 changed files with 187 additions and 23 deletions

View File

@ -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));
}
}

View File

@ -53,4 +53,9 @@ public class BukkitCMDSender implements CMDSender {
public void send(String msg) {
sender.sendMessage(msg);
}
@Override
public ChatFormatter getFormatter() {
return new ConsoleChatFormatter();
}
}

View File

@ -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;
}
}

View File

@ -44,4 +44,9 @@ public class BukkitPlayerCMDSender extends BukkitCMDSender {
public Optional<UUID> getUUID() {
return Optional.of(player.getUniqueId());
}
@Override
public ChatFormatter getFormatter() {
return new PlayerChatFormatter();
}
}

View File

@ -59,6 +59,7 @@ public class PlanCommand {
.alias("plan")
.colorScheme(colors)
.subcommand(serverCommand())
.subcommand(serversCommand())
.subcommand(playerCommand())
.subcommand(playersCommand())
.subcommand(networkCommand())

View File

@ -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();
}
}

View File

@ -44,4 +44,6 @@ public interface CMDSender {
void send(String message);
ChatFormatter getFormatter();
}

View File

@ -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<String[]> 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<String[]> tableAsParts(String message, String separator) {
String[] lines = StringUtils.split(message, '\n');
List<String[]> 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<String[]> table = new ArrayList<>();
for (String[] row : rows) {
List<String> 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<String[]> 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;
}
}

View File

@ -45,9 +45,11 @@ public class CommandWithSubcommands extends Subcommand {
public void onHelp(CMDSender sender, Arguments arguments) {
List<Subcommand> 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();
}

View File

@ -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);
}
}

View File

@ -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<Subcommand> subcommands;
public HelpFormatter(
ColorScheme colors, String mainCommand, List<Subcommand> subcommands
CMDSender sender, ColorScheme colors, String mainCommand, List<Subcommand> 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<String[]> 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<String> argumentsAndAliases(List<Subcommand.ArgumentDescriptor> descriptors, Set<String> aliases) {

View File

@ -23,6 +23,13 @@ public interface MessageBuilder {
MessageBuilder addPart(String msg);
default MessageBuilder addEach(Iterable<String> iterable) {
for (String part : iterable) {
addPart(part);
}
return this;
}
MessageBuilder newLine();
MessageBuilder link(String address);

View File

@ -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
}
}

View File

@ -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<T extends SubcommandBuilder> implements SubcommandBuilder {
private final Subcommand subcommand;