ArcanePlugins / Treasury

🏦 A powerful multi-platform library for next-level plugin integrations.
https://hangar.papermc.io/ArcanePlugins/Treasury
Other
56 stars 13 forks source link

Support Sponge #230

Closed MrIvanPlays closed 1 year ago

MrIvanPlays commented 1 year ago

This PR partly solves #225, by adding SpongeAPI support to Treasury.

montlikadani commented 1 year ago

Also can you list out a todo list what need to be implemented? Or do you want everything the same that is in Bukkit?

MrIvanPlays commented 1 year ago

@montlikadani I'm new to the sponge API, can you please do a full review and tell me what to change? Thanks in advance

Also can you list out a todo list what need to be implemented? Or do you want everything the same that is in Bukkit?

I was writing this when you commented. But basically:

A PR to this branch will be greatly appreciated too, and you will be credited accordingly.

MrIvanPlays commented 1 year ago

Oh and also, our core implementation had Scheduler#runSync. I removed it because I couldn't find a way to run tasks in Sponge on the main thread. I'd like this method back, even though it is unused. It may be needed in the future.

montlikadani commented 1 year ago

Oh and also, our core implementation had Scheduler#runSync. I removed it because I couldn't find a way to run tasks in Sponge on the main thread. I'd like this method back, even though it is unused. It may be needed in the future.

To execute in synchronous thread, you can use

Sponge.server().scheduler().submit(Task.builder().plugin(pluginContainer).execute(() -> {

}).build());

Where org.spongepowered.api.scheduler.Task#builder provides you many scheduling related methods. execute method can also accept Runnable and Consumer functions too.

MrIvanPlays commented 1 year ago

Thanks! Can you please review the current code and point where I can improve stuff?

MrIvanPlays commented 1 year ago

@montlikadani How do I get the plugin jar in Sponge? Also I recommend you to get in the ArcanePlugins discord so we can chat there: https://discord.gg/HqZwdcJ

montlikadani commented 1 year ago
  • A command source/sender/executor wrapper

In order to make Parameterized command, you need to build a command using Command#builder. I made a simple command builder with one parameter:

private Parameter.Value<ServerPlayer> playerArgumentValue;

@Listener
public void onRegisterCommands(RegisterCommandEvent<Command.Parameterized> event) {
    Command.Parameterized exampleCommand = Command.builder().permission("name.permission")
        .shortDescription(Component.text("This is a short description of this command argument"))
        .addParameters(playerArgumentValue = Parameter.player().key("player")
            .optional().requiredPermission("name.argument.player").build()
        .completer((context, currentInput) -> currentInput.isEmpty()
            ? Arrays.asList(CommandCompletion.of("completableArgumentName"))
            : Collections.emptyList()).build()).executor(this::processExample).build();

        event.register(plugin,
                Command.builder().addChild(exampleCommand, "example").terminal(true)
                .executor(this::processExample).build(), "maincommand", "mc");
    }

For the first look this looks so many lines and codes. But this is how Sponge implemented their command execution.

This is an example of how you can make a parameterized command. To simplify what is this exactly: onRegisterCommands this is a method name in which you can register and add as many commands as you want, this method will be called when the server state is ready to register commands. This is why @Listener annotation added to this method to mark that we need this method to be called.

Command.Parameterized is an interface which allows you to create arguments for your main command. There is no limit of how many of parameters you have, you just need to build them. The main command here is the maincommand or mc which is the short aliase. You can add more labels/aliases if you want.

addParameters method adds parameters to your argument like as I created an example player which awaits the player name and requires name.argument.player permission for the executor (sender). You can add more parameters to this argument if you want.

You can see that playerArgumentValue is cached outside of this method, because we need to use it later for checking the command contexts when performing the command.

completer is the same like in Bukkit, tab-completer in which you can add parameters to complete them on pressing the tab key.

Will do the others ...

MrIvanPlays commented 1 year ago

Overall LGTM, if it worked then we're ready unless there is something that we need to do.

Tested on spongevanilla, if you can please test it on spongeforge or whatever was it called. I am unable to right now.

montlikadani commented 1 year ago

SpongeForge implements SpongeAPI same as on SpongeVanilla, so it should work.

MrIvanPlays commented 1 year ago

SpongeForge implements SpongeAPI same as on SpongeVanilla, so it should work.

Then we're good. I just need @lokka30's approval and I'm merging it.