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

Cloud for commands #3808

Open
wants to merge 117 commits into
base: master
Choose a base branch
from
Open

Cloud for commands #3808

wants to merge 117 commits into from

Conversation

Konicai
Copy link
Member

@Konicai Konicai commented Jun 2, 2023

changes

  • GeyserCommandManager has been renamed to CommandRegistry

  • GeyserCommandExecutor and all subclasses have been removed in favour of Cloud.

  • WorldManager#hasPermission has been removed in favour of Cloud.

  • permission node for the root command of Geyser and extensions, that is required to use any child commands

  • Spigot

    • no longer depends on paper mojang api.
    • GeyserBrigadierSupport has been removed in favour of Cloud.
    • GeyserPaperCommandListener has been removed - cloud (and the way i designed permission checks) handles what it did.
  • Standalone/ViaProxy:

    • permissions.yml has been added, a list of default permissions available to all players.
  • Velocity/BungeeCord/Fabric/Standalone: commands are now registered before GeyserPostInitializeEvent, for consistency with Spigot, and to allow valid registration on Fabric.

    • There is still inconsistency between bootstraps on whether or not commands are re-registered whenever a reload occurs.

api changes:

deprecations

  • Command#isSuggestedOpOnly and the relevant builder method have been deprecated for removal
  • Command#subCommands has been deprecated for removal and will always return Collections.emptyList()
  • Command#isExecutableOnConsole() has been deprecated & replaced with #isPlayerOnly()

changes

  • Command#aliases() now always returns an immutable list

additions

  • Command.Builder#permission(String, Tristate) - register the permission and its default value to the server implementation if possible.
  • CommandSource#playerUuid - return a uuid if the source represents a player.
  • CommandSource#connection - return a Connection if the source represents a bedrock player managed by the current Geyser instance.

  • GeyserRegisterPermissionCheckersEvent - only used by Geyser-Standalone/ViaProxy. Fired when the command manager is created. Allows registering PermissionCheckers to the manager. Event listeners with a higher listener priority will register PermissionCheckers as having a higher priority.
  • PermissionChecker - api interface that is responsible for resolving a CommandSource and a permission node to a Tristate.

  • GeyserRegisterPermissionsEvent - fired by a server platform, or extension, or anything, when it is the proper time for permissions to be registered to the event caller. This event will be called by Geyser-Spigot/Standalone/Forge. An extension may also fire the event in order to register permissions to LuckPerms for Geyser-Velocity/BungeeCord/Fabric. Geyser's CommandRegistry will listen for this event, but api users may as well.

future and separate PRs

  • implementations of CommandSource#sendMessage are wildly different in terms of what kind of text format is passed to it. maybe an earlier PR.
  • use cloud's brigadier mappings to get suggestions on geyser standalone
  • add tab completion to geyser standalone JLine

todo:

  • the lack of permissions on standalone. what this causes needs to be cleaned up, at least in extension commands.
  • create permissions.yml file for standalone/viaproxy
  • remove standalone permission hacks from builtin cmmands
  • isSuggestedOpOnly is kind of problematic imo, in regards to its wording and the way it is used. it can probably just be deprecated in favour of optional permission registration
  • properly handle stopping execution due to isExecutableOnConsole or isBedrockOnly with descriptive messages
  • exceptions are completely unhandled on Geyser-Standalone right now
  • convert builtin commands to fully utilize cloud features
  • pretty sure just /geyser is suppose to send help?
  • localize all messages
  • deal with possible trailing whitespace on geyser standalone gui
  • java players get suggested bedrock only commands -> additionally add platform check as a permission predicate
  • restore Spigot COMMAND_MAP lookup for descriptions
  • search CommandRegistry for our own description(s)
  • javadocs
  • check if we need to strip trailing whitespace before dispatching to cloud from BedrockCommandRequestTranslator (when Geyser Standalone is in use)
  • fix certain commands not working properly with handleNoPermission
  • i think command.failed lang might be broken
  • ensure viaproxy doesn't error on the clearing of the command manager when viaproxy was initialized, but not started
  • Spigot has a root command permission. fix regression of it being removed.
  • ensure all extension command permissions are registered on NeoForge, regardless of permission defaults. maybe just change the overall handling.
  • final testing

@Konicai Konicai changed the title Feature/cloud Cloud for commands Jun 2, 2023
Konicai and others added 12 commits June 2, 2023 18:52
any GeyserCommandSource should be valid to use in any CommandManager as long as one of the following is satisfied
1. it is a platform implementation
2. isConsole() returns true
2. playerUuid() returns a valid uuid and the player lookup succeeds
# Conflicts:
#	bootstrap/bungeecord/build.gradle.kts
#	bootstrap/spigot/build.gradle.kts
#	core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java
#	core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java
# Conflicts:
#	bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java
# Conflicts:
#	bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java
#	bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSource.java
#	bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java
#	bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java
#	core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java
#	core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java
#	core/src/main/resources/languages
#	gradle/libs.versions.toml
Copy link
Member

@onebeastchris onebeastchris left a comment

Choose a reason for hiding this comment

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

some thoughts that came to mind, looks good otherwise (skipped the NeoForge permission stuff, since well, that's known)

Copy link
Member

@onebeastchris onebeastchris left a comment

Choose a reason for hiding this comment

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

One nitpick; also the @NonNull nature of the permission/permission default on the permission registration event doesn't seem to be enforced at the moment

@@ -213,6 +218,7 @@ public void onGeyserEnable() {

GeyserImpl.start();


if (geyserConfig.isLegacyPingPassthrough()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

remove diff

VersionCheckUtils.checkForGeyserUpdate(() -> new ModCommandSender(stack));
ModCommandSource source = new ModCommandSource(player.createCommandSourceStack());
if (source.hasPermission(Permissions.CHECK_UPDATE)) {
VersionCheckUtils.checkForGeyserUpdate(() -> source);
Copy link
Member Author

Choose a reason for hiding this comment

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

revert but use source.getServer().getOperatorUserPermissionLevel() instead of 2

}
}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

undo


private final CommandSourceStack source;

public ModCommandSender(CommandSourceStack source) {
public ModCommandSource(CommandSourceStack source) {
this.source = source;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

load geyser locale like other CommandSource implementations?

Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately, the CommandSourceStack doesn't expose a locale - Floodgate-Fabric for example always fallbacks to en_US as of now: https://github.com/GeyserMC/Floodgate-Fabric/blob/master/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java#L43

public @NonNull S reverse(GeyserCommandSource source) throws IllegalArgumentException {
Object handle = source.handle();
if (senderType.isInstance(handle)) {
return senderType.cast(source); // one of the server platform implementations
Copy link
Member Author

@Konicai Konicai Jun 10, 2024

Choose a reason for hiding this comment

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

handle not source, recent regression


private final CommandSourceStack source;

public ModCommandSender(CommandSourceStack source) {
public ModCommandSource(CommandSourceStack source) {
this.source = source;
}
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately, the CommandSourceStack doesn't expose a locale - Floodgate-Fabric for example always fallbacks to en_US as of now: https://github.com/GeyserMC/Floodgate-Fabric/blob/master/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java#L43

* it yet to platforms like Velocity where we cannot natively specify a permission default. Doing so will
* break setups as players would suddenly not have the required permission to execute any Geyser commands.
*/
protected boolean applyRootPermission() {
Copy link
Member

Choose a reason for hiding this comment

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

should also be overridden on Standalone/ViaProxy/NeoForge

core/src/main/java/org/geysermc/geyser/Permissions.java Outdated Show resolved Hide resolved
});
this.commands.stream()
.distinct() // remove aliases
.filter(cmd -> !cmd.isBedrockOnly() || bedrockPlayer) // remove bedrock only commands if not a bedrock player
Copy link
Member

Choose a reason for hiding this comment

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

Small, unimportant nitpick: this might be a bit better as .filter(bedrockPlayer ? Predicates.alwaysTrue() : cmd -> !cmd.isBedrockOnly()).

public abstract void execute(@Nullable GeyserSession session, GeyserCommandSource sender, String[] args);
/**
* The default value of the permission node.
* A null value indicates that the permission node should not be registered whatsoever.
Copy link
Member

Choose a reason for hiding this comment

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

Can we document what each of the values means here, or link to another Javadoc where they are explained?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: Under Review When a PR (particularly a large one) is currently being reviewed to see if it can be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants