more command stuff

This commit is contained in:
dfsek
2021-03-09 20:05:42 -07:00
parent 31b583910e
commit f5c0174473
23 changed files with 151 additions and 424 deletions

View File

@@ -12,9 +12,11 @@ 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;
@@ -128,7 +130,7 @@ public class TerraCommandManager implements CommandManager {
invoke(commandClass, state, commandHolder);
}
private void invoke(Class<? extends CommandTemplate> clazz, ExecutionState state, CommandHolder holder) throws MalformedCommandException {
private void invoke(Class<? extends CommandTemplate> clazz, ExecutionState state, CommandHolder holder) throws CommandException {
try {
CommandTemplate template = clazz.getConstructor().newInstance();
@@ -166,7 +168,11 @@ public class TerraCommandManager implements CommandManager {
}
}
template.execute(state.getSender());
try {
template.execute(state.getSender());
} catch(Throwable e) {
throw new ExecutionException("Failed to execute command: ", e);
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate command: ", e);
}
@@ -216,9 +222,11 @@ public class TerraCommandManager implements CommandManager {
}
try {
if(args.size() <= holder.arguments.size()) {
completions.addAll(holder.arguments.get(args.size() - 1).tabCompleter().getConstructor().newInstance().complete(sender));
TabCompleter completer = holder.arguments.get(args.size() - 1).tabCompleter().getConstructor().newInstance();
pluginInjector.inject(completer);
completions.addAll(completer.complete(sender));
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
throw new MalformedCommandException("Unable to reflectively instantiate tab-completer: ", e);
}
return completions;

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

@@ -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,17 @@
package com.dfsek.terra.commands;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.command.CommandTemplate;
import com.dfsek.terra.api.injection.annotations.Inject;
import com.dfsek.terra.api.platform.CommandSender;
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

@@ -9,5 +9,6 @@ public final class CommandUtil {
manager.register("structure", StructureCommand.class);
manager.register("profile", ProfileCommand.class);
manager.register("reload", ReloadCommand.class);
manager.register("addons", AddonsCommand.class);
}
}

View File

@@ -0,0 +1,18 @@
package com.dfsek.terra.commands.structure;
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,21 @@
package com.dfsek.terra.commands.structure;
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

@@ -1,15 +1,35 @@
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 java.util.concurrent.ThreadLocalRandom;
@PlayerCommand
@DebugCommand
@WorldCommand
@Command(
arguments = {
@Argument(
value = "structure",
tabCompleter = ScriptCompleter.class,
argumentParser = ScriptArgumentParser.class
),
@Argument(
value = "rotation",
required = false,
@@ -25,10 +45,43 @@ import com.dfsek.terra.api.platform.CommandSender;
)
public class StructureLoadCommand implements CommandTemplate {
@ArgumentTarget("rotation")
private Integer 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

@@ -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,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,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,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,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();
}
}

View File

@@ -67,11 +67,6 @@ public class BukkitWorld implements World {
return new BukkitBlock(delegate.getBlockAt(x, y, z));
}
@Override
public Block getBlockAt(Location l) {
return new BukkitBlock(delegate.getBlockAt(l.getBlockX(), l.getBlockY(), l.getBlockZ()));
}
@Override
public Entity spawnEntity(Location location, EntityType entityType) {
return new BukkitEntity(delegate.spawnEntity(BukkitAdapter.adapt(location), ((BukkitEntityType) entityType).getHandle()));

View File

@@ -85,11 +85,6 @@ public class FabricWorld implements World, FabricWorldHandle {
return ((ServerWorldAccess) ((FabricWorld) obj).delegate.world).toServerWorld().equals(((ServerWorldAccess) delegate.world).toServerWorld());
}
@Override
public Block getBlockAt(Location l) {
return getBlockAt(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
@Override
public Entity spawnEntity(Location location, EntityType entityType) {
net.minecraft.entity.Entity entity = FabricAdapter.adapt(entityType).create(delegate.world);

View File

@@ -73,11 +73,6 @@ public class FabricSeededWorldAccess implements World, FabricWorldHandle {
return new FabricBlock(pos, handle.worldAccess);
}
@Override
public Block getBlockAt(Location l) {
return getBlockAt(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
@Override
public Entity spawnEntity(Location location, EntityType entityType) {
net.minecraft.entity.Entity entity = FabricAdapter.adapt(entityType).create((ServerWorld) handle.worldAccess);

View File

@@ -72,11 +72,6 @@ public class FabricWorldAccess implements World, FabricWorldHandle {
return new FabricBlock(pos, delegate);
}
@Override
public Block getBlockAt(Location l) {
return getBlockAt(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
@Override
public Entity spawnEntity(Location location, EntityType entityType) {
net.minecraft.entity.Entity entity = FabricAdapter.adapt(entityType).create(((ServerWorldAccess) delegate).toServerWorld());

View File

@@ -82,11 +82,6 @@ public class DirectWorld implements World {
return new DirectBlock(this, new Vector3(x, y, z));
}
@Override
public Block getBlockAt(Location l) {
return getBlockAt(l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
@Override
public Entity spawnEntity(Location location, EntityType entityType) {
return null;