Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dynamic usage messages for commands #6627

Merged
85 changes: 85 additions & 0 deletions src/main/java/ch/njol/skript/command/CommandUsage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.command;

import ch.njol.skript.lang.VariableString;
import ch.njol.skript.util.Utils;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

/**
* Holds info about the usage of a command.
* TODO: replace with record when java 17
*/
public class CommandUsage {

/**
* A dynamic usage message that can contain expressions.
*/
private final VariableString usage;

/**
* A fallback usage message that can be used in non-event environments,
* like when registering the Bukkit command.
*/
private final String defaultUsage;

/**
* @param usage The dynamic usage message, can contain expressions.
* @param defaultUsage A fallback usage message for use in non-event environments.
*/
public CommandUsage(@Nullable VariableString usage, String defaultUsage) {
if (usage == null) {
usage = VariableString.newInstance(defaultUsage);
assert usage != null;
}
this.usage = usage;
this.defaultUsage = Utils.replaceChatStyles(defaultUsage);
}

/**
* @return The usage message as a {@link VariableString}.
*/
public VariableString getRawUsage() {
return usage;
}
/**
* Get the usage message without an event to evaluate it.
* @return The evaluated usage message.
*/
public String getUsage() {
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
return getUsage(null);
}

/**
* @param event The event used to evaluate the usage message.
* @return The evaluated usage message.
*/
public String getUsage(@Nullable Event event) {
if (event != null || usage.isSimple())
return usage.toString(event);
return defaultUsage;
}

@Override
public String toString() {
return getUsage();
}

}
43 changes: 36 additions & 7 deletions src/main/java/ch/njol/skript/command/ScriptCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public class ScriptCommand implements TabExecutor {
private final String cooldownBypass;
@Nullable
private final Expression<String> cooldownStorage;
final String usage;
final CommandUsage usage;

private final Trigger trigger;

Expand All @@ -115,11 +115,13 @@ public class ScriptCommand implements TabExecutor {

private Map<UUID,Date> lastUsageMap = new HashMap<>();

//<editor-fold default-state="collapsed" desc="public ScriptCommand(... String usage ...)">
/**
* Creates a new SkriptCommand.
* Creates a new ScriptCommand.
* Prefer using the CommandUsage class for the usage parameter.
*
* @param name /name
* @param pattern
* @param pattern the Skript pattern used to parse the input into arguments.
* @param arguments the list of Arguments this command takes
* @param description description to display in /help
* @param prefix the prefix of the command
Expand All @@ -135,6 +137,33 @@ public ScriptCommand(
String permission, @Nullable VariableString permissionMessage, @Nullable Timespan cooldown,
@Nullable VariableString cooldownMessage, String cooldownBypass,
@Nullable VariableString cooldownStorage, int executableBy, SectionNode node
) {
this(script, name, pattern, arguments, description, prefix, new CommandUsage(null, usage),
aliases, permission, permissionMessage, cooldown, cooldownMessage, cooldownBypass,
cooldownStorage, executableBy, node);
}
//</editor-fold>

/**
* Creates a new ScriptCommand.
*
* @param name /name
* @param pattern the Skript pattern used to parse the input into arguments.
* @param arguments the list of Arguments this command takes
* @param description description to display in /help
* @param prefix the prefix of the command
* @param usage message to display if the command was used incorrectly
* @param aliases /alias1, /alias2, ...
* @param permission permission or null if none
* @param permissionMessage message to display if the player doesn't have the given permission
* @param node the node to parse and load into a Trigger
*/
public ScriptCommand(
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
Script script, String name, String pattern, List<Argument<?>> arguments,
String description, @Nullable String prefix, CommandUsage usage, List<String> aliases,
String permission, @Nullable VariableString permissionMessage, @Nullable Timespan cooldown,
@Nullable VariableString cooldownMessage, String cooldownBypass,
@Nullable VariableString cooldownStorage, int executableBy, SectionNode node
) {
Validate.notNull(name, pattern, arguments, description, usage, aliases, node);
this.name = name;
Expand Down Expand Up @@ -180,7 +209,7 @@ public ScriptCommand(
activeAliases = new ArrayList<>(aliases);

this.description = Utils.replaceEnglishChatStyles(description);
this.usage = Utils.replaceEnglishChatStyles(usage);
this.usage = usage;

this.executableBy = executableBy;

Expand All @@ -205,7 +234,7 @@ private PluginCommand setupBukkitCommand() {
// We can only set the message if it's simple (doesn't contains expressions)
if (permissionMessage.isSimple())
bukkitCommand.setPermissionMessage(permissionMessage.toString(null));
bukkitCommand.setUsage(usage);
bukkitCommand.setUsage(usage.getUsage());
bukkitCommand.setExecutor(this);
return bukkitCommand;
} catch (final Exception e) {
Expand Down Expand Up @@ -300,7 +329,7 @@ boolean execute2(final ScriptCommandEvent event, final CommandSender sender, fin
final LogEntry e = log.getError();
if (e != null)
sender.sendMessage(ChatColor.DARK_RED + e.toString());
sender.sendMessage(usage);
sender.sendMessage(usage.getUsage(event));
log.clear();
return false;
}
Expand Down Expand Up @@ -342,7 +371,7 @@ public boolean checkPermissions(CommandSender sender, Event event) {
public void sendHelp(final CommandSender sender) {
if (!description.isEmpty())
sender.sendMessage(description);
sender.sendMessage(ChatColor.GOLD + "Usage" + ChatColor.RESET + ": " + usage);
sender.sendMessage(ChatColor.GOLD + "Usage" + ChatColor.RESET + ": " + usage.getUsage());
}

/**
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/ch/njol/skript/structures/StructCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.command.Argument;
import ch.njol.skript.command.CommandUsage;
import ch.njol.skript.command.Commands;
import ch.njol.skript.command.ScriptCommand;
import ch.njol.skript.command.ScriptCommandEvent;
Expand Down Expand Up @@ -92,10 +93,10 @@ public class StructCommand extends Structure {
Skript.registerStructure(
StructCommand.class,
EntryValidator.builder()
.addEntry("usage", null, true)
.addEntry("description", "", true)
.addEntry("prefix", null, true)
.addEntry("permission", "", true)
.addEntryData(new VariableStringEntryData("usage", null, true))
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
.addEntryData(new VariableStringEntryData("permission message", null, true))
.addEntryData(new KeyValueEntryData<List<String>>("aliases", new ArrayList<>(), true) {
private final Pattern pattern = Pattern.compile("\\s*,\\s*/?");
Expand Down Expand Up @@ -261,10 +262,9 @@ public boolean load() {
});
desc = Commands.unescape(desc).trim();

String usage = entryContainer.getOptional("usage", String.class, false);
if (usage == null) {
usage = Commands.m_correct_usage + " " + desc;
}
VariableString usageMessage = entryContainer.getOptional("usage", VariableString.class, false);
String defaultUsageMessage = Commands.m_correct_usage + " " + desc;
CommandUsage usage = new CommandUsage(usageMessage, defaultUsageMessage);

String description = entryContainer.get("description", String.class, true);
String prefix = entryContainer.getOptional("prefix", String.class, false);
Expand Down
Loading