CommandListPage.java
package com.hypixel.hytale.server.core.command.system.pages;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.protocol.packets.interface_.OpenChatWithCommand;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.command.system.AbstractCommand;
import com.hypixel.hytale.server.core.command.system.CommandManager;
import com.hypixel.hytale.server.core.command.system.MatchResult;
import com.hypixel.hytale.server.core.command.system.arguments.system.DefaultArg;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
import com.hypixel.hytale.server.core.command.system.arguments.system.OptionalArg;
import com.hypixel.hytale.server.core.command.system.arguments.system.RequiredArg;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgumentType;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;
import com.hypixel.hytale.server.core.ui.Value;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class CommandListPage extends InteractiveCustomUIPage<CommandListPageEventData> {
private static final Value<String> BUTTON_LABEL_STYLE = Value.<String>ref("Pages/BasicTextButton.ui", "LabelStyle");
private static final Value<String> BUTTON_LABEL_STYLE_SELECTED = Value.<String>ref("Pages/BasicTextButton.ui", "SelectedLabelStyle");
private final List<String> visibleCommands;
@Nonnull
private String searchQuery;
private String selectedCommand;
private String selectedSubcommand;
private Integer selectedVariantIndex;
private final List<String> subcommandBreadcrumb;
@Nullable
private final String initialCommand;
public CommandListPage(@Nonnull PlayerRef playerRef) {
this(playerRef, (String)null);
}
public CommandListPage(@Nonnull PlayerRef playerRef, @Nullable String initialCommand) {
super(playerRef, CustomPageLifetime.CanDismiss, CommandListPage.CommandListPageEventData.CODEC);
this.visibleCommands = new ObjectArrayList<String>();
this.searchQuery = "";
this.subcommandBreadcrumb = new ObjectArrayList<String>();
this.initialCommand = initialCommand;
}
public void build(@Nonnull Ref<EntityStore> ref, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder, @Nonnull Store<EntityStore> store) {
commandBuilder.append("Pages/CommandListPage.ui");
eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#SearchInput", EventData.of("@SearchQuery", "#SearchInput.Value"), false);
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BackButton", EventData.of("NavigateUp", "true"));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#SendToChatButton", EventData.of("SendToChat", "true"));
this.buildCommandList(ref, commandBuilder, eventBuilder, store);
String commandToSelect = (String)this.visibleCommands.getFirst();
if (this.initialCommand != null && this.visibleCommands.contains(this.initialCommand)) {
commandToSelect = this.initialCommand;
}
this.selectCommand(ref, commandToSelect, commandBuilder, eventBuilder, store);
}
public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull CommandListPageEventData data) {
if (data.searchQuery != null) {
this.searchQuery = data.searchQuery.trim().toLowerCase();
UICommandBuilder commandBuilder = new UICommandBuilder();
UIEventBuilder eventBuilder = new UIEventBuilder();
this.buildCommandList(ref, commandBuilder, eventBuilder, store);
this.sendUpdate(commandBuilder, eventBuilder, false);
} else if (data.command != null) {
UICommandBuilder commandBuilder = new UICommandBuilder();
UIEventBuilder eventBuilder = new UIEventBuilder();
this.selectCommand(ref, data.command, commandBuilder, eventBuilder, store);
this.sendUpdate(commandBuilder, eventBuilder, false);
} else if (data.navigateUp != null) {
UICommandBuilder commandBuilder = new UICommandBuilder();
UIEventBuilder eventBuilder = new UIEventBuilder();
this.navigateUp(ref, commandBuilder, eventBuilder, store);
this.sendUpdate(commandBuilder, eventBuilder, false);
} else if (data.subcommand != null) {
UICommandBuilder commandBuilder = new UICommandBuilder();
UIEventBuilder eventBuilder = new UIEventBuilder();
this.selectSubcommand(ref, data.subcommand, commandBuilder, eventBuilder, store);
this.sendUpdate(commandBuilder, eventBuilder, false);
} else if (data.variantIndex != null) {
UICommandBuilder commandBuilder = new UICommandBuilder();
UIEventBuilder eventBuilder = new UIEventBuilder();
try {
int variantIdx = Integer.parseInt(data.variantIndex);
this.selectVariant(ref, variantIdx, commandBuilder, eventBuilder, store);
this.sendUpdate(commandBuilder, eventBuilder, false);
} catch (NumberFormatException var7) {
}
} else if (data.sendToChat != null) {
this.handleSendToChat(ref, store);
}
}
private void handleSendToChat(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
Player playerComponent = (Player)store.getComponent(ref, Player.getComponentType());
if (playerComponent != null) {
String command = this.buildCurrentCommandString();
playerComponent.getPageManager().setPage(ref, store, Page.None);
this.playerRef.getPacketHandler().write((Packet)(new OpenChatWithCommand(command)));
}
}
@Nonnull
private String buildCurrentCommandString() {
StringBuilder sb = new StringBuilder("/");
sb.append(this.selectedCommand);
for(String part : this.subcommandBreadcrumb) {
sb.append(" ").append(part);
}
AbstractCommand currentContext = (AbstractCommand)CommandManager.get().getCommandRegistration().get(this.selectedCommand);
if (currentContext != null) {
for(String part : this.subcommandBreadcrumb) {
Map<String, AbstractCommand> subcommands = currentContext.getSubCommands();
currentContext = (AbstractCommand)subcommands.get(part);
if (currentContext == null) {
break;
}
}
if (currentContext != null) {
for(RequiredArg<?> arg : currentContext.getRequiredArguments()) {
sb.append(" <").append(arg.getName()).append(">");
}
}
}
return sb.toString();
}
private void buildCommandList(@Nonnull Ref<EntityStore> ref, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
commandBuilder.clear("#CommandList");
Map<String, AbstractCommand> commands = new Object2ObjectOpenHashMap<String, AbstractCommand>(CommandManager.get().getCommandRegistration());
Player playerComponent = (Player)componentAccessor.getComponent(ref, Player.getComponentType());
assert playerComponent != null;
commands.values().removeIf((commandx) -> !commandx.hasPermission(playerComponent));
if (this.searchQuery.isEmpty()) {
this.visibleCommands.clear();
this.visibleCommands.addAll(commands.keySet());
Collections.sort(this.visibleCommands);
} else {
ObjectArrayList<SearchResult> results = new ObjectArrayList<SearchResult>();
for(Map.Entry<String, AbstractCommand> entry : commands.entrySet()) {
if (entry.getValue() != null) {
results.add(new SearchResult((String)entry.getKey(), MatchResult.EXACT));
}
}
String[] terms = this.searchQuery.split(" ");
for(int termIndex = 0; termIndex < terms.length; ++termIndex) {
String term = terms[termIndex];
for(int cmdIndex = results.size() - 1; cmdIndex >= 0; --cmdIndex) {
SearchResult result = results.get(cmdIndex);
AbstractCommand command = (AbstractCommand)commands.get(result.name);
MatchResult match;
if (command != null) {
match = command.matches(this.playerRef.getLanguage(), term, termIndex);
} else {
match = MatchResult.NONE;
}
if (match == MatchResult.NONE) {
results.remove(cmdIndex);
} else {
result.match = result.match.min(match);
}
}
}
results.sort(CommandListPage.SearchResult.COMPARATOR);
this.visibleCommands.clear();
for(int i = 0; i < results.size(); ++i) {
this.visibleCommands.add((results.get(i)).name);
}
}
for(int i = 0; i < this.visibleCommands.size(); ++i) {
String name = (String)this.visibleCommands.get(i);
commandBuilder.append("#CommandList", "Pages/BasicTextButton.ui");
commandBuilder.set("#CommandList[" + i + "].TextSpans", Message.raw(name));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#CommandList[" + i + "]", EventData.of("Command", name));
if (name.equals(this.selectedCommand)) {
commandBuilder.set("#CommandList[" + i + "].Style", BUTTON_LABEL_STYLE_SELECTED);
}
}
}
private void selectCommand(@Nonnull Ref<EntityStore> ref, @Nonnull String commandName, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
AbstractCommand command = (AbstractCommand)CommandManager.get().getCommandRegistration().get(commandName);
if (command == null) {
throw new IllegalArgumentException("Unknown command: " + commandName);
} else {
commandBuilder.set("#CommandName.TextSpans", Message.raw(commandName));
Player playerComponent = (Player)componentAccessor.getComponent(ref, Player.getComponentType());
commandBuilder.set("#CommandDescription.TextSpans", Message.translation(command.getDescription()));
this.selectedSubcommand = null;
this.selectedVariantIndex = null;
this.subcommandBreadcrumb.clear();
this.buildSubcommandTabs(command, playerComponent, commandBuilder, eventBuilder);
this.displayCommandInfo(command, playerComponent, commandBuilder, eventBuilder);
if (this.selectedCommand != null && this.visibleCommands.contains(this.selectedCommand)) {
commandBuilder.set("#CommandList[" + this.visibleCommands.indexOf(this.selectedCommand) + "].Style", BUTTON_LABEL_STYLE);
}
commandBuilder.set("#CommandList[" + this.visibleCommands.indexOf(commandName) + "].Style", BUTTON_LABEL_STYLE_SELECTED);
this.selectedCommand = commandName;
}
}
private void selectSubcommand(@Nonnull Ref<EntityStore> ref, @Nonnull String subcommandName, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
AbstractCommand currentContext = (AbstractCommand)CommandManager.get().getCommandRegistration().get(this.selectedCommand);
if (currentContext != null) {
for(String breadcrumbPart : this.subcommandBreadcrumb) {
Map<String, AbstractCommand> subcommands = currentContext.getSubCommands();
currentContext = (AbstractCommand)subcommands.get(breadcrumbPart);
if (currentContext == null) {
return;
}
}
Player playerComponent = (Player)componentAccessor.getComponent(ref, Player.getComponentType());
Map<String, AbstractCommand> subcommands = currentContext.getSubCommands();
AbstractCommand subcommand = (AbstractCommand)subcommands.get(subcommandName);
if (subcommand != null) {
this.subcommandBreadcrumb.add(subcommandName);
this.selectedSubcommand = subcommandName;
this.selectedVariantIndex = null;
this.updateTitleWithBreadcrumb(commandBuilder);
commandBuilder.set("#CommandDescription.TextSpans", Message.translation(subcommand.getDescription()));
this.buildSubcommandTabs(subcommand, playerComponent, commandBuilder, eventBuilder);
commandBuilder.set("#BackButton.Visible", true);
this.displayCommandInfo(subcommand, playerComponent, commandBuilder, eventBuilder);
}
}
}
private void selectVariant(@Nonnull Ref<EntityStore> ref, int variantIndex, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
AbstractCommand currentContext = (AbstractCommand)CommandManager.get().getCommandRegistration().get(this.selectedCommand);
if (currentContext != null) {
for(String breadcrumbPart : this.subcommandBreadcrumb) {
Map<String, AbstractCommand> subcommands = currentContext.getSubCommands();
currentContext = (AbstractCommand)subcommands.get(breadcrumbPart);
if (currentContext == null) {
return;
}
}
Player playerComponent = (Player)componentAccessor.getComponent(ref, Player.getComponentType());
try {
Field variantsField = AbstractCommand.class.getDeclaredField("variantCommands");
variantsField.setAccessible(true);
Int2ObjectMap<AbstractCommand> variants = (Int2ObjectMap)variantsField.get(currentContext);
AbstractCommand variant = (AbstractCommand)variants.get(variantIndex);
if (variant == null || !variant.hasPermission(playerComponent)) {
return;
}
this.selectedVariantIndex = variantIndex;
this.updateTitleWithVariantSuffix(commandBuilder);
commandBuilder.set("#VariantsSection.Visible", false);
commandBuilder.set("#BackButton.Visible", true);
commandBuilder.set("#CommandUsageLabel.TextSpans", this.getSimplifiedUsage(variant, playerComponent));
this.buildParametersSection(variant, playerComponent, commandBuilder);
this.buildArgumentTypesSection(variant, playerComponent, commandBuilder);
} catch (Exception var11) {
}
}
}
private void navigateUp(@Nonnull Ref<EntityStore> ref, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
if (this.selectedVariantIndex != null) {
this.selectedVariantIndex = null;
AbstractCommand currentContext = (AbstractCommand)CommandManager.get().getCommandRegistration().get(this.selectedCommand);
if (currentContext != null) {
for(String breadcrumbPart : this.subcommandBreadcrumb) {
Map<String, AbstractCommand> subcommands = currentContext.getSubCommands();
currentContext = (AbstractCommand)subcommands.get(breadcrumbPart);
if (currentContext == null) {
return;
}
}
Player playerComponent = (Player)componentAccessor.getComponent(ref, Player.getComponentType());
this.updateTitleWithBreadcrumb(commandBuilder);
this.displayCommandInfo(currentContext, playerComponent, commandBuilder, eventBuilder);
commandBuilder.set("#BackButton.Visible", !this.subcommandBreadcrumb.isEmpty());
}
} else if (!this.subcommandBreadcrumb.isEmpty()) {
this.subcommandBreadcrumb.remove(this.subcommandBreadcrumb.size() - 1);
AbstractCommand currentContext = (AbstractCommand)CommandManager.get().getCommandRegistration().get(this.selectedCommand);
if (currentContext != null) {
for(String breadcrumbPart : this.subcommandBreadcrumb) {
Map<String, AbstractCommand> subcommands = currentContext.getSubCommands();
currentContext = (AbstractCommand)subcommands.get(breadcrumbPart);
if (currentContext == null) {
return;
}
}
Player playerComponent = (Player)componentAccessor.getComponent(ref, Player.getComponentType());
this.selectedSubcommand = this.subcommandBreadcrumb.isEmpty() ? null : (String)this.subcommandBreadcrumb.get(this.subcommandBreadcrumb.size() - 1);
this.updateTitleWithBreadcrumb(commandBuilder);
this.buildSubcommandTabs(currentContext, playerComponent, commandBuilder, eventBuilder);
this.displayCommandInfo(currentContext, playerComponent, commandBuilder, eventBuilder);
}
}
}
private void buildSubcommandTabs(@Nonnull AbstractCommand command, @Nonnull Player playerComponent, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder) {
commandBuilder.clear("#SubcommandCards");
Map<String, AbstractCommand> subcommands = command.getSubCommands();
if (subcommands.isEmpty()) {
commandBuilder.set("#SubcommandSection.Visible", false);
} else {
commandBuilder.set("#SubcommandSection.Visible", true);
int cardIndex = 0;
int rowIndex = 0;
int cardsInCurrentRow = 0;
for(Map.Entry<String, AbstractCommand> entry : subcommands.entrySet()) {
AbstractCommand subcommand = (AbstractCommand)entry.getValue();
if (subcommand.hasPermission(playerComponent)) {
if (cardsInCurrentRow == 0) {
commandBuilder.appendInline("#SubcommandCards", "Group { LayoutMode: Left; Anchor: (Bottom: 0); }");
}
commandBuilder.append("#SubcommandCards[" + rowIndex + "]", "Pages/SubcommandCard.ui");
commandBuilder.set("#SubcommandCards[" + rowIndex + "][" + cardsInCurrentRow + "] #SubcommandName.TextSpans", Message.raw((String)entry.getKey()));
commandBuilder.set("#SubcommandCards[" + rowIndex + "][" + cardsInCurrentRow + "] #SubcommandUsage.TextSpans", this.getSimplifiedUsage(subcommand, playerComponent));
commandBuilder.set("#SubcommandCards[" + rowIndex + "][" + cardsInCurrentRow + "] #SubcommandDescription.TextSpans", Message.translation(subcommand.getDescription()));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#SubcommandCards[" + rowIndex + "][" + cardsInCurrentRow + "]", EventData.of("Subcommand", (String)entry.getKey()));
++cardsInCurrentRow;
++cardIndex;
if (cardsInCurrentRow >= 3) {
cardsInCurrentRow = 0;
++rowIndex;
}
}
}
}
commandBuilder.set("#BackButton.Visible", !this.subcommandBreadcrumb.isEmpty());
}
private void updateTitleWithBreadcrumb(@Nonnull UICommandBuilder commandBuilder) {
StringBuilder titleText = new StringBuilder(this.selectedCommand);
for(String part : this.subcommandBreadcrumb) {
titleText.append(" > ").append(part);
}
commandBuilder.set("#CommandName.TextSpans", Message.raw(titleText.toString()));
}
private void updateTitleWithVariantSuffix(@Nonnull UICommandBuilder commandBuilder) {
StringBuilder titleText = new StringBuilder(this.selectedCommand);
for(String part : this.subcommandBreadcrumb) {
titleText.append(" > ").append(part);
}
titleText.append(" [Variant]");
commandBuilder.set("#CommandName.TextSpans", Message.raw(titleText.toString()));
}
private void buildAliasesSection(@Nonnull AbstractCommand command, @Nonnull UICommandBuilder commandBuilder) {
Set<String> aliases = command.getAliases();
if (aliases != null && !aliases.isEmpty()) {
commandBuilder.set("#AliasesSection.Visible", true);
commandBuilder.set("#AliasesList.TextSpans", Message.raw(String.join(", ", aliases)));
} else {
commandBuilder.set("#AliasesSection.Visible", false);
}
}
private void buildPermissionSection(@Nonnull AbstractCommand command, @Nonnull UICommandBuilder commandBuilder) {
String permission = command.getPermission();
if (permission != null && !permission.isEmpty()) {
commandBuilder.set("#PermissionSection.Visible", true);
commandBuilder.set("#PermissionLabel.TextSpans", Message.raw(permission));
} else {
commandBuilder.set("#PermissionSection.Visible", false);
}
}
private void buildVariantsSection(@Nonnull AbstractCommand command, @Nonnull Player playerComponent, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder) {
commandBuilder.clear("#VariantsList");
try {
Field variantsField = AbstractCommand.class.getDeclaredField("variantCommands");
variantsField.setAccessible(true);
Int2ObjectMap<AbstractCommand> variants = (Int2ObjectMap)variantsField.get(command);
if (variants.isEmpty()) {
commandBuilder.set("#VariantsSection.Visible", false);
return;
}
commandBuilder.set("#VariantsSection.Visible", true);
int displayIndex = 0;
for(Int2ObjectMap.Entry<AbstractCommand> entry : variants.int2ObjectEntrySet()) {
AbstractCommand variant = (AbstractCommand)entry.getValue();
int variantIndex = entry.getIntKey();
if (variant.hasPermission(playerComponent)) {
commandBuilder.append("#VariantsList", "Pages/VariantCard.ui");
commandBuilder.set("#VariantsList[" + displayIndex + "] #VariantUsage.TextSpans", this.getSimplifiedUsage(variant, playerComponent));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#VariantsList[" + displayIndex + "]", EventData.of("Variant", String.valueOf(variantIndex)));
++displayIndex;
}
}
if (displayIndex == 0) {
commandBuilder.set("#VariantsSection.Visible", false);
}
} catch (Exception var12) {
commandBuilder.set("#VariantsSection.Visible", false);
}
}
private void displayCommandInfo(@Nonnull AbstractCommand command, @Nonnull Player playerComponent, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder) {
this.buildVariantsSection(command, playerComponent, commandBuilder, eventBuilder);
this.buildAliasesSection(command, commandBuilder);
this.buildPermissionSection(command, commandBuilder);
commandBuilder.set("#CommandUsageLabel.TextSpans", this.getSimplifiedUsage(command, playerComponent));
this.buildParametersSection(command, playerComponent, commandBuilder);
this.buildArgumentTypesSection(command, playerComponent, commandBuilder);
}
private Message getSimplifiedUsage(@Nonnull AbstractCommand command, @Nonnull Player playerComponent) {
Message message = Message.raw("/").insert(command.getFullyQualifiedName());
try {
Field requiredArgsField = AbstractCommand.class.getDeclaredField("requiredArguments");
requiredArgsField.setAccessible(true);
for(RequiredArg<?> arg : (List)requiredArgsField.get(command)) {
message.insert(" <").insert(Message.translation(arg.getName())).insert(">");
}
} catch (Exception var9) {
}
try {
Field optionalArgsField = AbstractCommand.class.getDeclaredField("optionalArguments");
optionalArgsField.setAccessible(true);
Map<String, ?> optionalArgs = (Map)optionalArgsField.get(command);
if (!optionalArgs.isEmpty()) {
message.insert(" [").insert(Message.translation("server.customUI.commandListPage.optionsIndicator")).insert("]");
}
} catch (Exception var8) {
}
return message;
}
private void buildParametersSection(@Nonnull AbstractCommand command, @Nonnull Player playerComponent, @Nonnull UICommandBuilder commandBuilder) {
commandBuilder.clear("#RequiredArgumentsList");
commandBuilder.clear("#OptionalArgumentsList");
commandBuilder.clear("#DefaultArgumentsList");
commandBuilder.clear("#FlagArgumentsList");
boolean hasAnyParameters = false;
try {
Field requiredArgsField = AbstractCommand.class.getDeclaredField("requiredArguments");
requiredArgsField.setAccessible(true);
List<RequiredArg<?>> requiredArgs = (List)requiredArgsField.get(command);
if (!requiredArgs.isEmpty()) {
hasAnyParameters = true;
for(int i = 0; i < requiredArgs.size(); ++i) {
RequiredArg<?> arg = (RequiredArg)requiredArgs.get(i);
commandBuilder.append("#RequiredArgumentsList", "Pages/ParameterItem.ui");
commandBuilder.set("#RequiredArgumentsList[" + i + "] #ParamName.TextSpans", Message.raw(arg.getName()));
commandBuilder.set("#RequiredArgumentsList[" + i + "] #ParamTag.TextSpans", Message.raw("[Required]"));
commandBuilder.set("#RequiredArgumentsList[" + i + "] #ParamType.TextSpans", Message.translation("server.customUI.commandListPage.paramType").param("type", arg.getArgumentType().getName()));
commandBuilder.set("#RequiredArgumentsList[" + i + "] #ParamDescription.TextSpans", arg.getDescription() != null ? Message.translation(arg.getDescription()) : Message.translation("server.customUI.commandListPage.noDescription"));
}
}
} catch (Exception var17) {
}
try {
Field optionalArgsField = AbstractCommand.class.getDeclaredField("optionalArguments");
optionalArgsField.setAccessible(true);
Map<String, ?> optionalArgs = (Map)optionalArgsField.get(command);
if (!optionalArgs.isEmpty()) {
hasAnyParameters = true;
}
int optIndex = 0;
int defIndex = 0;
int flagIndex = 0;
for(Map.Entry<String, ?> entry : optionalArgs.entrySet()) {
Object arg = entry.getValue();
if (arg instanceof OptionalArg<?> optArg) {
if (optArg.getPermission() == null || playerComponent.hasPermission(optArg.getPermission())) {
commandBuilder.append("#OptionalArgumentsList", "Pages/ParameterItem.ui");
String var22 = "#OptionalArgumentsList[" + optIndex + "] #ParamName.TextSpans";
String var23 = optArg.getName();
commandBuilder.set(var22, Message.raw("--" + var23 + " <" + optArg.getName() + ">"));
commandBuilder.set("#OptionalArgumentsList[" + optIndex + "] #ParamTag.TextSpans", Message.raw("[Optional]"));
commandBuilder.set("#OptionalArgumentsList[" + optIndex + "] #ParamType.TextSpans", Message.translation("server.customUI.commandListPage.paramType").param("type", optArg.getArgumentType().getName()));
commandBuilder.set("#OptionalArgumentsList[" + optIndex + "] #ParamDescription.TextSpans", optArg.getDescription() != null ? Message.translation(optArg.getDescription()) : Message.translation("server.customUI.commandListPage.noDescription"));
++optIndex;
}
} else if (arg instanceof DefaultArg<?> defArg) {
if (defArg.getPermission() == null || playerComponent.hasPermission(defArg.getPermission())) {
commandBuilder.append("#DefaultArgumentsList", "Pages/ParameterItem.ui");
String var10001 = "#DefaultArgumentsList[" + defIndex + "] #ParamName.TextSpans";
String var10002 = defArg.getName();
commandBuilder.set(var10001, Message.raw("--" + var10002 + " <" + defArg.getName() + ">"));
commandBuilder.set("#DefaultArgumentsList[" + defIndex + "] #ParamTag.TextSpans", Message.raw("[Default]"));
commandBuilder.set("#DefaultArgumentsList[" + defIndex + "] #ParamType.TextSpans", Message.translation("server.customUI.commandListPage.paramTypeDefault").param("type", defArg.getArgumentType().getName()).param("default", defArg.getDefaultValueDescription()));
commandBuilder.set("#DefaultArgumentsList[" + defIndex + "] #ParamDescription.TextSpans", defArg.getDescription() != null ? Message.translation(defArg.getDescription()) : Message.translation("server.customUI.commandListPage.noDescription"));
++defIndex;
}
} else if (arg instanceof FlagArg flagArg) {
if (flagArg.getPermission() == null || playerComponent.hasPermission(flagArg.getPermission())) {
commandBuilder.append("#FlagArgumentsList", "Pages/ParameterItem.ui");
commandBuilder.set("#FlagArgumentsList[" + flagIndex + "] #ParamName.TextSpans", Message.raw("--" + flagArg.getName()));
commandBuilder.set("#FlagArgumentsList[" + flagIndex + "] #ParamTag.TextSpans", Message.raw("[Flag]"));
commandBuilder.set("#FlagArgumentsList[" + flagIndex + "] #ParamType.TextSpans", Message.translation("server.customUI.commandListPage.paramTypeFlag"));
commandBuilder.set("#FlagArgumentsList[" + flagIndex + "] #ParamDescription.TextSpans", flagArg.getDescription() != null ? Message.translation(flagArg.getDescription()) : Message.translation("server.customUI.commandListPage.noDescription"));
++flagIndex;
}
}
}
} catch (Exception var16) {
}
commandBuilder.set("#ParametersSection.Visible", hasAnyParameters);
}
private void buildArgumentTypesSection(@Nonnull AbstractCommand command, @Nonnull Player playerComponent, @Nonnull UICommandBuilder commandBuilder) {
commandBuilder.clear("#ArgumentTypesList");
HashSet<ArgumentType<?>> allArgumentTypes = new HashSet();
try {
Field requiredArgsField = AbstractCommand.class.getDeclaredField("requiredArguments");
requiredArgsField.setAccessible(true);
for(RequiredArg<?> arg : (List)requiredArgsField.get(command)) {
allArgumentTypes.add(arg.getArgumentType());
}
Field optionalArgsField = AbstractCommand.class.getDeclaredField("optionalArguments");
optionalArgsField.setAccessible(true);
Map<String, ?> optionalArgs = (Map)optionalArgsField.get(command);
for(Object entry : optionalArgs.values()) {
if (entry instanceof OptionalArg) {
allArgumentTypes.add(((OptionalArg)entry).getArgumentType());
} else if (entry instanceof DefaultArg) {
allArgumentTypes.add(((DefaultArg)entry).getArgumentType());
}
}
} catch (Exception var11) {
}
if (allArgumentTypes.isEmpty()) {
commandBuilder.set("#ArgumentTypesSection.Visible", false);
} else {
commandBuilder.set("#ArgumentTypesSection.Visible", true);
int index = 0;
for(ArgumentType<?> argType : allArgumentTypes) {
commandBuilder.append("#ArgumentTypesList", "Pages/ArgumentTypeItem.ui");
commandBuilder.set("#ArgumentTypesList[" + index + "] #TypeName.TextSpans", argType.getName());
commandBuilder.set("#ArgumentTypesList[" + index + "] #TypeDescription.TextSpans", argType.getArgumentUsage());
String[] examples = argType.getExamples();
if (examples != null && examples.length > 0) {
commandBuilder.set("#ArgumentTypesList[" + index + "] #TypeExamples.TextSpans", Message.translation("server.customUI.commandListPage.examples").param("examples", String.join("', '", examples)));
} else {
commandBuilder.set("#ArgumentTypesList[" + index + "] #TypeExamples.Visible", false);
}
++index;
}
}
}
public static class CommandListPageEventData {
static final String KEY_COMMAND = "Command";
static final String KEY_SUBCOMMAND = "Subcommand";
static final String KEY_SEARCH_QUERY = "@SearchQuery";
static final String KEY_NAVIGATE_UP = "NavigateUp";
static final String KEY_VARIANT = "Variant";
static final String KEY_SEND_TO_CHAT = "SendToChat";
public static final BuilderCodec<CommandListPageEventData> CODEC;
private String command;
private String subcommand;
private String searchQuery;
private String navigateUp;
private String variantIndex;
private String sendToChat;
public CommandListPageEventData() {
}
static {
CODEC = ((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)BuilderCodec.builder(CommandListPageEventData.class, CommandListPageEventData::new).addField(new KeyedCodec("Command", Codec.STRING), (entry, s) -> entry.command = s, (entry) -> entry.command)).addField(new KeyedCodec("Subcommand", Codec.STRING), (entry, s) -> entry.subcommand = s, (entry) -> entry.subcommand)).addField(new KeyedCodec("@SearchQuery", Codec.STRING), (entry, s) -> entry.searchQuery = s, (entry) -> entry.searchQuery)).addField(new KeyedCodec("NavigateUp", Codec.STRING), (entry, s) -> entry.navigateUp = s, (entry) -> entry.navigateUp)).addField(new KeyedCodec("Variant", Codec.STRING), (entry, s) -> entry.variantIndex = s, (entry) -> entry.variantIndex)).addField(new KeyedCodec("SendToChat", Codec.STRING), (entry, s) -> entry.sendToChat = s, (entry) -> entry.sendToChat)).build();
}
}
private static class SearchResult {
public static final Comparator<SearchResult> COMPARATOR = Comparator.comparing((o) -> o.match);
private final String name;
private MatchResult match;
public SearchResult(String name, MatchResult match) {
this.name = name;
this.match = match;
}
}
}