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 support for custom namespaces for commands #509
Conversation
commandapi-core/src/main/java/dev/jorel/commandapi/AbstractCommandAPICommand.java
Outdated
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/AbstractCommandAPICommand.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit-nms/commandapi-bukkit-1.15/src/main/java/dev/jorel/commandapi/nms/NMS_1_15.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit-nms/commandapi-bukkit-1.15/src/main/java/dev/jorel/commandapi/nms/NMS_1_15.java
Outdated
Show resolved
Hide resolved
I have a suggestion on how to make this work with Velocity. It requires changing the structure a bit, but I think it can also make the system simpler on Bukkit. Velocity doesn't do anything to generate namespaces itself and it only uses one @Override
public LiteralCommandNode<CommandSource> registerCommandNode(LiteralArgumentBuilder<CommandSource> node, String namespace) {
LiteralCommandNode<CommandSource> builtNode = getBrigadierDispatcher().register(node);
getBrigadierDispatcher().register(LiteralArgumentBuilder.<CommandSource>literal(namespace + ":" + node.getLiteral()).redirect(builtNode));
return builtNode;
} On Bukkit, the same thing should work. We could create the namespaced versions inside the vanilla List<String> namespacesToFix = new ArrayList<>();
@Override
public LiteralCommandNode<Source> registerCommandNode(LiteralArgumentBuilder<Source> node, String namespace) {
LiteralCommandNode<Source> builtNode = getBrigadierDispatcher().register(node);
if(!namespace.equals("minecraft")) {
String name = node.getLiteral();
String namespacedName = namespace + ":" + name;
getBrigadierDispatcher().register(LiteralArgumentBuilder.<Source>literal(namespacedName).redirect(builtNode));
namespacesToFix.add("minecraft:" + name);
namespacesToFix.add("minecraft:" + namespacedName);
}
return builtNode;
}
private void setupNamespaces() {
Map<String, Command> knownCommands = commandMapKnownCommands.get((SimpleCommandMap) paper.getCommandMap());
CommandDispatcher<Source> resourcesDispatcher = getResourcesDispatcher();
for (String command : namespacesToFix) {
knownCommands.remove(command);
removeBrigadierCommands(resourcesDispatcher, command, false, c -> true);
}
} Here, I can't test this myself right now, but I think it should work. I think other platforms should be a lot more like Velocity, with only one |
In fact, I did what unregisterInternal does. I double checked any mistakes I may have made. It didn't work until I called syncCommands. |
Ah, I think the one detail missing from Lines 594 to 598 in 38a1a76
... which uses these functions: Lines 611 to 650 in 38a1a76
The important thing happening there is that commands are being removed from what I call the "resources dispatcher". Bukkit copies commands from the vanilla The If you do want to avoid calling Lines 392 to 402 in caad9b3
It's probably fine since |
Oh, I see. Also, does Velocity even have namespaces? Commands with namespaces are a Bukkit concept as Brigadier doesn't really know about them. As Velocity is its own project, does it have namespaces? I also briefly tried to get a Velocity plugin's name but couldn't find a way... |
Yeah, currently, Velocity commands do not have namespaces. Since it's just a proxy, it doesn't include Minecraft server commands like Bukkit does, so I guess they didn't bother with automatically assigning Velocity plugins do have IDs (see https://docs.papermc.io/velocity/dev/api-basics#create-the-plugin-class), which would make sense as the namespace to use for a Velocity Plugin. It looks like you can get that ID given a plugin object with something like this: CommandAPIVelocity.getConfiguration().getServer().getPluginManager().fromInstance(/* Plugin object here */).get().getDescription().getId(); |
So this is basically done. I need to test compatibility with #417 because when I read it I got worried it would only work with a @willkroboth Would be great if you'd review this, after all you made this issue #367 and probably had an idea how it could work. |
commandapi-core/src/main/java/dev/jorel/commandapi/AbstractCommandAPICommand.java
Outdated
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/AbstractCommandAPICommand.java
Outdated
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/AbstractCommandAPICommand.java
Show resolved
Hide resolved
...dapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPICommand.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkit.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit-nms/commandapi-bukkit-1.15/src/main/java/dev/jorel/commandapi/nms/NMS_1_15.java
Outdated
Show resolved
Hide resolved
...-bukkit-nms/commandapi-bukkit-1.16.1/src/main/java/dev/jorel/commandapi/nms/NMS_1_16_R1.java
Outdated
Show resolved
Hide resolved
...ndapi-sponge/commandapi-sponge-core/src/main/java/dev/jorel/commandapi/CommandAPISponge.java
Outdated
Show resolved
Hide resolved
...ndapi-velocity-kotlin/src/main/kotlin/dev/jorel/commandapi/kotlindsl/CommandAPICommandDSL.kt
Show resolved
Hide resolved
So, this is done. If there's nothing else, we could even say we still put this into 9.3.0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should definitely add some tests before merging. All the ways of setting namespaces should work. Two commands registered with different namespaces also shouldn't conflict.
Everything should also work the same once these lines are called to simulate the server finishing enabling:
disablePaperImplementations();
assertDoesNotThrow(() -> server.getScheduler().performOneTick());
We should make sure the namespace logic that is triggered after the server is enabled works the same as before enabling. The minecraft:
version of commands should also be properly removed from the CommandMap
and resources dispatcher.
Those tests can probably be added to CommandRegistrationTests
and OnEnableTests
. I'd be happy to figure out the OnEnableTests
, mostly because they're a big mess that I should probably clean up anyway.
commandapi-core/src/main/java/dev/jorel/commandapi/CommandAPIHandler.java
Outdated
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/ExecutableCommand.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkit.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkit.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkit.java
Outdated
Show resolved
Hide resolved
...ndapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkit.java
Outdated
Show resolved
Hide resolved
...bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkitConfig.java
Outdated
Show resolved
Hide resolved
...velocity/commandapi-velocity-core/src/main/java/dev/jorel/commandapi/CommandAPIVelocity.java
Outdated
Show resolved
Hide resolved
Cool, apparently I committed something stupid and now the tests fail. I am not gonna do this today though. |
Yeah, well, I thought about tests too. It's probably enough to simply test the registration and then whether the correct values have been removed and added by simply invoking the commands. |
e4c1317
to
977017e
Compare
c347561
to
709da8d
Compare
Alright. I now consider this feature finished. After multiple revisions started by @willkroboth pointing out mistakes I made, I am now confident in saying that this feature works now. The current caveat is that some test don't succeed but manual test have confirmed that the failing automated tests actually succeed in a real Minecraft environment. @willkroboth @JorelAli |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No major changes, just some details I noticed in the implementation and wording of various bits and pieces.
I would prefer to resolve all the disabled tests before merging. While it is probably just a problem with the testing framework and doesn't affect a real server, leaving a disabled test without an explanation indicates that we don't understand why the code we wrote is doing what it does.
commandapi-core/src/main/java/dev/jorel/commandapi/AbstractCommandAPICommand.java
Outdated
Show resolved
Hide resolved
...bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkitConfig.java
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/CommandAPIHandler.java
Outdated
Show resolved
Hide resolved
...bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkitConfig.java
Outdated
Show resolved
Hide resolved
...i-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/InternalBukkitConfig.java
Outdated
Show resolved
Hide resolved
...mandapi-bukkit-test-tests/src/test/java/dev/jorel/commandapi/test/CommandNamespaceTests.java
Outdated
Show resolved
Hide resolved
...-velocity/commandapi-velocity-core/src/main/java/dev/jorel/commandapi/CommandAPICommand.java
Outdated
Show resolved
Hide resolved
...velocity/commandapi-velocity-core/src/main/java/dev/jorel/commandapi/CommandAPIVelocity.java
Outdated
Show resolved
Hide resolved
...city/commandapi-velocity-core/src/main/java/dev/jorel/commandapi/InternalVelocityConfig.java
Outdated
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/CommandAPIHandler.java
Show resolved
Hide resolved
...velocity/commandapi-velocity-core/src/main/java/dev/jorel/commandapi/CommandAPIVelocity.java
Outdated
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/CommandAPIHandler.java
Outdated
Show resolved
Hide resolved
Part of #509 Expanded namespace+permissions tests Fixed bug where `fixPermissions` would not do anything. This happened because the `registeredPermissions` map refers to commands with their namespace, while the `registeredCommandMap` refers to commands without their namespace. So, `fixPermissions` thought all the commands were aliases and skipped everything. The fix I did removed the `registeredCommandMap` #509 (comment). Instead, all command name and permissions are kept track of in the `registeredPermissions` map. I also made some changes to the test setup, so the mocked `CraftPlayer` returned by `enableWithNamespaces` worked properly with setting and updating permissions. Note the test is not yet fully working. There is one assertion that still fails if commands are registered after the server enables. I think `CommandAPIBukkit#postCommandRegistration` is still doing something incorrect, as discussed on the CommandAPI discord https://discord.com/channels/745416925924032523/745419648970784821/1192439010132496474.
commandapi-core/src/main/java/dev/jorel/commandapi/AbstractCommandAPICommand.java
Outdated
Show resolved
Hide resolved
commandapi-core/src/main/java/dev/jorel/commandapi/CommandAPIHandler.java
Show resolved
Hide resolved
...ndapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPIBukkit.java
Outdated
Show resolved
Hide resolved
...dapi-bukkit/commandapi-bukkit-core/src/main/java/dev/jorel/commandapi/CommandAPICommand.java
Show resolved
Hide resolved
1ae6fc1
to
c7c6140
Compare
Co-authored-by: willkroboth <46540330+willkroboth@users.noreply.github.com>
Also adds a regex to only allow lowercase letters, numbers, underscores, hyphens and periods as per https://minecraft.wiki/w/Resource_location#Java_Edition
1749274
to
17e1f56
Compare
Part of #509 Expanded namespace+permissions tests Fixed bug where `fixPermissions` would not do anything. This happened because the `registeredPermissions` map refers to commands with their namespace, while the `registeredCommandMap` refers to commands without their namespace. So, `fixPermissions` thought all the commands were aliases and skipped everything. The fix I did removed the `registeredCommandMap` #509 (comment). Instead, all command name and permissions are kept track of in the `registeredPermissions` map. I also made some changes to the test setup, so the mocked `CraftPlayer` returned by `enableWithNamespaces` worked properly with setting and updating permissions. Note the test is not yet fully working. There is one assertion that still fails if commands are registered after the server enables. I think `CommandAPIBukkit#postCommandRegistration` is still doing something incorrect, as discussed on the CommandAPI discord https://discord.com/channels/745416925924032523/745419648970784821/1192439010132496474.
… minecraft namespace This makes all the tests work as expected When VanillaCommandWrappers are executed, they defer to the Brigadier dispatcher using their name. This was causing problems with permissions and conflicts when the minecraft namespace was involved. In certain cases, CommandMap commands were referencing different commands in the Brigadier dispatcher. The changes here fix all that so CommandMap commands are always referencing the correct node in the Brigadier dispatcher.
commandapi-core/src/main/java/dev/jorel/commandapi/CommandAPIHandler.java
Outdated
Show resolved
Hide resolved
I messed this up when rebasing changes from #509 into `dev/command-build-rewrite`
I messed this up when rebasing changes from #509 into `dev/command-build-rewrite`
I messed this up when rebasing changes from #509 into `dev/command-build-rewrite`
I messed this up when rebasing changes from #509 into `dev/command-build-rewrite`
I messed this up when rebasing changes from #509 into `dev/command-build-rewrite`
I messed this up when rebasing changes from #509 into `dev/command-build-rewrite`
This PR adds the ability to register commands with other namespaces than just
minecraft:
.However,
minecraft:
is still the default if no namespace is given.A bit of works still needs to be done:
CommandAPIMain.java
has to be removedNew tasks:
minecraft:
one, everything else works