Merge pull request #89 from PolyhedralDev/dev/commands

Platform-agnostic command API
This commit is contained in:
dfsek
2021-03-10 16:16:40 -07:00
committed by GitHub
127 changed files with 2419 additions and 1857 deletions

View File

@@ -49,4 +49,19 @@ public interface TerraPlugin extends LoaderRegistrar {
DebugLogger getDebugLogger();
EventManager getEventManager();
default String getVersion() {
return "@VERSION@";
}
/**
* Runs a task that may or may not be thread safe, depending on platform.
* <p>
* Allows platforms to define what code is safe to be run asynchronously.
*
* @param task Task to be run.
*/
default void runPossiblyUnsafeTask(Runnable task) {
task.run();
}
}

View File

@@ -0,0 +1,17 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.List;
public interface CommandManager {
void execute(String command, CommandSender sender, List<String> args) throws CommandException;
void register(String name, Class<? extends CommandTemplate> clazz) throws MalformedCommandException;
List<String> tabComplete(String command, CommandSender sender, List<String> args) throws CommandException;
int getMaxArgumentDepth();
}

View File

@@ -0,0 +1,7 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.platform.CommandSender;
public interface CommandTemplate {
void execute(CommandSender sender);
}

View File

@@ -0,0 +1,38 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public final class ExecutionState {
private final Set<String> switches = new HashSet<>();
private final Map<String, String> args = new HashMap<>();
private final CommandSender sender;
protected ExecutionState(CommandSender sender) {
this.sender = sender;
}
protected void addSwitch(String flag) {
switches.add(flag);
}
protected void addArgument(String arg, String value) {
args.put(arg, value);
}
public String getArgument(String argument) {
return args.get(argument);
}
public boolean hasSwitch(String flag) {
return switches.contains(flag);
}
public CommandSender getSender() {
return sender;
}
}

View File

@@ -0,0 +1,284 @@
package com.dfsek.terra.api.command;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.ExecutionException;
import com.dfsek.terra.api.command.exception.InvalidArgumentsException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.command.exception.SwitchFormatException;
import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.injection.Injector;
import com.dfsek.terra.api.injection.exception.InjectionException;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.util.ReflectionUtil;
import com.dfsek.terra.world.TerraWorld;
import net.jafama.FastMath;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TerraCommandManager implements CommandManager {
private final Map<String, CommandHolder> commands = new HashMap<>();
private final Injector<TerraPlugin> pluginInjector;
private final TerraPlugin main;
public TerraCommandManager(TerraPlugin main) {
this.main = main;
this.pluginInjector = new Injector<>(main);
pluginInjector.addExplicitTarget(TerraPlugin.class);
}
@Override
public void execute(String commandName, CommandSender sender, List<String> argsIn) throws CommandException {
if(!commands.containsKey(commandName)) throw new InvalidArgumentsException("No such command \"" + commandName + "\"");
execute(commands.get(commandName), sender, new ArrayList<>(argsIn));
}
private void execute(CommandHolder commandHolder, CommandSender sender, List<String> args) throws CommandException {
Class<? extends CommandTemplate> commandClass = commandHolder.clazz;
if(commandClass.isAnnotationPresent(DebugCommand.class) && !main.isDebug()) {
sender.sendMessage("Command must be executed with debug mode enabled.");
return;
}
if(commandClass.isAnnotationPresent(PlayerCommand.class) && !(sender instanceof Player)) {
sender.sendMessage("Command must be executed by player.");
return;
}
if(commandClass.isAnnotationPresent(WorldCommand.class) && (!(sender instanceof Player) || !TerraWorld.isTerraWorld(((Player) sender).getWorld()))) {
sender.sendMessage("Command must be executed in a Terra world.");
return;
}
List<String> ogArgs = new ArrayList<>(args);
ExecutionState state = new ExecutionState(sender);
if(!commandClass.isAnnotationPresent(Command.class)) {
invoke(commandClass, state, commandHolder);
return;
}
Command command = commandClass.getAnnotation(Command.class);
if(command.arguments().length == 0 && command.subcommands().length == 0) {
if(args.isEmpty()) {
invoke(commandClass, state, commandHolder);
return;
} else throw new InvalidArgumentsException("Expected 0 arguments, found " + args.size());
}
if(!args.isEmpty() && commandHolder.subcommands.containsKey(args.get(0))) {
String c = args.get(0);
args.remove(0);
execute(commandHolder.subcommands.get(c), sender, args);
return;
}
boolean req = true;
for(Argument argument : command.arguments()) {
if(!req && argument.required()) {
throw new MalformedCommandException("Required arguments must come first! Arguments: " + Arrays.toString(command.arguments()));
}
req = argument.required();
if(args.isEmpty()) {
if(req) throw new InvalidArgumentsException("Invalid arguments: " + ogArgs + ", usage: " + command.usage());
break;
}
String arg = args.get(0);
if(arg.startsWith("-")) { // switches have started.
if(req) throw new InvalidArgumentsException("Switches must come after arguments.");
break;
}
state.addArgument(argument.value(), args.remove(0));
}
while(!args.isEmpty()) {
String aSwitch = args.remove(0);
if(!aSwitch.startsWith("-")) throw new SwitchFormatException("Invalid switch \"" + aSwitch + "\"");
String val = aSwitch.substring(1); // remove dash
if(!commandHolder.switches.containsKey(val)) throw new SwitchFormatException("No such switch \"" + aSwitch + "\"");
state.addSwitch(commandHolder.switches.get(val));
}
invoke(commandClass, state, commandHolder);
}
private void invoke(Class<? extends CommandTemplate> clazz, ExecutionState state, CommandHolder holder) throws CommandException {
try {
CommandTemplate template = clazz.getConstructor().newInstance();
pluginInjector.inject(template);
for(Field field : ReflectionUtil.getFields(clazz)) {
if(field.isAnnotationPresent(ArgumentTarget.class)) {
ArgumentTarget argumentTarget = field.getAnnotation(ArgumentTarget.class);
if(!holder.argumentMap.containsKey(argumentTarget.value())) {
throw new MalformedCommandException("Argument Target specifies nonexistent argument \"" + argumentTarget.value() + "\"");
}
String argument = argumentTarget.value();
ArgumentParser<?> argumentParser = holder.argumentMap.get(argumentTarget.value()).argumentParser().getConstructor().newInstance();
pluginInjector.inject(argumentParser);
field.setAccessible(true);
String value = state.getArgument(argument);
if(value == null) value = holder.argumentMap.get(argumentTarget.value()).defaultValue();
field.set(template, argumentParser.parse(state.getSender(), value));
}
if(field.isAnnotationPresent(SwitchTarget.class)) {
SwitchTarget switchTarget = field.getAnnotation(SwitchTarget.class);
if(!holder.switches.containsValue(switchTarget.value())) {
System.out.println(holder.switches);
throw new MalformedCommandException("Switch Target specifies nonexistent switch \"" + switchTarget.value() + "\"");
}
if(!(field.getType() == boolean.class)) {
throw new MalformedCommandException("Switch Target must be of type boolean.");
}
field.setAccessible(true);
field.setBoolean(template, state.hasSwitch(switchTarget.value()));
}
}
try {
template.execute(state.getSender());
} catch(Throwable e) {
throw new ExecutionException("Failed to execute command: " + e.getMessage(), e);
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate command: ", e);
}
}
@Override
public void register(String name, Class<? extends CommandTemplate> clazz) throws MalformedCommandException {
commands.put(name, new CommandHolder(clazz));
}
@Override
public List<String> tabComplete(String command, CommandSender sender, List<String> args) throws CommandException {
if(args.isEmpty()) return new ArrayList<>(commands.keySet()).stream().sorted(String::compareTo).collect(Collectors.toList());
if(!commands.containsKey(command)) return Collections.emptyList();
return tabComplete(commands.get(command), sender, new ArrayList<>(args)).stream().filter(s -> s.toLowerCase().startsWith(args.get(args.size() - 1).toLowerCase())).sorted(String::compareTo).collect(Collectors.toList());
}
@Override
public int getMaxArgumentDepth() {
int max = 0;
for(CommandHolder value : commands.values()) {
max = FastMath.max(getMaxArgumentDepth(value), max);
}
return max;
}
private int getMaxArgumentDepth(CommandHolder holder) {
int max = 0;
max = FastMath.max(holder.arguments.size() + holder.switchList.size(), max);
for(CommandHolder value : holder.subcommands.values()) {
max = FastMath.max(max, getMaxArgumentDepth(value) + 1);
}
return max;
}
private List<String> tabComplete(CommandHolder holder, CommandSender sender, List<String> args) throws CommandException {
if(args.isEmpty()) return Collections.emptyList();
List<String> completions = new ArrayList<>();
if(args.size() == 1) {
completions.addAll(holder.subcommands.keySet());
}
if(holder.subcommands.containsKey(args.get(0))) {
List<String> newArgs = new ArrayList<>(args);
newArgs.remove(0);
completions.addAll(tabComplete(holder.subcommands.get(args.get(0)), sender, newArgs));
}
try {
if(args.size() <= holder.arguments.size()) {
TabCompleter completer = holder.arguments.get(args.size() - 1).tabCompleter().getConstructor().newInstance();
pluginInjector.inject(completer);
completions.addAll(completer.complete(sender));
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate tab-completer: ", e);
}
return completions;
}
/**
* Pre-processes command metadata.
*/
private static final class CommandHolder {
private final Class<? extends CommandTemplate> clazz;
private final Map<String, CommandHolder> subcommands = new HashMap<>();
private final Map<String, String> switches = new HashMap<>();
private final List<Argument> arguments;
private final List<Switch> switchList;
private final Map<String, Argument> argumentMap = new HashMap<>();
private CommandHolder(Class<? extends CommandTemplate> clazz) throws MalformedCommandException {
this.clazz = clazz;
if(clazz.isAnnotationPresent(Command.class)) {
Command command = clazz.getAnnotation(Command.class);
for(Subcommand subcommand : command.subcommands()) {
if(subcommands.containsKey(subcommand.value()))
throw new MalformedCommandException("Duplicate subcommand: " + subcommand);
CommandHolder holder = new CommandHolder(subcommand.clazz());
subcommands.put(subcommand.value(), holder);
for(String alias : subcommand.aliases()) {
subcommands.put(alias, holder);
}
}
for(Switch aSwitch : command.switches()) {
if(switches.containsKey(aSwitch.value())) throw new MalformedCommandException("Duplicate switch: " + aSwitch);
switches.put(aSwitch.value(), aSwitch.value());
for(String alias : aSwitch.aliases()) {
switches.put(alias, aSwitch.value());
}
}
for(Argument argument : command.arguments()) {
if(argumentMap.containsKey(argument.value())) throw new MalformedCommandException("Duplicate argument: " + argument);
argumentMap.put(argument.value(), argument);
}
arguments = Arrays.asList(command.arguments());
switchList = Arrays.asList(command.switches());
} else {
arguments = Collections.emptyList();
switchList = Collections.emptyList();
}
}
}
}

View File

@@ -0,0 +1,25 @@
package com.dfsek.terra.api.command.annotation;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.command.arg.StringArgumentParser;
import com.dfsek.terra.api.command.tab.NothingCompleter;
import com.dfsek.terra.api.command.tab.TabCompleter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Argument {
String value();
boolean required() default true;
Class<? extends TabCompleter> tabCompleter() default NothingCompleter.class;
Class<? extends ArgumentParser<?>> argumentParser() default StringArgumentParser.class;
String defaultValue() default "";
}

View File

@@ -0,0 +1,18 @@
package com.dfsek.terra.api.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Command {
Argument[] arguments() default {};
Switch[] switches() default {};
Subcommand[] subcommands() default {};
String usage() default "";
}

View File

@@ -0,0 +1,18 @@
package com.dfsek.terra.api.command.annotation;
import com.dfsek.terra.api.command.CommandTemplate;
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.ANNOTATION_TYPE)
public @interface Subcommand {
String value();
String[] aliases() default {};
Class<? extends CommandTemplate> clazz();
}

View File

@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.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.ANNOTATION_TYPE)
public @interface Switch {
String value();
String[] aliases() default {};
}

View File

@@ -0,0 +1,12 @@
package com.dfsek.terra.api.command.annotation.inject;
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.FIELD)
public @interface ArgumentTarget {
String value();
}

View File

@@ -0,0 +1,12 @@
package com.dfsek.terra.api.command.annotation.inject;
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.FIELD)
public @interface SwitchTarget {
String value();
}

View File

@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.annotation.type;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Command may only be executed with debug mode enabled.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DebugCommand {
}

View File

@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.annotation.type;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marks command as player-only
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PlayerCommand {
}

View File

@@ -0,0 +1,14 @@
package com.dfsek.terra.api.command.annotation.type;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Command may only be executed in a Terra world.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WorldCommand {
}

View File

@@ -0,0 +1,7 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public interface ArgumentParser<T> {
T parse(CommandSender sender, String arg);
}

View File

@@ -0,0 +1,10 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public class DoubleArgumentParser implements ArgumentParser<Double> {
@Override
public Double parse(CommandSender sender, String arg) {
return arg == null ? null : Double.parseDouble(arg);
}
}

View File

@@ -0,0 +1,10 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public class IntegerArgumentParser implements ArgumentParser<Integer> {
@Override
public Integer parse(CommandSender sender, String arg) {
return arg == null ? null : Integer.parseInt(arg);
}
}

View File

@@ -0,0 +1,10 @@
package com.dfsek.terra.api.command.arg;
import com.dfsek.terra.api.platform.CommandSender;
public class StringArgumentParser implements ArgumentParser<String> {
@Override
public String parse(CommandSender sender, String arg) {
return arg;
}
}

View File

@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public abstract class CommandException extends Exception {
private static final long serialVersionUID = -2955328495045879822L;
public CommandException(String message) {
super(message);
}
public CommandException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public class ExecutionException extends CommandException {
private static final long serialVersionUID = -6345523475880607959L;
public ExecutionException(String message) {
super(message);
}
public ExecutionException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public class InvalidArgumentsException extends CommandException {
private static final long serialVersionUID = 7563619667472569824L;
public InvalidArgumentsException(String message) {
super(message);
}
public InvalidArgumentsException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,16 @@
package com.dfsek.terra.api.command.exception;
/**
* Thrown when command is incorrectly defined.
*/
public class MalformedCommandException extends CommandException {
private static final long serialVersionUID = -5417760860407895496L;
public MalformedCommandException(String message) {
super(message);
}
public MalformedCommandException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.exception;
public class SwitchFormatException extends CommandException {
private static final long serialVersionUID = -965858989317844628L;
public SwitchFormatException(String message) {
super(message);
}
public SwitchFormatException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,13 @@
package com.dfsek.terra.api.command.tab;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.Collections;
import java.util.List;
public class NothingCompleter implements TabCompleter {
@Override
public List<String> complete(CommandSender sender) {
return Collections.emptyList();
}
}

View File

@@ -0,0 +1,9 @@
package com.dfsek.terra.api.command.tab;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.List;
public interface TabCompleter {
List<String> complete(CommandSender sender);
}

View File

@@ -170,4 +170,9 @@ public class Location implements Cloneable {
public String toString() {
return "[" + world + ": (" + getX() + ", " + getY() + ", " + getZ() + ")]";
}
public Location multiply(double v) {
vector.multiply(v);
return this;
}
}

View File

@@ -13,4 +13,6 @@ public interface BlockData extends Cloneable, Handle {
String getAsString();
boolean isAir();
boolean isStructureVoid();
}

View File

@@ -3,7 +3,12 @@ package com.dfsek.terra.api.platform.entity;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.Handle;
import com.dfsek.terra.api.platform.world.World;
public interface Entity extends Handle, CommandSender {
Location getLocation();
void setLocation(Location location);
World getWorld();
}

View File

@@ -1,22 +1,26 @@
package com.dfsek.terra.api.platform.handle;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.util.generic.pair.Pair;
/**
* Interface to be implemented for world manipulation.
*/
public interface WorldHandle {
default void setBlockData(Block block, BlockData data, boolean physics) {
block.setBlockData(data, physics);
}
default BlockData getBlockData(Block block) {
return block.getBlockData();
}
BlockData createBlockData(String data);
EntityType getEntity(String id);
/**
* Get the locations selected by a player. (Usually via WorldEdit)
*
* @param player Player to get locations for
* @return Pair of locations.
*/
default Pair<Location, Location> getSelectedLocation(Player player) {
throw new UnsupportedOperationException("Cannot get selection on this platform.");
}
}

View File

@@ -25,11 +25,17 @@ public interface World extends Handle {
Chunk getChunkAt(int x, int z);
default Chunk getChunkAt(Location location) {
return getChunkAt(location.getBlockX() >> 4, location.getBlockZ() >> 4);
}
File getWorldFolder();
Block getBlockAt(int x, int y, int z);
Block getBlockAt(Location l);
default Block getBlockAt(Location l) {
return getBlockAt(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
Entity spawnEntity(Location location, EntityType entityType);

View File

@@ -2,9 +2,12 @@ package com.dfsek.terra.api.util;
import org.jetbrains.annotations.NotNull;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.stream.Stream;
public class ReflectionUtil {
@@ -25,4 +28,9 @@ public class ReflectionUtil {
}
return result;
}
public static <T extends Annotation> void ifAnnotationPresent(AnnotatedElement element, Class<? extends T> annotation, Consumer<T> operation) {
T a = element.getAnnotation(annotation);
if(a != null) operation.accept(a);
}
}

View File

@@ -0,0 +1,52 @@
package com.dfsek.terra.api.util.generic.either;
import java.util.Optional;
import java.util.function.Consumer;
public final class Either<L, R> {
private final L left;
private final R right;
private final boolean leftPresent;
private Either(L left, R right, boolean leftPresent) {
this.left = left;
this.right = right;
this.leftPresent = leftPresent;
}
public static <L1, R1> Either<L1, R1> left(L1 left) {
return new Either<>(left, null, true);
}
public static <L1, R1> Either<L1, R1> right(R1 right) {
return new Either<>(null, right, false);
}
public Optional<L> getLeft() {
if(leftPresent) return Optional.of(left);
return Optional.empty();
}
public Optional<R> getRight() {
if(!leftPresent) return Optional.of(right);
return Optional.empty();
}
public Either<L, R> ifLeft(Consumer<L> action) {
if(leftPresent) action.accept(left);
return this;
}
public Either<L, R> ifRight(Consumer<R> action) {
if(!leftPresent) action.accept(right);
return this;
}
public boolean hasLeft() {
return leftPresent;
}
public boolean hasRight() {
return !leftPresent;
}
}

View File

@@ -0,0 +1,27 @@
package com.dfsek.terra.api.util.generic.pair;
public class ImmutablePair<L, R> {
private final L left;
private final R right;
public ImmutablePair(L left, R right) {
this.left = left;
this.right = right;
}
public static <L1, R1> ImmutablePair<L1, R1> of(L1 left, R1 right) {
return new ImmutablePair<>(left, right);
}
public R getRight() {
return right;
}
public L getLeft() {
return left;
}
public Pair<L, R> mutable() {
return new Pair<>(left, right);
}
}

View File

@@ -0,0 +1,35 @@
package com.dfsek.terra.api.util.generic.pair;
public class Pair<L, R> {
private L left;
private R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
public static <L1, R1> Pair<L1, R1> of(L1 left, R1 right) {
return new Pair<>(left, right);
}
public L getLeft() {
return left;
}
public void setLeft(L left) {
this.left = left;
}
public R getRight() {
return right;
}
public void setRight(R right) {
this.right = right;
}
public ImmutablePair<L, R> immutable() {
return new ImmutablePair<>(left, right);
}
}

View File

@@ -0,0 +1,21 @@
package com.dfsek.terra.commands;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
@Command(
usage = "/terra addons"
)
public class AddonsCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
sender.sendMessage("Installed Addons:");
main.getAddons().forEach(addon -> sender.sendMessage(" - " + addon.getName() + " v" + addon.getVersion() + " by " + addon.getAuthor()));
}
}

View File

@@ -0,0 +1,22 @@
package com.dfsek.terra.commands;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.commands.biome.BiomeCommand;
import com.dfsek.terra.commands.geometry.GeometryCommand;
import com.dfsek.terra.commands.profiler.ProfileCommand;
import com.dfsek.terra.commands.structure.StructureCommand;
public final class CommandUtil {
public static void registerAll(CommandManager manager) throws MalformedCommandException {
manager.register("structure", StructureCommand.class);
manager.register("profile", ProfileCommand.class);
manager.register("reload", ReloadCommand.class);
manager.register("addons", AddonsCommand.class);
manager.register("version", VersionCommand.class);
manager.register("getblock", GetBlockCommand.class);
manager.register("packs", PacksCommand.class);
manager.register("biome", BiomeCommand.class);
manager.register("geometry", GeometryCommand.class);
}
}

View File

@@ -0,0 +1,28 @@
package com.dfsek.terra.commands;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
@WorldCommand
@DebugCommand
@PlayerCommand
@Command(
usage = "/terra getblock"
)
public class GetBlockCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
sender.sendMessage("Block: " + main.getWorld(player.getWorld()).getUngeneratedBlock(player.getLocation()).getAsString());
}
}

View File

@@ -0,0 +1,35 @@
package com.dfsek.terra.commands;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.ConfigPackTemplate;
@Command(
usage = "/terra packs"
)
public class PacksCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
CheckedRegistry<ConfigPack> registry = main.getConfigRegistry();
if(registry.entries().size() == 0) {
LangUtil.send("command.packs.none", sender);
return;
}
LangUtil.send("command.packs.main", sender);
registry.entries().forEach(entry -> {
ConfigPackTemplate template = entry.getTemplate();
LangUtil.send("command.packs.pack", sender, template.getID(), template.getAuthor(), template.getVersion());
});
}
}

View File

@@ -0,0 +1,25 @@
package com.dfsek.terra.commands;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.config.lang.LangUtil;
@Command(
usage = "/terra reload"
)
public class ReloadCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
if(!main.reload()) {
LangUtil.send("command.reload-error", sender);
} else {
LangUtil.send("command.reload", sender);
}
}
}

View File

@@ -0,0 +1,22 @@
package com.dfsek.terra.commands;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.config.lang.LangUtil;
@Command(
usage = "/terra version"
)
public class VersionCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
String terraVersion = main.getVersion();
LangUtil.send("command.version", sender, terraVersion, main.platformName());
}
}

View File

@@ -0,0 +1,45 @@
package com.dfsek.terra.commands.biome;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.config.lang.LangUtil;
@Command(
subcommands = {
@Subcommand(
value = "info",
aliases = {"i"},
clazz = BiomeInfoCommand.class
),
@Subcommand(
value = "locate",
aliases = {"l"},
clazz = BiomeLocateCommand.class
)
},
usage = "/terra biome"
)
@WorldCommand
@PlayerCommand
public class BiomeCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
BiomeProvider provider = main.getWorld(player.getWorld()).getBiomeProvider();
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.getLocation());
LangUtil.send("command.biome.in", sender, biome.getID());
}
}

View File

@@ -0,0 +1,52 @@
package com.dfsek.terra.commands.biome;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.commands.biome.arg.BiomeArgumentParser;
import com.dfsek.terra.commands.biome.tab.BiomeTabCompleter;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.world.population.items.TerraStructure;
import java.util.List;
@Command(
arguments = {
@Argument(
value = "biome",
tabCompleter = BiomeTabCompleter.class,
argumentParser = BiomeArgumentParser.class
)
}
)
public class BiomeInfoCommand implements CommandTemplate {
@ArgumentTarget("biome")
private TerraBiome biome;
@Override
public void execute(CommandSender sender) {
sender.sendMessage("Biome info for \"" + biome.getID() + "\".");
sender.sendMessage("Vanilla biome: " + biome.getVanillaBiomes());
if(biome instanceof UserDefinedBiome) {
BiomeTemplate bio = ((UserDefinedBiome) biome).getConfig();
if(bio.getExtend() != null) sender.sendMessage("Extends: " + bio.getExtend());
List<TerraStructure> structureConfigs = bio.getStructures();
if(structureConfigs.size() == 0) sender.sendMessage("No Structures");
else {
sender.sendMessage("-------Structures-------");
for(TerraStructure c : structureConfigs) {
sender.sendMessage(" - " + c.getTemplate().getID());
}
}
}
}
}

View File

@@ -0,0 +1,78 @@
package com.dfsek.terra.commands.biome;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.locate.AsyncBiomeFinder;
import com.dfsek.terra.commands.biome.arg.BiomeArgumentParser;
import com.dfsek.terra.commands.biome.tab.BiomeTabCompleter;
import com.dfsek.terra.config.lang.LangUtil;
import java.util.Locale;
@PlayerCommand
@WorldCommand
@Command(
arguments = {
@Argument(
value = "biome",
tabCompleter = BiomeTabCompleter.class,
argumentParser = BiomeArgumentParser.class
),
@Argument(
value = "radius",
required = false,
defaultValue = "1000",
argumentParser = IntegerArgumentParser.class
)
},
switches = {
@Switch(
value = "teleport",
aliases = {"t", "tp"}
)
}
)
public class BiomeLocateCommand implements CommandTemplate {
@ArgumentTarget("radius")
private Integer radius;
@ArgumentTarget("biome")
private TerraBiome biome;
@SwitchTarget("teleport")
private boolean teleport;
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
new Thread(new AsyncBiomeFinder(main.getWorld(player.getWorld()).getBiomeProvider(), biome, player.getLocation().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), 0, radius, location -> {
if(location != null) {
sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", biome.getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.getLocation().getY(), 0)).distance(player.getLocation().toVector())));
if(teleport) {
main.runPossiblyUnsafeTask(() -> player.setLocation(new Location(player.getWorld(), location.getX(), player.getLocation().getY(), location.getZ())));
}
} else LangUtil.send("command.biome.unable-to-locate", sender);
}, main), "Biome Location Thread").start();
}
}

View File

@@ -0,0 +1,19 @@
package com.dfsek.terra.commands.biome.arg;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.world.biome.TerraBiome;
public class BiomeArgumentParser implements ArgumentParser<TerraBiome> {
@Inject
private TerraPlugin main;
@Override
public TerraBiome parse(CommandSender sender, String arg) {
Player player = (Player) sender;
return main.getWorld(player.getWorld()).getConfig().getBiomeRegistry().get(arg);
}
}

View File

@@ -0,0 +1,22 @@
package com.dfsek.terra.commands.biome.tab;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.world.biome.TerraBiome;
import java.util.List;
import java.util.stream.Collectors;
public class BiomeTabCompleter implements TabCompleter {
@Inject
private TerraPlugin main;
@Override
public List<String> complete(CommandSender sender) {
Player player = (Player) sender;
return main.getWorld(player.getWorld()).getConfig().getBiomeRegistry().entries().stream().map(TerraBiome::getID).collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,65 @@
package com.dfsek.terra.commands.geometry;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.arg.DoubleArgumentParser;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.math.voxel.DeformedSphere;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import java.util.concurrent.ThreadLocalRandom;
@DebugCommand
@PlayerCommand
@Command(
arguments = {
@Argument(
value = "radius",
argumentParser = IntegerArgumentParser.class
),
@Argument(
value = "deform",
argumentParser = DoubleArgumentParser.class
),
@Argument(
value = "frequency",
argumentParser = DoubleArgumentParser.class
)
},
usage = "/terra geometry deformedsphere <RADIUS> <DEFORM> <FREQUENCY>"
)
public class DeformedSphereCommand implements CommandTemplate {
@ArgumentTarget("radius")
private Integer radius;
@ArgumentTarget("deform")
private Double deform;
@ArgumentTarget("frequency")
private Double frequency;
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
OpenSimplex2Sampler noise = new OpenSimplex2Sampler(ThreadLocalRandom.current().nextInt());
noise.setFrequency(frequency);
DeformedSphere sphere = new DeformedSphere(player.getLocation().toVector(), radius, deform, noise);
for(Vector3 v : sphere.getGeometry()) {
v.toLocation(player.getWorld()).getBlock().setBlockData(main.getWorldHandle().createBlockData("minecraft:stone"), false);
}
}
}

View File

@@ -0,0 +1,39 @@
package com.dfsek.terra.commands.geometry;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.config.lang.LangUtil;
@DebugCommand
@PlayerCommand
@Command(
subcommands = {
@Subcommand(
value = "sphere",
clazz = SphereCommand.class,
aliases = {"s"}
),
@Subcommand(
value = "deformedsphere",
clazz = DeformedSphereCommand.class,
aliases = {"df"}
),
@Subcommand(
value = "tube",
clazz = TubeCommand.class,
aliases = {"t"}
)
},
usage = "/terra geometry"
)
public class GeometryCommand implements CommandTemplate {
@Override
public void execute(CommandSender sender) {
LangUtil.send("command.geometry.main-menu", sender);
}
}

View File

@@ -0,0 +1,44 @@
package com.dfsek.terra.commands.geometry;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.math.voxel.Sphere;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
@DebugCommand
@PlayerCommand
@Command(
arguments = {
@Argument(
value = "radius",
argumentParser = IntegerArgumentParser.class
)
},
usage = "/terra geometry sphere <RADIUS>"
)
public class SphereCommand implements CommandTemplate {
@ArgumentTarget("radius")
private Integer radius;
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
Sphere sphere = new Sphere(player.getLocation().toVector(), radius);
for(Vector3 v : sphere.getGeometry()) {
v.toLocation(player.getWorld()).getBlock().setBlockData(main.getWorldHandle().createBlockData("minecraft:stone"), false);
}
}
}

View File

@@ -0,0 +1,49 @@
package com.dfsek.terra.commands.geometry;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.math.voxel.Tube;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.util.generic.pair.Pair;
@DebugCommand
@PlayerCommand
@Command(
arguments = {
@Argument(
value = "radius",
argumentParser = IntegerArgumentParser.class
)
},
usage = "/terra geometry tube <RADIUS>"
)
public class TubeCommand implements CommandTemplate {
@ArgumentTarget("radius")
private Integer radius;
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
Pair<Location, Location> locations = main.getWorldHandle().getSelectedLocation(player);
Tube tube = new Tube(locations.getLeft().toVector(), locations.getRight().toVector(), radius);
for(Vector3 v : tube.getGeometry()) {
v.toLocation(player.getWorld()).getBlock().setBlockData(main.getWorldHandle().createBlockData("minecraft:stone"), false);
}
}
}

View File

@@ -0,0 +1,29 @@
package com.dfsek.terra.commands.profiler;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.config.lang.LangUtil;
@Command(
subcommands = {
@Subcommand(value = "query", aliases = {"q"}, clazz = ProfileQueryCommand.class),
@Subcommand(value = "start", aliases = {"s"}, clazz = ProfileStartCommand.class),
@Subcommand(value = "stop", aliases = {"st"}, clazz = ProfileStopCommand.class),
@Subcommand(value = "reset", aliases = {"r"}, clazz = ProfileResetCommand.class)
},
usage = "Commands to enable/disable/query/reset the profiler."
)
@WorldCommand
@PlayerCommand
@DebugCommand
public class ProfileCommand implements CommandTemplate {
@Override
public void execute(CommandSender sender) {
LangUtil.send("command.profile.main-menu", sender);
}
}

View File

@@ -0,0 +1,28 @@
package com.dfsek.terra.commands.profiler;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.world.TerraWorld;
@Command
@WorldCommand
@PlayerCommand
@DebugCommand
public class ProfileQueryCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
TerraWorld world = main.getWorld(player.getWorld());
player.sendMessage(world.getProfiler().getResultsFormatted());
}
}

View File

@@ -0,0 +1,29 @@
package com.dfsek.terra.commands.profiler;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.world.TerraWorld;
@Command
@WorldCommand
@PlayerCommand
@DebugCommand
public class ProfileResetCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
TerraWorld world = main.getWorld(player.getWorld());
world.getProfiler().reset();
player.sendMessage("Profiler reset.");
}
}

View File

@@ -0,0 +1,29 @@
package com.dfsek.terra.commands.profiler;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.world.TerraWorld;
@Command
@WorldCommand
@PlayerCommand
@DebugCommand
public class ProfileStartCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
TerraWorld world = main.getWorld(player.getWorld());
world.getProfiler().setProfiling(true);
player.sendMessage("Profiling enabled.");
}
}

View File

@@ -0,0 +1,29 @@
package com.dfsek.terra.commands.profiler;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.world.TerraWorld;
@Command
@WorldCommand
@PlayerCommand
@DebugCommand
public class ProfileStopCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
TerraWorld world = main.getWorld(player.getWorld());
world.getProfiler().setProfiling(false);
player.sendMessage("Profiling disabled.");
}
}

View File

@@ -0,0 +1,48 @@
package com.dfsek.terra.commands.structure;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.structures.parser.lang.constants.NumericConstant;
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
import com.dfsek.terra.api.structures.script.functions.CheckFunction;
import com.dfsek.terra.api.structures.structure.Rotation;
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.api.util.FastRandom;
import java.util.HashMap;
@DebugCommand
@PlayerCommand
@WorldCommand
@Command(
usage = "/terra spawn"
)
public class SpawnCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
Location p = player.getLocation();
int x = p.getBlockX();
int y = p.getBlockY();
int z = p.getBlockZ();
Position dummy = new Position(0, 0);
String check = new CheckFunction(main, new NumericConstant(0, dummy), new NumericConstant(0, dummy), new NumericConstant(0, dummy), dummy).apply(new TerraImplementationArguments(new StructureBuffer(
new com.dfsek.terra.api.math.vector.Location(player.getWorld(), x, y, z)
), Rotation.NONE, new FastRandom(), 0), new HashMap<>());
sender.sendMessage("Found: " + check);
}
}

View File

@@ -0,0 +1,34 @@
package com.dfsek.terra.commands.structure;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.config.lang.LangUtil;
@Command(
subcommands = {
@Subcommand(
clazz = StructureExportCommand.class,
value = "export",
aliases = "ex"
),
@Subcommand(
clazz = StructureLoadCommand.class,
value = "load",
aliases = "ld"
),
@Subcommand(
clazz = SpawnCommand.class,
value = "spawn",
aliases = "s"
)
},
usage = "/te structure"
)
public class StructureCommand implements CommandTemplate {
@Override
public void execute(CommandSender sender) {
LangUtil.send("command.structure.main-menu", sender);
}
}

View File

@@ -1,40 +1,56 @@
package com.dfsek.terra.bukkit.command.command.structure;
package com.dfsek.terra.commands.structure;
import com.dfsek.terra.bukkit.command.PlayerCommand;
import com.dfsek.terra.bukkit.structure.WorldEditUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.state.BlockState;
import com.dfsek.terra.api.platform.block.state.Sign;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.util.generic.pair.Pair;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
public class ExportCommand extends PlayerCommand {
public ExportCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@PlayerCommand
@WorldCommand
@DebugCommand
@Command(
arguments = {
@Argument(
value = "id"
)
},
usage = "/terra structure export <ID>"
)
public class StructureExportCommand implements CommandTemplate {
@Inject
private TerraPlugin main;
@ArgumentTarget("id")
private String id;
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
Location[] l = WorldEditUtil.getSelectionLocations(sender);
if(l == null) return true;
public void execute(CommandSender sender) {
Player player = (Player) sender;
Location l1 = l[0];
Location l2 = l[1];
Pair<Location, Location> l = main.getWorldHandle().getSelectedLocation(player);
StringBuilder scriptBuilder = new StringBuilder("id \"" + args[0] + "\";\nnum y = 0;\n");
Location l1 = l.getLeft();
Location l2 = l.getRight();
StringBuilder scriptBuilder = new StringBuilder("id \"" + id + "\";\nnum y = 0;\n");
int centerX = 0;
int centerY = 0;
@@ -63,24 +79,24 @@ public class ExportCommand extends PlayerCommand {
Block block = new Location(l1.getWorld(), x, y, z).getBlock();
BlockData data = block.getBlockData();
if(block.getType().equals(Material.STRUCTURE_VOID)) continue;
if(block.getBlockData().isStructureVoid()) continue;
BlockState state = block.getState();
if(state instanceof Sign) {
Sign sign = (Sign) state;
if(sign.getLine(0).equals("[TERRA]")) {
data = Bukkit.createBlockData(sign.getLine(2) + sign.getLine(3));
data = main.getWorldHandle().createBlockData(sign.getLine(2) + sign.getLine(3));
}
}
if(!data.getMaterial().equals(Material.STRUCTURE_VOID)) {
if(!data.isStructureVoid()) {
scriptBuilder.append("block(").append(x - l1.getBlockX() - centerX).append(", y + ").append(y - l1.getBlockY() - centerY).append(", ").append(z - l1.getBlockZ() - centerZ).append(", ")
.append("\"");
scriptBuilder.append(data.getAsString(false)).append("\");\n");
scriptBuilder.append(data.getAsString()).append("\");\n");
}
}
}
}
File file = new File(getMain().getDataFolder() + File.separator + "export" + File.separator + "structures", args[0] + ".tesf");
File file = new File(main.getDataFolder() + File.separator + "export" + File.separator + "structures", id + ".tesf");
try {
file.getParentFile().mkdirs();
file.createNewFile();
@@ -93,29 +109,6 @@ public class ExportCommand extends PlayerCommand {
e.printStackTrace();
}
sender.sendMessage("Exported structure to " + file.getAbsolutePath());
return true;
}
@Override
public String getName() {
return "export";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 1;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -0,0 +1,92 @@
package com.dfsek.terra.commands.structure;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.annotation.type.DebugCommand;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.structures.script.StructureScript;
import com.dfsek.terra.api.structures.structure.Rotation;
import com.dfsek.terra.api.util.FastRandom;
import com.dfsek.terra.commands.structure.argument.ScriptArgumentParser;
import com.dfsek.terra.commands.structure.completer.RotationCompleter;
import com.dfsek.terra.commands.structure.completer.ScriptCompleter;
import java.util.concurrent.ThreadLocalRandom;
@PlayerCommand
@DebugCommand
@WorldCommand
@Command(
arguments = {
@Argument(
value = "structure",
tabCompleter = ScriptCompleter.class,
argumentParser = ScriptArgumentParser.class
),
@Argument(
value = "rotation",
required = false,
tabCompleter = RotationCompleter.class,
argumentParser = IntegerArgumentParser.class,
defaultValue = "0"
)
},
switches = {
@Switch(value = "chunk",
aliases = "c"
)
},
usage = "/terra structure load [ROTATION] [-c]"
)
public class StructureLoadCommand implements CommandTemplate {
@ArgumentTarget("rotation")
private Integer rotation = 0;
@SwitchTarget("chunk")
private boolean chunk;
@ArgumentTarget("structure")
private StructureScript script;
@Inject
private TerraPlugin main;
@Override
public void execute(CommandSender sender) {
System.out.println(rotation);
Player player = (Player) sender;
long t = System.nanoTime();
FastRandom random = new FastRandom(ThreadLocalRandom.current().nextLong());
Rotation r;
try {
r = Rotation.fromDegrees(rotation);
} catch(Exception e) {
sender.sendMessage("Invalid rotation: " + rotation);
return;
}
if(script == null) {
sender.sendMessage("Invalid structure.");
return;
}
if(this.chunk) {
script.execute(player.getLocation(), player.getWorld().getChunkAt(player.getLocation()), random, r);
} else {
script.execute(player.getLocation(), random, r);
}
long l = System.nanoTime() - t;
sender.sendMessage("Took " + ((double) l) / 1000000 + "ms");
}
}

View File

@@ -0,0 +1,18 @@
package com.dfsek.terra.commands.structure.argument;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.arg.ArgumentParser;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.structures.script.StructureScript;
public class ScriptArgumentParser implements ArgumentParser<StructureScript> {
@Inject
private TerraPlugin main;
@Override
public StructureScript parse(CommandSender sender, String arg) {
return main.getWorld(((Player) sender).getWorld()).getConfig().getScriptRegistry().get(arg);
}
}

View File

@@ -0,0 +1,14 @@
package com.dfsek.terra.commands.structure.completer;
import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.platform.CommandSender;
import java.util.Arrays;
import java.util.List;
public class RotationCompleter implements TabCompleter {
@Override
public List<String> complete(CommandSender sender) {
return Arrays.asList("0", "90", "180", "270");
}
}

View File

@@ -0,0 +1,21 @@
package com.dfsek.terra.commands.structure.completer;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.tab.TabCompleter;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.structures.script.StructureScript;
import java.util.List;
import java.util.stream.Collectors;
public class ScriptCompleter implements TabCompleter {
@Inject
private TerraPlugin main;
@Override
public List<String> complete(CommandSender sender) {
return main.getWorld(((Player) sender).getWorld()).getConfig().getScriptRegistry().entries().stream().map(StructureScript::getId).collect(Collectors.toList());
}
}

View File

@@ -63,11 +63,6 @@ public class DummyWorld implements World {
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
}
@Override
public Block getBlockAt(Location l) {
throw new UnsupportedOperationException("Cannot get block in DummyWorld");
}
@Override
public Entity spawnEntity(Location location, EntityType entityType) {
throw new UnsupportedOperationException("Cannot spawn entity in DummyWorld");

View File

@@ -1,19 +1,19 @@
package com.dfsek.terra.config.loaders.config.biome.templates.provider;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.api.world.biome.provider.SingleBiomeProvider;
import com.dfsek.terra.config.builder.BiomeBuilder;
public class SingleBiomeProviderTemplate extends BiomeProviderTemplate {
@Value("biome")
private TerraBiome biome;
private BiomeBuilder biome;
public SingleBiomeProviderTemplate() {
}
@Override
public BiomeProvider build(long seed) {
return new SingleBiomeProvider(biome);
return new SingleBiomeProvider(biome.apply(seed));
}
}

View File

@@ -274,6 +274,7 @@ public class ConfigPack implements LoaderRegistrar {
.registerLoader(NoiseSeeded.class, new NoiseSamplerBuilderLoader(noiseRegistry))
.registerLoader(SingleBiomeProviderTemplate.class, SingleBiomeProviderTemplate::new)
.registerLoader(BiomePipelineTemplate.class, () -> new BiomePipelineTemplate(main))
.registerLoader(ImageProviderTemplate.class, () -> new ImageProviderTemplate(biomeRegistry))
.registerLoader(ImageSamplerTemplate.class, () -> new ImageProviderTemplate(biomeRegistry));
}

View File

@@ -11,7 +11,6 @@ import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.util.world.PopulationUtil;
import com.dfsek.terra.api.world.generation.TerraBlockPopulator;
import com.dfsek.terra.carving.UserDefinedCarver;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.config.templates.CarverTemplate;
import com.dfsek.terra.profiler.ProfileFuture;
@@ -49,7 +48,7 @@ public class CavePopulator implements TerraBlockPopulator {
Set<Block> updateNeeded = new HashSet<>();
c.carve(chunk.getX(), chunk.getZ(), world, (v, type) -> {
Block b = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
BlockData m = handle.getBlockData(b);
BlockData m = b.getBlockData();
BlockType re = m.getBlockType();
switch(type) {
case CENTER:
@@ -85,18 +84,18 @@ public class CavePopulator implements TerraBlockPopulator {
for(Map.Entry<Location, BlockData> entry : shiftCandidate.entrySet()) {
Location l = entry.getKey();
Location mut = l.clone();
BlockData orig = handle.getBlockData(l.getBlock());
BlockData orig = l.getBlock().getBlockData();
do mut.subtract(0, 1, 0);
while(mut.getY() > 0 && handle.getBlockData(mut.getBlock()).matches(orig));
while(mut.getY() > 0 && mut.getBlock().getBlockData().matches(orig));
try {
if(template.getShift().get(entry.getValue().getBlockType()).contains(mut.getBlock().getBlockData().getBlockType())) {
handle.setBlockData(mut.getBlock(), shiftStorage.computeIfAbsent(entry.getValue().getBlockType(), BlockType::getDefaultData), false);
mut.getBlock().setBlockData(shiftStorage.computeIfAbsent(entry.getValue().getBlockType(), BlockType::getDefaultData), false);
}
} catch(NullPointerException ignore) {
}
}
for(Block b : updateNeeded) {
BlockData orig = handle.getBlockData(b);
BlockData orig = b.getBlockData();
b.setBlockData(AIR, false);
b.setBlockData(orig, true);
}

View File

@@ -118,7 +118,7 @@ public class TerraFlora implements Flora {
((Rotatable) data).setRotation(oneFace);
}
}
handle.setBlockData(location.clone().add(0, i + c, 0).getBlock(), data, physics);
location.clone().add(0, i + c, 0).getBlock().setBlockData(data, physics);
}
return true;
}

View File

@@ -40,7 +40,7 @@ public class DeformedSphereOre extends Ore {
if(oreLoc.distance(origin) < (rad + 0.5) * ((ore.getNoise(x, y, z) + 1) * deform)) {
Block b = c.getBlock(oreLoc.getBlockX(), oreLoc.getBlockY(), oreLoc.getBlockZ());
if(getReplaceable().contains(b.getType()) && b.getLocation().getY() >= 0)
handle.setBlockData(b, getMaterial(), isApplyGravity());
b.setBlockData(getMaterial(), isApplyGravity());
}
}
}

View File

@@ -68,7 +68,7 @@ public class VanillaOre extends Ore {
if(x > 15 || z > 15 || y > 255 || x < 0 || z < 0 || y < 0) continue;
Block block = chunk.getBlock(x, y, z);
if((d13 * d13 + d14 * d14 + d15 * d15 < 1.0D) && getReplaceable().contains(block.getType())) {
handle.setBlockData(block, getMaterial(), isApplyGravity());
block.setBlockData(getMaterial(), isApplyGravity());
}
}
}

View File

@@ -112,7 +112,7 @@ warning:
error:
severe-config: "A severe configuration error has prevented Terra from properly generating terrain at coordinates: %1$s, %2$s. Please check your configuration for errors. Any config errors will have been reported above."
debug:
data-save: "Saved population data for world \"%s\""
data-save : "Saved population data."
use-paper:
- "You appear to be using Spigot/CraftBukkit."
- "While Terra &odoes&r work on Spigot, some functionality will be lost. (Terra is untested on CraftBukkit; no support will be given for CraftBukkit)."

View File

@@ -0,0 +1,236 @@
package command;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.TerraCommandManager;
import com.dfsek.terra.api.command.annotation.Argument;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.Subcommand;
import com.dfsek.terra.api.command.annotation.Switch;
import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget;
import com.dfsek.terra.api.command.annotation.inject.SwitchTarget;
import com.dfsek.terra.api.command.arg.DoubleArgumentParser;
import com.dfsek.terra.api.command.arg.IntegerArgumentParser;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.InvalidArgumentsException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.platform.CommandSender;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.fail;
public class CommandTest {
@Test
public void subcommand() throws CommandException {
CommandManager manager = new TerraCommandManager(null);
manager.register("test", DemoParentCommand.class);
manager.execute("test", null, Arrays.asList("subcommand1", "first", "2"));
manager.execute("test", null, Arrays.asList("subcommand2", "first", "2"));
manager.execute("test", null, Arrays.asList("s1", "first", "2", "3.4"));
manager.execute("test", null, Arrays.asList("s2", "first", "2"));
manager.execute("test", null, Arrays.asList("sub1", "first", "2", "3.4"));
manager.execute("test", null, Arrays.asList("sub2", "first", "2"));
manager.execute("test", null, Arrays.asList("first", "2")); // Parent command args
System.out.println("ARGS: " + manager.getMaxArgumentDepth());
}
@Test
public void args() throws CommandException {
CommandManager manager = new TerraCommandManager(null);
manager.register("test", DemoCommand.class);
manager.execute("test", null, Arrays.asList("first", "2"));
manager.execute("test", null, Arrays.asList("first", "2", "3.4"));
}
@Test
public void argsBeforeFlags() throws CommandException {
CommandManager manager = new TerraCommandManager(null);
manager.register("test", DemoCommand.class);
try {
manager.execute("test", null, Arrays.asList("first", "-flag", "2"));
fail();
} catch(InvalidArgumentsException ignore) {
}
}
@Test
public void requiredArgsFirst() throws CommandException {
CommandManager manager = new TerraCommandManager(null);
manager.register("test", DemoInvalidCommand.class);
try {
manager.execute("test", null, Arrays.asList("first", "2"));
fail();
} catch(MalformedCommandException ignore) {
}
}
@Test
public void switches() throws CommandException {
CommandManager manager = new TerraCommandManager(null);
manager.register("test", DemoSwitchCommand.class);
manager.execute("test", null, Arrays.asList("first", "2"));
manager.execute("test", null, Arrays.asList("first", "2", "3.4"));
manager.execute("test", null, Arrays.asList("first", "2", "-a"));
manager.execute("test", null, Arrays.asList("first", "2", "3.4", "-b"));
manager.execute("test", null, Arrays.asList("first", "2", "-aSwitch"));
manager.execute("test", null, Arrays.asList("first", "2", "3.4", "-bSwitch"));
manager.execute("test", null, Arrays.asList("first", "2", "-aSwitch", "-b"));
manager.execute("test", null, Arrays.asList("first", "2", "3.4", "-bSwitch", "-a"));
}
@Command(
arguments = {
@Argument(value = "arg0"),
@Argument(value = "arg1", argumentParser = IntegerArgumentParser.class),
@Argument(value = "arg2", required = false, argumentParser = DoubleArgumentParser.class)
}
)
public static final class DemoCommand implements CommandTemplate {
@ArgumentTarget("arg0")
private String arg0;
@ArgumentTarget("arg1")
private Integer arg1;
@ArgumentTarget("arg2")
private Double arg2;
@Override
public void execute(CommandSender sender) {
System.out.println(arg0);
System.out.println(arg1);
System.out.println(arg2);
}
}
@Command(
arguments = {
@Argument(value = "arg0"),
@Argument(value = "arg1"),
@Argument(value = "arg2", required = false)
},
switches = {
@Switch(value = "a", aliases = {"aSwitch"}),
@Switch(value = "b", aliases = {"bSwitch"})
}
)
public static final class DemoSwitchCommand implements CommandTemplate {
@ArgumentTarget("arg0")
private String arg0;
@ArgumentTarget("arg1")
private String arg1;
@ArgumentTarget("arg2")
private String arg2;
@SwitchTarget("a")
private boolean a;
@SwitchTarget("b")
private boolean b;
@Override
public void execute(CommandSender sender) {
System.out.println(arg0);
System.out.println(arg1);
System.out.println(arg2);
System.out.println("A: " + a);
System.out.println("B: " + b);
}
}
@Command(
arguments = {
@Argument(value = "arg0"),
@Argument(value = "arg2", required = false), // optional arguments must be last. this command is invalid.
@Argument(value = "arg1")
}
)
public static final class DemoInvalidCommand implements CommandTemplate {
@Override
public void execute(CommandSender sender) {
throw new Error("this should never be reached");
}
}
@Command(
arguments = {
@Argument(value = "arg0"),
@Argument(value = "arg1"),
@Argument(value = "arg2", required = false),
},
subcommands = {
@Subcommand(
value = "subcommand1",
aliases = {"s1", "sub1"},
clazz = DemoChildCommand.class
),
@Subcommand(
value = "subcommand2",
aliases = {"s2", "sub2"},
clazz = DemoChildCommand.class // Duplicate command intentional.
)
}
)
public static final class DemoParentCommand implements CommandTemplate {
@ArgumentTarget("arg0")
private String arg0;
@ArgumentTarget("arg1")
private String arg1;
@ArgumentTarget("arg2")
private String arg2;
@Override
public void execute(CommandSender sender) {
System.out.println(arg0);
System.out.println(arg1);
System.out.println(arg2);
}
}
@Command(
arguments = {
@Argument(value = "arg0"),
@Argument(value = "arg1"),
@Argument(value = "arg2", required = false),
}
)
public static final class DemoChildCommand implements CommandTemplate {
@ArgumentTarget("arg0")
private String arg0;
@ArgumentTarget("arg1")
private String arg1;
@ArgumentTarget("arg2")
private String arg2;
@Override
public void execute(CommandSender sender) {
System.out.println(arg0);
System.out.println(arg1);
System.out.println(arg2);
}
}
}

View File

@@ -2,6 +2,7 @@ package com.dfsek.terra.bukkit;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.entity.Entity;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
public class BukkitEntity implements Entity {
@@ -21,6 +22,16 @@ public class BukkitEntity implements Entity {
return BukkitAdapter.adapt(entity.getLocation());
}
@Override
public void setLocation(Location location) {
entity.teleport(BukkitAdapter.adapt(location));
}
@Override
public World getWorld() {
return BukkitAdapter.adapt(entity.getWorld());
}
@Override
public void sendMessage(String message) {
entity.sendMessage(message);

View File

@@ -2,6 +2,7 @@ package com.dfsek.terra.bukkit;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
public class BukkitPlayer implements Player {
@@ -22,6 +23,16 @@ public class BukkitPlayer implements Player {
return new Location(BukkitAdapter.adapt(bukkit.getWorld()), bukkit.getX(), bukkit.getY(), bukkit.getZ());
}
@Override
public void setLocation(Location location) {
delegate.teleport(BukkitAdapter.adapt(location));
}
@Override
public World getWorld() {
return BukkitAdapter.adapt(delegate.getWorld());
}
@Override
public void sendMessage(String message) {
delegate.sendMessage(message);

View File

@@ -6,6 +6,9 @@ import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.addons.annotations.Addon;
import com.dfsek.terra.api.addons.annotations.Author;
import com.dfsek.terra.api.addons.annotations.Version;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.TerraCommandManager;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.event.EventManager;
import com.dfsek.terra.api.event.TerraEventManager;
import com.dfsek.terra.api.platform.block.BlockData;
@@ -19,8 +22,9 @@ import com.dfsek.terra.api.util.logging.DebugLogger;
import com.dfsek.terra.api.util.logging.JavaLogger;
import com.dfsek.terra.api.util.logging.Logger;
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
import com.dfsek.terra.bukkit.command.command.TerraCommand;
import com.dfsek.terra.bukkit.command.command.structure.LocateCommand;
import com.dfsek.terra.bukkit.command.BukkitCommandAdapter;
import com.dfsek.terra.bukkit.command.FixChunkCommand;
import com.dfsek.terra.bukkit.command.SaveDataCommand;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.bukkit.handles.BukkitItemHandle;
import com.dfsek.terra.bukkit.handles.BukkitWorldHandle;
@@ -30,6 +34,7 @@ import com.dfsek.terra.bukkit.listeners.SpigotListener;
import com.dfsek.terra.bukkit.listeners.TerraListener;
import com.dfsek.terra.bukkit.util.PaperUtil;
import com.dfsek.terra.bukkit.world.BukkitBiome;
import com.dfsek.terra.commands.CommandUtil;
import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.PluginConfig;
import com.dfsek.terra.config.lang.LangUtil;
@@ -131,6 +136,11 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin {
return eventManager;
}
@Override
public void runPossiblyUnsafeTask(Runnable task) {
Bukkit.getScheduler().runTask(this, task);
}
@Override
public void onDisable() {
BukkitChunkGeneratorWrapper.saveAll();
@@ -163,15 +173,27 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin {
registry.loadAll(this); // Load all config packs.
PluginCommand c = Objects.requireNonNull(getCommand("terra"));
TerraCommand command = new TerraCommand(this); // Set up main Terra command.
CommandManager manager = new TerraCommandManager(this);
try {
CommandUtil.registerAll(manager);
manager.register("save-data", SaveDataCommand.class);
manager.register("fix-chunk", FixChunkCommand.class);
} catch(MalformedCommandException e) { // This should never happen.
logger().severe("Errors occurred while registering commands.");
e.printStackTrace();
logger().severe("Please report this to Terra.");
Bukkit.getPluginManager().disablePlugin(this);
return;
}
BukkitCommandAdapter command = new BukkitCommandAdapter(manager);
c.setExecutor(command);
c.setTabCompleter(command);
LocateCommand locate = new LocateCommand(command);
PluginCommand locatePl = Objects.requireNonNull(getCommand("locate"));
locatePl.setExecutor(locate); // Override locate command. Once Paper accepts StructureLocateEvent this will be unneeded on Paper implementations.
locatePl.setTabCompleter(locate);
long save = config.getDataSaveInterval();
Bukkit.getScheduler().runTaskTimerAsynchronously(this, BukkitChunkGeneratorWrapper::saveAll, save, save); // Schedule population data saving

View File

@@ -0,0 +1,54 @@
package com.dfsek.terra.bukkit.command;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public class BukkitCommandAdapter implements CommandExecutor, TabCompleter {
private final CommandManager manager;
public BukkitCommandAdapter(CommandManager manager) {
this.manager = manager;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
List<String> argList = new ArrayList<>(Arrays.asList(args));
if(argList.isEmpty()) {
sender.sendMessage("Command requires arguments.");
return true;
}
try {
manager.execute(argList.remove(0), BukkitAdapter.adapt(sender), argList);
} catch(CommandException e) {
sender.sendMessage(e.getMessage());
}
return true;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
List<String> argList = new ArrayList<>(Arrays.asList(args));
try {
return manager.tabComplete(argList.remove(0), BukkitAdapter.adapt(sender), argList).stream()
.filter(s -> s.toLowerCase(Locale.ROOT).startsWith(args[args.length - 1].toLowerCase(Locale.ROOT))).sorted(String::compareTo).collect(Collectors.toList());
} catch(CommandException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
}

View File

@@ -1,112 +0,0 @@
package com.dfsek.terra.bukkit.command;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Represents a command or subcommand, can be nested via getSubCommands.
*/
public abstract class Command implements CommandExecutor, TabCompleter {
private final TerraPlugin main;
public Command(TerraPlugin main) {
this.main = main;
}
public Command(Command parent) {
main = parent.getMain();
}
public TerraPlugin getMain() {
return main;
}
/**
* Gets the name of the command/subcommand
* @return Name of command
*/
public abstract String getName();
/**
* Gets a list of subcommands
* @return List of subcommands
*/
public abstract List<Command> getSubCommands();
/**
* Executes the given command, returning its success.
* <br>
* If false is returned, then the "usage" plugin.yml entry for this command
* (if defined) will be sent to the player.
*
* @param sender Source of the command
* @param command Command which was executed
* @param label Alias of the command which was used
* @param args Passed command arguments
* @return true if a valid command, otherwise false
*/
public abstract boolean execute(@NotNull CommandSender sender, @NotNull org.bukkit.command.Command command, @NotNull String label, @NotNull String[] args);
/**
* Gets the number of arguments
* @return Number of arguments
*/
public abstract int arguments();
/**
* Executes the given command, invoking subcommands if applicable and returning its success.
* <br>
* If false is returned, then the "usage" plugin.yml entry for this command
* (if defined) will be sent to the player.
*
* @param sender Source of the command
* @param command Command which was executed
* @param label Alias of the command which was used
* @param args Passed command arguments
* @return true if a valid command, otherwise false
*/
@Override
public final boolean onCommand(@NotNull CommandSender sender, @NotNull org.bukkit.command.Command command, @NotNull String label, @NotNull String[] args) {
if(this instanceof DebugCommand && ! main.isDebug()) {
main.getLanguage().send("command.debug-only", new BukkitCommandSender(sender));
return true;
}
if(args.length > 0) {
for(Command c : getSubCommands()) {
if(c.getName().equals(args[0])) {
return c.onCommand(sender, command, label, Arrays.stream(args, 1, args.length).toArray(String[]::new));
}
}
if(args.length != arguments()) {
main.getLanguage().send("command.invalid", new BukkitCommandSender(sender), String.valueOf(arguments()), String.valueOf(args.length));
return true;
}
return execute(sender, command, label, args);
}
if(args.length != arguments()) {
main.getLanguage().send("command.invalid", new BukkitCommandSender(sender), String.valueOf(arguments()), String.valueOf(args.length));
return true;
}
return execute(sender, command, label, new String[] {});
}
public abstract List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args);
@Override
public final @Nullable List<String> onTabComplete(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String alias, @NotNull String[] args) {
List<String> complete = new ArrayList<>();
if(args.length > 0) for(Command c : getSubCommands()) {
if(c.getName().startsWith(args[0])) complete.add(c.getName());
if(c.getName().equals(args[0])) return c.onTabComplete(sender, command, alias, Arrays.stream(args, 1, args.length).toArray(String[]::new));
}
complete.addAll(getTabCompletions(sender, alias, args));
return complete;
}
}

View File

@@ -1,8 +0,0 @@
package com.dfsek.terra.bukkit.command;
/**
* Implementing this interface marks a command as debug-only.
* If a parent command implements this interface, all child commands will be considered debug commands, regardless of whether they implement DebugCommand as well.
*/
public interface DebugCommand {
}

View File

@@ -0,0 +1,20 @@
package com.dfsek.terra.bukkit.command;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.command.annotation.type.PlayerCommand;
import com.dfsek.terra.api.command.annotation.type.WorldCommand;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
@Command
@WorldCommand
@PlayerCommand
public class FixChunkCommand implements CommandTemplate {
@Override
public void execute(CommandSender sender) {
Player player = (Player) sender;
BukkitChunkGeneratorWrapper.fixChunk(player.getWorld().getChunkAt(player.getLocation()));
}
}

View File

@@ -1,50 +0,0 @@
package com.dfsek.terra.bukkit.command;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* A command that may only be executed by a player. If executor is not a player, a message will be displayed and no action will be performed.
*/
public abstract class PlayerCommand extends Command {
public PlayerCommand(Command parent) {
super(parent);
}
/**
* Executes the given command, returning its success.
* <br>
* If false is returned, then the "usage" plugin.yml entry for this command
* (if defined) will be sent to the player.
*
* @param sender Source of the command
* @param command Command which was executed
* @param label Alias of the command which was used
* @param args Passed command arguments
* @return true if a valid command, otherwise false
*/
@Override
public final boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!(sender instanceof Player)) {
getMain().getLanguage().send("command.players-only", new BukkitCommandSender(sender));
return true;
}
Player p = (Player) sender;
return execute(p, command, label, args);
}
/**
* Executes the given command, returning its success.
* <br>
* If false is returned, then the "usage" plugin.yml entry for this command
* (if defined) will be sent to the player.
*
* @param sender Player that executed command
* @param command Command which was executed
* @param label Alias of the command which was used
* @param args Passed command arguments
* @return true if a valid command, otherwise false
*/
public abstract boolean execute(@NotNull Player sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args);
}

View File

@@ -0,0 +1,16 @@
package com.dfsek.terra.bukkit.command;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.command.annotation.Command;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.config.lang.LangUtil;
@Command
public class SaveDataCommand implements CommandTemplate {
@Override
public void execute(CommandSender sender) {
BukkitChunkGeneratorWrapper.saveAll();
LangUtil.send("debug.data-save", sender);
}
}

View File

@@ -1,53 +0,0 @@
package com.dfsek.terra.bukkit.command;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull;
/**
* A command that must be executed by a player, in a Terra world.
*/
public abstract class WorldCommand extends PlayerCommand {
public WorldCommand(Command parent) {
super(parent);
}
/**
* Executes the given command, returning its success.
* <br>
* If false is returned, then the "usage" plugin.yml entry for this command
* (if defined) will be sent to the player.
*
* @param sender Source of the command
* @param command Command which was executed
* @param label Alias of the command which was used
* @param args Passed command arguments
* @return true if a valid command, otherwise false
*/
@Override
public boolean execute(@NotNull Player sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(sender.getWorld().getGenerator() instanceof ChunkGenerator) { // TODO: implementation
return execute(sender, command, label, args, sender.getWorld());
} else {
getMain().getLanguage().send("command.world", new BukkitCommandSender(sender));
}
return true;
}
/**
* Executes the given command, returning its success.
* <br>
* If false is returned, then the "usage" plugin.yml entry for this command
* (if defined) will be sent to the player.
*
* @param sender Player that executed command
* @param command Command which was executed
* @param label Alias of the command which was used
* @param args Passed command arguments
* @param world World in which command was executed
* @return true if a valid command, otherwise false
*/
public abstract boolean execute(@NotNull Player sender, @NotNull org.bukkit.command.Command command, @NotNull String label, @NotNull String[] args, World world);
}

View File

@@ -1,41 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class AddonsCommand extends Command {
public AddonsCommand(Command parent) {
super(parent);
}
@Override
public String getName() {
return "addons";
}
@Override
public List<Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
sender.sendMessage("Installed Addons:");
getMain().getAddons().forEach(addon -> sender.sendMessage(" - " + addon.getName() + " v" + addon.getVersion() + " by " + addon.getAuthor()));
return true;
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,45 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class FixChunkCommand extends WorldCommand {
public FixChunkCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player player, @NotNull Command command, @NotNull String s, @NotNull String[] strings, World world) {
BukkitChunkGeneratorWrapper.fixChunk(BukkitAdapter.adapt(player.getLocation().getChunk()));
return true;
}
@Override
public String getName() {
return "fixchunk";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
return Collections.emptyList();
}
}

View File

@@ -1,44 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class GetBlockCommand extends WorldCommand {
public GetBlockCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player player, @NotNull Command command, @NotNull String s, @NotNull String[] strings, World world) {
player.sendMessage("Block: " + getMain().getWorld(BukkitAdapter.adapt(world)).getUngeneratedBlock(BukkitAdapter.adapt(player.getLocation())).getAsString());
return true;
}
@Override
public String getName() {
return "block";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
return Collections.emptyList();
}
}

View File

@@ -1,58 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.Command;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.ConfigPackTemplate;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class PacksCommand extends Command {
public PacksCommand(Command parent) {
super(parent);
}
@Override
public String getName() {
return "packs";
}
@Override
public List<Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public boolean execute(@NotNull CommandSender commandSender, org.bukkit.command.@NotNull Command command, @NotNull String s, @NotNull String[] strings) {
CheckedRegistry<ConfigPack> registry = getMain().getConfigRegistry();
if(registry.entries().size() == 0) {
LangUtil.send("command.packs.none", new BukkitCommandSender(commandSender));
return true;
}
LangUtil.send("command.packs.main", new BukkitCommandSender(commandSender));
registry.entries().forEach(entry -> {
ConfigPackTemplate template = entry.getTemplate();
LangUtil.send("command.packs.pack", new BukkitCommandSender(commandSender), template.getID(), template.getAuthor(), template.getVersion());
});
return true;
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) {
return Collections.emptyList();
}
}

View File

@@ -1,48 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.Command;
import com.dfsek.terra.bukkit.command.DebugCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class ReloadCommand extends Command implements DebugCommand {
public ReloadCommand(Command parent) {
super(parent);
}
@Override
public String getName() {
return "reload";
}
@Override
public List<Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!getMain().reload()) {
LangUtil.send("command.reload-error", new BukkitCommandSender(sender));
return true;
}
LangUtil.send("command.reload", new BukkitCommandSender(sender));
return true;
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,47 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.Command;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class SaveDataCommand extends WorldCommand {
public SaveDataCommand(Command parent) {
super(parent);
}
@Override
public String getName() {
return "save-data";
}
@Override
public List<Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
@Override
public boolean execute(@NotNull Player sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
BukkitChunkGeneratorWrapper.saveAll();
LangUtil.send("debug.data-save", new BukkitCommandSender(sender), w.getName());
return true;
}
}

View File

@@ -1,60 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.Command;
import com.dfsek.terra.bukkit.command.command.biome.BiomeCommand;
import com.dfsek.terra.bukkit.command.command.geometry.GeometryCommand;
import com.dfsek.terra.bukkit.command.command.profile.ProfileCommand;
import com.dfsek.terra.bukkit.command.command.structure.StructureCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class TerraCommand extends Command {
private final List<Command> commands = Arrays.asList(new ReloadCommand(this),
new BiomeCommand(this),
new ProfileCommand(this),
new SaveDataCommand(this),
new StructureCommand(this),
new GeometryCommand(this),
new FixChunkCommand(this),
new VersionCommand(this),
new GetBlockCommand(this),
new PacksCommand(this),
new AddonsCommand(this));
public TerraCommand(TerraPlugin main) {
super(main);
}
@Override
public String getName() {
return "terra";
}
@Override
public List<Command> getSubCommands() {
return commands;
}
@Override
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
LangUtil.send("command.main-menu", new BukkitCommandSender(sender));
return true;
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,44 +0,0 @@
package com.dfsek.terra.bukkit.command.command;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import com.dfsek.terra.bukkit.command.Command;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class VersionCommand extends Command {
public VersionCommand(Command parent) {
super(parent);
}
@Override
public String getName() {
return "version";
}
@Override
public List<Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public boolean execute(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
String terraVersion = ((TerraBukkitPlugin) getMain()).getDescription().getVersion();
LangUtil.send("command.version", new BukkitCommandSender(sender), terraVersion, getMain().platformName());
return true;
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,50 +0,0 @@
package com.dfsek.terra.bukkit.command.command.biome;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.api.world.biome.provider.BiomeProvider;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class BiomeCommand extends WorldCommand {
public BiomeCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
BiomeProvider grid = getMain().getWorld(BukkitAdapter.adapt(sender.getWorld())).getBiomeProvider();
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome(BukkitAdapter.adapt(sender.getLocation()));
LangUtil.send("command.biome.in", BukkitAdapter.adapt(sender), biome.getID());
return true;
}
@Override
public String getName() {
return "biome";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Arrays.asList(new BiomeLocateCommand(this), new BiomeInfoCommand(this));
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,86 +0,0 @@
package com.dfsek.terra.bukkit.command.command.biome;
import com.dfsek.terra.api.world.biome.UserDefinedBiome;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.pack.WorldConfig;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.population.items.TerraStructure;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class BiomeInfoCommand extends WorldCommand {
public BiomeInfoCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
String id = args[0];
WorldConfig cfg = getMain().getWorld(BukkitAdapter.adapt(world)).getConfig();
UserDefinedBiome b;
try {
b = (UserDefinedBiome) cfg.getBiomeRegistry().get(id);
} catch(IllegalArgumentException | NullPointerException e) {
LangUtil.send("command.biome.invalid", new BukkitCommandSender(sender), id);
return true;
}
sender.sendMessage("TerraBiome info for \"" + b.getID() + "\".");
sender.sendMessage("Vanilla biome: " + b.getVanillaBiomes());
BiomeTemplate bio = b.getConfig();
if(bio.getExtend() != null) sender.sendMessage("Extends: " + bio.getExtend());
List<TerraStructure> structureConfigs = bio.getStructures();
if(structureConfigs.size() == 0) sender.sendMessage("No Structures");
else {
sender.sendMessage("-------Structures-------");
for(TerraStructure c : structureConfigs) {
sender.sendMessage(" - " + c.getTemplate().getID());
}
}
return true;
}
@Override
public String getName() {
return "info";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 1;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
if(!(sender instanceof Player) || !TerraWorld.isTerraWorld(BukkitAdapter.adapt(((Player) sender).getWorld())))
return Collections.emptyList();
List<String> ids = new ArrayList<>();
getMain().getWorld(BukkitAdapter.adapt(((Player) sender).getWorld())).getConfig().getBiomeRegistry().forEach((id, biome) -> ids.add(id));
if(args.length == 1)
return ids.stream().filter(string -> string.toUpperCase().startsWith(args[0].toUpperCase())).collect(Collectors.toList());
return Collections.emptyList();
}
}

View File

@@ -1,95 +0,0 @@
package com.dfsek.terra.bukkit.command.command.biome;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.locate.AsyncBiomeFinder;
import com.dfsek.terra.bukkit.TerraBukkitPlugin;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.world.TerraWorld;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@SuppressWarnings("deprecation")
public class BiomeLocateCommand extends WorldCommand {
public BiomeLocateCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@SuppressWarnings("DuplicatedCode")
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
String id = args[0];
int maxRadius;
try {
maxRadius = Integer.parseInt(args[1]);
} catch(NumberFormatException e) {
LangUtil.send("command.biome.invalid-radius", BukkitAdapter.adapt(sender), args[1]);
return true;
}
TerraBiome b;
try {
b = getMain().getWorld(BukkitAdapter.adapt(world)).getConfig().getBiomeRegistry().get(id);
} catch(IllegalArgumentException | NullPointerException e) {
LangUtil.send("command.biome.invalid", BukkitAdapter.adapt(sender), id);
return true;
}
Bukkit.getScheduler().runTaskAsynchronously((TerraBukkitPlugin) getMain(), new AsyncBiomeFinder(getMain().getWorld(BukkitAdapter.adapt(world)).getBiomeProvider(), b, BukkitAdapter.adapt(sender.getLocation().clone().multiply((1D / ((TerraBukkitPlugin) getMain()).getTerraConfig().getBiomeSearchResolution()))), 0, maxRadius, location -> {
if(location != null) {
ComponentBuilder cm = new ComponentBuilder(String.format("The nearest %s is at ", id.toLowerCase()))
.append(String.format("[%d, ~, %d]", location.getBlockX(), location.getBlockZ()), ComponentBuilder.FormatRetention.NONE)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/minecraft:tp %s %d.0 %.2f %d.0", sender.getName(), location.getBlockX(), sender.getLocation().getY(), location.getBlockZ())))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] {new TextComponent("Click to teleport")}))
.color(ChatColor.GREEN)
.append(String.format(" (%.1f blocks away)", location.add(new Vector3(0, sender.getLocation().getY(), 0)).distance(BukkitAdapter.adapt(sender.getLocation().toVector()))), ComponentBuilder.FormatRetention.NONE);
sender.spigot().sendMessage(cm.create());
// LangUtil.send("command.biome.biome-found", sender, String.valueOf(location.getBlockX()), String.valueOf(location.getBlockZ()));
} else LangUtil.send("command.biome.unable-to-locate", BukkitAdapter.adapt(sender));
}, getMain()));
return true;
}
@Override
public String getName() {
return "locate";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 2;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
if(!(sender instanceof Player) || !TerraWorld.isTerraWorld(BukkitAdapter.adapt(((Player) sender).getWorld())))
return Collections.emptyList();
List<String> ids = new ArrayList<>();
getMain().getWorld(BukkitAdapter.adapt(((Player) sender).getWorld())).getConfig().getBiomeRegistry().forEach((id, biome) -> ids.add(id));
if(args.length == 1)
return ids.stream().filter(string -> string.toUpperCase().startsWith(args[0].toUpperCase())).collect(Collectors.toList());
return Collections.emptyList();
}
}

View File

@@ -1,75 +0,0 @@
package com.dfsek.terra.bukkit.command.command.geometry;
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.math.voxel.DeformedSphere;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.PlayerCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class DeformedSphereCommand extends PlayerCommand {
public DeformedSphereCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
int radius;
try {
radius = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
LangUtil.send("command.geometry.deform.invalid-radius", new BukkitCommandSender(sender), args[0]);
return true;
}
double deform;
try {
deform = Double.parseDouble(args[1]);
} catch(NumberFormatException e) {
LangUtil.send("command.geometry.deform.invalid-deform", new BukkitCommandSender(sender), args[1]);
return true;
}
double freq;
try {
freq = Float.parseFloat(args[2]);
} catch(NumberFormatException e) {
LangUtil.send("command.geometry.deform.invalid-frequency", new BukkitCommandSender(sender), args[2]);
return true;
}
OpenSimplex2Sampler n = new OpenSimplex2Sampler((int) sender.getWorld().getSeed());
n.setFrequency(freq);
DeformedSphere sphere = new DeformedSphere(BukkitAdapter.adapt(sender).getLocation().toVector(), radius, deform, n);
for(Vector3 v : sphere.getGeometry()) {
v.toLocation(BukkitAdapter.adapt(sender.getWorld())).getBlock().setBlockData(getMain().getWorldHandle().createBlockData("minecraft:stone"), false);
}
return true;
}
@Override
public String getName() {
return "deformedsphere";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 3;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,46 +0,0 @@
package com.dfsek.terra.bukkit.command.command.geometry;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.DebugCommand;
import com.dfsek.terra.bukkit.command.PlayerCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class GeometryCommand extends PlayerCommand implements DebugCommand {
public GeometryCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
LangUtil.send("command.geometry.main-menu", new BukkitCommandSender(sender));
return true;
}
@Override
public String getName() {
return "geometry";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Arrays.asList(new SphereCommand(this), new TubeCommand(this), new DeformedSphereCommand(this));
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,58 +0,0 @@
package com.dfsek.terra.bukkit.command.command.geometry;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.math.voxel.Sphere;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.BukkitPlayer;
import com.dfsek.terra.bukkit.command.PlayerCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class SphereCommand extends PlayerCommand {
public SphereCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
int radius;
try {
radius = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
LangUtil.send("command.geometry.sphere.invalid-radius", new BukkitCommandSender(sender), args[0]);
return true;
}
Sphere sphere = new Sphere(new BukkitPlayer(sender).getLocation().toVector(), radius);
for(Vector3 v : sphere.getGeometry()) {
v.toLocation(BukkitAdapter.adapt(sender.getWorld())).getBlock().setBlockData(getMain().getWorldHandle().createBlockData("minecraft:stone"), false);
}
return true;
}
@Override
public String getName() {
return "sphere";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 1;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,61 +0,0 @@
package com.dfsek.terra.bukkit.command.command.geometry;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.math.voxel.Tube;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.PlayerCommand;
import com.dfsek.terra.bukkit.structure.WorldEditUtil;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class TubeCommand extends PlayerCommand {
public TubeCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
Location[] l = WorldEditUtil.getSelectionPositions(sender);
if(l == null) return true;
int radius;
try {
radius = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
LangUtil.send("command.geometry.tube.invalid-radius", new BukkitCommandSender(sender), args[0]);
return true;
}
Tube tube = new Tube(BukkitAdapter.adapt(l[0].toVector()), BukkitAdapter.adapt(l[1].toVector()), radius);
for(Vector3 v : tube.getGeometry()) {
v.toLocation(BukkitAdapter.adapt(sender.getWorld())).getBlock().setBlockData(getMain().getWorldHandle().createBlockData("minecraft:stone"), false);
}
return true;
}
@Override
public String getName() {
return "tube";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 1;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,46 +0,0 @@
package com.dfsek.terra.bukkit.command.command.profile;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.config.lang.LangUtil;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ProfileCommand extends WorldCommand {
public ProfileCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World w) {
LangUtil.send("command.profile.main-menu", new BukkitCommandSender(sender));
return true;
}
@Override
public String getName() {
return "profile";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Arrays.asList(new QueryCommand(this), new ResetCommand(this), new StartCommand(this), new StopCommand(this));
}
@Override
public int arguments() {
return 1;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,46 +0,0 @@
package com.dfsek.terra.bukkit.command.command.profile;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.profiler.WorldProfiler;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class QueryCommand extends WorldCommand {
public QueryCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
WorldProfiler profile = getMain().getWorld(BukkitAdapter.adapt(world)).getProfiler();
sender.sendMessage(profile.getResultsFormatted());
return true;
}
@Override
public String getName() {
return "query";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,49 +0,0 @@
package com.dfsek.terra.bukkit.command.command.profile;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.profiler.WorldProfiler;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class ResetCommand extends WorldCommand {
public ResetCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
WorldProfiler profile = getMain().getWorld(BukkitAdapter.adapt(world)).getProfiler();
profile.reset();
LangUtil.send("command.profile.reset", new BukkitCommandSender(sender));
return true;
}
@Override
public String getName() {
return "reset";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,49 +0,0 @@
package com.dfsek.terra.bukkit.command.command.profile;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.profiler.WorldProfiler;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class StartCommand extends WorldCommand {
public StartCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
WorldProfiler profile = getMain().getWorld(BukkitAdapter.adapt(world)).getProfiler();
profile.setProfiling(true);
LangUtil.send("command.profile.start", new BukkitCommandSender(sender));
return true;
}
@Override
public String getName() {
return "start";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@@ -1,49 +0,0 @@
package com.dfsek.terra.bukkit.command.command.profile;
import com.dfsek.terra.bukkit.BukkitCommandSender;
import com.dfsek.terra.bukkit.command.WorldCommand;
import com.dfsek.terra.bukkit.world.BukkitAdapter;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.profiler.WorldProfiler;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class StopCommand extends WorldCommand {
public StopCommand(com.dfsek.terra.bukkit.command.Command parent) {
super(parent);
}
@Override
public boolean execute(@NotNull Player sender, @NotNull Command command, @NotNull String label, @NotNull String[] args, World world) {
WorldProfiler profile = getMain().getWorld(BukkitAdapter.adapt(world)).getProfiler();
profile.setProfiling(false);
LangUtil.send("command.profile.stop", new BukkitCommandSender(sender));
return true;
}
@Override
public String getName() {
return "stop";
}
@Override
public List<com.dfsek.terra.bukkit.command.Command> getSubCommands() {
return Collections.emptyList();
}
@Override
public int arguments() {
return 0;
}
@Override
public List<String> getTabCompletions(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

Some files were not shown because too many files have changed in this diff Show More