Skip to content

Commit

Permalink
✨ added args for slash commands
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsTheSky committed May 6, 2024
1 parent fe6fdb5 commit 04b279a
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package info.itsthesky.disky.elements.structures.slash;

import ch.njol.skript.ScriptLoader;
import ch.njol.skript.Skript;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Name;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.log.ErrorQuality;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.util.Utils;
import ch.njol.util.Kleenean;
import ch.njol.util.StringUtils;
import info.itsthesky.disky.elements.commands.Argument;
import info.itsthesky.disky.elements.commands.CommandEvent;
import info.itsthesky.disky.elements.commands.CommandFactory;
import info.itsthesky.disky.elements.structures.slash.models.ParsedArgument;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

public class ExprSlashArgument extends SimpleExpression<Object> {

static {
Skript.registerExpression(ExprSlashArgument.class, Object.class, ExpressionType.SIMPLE,
"[][the] last arg[ument][s]",
"[][the] arg[ument][s](-| )<(\\d+)>", "[][the] <(\\d*1)st|(\\d*2)nd|(\\d*3)rd|(\\d*[4-90])th> arg[ument][s]",
"[][the] arg[ument][s]",
"[][the] %*classinfo%( |-)arg[ument][( |-)<\\d+>]", "[][the] arg[ument]( |-)%*classinfo%[( |-)<\\d+>]");
}

@SuppressWarnings("null")
private ParsedArgument arg;

@Override
public boolean init(final Expression<?> @NotNull [] exprs, final int matchedPattern, final @NotNull Kleenean isDelayed, final @NotNull ParseResult parser) {
if (!getParser().isCurrentStructure(StructSlashCommand.class))
return false;

List<ParsedArgument> currentArguments = ((StructSlashCommand) getParser().getCurrentStructure())
.getParsedCommand().getArguments();

if (currentArguments.isEmpty()) {
Skript.error("This command doesn't have any arguments", ErrorQuality.SEMANTIC_ERROR);
return false;
}

ParsedArgument arg = null;
switch (matchedPattern) {
case 0:
arg = currentArguments.get(currentArguments.size() - 1);
break;
case 1:
case 2:
@SuppressWarnings("null") final int i = Utils.parseInt(parser.regexes.get(0).group(1));
if (i > currentArguments.size()) {
Skript.error("The command doesn't have a " + StringUtils.fancyOrderNumber(i) + " argument", ErrorQuality.SEMANTIC_ERROR);
return false;
}
arg = currentArguments.get(i - 1);
break;
case 3:
if (currentArguments.size() == 1) {
arg = currentArguments.get(0);
} else {
Skript.error("'argument(s)' cannot be used if the command has multiple arguments. Use 'argument 1', 'argument 2', etc. instead", ErrorQuality.SEMANTIC_ERROR);
return false;
}
break;
case 4:
case 5:
@SuppressWarnings("unchecked") final ClassInfo<?> c = ((Literal<ClassInfo<?>>) exprs[0]).getSingle();
@SuppressWarnings("null") final int num = parser.regexes.size() > 0 ? Utils.parseInt(parser.regexes.get(0).group()) : -1;
int j = 1;
for (final ParsedArgument a : currentArguments) {
if (!c.getC().isAssignableFrom(a.getTypeInfo().getC()))
continue;
if (arg != null) {
Skript.error("There are multiple " + c + " arguments in this command", ErrorQuality.SEMANTIC_ERROR);
return false;
}
if (j < num) {
j++;
continue;
}
arg = a;
if (j == num)
break;
}
if (arg == null) {
j--;
if (num == -1 || j == 0)
Skript.error("There is no " + c + " argument in this command", ErrorQuality.SEMANTIC_ERROR);
else if (j == 1)
Skript.error("There is only one " + c + " argument in this command", ErrorQuality.SEMANTIC_ERROR);
else
Skript.error("There are only " + j + " " + c + " arguments in this command", ErrorQuality.SEMANTIC_ERROR);
return false;
}
break;
default:
assert false : matchedPattern;
return false;
}
assert arg != null;
this.arg = arg;
return true;
}

@Override
protected Object @NotNull [] get(final @NotNull Event e) {
final Object value = arg.getValue();
if (value == null)
return new Object[0];

return new Object[] {value};
}

@Override
public @NotNull Class<?> getReturnType() {
System.out.println("class: " + arg.getTypeInfo().getC());
return arg.getTypeInfo().getC();
}

@Override
public @NotNull String toString(final @Nullable Event e, final boolean debug) {
if (e == null)
return "the " + StringUtils.fancyOrderNumber(1) + " argument";
return Classes.getDebugMessage(getArray(e));
}

@Override
public boolean isSingle() {
return true;
}

@Override
public boolean isLoopOf(final String s) {
return s.equalsIgnoreCase("argument");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ public void updateCommand(ParsedCommand command,
RegisteredCommand registeredCommand,
Bot bot, String guildId) {
// We first must check if they were any changes in the command itself
registeredCommand.setTrigger(command.getTrigger()); // we update the trigger anyway

registeredCommand.setTrigger(command.getTrigger()); // we update the trigger anyway & the args
registeredCommand.setArguments(command.getArguments());

if (!registeredCommand.shouldUpdate(command))
{
DiSky.debug("{UPDATE} No changes detected for command " + command.getName() + " on guild " + guildId + " for bot " + bot.getName());
Expand Down Expand Up @@ -194,6 +197,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
return;
}

registeredCommand.prepareArguments(event);
final Trigger trigger = registeredCommand.getTrigger();
final SlashCommandReceiveEvent.BukkitSlashCommandReceiveEvent bukkitEvent = new SlashCommandReceiveEvent.BukkitSlashCommandReceiveEvent(new SlashCommandReceiveEvent());
bukkitEvent.setJDAEvent(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.Trigger;
import ch.njol.skript.lang.parser.ParserInstance;
import ch.njol.skript.lang.util.SimpleEvent;
import info.itsthesky.disky.DiSky;
import info.itsthesky.disky.api.events.SimpleDiSkyEvent;
Expand All @@ -28,6 +29,7 @@
import org.skriptlang.skript.lang.structure.Structure;

import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -76,9 +78,14 @@ public class StructSlashCommand extends Structure {
);
}

private ParsedCommand parsedCommand;
private EntryContainer entryContainer;
private @NotNull Node structure;

public ParsedCommand getParsedCommand() {
return parsedCommand;
}

@Override
public boolean init(Literal<?> @NotNull [] args, int matchedPattern, SkriptParser.@NotNull ParseResult parseResult, @NotNull EntryContainer entryContainer) {
this.entryContainer = entryContainer;
Expand All @@ -88,7 +95,7 @@ public boolean init(Literal<?> @NotNull [] args, int matchedPattern, SkriptParse

@Override
public boolean load() {
final ParsedCommand parsedCommand = new ParsedCommand();
parsedCommand = new ParsedCommand();

// Default command name
final String commandName = parseCommandName();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package info.itsthesky.disky.elements.structures.slash.models;

import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.lang.Trigger;
import ch.njol.skript.registrations.Classes;
import com.google.common.base.Objects;
import net.dv8tion.jda.api.entities.IMentionable;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import org.jetbrains.annotations.Nullable;

Expand All @@ -20,6 +27,9 @@ public class ParsedArgument {
private Map<String, Object> choices;
private @Nullable Trigger onCompletionRequest;

// Set when the argument is executed
private Object value;

public ParsedArgument(OptionType type, String name, boolean required) {
this.type = type;
this.name = name;
Expand Down Expand Up @@ -90,4 +100,37 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hashCode(type, name, required, description, choices);
}

public ClassInfo<?> getTypeInfo() {
switch (type) {
case STRING:
return Classes.getExactClassInfo(String.class);
case INTEGER:
return Classes.getExactClassInfo(Integer.class);
case BOOLEAN:
return Classes.getExactClassInfo(Boolean.class);
case USER:
return Classes.getExactClassInfo(User.class);
case CHANNEL:
return Classes.getExactClassInfo(MessageChannel.class);
case ROLE:
return Classes.getExactClassInfo(Role.class);
case NUMBER:
return Classes.getExactClassInfo(Number.class);
case ATTACHMENT:
return Classes.getExactClassInfo(Message.Attachment.class);
case MENTIONABLE:
return Classes.getExactClassInfo(IMentionable.class);
default:
return Classes.getExactClassInfo(Object.class);
}
}

public Object getValue() {
return value;
}

public void setValue(Object value) {
this.value = value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import ch.njol.skript.lang.Trigger;
import info.itsthesky.disky.core.Bot;
import info.itsthesky.disky.core.JDAUtils;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.DiscordLocale;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;

import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -120,4 +123,14 @@ public boolean shouldUpdate(ParsedCommand command) {
/*|| !this.getBots().equals(command.getBots())
|| !this.getGuilds().equals(command.getGuilds());*/
}

public void prepareArguments(SlashCommandInteractionEvent event) {
final List<OptionMapping> options = event.getOptions();
for (int i = 0; i < options.size(); i++) {
final OptionMapping option = options.get(i);
final ParsedArgument argument = arguments.get(i);

argument.setValue(JDAUtils.parseOptionValue(option));
}
}
}

0 comments on commit 04b279a

Please sign in to comment.