Skip to content

Instantly share code, notes, and snippets.

@Revxrsal
Created March 30, 2024 21:30
Show Gist options
  • Save Revxrsal/7f30684f206deef2d89071847a411651 to your computer and use it in GitHub Desktop.
Save Revxrsal/7f30684f206deef2d89071847a411651 to your computer and use it in GitHub Desktop.
A utility for creating interactive help menus using Lamp
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