Source Resolver
In Imperat, SourceResolver<S extends Source, R>
is an interface designed to handle the resolution of platform-specific command sources (S
) into custom types (R
). This allows for the flexibility of customizing the command source based on the platform, enabling developers to transform platform-specific command senders into their own command source representations.
Source Interface
Source
is an interface representing the command sender on a given platform. Since Imperat is designed to work across multiple platforms, the type of S
depends on the platform you're working with. For example, in a Bukkit environment, BukkitSource
would implement the Source
interface, representing the sender of a command in Bukkit.
The purpose of the SourceResolver
is to map a command sender (such as BukkitSource
) into a custom type (R
) that better fits the needs of your project.
Interface Definition
The SourceResolver
interface is simple in its design:
public interface SourceResolver<S extends Source, R> {
R resolve(S source) throws ImperatException;
}
S
: The platform-specific source, e.g.,BukkitSource
in Bukkit.R
: The resolved type, representing your custom command source.resolve(S source)
: This method transforms a platform-specific source into a custom typeR
. It can throw anImperatException
to signal any issues during the resolution process.
Example of Custom Source
Here's an example of a custom class representing a player on a given platform:
public final class CustomPlayer {
private final CommandSender sender;
public CustomPlayer(CommandSender sender) {
this.sender = sender;
}
public void sendMessage(String msg) {
sender.sendMessage(msg);
}
public void greet() {
sendMessage("Greetings " + sender.getName());
}
// Additional methods to access player-specific data
}
Example: Implementing a SourceResolver
Below is an example of how to create a SourceResolver
for Bukkit's BukkitSource
, which transforms it into a custom CustomPlayer
type:
public class CustomSourceResolver implements SourceResolver<BukkitSource, CustomPlayer> {
@Override
public @NotNull CustomPlayer resolve(BukkitSource source) throws ImperatException {
if (source.isConsole()) {
throw new SourceException("Only players are allowed to execute this command");
}
return new CustomPlayer(source.origin());
}
}
In this example:
- The
resolve
method checks if the source is a console (and disallows it) and otherwise returns aCustomPlayer
instance, wrapping the originalCommandSender
.
Registering a SourceResolver
Once your SourceResolver
is implemented, you can register it with Imperat as follows:
imperat.registerSourceResolver(CustomPlayer.class, new CustomSourceResolver());
This allows Imperat to resolve BukkitSource
into your CustomPlayer
type whenever necessary.
Example Usage
This can be used differently depending on the way your making your commands (whether Classic or Annotations)
Classic example
imperat.registerCommand(
Command.<BukkitSource>create("test")
.usage(
CommandUsage.<BukkitSource>builder()
.parameters(CommandParameter.requiredText("txt"))
.execute((source, ctx)-> {
CustomPlayer customPlayer = ctx.getResolvedSource(CustomPlayer.class);
String txt = ctx.getArgument("txt");
//do whatever you want with custom player
customPlayer.greet();
customPlayer.sendMessage("The text you entered is '" + txt + "'");
})
).build()
);
Annotations example
public final class TestCommand {
@Usage
public void someUsage(CustomPlayer player, @Named("txt") String txt) {
player.greet();
player.sendMessage("The text you entered is '" + txt + "'");
}
}