feat: add `ExecutionScope`

dependabot/gradle/org.projectlombok-lombok-1.18.34 1.2.1
William 5 months ago
parent 8c62c77bf3
commit 072c8a1b88
No known key found for this signature in database

@ -19,7 +19,7 @@
Versions are available on maven in the format `net.william278.uniform:ARTIFACT:VERSION`. See below for a table of supported platforms. Versions are available on maven in the format `net.william278.uniform:ARTIFACT:VERSION`. See below for a table of supported platforms.
Note that Uniform versions omit the `v` prefix. Fabric versions are suffixed with the target Minecraft version (e.g. `1.2+1.21`) and also require Fabric API installed on the server. Sponge versions are suffixed with the target Sponge API version (e.g. `1.2+11`). Note that Uniform versions omit the `v` prefix. Fabric versions are suffixed with the target Minecraft version (e.g. `1.2.1+1.21`) and also require Fabric API installed on the server. Sponge versions are suffixed with the target Sponge API version (e.g. `1.2.1+11`).
<table align="center"> <table align="center">
<thead> <thead>
@ -89,7 +89,7 @@ Note that Uniform versions omit the `v` prefix. Fabric versions are suffixed wit
</tbody> </tbody>
</table> </table>
Example: To target Uniform on Bukkit, the artifact is `net.william278.uniform:uniform-bukkit:1.2` (check that this version is up-to-date &ndash; make sure you target the latest available!). Example: To target Uniform on Bukkit, the artifact is `net.william278.uniform:uniform-bukkit:1.2.1` (check that this version is up-to-date &ndash; make sure you target the latest available!).
## Setup ## Setup
Uniform is available [on Maven](https://repo.william278.net/#/releases/net/william278/uniform/). You can browse the Javadocs [here](https://repo.william278.net/javadoc/releases/net/william278/uniform/latest). Uniform is available [on Maven](https://repo.william278.net/#/releases/net/william278/uniform/). You can browse the Javadocs [here](https://repo.william278.net/javadoc/releases/net/william278/uniform/latest).
@ -104,7 +104,7 @@ repositories {
} }
``` ```
Then, add the dependency itself. Replace `VERSION` with the latest release version. (e.g., `1.2`) and `PLATFORM` with the platform you are targeting (e.g., `paper`). If you want to target pre-release "snapshot" versions (not recommended), you should use the `/snapshots` repository instead. Then, add the dependency itself. Replace `VERSION` with the latest release version. (e.g., `1.2.1`) and `PLATFORM` with the platform you are targeting (e.g., `paper`). If you want to target pre-release "snapshot" versions (not recommended), you should use the `/snapshots` repository instead.
```groovy ```groovy
dependencies { dependencies {

@ -55,6 +55,7 @@ public abstract class BaseCommand<S> {
this.name = command.getName(); this.name = command.getName();
this.aliases = command.getAliases(); this.aliases = command.getAliases();
this.description = command.getDescription(); this.description = command.getDescription();
setExecutionScope(command.getScope());
command.getPermission().ifPresent(this::setPermission); command.getPermission().ifPresent(this::setPermission);
command.provide(this); command.provide(this);
} }
@ -79,8 +80,16 @@ public abstract class BaseCommand<S> {
this.condition = condition; this.condition = condition;
} }
public final void addCondition(@NotNull Predicate<S> condition) {
if (this.condition == null) {
this.condition = condition;
} else {
this.condition = this.condition.and(condition);
}
}
public void setPermission(@NotNull Permission permission) { public void setPermission(@NotNull Permission permission) {
this.setCondition(this.createPermission(permission)); this.addCondition(this.createPermission(permission));
} }
public final void setPermission(@NotNull String permission) { public final void setPermission(@NotNull String permission) {
@ -91,6 +100,13 @@ public abstract class BaseCommand<S> {
this.setPermission(new Permission(permission, permissionDefault)); this.setPermission(new Permission(permission, permissionDefault));
} }
public final void setExecutionScope(@NotNull Command.ExecutionScope scope) {
final Predicate<S> predicate = scope.toPredicate(this);
if (predicate != null) {
this.addCondition(predicate);
}
}
public final void setDefaultExecutor(@NotNull CommandExecutor<S> executor) { public final void setDefaultExecutor(@NotNull CommandExecutor<S> executor) {
this.defaultExecutor = executor; this.defaultExecutor = executor;
} }
@ -130,6 +146,12 @@ public abstract class BaseCommand<S> {
this.addSubCommand(new Command.SubCommand(name, aliases, permission, provider).command()); this.addSubCommand(new Command.SubCommand(name, aliases, permission, provider).command());
} }
public final void addSubCommand(@NotNull String name, @NotNull List<String> aliases,
@NotNull Permission permission, @NotNull Command.ExecutionScope scope,
@NotNull CommandProvider provider) {
this.addSubCommand(new Command.SubCommand(name, aliases, permission, scope, provider).command());
}
public abstract void addSubCommand(@NotNull Command command); public abstract void addSubCommand(@NotNull Command command);
public abstract Uniform getUniform(); public abstract Uniform getUniform();

@ -55,6 +55,7 @@ public abstract class Command implements CommandProvider {
private String description = ""; private String description = "";
@Getter(AccessLevel.NONE) @Getter(AccessLevel.NONE)
private @Nullable Permission permission = null; private @Nullable Permission permission = null;
private ExecutionScope scope = ExecutionScope.ALL;
public Optional<Permission> getPermission() { public Optional<Permission> getPermission() {
return Optional.ofNullable(permission); return Optional.ofNullable(permission);
@ -71,9 +72,29 @@ public abstract class Command implements CommandProvider {
this.name = node.value(); this.name = node.value();
this.aliases = List.of(node.aliases()); this.aliases = List.of(node.aliases());
this.description = node.description(); this.description = node.description();
this.scope = node.scope();
Permission.annotated(node.permission()).ifPresent(this::setPermission); Permission.annotated(node.permission()).ifPresent(this::setPermission);
} }
public enum ExecutionScope {
IN_GAME,
CONSOLE,
ALL;
@Nullable
public <S> Predicate<S> toPredicate(@NotNull BaseCommand<S> command) {
return this == ALL ? null : user -> this.contains(command.getUser(user));
}
public boolean contains(@NotNull CommandUser user) {
return switch (this) {
case IN_GAME -> !user.isConsole();
case CONSOLE -> user.isConsole();
case ALL -> true;
};
}
}
static class AnnotatedCommand extends Command { static class AnnotatedCommand extends Command {
private final Object annotated; private final Object annotated;
@ -102,11 +123,15 @@ public abstract class Command implements CommandProvider {
continue; continue;
} }
// Conditional & unconditional syntax // Determine predicates
final Optional<Predicate> perm = Permission.annotated(syntax.permission()).map(p -> p.toPredicate(cmd)); final Optional<Predicate> perm = Permission.annotated(syntax.permission()).map(p -> p.toPredicate(cmd));
final Optional<Predicate> scope = Optional.ofNullable(syntax.scope().toPredicate(cmd));
final Optional<Predicate> combined = scope.map(sp -> perm.map(pp -> sp.and(pp)).orElse(sp));
// Conditional & unconditional syntax
final CommandExecutor executor = methodToExecutor(method, annotated, cmd); final CommandExecutor executor = methodToExecutor(method, annotated, cmd);
if (perm.isPresent()) { if (combined.isPresent()) {
cmd.addConditionalSyntax(perm.get(), executor, args); cmd.addConditionalSyntax(combined.get(), executor, args);
continue; continue;
} }
cmd.addSyntax(executor, args); cmd.addSyntax(executor, args);
@ -170,22 +195,28 @@ public abstract class Command implements CommandProvider {
} }
public record SubCommand(@NotNull String name, @NotNull List<String> aliases, @Nullable Permission permission, public record SubCommand(@NotNull String name, @NotNull List<String> aliases, @Nullable Permission permission,
@NotNull ExecutionScope scope, @NotNull CommandProvider provider) {
public SubCommand(@NotNull String name, @NotNull List<String> aliases, @Nullable Permission permission,
@NotNull CommandProvider provider) { @NotNull CommandProvider provider) {
public SubCommand(@NotNull String name, @NotNull List<String> aliases, @NotNull CommandProvider provider) { this(name, aliases, permission, ExecutionScope.ALL, provider);
this(name, aliases, null, provider);
} }
public SubCommand(@NotNull String name, @NotNull CommandProvider provider) { public SubCommand(@NotNull String name, @NotNull List<String> aliases, @NotNull CommandProvider provider) {
this(name, List.of(), null, provider); this(name, aliases, null, ExecutionScope.ALL, provider);
} }
public SubCommand(@NotNull String name, @Nullable Permission permission, @NotNull CommandProvider provider) { public SubCommand(@NotNull String name, @Nullable Permission permission, @NotNull CommandProvider provider) {
this(name, List.of(), permission, provider); this(name, List.of(), permission, ExecutionScope.ALL, provider);
} }
public SubCommand(@NotNull String name, @NotNull CommandProvider provider) {
this(name, List.of(), null, ExecutionScope.ALL, provider);
}
@NotNull @NotNull
Command command() { Command command() {
return new Command(name, aliases, "", permission) { return new Command(name, aliases, "", permission, scope) {
@Override @Override
public void provide(@NotNull BaseCommand<?> command) { public void provide(@NotNull BaseCommand<?> command) {
provider.provide(command); provider.provide(command);

@ -21,6 +21,8 @@
package net.william278.uniform.annotations; package net.william278.uniform.annotations;
import net.william278.uniform.Command;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -34,5 +36,6 @@ public @interface CommandNode {
String[] aliases() default {}; String[] aliases() default {};
String description() default ""; String description() default "";
PermissionNode permission() default @PermissionNode(""); PermissionNode permission() default @PermissionNode("");
Command.ExecutionScope scope() default Command.ExecutionScope.ALL;
} }

@ -21,6 +21,8 @@
package net.william278.uniform.annotations; package net.william278.uniform.annotations;
import net.william278.uniform.Command;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -29,5 +31,8 @@ import java.lang.annotation.Target;
@Target({ElementType.METHOD}) @Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Syntax { public @interface Syntax {
PermissionNode permission() default @PermissionNode(""); PermissionNode permission() default @PermissionNode("");
Command.ExecutionScope scope() default Command.ExecutionScope.ALL;
} }

@ -3,6 +3,6 @@ javaVersion=17
org.gradle.jvmargs='-Dfile.encoding=UTF-8' org.gradle.jvmargs='-Dfile.encoding=UTF-8'
org.gradle.daemon=true org.gradle.daemon=true
library_version=1.2 library_version=1.2.1
library_archive=uniform library_archive=uniform
library_description=Cross-platform wrapper for making Brigadier commands, based on BrigadierWrapper by Tofaa2, itself inspired by emortalmcs command system. library_description=Cross-platform wrapper for making Brigadier commands, based on BrigadierWrapper by Tofaa2, itself inspired by emortalmcs command system.
Loading…
Cancel
Save