├── .github
└── FUNDING.yml
├── settings.gradle.kts
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .idea
├── vcs.xml
├── .gitignore
├── misc.xml
└── runConfigurations
│ ├── Clean_CommandAPI.xml
│ ├── Publish_CommandAPI.xml
│ └── Build_CommandAPI.xml
├── bungee
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── net
│ └── j4c0b3y
│ └── api
│ └── command
│ └── bungee
│ ├── locale
│ └── BungeeCommandLocale.java
│ ├── annotation
│ └── ConsoleSender.java
│ ├── provider
│ ├── actor
│ │ ├── CommandSenderProvider.java
│ │ ├── BungeeActorProvider.java
│ │ ├── ConsoleCommandSenderProvider.java
│ │ └── ProxiedPlayerSenderProvider.java
│ └── argument
│ │ └── ServerInfoProvider.java
│ ├── actor
│ └── BungeeActor.java
│ ├── BungeeCommandWrapper.java
│ └── BungeeCommandHandler.java
├── .gitignore
├── core
└── src
│ └── main
│ └── java
│ └── net
│ └── j4c0b3y
│ └── api
│ └── command
│ ├── execution
│ ├── argument
│ │ ├── flag
│ │ │ ├── FlagAction.java
│ │ │ └── CommandFlag.java
│ │ └── CommandArgument.java
│ ├── usage
│ │ ├── UsageHandler.java
│ │ └── impl
│ │ │ └── SimpleUsageHandler.java
│ ├── ProvidedParameter.java
│ ├── locale
│ │ └── CommandLocale.java
│ └── CommandExecution.java
│ ├── actor
│ ├── ConsoleActor.java
│ ├── ProxyActor.java
│ ├── PlayerActor.java
│ └── Actor.java
│ ├── wrapper
│ ├── binding
│ │ ├── condition
│ │ │ ├── ExecuteCondition.java
│ │ │ └── ConditionHandler.java
│ │ ├── provider
│ │ │ ├── ProviderType.java
│ │ │ ├── impl
│ │ │ │ ├── context
│ │ │ │ │ ├── LabelProvider.java
│ │ │ │ │ ├── CommandExecutionProvider.java
│ │ │ │ │ ├── InstanceProvider.java
│ │ │ │ │ ├── CommandHandleProvider.java
│ │ │ │ │ └── CommandWrapperProvider.java
│ │ │ │ ├── argument
│ │ │ │ │ ├── StringProvider.java
│ │ │ │ │ ├── CharacterProvider.java
│ │ │ │ │ ├── UUIDProvider.java
│ │ │ │ │ ├── NumberProvider.java
│ │ │ │ │ ├── MapProvider.java
│ │ │ │ │ ├── ArrayProvider.java
│ │ │ │ │ ├── EnumProvider.java
│ │ │ │ │ └── BooleanProvider.java
│ │ │ │ └── actor
│ │ │ │ │ ├── ActorProvider.java
│ │ │ │ │ ├── ProxyActorProvider.java
│ │ │ │ │ ├── PlayerActorProvider.java
│ │ │ │ │ └── ConsoleActorProvider.java
│ │ │ └── Provider.java
│ │ ├── modifier
│ │ │ ├── ArgumentModifier.java
│ │ │ ├── impl
│ │ │ │ ├── LengthModifier.java
│ │ │ │ └── RangeModifier.java
│ │ │ └── ModifierHandler.java
│ │ ├── ParameterBinding.java
│ │ ├── BindingHandler.java
│ │ └── BindingBuilder.java
│ ├── suggestion
│ │ └── CommandSuggestion.java
│ ├── CommandParameter.java
│ ├── CommandWrapper.java
│ └── CommandHandle.java
│ ├── exception
│ ├── binding
│ │ └── InvalidBindingException.java
│ ├── registration
│ │ ├── InvalidHandleException.java
│ │ ├── InvalidWrapperException.java
│ │ ├── InvalidParameterException.java
│ │ ├── MissingProviderException.java
│ │ ├── ParameterStructureException.java
│ │ └── RegistrationException.java
│ └── execution
│ │ ├── MissingValidatorException.java
│ │ ├── UnknownFlagException.java
│ │ └── ExitMessage.java
│ ├── annotation
│ ├── parameter
│ │ ├── Last.java
│ │ ├── Optional.java
│ │ ├── Text.java
│ │ ├── modifier
│ │ │ ├── Modifier.java
│ │ │ ├── Length.java
│ │ │ └── Range.java
│ │ ├── Named.java
│ │ ├── Default.java
│ │ ├── Manual.java
│ │ ├── Option.java
│ │ ├── classifier
│ │ │ ├── Classifier.java
│ │ │ ├── Label.java
│ │ │ └── Sender.java
│ │ └── Flag.java
│ ├── command
│ │ ├── condition
│ │ │ └── Condition.java
│ │ ├── Usage.java
│ │ ├── Requires.java
│ │ ├── Help.java
│ │ └── Command.java
│ └── registration
│ │ ├── Ignore.java
│ │ └── Register.java
│ ├── utils
│ ├── ClassUtils.java
│ ├── StringUtils.java
│ ├── ListUtils.java
│ └── AnnotationUtils.java
│ └── CommandHandler.java
├── bukkit
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── net
│ └── j4c0b3y
│ └── api
│ └── command
│ └── bukkit
│ ├── locale
│ └── BukkitCommandLocale.java
│ ├── provider
│ ├── actor
│ │ ├── CommandSenderProvider.java
│ │ ├── BukkitActorProvider.java
│ │ ├── PlayerSenderProvider.java
│ │ └── ConsoleCommandSenderProvider.java
│ └── argument
│ │ ├── EnchantmentProvider.java
│ │ ├── WorldProvider.java
│ │ ├── OfflinePlayerProvider.java
│ │ └── PlayerProvider.java
│ ├── utils
│ └── ClassUtils.java
│ ├── actor
│ └── BukkitActor.java
│ ├── listener
│ └── AsyncTabListener.java
│ ├── BukkitCommandWrapper.java
│ ├── BukkitCommandRegistry.java
│ └── BukkitCommandHandler.java
├── velocity
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── net
│ └── j4c0b3y
│ └── api
│ └── command
│ └── velocity
│ ├── locale
│ └── VelocityCommandLocale.java
│ ├── provider
│ ├── actor
│ │ ├── CommandSourceProvider.java
│ │ ├── VelocityActorProvider.java
│ │ ├── PlayerSenderProvider.java
│ │ └── ConsoleCommandSourceProvider.java
│ └── argument
│ │ ├── PlayerProvider.java
│ │ └── RegisteredServerProvider.java
│ ├── actor
│ └── VelocityActor.java
│ ├── VelocityCommandWrapper.java
│ └── VelocityCommandHandler.java
├── LICENSE.md
├── README.md
├── gradlew.bat
└── gradlew
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: https://donate.j4c0b3y.net
2 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "CommandAPI"
2 | include("core", "bukkit", "velocity", "bungee")
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/J4C0B3Y/CommandAPI/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 |
3 | !.gitignore
4 |
5 | !vcs.xml
6 | !encodings.xml
7 | !codeStyleSettings.xml
8 | !misc.xml
9 |
10 | !runConfigurations
11 | !runConfigurations/*
12 |
13 | !modules
14 | !modules/*
--------------------------------------------------------------------------------
/bungee/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | repositories {
3 | maven("https://repo.codemc.org/repository/maven-public/")
4 | maven("https://libraries.minecraft.net")
5 | }
6 |
7 | dependencies {
8 | compileOnly("net.md-5:bungeecord-api:1.21-R0.1-SNAPSHOT")
9 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 | !gradle/wrapper/gradle-wrapper.jar
4 | !**/src/main/**/build/
5 | !**/src/test/**/build/
6 | gradle.properties
7 | jars/
8 |
9 | *.iws
10 | *.iml
11 | *.ipr
12 | out/
13 | !**/src/main/**/out/
14 | !**/src/test/**/out/
15 |
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Aug 26 22:56:20 AEST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/argument/flag/FlagAction.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution.argument.flag;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 1/09/2024
7 | */
8 | public enum FlagAction {
9 | STRIP,
10 | ARGUMENT,
11 | ERROR
12 | }
13 |
--------------------------------------------------------------------------------
/bukkit/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | repositories {
3 | maven("https://repo.codemc.org/repository/nms/")
4 | maven("https://repo.codemc.org/repository/maven-public/")
5 | maven("https://libraries.minecraft.net")
6 | }
7 |
8 | dependencies {
9 | compileOnly("com.destroystokyo.paper:paper-api:1.12.2-R0.1-SNAPSHOT")
10 | }
11 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/actor/ConsoleActor.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.actor;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 28/08/2024
7 | */
8 | public interface ConsoleActor {
9 | boolean isConsole();
10 | void sendMessage(String message);
11 | String getName();
12 | }
13 |
--------------------------------------------------------------------------------
/velocity/build.gradle.kts:
--------------------------------------------------------------------------------
1 |
2 | repositories {
3 | maven("https://nexus.velocitypowered.com/repository/maven-public/")
4 | }
5 |
6 | java {
7 | sourceCompatibility = JavaVersion.VERSION_17
8 | targetCompatibility = JavaVersion.VERSION_17
9 | }
10 |
11 | dependencies {
12 | compileOnly("com.velocitypowered:velocity-api:3.3.0-SNAPSHOT")
13 | }
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/actor/ProxyActor.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.actor;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 28/08/2024
7 | */
8 | public interface ProxyActor {
9 | boolean isProxy();
10 | boolean hasPermission(String permission);
11 | void sendMessage(String message);
12 | String getName();
13 | }
14 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/locale/BungeeCommandLocale.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.locale;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 20/10/2024
7 | */
8 | public class BungeeCommandLocale {
9 |
10 | public String getBungeeOnly() {
11 | return "&cThis command can only be run through bungee.";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/condition/ExecuteCondition.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.condition;
2 |
3 | import net.j4c0b3y.api.command.actor.Actor;
4 |
5 | /**
6 | * @author J4C0B3Y
7 | * @version CommandAPI
8 | * @since 25/10/2024
9 | */
10 | public interface ExecuteCondition {
11 | boolean validate(Actor actor, T annotation);
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/binding/InvalidBindingException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.binding;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 27/08/2024
7 | */
8 | public class InvalidBindingException extends RuntimeException {
9 | public InvalidBindingException(String message) {
10 | super(message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/registration/InvalidHandleException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.registration;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 28/08/2024
7 | */
8 | public class InvalidHandleException extends RuntimeException {
9 | public InvalidHandleException(String message) {
10 | super(message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/registration/InvalidWrapperException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.registration;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 28/08/2024
7 | */
8 | public class InvalidWrapperException extends RuntimeException {
9 | public InvalidWrapperException(String message) {
10 | super(message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/execution/MissingValidatorException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.execution;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 25/10/2024
7 | */
8 | public class MissingValidatorException extends RuntimeException {
9 |
10 | public MissingValidatorException(String message) {
11 | super(message);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/registration/InvalidParameterException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.registration;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 3/11/2024
7 | */
8 | public class InvalidParameterException extends RuntimeException {
9 | public InvalidParameterException(String message) {
10 | super(message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/registration/MissingProviderException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.registration;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 27/08/2024
7 | */
8 | public class MissingProviderException extends RuntimeException {
9 | public MissingProviderException(String message) {
10 | super(message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/registration/ParameterStructureException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.registration;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 28/08/2024
7 | */
8 | public class ParameterStructureException extends RuntimeException {
9 | public ParameterStructureException(String message) {
10 | super(message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/actor/PlayerActor.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.actor;
2 |
3 | import java.util.UUID;
4 |
5 | /**
6 | * @author J4C0B3Y
7 | * @version CommandAPI
8 | * @since 28/08/2024
9 | */
10 | public interface PlayerActor {
11 | boolean isPlayer();
12 | UUID getUniqueId();
13 | boolean hasPermission(String permission);
14 | void sendMessage(String message);
15 | String getName();
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/ProviderType.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 |
6 | /**
7 | * @author J4C0B3Y
8 | * @version CommandAPI
9 | * @since 30/08/2024
10 | */
11 | @Getter
12 | @RequiredArgsConstructor
13 | public enum ProviderType {
14 | ARGUMENT(true),
15 | CONTEXT(false);
16 |
17 | private final boolean consumer;
18 | }
19 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/modifier/ArgumentModifier.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.modifier;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
5 |
6 | /**
7 | * @author J4C0B3Y
8 | * @version CommandAPI
9 | * @since 27/08/2024
10 | */
11 | public interface ArgumentModifier {
12 | T modify(T value, CommandExecution execution, CommandParameter parameter);
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Last.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Last {
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Optional.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 31/08/2024
12 | */
13 | @Target(ElementType.PARAMETER)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Optional {
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Text.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Last
14 | @Target(ElementType.PARAMETER)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface Text {
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/command/condition/Condition.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.command.condition;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 25/10/2024
12 | */
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Condition {
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/modifier/Modifier.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter.modifier;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 27/08/2024
12 | */
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Modifier {
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/argument/CommandArgument.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution.argument;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
6 |
7 | /**
8 | * @author J4C0B3Y
9 | * @version CommandAPI
10 | * @since 27/08/2024
11 | */
12 | @Getter
13 | @RequiredArgsConstructor
14 | public class CommandArgument {
15 | private final String value;
16 | private final CommandParameter parameter;
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/utils/ClassUtils.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.utils;
2 |
3 | import lombok.experimental.UtilityClass;
4 |
5 | import java.lang.invoke.MethodType;
6 |
7 | /**
8 | * @author J4C0B3Y
9 | * @version CommandAPI
10 | * @since 17/10/2024
11 | */
12 | @UtilityClass
13 | public class ClassUtils {
14 |
15 | @SuppressWarnings("unchecked")
16 | public Class wrap(Class type) {
17 | return (Class) MethodType.methodType(type).wrap().returnType();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Named.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 27/08/2024
12 | */
13 | @Target(ElementType.PARAMETER)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Named {
16 | String value();
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/registration/Ignore.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.registration;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Target({ElementType.TYPE, ElementType.METHOD})
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Ignore {
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/registration/RegistrationException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.registration;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 30/08/2024
7 | */
8 | public class RegistrationException extends RuntimeException {
9 | public RegistrationException(String message) {
10 | super(message);
11 | }
12 |
13 | public RegistrationException(String message, Throwable throwable) {
14 | super(message, throwable);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Default.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Target(ElementType.PARAMETER)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Default {
16 | String value();
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Manual.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 24/10/2024
12 | */
13 | @Target(ElementType.PARAMETER)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Manual {
16 | String value();
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Option.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 30/08/2024
12 | */
13 | @Target(ElementType.PARAMETER)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Option {
16 | String[] value();
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/classifier/Classifier.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter.classifier;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 27/08/2024
12 | */
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Classifier {
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/Flag.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Target(ElementType.PARAMETER)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Flag {
16 | String[] value() default {};
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/classifier/Label.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter.classifier;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 1/09/2024
12 | */
13 | @Classifier
14 | @Target(ElementType.PARAMETER)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface Label {
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/classifier/Sender.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter.classifier;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Classifier
14 | @Target(ElementType.PARAMETER)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface Sender {
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/command/Usage.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.command;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Target(ElementType.METHOD)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Usage {
16 | String value();
17 | String[] expanded() default {};
18 | }
19 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/execution/UnknownFlagException.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.execution;
2 |
3 | import lombok.Getter;
4 |
5 | /**
6 | * @author J4C0B3Y
7 | * @version CommandAPI
8 | * @since 7/09/2024
9 | */
10 | @Getter
11 | public class UnknownFlagException extends ExitMessage {
12 | public UnknownFlagException(String message, boolean showUsage) {
13 | super(message, showUsage);
14 | }
15 |
16 | public UnknownFlagException(String message) {
17 | this(message, false);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/locale/VelocityCommandLocale.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.locale;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 20/10/2024
7 | */
8 | public class VelocityCommandLocale {
9 |
10 | public String getVelocityOnly() {
11 | return "&cThis command can only be run through velocity.";
12 | }
13 |
14 | public String getPlayerOffline(String argument) {
15 | return "&cA player with name '" + argument + "' is not on the network.";
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/command/Requires.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.command;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Requires {
16 | String value();
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/command/Help.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.command;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 30/08/24
12 | */
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Help {
16 | String command() default "help";
17 | boolean register() default true;
18 | }
19 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/annotation/ConsoleSender.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.annotation;
2 |
3 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Classifier;
4 |
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * @author J4C0B3Y
12 | * @version CommandAPI
13 | * @since 25/10/2024
14 | */
15 | @Classifier
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Target(ElementType.PARAMETER)
18 | public @interface ConsoleSender {
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/modifier/Length.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter.modifier;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Modifier
14 | @Target(ElementType.PARAMETER)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface Length {
17 | int min() default 1;
18 | int max() default Integer.MAX_VALUE;
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/registration/Register.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.registration;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Target(ElementType.TYPE)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Register {
16 | String name();
17 | String[] aliases() default {};
18 | String description() default "";
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/parameter/modifier/Range.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.parameter.modifier;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 28/08/2024
12 | */
13 | @Modifier
14 | @Target(ElementType.PARAMETER)
15 | @Retention(RetentionPolicy.RUNTIME)
16 | public @interface Range {
17 | double min() default -Double.MAX_VALUE;
18 | double max() default Double.MAX_VALUE;
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/suggestion/CommandSuggestion.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.suggestion;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.command.CommandHandler;
6 | import net.j4c0b3y.api.command.actor.Actor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author J4C0B3Y
12 | * @version CommandAPI
13 | * @since 27/10/2024
14 | */
15 | @Getter
16 | @RequiredArgsConstructor
17 | public class CommandSuggestion {
18 | private final Actor actor;
19 | private final List arguments;
20 | private final CommandHandler handler;
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/usage/UsageHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution.usage;
2 |
3 | import net.j4c0b3y.api.command.actor.Actor;
4 | import net.j4c0b3y.api.command.wrapper.CommandHandle;
5 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 30/08/24
13 | */
14 | public interface UsageHandler {
15 | List getUsageMessage(Actor actor, CommandHandle handle, String label);
16 | List getHelpMessage(Actor actor, CommandWrapper wrapper, String label, List arguments);
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/actor/Actor.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.actor;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.command.CommandHandler;
6 |
7 | /**
8 | * @author J4C0B3Y
9 | * @version CommandAPI
10 | * @since 28/08/2024
11 | */
12 | @Getter
13 | @RequiredArgsConstructor
14 | public abstract class Actor implements PlayerActor, ConsoleActor, ProxyActor {
15 | private final CommandHandler handler;
16 |
17 | public abstract boolean hasPermission(String permission);
18 | public abstract void sendMessage(String message);
19 |
20 | public abstract String getName();
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/exception/execution/ExitMessage.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.exception.execution;
2 |
3 | import lombok.Getter;
4 |
5 | /**
6 | * @author J4C0B3Y
7 | * @version CommandAPI
8 | * @since 27/08/2024
9 | */
10 | @Getter
11 | public class ExitMessage extends RuntimeException {
12 | private final boolean showUsage;
13 |
14 | public ExitMessage(String message, boolean showUsage) {
15 | super(message);
16 | this.showUsage = showUsage;
17 | }
18 |
19 | public ExitMessage(String message) {
20 | this(message, false);
21 | }
22 |
23 | public ExitMessage() {
24 | this(null, true);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/annotation/command/Command.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.annotation.command;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 27/08/2024
12 | */
13 | @Target(ElementType.METHOD)
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface Command {
16 | String name();
17 | String description() default "";
18 | String[] aliases() default {};
19 |
20 | boolean hidden() default false;
21 | boolean async() default false;
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/ProvidedParameter.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 | import lombok.Setter;
6 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 29/08/2024
12 | */
13 | @Getter
14 | @RequiredArgsConstructor
15 | public class ProvidedParameter {
16 | private final CommandParameter parameter;
17 | private @Setter String argument;
18 |
19 | private boolean provided;
20 | private Object value;
21 |
22 | public void provide(Object value) {
23 | this.value = value;
24 | this.provided = true;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/locale/BukkitCommandLocale.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.locale;
2 |
3 | /**
4 | * @author J4C0B3Y
5 | * @version CommandAPI
6 | * @since 20/10/2024
7 | */
8 | public class BukkitCommandLocale {
9 |
10 | public String getInvalidWorld(String argument) {
11 | return "&cA world with name '" + argument + "' doesn't exist.";
12 | }
13 |
14 | public String getPlayerOffline(String argument) {
15 | return "&cA player with name '" + argument + "' is not online.";
16 | }
17 |
18 | public String getInvalidOfflinePlayer(String argument) {
19 | return "&cA player with name '" + argument + "' has never joined before.";
20 | }
21 |
22 | public String getBukkitOnly() {
23 | return "&cThis command can only be run through bukkit.";
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/context/LabelProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.context;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 1/09/2024
12 | */
13 | public class LabelProvider extends Provider {
14 |
15 | public LabelProvider() {
16 | super(ProviderType.CONTEXT);
17 | }
18 |
19 | @Override
20 | public String provide(CommandExecution execution, CommandArgument argument) {
21 | return execution.getLabel();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/StringProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 27/08/24
12 | */
13 | public class StringProvider extends Provider {
14 |
15 | public StringProvider() {
16 | super(ProviderType.ARGUMENT, "string");
17 | }
18 |
19 | @Override
20 | public String provide(CommandExecution execution, CommandArgument argument) {
21 | return argument.getValue();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/actor/ActorProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor;
2 |
3 | import net.j4c0b3y.api.command.actor.Actor;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 31/08/2024
13 | */
14 | public class ActorProvider extends Provider {
15 |
16 | public ActorProvider() {
17 | super(ProviderType.CONTEXT);
18 | }
19 |
20 | @Override
21 | public Actor provide(CommandExecution execution, CommandArgument argument) {
22 | return execution.getActor();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/context/CommandExecutionProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.context;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 27/08/2024
12 | */
13 | public class CommandExecutionProvider extends Provider {
14 |
15 | public CommandExecutionProvider() {
16 | super(ProviderType.CONTEXT);
17 | }
18 |
19 | @Override
20 | public CommandExecution provide(CommandExecution execution, CommandArgument argument) {
21 | return execution;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/context/InstanceProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.context;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 27/08/2024
12 | */
13 | public class InstanceProvider extends Provider {
14 | private final T instance;
15 |
16 | public InstanceProvider(T instance) {
17 | super(ProviderType.CONTEXT);
18 | this.instance = instance;
19 | }
20 |
21 | @Override
22 | public T provide(CommandExecution execution, CommandArgument argument) {
23 | return instance;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/context/CommandHandleProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.context;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.CommandHandle;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 1/09/2024
13 | */
14 | public class CommandHandleProvider extends Provider {
15 |
16 | public CommandHandleProvider() {
17 | super(ProviderType.CONTEXT);
18 | }
19 |
20 | @Override
21 | public CommandHandle provide(CommandExecution execution, CommandArgument argument) {
22 | return execution.getHandle();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/utils/StringUtils.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.utils;
2 |
3 | import lombok.experimental.UtilityClass;
4 |
5 | import java.util.Collections;
6 |
7 | /**
8 | * @author J4C0B3Y
9 | * @version CommandAPI
10 | * @since 30/08/24
11 | */
12 | @UtilityClass
13 | public class StringUtils {
14 | public String repeat(String content, int amount) {
15 | return String.join("", Collections.nCopies(amount, content));
16 | }
17 |
18 | public boolean startsWithIgnoreCase(String content, String prefix) {
19 | return content.toLowerCase().startsWith(prefix.toLowerCase());
20 | }
21 |
22 | public String decapitalize(String content) {
23 | if (content == null || content.isEmpty()) return content;
24 |
25 | char[] characters = content.toCharArray();
26 | characters[0] = Character.toLowerCase(characters[0]);
27 |
28 | return new String(characters);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/context/CommandWrapperProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.context;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 1/09/2024
13 | */
14 | public class CommandWrapperProvider extends Provider {
15 |
16 | public CommandWrapperProvider() {
17 | super(ProviderType.CONTEXT);
18 | }
19 |
20 | @Override
21 | public CommandWrapper provide(CommandExecution execution, CommandArgument argument) {
22 | return execution.getHandle().getWrapper();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024-Present J4C0B3Y
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/Clean_CommandAPI.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
11 |
17 |
18 |
19 | true
20 | true
21 | false
22 | false
23 |
24 |
25 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/actor/CommandSenderProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
7 | import org.bukkit.command.CommandSender;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 9/1/24
13 | */
14 | public class CommandSenderProvider extends Provider {
15 | private final BukkitActorProvider bukkitActorProvider;
16 |
17 | public CommandSenderProvider(BukkitActorProvider bukkitActorProvider) {
18 | super(ProviderType.CONTEXT);
19 | this.bukkitActorProvider = bukkitActorProvider;
20 | }
21 |
22 | @Override
23 | public CommandSender provide(CommandExecution execution, CommandArgument argument) {
24 | return bukkitActorProvider.provide(execution, argument).getSender();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/provider/actor/CommandSenderProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
7 | import net.md_5.bungee.api.CommandSender;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 25/10/2024
13 | */
14 | public class CommandSenderProvider extends Provider {
15 | private final BungeeActorProvider bungeeActorProvider;
16 |
17 | public CommandSenderProvider(BungeeActorProvider bungeeActorProvider) {
18 | super(ProviderType.CONTEXT);
19 | this.bungeeActorProvider = bungeeActorProvider;
20 | }
21 |
22 | @Override
23 | public CommandSender provide(CommandExecution execution, CommandArgument argument) {
24 | return bungeeActorProvider.provide(execution, argument).getSender();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/provider/actor/CommandSourceProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.provider.actor;
2 |
3 | import com.velocitypowered.api.command.CommandSource;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 20/10/2024
13 | */
14 | public class CommandSourceProvider extends Provider {
15 | private final VelocityActorProvider velocityActorProvider;
16 |
17 | public CommandSourceProvider(VelocityActorProvider velocityActorProvider) {
18 | super(ProviderType.CONTEXT);
19 | this.velocityActorProvider = velocityActorProvider;
20 | }
21 |
22 | @Override
23 | public CommandSource provide(CommandExecution execution, CommandArgument argument) {
24 | return velocityActorProvider.provide(execution, null).getSource();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/Publish_CommandAPI.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | true
21 | true
22 | false
23 | false
24 |
25 |
26 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/actor/ProxyActorProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor;
2 |
3 | import net.j4c0b3y.api.command.actor.ProxyActor;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 |
10 | /**
11 | * @author J4C0B3Y
12 | * @version CommandAPI
13 | * @since 9/1/24
14 | */
15 | public class ProxyActorProvider extends Provider {
16 |
17 | public ProxyActorProvider() {
18 | super(ProviderType.CONTEXT);
19 | }
20 |
21 | @Override
22 | public ProxyActor provide(CommandExecution execution, CommandArgument argument) {
23 | if (!execution.getActor().isProxy()) {
24 | throw new ExitMessage(execution.getHandler().getLocale().getProxyOnly());
25 | }
26 |
27 | return execution.getActor();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/actor/PlayerActorProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor;
2 |
3 | import net.j4c0b3y.api.command.actor.PlayerActor;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 |
10 | /**
11 | * @author J4C0B3Y
12 | * @version CommandAPI
13 | * @since 1/09/2024
14 | */
15 | public class PlayerActorProvider extends Provider {
16 |
17 | public PlayerActorProvider() {
18 | super(ProviderType.CONTEXT);
19 | }
20 |
21 | @Override
22 | public PlayerActor provide(CommandExecution execution, CommandArgument argument) {
23 | if (!execution.getActor().isPlayer()) {
24 | throw new ExitMessage(execution.getHandler().getLocale().getPlayerOnly());
25 | }
26 |
27 | return execution.getActor();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/actor/ConsoleActorProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor;
2 |
3 | import net.j4c0b3y.api.command.actor.ConsoleActor;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 |
10 | /**
11 | * @author J4C0B3Y
12 | * @version CommandAPI
13 | * @since 9/1/24
14 | */
15 | public class ConsoleActorProvider extends Provider {
16 |
17 | public ConsoleActorProvider() {
18 | super(ProviderType.CONTEXT);
19 | }
20 |
21 | @Override
22 | public ConsoleActor provide(CommandExecution execution, CommandArgument argument) {
23 | if (!execution.getActor().isConsole()) {
24 | throw new ExitMessage(execution.getHandler().getLocale().getConsoleOnly());
25 | }
26 |
27 | return execution.getActor();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/ParameterBinding.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding;
2 |
3 | import lombok.Getter;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 |
8 | import java.lang.annotation.Annotation;
9 | import java.util.List;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 27/08/2024
15 | */
16 | @Getter
17 | @RequiredArgsConstructor
18 | public class ParameterBinding {
19 | private final Class type;
20 | private final Provider provider;
21 | private final List> classifiers;
22 |
23 | public boolean provides(CommandParameter parameter) {
24 | if (parameter.getClassifiers().size() != classifiers.size()) {
25 | return false;
26 | }
27 |
28 | for (Annotation classifier : parameter.getClassifiers()) {
29 | if (!classifiers.contains(classifier.annotationType())) {
30 | return false;
31 | }
32 | }
33 |
34 | return true;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/utils/ListUtils.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.utils;
2 |
3 | import lombok.experimental.UtilityClass;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 | import java.util.List;
9 | import java.util.function.Function;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 28/08/2024
15 | */
16 | @UtilityClass
17 | public class ListUtils {
18 | public List map(List list, Function mapper) {
19 | List mapped = new ArrayList<>();
20 |
21 | for (T item : list) {
22 | mapped.add(mapper.apply(item));
23 | }
24 |
25 | return mapped;
26 | }
27 |
28 | public List map(T[] array, Function mapper) {
29 | return map(Arrays.asList(array), mapper);
30 | }
31 |
32 | public List reversed(List list) {
33 | List reversed = new ArrayList<>(list);
34 | Collections.reverse(reversed);
35 | return reversed;
36 | }
37 |
38 | public List asList(T[] array) {
39 | return new ArrayList<>(Arrays.asList(array));
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/CharacterProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 27/08/2024
13 | */
14 | public class CharacterProvider extends Provider {
15 |
16 | public CharacterProvider() {
17 | super(ProviderType.ARGUMENT, "character");
18 | }
19 |
20 | @Override
21 | public Character provide(CommandExecution execution, CommandArgument argument) {
22 | String value = argument.getValue();
23 |
24 | if (value.length() > 1) {
25 | throw new ExitMessage(execution.getHandler().getLocale()
26 | .getInvalidType("character", argument.getValue())
27 | );
28 | }
29 |
30 | return value.charAt(0);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/Build_CommandAPI.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | true
23 | true
24 | false
25 | false
26 |
27 |
28 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/UUIDProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 |
9 | import java.util.UUID;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 25/10/2024
15 | */
16 | public class UUIDProvider extends Provider {
17 |
18 | public UUIDProvider() {
19 | super(ProviderType.ARGUMENT, "uuid");
20 | }
21 |
22 | @Override
23 | public UUID provide(CommandExecution execution, CommandArgument argument) {
24 | try {
25 | return UUID.fromString(argument.getValue());
26 | } catch (IllegalArgumentException exception) {
27 | throw new ExitMessage(execution.getHandler().getLocale()
28 | .getInvalidType("uuid", argument.getValue())
29 | );
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/actor/BukkitActorProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.bukkit.BukkitCommandHandler;
4 | import net.j4c0b3y.api.command.bukkit.actor.BukkitActor;
5 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
6 | import net.j4c0b3y.api.command.execution.CommandExecution;
7 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 9/1/24
15 | */
16 | public class BukkitActorProvider extends Provider {
17 | private final BukkitCommandHandler handler;
18 |
19 | public BukkitActorProvider(BukkitCommandHandler handler) {
20 | super(ProviderType.CONTEXT);
21 | this.handler = handler;
22 | }
23 |
24 | @Override
25 | public BukkitActor provide(CommandExecution execution, CommandArgument argument) {
26 | if (!(execution.getActor() instanceof BukkitActor)) {
27 | throw new ExitMessage(handler.getBukkitLocale().getBukkitOnly());
28 | }
29 |
30 | return (BukkitActor) execution.getActor();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/provider/actor/BungeeActorProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.bungee.BungeeCommandHandler;
4 | import net.j4c0b3y.api.command.bungee.actor.BungeeActor;
5 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
6 | import net.j4c0b3y.api.command.execution.CommandExecution;
7 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 25/10/2024
15 | */
16 | public class BungeeActorProvider extends Provider {
17 | private final BungeeCommandHandler handler;
18 |
19 | public BungeeActorProvider(BungeeCommandHandler handler) {
20 | super(ProviderType.CONTEXT);
21 | this.handler = handler;
22 | }
23 |
24 | @Override
25 | public BungeeActor provide(CommandExecution execution, CommandArgument argument) {
26 | if (!(execution.getActor() instanceof BungeeActor)) {
27 | throw new ExitMessage(handler.getBungeeLocale().getBungeeOnly());
28 | }
29 |
30 | return (BungeeActor) execution.getActor();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/Provider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
7 |
8 | import java.util.Collections;
9 | import java.util.List;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 27/08/2024
15 | */
16 | @Getter
17 | public abstract class Provider {
18 | private final boolean consumer;
19 | private final String defaultName;
20 |
21 | public Provider(ProviderType type, String defaultName) {
22 | this.consumer = type.isConsumer();
23 | this.defaultName = defaultName;
24 | }
25 |
26 | public Provider(ProviderType type) {
27 | this(type, null);
28 | }
29 |
30 | public T flagDefault(CommandExecution execution) {
31 | return null;
32 | }
33 |
34 | public boolean isAsync() {
35 | return false;
36 | }
37 |
38 | public abstract T provide(CommandExecution execution, CommandArgument argument);
39 |
40 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
41 | return Collections.emptyList();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/modifier/impl/LengthModifier.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.modifier.impl;
2 |
3 | import net.j4c0b3y.api.command.annotation.parameter.modifier.Length;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
7 | import net.j4c0b3y.api.command.wrapper.binding.modifier.ArgumentModifier;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 28/08/2024
13 | */
14 | public class LengthModifier implements ArgumentModifier {
15 |
16 | @Override
17 | public String modify(String value, CommandExecution execution, CommandParameter parameter) {
18 | Length length = parameter.getAnnotation(Length.class);
19 |
20 | if (value.length() < length.min()) {
21 | throw new ExitMessage(execution.getHandler().getLocale().getBelowMinimum(
22 | String.valueOf(length.min()), value
23 | ));
24 | }
25 |
26 | if (value.length() > length.max()) {
27 | throw new ExitMessage(execution.getHandler().getLocale().getAboveMaximum(
28 | String.valueOf(length.max()), value
29 | ));
30 | }
31 |
32 | return value;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/provider/actor/VelocityActorProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.velocity.VelocityCommandHandler;
7 | import net.j4c0b3y.api.command.velocity.actor.VelocityActor;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 20/10/2024
15 | */
16 | public class VelocityActorProvider extends Provider {
17 | private final VelocityCommandHandler handler;
18 |
19 | public VelocityActorProvider(VelocityCommandHandler handler) {
20 | super(ProviderType.CONTEXT);
21 | this.handler = handler;
22 | }
23 |
24 | @Override
25 | public VelocityActor provide(CommandExecution execution, CommandArgument argument) {
26 | if (!(execution.getActor() instanceof VelocityActor)) {
27 | throw new ExitMessage(handler.getVelocityLocale().getVelocityOnly());
28 | }
29 |
30 | return (VelocityActor) execution.getActor();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/modifier/impl/RangeModifier.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.modifier.impl;
2 |
3 | import net.j4c0b3y.api.command.annotation.parameter.modifier.Range;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
7 | import net.j4c0b3y.api.command.wrapper.binding.modifier.ArgumentModifier;
8 |
9 | /**
10 | * @author J4C0B3Y
11 | * @version CommandAPI
12 | * @since 28/08/2024
13 | */
14 | public class RangeModifier implements ArgumentModifier {
15 |
16 | @Override
17 | public T modify(T value, CommandExecution execution, CommandParameter parameter) {
18 | Range range = parameter.getAnnotation(Range.class);
19 |
20 | if (value.doubleValue() < range.min()) {
21 | throw new ExitMessage(execution.getHandler().getLocale().getBelowMinimum(
22 | String.valueOf(range.min()), value.toString()
23 | ));
24 | }
25 |
26 | if (value.doubleValue() > range.max()) {
27 | throw new ExitMessage(execution.getHandler().getLocale().getAboveMaximum(
28 | String.valueOf(range.max()), value.toString()
29 | ));
30 | }
31 |
32 | return value;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/actor/PlayerSenderProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.bukkit.actor.BukkitActor;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import org.bukkit.entity.Player;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 9/1/24
15 | */
16 | public class PlayerSenderProvider extends Provider {
17 | private final BukkitActorProvider bukkitActorProvider;
18 |
19 | public PlayerSenderProvider(BukkitActorProvider bukkitActorProvider) {
20 | super(ProviderType.CONTEXT);
21 | this.bukkitActorProvider = bukkitActorProvider;
22 | }
23 |
24 | @Override
25 | public Player provide(CommandExecution execution, CommandArgument argument) {
26 | BukkitActor bukkitActor = bukkitActorProvider.provide(execution, null);
27 |
28 | if (!bukkitActor.isPlayer()) {
29 | throw new ExitMessage(execution.getHandler().getLocale().getPlayerOnly());
30 | }
31 |
32 | return (Player) bukkitActor.getSender();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/provider/actor/PlayerSenderProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.provider.actor;
2 |
3 | import com.velocitypowered.api.proxy.Player;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.velocity.actor.VelocityActor;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 20/10/2024
15 | */
16 | public class PlayerSenderProvider extends Provider {
17 | private final VelocityActorProvider velocityActorProvider;
18 |
19 | public PlayerSenderProvider(VelocityActorProvider velocityActorProvider) {
20 | super(ProviderType.CONTEXT);
21 | this.velocityActorProvider = velocityActorProvider;
22 | }
23 |
24 | @Override
25 | public Player provide(CommandExecution execution, CommandArgument argument) {
26 | VelocityActor velocityActor = velocityActorProvider.provide(execution, null);
27 |
28 | if (!velocityActor.isPlayer()) {
29 | throw new ExitMessage(execution.getHandler().getLocale().getPlayerOnly());
30 | }
31 |
32 | return (Player) velocityActor.getSource();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/provider/actor/ConsoleCommandSenderProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.bungee.actor.BungeeActor;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import net.md_5.bungee.api.CommandSender;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 25/10/2024
15 | */
16 | public class ConsoleCommandSenderProvider extends Provider {
17 | private final BungeeActorProvider bungeeActorProvider;
18 |
19 | public ConsoleCommandSenderProvider(BungeeActorProvider bungeeActorProvider) {
20 | super(ProviderType.CONTEXT);
21 | this.bungeeActorProvider = bungeeActorProvider;
22 | }
23 |
24 | @Override
25 | public CommandSender provide(CommandExecution execution, CommandArgument argument) {
26 | BungeeActor bungeeActor = bungeeActorProvider.provide(execution, argument);
27 |
28 | if (!bungeeActor.isConsole()) {
29 | throw new ExitMessage(execution.getHandler().getLocale().getConsoleOnly());
30 | }
31 |
32 | return bungeeActor.getSender();
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/provider/actor/ProxiedPlayerSenderProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.bungee.actor.BungeeActor;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import net.md_5.bungee.api.connection.ProxiedPlayer;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 25/10/2024
15 | */
16 | public class ProxiedPlayerSenderProvider extends Provider {
17 | private final BungeeActorProvider bungeeActorProvider;
18 |
19 | public ProxiedPlayerSenderProvider(BungeeActorProvider bungeeActorProvider) {
20 | super(ProviderType.CONTEXT);
21 | this.bungeeActorProvider = bungeeActorProvider;
22 | }
23 |
24 | @Override
25 | public ProxiedPlayer provide(CommandExecution execution, CommandArgument argument) {
26 | BungeeActor bungeeActor = bungeeActorProvider.provide(execution, null);
27 |
28 | if (!bungeeActor.isPlayer()) {
29 | throw new ExitMessage(execution.getHandler().getLocale().getPlayerOnly());
30 | }
31 |
32 | return (ProxiedPlayer) bungeeActor.getSender();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/utils/AnnotationUtils.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.utils;
2 |
3 | import lombok.experimental.UtilityClass;
4 |
5 | import java.lang.annotation.Annotation;
6 | import java.lang.reflect.AnnotatedElement;
7 | import java.util.ArrayList;
8 | import java.util.Arrays;
9 | import java.util.List;
10 | import java.util.function.Function;
11 |
12 | /**
13 | * @author J4C0B3Y
14 | * @version CommandAPI
15 | * @since 28/08/2024
16 | */
17 | @UtilityClass
18 | public class AnnotationUtils {
19 | public R getValue(AnnotatedElement element, Class type, Function mapper, R fallback) {
20 | T annotation = element.getAnnotation(type);
21 |
22 | if (annotation == null) {
23 | return fallback;
24 | }
25 |
26 | return mapper.apply(annotation);
27 | }
28 |
29 | public List getSpecial(List annotations, Class extends Annotation> type) {
30 | List special = new ArrayList<>();
31 |
32 | for (Annotation annotation : annotations) {
33 | if (annotation.annotationType().isAnnotationPresent(type)) {
34 | special.add(annotation);
35 | }
36 | }
37 |
38 | return special;
39 | }
40 |
41 | public List getSpecial(Annotation[] annotations, Class extends Annotation> type) {
42 | return getSpecial(Arrays.asList(annotations), type);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/actor/ConsoleCommandSenderProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.actor;
2 |
3 | import net.j4c0b3y.api.command.bukkit.actor.BukkitActor;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import org.bukkit.command.ConsoleCommandSender;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 9/1/24
15 | */
16 | public class ConsoleCommandSenderProvider extends Provider {
17 | private final BukkitActorProvider bukkitActorProvider;
18 |
19 | public ConsoleCommandSenderProvider(BukkitActorProvider bukkitActorProvider) {
20 | super(ProviderType.CONTEXT);
21 | this.bukkitActorProvider = bukkitActorProvider;
22 | }
23 |
24 | @Override
25 | public ConsoleCommandSender provide(CommandExecution execution, CommandArgument argument) {
26 | BukkitActor bukkitActor = bukkitActorProvider.provide(execution, null);
27 |
28 | if (!bukkitActor.isConsole()) {
29 | throw new ExitMessage(execution.getHandler().getLocale().getConsoleOnly());
30 | }
31 |
32 | return (ConsoleCommandSender) bukkitActor.getSender();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/argument/flag/CommandFlag.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution.argument.flag;
2 |
3 | import lombok.experimental.UtilityClass;
4 | import net.j4c0b3y.api.command.CommandHandler;
5 | import net.j4c0b3y.api.command.exception.execution.UnknownFlagException;
6 | import net.j4c0b3y.api.command.utils.StringUtils;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 1/09/2024
12 | */
13 | @UtilityClass
14 | public class CommandFlag {
15 | public String getName(String flag) {
16 | return flag.replaceAll("^-+", "");
17 | }
18 |
19 | public String getFlag(String name) {
20 | return StringUtils.repeat("-", Math.min(name.length(), 2)) + name;
21 | }
22 |
23 | public String validate(String argument, CommandHandler handler) throws UnknownFlagException {
24 | int length = argument.length();
25 | int hyphens = length - getName(argument).length();
26 |
27 | if (hyphens == 1 && length != 2) {
28 | throw new UnknownFlagException(handler.getLocale().getFlagDoubleHyphen(argument));
29 | }
30 |
31 | if (hyphens == 2 && length < 4) {
32 | throw new UnknownFlagException(handler.getLocale().getFlagNameTooShort(argument));
33 | }
34 |
35 | if (hyphens >= 3) {
36 | throw new UnknownFlagException(handler.getLocale().getFlagNameHyphen(argument));
37 | }
38 |
39 | return hyphens != 0 ? argument.substring(hyphens) : null;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/provider/actor/ConsoleCommandSourceProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.provider.actor;
2 |
3 | import com.velocitypowered.api.proxy.ConsoleCommandSource;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.velocity.actor.VelocityActor;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 25/10/2024
15 | */
16 | public class ConsoleCommandSourceProvider extends Provider {
17 | private final VelocityActorProvider velocityActorProvider;
18 |
19 | public ConsoleCommandSourceProvider(VelocityActorProvider velocityActorProvider) {
20 | super(ProviderType.CONTEXT);
21 | this.velocityActorProvider = velocityActorProvider;
22 | }
23 |
24 | @Override
25 | public ConsoleCommandSource provide(CommandExecution execution, CommandArgument argument) {
26 | VelocityActor velocityActor = velocityActorProvider.provide(execution, argument);
27 |
28 | if (!velocityActor.isConsole()) {
29 | throw new ExitMessage(execution.getHandler().getLocale().getConsoleOnly());
30 | }
31 |
32 | return (ConsoleCommandSource) velocityActor.getSource();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/NumberProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 |
9 | import java.util.function.Function;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 20/10/2024
15 | */
16 | public class NumberProvider extends Provider {
17 | private final Function parser;
18 | private final String type;
19 | private final T flagDefault;
20 |
21 | public NumberProvider(Function parser, String type, T flagDefault) {
22 | super(ProviderType.ARGUMENT);
23 | this.parser = parser;
24 | this.type = type;
25 | this.flagDefault = flagDefault;
26 | }
27 |
28 | @Override
29 | public T flagDefault(CommandExecution execution) {
30 | return flagDefault;
31 | }
32 |
33 | @Override
34 | public T provide(CommandExecution execution, CommandArgument argument) {
35 | try {
36 | return parser.apply(argument.getValue());
37 | } catch (NumberFormatException exception) {
38 | throw new ExitMessage(execution.getHandler().getLocale()
39 | .getInvalidType(type, argument.getValue())
40 | );
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/utils/ClassUtils.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.utils;
2 |
3 | import lombok.experimental.UtilityClass;
4 |
5 | import java.lang.reflect.Constructor;
6 | import java.lang.reflect.Field;
7 |
8 | /**
9 | * @author J4C0B3Y
10 | * @version CommandAPI
11 | * @since 30/08/2024
12 | */
13 | @UtilityClass
14 | public class ClassUtils {
15 | public void ifPresent(String className, Runnable callback) {
16 | try {
17 | Class.forName(className);
18 | callback.run();
19 | } catch (ClassNotFoundException exception) {
20 | // ignored
21 | }
22 | }
23 |
24 | public Object getField(Object object, Class> type, String name) throws ReflectiveOperationException {
25 | Field field = type.getDeclaredField(name);
26 | field.setAccessible(true);
27 | return field.get(object);
28 | }
29 |
30 | public Object getField(Object object, String name) throws ReflectiveOperationException {
31 | return getField(object, object.getClass(), name);
32 | }
33 |
34 | public void setField(Object object, Class> type, String name, Object value) throws ReflectiveOperationException {
35 | Field field = type.getDeclaredField(name);
36 | field.setAccessible(true);
37 | field.set(object, value);
38 | }
39 |
40 | public Constructor getConstructor(Class clazz, Class> ...parameters) throws ReflectiveOperationException {
41 | Constructor constructor = clazz.getDeclaredConstructor(parameters);
42 | constructor.setAccessible(true);
43 | return constructor;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/argument/EnchantmentProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.argument;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
9 | import org.bukkit.enchantments.Enchantment;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | /**
15 | * @author J4C0B3Y
16 | * @version CommandAPI
17 | * @since 25/10/2024
18 | */
19 | public class EnchantmentProvider extends Provider {
20 |
21 | public EnchantmentProvider() {
22 | super(ProviderType.ARGUMENT, "enchantment");
23 | }
24 |
25 | @Override
26 | public Enchantment provide(CommandExecution execution, CommandArgument argument) {
27 | Enchantment enchantment = Enchantment.getByName(argument.getValue().toUpperCase());
28 |
29 | if (enchantment == null) {
30 | throw new ExitMessage(execution.getHandler().getLocale()
31 | .getInvalidEnum(argument.getValue(), suggest(null, null))
32 | );
33 | }
34 |
35 | return enchantment;
36 | }
37 |
38 | @Override
39 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
40 | List suggestions = new ArrayList<>();
41 |
42 | for (Enchantment enchantment : Enchantment.values()) {
43 | suggestions.add(enchantment.getName());
44 | }
45 |
46 | return suggestions;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/modifier/ModifierHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.modifier;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
5 |
6 | import java.lang.annotation.Annotation;
7 | import java.util.ArrayList;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | /**
13 | * @author J4C0B3Y
14 | * @version CommandAPI
15 | * @since 27/08/2024
16 | */
17 | public class ModifierHandler {
18 | private final Map, Map, List>>> modifiers = new HashMap<>();
19 |
20 | public void put(Class type, Class extends Annotation> annotation, ArgumentModifier modifier) {
21 | modifiers.computeIfAbsent(annotation, key -> new HashMap<>()).computeIfAbsent(type, key -> new ArrayList<>()).add(modifier);
22 | }
23 |
24 | @SuppressWarnings("unchecked")
25 | public T modify(T value, CommandExecution execution, CommandParameter parameter) {
26 | for (Annotation annotation : parameter.getModifiers()) {
27 | if (value == null) break;
28 |
29 | Map, List>> map = this.modifiers.get(annotation.annotationType());
30 | if (map == null) continue;
31 |
32 | List> modifiers = map.get(value.getClass());
33 | if (modifiers == null) continue;
34 |
35 | for (ArgumentModifier> modifier : modifiers) {
36 | value = ((ArgumentModifier) modifier).modify(value, execution, parameter);
37 | }
38 | }
39 |
40 | return value;
41 | }
42 |
43 | public void clear() {
44 | modifiers.clear();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/MapProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
9 |
10 | import java.util.ArrayList;
11 | import java.util.List;
12 | import java.util.Map;
13 | import java.util.function.Supplier;
14 |
15 | /**
16 | * @author J4C0B3Y
17 | * @version CommandAPI
18 | * @since 1/02/2025
19 | */
20 | public class MapProvider> extends Provider {
21 |
22 | private final Supplier supplier;
23 | private final String keyName;
24 |
25 | public MapProvider(Supplier supplier, String keyName, String valueName) {
26 | super(ProviderType.ARGUMENT, valueName);
27 | this.supplier = supplier;
28 | this.keyName = keyName;
29 | }
30 |
31 | @Override
32 | public T provide(CommandExecution execution, CommandArgument argument) {
33 | T value = supplier.get().get(argument.getValue());
34 |
35 | if (value == null) {
36 | throw new ExitMessage(execution.getHandler().getLocale()
37 | .getMapEntryNotFound(argument.getValue(), keyName, getDefaultName())
38 | );
39 | }
40 |
41 | return value;
42 | }
43 |
44 | @Override
45 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
46 | return new ArrayList<>(supplier.get().keySet());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/condition/ConditionHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.condition;
2 |
3 | import net.j4c0b3y.api.command.actor.Actor;
4 | import net.j4c0b3y.api.command.annotation.command.condition.Condition;
5 | import net.j4c0b3y.api.command.exception.execution.MissingValidatorException;
6 |
7 | import java.lang.annotation.Annotation;
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | /**
12 | * @author J4C0B3Y
13 | * @version CommandAPI
14 | * @since 25/10/2024
15 | */
16 | public class ConditionHandler {
17 | private final Map, ExecuteCondition>> conditions = new HashMap<>();
18 |
19 | public void put(Class annotation, ExecuteCondition condition) {
20 | if (!annotation.isAnnotation() || !annotation.isAnnotationPresent(Condition.class)) {
21 | throw new IllegalArgumentException(annotation.getSimpleName() + " must be an annotation marked @Condition.");
22 | }
23 |
24 | conditions.put(annotation, condition);
25 | }
26 |
27 | @SuppressWarnings("unchecked")
28 | public boolean validate(T annotation, Actor actor) {
29 | Class> type = annotation.annotationType();
30 |
31 | if (!type.isAnnotationPresent(Condition.class)) {
32 | throw new IllegalArgumentException("Cannot validate using a non @Condition annotation.");
33 | }
34 |
35 | if (!conditions.containsKey(annotation.annotationType())) {
36 | throw new MissingValidatorException("No validator bound for condition '@" + type.getSimpleName() + "'.");
37 | }
38 |
39 | ExecuteCondition condition = (ExecuteCondition) conditions.get(type);
40 | return condition.validate(actor, annotation);
41 | }
42 |
43 | public void clear() {
44 | conditions.clear();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/actor/BukkitActor.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.actor;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.command.CommandHandler;
5 | import net.j4c0b3y.api.command.actor.Actor;
6 | import org.bukkit.command.CommandSender;
7 | import org.bukkit.command.ConsoleCommandSender;
8 | import org.bukkit.entity.Player;
9 |
10 | import java.util.UUID;
11 |
12 | /**
13 | * @author J4C0B3Y
14 | * @version CommandAPI
15 | * @since 30/08/2024
16 | */
17 | @Getter
18 | public class BukkitActor extends Actor {
19 | private final CommandSender sender;
20 |
21 | public BukkitActor(CommandSender sender, CommandHandler handler) {
22 | super(handler);
23 | this.sender = sender;
24 | }
25 |
26 | @Override
27 | public boolean hasPermission(String permission) {
28 | return permission == null || sender.hasPermission(permission);
29 | }
30 |
31 | @Override
32 | public void sendMessage(String message) {
33 | sender.sendMessage(getHandler().getTranslator().apply(message));
34 | }
35 |
36 | @Override
37 | public boolean isConsole() {
38 | return sender instanceof ConsoleCommandSender;
39 | }
40 |
41 | @Override
42 | public boolean isPlayer() {
43 | return sender instanceof Player;
44 | }
45 |
46 | @Override
47 | public UUID getUniqueId() {
48 | return isPlayer() ? ((Player) sender).getUniqueId() : null;
49 | }
50 |
51 | @Override
52 | public String getName() {
53 | return sender.getName();
54 | }
55 |
56 | public Player getPlayer() {
57 | if (!isPlayer()) {
58 | throw new IllegalStateException("Sender is not a player!");
59 | }
60 |
61 | return (Player) sender;
62 | }
63 |
64 | @Override
65 | public boolean isProxy() {
66 | return false;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/provider/argument/PlayerProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.provider.argument;
2 |
3 | import com.velocitypowered.api.proxy.Player;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.velocity.VelocityCommandHandler;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
10 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.Optional;
15 |
16 | /**
17 | * @author J4C0B3Y
18 | * @version CommandAPI
19 | * @since 15/6/2025
20 | */
21 | public class PlayerProvider extends Provider {
22 | private final VelocityCommandHandler handler;
23 |
24 | public PlayerProvider(VelocityCommandHandler handler) {
25 | super(ProviderType.ARGUMENT, "player");
26 | this.handler = handler;
27 | }
28 |
29 | @Override
30 | public Player provide(CommandExecution execution, CommandArgument argument) {
31 | Optional player = handler.getProxy().getPlayer(argument.getValue());
32 |
33 | if (player.isEmpty()) {
34 | throw new ExitMessage(handler.getVelocityLocale().getPlayerOffline(argument.getValue()));
35 | }
36 |
37 | return player.get();
38 | }
39 |
40 | @Override
41 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
42 | List suggestions = new ArrayList<>();
43 |
44 | for (Player player : handler.getProxy().getAllPlayers()) {
45 | suggestions.add(player.getUsername());
46 | }
47 |
48 | return suggestions;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/ArrayProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.execution.CommandExecution;
4 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
7 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
8 |
9 | import java.lang.reflect.Array;
10 | import java.util.List;
11 |
12 | /**
13 | * @author J4C0B3Y
14 | * @version CommandAPI
15 | * @since 4/10/2025
16 | */
17 | public class ArrayProvider extends Provider {
18 |
19 | private final Provider> provider;
20 | private final Class> type;
21 |
22 | public ArrayProvider(Provider> provider, Class type) {
23 | super(ProviderType.ARGUMENT, provider.getDefaultName() + "s");
24 |
25 | if (type.isPrimitive()) {
26 | throw new IllegalArgumentException("Primitive array parameters are not supported.");
27 | }
28 |
29 | this.provider = provider;
30 | this.type = type;
31 | }
32 |
33 | @Override
34 | @SuppressWarnings("unchecked")
35 | public T[] provide(CommandExecution execution, CommandArgument argument) {
36 | String[] arguments = argument.getValue().split(" ");
37 | T[] values = (T[]) Array.newInstance(type, arguments.length);
38 |
39 | for (int i = 0; i < arguments.length; i++) {
40 | values[i] = (T) provider.provide(execution,
41 | new CommandArgument(arguments[i], argument.getParameter())
42 | );
43 | }
44 |
45 | return values;
46 | }
47 |
48 | @Override
49 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
50 | return provider.suggest(suggestion, argument);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/argument/WorldProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.argument;
2 |
3 | import net.j4c0b3y.api.command.bukkit.BukkitCommandHandler;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.World;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * @author J4C0B3Y
18 | * @version CommandAPI
19 | * @since 20/10/2024
20 | */
21 | public class WorldProvider extends Provider {
22 | private final BukkitCommandHandler handler;
23 |
24 | public WorldProvider(BukkitCommandHandler handler) {
25 | super(ProviderType.ARGUMENT, "world");
26 | this.handler = handler;
27 | }
28 |
29 | @Override
30 | public World flagDefault(CommandExecution execution) {
31 | return Bukkit.getWorlds().get(0);
32 | }
33 |
34 | @Override
35 | public World provide(CommandExecution execution, CommandArgument argument) {
36 | World world = Bukkit.getWorld(argument.getValue());
37 |
38 | if (world == null) {
39 | throw new ExitMessage(handler.getBukkitLocale().getInvalidWorld(argument.getValue()));
40 | }
41 |
42 | return world;
43 | }
44 |
45 | @Override
46 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
47 | List suggestions = new ArrayList<>();
48 |
49 | for (World world : Bukkit.getWorlds()) {
50 | suggestions.add(world.getName());
51 | }
52 |
53 | return suggestions;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/listener/AsyncTabListener.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.listener;
2 |
3 | import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent;
4 | import lombok.RequiredArgsConstructor;
5 | import net.j4c0b3y.api.command.bukkit.BukkitCommandHandler;
6 | import net.j4c0b3y.api.command.bukkit.actor.BukkitActor;
7 | import net.j4c0b3y.api.command.utils.ListUtils;
8 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
9 | import org.bukkit.command.Command;
10 | import org.bukkit.entity.Player;
11 | import org.bukkit.event.EventHandler;
12 | import org.bukkit.event.Listener;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * @author J4C0B3Y
18 | * @version CommandAPI
19 | * @since 30/08/2024
20 | */
21 | @RequiredArgsConstructor
22 | public class AsyncTabListener implements Listener {
23 | private final BukkitCommandHandler handler;
24 |
25 | @EventHandler
26 | public void onTabComplete(AsyncTabCompleteEvent event) {
27 | if (!event.isCommand() || !event.getBuffer().contains(" ")) return;
28 |
29 | List arguments = ListUtils.asList(event.getBuffer().split(" ", -1));
30 | String name = arguments.remove(0);
31 |
32 | if (event.getSender() instanceof Player) {
33 | name = name.replaceFirst("/", "");
34 | }
35 |
36 | Command command = handler.getRegistry().getKnownCommands().get(name);
37 | if (command == null) return;
38 |
39 | CommandWrapper wrapper = handler.getRegistry().getWrappers().get(command);
40 | if (wrapper == null) return;
41 |
42 | List suggestions = wrapper.suggest(new BukkitActor(event.getSender(), handler), arguments);
43 |
44 | if (suggestions.isEmpty()) {
45 | return;
46 | }
47 |
48 | for (String suggestion : suggestions) {
49 | event.getCompletions().add(suggestion);
50 | }
51 |
52 | event.setHandled(true);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/provider/argument/ServerInfoProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.provider.argument;
2 |
3 | import net.j4c0b3y.api.command.bungee.BungeeCommandHandler;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
10 | import net.md_5.bungee.api.ProxyServer;
11 | import net.md_5.bungee.api.config.ServerInfo;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * @author J4C0B3Y
18 | * @version CommandAPI
19 | * @since 25/10/2024
20 | */
21 | public class ServerInfoProvider extends Provider {
22 | private final BungeeCommandHandler handler;
23 | private final ProxyServer proxy;
24 |
25 | public ServerInfoProvider(BungeeCommandHandler handler) {
26 | super(ProviderType.ARGUMENT, "server");
27 | this.handler = handler;
28 | this.proxy = handler.getPlugin().getProxy();
29 | }
30 |
31 | @Override
32 | public ServerInfo provide(CommandExecution execution, CommandArgument argument) {
33 | ServerInfo server = proxy.getServerInfo(argument.getValue());
34 |
35 | if (server == null) {
36 | throw new ExitMessage(handler.getLocale().getInvalidServer(argument.getValue()));
37 | }
38 |
39 | return server;
40 | }
41 |
42 | @Override
43 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
44 | List suggestions = new ArrayList<>();
45 |
46 | for (ServerInfo server : proxy.getServers().values()) {
47 | suggestions.add(server.getName());
48 | }
49 |
50 | return suggestions;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/actor/BungeeActor.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee.actor;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.command.CommandHandler;
5 | import net.j4c0b3y.api.command.actor.Actor;
6 | import net.md_5.bungee.api.CommandSender;
7 | import net.md_5.bungee.api.ProxyServer;
8 | import net.md_5.bungee.api.chat.TextComponent;
9 | import net.md_5.bungee.api.connection.ProxiedPlayer;
10 |
11 | import java.util.UUID;
12 |
13 | /**
14 | * @author J4C0B3Y
15 | * @version CommandAPI
16 | * @since 30/08/2024
17 | */
18 | @Getter
19 | public class BungeeActor extends Actor {
20 | private final CommandSender sender;
21 |
22 | public BungeeActor(CommandSender sender, CommandHandler handler) {
23 | super(handler);
24 | this.sender = sender;
25 | }
26 |
27 | @Override
28 | public boolean hasPermission(String permission) {
29 | return permission == null || sender.hasPermission(permission);
30 | }
31 |
32 | @Override
33 | public void sendMessage(String message) {
34 | sender.sendMessage(new TextComponent(getHandler().getTranslator().apply(message)));
35 | }
36 |
37 | @Override
38 | public boolean isConsole() {
39 | return sender.equals(ProxyServer.getInstance().getConsole());
40 | }
41 |
42 | @Override
43 | public boolean isPlayer() {
44 | return sender instanceof ProxiedPlayer;
45 | }
46 |
47 | @Override
48 | public UUID getUniqueId() {
49 | return isPlayer() ? ((ProxiedPlayer) sender).getUniqueId() : null;
50 | }
51 |
52 | @Override
53 | public String getName() {
54 | return sender.getName();
55 | }
56 |
57 | public ProxiedPlayer getPlayer() {
58 | if (!isPlayer()) {
59 | throw new IllegalStateException("Sender is not a player!");
60 | }
61 |
62 | return (ProxiedPlayer) sender;
63 | }
64 |
65 | @Override
66 | public boolean isProxy() {
67 | return true;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/provider/argument/RegisteredServerProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.provider.argument;
2 |
3 | import com.velocitypowered.api.proxy.server.RegisteredServer;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.velocity.VelocityCommandHandler;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
10 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.Optional;
15 |
16 | /**
17 | * @author J4C0B3Y
18 | * @version CommandAPI
19 | * @since 20/10/2024
20 | */
21 | public class RegisteredServerProvider extends Provider {
22 | private final VelocityCommandHandler handler;
23 |
24 | public RegisteredServerProvider(VelocityCommandHandler handler) {
25 | super(ProviderType.ARGUMENT, "server");
26 | this.handler = handler;
27 | }
28 |
29 | @Override
30 | public RegisteredServer provide(CommandExecution execution, CommandArgument argument) {
31 | Optional server = handler.getProxy().getServer(argument.getValue());
32 |
33 | if (server.isEmpty()) {
34 | throw new ExitMessage(handler.getLocale().getInvalidServer(argument.getValue()));
35 | }
36 |
37 | return server.get();
38 | }
39 |
40 | @Override
41 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
42 | List suggestions = new ArrayList<>();
43 |
44 | for (RegisteredServer server : handler.getProxy().getAllServers()) {
45 | suggestions.add(server.getServerInfo().getName());
46 | }
47 |
48 | return suggestions;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/EnumProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.utils.StringUtils;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | /**
15 | * @author J4C0B3Y
16 | * @version CommandAPI
17 | * @since 20/10/2024
18 | */
19 | public class EnumProvider> extends Provider {
20 | private final Class type;
21 |
22 | public EnumProvider(Class type, String name) {
23 | super(ProviderType.ARGUMENT, name);
24 | this.type = type;
25 | }
26 |
27 | public EnumProvider(Class type) {
28 | this(type, StringUtils.decapitalize(type.getSimpleName()));
29 | }
30 |
31 | @Override
32 | public T provide(CommandExecution execution, CommandArgument argument) {
33 | String name = argument.getValue();
34 |
35 | for (T constant : type.getEnumConstants()) {
36 | if (constant.name().equalsIgnoreCase(name)) {
37 | return constant;
38 | }
39 | }
40 |
41 | throw new ExitMessage(execution.getHandler().getLocale()
42 | .getInvalidEnum(name, suggest(null, null))
43 | );
44 | }
45 |
46 | @Override
47 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
48 | List suggestions = new ArrayList<>();
49 |
50 | for (T constant : type.getEnumConstants()) {
51 | suggestions.add(constant.name());
52 | }
53 |
54 | return suggestions;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/argument/OfflinePlayerProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.argument;
2 |
3 | import net.j4c0b3y.api.command.bukkit.BukkitCommandHandler;
4 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
5 | import net.j4c0b3y.api.command.execution.CommandExecution;
6 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
9 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.OfflinePlayer;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * @author J4C0B3Y
18 | * @version CommandAPI
19 | * @since 9/1/24
20 | */
21 | public class OfflinePlayerProvider extends Provider {
22 | private final BukkitCommandHandler handler;
23 |
24 | public OfflinePlayerProvider(BukkitCommandHandler bukkitCommandHandler) {
25 | super(ProviderType.ARGUMENT, "player");
26 | this.handler = bukkitCommandHandler;
27 | }
28 |
29 | @Override
30 | @SuppressWarnings("deprecation")
31 | public OfflinePlayer provide(CommandExecution execution, CommandArgument argument) {
32 | OfflinePlayer player = Bukkit.getOfflinePlayer(argument.getValue());
33 |
34 | if (!player.hasPlayedBefore() && !player.isOnline() && player.getFirstPlayed() == 0) {
35 | throw new ExitMessage(handler.getBukkitLocale()
36 | .getInvalidOfflinePlayer(argument.getValue())
37 | );
38 | }
39 |
40 | return player;
41 | }
42 |
43 | @Override
44 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
45 | List suggestions = new ArrayList<>();
46 |
47 | for (OfflinePlayer player : Bukkit.getOfflinePlayers()) {
48 | suggestions.add(player.getName());
49 | }
50 |
51 | return suggestions;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/BindingHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding;
2 |
3 | import net.j4c0b3y.api.command.utils.ListUtils;
4 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
5 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument.ArrayProvider;
7 |
8 | import java.util.ArrayList;
9 | import java.util.HashMap;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | /**
14 | * @author J4C0B3Y
15 | * @version CommandAPI
16 | * @since 27/08/2024
17 | */
18 | public class BindingHandler {
19 | private final Map, List>> bindings = new HashMap<>();
20 |
21 | public void put(Class type, ParameterBinding binding) {
22 | bindings.computeIfAbsent(type, key -> new ArrayList<>()).add(binding);
23 | }
24 |
25 | public Provider> assign(CommandParameter parameter) {
26 | Class> type = parameter.getType();
27 |
28 | if (type.isArray()) {
29 | return new ArrayProvider<>(assign(type.getComponentType()), type.getComponentType());
30 | }
31 |
32 | List> bindings = this.bindings.get(parameter.getType());
33 | if (bindings == null) return null;
34 |
35 | for (ParameterBinding> binding : ListUtils.reversed(bindings)) {
36 | if (binding.provides(parameter)) {
37 | return binding.getProvider();
38 | }
39 | }
40 |
41 | return null;
42 | }
43 |
44 | @SuppressWarnings("unchecked")
45 | public Provider assign(Class type) {
46 | List> bindings = this.bindings.get(type);
47 | if (bindings == null) return null;
48 |
49 | for (ParameterBinding> binding : ListUtils.reversed(bindings)) {
50 | if (binding.getClassifiers().isEmpty()) {
51 | return (Provider) binding.getProvider();
52 | }
53 | }
54 |
55 | return null;
56 | }
57 |
58 | public void clear() {
59 | bindings.clear();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/actor/VelocityActor.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity.actor;
2 |
3 | import com.velocitypowered.api.command.CommandSource;
4 | import com.velocitypowered.api.proxy.ConsoleCommandSource;
5 | import com.velocitypowered.api.proxy.Player;
6 | import lombok.Getter;
7 | import net.j4c0b3y.api.command.actor.Actor;
8 | import net.j4c0b3y.api.command.velocity.VelocityCommandHandler;
9 |
10 | import java.util.UUID;
11 |
12 | /**
13 | * @author J4C0B3Y
14 | * @version CommandAPI
15 | * @since 30/08/2024
16 | */
17 | @Getter
18 | public class VelocityActor extends Actor {
19 | private final CommandSource source;
20 | private final VelocityCommandHandler handler;
21 |
22 | public VelocityActor(CommandSource source, VelocityCommandHandler handler) {
23 | super(handler);
24 | this.handler = handler;
25 | this.source = source;
26 | }
27 |
28 | @Override
29 | public boolean hasPermission(String permission) {
30 | return permission == null || source.hasPermission(permission);
31 | }
32 |
33 | @Override
34 | public void sendMessage(String message) {
35 | String translated = handler.getTranslator().apply(message);
36 | source.sendMessage(handler.getVelocityTranslator().apply(translated));
37 | }
38 |
39 | @Override
40 | public boolean isConsole() {
41 | return source instanceof ConsoleCommandSource;
42 | }
43 |
44 | @Override
45 | public boolean isPlayer() {
46 | return source instanceof Player;
47 | }
48 |
49 | @Override
50 | public UUID getUniqueId() {
51 | return isPlayer() ? ((Player) source).getUniqueId() : null;
52 | }
53 |
54 | @Override
55 | public String getName() {
56 | return isPlayer() ? ((Player) source).getUsername() : "CONSOLE";
57 | }
58 |
59 | public Player getPlayer() {
60 | if (!isPlayer()) {
61 | throw new IllegalStateException("Source is not a player!");
62 | }
63 |
64 | return (Player) source;
65 | }
66 |
67 | @Override
68 | public boolean isProxy() {
69 | return true;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/usage/impl/SimpleUsageHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution.usage.impl;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import net.j4c0b3y.api.command.actor.Actor;
5 | import net.j4c0b3y.api.command.execution.usage.UsageHandler;
6 | import net.j4c0b3y.api.command.wrapper.CommandHandle;
7 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
8 |
9 | import java.util.ArrayList;
10 | import java.util.Collections;
11 | import java.util.List;
12 |
13 | /**
14 | * @author J4C0B3Y
15 | * @version CommandAPI
16 | * @since 1/09/2024
17 | */
18 | @RequiredArgsConstructor
19 | public class SimpleUsageHandler implements UsageHandler {
20 |
21 | @Override
22 | public List getUsageMessage(Actor actor, CommandHandle handle, String label) {
23 | return Collections.singletonList("&7Usage: " + getFullUsage(handle, label));
24 | }
25 |
26 | @Override
27 | public List getHelpMessage(Actor actor, CommandWrapper wrapper, String label, List arguments) {
28 | if (arguments.isEmpty() || !arguments.get(0).equals(wrapper.getHelp().command())) {
29 | return null;
30 | }
31 |
32 | List lines = new ArrayList<>();
33 |
34 | lines.add("");
35 | lines.add("&7&m---&7 Showing help for &f/" + label + "&7. &m---");
36 | lines.add("");
37 |
38 | for (CommandHandle handle : wrapper.getHandles().values()) {
39 | if (handle.isHidden() || !actor.hasPermission(handle.getPermission())) continue;
40 |
41 | String description = handle.hasDescription() ? " (" + handle.getDescription() + ")" : "";
42 | lines.add("&7 » &f" + getFullUsage(handle, label) + "&7" + description);
43 | }
44 |
45 | lines.add("");
46 | return lines;
47 | }
48 |
49 | private String getFullUsage(CommandHandle handle, String label) {
50 | String labelSpace = !handle.getName().isEmpty() ? " " : "";
51 | String nameSpace = !handle.getUsage().isEmpty() ? " " : "";
52 |
53 | return "/" + label + labelSpace + handle.getName() + nameSpace + handle.getUsage();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/provider/impl/argument/BooleanProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument;
2 |
3 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
4 | import net.j4c0b3y.api.command.execution.CommandExecution;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
7 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
8 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Arrays;
12 | import java.util.List;
13 |
14 | /**
15 | * @author J4C0B3Y
16 | * @version CommandAPI
17 | * @since 27/08/2024
18 | */
19 | public class BooleanProvider extends Provider {
20 | private final static List TRUE_VALUES = Arrays.asList("true", "yes");
21 | private final static List FALSE_VALUES = Arrays.asList("false", "no");
22 |
23 | public BooleanProvider() {
24 | super(ProviderType.ARGUMENT, "boolean");
25 | }
26 |
27 | @Override
28 | public Boolean flagDefault(CommandExecution execution) {
29 | return false;
30 | }
31 |
32 | @Override
33 | public Boolean provide(CommandExecution execution, CommandArgument argument) {
34 | String lowered = argument.getValue().toLowerCase();
35 |
36 | for (String value : TRUE_VALUES) {
37 | if (lowered.equals(value)) {
38 | return true;
39 | }
40 | }
41 |
42 | for (String value : FALSE_VALUES) {
43 | if (lowered.equals(value)) {
44 | return false;
45 | }
46 | }
47 |
48 | throw new ExitMessage(execution.getHandler().getLocale()
49 | .getInvalidType("boolean", argument.getValue())
50 | );
51 | }
52 |
53 | @Override
54 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
55 | List suggestions = new ArrayList<>();
56 |
57 | suggestions.addAll(TRUE_VALUES);
58 | suggestions.addAll(FALSE_VALUES);
59 |
60 | return suggestions;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/BungeeCommandWrapper.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee;
2 |
3 | import net.j4c0b3y.api.command.bungee.actor.BungeeActor;
4 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
5 | import net.md_5.bungee.api.CommandSender;
6 | import net.md_5.bungee.api.ProxyServer;
7 | import net.md_5.bungee.api.plugin.Command;
8 | import net.md_5.bungee.api.plugin.TabExecutor;
9 |
10 | import java.util.Arrays;
11 | import java.util.List;
12 |
13 | /**
14 | * @author J4C0B3Y
15 | * @version CommandAPI
16 | * @since 30/08/2024
17 | */
18 | public class BungeeCommandWrapper extends CommandWrapper {
19 | private final BungeeCommandHandler bungeeHandler;
20 | private final BungeeCommand command;
21 |
22 | public BungeeCommandWrapper(Object instance, String name, List aliases, BungeeCommandHandler handler) {
23 | super(instance, name, aliases, handler);
24 | this.bungeeHandler = handler;
25 | this.command = new BungeeCommand(this);
26 | }
27 |
28 | @Override
29 | public void register() {
30 | ProxyServer.getInstance().getPluginManager().registerCommand(bungeeHandler.getPlugin(), command);
31 | }
32 |
33 | public static class BungeeCommand extends Command implements TabExecutor {
34 | private final BungeeCommandWrapper wrapper;
35 |
36 | public BungeeCommand(BungeeCommandWrapper wrapper) {
37 | super(wrapper.getName(), wrapper.getPermission(), wrapper.getAliases().toArray(new String[0]));
38 | this.wrapper = wrapper;
39 | }
40 |
41 | @Override
42 | public void execute(CommandSender sender, String[] arguments) {
43 | wrapper.dispatch(new BungeeActor(sender, wrapper.getHandler()), getName(), Arrays.asList(arguments));
44 | }
45 |
46 | @Override
47 | public Iterable onTabComplete(CommandSender sender, String[] arguments) {
48 | return wrapper.suggest(new BungeeActor(sender, wrapper.getHandler()), Arrays.asList(arguments));
49 | }
50 |
51 | @Override
52 | public boolean hasPermission(CommandSender sender) {
53 | return !wrapper.hasPermission() || sender.hasPermission(wrapper.getPermission());
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CommandAPI
2 |
3 | Powerful multi-platform annotation based command api.
4 |
5 | ###### Trusted and used by [Refine Development](https://refinedev.xyz/).
6 |
7 | ## Features
8 |
9 | - Asynchronous execution and tab completion
10 | - Annotation based command registration
11 | - Inbuilt command usage and help handler
12 | - Flexible flags system (eg, --silent)
13 | - Small and lightweight (~100kb)
14 | - Works on all major platforms
15 | - Supports spigot 1.8+
16 |
17 | ## Support
18 |
19 | If you need any assistance using or installing my CommandAPI,
20 | feel free to contact me by either adding me on discord (@J4C0B3Y)
21 | or by creating an issue and explaining your problem or question.
22 |
23 | ## Installation
24 |
25 | Prebuilt jars can be found in [releases](https://github.com/J4C0B3Y/CommandAPI/releases).
26 |
27 | > **NOTE:**
28 | > It is recommended to relocate the library to prevent
29 | > version mismatches with other plugins that use the api.
30 |
31 | ### Maven & Gradle
32 |
33 | - Replace `PLATFORM` with your desired platform. (eg, bukkit).
34 | - Replace `VERSION` with the latest release version on GitHub.
35 |
36 | ```kts
37 | repositories {
38 | maven("https://repo.j4c0b3y.net/public/")
39 | }
40 |
41 | dependencies {
42 | implementation("net.j4c0b3y.CommandAPI:PLATFORM:VERSION")
43 | }
44 | ```
45 |
46 | ```xml
47 |
48 |
49 | j4c0b3y-public
50 | https://repo.j4c0b3y.net/public/
51 |
52 |
53 |
54 |
55 |
56 | net.j4c0b3y.CommandAPI
57 | PLATFORM
58 | VERSION
59 |
60 |
61 | ```
62 |
63 | ### Building
64 |
65 | 1. Clone this repository and enter its directory.
66 | 2. Run the intellij build configuration by clicking the top right icon.
67 | 3. Alternatively you can run `gradle classes shadow delete copy install`.
68 | 4. The output jar files will be located in the `jars` directory.
69 |
70 | ## Usage
71 |
72 | Coming soon, for now message me on discord for help.
73 |
74 | ### Want more?
75 |
76 | Each and every class in my command api has detailed javadocs explaining what
77 | methods and variables are used for, and functionality of internal methods.
78 |
79 | > Made with ❤ // J4C0B3Y 2024
80 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/VelocityCommandWrapper.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity;
2 |
3 | import com.velocitypowered.api.command.CommandManager;
4 | import com.velocitypowered.api.command.CommandMeta;
5 | import com.velocitypowered.api.command.SimpleCommand;
6 | import net.j4c0b3y.api.command.utils.ListUtils;
7 | import net.j4c0b3y.api.command.velocity.actor.VelocityActor;
8 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
9 |
10 | import java.util.Arrays;
11 | import java.util.List;
12 | import java.util.concurrent.CompletableFuture;
13 |
14 | /**
15 | * @author J4C0B3Y
16 | * @version CommandAPI
17 | * @since 30/08/2024
18 | */
19 | public class VelocityCommandWrapper extends CommandWrapper implements SimpleCommand {
20 | private final VelocityCommandHandler velocityHandler;
21 |
22 | public VelocityCommandWrapper(Object instance, String name, List aliases, VelocityCommandHandler handler) {
23 | super(instance, name, aliases, handler);
24 | this.velocityHandler = handler;
25 | }
26 |
27 | @Override
28 | public void register() {
29 | CommandManager manager = velocityHandler.getProxy().getCommandManager();
30 |
31 | CommandMeta meta = manager.metaBuilder(getName())
32 | .aliases(getAliases().toArray(new String[0]))
33 | .build();
34 |
35 | manager.register(meta, this);
36 | }
37 |
38 | @Override
39 | public void execute(Invocation invocation) {
40 | dispatch(new VelocityActor(invocation.source(), velocityHandler), invocation.alias(), Arrays.asList(invocation.arguments()));
41 | }
42 |
43 | @Override
44 | public List suggest(Invocation invocation) {
45 | List arguments = ListUtils.asList(invocation.arguments());
46 |
47 | if (arguments.isEmpty()) {
48 | arguments.add("");
49 | }
50 |
51 | return suggest(new VelocityActor(invocation.source(), velocityHandler), arguments);
52 | }
53 |
54 | @Override
55 | public CompletableFuture> suggestAsync(Invocation invocation) {
56 | return CompletableFuture.supplyAsync(() -> suggest(invocation));
57 | }
58 |
59 | @Override
60 | public boolean hasPermission(Invocation invocation) {
61 | return !hasPermission() || invocation.source().hasPermission(getPermission());
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/provider/argument/PlayerProvider.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit.provider.argument;
2 |
3 | import net.j4c0b3y.api.command.actor.Actor;
4 | import net.j4c0b3y.api.command.bukkit.BukkitCommandHandler;
5 | import net.j4c0b3y.api.command.bukkit.actor.BukkitActor;
6 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
7 | import net.j4c0b3y.api.command.execution.CommandExecution;
8 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
9 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
10 | import net.j4c0b3y.api.command.wrapper.binding.provider.ProviderType;
11 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
12 | import org.bukkit.Bukkit;
13 | import org.bukkit.entity.Player;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | /**
19 | * @author J4C0B3Y
20 | * @version CommandAPI
21 | * @since 1/09/24
22 | */
23 | public class PlayerProvider extends Provider {
24 | private final BukkitCommandHandler handler;
25 |
26 | public PlayerProvider(BukkitCommandHandler handler) {
27 | super(ProviderType.ARGUMENT, "player");
28 | this.handler = handler;
29 | }
30 |
31 | @Override
32 | public Player provide(CommandExecution execution, CommandArgument argument) {
33 | Player player = Bukkit.getPlayer(argument.getValue());
34 |
35 | if (player == null || !canSee(execution.getActor(), player)) {
36 | throw new ExitMessage(handler.getBukkitLocale().getPlayerOffline(argument.getValue()));
37 | }
38 |
39 | return player;
40 | }
41 |
42 | @Override
43 | public List suggest(CommandSuggestion suggestion, CommandArgument argument) {
44 | List suggestions = new ArrayList<>();
45 |
46 | for (Player player : Bukkit.getOnlinePlayers()) {
47 | if (canSee(suggestion.getActor(), player)) {
48 | suggestions.add(player.getName());
49 | }
50 | }
51 |
52 | return suggestions;
53 | }
54 |
55 | private boolean canSee(Actor actor, Player target) {
56 | if (!(actor instanceof BukkitActor)) return true;
57 | BukkitActor bukkitActor = (BukkitActor) actor;
58 |
59 | if (!bukkitActor.isPlayer()) return true;
60 | Player player = (Player) bukkitActor.getSender();
61 |
62 | return player.canSee(target);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/bungee/src/main/java/net/j4c0b3y/api/command/bungee/BungeeCommandHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bungee;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import net.j4c0b3y.api.command.CommandHandler;
6 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Sender;
7 | import net.j4c0b3y.api.command.bungee.actor.BungeeActor;
8 | import net.j4c0b3y.api.command.bungee.annotation.ConsoleSender;
9 | import net.j4c0b3y.api.command.bungee.locale.BungeeCommandLocale;
10 | import net.j4c0b3y.api.command.bungee.provider.actor.BungeeActorProvider;
11 | import net.j4c0b3y.api.command.bungee.provider.actor.CommandSenderProvider;
12 | import net.j4c0b3y.api.command.bungee.provider.actor.ConsoleCommandSenderProvider;
13 | import net.j4c0b3y.api.command.bungee.provider.actor.ProxiedPlayerSenderProvider;
14 | import net.j4c0b3y.api.command.bungee.provider.argument.ServerInfoProvider;
15 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
16 | import net.md_5.bungee.api.ChatColor;
17 | import net.md_5.bungee.api.CommandSender;
18 | import net.md_5.bungee.api.config.ServerInfo;
19 | import net.md_5.bungee.api.connection.ProxiedPlayer;
20 | import net.md_5.bungee.api.plugin.Plugin;
21 |
22 | import java.util.List;
23 | import java.util.logging.Logger;
24 |
25 | /**
26 | * @author J4C0B3Y
27 | * @version CommandAPI
28 | * @since 27/08/2024
29 | */
30 | @Getter @Setter
31 | public class BungeeCommandHandler extends CommandHandler {
32 | private final Plugin plugin;
33 |
34 | private BungeeCommandLocale bungeeLocale = new BungeeCommandLocale();
35 |
36 | public BungeeCommandHandler(Plugin plugin) {
37 | this.plugin = plugin;
38 |
39 | setTranslator(text -> ChatColor.translateAlternateColorCodes('&', text));
40 | bindDefaults();
41 | }
42 |
43 | @Override
44 | public CommandWrapper wrap(Object wrapper, String name, List aliases) {
45 | return new BungeeCommandWrapper(wrapper, name, aliases, this);
46 | }
47 |
48 | @Override
49 | public Logger getLogger() {
50 | return plugin.getLogger();
51 | }
52 |
53 | @Override
54 | public void bindDefaults() {
55 | super.bindDefaults();
56 |
57 | BungeeActorProvider actorProvider = new BungeeActorProvider(this);
58 |
59 | bind(BungeeActor.class).annotated(Sender.class).to(actorProvider);
60 | bind(ProxiedPlayer.class).annotated(Sender.class).to(new ProxiedPlayerSenderProvider(actorProvider));
61 | bind(CommandSender.class).annotated(Sender.class).to(new CommandSenderProvider(actorProvider));
62 | bind(CommandSender.class).annotated(ConsoleSender.class).to(new ConsoleCommandSenderProvider(actorProvider));
63 |
64 | bind(ServerInfo.class).to(new ServerInfoProvider(this));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/velocity/src/main/java/net/j4c0b3y/api/command/velocity/VelocityCommandHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.velocity;
2 |
3 | import com.velocitypowered.api.command.CommandSource;
4 | import com.velocitypowered.api.proxy.ConsoleCommandSource;
5 | import com.velocitypowered.api.proxy.Player;
6 | import com.velocitypowered.api.proxy.ProxyServer;
7 | import com.velocitypowered.api.proxy.server.RegisteredServer;
8 | import lombok.Getter;
9 | import lombok.Setter;
10 | import net.j4c0b3y.api.command.CommandHandler;
11 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Sender;
12 | import net.j4c0b3y.api.command.velocity.actor.VelocityActor;
13 | import net.j4c0b3y.api.command.velocity.locale.VelocityCommandLocale;
14 | import net.j4c0b3y.api.command.velocity.provider.actor.CommandSourceProvider;
15 | import net.j4c0b3y.api.command.velocity.provider.actor.ConsoleCommandSourceProvider;
16 | import net.j4c0b3y.api.command.velocity.provider.actor.PlayerSenderProvider;
17 | import net.j4c0b3y.api.command.velocity.provider.actor.VelocityActorProvider;
18 | import net.j4c0b3y.api.command.velocity.provider.argument.PlayerProvider;
19 | import net.j4c0b3y.api.command.velocity.provider.argument.RegisteredServerProvider;
20 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
21 | import net.kyori.adventure.text.Component;
22 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
23 |
24 | import java.util.List;
25 | import java.util.function.Function;
26 | import java.util.logging.Logger;
27 |
28 | /**
29 | * @author J4C0B3Y
30 | * @version CommandAPI
31 | * @since 27/08/2024
32 | */
33 | @Getter @Setter
34 | public class VelocityCommandHandler extends CommandHandler {
35 | private final Object plugin;
36 | private final ProxyServer proxy;
37 | private final Logger logger;
38 |
39 | private VelocityCommandLocale velocityLocale = new VelocityCommandLocale();
40 | private Function velocityTranslator = LegacyComponentSerializer.legacyAmpersand()::deserialize;
41 |
42 | public VelocityCommandHandler(Object plugin, ProxyServer proxy, Logger logger) {
43 | this.plugin = plugin;
44 | this.proxy = proxy;
45 | this.logger = logger;
46 |
47 | bindDefaults();
48 | }
49 |
50 | @Override
51 | public CommandWrapper wrap(Object wrapper, String name, List aliases) {
52 | return new VelocityCommandWrapper(wrapper, name, aliases, this);
53 | }
54 |
55 | @Override
56 | public void bindDefaults() {
57 | super.bindDefaults();
58 |
59 | VelocityActorProvider actorProvider = new VelocityActorProvider(this);
60 |
61 | bind(VelocityActor.class).annotated(Sender.class).to(actorProvider);
62 | bind(Player.class).annotated(Sender.class).to(new PlayerSenderProvider(actorProvider));
63 | bind(CommandSource.class).annotated(Sender.class).to(new CommandSourceProvider(actorProvider));
64 | bind(ConsoleCommandSource.class).annotated(Sender.class).to(new ConsoleCommandSourceProvider(actorProvider));
65 |
66 | bind(Player.class).to(new PlayerProvider(this));
67 |
68 | bind(RegisteredServer.class).to(new RegisteredServerProvider(this));
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/BukkitCommandWrapper.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.command.bukkit.actor.BukkitActor;
5 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
6 | import net.j4c0b3y.api.command.wrapper.CommandHandle;
7 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
8 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
9 | import net.j4c0b3y.api.command.wrapper.suggestion.CommandSuggestion;
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.command.*;
12 |
13 | import java.util.Arrays;
14 | import java.util.List;
15 |
16 | /**
17 | * @author J4C0B3Y
18 | * @version CommandAPI
19 | * @since 30/08/2024
20 | */
21 | @Getter
22 | public class BukkitCommandWrapper extends CommandWrapper implements CommandExecutor, TabCompleter {
23 | private final BukkitCommandHandler bukkitHandler;
24 | private final PluginCommand command;
25 |
26 | public BukkitCommandWrapper(Object instance, String name, List aliases, BukkitCommandHandler handler) {
27 | super(instance, name, aliases, handler);
28 | this.bukkitHandler = handler;
29 | this.command = handler.getRegistry().getPluginCommand(this);
30 |
31 | this.command.setExecutor(this);
32 | this.command.setTabCompleter(this);
33 | this.command.setPermission(getPermission());
34 | this.command.setDescription(getDescription());
35 | this.command.setAliases(getAliases());
36 |
37 | registerPermissions();
38 | }
39 |
40 | @Override
41 | public void setPermission(String permission) {
42 | this.command.setPermission(permission);
43 | super.setPermission(permission);
44 | }
45 |
46 | @Override
47 | public void register() {
48 | bukkitHandler.getRegistry().register(this);
49 | }
50 |
51 | @Override
52 | public boolean onCommand(CommandSender sender, Command command, String label, String[] arguments) {
53 | dispatch(new BukkitActor(sender, getHandler()), label, Arrays.asList(arguments));
54 | return true;
55 | }
56 |
57 | @Override
58 | public List onTabComplete(CommandSender sender, Command command, String label, String[] arguments) {
59 | return suggest(new BukkitActor(sender, getHandler()), Arrays.asList(arguments));
60 | }
61 |
62 | @Override
63 | protected List suggestValue(Provider> provider, CommandSuggestion suggestion, CommandArgument argument) {
64 | if (provider.isAsync() || Bukkit.isPrimaryThread()) {
65 | return super.suggestValue(provider, suggestion, argument);
66 | }
67 |
68 | try {
69 | return bukkitHandler.callSync(() ->
70 | super.suggestValue(provider, suggestion, argument)
71 | ).get();
72 | } catch (Exception exception) {
73 | throw new RuntimeException("Failed to execute synchronous suggestion!", exception);
74 | }
75 | }
76 |
77 | private void registerPermissions() {
78 | BukkitCommandRegistry registry = bukkitHandler.getRegistry();
79 | registry.registerPermission(getPermission());
80 |
81 | for (CommandHandle handle : getHandles().values()) {
82 | registry.registerPermission(handle.getPermission());
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/locale/CommandLocale.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution.locale;
2 |
3 | import net.j4c0b3y.api.command.annotation.command.Help;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 | import java.util.List;
9 |
10 | /**
11 | * @author J4C0B3Y
12 | * @version CommandAPI
13 | * @since 1/09/2024
14 | */
15 | public class CommandLocale {
16 |
17 | public List getNoPermission() {
18 | return Collections.singletonList(
19 | "&cYou do not have permission to execute this command!"
20 | );
21 | }
22 |
23 | public List getExceptionOccurred() {
24 | return Arrays.asList(
25 | "&cAn exception occurred whilst executing this command!",
26 | "&7Please report this to a server staff member."
27 | );
28 | }
29 |
30 | public List getInvalidSubcommand(String label, Help help) {
31 | List lines = new ArrayList<>();
32 |
33 | lines.add("&cThat subcommand could not be found!");
34 |
35 | if (help != null) {
36 | lines.add("&7Run '/" + label + " " + help.command() + "' for a list of commands.");
37 | }
38 |
39 | return lines;
40 | }
41 |
42 | public String getMissingArgument(String parameter) {
43 | return "&cMissing argument for '" + parameter + "'.";
44 | }
45 |
46 | public String getFlagNameHyphen(String argument) {
47 | return "&cFlag '" + argument + "' cannot start with '-'.";
48 | }
49 |
50 | public String getFlagNameTooShort(String argument) {
51 | return "&cFlag '" + argument + "' must be more then one character.";
52 | }
53 |
54 | public String getFlagDoubleHyphen(String argument) {
55 | return "&cFlag '" + argument + "' must start with '--'.";
56 | }
57 |
58 | public String getFlagValueRequired(String argument) {
59 | return "&cFlag '" + argument + "' requires a value.";
60 | }
61 |
62 | public String getFlagSpecified(String argument) {
63 | return "&cFlag '" + argument + "' already specified.";
64 | }
65 |
66 | public String getUnknownFlag(String argument) {
67 | return "&cUnknown flag '" + argument + "'.";
68 | }
69 |
70 | public String getConsoleOnly() {
71 | return "&cThis command can only be run by console.";
72 | }
73 |
74 | public String getProxyOnly() {
75 | return "&cThis command can only be run on a proxy.";
76 | }
77 |
78 | public String getPlayerOnly() {
79 | return "&cThis command can only be run by players.";
80 | }
81 |
82 | public String getInvalidType(String expected, String argument) {
83 | return "&cType '" + expected + "' expected, '" + argument + "' found.";
84 | }
85 |
86 | public String getBelowMinimum(String minimum, String argument) {
87 | return "&cMinimum '" + minimum + "', found '" + argument + "'";
88 | }
89 |
90 | public String getAboveMaximum(String maximum, String argument) {
91 | return "&cMaximum '" + maximum + "', found '" + argument + "'";
92 | }
93 |
94 | public String getInvalidServer(String argument) {
95 | return "&cA server with name '" + argument + "' doesn't exist.";
96 | }
97 |
98 | public String getInvalidEnum(String argument, List valid) {
99 | return "&cNo value found for '" + argument + "', " +
100 | "valid: " + String.join(", ", valid) + ".";
101 | }
102 |
103 | public String getMapEntryNotFound(String argument, String keyName, String valueName) {
104 | return "&cA" + valueName + " with " + keyName + " '" + argument + "' was not found!";
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/BukkitCommandRegistry.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.command.bukkit.utils.ClassUtils;
5 | import net.j4c0b3y.api.command.exception.registration.RegistrationException;
6 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
7 | import org.bukkit.Bukkit;
8 | import org.bukkit.command.Command;
9 | import org.bukkit.command.PluginCommand;
10 | import org.bukkit.command.SimpleCommandMap;
11 | import org.bukkit.permissions.Permission;
12 | import org.bukkit.permissions.PermissionDefault;
13 | import org.bukkit.plugin.Plugin;
14 | import org.bukkit.plugin.PluginManager;
15 |
16 | import java.lang.reflect.Constructor;
17 | import java.util.*;
18 |
19 | /**
20 | * @author J4C0B3Y
21 | * @version CommandAPI
22 | * @since 31/08/2024
23 | */
24 | @Getter
25 | public class BukkitCommandRegistry {
26 | private final BukkitCommandHandler handler;
27 |
28 | private final SimpleCommandMap commandMap;
29 | private final Map knownCommands;
30 | private final Constructor pluginCommand;
31 |
32 | private final Map wrappers = new HashMap<>();
33 |
34 | @SuppressWarnings("unchecked")
35 | public BukkitCommandRegistry(BukkitCommandHandler handler) {
36 | this.handler = handler;
37 |
38 | try {
39 | this.commandMap = (SimpleCommandMap) ClassUtils.getField(Bukkit.getServer(), "commandMap");
40 | this.knownCommands = (Map) ClassUtils.getField(this.commandMap, SimpleCommandMap.class, "knownCommands");
41 | } catch (Exception exception) {
42 | throw new IllegalStateException("Failed to access command map!", exception);
43 | }
44 |
45 | try {
46 | this.pluginCommand = ClassUtils.getConstructor(PluginCommand.class, String.class, Plugin.class);
47 | } catch (Exception exception) {
48 | throw new IllegalStateException("Failed to access command constructor!", exception);
49 | }
50 | }
51 |
52 | public void register(BukkitCommandWrapper wrapper) {
53 | try {
54 | List labels = new ArrayList<>();
55 | labels.add(wrapper.getName());
56 | labels.addAll(wrapper.getAliases());
57 |
58 | for (String label : labels) {
59 | Command command = knownCommands.get(label);
60 | if (command == null) continue;
61 |
62 | if (command instanceof PluginCommand) {
63 | Plugin plugin = ((PluginCommand) command).getPlugin();
64 | if (plugin == handler.getPlugin()) continue;
65 |
66 | if (handler.isDebug()) {
67 | String origin = plugin.getDescription().getName();
68 | handler.getLogger().warning("Overriding command '" + label + "' from '" + origin + "'.");
69 | }
70 | }
71 |
72 | knownCommands.remove(label);
73 | }
74 |
75 | commandMap.register(handler.getPlugin().getName(), wrapper.getCommand());
76 | wrappers.put(wrapper.getCommand(), wrapper);
77 | } catch (Exception exception) {
78 | throw new RegistrationException("Failed to register wrapper in command map!", exception);
79 | }
80 | }
81 |
82 | public void registerPermission(String permission, String description) {
83 | if (permission == null) return;
84 |
85 | PluginManager pluginManager = handler.getPlugin().getServer().getPluginManager();
86 | if (pluginManager.getPermission(permission) != null) return;
87 |
88 | pluginManager.addPermission(new Permission(permission, description, PermissionDefault.OP));
89 | }
90 |
91 | public void registerPermission(String permission) {
92 | registerPermission(permission, "A permission registered by " + handler.getPlugin().getName());
93 | }
94 |
95 | public PluginCommand getPluginCommand(BukkitCommandWrapper wrapper) {
96 | try {
97 | return pluginCommand.newInstance(wrapper.getName(), handler.getPlugin());
98 | } catch (Exception exception) {
99 | throw new RegistrationException("Failed to instantiate plugin command!", exception);
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/binding/BindingBuilder.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper.binding;
2 |
3 | import lombok.RequiredArgsConstructor;
4 | import net.j4c0b3y.api.command.CommandHandler;
5 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Classifier;
6 | import net.j4c0b3y.api.command.annotation.parameter.modifier.Modifier;
7 | import net.j4c0b3y.api.command.exception.binding.InvalidBindingException;
8 | import net.j4c0b3y.api.command.utils.ClassUtils;
9 | import net.j4c0b3y.api.command.wrapper.binding.condition.ExecuteCondition;
10 | import net.j4c0b3y.api.command.wrapper.binding.modifier.ArgumentModifier;
11 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
12 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.context.InstanceProvider;
13 |
14 | import java.lang.annotation.Annotation;
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import java.util.function.Consumer;
18 |
19 | /**
20 | * @author J4C0B3Y
21 | * @version CommandAPI
22 | * @since 27/08/2024
23 | */
24 | @RequiredArgsConstructor
25 | public class BindingBuilder {
26 | private final Class type;
27 | private final CommandHandler handler;
28 |
29 | private final List> classifiers = new ArrayList<>();
30 | private Class extends Annotation> modifier;
31 |
32 | public BindingBuilder annotated(Class extends Annotation> annotation) {
33 | boolean classifier = annotation.isAnnotationPresent(Classifier.class);
34 | boolean modifier = annotation.isAnnotationPresent(Modifier.class);
35 |
36 | if (classifier && modifier) {
37 | throw new InvalidBindingException("Annotation '" + annotation.getSimpleName() + "' cannot be @Classifier and @Modifier.");
38 | }
39 |
40 | if (classifier) {
41 | if (this.modifier != null) {
42 | throw new InvalidBindingException("Cannot bind both @Classifier and @Modifier.");
43 | }
44 |
45 | if (classifiers.contains(annotation)) {
46 | throw new InvalidBindingException("Cannot bind @Classifier '" + annotation.getSimpleName() + "' multiple times.");
47 | }
48 |
49 | classifiers.add(annotation);
50 | return this;
51 | }
52 |
53 | if (modifier) {
54 | if (!classifiers.isEmpty()) {
55 | throw new InvalidBindingException("Cannot bind both @Modifier and @Classifier.");
56 | }
57 |
58 | if (this.modifier != null) {
59 | throw new InvalidBindingException("Cannot bind multiple @Modifier at once.");
60 | }
61 |
62 | this.modifier = annotation;
63 | return this;
64 | }
65 |
66 | throw new InvalidBindingException("Annotation '" + annotation.getSimpleName() + "' must have @Classifier or @Modifier.");
67 | }
68 |
69 | public void to(Provider provider) {
70 | if (modifier != null) {
71 | throw new InvalidBindingException("@Modifier cannot be bound to a provider.");
72 | }
73 |
74 | to(type -> handler.getBindingHandler().put(type, new ParameterBinding<>(type, provider, classifiers)));
75 | }
76 |
77 | public void to(T instance) {
78 | to(new InstanceProvider<>(instance));
79 | }
80 |
81 | public void to(ArgumentModifier modifier) {
82 | if (this.modifier == null) {
83 | throw new InvalidBindingException("No @Modifier was provided.");
84 | }
85 |
86 | to(type -> handler.getModifierHandler().put(type, this.modifier, modifier));
87 | }
88 |
89 | public void to(ExecuteCondition condition) {
90 | if (modifier != null) {
91 | throw new InvalidBindingException("Cannot bind @Modifier to a condition.");
92 | }
93 |
94 | if (!classifiers.isEmpty()) {
95 | throw new InvalidBindingException("Cannot bind @Classifier to a condition.");
96 | }
97 |
98 | handler.getConditionHandler().put(type, condition);
99 | }
100 |
101 | private void to(Consumer> binder) {
102 | // If the type is a primitive, bind its wrapper class.
103 | if (type.isPrimitive()) {
104 | binder.accept(ClassUtils.wrap(type));
105 | }
106 |
107 | binder.accept(type);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/wrapper/CommandParameter.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.wrapper;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.command.annotation.command.Requires;
5 | import net.j4c0b3y.api.command.annotation.parameter.*;
6 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Classifier;
7 | import net.j4c0b3y.api.command.annotation.parameter.modifier.Modifier;
8 | import net.j4c0b3y.api.command.exception.registration.InvalidParameterException;
9 | import net.j4c0b3y.api.command.exception.registration.MissingProviderException;
10 | import net.j4c0b3y.api.command.utils.AnnotationUtils;
11 | import net.j4c0b3y.api.command.utils.ListUtils;
12 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
13 |
14 | import java.lang.annotation.Annotation;
15 | import java.lang.reflect.Parameter;
16 | import java.util.Arrays;
17 | import java.util.Collections;
18 | import java.util.List;
19 |
20 | /**
21 | * @author J4C0B3Y
22 | * @version CommandAPI
23 | * @since 27/08/2024
24 | */
25 | @Getter
26 | public class CommandParameter {
27 | private final Class> type;
28 |
29 | private final List annotations;
30 | private final List classifiers;
31 | private final List modifiers;
32 |
33 | private final String name;
34 | private final String defaultValue;
35 | private final boolean optional;
36 |
37 | private final List options;
38 | private final List flagNames;
39 |
40 | private final Provider> provider;
41 | private final String permission;
42 |
43 | private final boolean last;
44 | private final boolean array;
45 | private final boolean combine;
46 |
47 | public CommandParameter(CommandHandle handle, Parameter parameter) {
48 | this.type = parameter.getType();
49 |
50 | this.annotations = Arrays.asList(parameter.getAnnotations());
51 | this.classifiers = AnnotationUtils.getSpecial(annotations, Classifier.class);
52 | this.modifiers = AnnotationUtils.getSpecial(annotations, Modifier.class);
53 |
54 | this.provider = handle.getWrapper().getHandler().getBindingHandler().assign(this);
55 |
56 | if (this.provider == null) {
57 | throw new MissingProviderException("Parameter '" + parameter.getName() + "' has no valid providers bound for '" + type.getSimpleName() + "'.");
58 | }
59 |
60 | this.permission = AnnotationUtils.getValue(parameter, Requires.class, Requires::value, null);
61 |
62 | String name = AnnotationUtils.getValue(parameter, Named.class, Named::value, provider.getDefaultName());
63 | this.name = name != null ? name : parameter.getName();
64 |
65 | this.defaultValue = AnnotationUtils.getValue(parameter, Default.class, Default::value, null);
66 | this.optional = defaultValue != null || parameter.isAnnotationPresent(Optional.class);
67 |
68 | if (hasPermission() && !optional) {
69 | throw new InvalidParameterException("Parameter '" + parameter.getName() + "' has @Requires but is not optional.");
70 | }
71 |
72 | this.options = AnnotationUtils.getValue(parameter, Option.class, option -> ListUtils.map(option.value(), String::toLowerCase), Collections.emptyList());
73 | this.flagNames = AnnotationUtils.getValue(parameter, Flag.class, flag -> ListUtils.asList(flag.value()), null);
74 |
75 | // Use the parameter name if no flag names are specified.
76 | if (flagNames != null && flagNames.isEmpty()) {
77 | flagNames.add(name);
78 | }
79 |
80 | this.array = type.isArray();
81 | this.last = !AnnotationUtils.getSpecial(annotations, Last.class).isEmpty() || type.isArray();
82 | this.combine = parameter.isAnnotationPresent(Text.class) || this.array;
83 |
84 | if (isCombine() && isFlag()) {
85 | throw new InvalidParameterException("Parameter '" + parameter.getName() + "' cannot be a flag.");
86 | }
87 | }
88 |
89 | public boolean isBoolean() {
90 | return type == boolean.class || type == Boolean.class;
91 | }
92 |
93 | public boolean isFlag() {
94 | return flagNames != null && !flagNames.isEmpty();
95 | }
96 |
97 | public boolean hasPermission() {
98 | return permission != null;
99 | }
100 |
101 | public boolean hasOption(String option) {
102 | return options.contains(option.toLowerCase());
103 | }
104 |
105 | @SuppressWarnings("unchecked")
106 | public T getAnnotation(Class type) {
107 | for (Annotation annotation : annotations) {
108 | if (annotation.annotationType().equals(type)) {
109 | return (T) annotation;
110 | }
111 | }
112 |
113 | return null;
114 | }
115 |
116 | public boolean hasAnnotation(Class extends Annotation> type) {
117 | return getAnnotation(type) != null;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/bukkit/src/main/java/net/j4c0b3y/api/command/bukkit/BukkitCommandHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.bukkit;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import net.j4c0b3y.api.command.CommandHandler;
6 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Sender;
7 | import net.j4c0b3y.api.command.bukkit.actor.BukkitActor;
8 | import net.j4c0b3y.api.command.bukkit.listener.AsyncTabListener;
9 | import net.j4c0b3y.api.command.bukkit.locale.BukkitCommandLocale;
10 | import net.j4c0b3y.api.command.bukkit.provider.actor.BukkitActorProvider;
11 | import net.j4c0b3y.api.command.bukkit.provider.actor.CommandSenderProvider;
12 | import net.j4c0b3y.api.command.bukkit.provider.actor.ConsoleCommandSenderProvider;
13 | import net.j4c0b3y.api.command.bukkit.provider.actor.PlayerSenderProvider;
14 | import net.j4c0b3y.api.command.bukkit.provider.argument.EnchantmentProvider;
15 | import net.j4c0b3y.api.command.bukkit.provider.argument.OfflinePlayerProvider;
16 | import net.j4c0b3y.api.command.bukkit.provider.argument.PlayerProvider;
17 | import net.j4c0b3y.api.command.bukkit.provider.argument.WorldProvider;
18 | import net.j4c0b3y.api.command.bukkit.utils.ClassUtils;
19 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
20 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument.EnumProvider;
21 | import org.bukkit.*;
22 | import org.bukkit.block.Biome;
23 | import org.bukkit.block.BlockFace;
24 | import org.bukkit.command.CommandSender;
25 | import org.bukkit.command.ConsoleCommandSender;
26 | import org.bukkit.enchantments.Enchantment;
27 | import org.bukkit.entity.EntityType;
28 | import org.bukkit.entity.Player;
29 | import org.bukkit.plugin.Plugin;
30 | import org.bukkit.potion.PotionType;
31 |
32 | import java.util.List;
33 | import java.util.concurrent.Callable;
34 | import java.util.concurrent.CompletableFuture;
35 | import java.util.concurrent.Future;
36 | import java.util.logging.Logger;
37 |
38 | /**
39 | * @author J4C0B3Y
40 | * @version CommandAPI
41 | * @since 27/08/2024
42 | */
43 | @Getter @Setter
44 | public class BukkitCommandHandler extends CommandHandler {
45 | private final Plugin plugin;
46 | private final BukkitCommandRegistry registry;
47 |
48 | private BukkitCommandLocale bukkitLocale = new BukkitCommandLocale();
49 |
50 | public BukkitCommandHandler(Plugin plugin) {
51 | this.plugin = plugin;
52 | this.registry = new BukkitCommandRegistry(this);
53 |
54 | setTranslator(text -> ChatColor.translateAlternateColorCodes('&', text));
55 |
56 | ClassUtils.ifPresent("com.destroystokyo.paper.event.server.AsyncTabCompleteEvent", () -> {
57 | plugin.getServer().getPluginManager().registerEvents(new AsyncTabListener(this), plugin);
58 | plugin.getLogger().info("Enabled async tab completion support.");
59 | });
60 |
61 | bindDefaults();
62 | }
63 |
64 | @Override
65 | public CommandWrapper wrap(Object wrapper, String name, List aliases) {
66 | return new BukkitCommandWrapper(wrapper, name, aliases, this);
67 | }
68 |
69 | @Override
70 | public Logger getLogger() {
71 | return plugin.getLogger();
72 | }
73 |
74 | @Override
75 | public void runTask(Runnable task, boolean async) {
76 | if (async == !Bukkit.isPrimaryThread()) {
77 | task.run();
78 | return;
79 | }
80 |
81 | if (async) {
82 | CompletableFuture.runAsync(task);
83 | return;
84 | }
85 |
86 | Bukkit.getScheduler().runTask(plugin, task);
87 | }
88 |
89 | protected Future callSync(Callable task) {
90 | return Bukkit.getScheduler().callSyncMethod(plugin, task);
91 | }
92 |
93 | @Override
94 | public void bindDefaults() {
95 | super.bindDefaults();
96 |
97 | BukkitActorProvider actorProvider = new BukkitActorProvider(this);
98 |
99 | bind(BukkitActor.class).annotated(Sender.class).to(actorProvider);
100 | bind(Player.class).annotated(Sender.class).to(new PlayerSenderProvider(actorProvider));
101 | bind(CommandSender.class).annotated(Sender.class).to(new CommandSenderProvider(actorProvider));
102 | bind(ConsoleCommandSender.class).annotated(Sender.class).to(new ConsoleCommandSenderProvider(actorProvider));
103 |
104 | bind(Player.class).to(new PlayerProvider(this));
105 | bind(OfflinePlayer.class).to(new OfflinePlayerProvider(this));
106 |
107 | bind(World.class).to(new WorldProvider(this));
108 | bind(Enchantment.class).to(new EnchantmentProvider());
109 |
110 | bind(EntityEffect.class).to(new EnumProvider<>(EntityEffect.class, "effect"));
111 | bind(WeatherType.class).to(new EnumProvider<>(WeatherType.class, "weather"));
112 | bind(EntityType.class).to(new EnumProvider<>(EntityType.class, "entity"));
113 | bind(PotionType.class).to(new EnumProvider<>(PotionType.class, "potion"));
114 | bind(TreeSpecies.class).to(new EnumProvider<>(TreeSpecies.class, "tree"));
115 | bind(GameMode.class).to(new EnumProvider<>(GameMode.class, "gamemode"));
116 | bind(ChatColor.class).to(new EnumProvider<>(ChatColor.class, "color"));
117 | bind(BlockFace.class).to(new EnumProvider<>(BlockFace.class, "face"));
118 | bind(DyeColor.class).to(new EnumProvider<>(DyeColor.class, "color"));
119 | bind(TreeType.class).to(new EnumProvider<>(TreeType.class, "tree"));
120 | bind(Art.class).to(new EnumProvider<>(Art.class, "painting"));
121 |
122 | bind(World.Environment.class).to(new EnumProvider<>(World.Environment.class));
123 | bind(Instrument.class).to(new EnumProvider<>(Instrument.class));
124 | bind(Difficulty.class).to(new EnumProvider<>(Difficulty.class));
125 | bind(WorldType.class).to(new EnumProvider<>(WorldType.class));
126 | bind(SkullType.class).to(new EnumProvider<>(SkullType.class));
127 | bind(Material.class).to(new EnumProvider<>(Material.class));
128 | bind(Effect.class).to(new EnumProvider<>(Effect.class));
129 | bind(Sound.class).to(new EnumProvider<>(Sound.class));
130 | bind(Biome.class).to(new EnumProvider<>(Biome.class));
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/CommandHandler.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 | import net.j4c0b3y.api.command.actor.Actor;
6 | import net.j4c0b3y.api.command.actor.ConsoleActor;
7 | import net.j4c0b3y.api.command.actor.PlayerActor;
8 | import net.j4c0b3y.api.command.actor.ProxyActor;
9 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Label;
10 | import net.j4c0b3y.api.command.annotation.parameter.classifier.Sender;
11 | import net.j4c0b3y.api.command.annotation.parameter.modifier.Length;
12 | import net.j4c0b3y.api.command.annotation.parameter.modifier.Range;
13 | import net.j4c0b3y.api.command.annotation.registration.Ignore;
14 | import net.j4c0b3y.api.command.annotation.registration.Register;
15 | import net.j4c0b3y.api.command.exception.registration.RegistrationException;
16 | import net.j4c0b3y.api.command.execution.CommandExecution;
17 | import net.j4c0b3y.api.command.execution.argument.flag.FlagAction;
18 | import net.j4c0b3y.api.command.execution.locale.CommandLocale;
19 | import net.j4c0b3y.api.command.execution.usage.UsageHandler;
20 | import net.j4c0b3y.api.command.execution.usage.impl.SimpleUsageHandler;
21 | import net.j4c0b3y.api.command.wrapper.CommandHandle;
22 | import net.j4c0b3y.api.command.wrapper.CommandWrapper;
23 | import net.j4c0b3y.api.command.wrapper.binding.BindingBuilder;
24 | import net.j4c0b3y.api.command.wrapper.binding.BindingHandler;
25 | import net.j4c0b3y.api.command.wrapper.binding.condition.ConditionHandler;
26 | import net.j4c0b3y.api.command.wrapper.binding.modifier.ModifierHandler;
27 | import net.j4c0b3y.api.command.wrapper.binding.modifier.impl.LengthModifier;
28 | import net.j4c0b3y.api.command.wrapper.binding.modifier.impl.RangeModifier;
29 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor.ActorProvider;
30 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor.ConsoleActorProvider;
31 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor.PlayerActorProvider;
32 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.actor.ProxyActorProvider;
33 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.argument.*;
34 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.context.CommandExecutionProvider;
35 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.context.CommandHandleProvider;
36 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.context.CommandWrapperProvider;
37 | import net.j4c0b3y.api.command.wrapper.binding.provider.impl.context.LabelProvider;
38 |
39 | import java.util.Arrays;
40 | import java.util.List;
41 | import java.util.UUID;
42 | import java.util.concurrent.CompletableFuture;
43 | import java.util.function.Function;
44 | import java.util.logging.Logger;
45 |
46 | /**
47 | * @author J4C0B3Y
48 | * @version CommandAPI
49 | * @since 26/08/2024
50 | */
51 | @Getter @Setter
52 | public abstract class CommandHandler {
53 | private final BindingHandler bindingHandler = new BindingHandler();
54 | private final ModifierHandler modifierHandler = new ModifierHandler();
55 | private final ConditionHandler conditionHandler = new ConditionHandler();
56 |
57 | private UsageHandler usageHandler = new SimpleUsageHandler();
58 | private CommandLocale locale = new CommandLocale();
59 |
60 | private FlagAction unknownFlagAction = FlagAction.ARGUMENT;
61 | private Function translator = content -> content;
62 |
63 | private boolean debug;
64 |
65 | public abstract CommandWrapper wrap(Object wrapper, String name, List aliases);
66 | public abstract Logger getLogger();
67 |
68 | public BindingBuilder bind(Class type) {
69 | return new BindingBuilder<>(type, this);
70 | }
71 |
72 | public void register(Object wrapper, String name, String permission, String... aliases) {
73 | if (wrapper.getClass().isAnnotationPresent(Ignore.class)) return;
74 |
75 | try {
76 | CommandWrapper wrapped = wrap(wrapper, name, Arrays.asList(aliases));
77 |
78 | if (permission != null) {
79 | wrapped.setPermission(permission);
80 | }
81 |
82 | wrapped.register();
83 | } catch (Exception exception) {
84 | throw new RegistrationException("Failed to register command '" + name + "'", exception);
85 | }
86 | }
87 |
88 | public void register(Object wrapper, String name) {
89 | register(wrapper, name, null);
90 | }
91 |
92 | public void register(Object wrapper) {
93 | Class> clazz = wrapper.getClass();
94 | Register annotation = clazz.getAnnotation(Register.class);
95 |
96 | if (annotation == null) {
97 | throw new RegistrationException("Wrapper '" + clazz.getSimpleName() + "' must be annotated @Register.");
98 | }
99 |
100 | register(wrapper, annotation.name(), null, annotation.aliases());
101 | }
102 |
103 | public void register(Class> clazz) {
104 | try {
105 | register(clazz.getConstructor().newInstance());
106 | } catch (ReflectiveOperationException exception) {
107 | throw new RegistrationException("Failed to instantiate wrapper!", exception);
108 | }
109 | }
110 |
111 | public void runTask(Runnable task, boolean async) {
112 | if (!async) {
113 | task.run();
114 | return;
115 | }
116 |
117 | CompletableFuture.runAsync(task);
118 | }
119 |
120 | public void bindDefaults() {
121 | bind(String.class).to(new StringProvider());
122 | bind(char.class).to(new CharacterProvider());
123 | bind(boolean.class).to(new BooleanProvider());
124 | bind(UUID.class).to(new UUIDProvider());
125 |
126 | bind(int.class).to(new NumberProvider<>(Integer::parseInt, "integer", 0));
127 | bind(double.class).to(new NumberProvider<>(Double::parseDouble, "double", 0D));
128 | bind(float.class).to(new NumberProvider<>(Float::parseFloat, "float", 0f));
129 | bind(long.class).to(new NumberProvider<>(Long::parseLong, "long", 0L));
130 | bind(short.class).to(new NumberProvider<>(Short::parseShort, "short", (short) 0));
131 |
132 | bind(String.class).annotated(Length.class).to(new LengthModifier());
133 | bind(int.class).annotated(Range.class).to(new RangeModifier<>());
134 | bind(double.class).annotated(Range.class).to(new RangeModifier<>());
135 | bind(float.class).annotated(Range.class).to(new RangeModifier<>());
136 | bind(long.class).annotated(Range.class).to(new RangeModifier<>());
137 |
138 | bind(String.class).annotated(Label.class).to(new LabelProvider());
139 | bind(Actor.class).annotated(Sender.class).to(new ActorProvider());
140 | bind(ProxyActor.class).annotated(Sender.class).to(new ProxyActorProvider());
141 | bind(PlayerActor.class).annotated(Sender.class).to(new PlayerActorProvider());
142 | bind(ConsoleActor.class).annotated(Sender.class).to(new ConsoleActorProvider());
143 |
144 | bind(CommandExecution.class).to(new CommandExecutionProvider());
145 | bind(CommandHandle.class).to(new CommandHandleProvider());
146 | bind(CommandWrapper.class).to(new CommandWrapperProvider());
147 |
148 | bind(CommandHandler.class).to(this);
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
84 |
85 | APP_NAME="Gradle"
86 | APP_BASE_NAME=${0##*/}
87 |
88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 |
142 | # Increase the maximum file descriptors if we can.
143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
144 | case $MAX_FD in #(
145 | max*)
146 | MAX_FD=$( ulimit -H -n ) ||
147 | warn "Could not query maximum file descriptor limit"
148 | esac
149 | case $MAX_FD in #(
150 | '' | soft) :;; #(
151 | *)
152 | ulimit -n "$MAX_FD" ||
153 | warn "Could not set maximum file descriptor limit to $MAX_FD"
154 | esac
155 | fi
156 |
157 | # Collect all arguments for the java command, stacking in reverse order:
158 | # * args from the command line
159 | # * the main class name
160 | # * -classpath
161 | # * -D...appname settings
162 | # * --module-path (only if needed)
163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
164 |
165 | # For Cygwin or MSYS, switch paths to Windows format before running java
166 | if "$cygwin" || "$msys" ; then
167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
169 |
170 | JAVACMD=$( cygpath --unix "$JAVACMD" )
171 |
172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
173 | for arg do
174 | if
175 | case $arg in #(
176 | -*) false ;; # don't mess with options #(
177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
178 | [ -e "$t" ] ;; #(
179 | *) false ;;
180 | esac
181 | then
182 | arg=$( cygpath --path --ignore --mixed "$arg" )
183 | fi
184 | # Roll the args list around exactly as many times as the number of
185 | # args, so each arg winds up back in the position where it started, but
186 | # possibly modified.
187 | #
188 | # NB: a `for` loop captures its iteration list before it begins, so
189 | # changing the positional parameters here affects neither the number of
190 | # iterations, nor the values presented in `arg`.
191 | shift # remove old arg
192 | set -- "$@" "$arg" # push replacement arg
193 | done
194 | fi
195 |
196 | # Collect all arguments for the java command;
197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
198 | # shell script including quotes and variable substitutions, so put them in
199 | # double quotes to make sure that they get re-expanded; and
200 | # * put everything else in single quotes, so that it's not re-expanded.
201 |
202 | set -- \
203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
204 | -classpath "$CLASSPATH" \
205 | org.gradle.wrapper.GradleWrapperMain \
206 | "$@"
207 |
208 | # Use "xargs" to parse quoted args.
209 | #
210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
211 | #
212 | # In Bash we could simply go:
213 | #
214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
215 | # set -- "${ARGS[@]}" "$@"
216 | #
217 | # but POSIX shell has neither arrays nor command substitution, so instead we
218 | # post-process each arg (as a line of input to sed) to backslash-escape any
219 | # character that might be a shell metacharacter, then use eval to reverse
220 | # that process (while maintaining the separation between arguments), and wrap
221 | # the whole thing up as a single "set" statement.
222 | #
223 | # This will of course break if any of these variables contains a newline or
224 | # an unmatched quote.
225 | #
226 |
227 | eval "set -- $(
228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
229 | xargs -n1 |
230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
231 | tr '\n' ' '
232 | )" '"$@"'
233 |
234 | exec "$JAVACMD" "$@"
235 |
--------------------------------------------------------------------------------
/core/src/main/java/net/j4c0b3y/api/command/execution/CommandExecution.java:
--------------------------------------------------------------------------------
1 | package net.j4c0b3y.api.command.execution;
2 |
3 | import lombok.Getter;
4 | import net.j4c0b3y.api.command.CommandHandler;
5 | import net.j4c0b3y.api.command.actor.Actor;
6 | import net.j4c0b3y.api.command.exception.execution.ExitMessage;
7 | import net.j4c0b3y.api.command.exception.execution.UnknownFlagException;
8 | import net.j4c0b3y.api.command.execution.argument.CommandArgument;
9 | import net.j4c0b3y.api.command.execution.argument.flag.CommandFlag;
10 | import net.j4c0b3y.api.command.wrapper.CommandHandle;
11 | import net.j4c0b3y.api.command.wrapper.CommandParameter;
12 | import net.j4c0b3y.api.command.wrapper.binding.provider.Provider;
13 |
14 | import java.lang.annotation.Annotation;
15 | import java.util.*;
16 |
17 | /**
18 | * @author J4C0B3Y
19 | * @version CommandAPI
20 | * @since 27/08/2024
21 | */
22 | @Getter
23 | public class CommandExecution {
24 | private final Actor actor;
25 | private final CommandHandle handle;
26 | private final String label;
27 | private final List arguments;
28 | private final CommandHandler handler;
29 |
30 | private final List providedParameters = new ArrayList<>();
31 |
32 | public CommandExecution(Actor actor, CommandHandle handle, String label, List arguments) {
33 | this.actor = actor;
34 | this.handle = handle;
35 | this.label = label;
36 | this.arguments = arguments;
37 | this.handler = handle.getWrapper().getHandler();
38 |
39 | for (CommandParameter parameter : handle.getParameters()) {
40 | providedParameters.add(new ProvidedParameter(parameter));
41 | }
42 | }
43 |
44 | public CommandExecution(Actor actor, CommandHandler handler, String label, List arguments) {
45 | this.actor = actor;
46 | this.handle = null;
47 | this.label = label;
48 | this.arguments = arguments;
49 | this.handler = handler;
50 | }
51 |
52 | public void execute() {
53 | if (handle == null) {
54 | throw new IllegalStateException("Cannot run command execution without a handle.");
55 | }
56 |
57 | // Wrapper conditions
58 | for (Annotation condition : handle.getWrapper().getConditions()) {
59 | if (!handler.getConditionHandler().validate(condition, actor)) {
60 | return;
61 | }
62 | }
63 |
64 | // Handle conditions
65 | for (Annotation condition : handle.getConditions()) {
66 | if (!handler.getConditionHandler().validate(condition, actor)) {
67 | return;
68 | }
69 | }
70 |
71 | if (providedParameters.isEmpty()) {
72 | complete();
73 | }
74 |
75 | List arguments = new ArrayList<>(this.arguments);
76 |
77 | extractFlags(arguments);
78 | parseArguments(arguments);
79 |
80 | for (ProvidedParameter provided : providedParameters) {
81 | if (provided.isProvided()) {
82 | continue;
83 | }
84 |
85 | CommandParameter parameter = provided.getParameter();
86 | Provider> provider = parameter.getProvider();
87 |
88 | handler.runTask(() ->
89 | handle.getWrapper().handleExceptions(actor, handle, label, () -> {
90 | boolean skip = provided.getArgument() == null && provider.isConsumer();
91 |
92 | if (!skip && !actor.hasPermission(parameter.getPermission())) {
93 | handler.getLocale().getNoPermission().forEach(actor::sendMessage);
94 | return null;
95 | }
96 |
97 | provided.provide(skip ? null : provider.provide(this,
98 | new CommandArgument(provided.getArgument(), parameter)
99 | ));
100 |
101 | if (provided.isProvided()) {
102 | provided.provide(handler.getModifierHandler().modify(
103 | provided.getValue(), this, parameter
104 | ));
105 | }
106 |
107 | complete();
108 | return null;
109 | }),
110 | provider.isAsync()
111 | );
112 | }
113 | }
114 |
115 | private void extractFlags(List arguments) {
116 | Map flags = new HashMap<>();
117 |
118 | for (ProvidedParameter provided : providedParameters) {
119 | CommandParameter parameter = provided.getParameter();
120 |
121 | if (!parameter.isFlag()) {
122 | continue;
123 | }
124 |
125 | for (String flag : parameter.getFlagNames()) {
126 | flags.put(flag, provided);
127 | }
128 | }
129 |
130 | Iterator iterator = arguments.iterator();
131 |
132 | while (iterator.hasNext()) {
133 | String argument = iterator.next();
134 |
135 | try {
136 | argument = CommandFlag.validate(argument, handler);
137 |
138 | if (argument == null) {
139 | continue;
140 | }
141 |
142 | ProvidedParameter parameter = flags.get(argument);
143 |
144 | if (parameter == null) {
145 | throw new UnknownFlagException(handler.getLocale().getUnknownFlag(argument), true);
146 | }
147 |
148 | if (parameter.getArgument() != null || parameter.isProvided()) {
149 | throw new ExitMessage(handler.getLocale().getFlagSpecified(argument));
150 | }
151 |
152 | if (parameter.getParameter().isBoolean()) {
153 | parameter.provide(true);
154 | iterator.remove();
155 | continue;
156 | }
157 |
158 | if (!iterator.hasNext()) {
159 | throw new ExitMessage(handler.getLocale().getFlagValueRequired(argument), true);
160 | }
161 |
162 | iterator.remove();
163 | String value = iterator.next();
164 |
165 | if (CommandFlag.validate(value, handler) != null) {
166 | throw new ExitMessage(handler.getLocale().getFlagValueRequired(argument), true);
167 | }
168 |
169 | parameter.setArgument(value);
170 | iterator.remove();
171 | } catch (UnknownFlagException exception) {
172 | switch (handler.getUnknownFlagAction()) {
173 | case ERROR: throw exception;
174 | case STRIP: iterator.remove();
175 | }
176 | }
177 | }
178 | }
179 |
180 | private void parseArguments(List arguments) {
181 | int offset = 0;
182 |
183 | for (int i = 0; i < providedParameters.size(); i++) {
184 | ProvidedParameter provided = providedParameters.get(i);
185 | CommandParameter parameter = provided.getParameter();
186 |
187 | if (parameter.isFlag()) {
188 | if (!provided.isProvided()) {
189 | // If no argument for a flag was given, provide its default value.
190 | if (provided.getArgument() == null) {
191 | provided.setArgument(parameter.getDefaultValue());
192 | }
193 |
194 | // If the @Default is null, use the provider's flag default.
195 | if (provided.getArgument() == null) {
196 | provided.provide(parameter.getProvider().flagDefault(this));
197 | }
198 | }
199 |
200 | offset++;
201 | continue;
202 | }
203 |
204 | if (!parameter.getProvider().isConsumer()) {
205 | offset++;
206 | continue;
207 | }
208 |
209 | int adjusted = i - offset;
210 |
211 | if (parameter.isCombine()) {
212 | arguments = combineRemaining(arguments, adjusted);
213 | }
214 |
215 | if (adjusted >= arguments.size()) {
216 | if (parameter.isOptional()) {
217 | provided.setArgument(parameter.getDefaultValue());
218 | continue;
219 | }
220 |
221 | if (!handle.hasExpandedUsage()) {
222 | throw new ExitMessage(handler.getLocale().getMissingArgument(parameter.getName()), true);
223 | } else {
224 | handle.getExpandedUsage().forEach(actor::sendMessage);
225 | return;
226 | }
227 | }
228 |
229 | provided.setArgument(arguments.get(adjusted));
230 | }
231 | }
232 |
233 | private List combineRemaining(List arguments, int startIndex) {
234 | List previous = new ArrayList<>(arguments.subList(0, startIndex));
235 | String combined = String.join(" ", arguments.subList(startIndex, arguments.size()));
236 |
237 | if (!combined.isEmpty()) {
238 | previous.add(combined);
239 | }
240 |
241 | return previous;
242 | }
243 |
244 | private void complete() {
245 | for (ProvidedParameter parameter : providedParameters) {
246 | if (!parameter.isProvided()) {
247 | return;
248 | }
249 | }
250 |
251 | List