Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions examples/bukkit-jakarta/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
plugins {
id("java")
id("com.gradleup.shadow") version "9.3.1"
id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
id("xyz.jpenilla.run-paper") version "3.0.2"
}

version = "3.11.0"

repositories {
mavenCentral()
maven { url = uri("https://repo.panda-lang.org/releases/") }
maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") }
}

dependencies {
compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT")

// implementation("dev.rollczi:litecommands-bukkit:3.11.0") // <-- uncomment in your project
// implementation("dev.rollczi:litecommands-jakarta:3.11.0") // <-- uncomment in your project
implementation(project(":litecommands-bukkit")) // don't use this line in your build.gradle
implementation(project(":litecommands-jakarta")) // don't use this line in your build.gradle
}

val pluginName = "ExampleBukkitJakartaPlugin"
val packageName = "dev.rollczi.example.bukkit.jakarta"

bukkit {
main = "$packageName.$pluginName"
apiVersion = "1.13"
author = "Rollczi"
name = pluginName
version = "${project.version}"
}

tasks.shadowJar {
archiveFileName.set("$pluginName v${project.version}.jar")

listOf(
"dev.rollczi.litecommands",
).forEach { relocate(it, "$packageName.libs.$it") }
}

java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}

tasks.withType<JavaCompile> {
options.compilerArgs.add("-parameters")
options.release = 21
}

sourceSets.test {
java.setSrcDirs(emptyList<String>())
resources.setSrcDirs(emptyList<String>())
}

tasks.runServer {
minecraftVersion("1.21.4")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.rollczi.example.bukkit.jakarta;

import dev.rollczi.example.bukkit.jakarta.command.JakartaCommand;
import dev.rollczi.litecommands.LiteCommands;
import dev.rollczi.litecommands.bukkit.LiteBukkitFactory;
import dev.rollczi.litecommands.jakarta.LiteJakartaExtension;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class ExampleBukkitJakartaPlugin extends JavaPlugin {

private LiteCommands<CommandSender> liteCommands;

@Override
public void onEnable() {
this.liteCommands = LiteBukkitFactory.builder("my-jakarta-plugin")
.extension(new LiteJakartaExtension<>())
.argument(JakartaCommand.User.class, new JakartaCommand.UserArgumentResolver())
.commands(
new JakartaCommand()
)
.build();
}

@Override
public void onDisable() {
if (this.liteCommands != null) {
this.liteCommands.unregister();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package dev.rollczi.example.bukkit.jakarta.command;

import dev.rollczi.litecommands.annotations.argument.Arg;
import dev.rollczi.litecommands.annotations.command.Command;
import dev.rollczi.litecommands.annotations.execute.Execute;
import dev.rollczi.litecommands.argument.Argument;
import dev.rollczi.litecommands.argument.parser.ParseResult;
import dev.rollczi.litecommands.argument.resolver.ArgumentResolver;
import dev.rollczi.litecommands.invocation.Invocation;
import dev.rollczi.litecommands.suggestion.SuggestionContext;
import dev.rollczi.litecommands.suggestion.SuggestionResult;
import org.bukkit.command.CommandSender;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import jakarta.validation.Valid;
import jakarta.validation.constraints.AssertFalse;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.FutureOrPresent;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Negative;
import jakarta.validation.constraints.NegativeOrZero;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Past;
import jakarta.validation.constraints.PastOrPresent;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import jakarta.validation.constraints.Size;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.time.Instant;
import java.util.List;

@Command(name = "jakarta")
public class JakartaCommand {

@Execute(name = "age")
String age(@Min(1) @Max(120) @Arg int age) {
return "Your age is " + age;
}

@Execute(name = "name")
String name(@NotBlank @Size(min = 3, max = 16) @Arg String name) {
return "Your name is " + name;
}

@Execute(name = "boolean-true")
String booleanTrue(@AssertTrue @Arg boolean value) {
return "Value is " + value;
}

@Execute(name = "boolean-false")
String booleanFalse(@AssertFalse @Arg boolean value) {
return "Value is " + value;
}

@Execute(name = "positive")
String positive(@Positive @Arg int value) {
return "Positive value: " + value;
}

@Execute(name = "positive-or-zero")
String positiveOrZero(@PositiveOrZero @Arg int value) {
return "Positive or zero value: " + value;
}

@Execute(name = "negative")
String negative(@Negative @Arg int value) {
return "Negative value: " + value;
}

@Execute(name = "negative-or-zero")
String negativeOrZero(@NegativeOrZero @Arg int value) {
return "Negative or zero value: " + value;
}

@Execute(name = "digits")
String digits(@Digits(integer = 3, fraction = 2) @Arg double value) {
return "Digits: " + value;
}

@Execute(name = "decimal")
String decimal(@DecimalMin("0.1") @DecimalMax("1.0") @Arg double value) {
return "Decimal value: " + value;
}

@Execute(name = "past")
String past(@Past @Arg Instant instant) {
return "Past instant: " + instant;
}

@Execute(name = "past-or-present")
String pastOrPresent(@PastOrPresent @Arg Instant instant) {
return "Past or present instant: " + instant;
}

@Execute(name = "future")
String future(@Future @Arg Instant instant) {
return "Future instant: " + instant;
}

@Execute(name = "future-or-present")
String futureOrPresent(@FutureOrPresent @Arg Instant instant) {
return "Future or present instant: " + instant;
}

@Execute(name = "pattern")
String pattern(@Pattern(regexp = "[a-z]+") @Arg String text) {
return "Pattern match: " + text;
}

@Execute(name = "email")
String email(@Email @Arg String email) {
return "Email: " + email;
}

@Execute(name = "list")
String list(@NotEmpty @Size(min = 2) @Arg List<String> list) {
return "List size: " + list.size();
}

@Execute(name = "user-info")
String userInfo(@NotBlank @Size(min = 3) @Arg String name, @Min(1) @Max(100) @Arg int level) {
return "User: " + name + ", Level: " + level;
}

@Execute(name = "transfer")
String transfer(@NotBlank @Arg String from, @NotBlank @Arg String to, @Positive @Arg double amount) {
return "Transferred " + amount + " from " + from + " to " + to;
}

@Execute(name = "user")
String user(@Valid @Arg User user) {
return "User: " + user.name + " (" + user.age + ")";
}

public record User(@NotBlank String name, @Min(18) int age) {

public User(String name, int age) {
this.name = name;
this.age = age;
}
}

public static class UserArgumentResolver extends ArgumentResolver<CommandSender, User> {

@Override
protected ParseResult<User> parse(Invocation<CommandSender> invocation, Argument<User> context, String argument) {
String[] split = argument.split(":", 2);

if (split.length < 2) {
return ParseResult.failure("Invalid user format. Use name:age");
}

try {
String name = split[0];
int age = Integer.parseInt(split[1]);

return ParseResult.success(new User(name, age));
} catch (NumberFormatException e) {
return ParseResult.failure("Age must be a number.");
}
}

@Override
public SuggestionResult suggest(Invocation<CommandSender> invocation, Argument<User> argument, SuggestionContext context) {
return SuggestionResult.of("name:18");
}

}

@Execute(name = "custom")
private String custom(@NotAdmin @Arg String name) {
return "Hello, " + name;
}

@Target({ ElementType.PARAMETER, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NotAdminValidator.class)
@Documented
private @interface NotAdmin {
String message() default "Name cannot be 'admin'";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

private static class NotAdminValidator implements ConstraintValidator<NotAdmin, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value == null || !value.equalsIgnoreCase("admin");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class MethodCommandExecutor<SENDER> extends AbstractCommandExecutor<SENDE
this.meta.putAll(meta);
}

@Override
public Object getInstance() {
return instance;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package dev.rollczi.litecommands.command.executor;

import dev.rollczi.litecommands.argument.Argument;
import dev.rollczi.litecommands.bind.BindRequirement;
import dev.rollczi.litecommands.command.CommandNode;
import dev.rollczi.litecommands.command.CommandRoute;
import dev.rollczi.litecommands.priority.Prioritized;
import dev.rollczi.litecommands.bind.BindRequirement;
import dev.rollczi.litecommands.context.ContextRequirement;
import dev.rollczi.litecommands.priority.Prioritized;
import dev.rollczi.litecommands.requirement.RequirementsResult;
import dev.rollczi.litecommands.scope.Scopeable;
import org.jetbrains.annotations.Unmodifiable;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.jetbrains.annotations.Unmodifiable;

/**
* CommandExecutor is a node of the command tree.
Expand All @@ -32,6 +32,10 @@ public interface CommandExecutor<SENDER> extends Scopeable, CommandNode<SENDER>,

CommandExecutorMatchResult match(RequirementsResult<SENDER> result);

default Object getInstance() {
return null;
}

@Unmodifiable
@Override
default Collection<String> names() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class SuggestionResult {
Expand Down Expand Up @@ -38,6 +39,10 @@ public void clear() {
this.suggestions.clear();
}

public void removeIf(Predicate<Suggestion> predicate) {
this.suggestions.removeIf(predicate);
}

public void addAll(SuggestionResult result) {
this.suggestions.addAll(result.suggestions);
}
Expand Down
Loading
Loading