Skip to content

Commit

Permalink
Release 2.0.0
Browse files Browse the repository at this point in the history
2.0.0
  • Loading branch information
vaperion authored Nov 17, 2021
2 parents 925fe31 + fc9de03 commit 18c5413
Show file tree
Hide file tree
Showing 54 changed files with 1,064 additions and 693 deletions.
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Blade

:warning: Blade only supports Java 8-11 due to the use of reflection!

Blade is an easy-to-use command framework based on annotations. It currently only supports Bukkit, but it can be easily extended to more platforms.
To use Blade, you simply have to include it as a dependency and shade it into your final jar.

Expand All @@ -23,7 +25,7 @@ Maven
<dependency>
<groupId>com.github.vaperion</groupId>
<artifactId>blade</artifactId>
<version>1.2.10</version>
<version>2.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
Expand All @@ -38,18 +40,18 @@ allprojects {
}
dependencies {
implementation 'com.github.vaperion:blade:1.2.10'
implementation 'com.github.vaperion:blade:2.0.0'
}
```

### Example code

Initializing Blade:

```java
import me.vaperion.blade.Blade;
import me.vaperion.blade.command.bindings.impl.BukkitBindings;
import me.vaperion.blade.command.container.impl.BukkitCommandContainer;
import me.vaperion.blade.completer.impl.ProtocolLibTabCompleter;
import me.vaperion.blade.bindings.impl.BukkitBindings;
import me.vaperion.blade.container.impl.BukkitCommandContainer;
import org.bukkit.plugin.java.JavaPlugin;

public class ExamplePlugin extends JavaPlugin {
Expand Down Expand Up @@ -91,12 +93,13 @@ Blade.of()
```

Example commands:

```java
import me.vaperion.blade.command.annotation.*;
import me.vaperion.blade.annotation.*;
import org.bukkit.entity.Player;

public class ExampleCommand {

@Command(value = {"ban", "go away"}, async = true, quoted = false, description = "Ban a player")
@Permission(value = "blade.command.ban", message = "You are not allowed to execute this command.")
public static void ban(@Sender Player sender,
Expand All @@ -107,7 +110,7 @@ public class ExampleCommand {
sender.sendMessage("Target: " + target.getName());
sender.sendMessage("Reason: " + reason);
}

@Command("test")
public static void test(@Sender Player sender,
@Range(min = 18) int age,
Expand All @@ -129,9 +132,10 @@ public class ExampleCommand {
```

Example custom tab completer with Netty:

```java
import me.vaperion.blade.command.service.BladeCommandService;
import me.vaperion.blade.completer.TabCompleter;
import me.vaperion.blade.service.BladeCommandService;
import me.vaperion.blade.tabcompleter.TabCompleter;
import net.minecraft.server.v1_7_R4.PacketPlayInTabComplete;
import net.minecraft.server.v1_7_R4.PacketPlayOutTabComplete;
import net.minecraft.util.io.netty.channel.ChannelDuplexHandler;
Expand Down
20 changes: 18 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>me.vaperion</groupId>
<artifactId>blade</artifactId>
<version>1.2.10</version>
<version>2.0.0</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand All @@ -29,7 +29,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -72,8 +72,24 @@
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand Down
80 changes: 49 additions & 31 deletions src/main/java/me/vaperion/blade/Blade.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
import lombok.Builder;
import lombok.Getter;
import lombok.Singular;
import me.vaperion.blade.command.argument.BladeProvider;
import me.vaperion.blade.command.argument.ProviderAnnotation;
import me.vaperion.blade.command.bindings.Binding;
import me.vaperion.blade.command.container.ContainerCreator;
import me.vaperion.blade.command.help.HelpGenerator;
import me.vaperion.blade.command.service.BladeCommandService;
import me.vaperion.blade.completer.TabCompleter;
import me.vaperion.blade.argument.BladeProvider;
import me.vaperion.blade.argument.ProviderAnnotation;
import me.vaperion.blade.bindings.Binding;
import me.vaperion.blade.container.ContainerCreator;
import me.vaperion.blade.help.HelpGenerator;
import me.vaperion.blade.service.BladeCommandRegistrar;
import me.vaperion.blade.service.BladeCommandService;
import me.vaperion.blade.tabcompleter.TabCompleter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
Expand All @@ -24,36 +25,57 @@
@SuppressWarnings("UnusedReturnValue")
@Getter
@Builder(builderMethodName = "of")
public class Blade {
public class Blade implements BladeCommandRegistrar.Registrar {
private final BladeCommandService commandService = new BladeCommandService();

private final boolean overrideCommands;
private final String fallbackPrefix;
private final String fallbackPrefix, defaultPermissionMessage;
private final ContainerCreator<?> containerCreator;
private final TabCompleter tabCompleter;
private final HelpGenerator helpGenerator;
private final Consumer<Runnable> asyncExecutor;

@Builder.Default
private final long executionTimeWarningThreshold = 5;

@Singular("bind0")
private final Map<Map.Entry<Class<?>, Class<? extends ProviderAnnotation>>, BladeProvider<?>> customProviderMap;
private final Map<Map.Entry<Class<?>, List<Class<? extends ProviderAnnotation>>>, BladeProvider<?>> customProviderMap;
@Singular
private final List<Binding> bindings;

private void register(@Nullable Object instance, @NotNull Class<?> clazz) {
commandService.getCommandRegistrar().registerClass(instance, clazz);
@Override
public @NotNull BladeCommandService commandService() {
return commandService;
}

@NotNull
public Blade register(@NotNull Class<?> containerClass) {
register(null, containerClass);
@Override
public @NotNull String fallbackPrefix() {
return fallbackPrefix;
}

@Override
public @NotNull Blade blade() {
return this;
}

@NotNull
public Blade register(@NotNull Object containerInstance) {
register(containerInstance, containerInstance.getClass());
return this;
public BladeCommandRegistrar.Registrar section(@NotNull String prefix) {
return new BladeCommandRegistrar.Registrar() {
@Override
public @NotNull BladeCommandService commandService() {
return Blade.this.commandService();
}

@Override
public @NotNull String fallbackPrefix() {
return prefix;
}

@Override
public @NotNull Blade blade() {
return Blade.this;
}
};
}

public static BladeBuilder of() {
Expand All @@ -64,14 +86,14 @@ public Blade build() {

blade.commandService.setOverrideCommands(blade.overrideCommands);

if (blade.defaultPermissionMessage != null && !"".equals(blade.defaultPermissionMessage))
blade.commandService.setDefaultPermissionMessage(blade.defaultPermissionMessage);

if (blade.containerCreator == null)
throw new NullPointerException();
else
blade.commandService.setContainerCreator(blade.containerCreator);

if (blade.fallbackPrefix != null)
blade.commandService.setFallbackPrefix(blade.fallbackPrefix);

if (blade.tabCompleter != null)
blade.commandService.setTabCompleter(blade.tabCompleter);

Expand All @@ -82,7 +104,7 @@ public Blade build() {
blade.commandService.setAsyncExecutor(blade.asyncExecutor);
} else {
ExecutorService service = Executors.newCachedThreadPool(
new ThreadFactoryBuilder().setNameFormat("blade-async-executor-%d").build()
new ThreadFactoryBuilder().setNameFormat("blade-async-executor-%d").build()
);
blade.commandService.setAsyncExecutor(service::execute);
}
Expand All @@ -95,7 +117,7 @@ public Blade build() {

blade.commandService.getTabCompleter().init(blade.commandService);

for (Map.Entry<Map.Entry<Class<?>, Class<? extends ProviderAnnotation>>, BladeProvider<?>> entry : blade.customProviderMap.entrySet()) {
for (Map.Entry<Map.Entry<Class<?>, List<Class<? extends ProviderAnnotation>>>, BladeProvider<?>> entry : blade.customProviderMap.entrySet()) {
//noinspection deprecation
blade.commandService.bindProviderUnsafely(entry.getKey().getKey(), entry.getValue(), entry.getKey().getValue());
}
Expand All @@ -106,13 +128,9 @@ public Blade build() {
}

public static class BladeBuilder {
public <T> BladeBuilder bind(Class<T> clazz, BladeProvider<T> provider) {
bind0(new AbstractMap.SimpleEntry<>(clazz, null), provider);
return this;
}

public <T> BladeBuilder bind(Class<T> clazz, BladeProvider<T> provider, Class<? extends ProviderAnnotation> annotation) {
bind0(new AbstractMap.SimpleEntry<>(clazz, annotation), provider);
@SafeVarargs
public final <T> BladeBuilder bind(Class<T> clazz, BladeProvider<T> provider, Class<? extends ProviderAnnotation>... annotations) {
bind0(new AbstractMap.SimpleEntry<>(clazz, Arrays.asList(annotations)), provider);
return this;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.vaperion.blade.command.annotation;
package me.vaperion.blade.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/me/vaperion/blade/annotation/Command.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package me.vaperion.blade.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Command {
/**
* The names you can use to execute this command.
* <p>Example: <code>{"a", "b"}</code> => <code>/a</code>; <code>/b</code>
*/
String[] value();

/**
* This method indicates whether this command should be executed asynchronously or not.
* <p>This is useful for interacting with a database in a command, so you don't have to do the threading manually.
*/
boolean async() default false;

/**
* This method indicates whether quotes (<code>'</code>) and double quotes (<code>"</code>) should be parsed or not.
* <p>If this is true, <code>"hello world"</code> will turn into one string argument instead of two (<code>"hello</code> and <code>world"</code>).
*/
boolean quoted() default false;

/**
* This is the description of the command that is shown when you hover over the usage message.
*/
String description() default "";

/**
* This data will get appended to the end of the usage message.
*/
String extraUsageData() default "";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package me.vaperion.blade.command.annotation;
package me.vaperion.blade.annotation;

import me.vaperion.blade.argument.BladeProvider;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand All @@ -7,6 +9,6 @@

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Optional {
String value() default "null";
public @interface Completer {
Class<? extends BladeProvider<?>> value();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.vaperion.blade.command.annotation;
package me.vaperion.blade.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.vaperion.blade.command.annotation;
package me.vaperion.blade.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/me/vaperion/blade/annotation/Optional.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package me.vaperion.blade.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Optional {
/**
* The value will be used if the argument is not provided.
* <p>
* Reserved values:
* <ul>
* <li><code>null</code> => passes null</li>
* <li><code>self</code> (for player types) => passes the sender</li>
* </ul>
* <p>
* Any other value will be parsed.
*/
String value() default "null";

/**
* This method indicates whether <code>null</code> is allowed if an argument is provided.
* <p>
* <p>Example:
* <p>Command declaration: <code>statsCommand(@Sender Player sender, @Name("player") @Optional Player target)</code>
* <p>Executed commands:
* <ul>
* <li>/stats -> <code>null</code> gets passed because no argument was provided</li>
* <li>/stats RealPlayer -> <code>RealPlayer</code> gets passed</li>
* <li>/stats FakePlayer -> If {@link #ignoreFailedArgumentParse()} returns true, <code>null</code> will be passed, otherwise usage will be shown</li>
* </ul>
*/
boolean ignoreFailedArgumentParse() default false;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.vaperion.blade.command.annotation;
package me.vaperion.blade.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand All @@ -10,5 +10,5 @@
public @interface Permission {
String value() default "";

String message() default "No permission.";
String message() default "";
}
Loading

0 comments on commit 18c5413

Please sign in to comment.