diff --git a/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java b/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java index e06b4256e..35375261e 100644 --- a/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java +++ b/src/main/java/com/volmit/iris/util/decree/virtual/VirtualDecreeCommand.java @@ -359,6 +359,18 @@ public class VirtualDecreeCommand { return true; } + else if(args.size() == 1) + { + for(String i : args) + { + if(i.startsWith("help=")) + { + sender.sendDecreeHelp(this, Integer.parseInt(i.split("\\Q=\\E")[1])-1); + return true; + } + } + } + String head = args.get(0); VirtualDecreeCommand match = matchNode(head, skip); diff --git a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java index 12023a444..679a99de1 100644 --- a/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java +++ b/src/main/java/com/volmit/iris/util/plugin/VolmitSender.java @@ -21,6 +21,7 @@ package com.volmit.iris.util.plugin; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.decree.DecreeParameter; import com.volmit.iris.util.decree.virtual.VirtualDecreeCommand; import com.volmit.iris.util.format.C; @@ -41,12 +42,14 @@ import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionAttachment; import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; +import org.bukkit.util.ChatPaginator; import java.time.Duration; import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -408,118 +411,167 @@ public class VolmitSender implements CommandSender { sendHeader(name, 46); } + public void sendDecreeHelp(VirtualDecreeCommand v) { + sendDecreeHelp(v, 0); + } + + + public static KList paginate(KList all, int linesPerPage, int page, AtomicBoolean hasNext) + { + int totalPages = (int) Math.ceil((double)all.size() / linesPerPage); + page = page < 0 ? 0 : page >= totalPages ? totalPages - 1 : page; + hasNext.set(page < totalPages-1); + KList d = new KList<>(); + + for(int i = linesPerPage * page; i < Math.min(all.size(), linesPerPage * (page + 1)); i++) + { + d.add(all.get(i)); + } + + return d; + } + + public void sendDecreeHelp(VirtualDecreeCommand v, int page) { int m = v.getNodes().size(); + sendMessageRaw("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + if (v.getNodes().isNotEmpty()) { - sendHeader(Form.capitalize(v.getName()) + " Help"); + sendHeader(v.getPath() + (page > 0 ? (" {" + (page+1) + "}") : "")); if (isPlayer() && v.getParent() != null) { sendMessageRaw("Click to go back to <#3299bf>" + Form.capitalize(v.getParent().getName()) + " Help" + "'><#f58571>〈 Back"); } - for (VirtualDecreeCommand i : v.getNodes()) { + AtomicBoolean next = new AtomicBoolean(false); + for (VirtualDecreeCommand i : paginate(v.getNodes(), 17, page, next)) { sendDecreeHelpNode(i); } + + String s = ""; + int l = 75 - (page > 0 ? 10 : 0) - (next.get() ? 10 : 0); + + if(page > 0) + { + s += "Click to go back to page " + page + "'>〈 Page " + page + " "; + } + + s += "" + Form.repeat(" ", l) + ""; + + if(next.get()) + { + s += " Click to go to back to page " + (page+2) + "'>Page " + (page+2) + " ❭"; + } + + sendMessageRaw(s); } else { sendMessage(C.RED + "There are no subcommands in this group! Contact support, this is a command design issue!"); } } + private static final KMap helpCache = new KMap<>(); + public void sendDecreeHelpNode(VirtualDecreeCommand i) { if (isPlayer()) { + sendMessageRaw(helpCache.compute(i.getPath(), (k, v) -> { + if(v != null) + { + return v; + } - String newline = "\n"; + String newline = "\n"; - /// Command - // Contains main command & aliases - String realText = i.getPath() + " >" + "<#46826a>⇀ " + i.getName(); - String hoverTitle = i.getNames().copy().reverse().convert((f) -> "<#42ecf5>" + f).toString(", "); - String description = "<#3fe05a>✎ <#6ad97d>" + i.getDescription(); - String usage = "<#bbe03f>✒ <#a8e0a2>"; - String onClick; - if (i.isNode()) { - if (i.getNode().getParameters().isEmpty()) { - usage += "There are no parameters. Click to run."; - onClick = "run_command"; + /// Command + // Contains main command & aliases + String realText = i.getPath() + " >" + "<#46826a>⇀ " + i.getName(); + String hoverTitle = i.getNames().copy().reverse().convert((f) -> "<#42ecf5>" + f).toString(", "); + String description = "<#3fe05a>✎ <#6ad97d>" + i.getDescription(); + String usage = "<#bbe03f>✒ <#a8e0a2>"; + String onClick; + if (i.isNode()) { + if (i.getNode().getParameters().isEmpty()) { + usage += "There are no parameters. Click to run."; + onClick = "run_command"; + } else { + usage += "Hover over all of the parameters to learn more."; + onClick = "suggest_command"; + } } else { - usage += "Hover over all of the parameters to learn more."; - onClick = "suggest_command"; + usage += "This is a command category. Click to run."; + onClick = "run_command"; } - } else { - usage += "This is a command category. Click to run."; - onClick = "run_command"; - } - String suggestion = ""; - String suggestions = ""; - if (i.isNode() && i.getNode().getParameters().isNotEmpty()) { - suggestion += newline + "<#aebef2>✦ <#5ef288>" + i.getParentPath() + " <#42ecf5>" + i.getName() + " " - + i.getNode().getParameters().convert((f) -> "<#d665f0>" + f.example()).toString(" "); - suggestions += newline + "" + pickRandoms(Math.min(i.getNode().getParameters().size() + 1, 5), i); - } - - /// Params - StringBuilder nodes = new StringBuilder(); - if (i.isNode()) { - for (DecreeParameter p : i.getNode().getParameters()) { - - String nTitle = "" + p.getName(); - String nHoverTitle = p.getNames().convert((ff) -> "<#d665f0>" + ff).toString(", "); - String nDescription = "<#3fe05a>✎ <#6ad97d>" + p.getDescription(); - String nUsage; - String context = ""; - if (p.isRequired()) { - nUsage = "<#db4321>⚠ <#faa796>This parameter is required."; - } else if (p.hasDefault()) { - nUsage = "<#2181db>✔ <#78dcf0>Defaults to \"" + p.getParam().defaultValue() + "\" if undefined."; - } else { - nUsage = "<#a73abd>✔ <#78dcf0>This parameter is optional."; - } - if (p.isContextual()) { - context = "<#ff9900>➱ <#ffcc00>The value may be derived from environment context" + newline; - } - String type = "<#cc00ff>✢ <#ff33cc>This parameter is of type " + p.getType().getSimpleName(); - String fullTitle; - if (p.isRequired()) { - fullTitle = "[" + nTitle + "] "; - } else { - fullTitle = "<#4f4f4f>⊰" + nTitle + "<#4f4f4f>⊱"; - } - - nodes - .append("") - .append(fullTitle) - .append(""); + String suggestion = ""; + String suggestions = ""; + if (i.isNode() && i.getNode().getParameters().isNotEmpty()) { + suggestion += newline + "<#aebef2>✦ <#5ef288>" + i.getParentPath() + " <#42ecf5>" + i.getName() + " " + + i.getNode().getParameters().convert((f) -> "<#d665f0>" + f.example()).toString(" "); + suggestions += newline + "" + pickRandoms(Math.min(i.getNode().getParameters().size() + 1, 5), i); } - } else { - nodes = new StringBuilder(" - Category of Commands"); - } - /// Wrapper - String wrapper = - "" + - "" + - "" + - " " + - nodes; + /// Params + StringBuilder nodes = new StringBuilder(); + if (i.isNode()) { + for (DecreeParameter p : i.getNode().getParameters()) { - sendMessageRaw(wrapper); + String nTitle = "" + p.getName(); + String nHoverTitle = p.getNames().convert((ff) -> "<#d665f0>" + ff).toString(", "); + String nDescription = "<#3fe05a>✎ <#6ad97d>" + p.getDescription(); + String nUsage; + String context = ""; + if (p.isRequired()) { + nUsage = "<#db4321>⚠ <#faa796>This parameter is required."; + } else if (p.hasDefault()) { + nUsage = "<#2181db>✔ <#78dcf0>Defaults to \"" + p.getParam().defaultValue() + "\" if undefined."; + } else { + nUsage = "<#a73abd>✔ <#78dcf0>This parameter is optional."; + } + if (p.isContextual()) { + context = "<#ff9900>➱ <#ffcc00>The value may be derived from environment context" + newline; + } + String type = "<#cc00ff>✢ <#ff33cc>This parameter is of type " + p.getType().getSimpleName(); + String fullTitle; + if (p.isRequired()) { + fullTitle = "[" + nTitle + "] "; + } else { + fullTitle = "<#4f4f4f>⊰" + nTitle + "<#4f4f4f>⊱"; + } + + nodes + .append("") + .append(fullTitle) + .append(""); + } + } else { + nodes = new StringBuilder(" - Category of Commands"); + } + + /// Wrapper + String wrapper = + "" + + "" + + "" + + " " + + nodes; + + return wrapper; + })); } else { sendMessage(i.getPath()); }