Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
ac98b45
Add basic Brigadier-based command structure
APickledWalrus Jun 23, 2026
15533d8
Switch to entry-data based approach
APickledWalrus Jun 23, 2026
2360399
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Jun 23, 2026
92bef10
Handle argument forwarding, better default string argument type
APickledWalrus Jun 23, 2026
72d682d
Proper native type support
APickledWalrus Jun 23, 2026
90f7e35
Don't require a trigger when subcommands are present
APickledWalrus Jun 23, 2026
61d9d23
Simplify argument handling
APickledWalrus Jun 23, 2026
eed9d0e
Command parser 9000 has arrived
APickledWalrus Jun 24, 2026
86be3f2
Organize and cleanup
APickledWalrus Jun 24, 2026
e113c0f
Command parser 9000v2
APickledWalrus Jun 24, 2026
44322a0
Simple argument range support
APickledWalrus Jun 25, 2026
87b3c98
Reimplement automatic argument naming
APickledWalrus Jun 29, 2026
a5ec99a
Restore command type hints
APickledWalrus Jun 29, 2026
4e23a9d
Properly handle plural arguments
APickledWalrus Jun 29, 2026
2b92399
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Jun 29, 2026
42be4e1
Integrate ExprArgument
APickledWalrus Jun 29, 2026
98180ef
Utility cleanup
APickledWalrus Jun 29, 2026
70bac5d
Improve default string argument behavior
APickledWalrus Jun 29, 2026
544dcc1
Add back several command entries
APickledWalrus Jun 29, 2026
c9d73b1
Cooldowns and fixes
APickledWalrus Jun 30, 2026
331d9de
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Jul 2, 2026
26b14d7
Add alternative reflection-based command registration
APickledWalrus Jul 2, 2026
6e6d489
Prevent legacy command registration
APickledWalrus Jul 2, 2026
a275c4c
Add questionable "prefix" entry compatibility
APickledWalrus Jul 3, 2026
3e49a44
Ensure other test commands run
APickledWalrus Jul 3, 2026
f889689
Fix double slash execution on older versions
APickledWalrus Jul 3, 2026
014cb21
Improve prefix validation
APickledWalrus Jul 3, 2026
868875b
Improve registered command organization
APickledWalrus Jul 3, 2026
6e74508
Cleanup and tweaks
APickledWalrus Jul 3, 2026
004968e
Add HelpTopic handling, restore "usage" entry
APickledWalrus Jul 4, 2026
214e1e9
Improve native argument validation
APickledWalrus Jul 5, 2026
4cb520d
Refine ranged argument validation
APickledWalrus Jul 6, 2026
8606b5b
Fix help topic creation
APickledWalrus Jul 6, 2026
c3ee50e
More testing and adjustments
APickledWalrus Jul 6, 2026
b3f068d
Port ExprCommandInfo
APickledWalrus Jul 6, 2026
bbefbc8
Continue porting syntax
APickledWalrus Jul 6, 2026
30c9be3
Account for dispatchCommand behavior
APickledWalrus Jul 6, 2026
2c19ef6
Port ExprAllCommands
APickledWalrus Jul 6, 2026
fba8623
Start deprecating legacy code
APickledWalrus Jul 6, 2026
773d78c
Add additional command event values
APickledWalrus Jul 7, 2026
7ea6a1b
Add ExecutableBy.BLOCKS option
APickledWalrus Jul 7, 2026
a0a4c3f
Add additional native argument types
APickledWalrus Jul 7, 2026
813cc99
Add ExecutableBy.OPERATORS
APickledWalrus Jul 7, 2026
ea560c6
Simple tab completion system
APickledWalrus Jul 8, 2026
a147436
Add suggestion input details expression
APickledWalrus Jul 9, 2026
1f04235
Provide argument values within suggestions entry
APickledWalrus Jul 9, 2026
c11f147
Add suggestion filtering mode
APickledWalrus Jul 9, 2026
9c980cf
Add back SkriptParser#parseArguments as deprecated
APickledWalrus Jul 13, 2026
b5e0254
Tweak suggestions handling
APickledWalrus Jul 13, 2026
e036a51
Add suggestion hovers through components
APickledWalrus Jul 13, 2026
939d7a0
Handle missing brackets in compilation
APickledWalrus Jul 14, 2026
ef3f2fb
Fix capitalized command handling
APickledWalrus Jul 14, 2026
41d22c9
Reorder arguments for compatibility
APickledWalrus Jul 14, 2026
1f453f1
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Jul 15, 2026
d77f3e4
Only attach suggestions if necessary
APickledWalrus Jul 15, 2026
68d896b
Restore console effect commands
APickledWalrus Jul 20, 2026
fb22645
Revert unintentional version change
APickledWalrus Jul 20, 2026
662bf8f
Add UnknownCommandEvent support
APickledWalrus Jul 30, 2026
1455e33
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Jul 31, 2026
8c382f3
Automatic native argument support for RegistryClassInfos
APickledWalrus Jul 31, 2026
c0cfd7f
Support selectors in OfflinePlayer arguments
APickledWalrus Aug 15, 2026
89c1d8b
Add support for having an optional subcommand
APickledWalrus Aug 16, 2026
b6f85f7
Add support for "subcommands" grouping
APickledWalrus Aug 19, 2026
217e7c0
Support real-time validation+highlighting for OfflinePlayer args
APickledWalrus Aug 20, 2026
1e91268
Add compatibility with TabCompleteEvent suggestions
APickledWalrus Aug 20, 2026
1367701
Refine TabCompleteEvent compatibility
APickledWalrus Aug 21, 2026
f2cabd6
Delay OfflinePlayer argument resolution
APickledWalrus Aug 21, 2026
710b3b4
Remove unsupported configuration options
APickledWalrus Aug 21, 2026
f32e2e6
Only convert underscores for suggesting arguments
APickledWalrus Aug 21, 2026
e3a7e83
Only evaluate used arguments in suggestions
APickledWalrus Aug 21, 2026
f49d52f
Re-implement usage entry support
APickledWalrus Aug 21, 2026
6d11444
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Aug 21, 2026
a82701f
Simplify fallback suggestion handling
APickledWalrus Aug 24, 2026
e77fce0
Add additional range keywords
APickledWalrus Aug 24, 2026
372d000
Partially fix plural offline player arguments
APickledWalrus Aug 24, 2026
5711560
Rework OfflinePlayerArgument for plural support
APickledWalrus Aug 25, 2026
471f446
Further rework of OfflinePlayerArgument for tab completions
APickledWalrus Aug 25, 2026
78d0d35
Fix compilation failure from deep chains
APickledWalrus Sep 1, 2026
5400cb0
Add ranged argument support for Skript types
APickledWalrus Sep 2, 2026
1e0ff93
Support localization, context for error messages
APickledWalrus Sep 2, 2026
68183fb
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Sep 2, 2026
e992f96
Further refine lang entries
APickledWalrus Sep 2, 2026
7f81a57
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Sep 4, 2026
566ddc1
Add support for validating choice arguments
APickledWalrus Sep 4, 2026
f99cde0
Add missing docs annotations
APickledWalrus Sep 4, 2026
5700c5d
Add support for command results
APickledWalrus Sep 21, 2026
b6a0371
Add support for command failures
APickledWalrus Sep 21, 2026
0029819
Address reviews with usability improvements
APickledWalrus Sep 21, 2026
b1fbfa2
Merge branch 'dev/feature' into feature/command-rework
APickledWalrus Sep 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 20 additions & 23 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import ch.njol.skript.bukkitutil.BurgerHelper;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.data.*;
import ch.njol.skript.command.Commands;
import ch.njol.skript.doc.Documentation;
import ch.njol.skript.events.EvtSkript;
import ch.njol.skript.expressions.arithmetic.ExprArithmetic;
Expand Down Expand Up @@ -44,15 +43,14 @@
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.event.server.ServerLoadEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import org.jetbrains.annotations.Unmodifiable;
Expand All @@ -63,6 +61,7 @@
import org.skriptlang.skript.addon.AddonModule;
import org.skriptlang.skript.bukkit.BukkitModule;
import org.skriptlang.skript.bukkit.SkriptMetrics;
import org.skriptlang.skript.bukkit.command.elements.effects.EffCommand;
import org.skriptlang.skript.bukkit.lang.eventvalue.EventValueRegistry;
import org.skriptlang.skript.bukkit.log.runtime.BukkitRuntimeErrorConsumer;
import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos;
Expand All @@ -80,7 +79,9 @@
import org.skriptlang.skript.lang.script.Script;
import org.skriptlang.skript.lang.structure.Structure;
import org.skriptlang.skript.lang.structure.StructureInfo;
import org.skriptlang.skript.log.runtime.ErrorSource;
import org.skriptlang.skript.log.runtime.RuntimeErrorManager;
import org.skriptlang.skript.log.runtime.RuntimeErrorProducer;
import org.skriptlang.skript.registration.DefaultSyntaxInfos;
import org.skriptlang.skript.registration.SyntaxInfo;
import org.skriptlang.skript.registration.SyntaxRegistry;
Expand Down Expand Up @@ -577,8 +578,6 @@ public String name() {

Aliases.load();

Commands.registerListeners();

if (logNormal())
info(" " + Language.get("skript.copyright"));

Expand Down Expand Up @@ -1804,26 +1803,24 @@ public static <E extends Structure> void registerStructure(
* @param sender
* @param command
* @return Whether the command was run
* @deprecated There is no replacement for this method.
*/
public static boolean dispatchCommand(final CommandSender sender, final String command) {
try {
if (sender instanceof Player) {
final PlayerCommandPreprocessEvent e = new PlayerCommandPreprocessEvent((Player) sender, "/" + command);
Bukkit.getPluginManager().callEvent(e);
if (e.isCancelled() || !e.getMessage().startsWith("/"))
return false;
return Bukkit.dispatchCommand(e.getPlayer(), e.getMessage().substring(1));
} else {
final ServerCommandEvent e = new ServerCommandEvent(sender, command);
Bukkit.getPluginManager().callEvent(e);
if (e.getCommand().isEmpty() || e.isCancelled())
return false;
return Bukkit.dispatchCommand(e.getSender(), e.getCommand());
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public static boolean dispatchCommand(CommandSender sender, String command) {
return EffCommand.dispatchCommand(sender, command, new RuntimeErrorProducer() {
@Override
public @NotNull ErrorSource getErrorSource() {
throw new UnsupportedOperationException();
}
} catch (final Exception ex) {
ex.printStackTrace(); // just like Bukkit
return false;
}
@Override
public void error(String message) { }
@Override
public void error(String message, String highlight) { }
@Override
public void warning(String message) { }
@Override
public void warning(String message, String highlight) { }
});
}

// ================ LOGGING ================
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/ch/njol/skript/SkriptConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ public static String formatDate(final long timestamp) {
public static final Option<Boolean> caseInsensitiveVariables = new Option<>("case-insensitive variables", true)
.setter(t -> Variables.caseInsensitiveVariables = t);

/**
* @deprecated This config option is no longer used and there is no replacement.
*/
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public static final Option<Boolean> caseInsensitiveCommands = new Option<>("case-insensitive commands", false)
.optional(true);

Expand Down Expand Up @@ -308,6 +312,13 @@ public static String formatDate(final long timestamp) {
public static final Option<Boolean> allowUnsafePlatforms = new Option<>("allow unsafe platforms", false)
.optional(true);

public static final Option<Boolean> enableLegacyTabCompletion = new Option<>("enable legacy tab completion event compatibility", true)
.optional(true);

/**
* @deprecated This config option is no longer used and there is no replacement.
*/
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public static final Option<Boolean> keepLastUsageDates = new Option<>("keep command last usage dates", false)
.optional(true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

/**
* Utilizes CraftServer with reflection to re-send commands to clients.
* @deprecated This behavior should not be relied upon. There is no replacement.
*/
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public class CommandReloader {

@Nullable
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/ch/njol/skript/command/Argument.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
* Represents an argument of a command
*
* @author Peter Güttinger
* @deprecated There is no direct replacement for this class.
* The closest alternative is {@link org.skriptlang.skript.bukkit.command.custom.ArgumentData}.
*/
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public class Argument<T> {

@Nullable
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/ch/njol/skript/command/CommandUsage.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
/**
* Holds info about the usage of a command.
* TODO: replace with record when java 17
* @deprecated There is no direct replacement for this class.
*/
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public class CommandUsage {

/**
Expand Down
107 changes: 35 additions & 72 deletions src/main/java/ch/njol/skript/command/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.help.HelpMap;
import org.bukkit.help.HelpTopic;
Expand Down Expand Up @@ -52,10 +51,6 @@
@SuppressWarnings("deprecation")
public abstract class Commands {

public final static ArgsMessage m_too_many_arguments = new ArgsMessage("commands.too many arguments");
public final static Message m_internal_error = new Message("commands.internal error");
public final static Message m_correct_usage = new Message("commands.correct usage");

/**
* A Converter flag declaring that a Converter cannot be used for parsing command arguments.
*/
Expand Down Expand Up @@ -125,46 +120,6 @@ public static String unescape(String string) {
return "" + unescape.matcher(string).replaceAll("$0");
}

private final static Listener commandListener = new Listener() {

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
// Spigot will simply report that the command doesn't exist if a player does not have permission to use it.
// This is good security but, well, it's a breaking change for Skript. So we need to check for permissions
// ourselves and handle those messages, for every command.

// parse command, see if it's a skript command
String[] cmd = event.getMessage().substring(1).split("\\s+", 2);
String label = cmd[0].toLowerCase(Locale.ENGLISH);
String arguments = cmd.length == 1 ? "" : "" + cmd[1];
ScriptCommand command = commands.get(label);

// is it a skript command?
if (command != null) {
// if so, check permissions to handle ourselves
if (!command.checkPermissions(event.getPlayer(), label, arguments))
event.setCancelled(true);

// we can also handle case sensitivity here:
if (SkriptConfig.caseInsensitiveCommands.value()) {
cmd[0] = event.getMessage().charAt(0) + label;
event.setMessage(String.join(" ", cmd));
}
}
}

@SuppressWarnings("null")
@EventHandler(priority = EventPriority.HIGHEST)
public void onServerCommand(ServerCommandEvent event) {
if (event.getCommand().isEmpty() || event.isCancelled())
return;
if ((Skript.testing() || SkriptConfig.enableEffectCommands.value()) && event.getCommand().startsWith(SkriptConfig.effectCommandToken.value())) {
if (handleEffectCommand(event.getSender(), event.getCommand()))
event.setCancelled(true);
}
}
};

static boolean handleEffectCommand(CommandSender sender, String command) {
if (!(Skript.testing() || sender instanceof ConsoleCommandSender || sender.hasPermission("skript.effectcommands") || SkriptConfig.allowOpsToUseEffectCommands.value() && sender.isOp()))
return false;
Expand Down Expand Up @@ -278,37 +233,45 @@ public static void unregisterCommand(ScriptCommand scriptCommand) {
private static boolean registeredListeners = false;

public static void registerListeners() {
if (!registeredListeners) {
Bukkit.getPluginManager().registerEvents(commandListener, Skript.getInstance());

Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerChat(AsyncPlayerChatEvent event) {
if ((!SkriptConfig.enableEffectCommands.value() && !Skript.testing()) || !event.getMessage().startsWith(SkriptConfig.effectCommandToken.value()))
return;
if (!event.isAsynchronous()) {
if (handleEffectCommand(event.getPlayer(), event.getMessage()))
event.setCancelled(true);
} else {
Future<Boolean> f = Bukkit.getScheduler().callSyncMethod(Skript.getInstance(), () -> handleEffectCommand(event.getPlayer(), event.getMessage()));
try {
while (true) {
try {
if (f.get())
event.setCancelled(true);
break;
} catch (InterruptedException ignored) {
}
}
} catch (ExecutionException e) {
Skript.exception(e);
if (registeredListeners) {
return;
}
Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler(priority = EventPriority.HIGHEST)
public void onServerCommand(ServerCommandEvent event) {
if (event.getCommand().isEmpty() || event.isCancelled())
return;
if ((Skript.testing() || SkriptConfig.enableEffectCommands.value()) && event.getCommand().startsWith(SkriptConfig.effectCommandToken.value())) {
if (handleEffectCommand(event.getSender(), event.getCommand()))
event.setCancelled(true);
}
}

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerChat(AsyncPlayerChatEvent event) {
if ((!SkriptConfig.enableEffectCommands.value() && !Skript.testing()) || !event.getMessage().startsWith(SkriptConfig.effectCommandToken.value()))
return;
if (!event.isAsynchronous()) {
if (handleEffectCommand(event.getPlayer(), event.getMessage()))
event.setCancelled(true);
} else {
Future<Boolean> f = Bukkit.getScheduler().callSyncMethod(Skript.getInstance(), () -> handleEffectCommand(event.getPlayer(), event.getMessage()));
try {
while (true) {
try {
if (f.get())
event.setCancelled(true);
break;
} catch (InterruptedException ignored) { }
}
} catch (ExecutionException e) {
Skript.exception(e);
}
}
}, Skript.getInstance());
}
}, Skript.getInstance());

registeredListeners = true;
}
registeredListeners = true;
}

/**
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/ch/njol/skript/command/ScriptCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@

/**
* This class is used for user-defined commands.
* @deprecated There is no direct replacement for this class.
* The closest alternative is {@link org.skriptlang.skript.bukkit.command.custom.ScriptBrigadierCommand}.
*/
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public class ScriptCommand implements TabExecutor {

public final static Message m_executable_by_players = new Message("commands.executable by players");
public final static Message m_executable_by_console = new Message("commands.executable by console");
private static final String DEFAULT_PREFIX = "skript";

final String name;
Expand Down Expand Up @@ -160,7 +161,7 @@ public ScriptCommand(
label = "" + name.toLowerCase(Locale.ENGLISH);
this.permission = permission;
if (permissionMessage == null) {
VariableString defaultMsg = VariableString.newInstance(Language.get("commands.no permission message"));
VariableString defaultMsg = VariableString.newInstance("You don't have the required permission to use this command");
assert defaultMsg != null;
permissionMessage = defaultMsg;
}
Expand Down Expand Up @@ -262,12 +263,12 @@ public boolean onCommand(final @Nullable CommandSender sender, final @Nullable C
public boolean execute(final CommandSender sender, final String commandLabel, final String rest) {
if (sender instanceof Player) {
if ((executableBy & PLAYERS) == 0) {
sender.sendMessage("" + m_executable_by_console);
sender.sendMessage("This command can only be used by the console");
return false;
}
} else {
if ((executableBy & CONSOLE) == 0) {
sender.sendMessage("" + m_executable_by_players);
Comment thread
sovdeeth marked this conversation as resolved.
sender.sendMessage("This command can only be used by players");
return false;
}
}
Expand Down Expand Up @@ -332,7 +333,7 @@ public boolean execute(final CommandSender sender, final String commandLabel, fi
boolean execute2(final ScriptCommandEvent event, final CommandSender sender, final String commandLabel, final String rest) {
final ParseLogHandler log = SkriptLogger.startParseLogHandler();
try {
final boolean ok = SkriptParser.parseArguments(rest, ScriptCommand.this, event);
final boolean ok = false;
if (!ok) {
final LogEntry e = log.getError();
if (e != null)
Expand All @@ -351,7 +352,7 @@ boolean execute2(final ScriptCommandEvent event, final CommandSender sender, fin
final long startTrigger = System.nanoTime();

if (!trigger.execute(event))
sender.sendMessage(Commands.m_internal_error.toString());
sender.sendMessage("An internal error occurred while attempting to perform this command.");

if (Skript.log(Verbosity.VERY_HIGH))
Skript.info("# " + name + " took " + 1. * (System.nanoTime() - startTrigger) / 1000000. + " milliseconds");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.skriptlang.skript.bukkit.command.custom.ScriptCommandExecutionEvent;

/**
* @deprecated There is no direct replacement for this class.
* The closest alternative is {@link ScriptCommandExecutionEvent}.
*/
@Deprecated(since = "INSERT VERSION", forRemoval = true)
public class ScriptCommandEvent extends CommandEvent {

private final ScriptCommand scriptCommand;
Expand Down
24 changes: 0 additions & 24 deletions src/main/java/ch/njol/skript/command/package-info.java
Original file line number Diff line number Diff line change
@@ -1,25 +1 @@
/**
* 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
*/
/**
* Code related to handling commands, either Skript commands or custom script commands.
*
* @author Peter Güttinger
*/
package ch.njol.skript.command;

Loading
Loading