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

Cache Bukkit Command when wrapping CommandNodes #11789

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

willkroboth
Copy link
Contributor

Reopens #11385.

Resolves #11378 by "restoring" the Spigot behavior where VanillaCommandNodes are only created once. Before this commit, BukkitBrigForwardingMap would create a new VanillaCommandWrapper each time a CommandNode was requested via the Bukkit CommandMap. This meant that calls to Command#setPermission would not persist between retrievals from the map.

This allows command frameworks that insert CommandNodes directly into the Brigadier dispatcher to change the permission String of the VanillaCommandNodes created for their commands, rather than it always being the default "minecraft.commands.<name>".

As discussed on the original PR, it's probably a good idea to eventually migrate the behavior of Bukkit#dispatchCommand to use Brigadier directly rather than working via the Bukkit CommandMap, which causes issues like this. Now that the hardfork is real, Paper may eventually fully remove CommandMap in favor of direct Brigadier API, which would make fixing CommandMap behavior like this PR does irrelevant. However, I feel like while Paper is still using the CommandMap fixes like this are still valuable.

If we'd rather fix #11378 by changing the implementation of Bukkit#dispatchCommand to use Brigadier directly, feel free to close this PR. Although, while not a requirement of the Map interface, it is also neat when map.get(a) == map.get(a) for all a, which isn't necessarily true for the BukkitBrigForwardingMap before this PR.

Resolves PaperMC#11378 by "restoring" the Spigot behavior where VanillaCommandNodes are only created once. Before this commit, BukkitBrigForwardingMap would create a new VanillaCommandWrapper each time a CommandNode was requested via the Bukkit CommandMap. This meant that calls to `Command#setPermission` would not persist between retrievals from the map.

This allows command frameworks that insert CommandNodes directly into the Brigadier dispatcher to change the permission String of the VanillaCommandNodes created for their commands, rather than it always being the default `"minecraft.commands.<name>"`.
@willkroboth willkroboth requested a review from a team as a code owner December 23, 2024 17:16
@kennytv kennytv added the type: bug Something doesn't work as it was intended to. label Dec 23, 2024
@jpenilla jpenilla self-requested a review December 23, 2024 19:37
@Owen1212055
Copy link
Member

This allows command frameworks that insert CommandNodes directly into the Brigadier dispatcher to change the permission String of the VanillaCommandNodes created for their commands, rather than it always being the default "minecraft.commands.".

The issue that if at any point Bukkit#dispatchCommand is reimplemented, wouldnt the above change kinda be invalidated? I find it very likely that bukkit dispatcher will be ripped out at one point or another, so I don't think this will have any effect command execution wise?

@willkroboth
Copy link
Contributor Author

Indeed, if CommandMap is ever removed, then BukkitBrigForwardingMap would not need to exist, and nothing would use the new CommandNode.wrappedBukkitCommandCached field added by this PR.

This PR only fixes CommandMap behavior, which is currently used by Bukkit#dispatchCommand. The current API is a bit broken in this edge case, and this PR fixes that bug. I don't expect CommandMap is going to be removed immediately, so I think it is a good idea to merge this PR. Since the change is so small, it will be obvious how to undo the changes from here when the time comes, so I don't think there is any downside to merging this PR.

But yeah, again, if we just want to fix #11378 by changing the implementation of Bukkit#dispatchCommand and don't care about the map identity thing, feel free to close this PR.

@@ -13,6 +13,7 @@
+ public CommandNode<net.minecraft.commands.CommandSourceStack> clientNode; // Paper - Brigadier API
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> unwrappedCached = null; // Paper - Brigadier Command API
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> wrappedCached = null; // Paper - Brigadier Command API
+ public org.bukkit.command.Command wrappedBukkitCommandCached = null; // Paper - Brigadier Command API
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semantics but, I think cachedWrappedBukkitCommand would read better than what's currently there

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, makes sense to me. I think I originally went with wrappedBukkitCommand + Cached to match the naming of unwrapped + Cached and wrapped + Cache directly above.

Maybe Owen had a reason to go with the original naming, but in isolation I prefer cached + WrappedBukkitCommand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something doesn't work as it was intended to.
Projects
Status: Awaiting review
4 participants