{
\ No newline at end of file
diff --git a/docs/en/create-commands/registration.md b/docs/en/create-commands/registration.md
index 48bf6e49..293c18df 100644
--- a/docs/en/create-commands/registration.md
+++ b/docs/en/create-commands/registration.md
@@ -1,5 +1,6 @@
---
order: 1
+preferences: ["paper-spigot"]
authors:
- DerEchtePilz
- willkroboth
@@ -202,11 +203,22 @@ Register the command with the provided plugin's name.
## Command loading order
-It is recommended to register commands in either the `onLoad()` or `onEnable()` method. With the CommandAPI, depending on whether you use `onLoad()` or `onEnable()` to load your commands depends on whether your plugin is used with Minecraft's functions:
+Places where you can register commands are listed below:
-| When to load | What to do |
-|---------------------|--------------------------------------------------------------------------------------------------------------------------------|
-| `onLoad()` method | Register commands to be used in Minecraft functions ([see the Function section for more info](./functions-and-tags/functions)) |
-| `onEnable()` method | Register regular commands |
+
-The CommandAPI does support registering commands outside of these methods while the server is running. Commands registered after the server is done loading _should_ work the same as commands registered in `onEnable`.
+| When to load | What to do |
+|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
+| `bootstrap(BootstrapContext)` method | Register commands to be used in Minecraft functions ([see the Function section for more info](./functions-and-tags/functions)) |
+| `onLoad()`/`onEnable()` method | Register regular commands not available in datapacks by default |
+
+
+
+
+| When to load | What to do |
+|--------------------------------|-----------------------------------------------------------------|
+| `onLoad()`/`onEnable()` method | Register regular commands not available in datapacks by default |
+
+
+
+The CommandAPI does support registering commands outside of these methods while the server is running. Commands registered after the server is done loading _should_ work the same as commands registered in `onLoad()`/`onEnable()`.
diff --git a/docs/en/create-commands/unregistration.md b/docs/en/create-commands/unregistration.md
index 2a8fe0f7..b795fd7f 100644
--- a/docs/en/create-commands/unregistration.md
+++ b/docs/en/create-commands/unregistration.md
@@ -1,6 +1,8 @@
---
order: 2
+preferences: ["paper-spigot"]
authors:
+ - DerEchtePilz
- willkroboth
- MC-XiaoHei
---
@@ -17,7 +19,32 @@ CommandAPI.unregister(String commandName, boolean unregisterNamespaces);
CommandAPIBukkit.unregister(String commandName, boolean unregisterNamespaces, boolean unregisterBukkit);
```
-To understand when and how to use these methods, you need to know a little about how Bukkit loads and sets up commands. This is basically the order of events when a Bukkit server starts:
+
+
+To understand when and how to use these methods, you need to know a little about how Paper loads and sets up commands. This is basically the order of events when a Paper server starts:
+
+1. Plugins are initialized
+ - `PluginBootstrap#boostrap(BootstrapContext)` is called
+2. Vanilla commands are registered
+3. Lifecycle events for the bootstrap stage are executed
+4. Bukkit commands are placed in the Bukkit CommandMap
+ - Given the `bukkit` namespace
+5. Plugins are loaded
+ - `onLoad()` is called
+6. Plugins are enabled
+ - If a plugin uses it, then
+ - Plugin commands are read from the [`plugin.yml` file](https://www.spigotmc.org/wiki/plugin-yml/#commands) and placed in the Bukkit CommandMap
+ - Given the plugin's name as their namespace (e.g. `luckperms:lp`)
+ - `onEnable` is called
+ - Repeat for each plugin
+7. Bukkit's help command is registered
+8. Lifecycle events for the plugin stage are executed
+9. The server is done loading
+
+
+
+
+To understand when and how to use these methods, you need to know a little about how Spigot loads and sets up commands. This is basically the order of events when a Spigot server starts:
1. Vanilla commands are placed in the Vanilla CommandDispatcher
2. Bukkit commands are placed in the Bukkit CommandMap
@@ -34,6 +61,8 @@ To understand when and how to use these methods, you need to know a little about
- Given the `minecraft` namespace (e.g. `minecraft:gamemode`)
7. The server is done loading
+
+
Unregistering a command only works if it happens after the command is created. Bukkit's command system is special and has two locations where commands can exist -- either the Vanilla CommandDispatcher or the Bukkit CommandMap -- so you also need to know where your command is registered. With that in mind, here is what each of the `unregister` methods do:
```java
@@ -56,57 +85,133 @@ Unregisters a command from Bukkit. As before, if `unregisterNamespaces` is `true
To give a better idea of how and when to use these methods, the rest of this page documents how to unregister different types of commands.
+
+
+::::tip Developer's Note:
+But first, let's take a look at where the CommandAPI registers commands. While you are able to call the `register()` method basically anywhere (as mentioned on the [registration page](registration.md#command-loading-order)), CommandAPI commands
+are only actually registered in two places: step 3 and step 8 of the loading sequence above.
+
+Step 3 applies if you register commands in a bootstrap context which may look something like this:
+
+:::tabs
+===Java
+<<< @/../reference-code/paper/src/main/java/createcommands/Unregistration.java#registerBootstrapExample
+===Kotlin
+<<< @/../reference-code/paper/src/main/kotlin/createcommands/Unregistration.kt#registerBootstrapExample
+:::
+
+Note that the `CommandAPI#onLoad(CommandAPIConfig)` call is now in the `bootstrap` method.
+
+Step 8 applies if you register commands in the `JavaPlugin#onLoad()` or the `JavaPlugin#onEnable()` methods.
+
+Similarly, unregistrations are also handled in a lifecycle event which runs after the events that register commands.
+
+::::
+
+
+
## Unregistering a Bukkit command - `/version`
+
+
+:::tip Developer's Note:
+Paper has recently converted some commands that were Bukkit commands before to Brigadier commands. This includes the `/version` command. For demonstration's sake we'll assume it is still a Bukkit command (which still does apply to some versions).
+:::
+
+`/version` is a command provided by Bukkit. Looking at the sequence of events above, that means it is created during step 4, before plugins are loaded in step 5. Consequently, the command will exist when the unregistration event is ran after step 8. Here we'll unregister the command in `onLoad`, but the same would work in `onEnable` too.
+
+
+
+
`/version` is a command provided by Bukkit. Looking at the sequence of events above, that means it is created during step 2, before plugins are loaded in step 3. Consequently, the command will exist when our plugin's `onLoad` method is called, so we'll unregister it there. The same code will work in `onEnable` too, since step 4 is also after step 2.
+
+
Since this command exists in the Bukkit CommandMap, we'll need to use `CommandAPIBukkit#unregister` with `unregisterBukkit` set to `true`. We'll also remove the namespaced version -- `/bukkit:version` -- so `unregisterNamespaces` will be `true`. All together, the code looks like this:
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterBukkitExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterBukkitExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterBukkitExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterBukkitExample
:::
With this plugin, executing `/version` or `/bukkit:version` will give the unknown command message. Note that aliases like `/ver` and its namespaced version `/bukkit:ver` will still work. To remove aliases as well, you need to unregister each as its own command. For, `/ver`, that would mean calling `CommandAPIBukkit.unregister("ver", true, true)`.
## Unregistering a Vanilla command - `/gamemode`
+
+
+`/gamemode` is a command provided by Vanilla Minecraft. Like the [previous example](#unregistering-a-bukkit-command-version), Vanilla commands are created in step 2, before lifecycle events for the bootstrap stage are ran and plugins are loaded in step 5. For variety, we'll unregister the command in our plugin's `onEnable` -- step 6 -- but the same code would also work in `onLoad`.
+
+
+
+
`/gamemode` is a command provided by Vanilla Minecraft. Like the [previous example](#unregistering-a-bukkit-command-version), Vanilla commands are created in step 1, before plugins are loaded in step 3. For variety, we'll unregister the command in our plugin's `onEnable` -- step 4 -- but the same code would also work in `onLoad`.
+
+
Since this command exists in the Vanilla CommandDispatcher, we can use `CommandAPI#unregister`. That works the same as `CommandAPIBukkit#unregister` with `unregisterBukkit` set to `false`. We don't care about the namespace, so `unregisterNamespaces` will be `false`. That means we can use the simplest method, `CommandAPI.unregister(String commandName)`, since it sets `unregisterNamespaces` to `false` by default. All together, the code looks like this:
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterVanillaExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterVanillaExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterVanillaExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterVanillaExample
:::
+
+
With this code, executing `/gamemode` will give the unknown command exception as expected. However, even though `unregisterNamespaces` was `false`, `/minecraft:gamemode` can also not be run. This happens because Vanilla commands are given their namespace in step 6, after our plugin has removed `/gamemode`.
When the server starts, `/gamemode` is created in step 2 inside the Vanilla CommandDispatcher. In step 4, our plugin is enabled and we remove the `/gamemode` command from that CommandDispatcher. After all the plugins enable, step 6 moves all commands in the Vanilla CommandDispatcher to the Bukkit CommandMap and gives them the `minecraft` namespace. Since `/gamemode` doesn't exist at this point, step 6 cannot create the `/minecraft:gamemode` command. So, even though `unregisterNamespaces` was `false`, `/minecraft:gamemode` doesn't exist anyway.
+
+
::::tip Example - Replacing Minecraft's `/gamemode` command
+
+
+To replace a command, simply register a new implementation for that command. Any attempts to unregister first will result in the new implementation to also not be present.
+
+:::tabs
+===Java
+<<< @/../reference-code/paper/src/main/java/createcommands/Unregistration.java#unregisterVanillaAndReplaceExample
+===Kotlin
+<<< @/../reference-code/paper/src/main/kotlin/createcommands/Unregistration.kt#unregisterVanillaAndReplaceExample
+:::
+
+
+
+
To replace a command, first unregister the original command, then register a new implementation for that command.
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterVanillaAndReplaceExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterVanillaAndReplaceExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterVanillaAndReplaceExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterVanillaAndReplaceExample
:::
+
+
Now, when `/gamemode` is executed, it will use the new implementation defined using the CommandAPI.
::::
## Unregistering a Plugin command - `/luckperms:luckperms`
+
+
+The `/luckperms` command is provided by the Bukkit [LuckPerms](https://luckperms.net/) plugin. Plugin commands are created during step 6, immediately before calling the `onEnable` method of the respective plugin. Since unregistrations run after step 8, it does not matter where we unregister, however here we choose to do it in the `onEnable`. We also have to make sure that our plugin is loaded after LuckPerms. The best way to make sure that happens is to add LuckPerms as a `depend` or `softdepend` in our plugin's plugin.yml. You can read more about the different between `depend` and `softdepend` in [Spigot's documentation](https://www.spigotmc.org/wiki/plugin-yml/#optional-attributes), but that will look something like this:
+
+
+
+
The `/luckperms` command is provided by the Bukkit [LuckPerms](https://luckperms.net/) plugin. Plugin commands are created during step 4, immediately before calling the `onEnable` method of the respective plugin. In this case, unregistering the command in our own plugin's `onLoad` would not work, since the command wouldn't exist yet. We also have to make sure that our `onEnable` method is called after LuckPerm's. The best way to make sure that happens is to add LuckPerms as a `depend` or `softdepend` in our plugin's plugin.yml. You can read more about the different between `depend` and `softdepend` in [Spigot's documentation](https://www.spigotmc.org/wiki/plugin-yml/#optional-attributes), but that will look something like this:
+
+
```yaml
name: MyPlugin
main: some.package.name.Main
@@ -119,15 +224,24 @@ Since plugin commands are stored in the Bukkit CommandMap, we need to use `Comma
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterPluginExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterPluginExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterPluginExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterPluginExample
:::
Executing `/luckperms` will work as normal, but `/luckperms:luckperms` will give the unknown command message.
## Unregistering a CommandAPI command
+
+
+Unregistering a command created by the CommandAPI is easy.
+
+For our example, let's say we want to unregister the `/break` command created by the [Bukkit Maven Example Project](https://github.com/CommandAPI/CommandAPI/tree/master/examples/bukkit/maven) for the CommandAPI.
+
+
+
+
Unregistering a command created by the CommandAPI is similar to both unregistering a Vanilla command and a plugin command. Like a Vanilla command, CommandAPI commands are stored in the Vanilla CommandDispatcher, so they should be unregistered with `unregisterBukkit` set to `false`. Like plugin commands, they may be created in `onEnable`, so you need to make sure your plugin is enabled after the plugin that adds the command.
Unlike plugin commands, CommandAPI commands may be created in `onLoad`, as discussed in [Command loading order](./registration#command-loading-order). That just means you may also be able to unregister the command in you own plugin's `onLoad`. As always, simply make sure you unregister a command after it is created, and it will be removed properly.
@@ -162,15 +276,19 @@ You can see that the ExamplePlugin registers its commands when `onEnable` is cal
In summary, we will unregister the `/break` command in our plugin's `onEnable`. We added Example plugin to the `depend` list in our plugin.yml so that our `onEnable` method runs second. `unregisterNamespaces` and `unregisterBukkit` will be set to `false`, and those are the default values, so we can simply use `CommandAPI.unregister(String commandName)`. All together, the code looks like this:
+
+
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterCommandAPIExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterCommandAPIExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterCommandAPIExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterCommandAPIExample
:::
Now, when you try to execute `/break`, you will just get the unknown command message as if it never existed.
+
+
## Special case: Unregistering Bukkit's `/help`
If you look at the sequence of events at the top of this page, you might notice that Bukkit's `/help` command gets its own place in step 5. Unlike the other [Bukkit commands](#unregistering-a-bukkit-command-version), `/help` is special and gets registered after plugins are loaded and enabled (don't ask, I don't know why :P). That means unregistering `/help` in `onLoad` or `onEnable` does not work, since the command doesn't exist yet.
@@ -181,9 +299,9 @@ Since `/help` is in the Bukkit CommandMap, we need to use `CommandAPIBukkit#unre
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterBukkitHelpExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterBukkitHelpExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterBukkitHelpExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterBukkitHelpExample
:::
Funnily, if you try to execute `/help`, the server will still tell you: `Unknown command. Type "/help" for help.`. Luckily, `unregisterNamespaces` was `false`, so you can still use `/bukkit:help` to figure out your problem.
@@ -200,9 +318,9 @@ Finally, `unregisterNamespaces` should be `false`, and since that's the default
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterVanillaNamespaceOnlyExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterVanillaNamespaceOnlyExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterVanillaNamespaceOnlyExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterVanillaNamespaceOnlyExample
:::
With this code, `/gamemode` will execute as normal, but `/minecraft:gamemode` will give the unknown command message.
@@ -213,9 +331,9 @@ Doing the opposite action here -- only unregistering `/gamemode` but keeping `/m
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterDelayedVanillaBadExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterDelayedVanillaBadExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterDelayedVanillaBadExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterDelayedVanillaBadExample
:::
The expected outcome of this code is that `/minecraft:gamemode` would work as expected, and `/gamemode` would give the command not found message. However, that is only true for the player's commands. If you try to use `/minecraft:gamemode` in the console, it *will not work* properly. Specifically, while you can tab-complete the command's label, `minecraft:gamemode` the command's arguments will not have any suggestions. If you try to execute `/minecraft:gamemode` in the console, it will always tell you your command is unknown or incomplete.
@@ -224,9 +342,11 @@ The main point is that if you ever try to unregister a Vanilla command after the
:::tabs
===Java
-<<< @/../reference-code/bukkit/src/main/java/createcommands/Unregistration.java#unregisterDelayedVanillaGoodExample
+<<< @/../reference-code/spigot/src/main/java/createcommands/Unregistration.java#unregisterDelayedVanillaGoodExample
===Kotlin
-<<< @/../reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt#unregisterDelayedVanillaGoodExample
+<<< @/../reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt#unregisterDelayedVanillaGoodExample
:::
-::::
\ No newline at end of file
+::::
+
+
\ No newline at end of file
diff --git a/reference-code/paper/src/main/java/createcommands/Unregistration.java b/reference-code/paper/src/main/java/createcommands/Unregistration.java
new file mode 100644
index 00000000..2d493403
--- /dev/null
+++ b/reference-code/paper/src/main/java/createcommands/Unregistration.java
@@ -0,0 +1,137 @@
+package createcommands;
+
+import dev.jorel.commandapi.CommandAPI;
+import dev.jorel.commandapi.CommandAPIBukkit;
+import dev.jorel.commandapi.CommandAPICommand;
+import dev.jorel.commandapi.CommandAPIPaperConfig;
+import dev.jorel.commandapi.arguments.MultiLiteralArgument;
+import io.papermc.paper.plugin.bootstrap.BootstrapContext;
+import io.papermc.paper.plugin.bootstrap.PluginBootstrap;
+import net.kyori.adventure.text.Component;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.jetbrains.annotations.NotNull;
+
+class Unregistration {
+
+ // #region registerBootstrapExample
+ public class MyPluginBootstrap implements PluginBootstrap {
+
+ @Override
+ public void bootstrap(@NotNull BootstrapContext context) {
+ CommandAPI.onLoad(new CommandAPIPaperConfig<>(context.getPluginMeta(), context));
+
+ new CommandAPICommand("inbootstrap")
+ .executes((sender, args) -> {
+ sender.sendMessage(Component.text("This command is registed in step 3!"));
+ })
+ .register();
+ }
+ }
+ // #endregion registerBootstrapExample
+
+ {
+ new JavaPlugin() {
+ // #region unregisterBukkitExample
+ @Override
+ public void onLoad() {
+ CommandAPIBukkit.unregister("version", true, true);
+ }
+ // #endregion unregisterBukkitExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterVanillaExample
+ @Override
+ public void onEnable() {
+ CommandAPI.unregister("gamemode");
+ }
+ // #endregion unregisterVanillaExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterVanillaAndReplaceExample
+ @Override
+ public void onEnable() {
+ // Register our new /gamemode, with survival, creative, adventure and spectator
+ new CommandAPICommand("gamemode")
+ .withArguments(new MultiLiteralArgument("gamemodes", "survival", "creative", "adventure", "spectator"))
+ .executes((sender, args) -> {
+ // Implementation of our /gamemode command
+ })
+ .register();
+ }
+ // #endregion unregisterVanillaAndReplaceExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterPluginExample
+ @Override
+ public void onEnable() {
+ CommandAPIBukkit.unregister("luckperms:luckperms", false, true);
+ }
+ // #endregion unregisterPluginExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterCommandAPIExample
+ @Override
+ public void onEnable() {
+ CommandAPI.unregister("break");
+ }
+ // #endregion unregisterCommandAPIExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterBukkitHelpExample
+ @Override
+ public void onEnable() {
+ CommandAPIBukkit.unregister("help", false, true);
+ }
+ // #endregion unregisterBukkitHelpExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterVanillaNamespaceOnlyExample
+ @Override
+ public void onEnable() {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ CommandAPI.unregister("minecraft:gamemode");
+ }
+ }.runTaskLater(this, 0);
+ }
+ // #endregion unregisterVanillaNamespaceOnlyExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterDelayedVanillaBadExample
+ // NOT RECOMMENDED
+ @Override
+ public void onEnable() {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ CommandAPI.unregister("gamemode");
+ }
+ }.runTaskLater(this, 0);
+ }
+ // #endregion unregisterDelayedVanillaBadExample
+ };
+
+ new JavaPlugin() {
+ // #region unregisterDelayedVanillaGoodExample
+ @Override
+ public void onEnable() {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ CommandAPI.unregister("gamemode", true);
+ }
+ }.runTaskLater(this, 0);
+ }
+ // #endregion unregisterDelayedVanillaGoodExample
+ };
+ }
+}
diff --git a/reference-code/paper/src/main/kotlin/createcommands/Unregistration.kt b/reference-code/paper/src/main/kotlin/createcommands/Unregistration.kt
new file mode 100644
index 00000000..783580ee
--- /dev/null
+++ b/reference-code/paper/src/main/kotlin/createcommands/Unregistration.kt
@@ -0,0 +1,122 @@
+package createcommands
+
+import dev.jorel.commandapi.CommandAPI
+import dev.jorel.commandapi.CommandAPIBukkit
+import dev.jorel.commandapi.CommandAPICommand
+import dev.jorel.commandapi.CommandAPIPaperConfig
+import dev.jorel.commandapi.arguments.MultiLiteralArgument
+import dev.jorel.commandapi.executors.CommandExecutor
+import io.papermc.paper.plugin.bootstrap.BootstrapContext
+import io.papermc.paper.plugin.bootstrap.PluginBootstrap
+import net.kyori.adventure.text.Component
+import org.bukkit.plugin.java.JavaPlugin
+import org.bukkit.scheduler.BukkitRunnable
+
+class UnregistrationKT {
+
+ // #region registerBootstrapExample
+ class MyPluginBootstrap : PluginBootstrap {
+
+ override fun bootstrap(context: BootstrapContext) {
+ CommandAPI.onLoad(CommandAPIPaperConfig(context.pluginMeta, context))
+
+ CommandAPICommand("inbootstrap")
+ .executes(CommandExecutor { sender, _ ->
+ sender.sendMessage(Component.text("This command is registed in step 3!"))
+ })
+ .register()
+ }
+ }
+ // #endregion registerBootstrapExample
+
+ class A : JavaPlugin() {
+ // #region unregisterBukkitExample
+ override fun onLoad() {
+ CommandAPIBukkit.unregister("version", true, true)
+ }
+ // #endregion unregisterBukkitExample
+ }
+
+ class B : JavaPlugin() {
+ // #region unregisterVanillaExample
+ override fun onEnable() {
+ CommandAPI.unregister("gamemode")
+ }
+ // #endregion unregisterVanillaExample
+ }
+
+ class C : JavaPlugin() {
+ // #region unregisterVanillaAndReplaceExample
+ override fun onEnable() {
+ // Register our new /gamemode, with survival, creative, adventure and spectator
+ CommandAPICommand("gamemode")
+ .withArguments(MultiLiteralArgument("gamemodes", "survival", "creative", "adventure", "spectator"))
+ .executes(CommandExecutor { sender, args ->
+ // Implementation of our /gamemode command
+ })
+ .register()
+ }
+ // #endregion unregisterVanillaAndReplaceExample
+ }
+
+ class D : JavaPlugin() {
+ // #region unregisterPluginExample
+ override fun onEnable() {
+ CommandAPIBukkit.unregister("luckperms:luckperms", false, true)
+ }
+ // #endregion unregisterPluginExample
+ }
+
+ class E : JavaPlugin() {
+ // #region unregisterCommandAPIExample
+ override fun onEnable() {
+ CommandAPI.unregister("break")
+ }
+ // #endregion unregisterCommandAPIExample
+ }
+
+ class F : JavaPlugin() {
+ // #region unregisterBukkitHelpExample
+ override fun onEnable() {
+ CommandAPIBukkit.unregister("help", false, true)
+ }
+ // #endregion unregisterBukkitHelpExample
+ }
+
+ class G : JavaPlugin() {
+ // #region unregisterVanillaNamespaceOnlyExample
+ override fun onEnable() {
+ object : BukkitRunnable() {
+ override fun run() {
+ CommandAPI.unregister("minecraft:gamemode")
+ }
+ }.runTaskLater(this, 0)
+ }
+ // #endregion unregisterVanillaNamespaceOnlyExample
+ }
+
+ class H : JavaPlugin() {
+ // #region unregisterDelayedVanillaBadExample
+ // NOT RECOMMENDED
+ override fun onEnable() {
+ object : BukkitRunnable() {
+ override fun run() {
+ CommandAPI.unregister("gamemode")
+ }
+ }.runTaskLater(this, 0)
+ }
+ // #endregion unregisterDelayedVanillaBadExample
+ }
+
+ class I : JavaPlugin() {
+ // #region unregisterDelayedVanillaGoodExample
+ override fun onEnable() {
+ object : BukkitRunnable() {
+ override fun run() {
+ CommandAPI.unregister("gamemode", true)
+ }
+ }.runTaskLater(this, 0)
+ }
+ // #endregion unregisterDelayedVanillaGoodExample
+ }
+}
\ No newline at end of file
diff --git a/reference-code/bukkit/src/main/java/createcommands/Unregistration.java b/reference-code/spigot/src/main/java/createcommands/Unregistration.java
similarity index 100%
rename from reference-code/bukkit/src/main/java/createcommands/Unregistration.java
rename to reference-code/spigot/src/main/java/createcommands/Unregistration.java
diff --git a/reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt b/reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt
similarity index 100%
rename from reference-code/bukkit/src/main/kotlin/createcommands/Unregistration.kt
rename to reference-code/spigot/src/main/kotlin/createcommands/Unregistration.kt
From 2873d18c918f330e039fd1f756e38840172aa27a Mon Sep 17 00:00:00 2001
From: DerEchtePilz <81232921+DerEchtePilz@users.noreply.github.com>
Date: Wed, 24 Sep 2025 15:29:51 +0200
Subject: [PATCH 23/33] Start dealing with the code review
- Functions page needs a rewrite
- The IntegerRange/DoubleRange argument page needs a new screenshot
- Apparently there might be some rendering issues with the diff on the upgrade page to 11.0.0?
---
.../arguments/suggestions/safe-suggestions.md | 10 +--
.../arguments/types/ranged-arguments.md | 2 +-
docs/en/create-commands/registration.md | 2 +-
docs/en/dev-setup/shading.md | 75 ++++++++++---------
docs/en/internal/internal.md | 4 +-
docs/en/upgrading-parts/10.1.2-to-11.0.0.md | 2 +-
update.sh | 2 +-
7 files changed, 52 insertions(+), 45 deletions(-)
diff --git a/docs/en/create-commands/arguments/suggestions/safe-suggestions.md b/docs/en/create-commands/arguments/suggestions/safe-suggestions.md
index ae364f1e..314b0510 100644
--- a/docs/en/create-commands/arguments/suggestions/safe-suggestions.md
+++ b/docs/en/create-commands/arguments/suggestions/safe-suggestions.md
@@ -51,16 +51,16 @@ The list of supported arguments are displayed in the following table. The parame
| [`AxisArgument`](../types/position/axis-arguments) | `java.util.EnumSet` |
| [`BiomeArgument`](../types/misc/biome-arguments) | `org.bukkit.block.Biome` |
| [`BooleanArgument`](../types/primitive-arguments) | **`Boolean`** |
-| [`ChatColorArgument`](../types/chat/spigot-chat-arguments#chat-color-argument) | `org.bukkit.ChatColor` |
+| [`ChatColorArgument`](../types/chat/spigot-chat-arguments#chat-color-argument) | `net.kyori.adventure.text.format.NamedTextColor` |
| [`DoubleArgument`](../types/primitive-arguments#numerical-arguments) | **`Double`** |
+| [`DoubleRangeArgument`](../types/ranged-arguments#the-integer-range-and-double-range-class) | `dev.jorel.commandapi.wrappers.DoubleRange` |
| [`EnchantmentArgument`](../types/misc/enchantment-arguments) | `org.bukkit.enchantments.Enchantment` |
| [`EntityTypeArgument`](../types/entities-arguments#entity-type-argument) | `org.bukkit.entity.EntityType` |
| [`FloatArgument`](../types/primitive-arguments#numerical-arguments) | **`Float`** |
-| [`FloatRangeArgument`](../types/ranged-arguments#the-integerrange--floatrange-class) | `dev.jorel.commandapi.wrappers.FloatRange` |
| [`FunctionArgument`](../../functions-and-tags/function-arguments) | **`org.bukkit.NamespacedKey`** |
| [`GreedyStringArgument`](../types/string-arguments#greedy-string-argument) | `String` |
| [`IntegerArgument`](../types/primitive-arguments#numerical-arguments) | **`Integer`** |
-| [`IntegerRangeArgument`](../types/ranged-arguments#the-integerrange--floatrange-class) | `dev.jorel.commandapi.wrappers.IntegerRange` |
+| [`IntegerRangeArgument`](../types/ranged-arguments#the-integer-range-and-double-range-class) | `dev.jorel.commandapi.wrappers.IntegerRange` |
| [`ItemStackArgument`](../types/misc/itemstack-arguments) | `org.bukkit.inventory.ItemStack` |
| [`Location2DArgument`](../types/position/location-arguments#2d-location) | `dev.jorel.commandapi.wrappers.Location2D` |
| [`LocationArgument`](../types/position/location-arguments#3d-location) | `org.bukkit.Location` |
@@ -91,14 +91,14 @@ The list of supported arguments are displayed in the following table. The parame
| [`BooleanArgument`](../types/primitive-arguments) | **`Boolean`** |
| [`ChatColorArgument`](../types/chat/spigot-chat-arguments#chat-color-argument) | `org.bukkit.ChatColor` |
| [`DoubleArgument`](../types/primitive-arguments#numerical-arguments) | **`Double`** |
+| [`DoubleRangeArgument`](../types/ranged-arguments#the-integer-range-and-double-range-class) | `dev.jorel.commandapi.wrappers.DoubleRange` |
| [`EnchantmentArgument`](../types/misc/enchantment-arguments) | `org.bukkit.enchantments.Enchantment` |
| [`EntityTypeArgument`](../types/entities-arguments#entity-type-argument) | `org.bukkit.entity.EntityType` |
| [`FloatArgument`](../types/primitive-arguments#numerical-arguments) | **`Float`** |
-| [`FloatRangeArgument`](../types/ranged-arguments#the-integerrange--floatrange-class) | `dev.jorel.commandapi.wrappers.FloatRange` |
| [`FunctionArgument`](../../functions-and-tags/function-arguments) | **`org.bukkit.NamespacedKey`** |
| [`GreedyStringArgument`](../types/string-arguments#greedy-string-argument) | `String` |
| [`IntegerArgument`](../types/primitive-arguments#numerical-arguments) | **`Integer`** |
-| [`IntegerRangeArgument`](../types/ranged-arguments#the-integerrange--floatrange-class) | `dev.jorel.commandapi.wrappers.IntegerRange` |
+| [`IntegerRangeArgument`](../types/ranged-arguments#the-integer-range-and-double-range-class) | `dev.jorel.commandapi.wrappers.IntegerRange` |
| [`ItemStackArgument`](../types/misc/itemstack-arguments) | `org.bukkit.inventory.ItemStack` |
| [`Location2DArgument`](../types/position/location-arguments#2d-location) | `dev.jorel.commandapi.wrappers.Location2D` |
| [`LocationArgument`](../types/position/location-arguments#3d-location) | `org.bukkit.Location` |
diff --git a/docs/en/create-commands/arguments/types/ranged-arguments.md b/docs/en/create-commands/arguments/types/ranged-arguments.md
index 7c94b932..973b5594 100644
--- a/docs/en/create-commands/arguments/types/ranged-arguments.md
+++ b/docs/en/create-commands/arguments/types/ranged-arguments.md
@@ -43,7 +43,7 @@ The `DoubleRange` class has the following methods:
class DoubleRange {
public double getLowerBound();
public double getUpperBound();
- public boolean isInRange(float);
+ public boolean isInRange(double);
}
```
diff --git a/docs/en/create-commands/registration.md b/docs/en/create-commands/registration.md
index 293c18df..44d09cc8 100644
--- a/docs/en/create-commands/registration.md
+++ b/docs/en/create-commands/registration.md
@@ -210,7 +210,7 @@ Places where you can register commands are listed below:
| When to load | What to do |
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|
| `bootstrap(BootstrapContext)` method | Register commands to be used in Minecraft functions ([see the Function section for more info](./functions-and-tags/functions)) |
-| `onLoad()`/`onEnable()` method | Register regular commands not available in datapacks by default |
+| `onLoad()`/`onEnable()` method | Register regular commands not available in datapacks |