Instantly share code, notes, and snippets.
Created
March 30, 2024 21:30
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save Revxrsal/7f30684f206deef2d89071847a411651 to your computer and use it in GitHub Desktop.
A utility for creating interactive help menus using Lamp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import net.kyori.adventure.audience.Audience; | |
import net.kyori.adventure.text.Component; | |
import net.kyori.adventure.text.event.ClickEvent; | |
import net.kyori.adventure.text.event.HoverEvent; | |
import net.kyori.adventure.text.format.Style; | |
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; | |
import org.jetbrains.annotations.NotNull; | |
import org.jetbrains.annotations.Nullable; | |
import revxrsal.commands.command.CommandActor; | |
import revxrsal.commands.command.ExecutableCommand; | |
import revxrsal.commands.help.CommandHelp; | |
import revxrsal.commands.help.CommandHelpWriter; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.StringJoiner; | |
/** | |
* A utility for creating interactive, paginated help menus. | |
* <p> | |
* Note: This requires adventure APIs to work. | |
*/ | |
public final class InteractiveHelpMenu implements CommandHelpWriter<Component> { | |
/** | |
* The default number of entries in a single help page | |
*/ | |
private static final int DEFAULT_PAGE_SIZE = 8; | |
/** | |
* The slash command color | |
*/ | |
private final String slashCommandColor; | |
/** | |
* The command name color | |
*/ | |
private final String commandNameColor; | |
/** | |
* The parameters/command usage color | |
*/ | |
private final String parametersColor; | |
/** | |
* The hover tooltip label color | |
*/ | |
private final String tooltipLabelsColor; | |
/** | |
* The page size | |
*/ | |
private final int pageSize; | |
private InteractiveHelpMenu(String slashCommandColor, String commandNameColor, String parametersColor, String tooltipLabelsColor, int pageSize) { | |
this.slashCommandColor = slashCommandColor; | |
this.commandNameColor = commandNameColor; | |
this.parametersColor = parametersColor; | |
this.tooltipLabelsColor = tooltipLabelsColor; | |
this.pageSize = pageSize; | |
} | |
/** | |
* Creates a new {@link Builder} | |
* | |
* @return A new builder | |
*/ | |
public static @NotNull Builder builder() { | |
return new Builder(); | |
} | |
@Override | |
public @Nullable Component generate(@NotNull ExecutableCommand command, @NotNull CommandActor actor) { | |
if (command.isSecret() || !command.hasPermission(actor)) | |
return null; | |
boolean hasParameters = !command.getValueParameters().isEmpty(); | |
List<String> tooltip = createTooltip(command); | |
StringJoiner desc = new StringJoiner(" "); | |
desc.add(slashCommandColor + "/" + commandNameColor + command.getPath().getParent()); | |
if (command.getPath().size() > 1) | |
desc.add(String.join(" ", command.getPath().getSubcommandPath())); | |
if (!command.getValueParameters().isEmpty()) | |
desc.add(parametersColor + command.getUsage()); | |
return lg(desc.toString()).style(Style.style() | |
.hoverEvent(HoverEvent.showText(lg(String.join("\n", tooltip)))) | |
.clickEvent(ClickEvent.suggestCommand('/' + command.getPath().toRealString() + (hasParameters ? " " : "")))); | |
} | |
private List<String> createTooltip(ExecutableCommand command) { | |
List<String> tooltip = new ArrayList<>(); | |
if (command.getDescription() != null) | |
tooltip.add(tooltipLabelsColor + "&lDescription&f: " + command.getDescription()); | |
if (!command.getValueParameters().isEmpty()) /* check if command has any parameters */ | |
tooltip.add(tooltipLabelsColor + "&lParameters&f: " + command.getUsage()); | |
if (!tooltip.isEmpty()) | |
tooltip.add(""); | |
tooltip.add("Click to add to your chat box!"); | |
return tooltip; | |
} | |
public void sendFullHelpMessage( | |
Audience target, | |
CommandHelp<Component> allEntries, | |
int page, | |
ExecutableCommand helpCommand | |
) { | |
int pageCount = allEntries.getPageSize(pageSize); | |
int index = coerce(page, 1, pageCount); | |
sendTopBar(target, index, pageCount, helpCommand); | |
CommandHelp<Component> helpPage = allEntries.paginate(index, pageSize); | |
for (Component component : helpPage) { | |
target.sendMessage(component); | |
} | |
sendBottomBar(target, index, pageCount); | |
} | |
private static void sendTopBar(Audience audience, int currentPage, int pageSize, ExecutableCommand command) { | |
String previous = "/" + command.getPath().toRealString() + " " + (currentPage - 1); | |
String next = "/" + command.getPath().toRealString() + " " + (currentPage + 1); | |
Component bar = Component.text() | |
.append(lg("&7&m------")) | |
.append( | |
currentPage <= 1 ? lg("&7&l <<") | |
.hoverEvent(HoverEvent.showText(lg("&fThis is the first page"))) | |
: lg("&a&l <<").clickEvent(ClickEvent.runCommand(previous)) | |
.hoverEvent(HoverEvent.showText(lg("&aPrevious page"))) | |
) | |
.append(lg("&r &8| ")) | |
.append( | |
currentPage >= pageSize ? lg("&7&l>> ") | |
.hoverEvent(HoverEvent.showText(lg("&fThis is the last page"))) | |
: lg("&a&l>> ").clickEvent(ClickEvent.runCommand(next)) | |
.hoverEvent(HoverEvent.showText(lg("&aNext page"))) | |
) | |
.append(lg("&7&m------")) | |
.build(); | |
audience.sendMessage(bar); | |
} | |
private static void sendBottomBar(Audience audience, int index, int pageSize) { | |
Component bar = Component.text() | |
.append(lg("&7&m-------&a (")) | |
.append(lg((index == pageSize ? "&2" : "&e") + index + "&7/&2" + pageSize)) | |
.append(lg("&a) &7&m-------")) | |
.build(); | |
audience.sendMessage(bar); | |
} | |
@Override | |
public String toString() { | |
return "InteractiveHelpMenu(" + | |
"slashCommandColor='" + slashCommandColor + '\'' + | |
", commandNameColor='" + commandNameColor + '\'' + | |
", parametersColor='" + parametersColor + '\'' + | |
", tooltipLabelsColor='" + tooltipLabelsColor + '\'' + | |
", pageSize=" + pageSize + | |
')'; | |
} | |
/* Utility methods */ | |
private static int coerce(int value, int min, int max) { | |
return value < min ? min : Math.min(value, max); | |
} | |
private static Component lg(String m) { | |
return LegacyComponentSerializer.legacyAmpersand().deserialize(m); | |
} | |
public static class Builder { | |
private String slashCommandColor = "&7"; | |
private String commandNameColor = "&e"; | |
private String parametersColor = "&6"; | |
private String tooltipLabelsColor = "&e"; | |
private int pageSize = DEFAULT_PAGE_SIZE; | |
public Builder slashCommandColor(String slashCommandColor) { | |
this.slashCommandColor = slashCommandColor; | |
return this; | |
} | |
public Builder commandNameColor(String commandNameColor) { | |
this.commandNameColor = commandNameColor; | |
return this; | |
} | |
public Builder parametersColor(String parametersColor) { | |
this.parametersColor = parametersColor; | |
return this; | |
} | |
public Builder tooltipLabelsColor(String tooltipLabelsColor) { | |
this.tooltipLabelsColor = tooltipLabelsColor; | |
return this; | |
} | |
public Builder pageSize(int pageSize) { | |
this.pageSize = pageSize; | |
return this; | |
} | |
public InteractiveHelpMenu build() { | |
return new InteractiveHelpMenu(this.slashCommandColor, this.commandNameColor, this.parametersColor, this.tooltipLabelsColor, this.pageSize); | |
} | |
public String toString() { | |
return "InteractiveHelpMenu.Builder(slashCommandColor=" + this.slashCommandColor + ", commandNameColor=" + this.commandNameColor + ", parametersColor=" + this.parametersColor + ", tooltipLabelsColor=" + this.tooltipLabelsColor + ", pageSize=" + this.pageSize + ")"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment