mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-22 16:18:32 +00:00
basic bukkit implementation
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
package com.dfsek.terra.api.command;
|
||||
|
||||
import com.dfsek.terra.api.command.exception.CommandException;
|
||||
import com.dfsek.terra.api.platform.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CommandManager {
|
||||
void execute(String command, List<String> args) throws CommandException;
|
||||
void execute(String command, CommandSender sender, List<String> args) throws CommandException;
|
||||
|
||||
void register(String name, Class<? extends CommandTemplate> clazz);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
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;
|
||||
@@ -8,9 +10,10 @@ 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() {
|
||||
|
||||
protected ExecutionState(CommandSender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
protected void addSwitch(String flag) {
|
||||
@@ -42,4 +45,8 @@ public final class ExecutionState {
|
||||
public boolean hasSwitch(String flag) {
|
||||
return switches.contains(flag);
|
||||
}
|
||||
|
||||
public CommandSender getSender() {
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
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.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.exception.CommandException;
|
||||
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.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.world.TerraWorld;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
@@ -18,38 +27,63 @@ import java.util.Map;
|
||||
|
||||
public class TerraCommandManager implements CommandManager {
|
||||
private final Map<String, CommandHolder> commands = new HashMap<>();
|
||||
private final Injector<TerraPlugin> pluginInjector;
|
||||
private final TerraPlugin main;
|
||||
|
||||
@Override
|
||||
public void execute(String commandName, List<String> argsIn) throws CommandException {
|
||||
execute(commands.get(commandName), new ArrayList<>(argsIn));
|
||||
public TerraCommandManager(TerraPlugin main) {
|
||||
this.main = main;
|
||||
this.pluginInjector = new Injector<>(main);
|
||||
pluginInjector.addExplicitTarget(TerraPlugin.class);
|
||||
}
|
||||
|
||||
private void execute(CommandHolder commandHolder, List<String> args) throws CommandException {
|
||||
@Override
|
||||
public void execute(String commandName, CommandSender sender, List<String> argsIn) throws CommandException {
|
||||
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();
|
||||
|
||||
Class<? extends CommandTemplate> commandClass = commandHolder.clazz;
|
||||
ExecutionState state = new ExecutionState(sender);
|
||||
|
||||
if(!commandClass.isAnnotationPresent(Command.class)) {
|
||||
invoke(commandClass, state);
|
||||
return;
|
||||
}
|
||||
|
||||
Command command = commandClass.getAnnotation(Command.class);
|
||||
|
||||
if(command.arguments().length == 0 && command.subcommands().length == 0) {
|
||||
if(args.isEmpty()) invoke(commandClass, state);
|
||||
else throw new InvalidArgumentsException("Expected 0 arguments, found " + args.size());
|
||||
if(args.isEmpty()) {
|
||||
invoke(commandClass, state);
|
||||
return;
|
||||
} else throw new InvalidArgumentsException("Expected 0 arguments, found " + args.size());
|
||||
}
|
||||
|
||||
if(commandHolder.subcommands.containsKey(args.get(0))) {
|
||||
String c = args.get(0);
|
||||
args.remove(0);
|
||||
execute(commandHolder.subcommands.get(c), args);
|
||||
execute(commandHolder.subcommands.get(c), sender, args);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
boolean req = true;
|
||||
for(Argument argument : command.arguments()) {
|
||||
if(!req && argument.required()) {
|
||||
@@ -83,15 +117,18 @@ public class TerraCommandManager implements CommandManager {
|
||||
state.addSwitch(commandHolder.switches.get(val));
|
||||
}
|
||||
|
||||
|
||||
invoke(commandClass, state);
|
||||
}
|
||||
|
||||
private void invoke(Class<? extends CommandTemplate> clazz, ExecutionState state) throws MalformedCommandException {
|
||||
try {
|
||||
System.out.println("invocation");
|
||||
clazz.getConstructor().newInstance().execute(state);
|
||||
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
CommandTemplate template = clazz.getConstructor().newInstance();
|
||||
|
||||
pluginInjector.inject(template);
|
||||
|
||||
template.execute(state);
|
||||
} catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InjectionException e) {
|
||||
throw new MalformedCommandException("Unable to reflectively instantiate command: ", e);
|
||||
}
|
||||
}
|
||||
@@ -101,6 +138,9 @@ public class TerraCommandManager implements CommandManager {
|
||||
commands.put(name, new CommandHolder(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-processes command metadata.
|
||||
*/
|
||||
private static final class CommandHolder {
|
||||
private final Class<? extends CommandTemplate> clazz;
|
||||
private final Map<String, CommandHolder> subcommands = new HashMap<>();
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -3,7 +3,10 @@ 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();
|
||||
|
||||
World getWorld();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.dfsek.terra.commands.profiler;
|
||||
|
||||
import com.dfsek.terra.api.command.CommandTemplate;
|
||||
import com.dfsek.terra.api.command.ExecutionState;
|
||||
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;
|
||||
|
||||
@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(ExecutionState state) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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.ExecutionState;
|
||||
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.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(ExecutionState state) {
|
||||
Player player = (Player) state.getSender();
|
||||
TerraWorld world = main.getWorld(player.getWorld());
|
||||
state.getSender().sendMessage(world.getProfiler().getResultsFormatted());
|
||||
}
|
||||
}
|
||||
@@ -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.ExecutionState;
|
||||
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.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(ExecutionState state) {
|
||||
Player player = (Player) state.getSender();
|
||||
TerraWorld world = main.getWorld(player.getWorld());
|
||||
world.getProfiler().reset();
|
||||
state.getSender().sendMessage("Profiler reset.");
|
||||
}
|
||||
}
|
||||
@@ -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.ExecutionState;
|
||||
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.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(ExecutionState state) {
|
||||
Player player = (Player) state.getSender();
|
||||
TerraWorld world = main.getWorld(player.getWorld());
|
||||
world.getProfiler().setProfiling(true);
|
||||
state.getSender().sendMessage("Profiling enabled.");
|
||||
}
|
||||
}
|
||||
@@ -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.ExecutionState;
|
||||
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.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(ExecutionState state) {
|
||||
Player player = (Player) state.getSender();
|
||||
TerraWorld world = main.getWorld(player.getWorld());
|
||||
world.getProfiler().setProfiling(false);
|
||||
state.getSender().sendMessage("Profiling enabled.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user