diff --git a/java/src/game/Game.java b/java/src/game/Game.java index 093a342..61ed363 100755 --- a/java/src/game/Game.java +++ b/java/src/game/Game.java @@ -52,6 +52,7 @@ import game.future.ListenableFuture; import game.future.ListenableFutureTask; import game.audio.AudioInterface; +import game.audio.PositionedSound; import game.audio.SoundManager; import game.audio.Volume; import game.biome.Biome; @@ -256,6 +257,7 @@ public class Game implements IThreadListener { public boolean itemCheat; public boolean dayCycle = true; public boolean showHud = true; + public boolean debugPlayer; private int leftClickCounter; private int rightClickTimer; @@ -348,7 +350,7 @@ public class Game implements IThreadListener { @Variable(name = "con_overlay", category = CVarCategory.CONSOLE, display = "Konsolen-Overlay") public boolean hudOverlay = true; @Variable(name = "con_position", category = CVarCategory.CONSOLE, display = "Position des Overlays") - public ConsolePos hudPos = ConsolePos.TOP; + public ConsolePos hudPos = ConsolePos.BOTTOM; @Variable(name = "con_opacity", category = CVarCategory.CONSOLE, min = 0x00, max = 0xff, display = "Deckkraft Hintergrund") public int hudOpacity = 0x40; public boolean syncLimited; @@ -1006,7 +1008,7 @@ public class Game implements IThreadListener { // gui_render_text(elem, 0, 0, sys.style.text_label, sys.work_buf); Drawing.drawText(draw, 0, 0, 0xffffffff); - str = this.getRight(false); + str = this.getRight(this.debugPlayer); // str = jstr ? (*jsys.env)->GetStringUTFChars(jsys.env, jstr, NULL) : NULL; // offset = 10 + (str ? 10 : 0); StringBuilder sb = new StringBuilder(); @@ -1771,7 +1773,7 @@ public class Game implements IThreadListener { return // list.add(""); - "Schaue auf: " + (entity.isPlayer() ? "Player/" : "") + EntityRegistry.getEntityString(entity) + // " [" + (entity.isPlayer() ? "player" : + (showPlayerInfo ? "Charakter: " : "Schaue auf: ") + (entity.isPlayer() ? "Player/" : "") + EntityRegistry.getEntityString(entity) + // " [" + (entity.isPlayer() ? "player" : /* (EntityRegistry.getEntityID(entity) + "/" + EntityRegistry.getObjectID(entity))) + "]" */ " (" + entity.getId() + ")" + "\n" + String.format("Position: %.3f %.3f %.3f", entity.posX, entity.posY, entity.posZ) + "\n" + @@ -2579,14 +2581,21 @@ public class Game implements IThreadListener { Game.this.showHud ^= true; } }); + this.registerDebug(Keysym.UE, "Spieler in Overlay umschalten", new DebugRunner() { + public void execute(Keysym key) { + Log.CONSOLE.user("Spieler-Info in Overlay: %s", (Game.this.debugPlayer ^= true) ? "an" : "aus"); + } + }); } private boolean handleDebugKey(Keysym key) { DebugFunction func = this.debug.get(key); if(func != null) { Bind.disableInput(key); - if(!(this.open instanceof GuiLoading)) + if(!(this.open instanceof GuiLoading)) { + this.soundManager.playSound(new PositionedSound(SoundEvent.CLICK, Volume.GUI)); func.runner.execute(key); + } } return func != null; } diff --git a/java/src/game/Server.java b/java/src/game/Server.java index 599333e..bbf8fe4 100755 --- a/java/src/game/Server.java +++ b/java/src/game/Server.java @@ -24,7 +24,7 @@ import game.future.ListenableFutureTask; import game.future.ThreadFactoryBuilder; import game.color.TextColor; -import game.command.ScriptEnvironment; +import game.command.CommandEnvironment; import game.dimension.Dimension; import game.dimension.Space; import game.entity.Entity; @@ -108,7 +108,7 @@ public final class Server implements Runnable, IThreadListener { private final List ticked = Lists.newArrayList(); private final List unload = Lists.newArrayList(); private final Map warps = Maps.newTreeMap(); - private final ScriptEnvironment scriptEnv = new ScriptEnvironment(this); + private final CommandEnvironment scriptEnv = new CommandEnvironment(this); // private final String owner; private final File playerDir; private final File baseDir; @@ -152,7 +152,7 @@ public final class Server implements Runnable, IThreadListener { // this.port = port; } - public ScriptEnvironment getScriptEnvironment() { + public CommandEnvironment getScriptEnvironment() { return this.scriptEnv; } diff --git a/java/src/game/command/ScriptArg.java b/java/src/game/command/Argument.java similarity index 81% rename from java/src/game/command/ScriptArg.java rename to java/src/game/command/Argument.java index 8eb83dd..fb1307e 100644 --- a/java/src/game/command/ScriptArg.java +++ b/java/src/game/command/Argument.java @@ -2,13 +2,13 @@ package game.command; import java.util.Map; -public class ScriptArg { +public class Argument { private final Parameter parameter; private final int position; private final String[] inputs; private final Map values; - public ScriptArg(Parameter parameter, int position, String[] inputs, Map values) { + public Argument(Parameter parameter, int position, String[] inputs, Map values) { this.parameter = parameter; this.position = position; this.inputs = inputs; diff --git a/java/src/game/command/ArgumentParser.java b/java/src/game/command/ArgumentParser.java index 509d9ad..6742b41 100644 --- a/java/src/game/command/ArgumentParser.java +++ b/java/src/game/command/ArgumentParser.java @@ -30,7 +30,7 @@ public abstract class ArgumentParser { arg += c; break; default: - throw new ScriptException("Unbekannte Sequenz bei Zeichen %d: '\\%c'", pos + 1, c); + throw new RunException("Unbekannte Sequenz bei Zeichen %d: '\\%c'", pos + 1, c); } } else if(c == '\\') { @@ -54,6 +54,7 @@ public abstract class ArgumentParser { args.add(arg); arg = ""; } + space = true; if(!args.isEmpty()) { cmds.add(args.toArray(new String[args.size()])); args.clear(); @@ -65,9 +66,9 @@ public abstract class ArgumentParser { } } if(escape) - throw new ScriptException("Unvollständige Sequenz bei Zeichen %d", pos + 1); + throw new RunException("Unvollständige Sequenz bei Zeichen %d", pos + 1); if(quote) - throw new ScriptException("Nicht geschlossenes Anführungszeichen bei %d", last + 1); + throw new RunException("Nicht geschlossenes Anführungszeichen bei %d", last + 1); if(!space) args.add(arg); if(!args.isEmpty()) { @@ -83,9 +84,9 @@ public abstract class ArgumentParser { this.name = name; } - public abstract Object parse(ScriptEnvironment env, String input); - public abstract Object getDefault(ScriptEnvironment env); - public abstract String[] getCompletions(ScriptEnvironment env); + public abstract Object parse(CommandEnvironment env, String input); + public abstract Object getDefault(CommandEnvironment env); + public abstract String[] getCompletions(CommandEnvironment env); public abstract Class getTypeClass(); public final String getName() { diff --git a/java/src/game/command/ScriptArgs.java b/java/src/game/command/ArgumentSplitter.java similarity index 85% rename from java/src/game/command/ScriptArgs.java rename to java/src/game/command/ArgumentSplitter.java index feaaeff..aa8ecb6 100644 --- a/java/src/game/command/ScriptArgs.java +++ b/java/src/game/command/ArgumentSplitter.java @@ -8,12 +8,12 @@ import game.collect.Lists; import game.collect.Maps; import game.collect.Sets; -public class ScriptArgs { +public class ArgumentSplitter { private final String command; - private final Map arguments; - private final ScriptEnvironment env; + private final Map arguments; + private final CommandEnvironment env; - protected ScriptArgs(Map arguments, String command, ScriptEnvironment env) { + protected ArgumentSplitter(Map arguments, String command, CommandEnvironment env) { this.arguments = arguments; this.command = command; this.env = env; @@ -29,11 +29,11 @@ public class ScriptArgs { return sb.append("'").toString(); } - public static ScriptArgs parseArgs(ScriptEnvironment env, String str, String[] argv, CachedExecutable cached) { + public static ArgumentSplitter parseArgs(CommandEnvironment env, String str, String[] argv, CachedExecutable cached) { Map parameters = cached.getParameters(); List positionals = Lists.newArrayList(cached.getPositionals()); // String[] argv = ArgumentParser.splitString(str); - Map args = Maps.newHashMap(); + Map args = Maps.newHashMap(); int ppos = 0; boolean parse = true; for(int z = 1; z < argv.length; z++) { @@ -60,20 +60,20 @@ public class ScriptArgs { pos = true; } else { - throw new ScriptException("Position %d: Parameter '%s' ist überflüssig", z, arg); + throw new RunException("Position %d: Parameter '%s' ist überflüssig", z, arg); } if(param == null) - throw new ScriptException("Position %d: Argument '%s' ist unbekannt", z, arg); + throw new RunException("Position %d: Argument '%s' ist unbekannt", z, arg); if(args.containsKey(param.getName())) - throw new ScriptException("Position %d: Parameter '%s' mehrfach angegeben", z, param.getName()); + throw new RunException("Position %d: Parameter '%s' mehrfach angegeben", z, param.getName()); int nargs = param.getParsers().size(); // if(!pos) // z += 1; if(z + (pos ? 0 : 1) + nargs > argv.length) if(nargs == 1 && param.getName().equals(param.getParsers().get(0).getName())) - throw new ScriptException("Position %d: Argument '%s' benötigt einen Parameter", z, param.getName()); + throw new RunException("Position %d: Argument '%s' benötigt einen Parameter", z, param.getName()); else - throw new ScriptException("Position %d: Argument '%s' benötigt %d Parameter (%s)", z, param.getName(), nargs, + throw new RunException("Position %d: Argument '%s' benötigt %d Parameter (%s)", z, param.getName(), nargs, joinArgs(param.getParsers())); Map params = Maps.newHashMapWithExpectedSize(nargs); String[] inputs = new String[nargs + (pos ? 0 : 1)]; @@ -83,26 +83,26 @@ public class ScriptArgs { ArgumentParser parser = param.getParsers().get(apos); if(parse && (par.startsWith("--") || (par.startsWith("-") && par.length() == 2))) if(nargs == 1 && param.getName().equals(parser.getName())) - throw new ScriptException("Position %d: Argument '%s': '%s' als Parameter verwendet", z + n, param.getName(), par); + throw new RunException("Position %d: Argument '%s': '%s' als Parameter verwendet", z + n, param.getName(), par); else - throw new ScriptException("Position %d: Argument '%s': '%s' als Parameter '%s' (#%d) verwendet", z + n, + throw new RunException("Position %d: Argument '%s': '%s' als Parameter '%s' (#%d) verwendet", z + n, param.getName(), par, parser.getName(), apos + 1); try { params.put(parser.getName(), parser.parse(env, par)); } catch(Throwable e) { if(nargs == 1 && param.getName().equals(parser.getName())) - throw new ScriptException(e, "Position %d: Argument '%s': Parameter konnte nicht interpretiert werden", z + n, + throw new RunException(e, "Position %d: Argument '%s': Parameter konnte nicht interpretiert werden", z + n, param.getName()); else - throw new ScriptException(e, "Position %d: Argument '%s': Parameter '%s' (#%d) konnte nicht interpretiert werden", z + n, + throw new RunException(e, "Position %d: Argument '%s': Parameter '%s' (#%d) konnte nicht interpretiert werden", z + n, param.getName(), parser.getName(), apos + 1); } apos += 1; } if(!pos) inputs[0] = arg; - args.put(param.getName(), new ScriptArg(param, z, inputs, params)); + args.put(param.getName(), new Argument(param, z, inputs, params)); z += nargs - (pos ? 1 : 0); } for(Parameter param : parameters.values()) { @@ -110,7 +110,7 @@ public class ScriptArgs { if(param.isRequired()) { for(ArgumentParser parser : param.getParsers()) { if(parser.getDefault(env) == null) - throw new ScriptException("Argument '%s' muss angegeben werden", param.getName()); + throw new RunException("Argument '%s' muss angegeben werden", param.getName()); } } else if(param.getParsers().isEmpty()) { @@ -120,13 +120,13 @@ public class ScriptArgs { for(ArgumentParser parser : param.getParsers()) { params.put(parser.getName(), parser.getDefault(env)); } - args.put(param.getName(), new ScriptArg(param, -1, null, params)); + args.put(param.getName(), new Argument(param, -1, null, params)); } } - return new ScriptArgs(args, str, env); + return new ArgumentSplitter(args, str, env); } - private static String[] getParam(ScriptEnvironment env, String[] argv, CachedExecutable cached) { + private static String[] getParam(CommandEnvironment env, String[] argv, CachedExecutable cached) { Map parameters = cached.getParameters(); List positionals = Lists.newArrayList(cached.getPositionals()); Set args = Sets.newHashSet(); @@ -190,7 +190,7 @@ public class ScriptArgs { return null; } - public static String[] parseComplete(ScriptEnvironment env, String[] argv, CachedExecutable cached, String last) { + public static String[] parseComplete(CommandEnvironment env, String[] argv, CachedExecutable cached, String last) { String[] comp = getParam(env, argv, cached); if(comp == null || comp.length == 0) { Set params = Sets.newTreeSet(); @@ -237,7 +237,7 @@ public class ScriptArgs { // } public T getUnchecked(String name, String par) { - ScriptArg arg = this.arguments.get(name); + Argument arg = this.arguments.get(name); if(arg == null) return null; Object value = arg.getValues().get(par); diff --git a/java/src/game/command/CachedExecutable.java b/java/src/game/command/CachedExecutable.java index 3d98ea1..af728d2 100644 --- a/java/src/game/command/CachedExecutable.java +++ b/java/src/game/command/CachedExecutable.java @@ -42,7 +42,7 @@ public class CachedExecutable { throw new NullPointerException("positions[" + z + "]"); positionals.add(positions[z]); } - List> classes = Lists.newArrayList(ScriptEnvironment.class, ScriptExecutor.class); + List> classes = Lists.newArrayList(CommandEnvironment.class, Executor.class); for(Parameter param : executable.getParamList()) { ArgCombiner combiner = param.getCombiner(); if(combiner != null) { diff --git a/java/src/game/command/ColorParser.java b/java/src/game/command/ColorParser.java index 6c7e5c7..d8db5ff 100644 --- a/java/src/game/command/ColorParser.java +++ b/java/src/game/command/ColorParser.java @@ -11,7 +11,7 @@ public class ColorParser extends IntParser { this(name, def, (Object[])DyeColor.values()); } - public Integer parse(ScriptEnvironment env, String input) { + public Integer parse(CommandEnvironment env, String input) { if(input.startsWith("#")) { input = input.substring(1); } @@ -21,7 +21,7 @@ public class ColorParser extends IntParser { return color.getColor(); } if(input.length() != 6) - throw new ScriptException("Der Farbcode muss 6 Stellen haben, habe %d ('%s')", input.length(), input); + throw new RunException("Der Farbcode muss 6 Stellen haben, habe %d ('%s')", input.length(), input); return super.parse(env, input); } } diff --git a/java/src/game/command/Command.java b/java/src/game/command/Command.java new file mode 100644 index 0000000..76c80fa --- /dev/null +++ b/java/src/game/command/Command.java @@ -0,0 +1,204 @@ +package game.command; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import game.collect.Lists; +import game.collect.Maps; + +import game.command.DoubleParser.DefType; +import game.world.Vec3; +import game.world.World; + +public abstract class Command implements Executable { + private final String name; + private final Map parameters = Maps.newHashMap(); + private final List argList = Lists.newArrayList(); + + private int parPos = 0; + private boolean parReq = true; + + protected Command(String name) { + this.name = name; + } + + protected Command setParamsOptional() { + this.parReq = false; + return this; + } + + protected Command addParameter(String name, ArgCombiner combiner, ArgumentParser ... parsers) { + Parameter param = new Parameter(name, (char)0, this.parPos++, this.parReq, Lists.newArrayList(parsers), combiner); + this.parameters.put(name, param); + this.argList.add(param); + return this; + } + + protected Command addParameter(String name, char shortName, ArgCombiner combiner, ArgumentParser ... parsers) { + Parameter param = new Parameter(name, shortName, -1, false, Lists.newArrayList(parsers), combiner); + this.parameters.put(name, param); + this.argList.add(param); + return this; + } + + protected Command addParameter(String name, ArgumentParser ... parsers) { + return this.addParameter(name, null, parsers); + } + + protected Command addParameter(String name, char shortName, ArgumentParser ... parsers) { + return this.addParameter(name, shortName, null, parsers); + } + + protected Command addParameter(ArgumentParser parser) { + return this.addParameter(parser.getName(), parser); + } + + protected Command addParameter(char shortName, ArgumentParser parser) { + return this.addParameter(parser.getName(), shortName, parser); + } + + protected Command addVector(String name, boolean defaulted, boolean centered) { + return this.addParameter(name, new ArgCombiner() { + public Vec3 combine(Double[] values) { + return new Vec3(values[0], values[1], values[2]); + } + + public Class getTypeClass() { + return Vec3.class; + } + + public Class getInputClass() { + return Double.class; + } + }, + new DoubleParser("x", defaulted ? DefType.X : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered), + new DoubleParser("y", defaulted ? DefType.Y : null, 0.0, (double)World.HEIGHT, false), + new DoubleParser("z", defaulted ? DefType.Z : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered)); + } + + protected Command addWorld(String name, boolean defaulted) { + return this.addParameter(new WorldParser(name, false, defaulted)); + } + + protected Command addDimension(String name, boolean defaulted) { + return this.addParameter(new DimensionParser(name, defaulted)); + } + + protected Command addInt(String name, char shortName, int min, int max, int def) { + return this.addParameter(shortName, new IntParser(name, false, def, min, max, def)); + } + + protected Command addInt(String name, int min, int max, int def) { + return this.addParameter(new IntParser(name, false, def, min, max, def)); + } + + protected Command addDouble(String name, char shortName, double min, double max, double def) { + return this.addParameter(shortName, new DoubleParser(name, def, min, max, false, def)); + } + + protected Command addDouble(String name, double min, double max, double def) { + return this.addParameter(new DoubleParser(name, def, min, max, false, def)); + } + + protected Command addInt(String name, char shortName, int min, int max) { + return this.addParameter(shortName, new IntParser(name, false, null, min, max)); + } + + protected Command addInt(String name, int min, int max) { + return this.addParameter(new IntParser(name, false, null, min, max)); + } + + protected Command addDouble(String name, char shortName, double min, double max) { + return this.addParameter(shortName, new DoubleParser(name, null, min, max, false)); + } + + protected Command addDouble(String name, double min, double max) { + return this.addParameter(new DoubleParser(name, null, min, max, false)); + } + + protected Command addFlag(String name, char shortName) { + return this.addParameter(name, shortName); + } + +// protected ScriptExecutable addFlag(String name) { +// return this.addParameter(name, name.charAt(0)); +// } + + protected Command addEnum(String name, T def, Class clazz, T ... values) { + return this.addParameter(new EnumParser(name, clazz, def, values)); + } + + protected Command addEnum(String name, Class clazz, T ... values) { + return this.addEnum(name, null, clazz, values); + } + + protected Command addEnum(String name, T def, Class clazz, Collection values) { + return this.addEnum(name, def, clazz, values.toArray((T[])Array.newInstance(clazz, values.size()))); + } + + protected Command addEnum(String name, Class clazz, Collection values) { + return this.addEnum(name, null, clazz, values); + } + + protected Command addTag(String name) { + return this.addParameter(new TagParser(name, null)); + } + + protected Command addTag(String name, char shortName) { + return this.addParameter(shortName, new TagParser(name, null)); + } + + protected Command addPlayer(String name, boolean defaulted) { + return this.addParameter(new PlayerParser(name, defaulted)); + } + + protected Command addPlayerEntity(String name, boolean defaulted) { + return this.addParameter(new PlayerEntityParser(name, defaulted)); + } + + protected Command addEntity(String name, boolean defaulted) { + return this.addParameter(new EntityParser(name, defaulted, false)); + } + + protected Command addEntity(String name, char shortName, boolean defaulted) { + return this.addParameter(shortName, new EntityParser(name, defaulted, false)); + } + + protected Command addEntityList(String name, boolean defaulted) { + return this.addParameter(new EntityListParser(name, defaulted, false)); + } + + protected Command addEntityList(String name, char shortName, boolean defaulted) { + return this.addParameter(shortName, new EntityListParser(name, defaulted, false)); + } + + protected Command addLivingEntity(String name, boolean defaulted) { + return this.addParameter(new EntityParser(name, defaulted, true)); + } + + protected Command addLivingEntityList(String name, boolean defaulted) { + return this.addParameter(new EntityListParser(name, defaulted, true)); + } + + protected Command addString(String name, boolean allowEmpty, Object ... completions) { + return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completions)); + } + + protected Command addString(String name, boolean allowEmpty, StringCompleter completer) { + return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completer)); + } + + public Map getParameters() { + return this.parameters; + } + + public List getParamList() { + return this.argList; + } + + public String getName() { + return this.name; + } +} diff --git a/java/src/game/command/ScriptEnvironment.java b/java/src/game/command/CommandEnvironment.java similarity index 60% rename from java/src/game/command/ScriptEnvironment.java rename to java/src/game/command/CommandEnvironment.java index 6f43407..a86ab82 100644 --- a/java/src/game/command/ScriptEnvironment.java +++ b/java/src/game/command/CommandEnvironment.java @@ -4,61 +4,69 @@ import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Function; import game.collect.Lists; import game.collect.Maps; - +import game.collect.Sets; import game.Server; import game.color.TextColor; -import game.command.commands.CommandHelp; -import game.command.commands.CommandMilk; -import game.command.commands.CommandPotion; -import game.command.commands.CommandSpawn; +import game.command.commands.*; import game.log.Log; -public class ScriptEnvironment { +public class CommandEnvironment { private final Server server; private final Map executables = Maps.newTreeMap(); private final List replacers = Lists.newArrayList(); + private final Set builtins = Sets.newHashSet(); + private final Map variables = Maps.newHashMap(); - private ScriptExecutor currentExecutor; + private Executor currentExecutor; private Object previousOutput; - public ScriptEnvironment(Server server) { + public CommandEnvironment(Server server) { this.server = server; this.registerDefaults(); } public void registerExecutable(Executable executable) { CachedExecutable cached = CachedExecutable.cacheExecutable(executable); + if(this.executables.containsKey(cached.getName())) + throw new IllegalStateException("Befehl " + cached.getName() + " ist bereits registriert"); this.executables.put(cached.getName(), cached); this.registerReplacer(cached.getName(), new Function() { public String apply(String str) { Object o; try { - o = ScriptEnvironment.this.execute(str, false); + o = CommandEnvironment.this.execute(str, false); } catch(Throwable e) { - throw new ScriptException(e, "Variable konnte nicht ersetzt werden: '%s' konnte nicht ausgeführt werden", str); + throw new RunException(e, "Variable konnte nicht ersetzt werden: '%s' konnte nicht ausgeführt werden", str); } if(o == null) - throw new ScriptException("Variable konnte nicht ersetzt werden: null von '%s' zurückgegeben", str); + throw new RunException("Variable konnte nicht ersetzt werden: null von '%s' zurückgegeben", str); return o.toString(); } }); } public void registerReplacer(String var, Function function) { + if(this.builtins.contains(var)) + throw new IllegalStateException("Variable " + var + " ist bereits registriert"); this.replacers.add(new PatternReplacer(var, true, function)); + this.builtins.add(var); } public void registerVariable(String var, Variable variable) { + if(this.builtins.contains(var)) + throw new IllegalStateException("Variable " + var + " ist bereits registriert"); this.replacers.add(new PatternReplacer(var, false, new Function() { public String apply(String ign) { return variable.get(); } })); + this.builtins.add(var); } public Server getServer() { @@ -69,7 +77,7 @@ public class ScriptEnvironment { return this.executables; } - public ScriptExecutor getExecutor() { + public Executor getExecutor() { return this.currentExecutor; } @@ -86,10 +94,25 @@ public class ScriptEnvironment { String[][] cmds = ArgumentParser.splitString(line); Object o = null; for(String[] argv : cmds) { - CachedExecutable cached = this.executables.get(argv[0]); + String exec = argv[0]; + String var = null; + int eq = exec.indexOf('='); + if(eq >= 0) { + var = exec.substring(0, eq); + exec = exec.substring(eq + 1); + } + CachedExecutable cached = this.executables.get(exec); if(cached == null) - throw new ScriptException("Skript '%s' existiert nicht", argv[0]); - ScriptArgs args = ScriptArgs.parseArgs(this, cmd, argv, cached); + throw new RunException("Befehl '%s' existiert nicht", exec); + for(int z = 0; z < argv.length; z++) { + String arg = argv[z]; + if(arg.startsWith("$(") && arg.endsWith(")")) { + String resolve = this.variables.get(arg.substring(2, arg.length() - 1)); + if(resolve != null) + argv[z] = resolve; + } + } + ArgumentSplitter args = ArgumentSplitter.parseArgs(this, cmd, argv, cached); List params = Lists.newArrayList(this, this.currentExecutor); for(Parameter param : cached.getExecutable().getParamList()) { ArgCombiner combiner = param.getCombiner(); @@ -116,22 +139,34 @@ public class ScriptEnvironment { try { o = cached.getMethod().invoke(cached.getExecutable(), params.toArray(new Object[params.size()])); } - catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + catch(InvocationTargetException e) { + if(e.getCause() instanceof RuntimeException) + throw ((RuntimeException)e.getCause()); + else + throw new RuntimeException(e.getCause()); + } + catch(IllegalAccessException | IllegalArgumentException e) { throw new RuntimeException(e); } // o = cached.getExecutable().exec(this, args); if(setPrev) this.previousOutput = o; + if(var != null && !var.isEmpty() && !this.builtins.contains(var)) { + if(o != null) + this.variables.put(var, String.valueOf(o)); + else + this.variables.remove(var); + } } return o; } - public void execute(String cmd, ScriptExecutor exec) { + public void execute(String cmd, Executor exec) { this.currentExecutor = exec; try { this.execute(cmd, true); } - catch(ScriptException e) { + catch(RunException e) { Throwable cause = e; do { exec.logConsole(TextColor.RED + cause.getMessage()); @@ -146,10 +181,11 @@ public class ScriptEnvironment { finally { this.currentExecutor = null; this.previousOutput = null; + this.variables.clear(); } } - public List complete(String cmd, ScriptExecutor exec) { + public List complete(String cmd, Executor exec) { this.currentExecutor = exec; List list = Lists.newArrayList(); try { @@ -162,10 +198,11 @@ public class ScriptEnvironment { String param = cmd.endsWith(" ") ? "" : argv[argv.length - 1]; String[] comp; if(argv.length > 1) { - CachedExecutable cached = this.executables.get(argv[0]); + int eq = argv[0].indexOf('='); + CachedExecutable cached = this.executables.get(eq >= 0 ? argv[0].substring(eq + 1) : argv[0]); if(cached == null) return list; - comp = ScriptArgs.parseComplete(this, argv, cached, param); + comp = ArgumentSplitter.parseComplete(this, argv, cached, param); } else { comp = this.executables.keySet().toArray(new String[this.executables.keySet().size()]); @@ -186,25 +223,33 @@ public class ScriptEnvironment { } public void registerDefaults() { - this.registerVariable("id", new Variable() { + this.registerVariable("*", new Variable() { public String get() { - return ScriptEnvironment.this.currentExecutor.getExecId(); + return CommandEnvironment.this.currentExecutor.getExecId(); } }); this.registerVariable("name", new Variable() { public String get() { - return ScriptEnvironment.this.currentExecutor.getExecName(); + return CommandEnvironment.this.currentExecutor.getExecName(); } }); - this.registerVariable("chain", new Variable() { + this.registerVariable("!", new Variable() { public String get() { - return ScriptEnvironment.this.previousOutput == null ? null : ScriptEnvironment.this.previousOutput.toString(); + return CommandEnvironment.this.previousOutput == null ? null : CommandEnvironment.this.previousOutput.toString(); } }); this.registerExecutable(new CommandSpawn()); this.registerExecutable(new CommandPotion()); this.registerExecutable(new CommandMilk()); + this.registerExecutable(new CommandAdmin()); + this.registerExecutable(new CommandRevoke()); + this.registerExecutable(new CommandTp()); + this.registerExecutable(new CommandTele()); + this.registerExecutable(new CommandWorld()); + this.registerExecutable(new CommandOfflinetp()); + this.registerExecutable(new CommandWarp()); + this.registerExecutable(new CommandTime()); this.registerExecutable(new CommandHelp(this)); } diff --git a/java/src/game/command/Completer.java b/java/src/game/command/Completer.java index 30b885d..e09a484 100644 --- a/java/src/game/command/Completer.java +++ b/java/src/game/command/Completer.java @@ -3,5 +3,5 @@ package game.command; import java.util.List; public interface Completer { - void complete(List comp, ScriptEnvironment env, ScriptArgs args, ScriptArg arg); + void complete(List comp, CommandEnvironment env, ArgumentSplitter args, Argument arg); } diff --git a/java/src/game/command/CompletingParser.java b/java/src/game/command/CompletingParser.java index 1053fb4..99701c5 100644 --- a/java/src/game/command/CompletingParser.java +++ b/java/src/game/command/CompletingParser.java @@ -11,7 +11,7 @@ public abstract class CompletingParser extends ArgumentParser { } } - public String[] getCompletions(ScriptEnvironment env) { + public String[] getCompletions(CommandEnvironment env) { return this.defCompletions; } } diff --git a/java/src/game/command/DefaultingParser.java b/java/src/game/command/DefaultingParser.java index ac22c4d..9accdaf 100644 --- a/java/src/game/command/DefaultingParser.java +++ b/java/src/game/command/DefaultingParser.java @@ -8,7 +8,7 @@ public abstract class DefaultingParser extends CompletingParser { this.def = def; } - public Object getDefault(ScriptEnvironment env) { + public Object getDefault(CommandEnvironment env) { return this.def; } diff --git a/java/src/game/command/DimensionParser.java b/java/src/game/command/DimensionParser.java index 7d4e56c..c0bfc72 100644 --- a/java/src/game/command/DimensionParser.java +++ b/java/src/game/command/DimensionParser.java @@ -12,7 +12,7 @@ public class DimensionParser extends CompletingParser { this.useSender = useSender; } - public Object parse(ScriptEnvironment env, String input) { + public Object parse(CommandEnvironment env, String input) { Dimension dim = UniverseRegistry.getDimension(input); if(dim != null) return dim; @@ -24,11 +24,11 @@ public class DimensionParser extends CompletingParser { } dim = UniverseRegistry.getDimension(id); if(dim == null) - throw new ScriptException("Unbekannte Dimension '%s'", input); + throw new RunException("Unbekannte Dimension '%s'", input); return dim; } - public Object getDefault(ScriptEnvironment env) { + public Object getDefault(CommandEnvironment env) { if(!this.useSender) return null; Position pos = env.getExecutor().getExecPos(); @@ -37,7 +37,7 @@ public class DimensionParser extends CompletingParser { // throw new ScriptException("Unbekannte Dimension '%s'"); } - public String[] getCompletions(ScriptEnvironment env) { + public String[] getCompletions(CommandEnvironment env) { return UniverseRegistry.getWorldNames().toArray(new String[UniverseRegistry.getWorldNames().size()]); } diff --git a/java/src/game/command/DoubleParser.java b/java/src/game/command/DoubleParser.java index 408bcb3..d3e32bb 100644 --- a/java/src/game/command/DoubleParser.java +++ b/java/src/game/command/DoubleParser.java @@ -1,5 +1,6 @@ package game.command; +import game.world.BlockPos; import game.world.Position; public class DoubleParser extends DefaultingParser { @@ -10,43 +11,50 @@ public class DoubleParser extends DefaultingParser { private final DefType defType; private final Double min; private final Double max; + private final boolean center; - public DoubleParser(String name, Double def, Double min, Double max, Object ... completions) { + public DoubleParser(String name, Double def, Double min, Double max, boolean center, Object ... completions) { super(name, def, completions); this.defType = null; this.min = min; this.max = max; + this.center = center; } - public DoubleParser(String name, DefType type, Double min, Double max, Object ... completions) { - super(name, null, completions); + public DoubleParser(String name, DefType type, Double min, Double max, boolean center) { + super(name, null); this.defType = type; this.min = min; this.max = max; + this.center = center; } - public Double parse(ScriptEnvironment env, String input) { + public Double parse(CommandEnvironment env, String input) { + Double pre = this.defType != null && input.startsWith("~") ? this.getDefault(env) : null; + input = pre != null ? input.substring(1) : input; double value; try { value = Double.parseDouble(input); } catch(NumberFormatException e) { - throw new ScriptException("Ungültige Gleitkommazahl '%s'", input); + throw new RunException("Ungültige Gleitkommazahl '%s'", input); } + if(this.center && pre == null && input.indexOf('.') < 0) + value += 0.5; if(this.min != null && value < this.min) if(this.max != null) - throw new ScriptException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value); + throw new RunException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value); else - throw new ScriptException("Die Zahl muss mindestens %f betragen, habe %f", this.min, value); + throw new RunException("Die Zahl muss mindestens %f betragen, habe %f", this.min, value); if(this.max != null && value > this.max) if(this.min != null) - throw new ScriptException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value); + throw new RunException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value); else - throw new ScriptException("Die Zahl darf höchstens %f betragen, habe %f", this.max, value); + throw new RunException("Die Zahl darf höchstens %f betragen, habe %f", this.max, value); return value; } - public Double getDefault(ScriptEnvironment env) { + public Double getDefault(CommandEnvironment env) { Position pos = this.defType == null ? null : env.getExecutor().getExecPos(); switch(this.defType) { case X: @@ -66,4 +74,17 @@ public class DoubleParser extends DefaultingParser { public Class getTypeClass() { return this.hasDefault() ? double.class : Double.class; } + + public String[] getCompletions(CommandEnvironment env) { + BlockPos pos = this.defType == null ? null : env.getExecutor().getPointedPosition(); + switch(this.defType) { + case X: + return pos == null ? null : new String[] {"" + pos.getX()}; + case Y: + return pos == null ? null : new String[] {"" + pos.getY()}; + case Z: + return pos == null ? null : new String[] {"" + pos.getZ()}; + } + return super.getCompletions(env); + } } diff --git a/java/src/game/command/EntityListParser.java b/java/src/game/command/EntityListParser.java index 1912c5e..f4fbd1e 100644 --- a/java/src/game/command/EntityListParser.java +++ b/java/src/game/command/EntityListParser.java @@ -1,8 +1,10 @@ package game.command; import java.util.List; +import java.util.Set; import game.collect.Lists; +import game.collect.Sets; import game.entity.Entity; import game.entity.types.EntityLiving; import game.init.EntityRegistry; @@ -14,7 +16,7 @@ public class EntityListParser extends EntityParser { super(name, useSender, livingOnly); } - public Object parse(ScriptEnvironment env, String input) { + public Object parse(CommandEnvironment env, String input) { if(input.equals("**")) { List list = Lists.newArrayList(); for(WorldServer world : env.getServer().getWorlds()) { @@ -29,7 +31,7 @@ public class EntityListParser extends EntityParser { } } if(list.isEmpty()) - throw new ScriptException(this.livingOnly ? "Keine lebendigen Objekte gefunden" : "Keine Objekte gefunden"); + throw new RunException(this.livingOnly ? "Keine lebendigen Objekte gefunden" : "Keine Objekte gefunden"); return list; } else if(input.equals("*")) { @@ -39,33 +41,37 @@ public class EntityListParser extends EntityParser { list.add(plr.getEntity()); } if(list.isEmpty()) - throw new ScriptException("Keine Spieler gefunden"); + throw new RunException("Keine Spieler gefunden"); return list; } - Class clazz = EntityRegistry.getEntityClass(input); - if(clazz != null) { - if(this.livingOnly && !EntityLiving.class.isAssignableFrom(clazz)) - throw new ScriptException("Objekttyp %s ist nicht lebendig", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz))); - List list = Lists.newArrayList(); - for(WorldServer world : env.getServer().getWorlds()) { - for(Entity ent : world.getEntities()) { - if(clazz.isAssignableFrom(ent.getClass())) - list.add(ent); + Set set = Sets.newHashSet(); + for(String tok : input.split(",", -1)) { + Class clazz = EntityRegistry.getEntityClass(tok); + if(clazz != null) { + if(this.livingOnly && !EntityLiving.class.isAssignableFrom(clazz)) + throw new RunException("Objekttyp %s ist nicht lebendig", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz))); + for(WorldServer world : env.getServer().getWorlds()) { + for(Entity ent : world.getEntities()) { + if(clazz.isAssignableFrom(ent.getClass())) + set.add(ent); + } } } - if(list.isEmpty()) - throw new ScriptException("Kein Objekt des Typs %s gefunden", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz))); - return list; + else { + set.add((Entity)super.parse(env, tok)); + } } - return Lists.newArrayList((Entity)super.parse(env, input)); + if(set.isEmpty()) + throw new RunException("Keine Objekte gefunden"); + return Lists.newArrayList(set); } - public Object getDefault(ScriptEnvironment env) { + public Object getDefault(CommandEnvironment env) { Entity entity = (Entity)super.getDefault(env); return entity == null ? null : Lists.newArrayList(entity); } - public String[] getCompletions(ScriptEnvironment env) { + public String[] getCompletions(CommandEnvironment env) { Entity target = env.getExecutor().getPointedEntity(); List comp = target == null || (this.livingOnly && !(target instanceof EntityLiving)) ? Lists.newArrayList() : Lists.newArrayList("#" + target.getId()); comp.addAll(env.getServer().getAllUsernames()); diff --git a/java/src/game/command/EntityParser.java b/java/src/game/command/EntityParser.java index cbeed90..b4944c7 100644 --- a/java/src/game/command/EntityParser.java +++ b/java/src/game/command/EntityParser.java @@ -15,7 +15,7 @@ public class EntityParser extends PlayerEntityParser { this.livingOnly = livingOnly; } - public Object parse(ScriptEnvironment env, String input) { + public Object parse(CommandEnvironment env, String input) { Entity entity = null; if(input.startsWith("#")) { int id = -1; @@ -36,17 +36,17 @@ public class EntityParser extends PlayerEntityParser { entity = (Entity)super.parse(env, input); } if(entity == null) - throw new ScriptException("Objekt '%s' wurde nicht gefunden", input); + throw new RunException("Objekt '%s' wurde nicht gefunden", input); else if(this.livingOnly && !(entity instanceof EntityLiving)) - throw new ScriptException("Objekt muss lebendig sein"); + throw new RunException("Objekt muss lebendig sein"); return entity; } - public Object getDefault(ScriptEnvironment env) { + public Object getDefault(CommandEnvironment env) { return this.useSender && (this.livingOnly ? (env.getExecutor() instanceof EntityLiving) : (env.getExecutor() instanceof Entity)) ? env.getExecutor() : super.getDefault(env); } - public String[] getCompletions(ScriptEnvironment env) { + public String[] getCompletions(CommandEnvironment env) { Entity target = env.getExecutor().getPointedEntity(); List comp = target == null || (this.livingOnly && !(target instanceof EntityLiving)) ? Lists.newArrayList() : Lists.newArrayList("#" + target.getId()); comp.addAll(env.getServer().getAllUsernames()); diff --git a/java/src/game/command/EnumParser.java b/java/src/game/command/EnumParser.java index 86e5482..356348d 100644 --- a/java/src/game/command/EnumParser.java +++ b/java/src/game/command/EnumParser.java @@ -28,7 +28,7 @@ public class EnumParser extends DefaultingParser { } } - public T parse(ScriptEnvironment env, String input) { + public T parse(CommandEnvironment env, String input) { T value = this.lookup.get(input.toLowerCase()); if(value != null) return value; @@ -39,7 +39,7 @@ public class EnumParser extends DefaultingParser { catch(NumberFormatException e) { } if(id < 0 || id >= this.selections.length) - throw new ScriptException("Ungültige Auswahl '%s', muss eine von diesen Optionen sein: %s", input, + throw new RunException("Ungültige Auswahl '%s', muss eine von diesen Optionen sein: %s", input, joinArgs(this.selections)); return this.selections[id]; } diff --git a/java/src/game/command/ScriptExecutor.java b/java/src/game/command/Executor.java similarity index 91% rename from java/src/game/command/ScriptExecutor.java rename to java/src/game/command/Executor.java index b79fcb2..85f7b93 100644 --- a/java/src/game/command/ScriptExecutor.java +++ b/java/src/game/command/Executor.java @@ -4,7 +4,7 @@ import game.entity.Entity; import game.world.BlockPos; import game.world.Position; -public interface ScriptExecutor { +public interface Executor { void logConsole(String msg); String getExecId(); String getExecName(); diff --git a/java/src/game/command/IntParser.java b/java/src/game/command/IntParser.java index 9f220b5..56dc52d 100644 --- a/java/src/game/command/IntParser.java +++ b/java/src/game/command/IntParser.java @@ -12,24 +12,24 @@ public class IntParser extends DefaultingParser { this.hex = hex; } - public Integer parse(ScriptEnvironment env, String input) { + public Integer parse(CommandEnvironment env, String input) { int value; try { value = Integer.parseInt(input, this.hex ? 16 : 10); } catch(NumberFormatException e) { - throw new ScriptException("Ungültige " + (this.hex ? "Hexadezimalzahl" : "Ganzzahl") + " '%s'", input); + throw new RunException("Ungültige " + (this.hex ? "Hexadezimalzahl" : "Ganzzahl") + " '%s'", input); } if(this.min != null && value < this.min) if(this.max != null) - throw new ScriptException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); + throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); else - throw new ScriptException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value); + throw new RunException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value); if(this.max != null && value > this.max) if(this.min != null) - throw new ScriptException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); + throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); else - throw new ScriptException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value); + throw new RunException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value); return value; } diff --git a/java/src/game/command/LongParser.java b/java/src/game/command/LongParser.java index fefe766..e2452f2 100644 --- a/java/src/game/command/LongParser.java +++ b/java/src/game/command/LongParser.java @@ -10,24 +10,24 @@ public class LongParser extends DefaultingParser { this.max = max; } - public Long parse(ScriptEnvironment env, String input) { + public Long parse(CommandEnvironment env, String input) { long value; try { value = Long.parseLong(input); } catch(NumberFormatException e) { - throw new ScriptException("Ungültige Ganzzahl '%s'", input); + throw new RunException("Ungültige Ganzzahl '%s'", input); } if(this.min != null && value < this.min) if(this.max != null) - throw new ScriptException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); + throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); else - throw new ScriptException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value); + throw new RunException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value); if(this.max != null && value > this.max) if(this.min != null) - throw new ScriptException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); + throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value); else - throw new ScriptException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value); + throw new RunException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value); return value; } diff --git a/java/src/game/command/NonDefaultingParser.java b/java/src/game/command/NonDefaultingParser.java index 83d83b3..af97377 100644 --- a/java/src/game/command/NonDefaultingParser.java +++ b/java/src/game/command/NonDefaultingParser.java @@ -5,7 +5,7 @@ public abstract class NonDefaultingParser extends CompletingParser { super(name, completions); } - public Object getDefault(ScriptEnvironment env) { + public Object getDefault(CommandEnvironment env) { return null; } } diff --git a/java/src/game/command/PatternReplacer.java b/java/src/game/command/PatternReplacer.java index 995711d..0f064b8 100644 --- a/java/src/game/command/PatternReplacer.java +++ b/java/src/game/command/PatternReplacer.java @@ -13,7 +13,7 @@ public class PatternReplacer { public PatternReplacer(String variable, boolean matchAll, Function function) { this.variable = variable; this.matchAll = matchAll; - this.pattern = Pattern.compile("\\$\\((" + variable + (matchAll ? "[^\\)]*" : "") + ")\\)"); + this.pattern = Pattern.compile("\\$\\((" + Pattern.quote(variable) + (matchAll ? "[^\\)]*" : "") + ")\\)"); this.function = function; } @@ -25,7 +25,7 @@ public class PatternReplacer { String orig = matcher.group(1); String rep = this.function.apply(orig); if(rep == null) - throw new ScriptException("Variable '%s' konnte in diesem Kontext nicht ersetzt werden", orig); + throw new RunException("Variable '%s' konnte in diesem Kontext nicht ersetzt werden", orig); matcher.appendReplacement(sb, rep); } matcher.appendTail(sb); diff --git a/java/src/game/command/PlayerEntityParser.java b/java/src/game/command/PlayerEntityParser.java index 18630d4..1c9b51d 100644 --- a/java/src/game/command/PlayerEntityParser.java +++ b/java/src/game/command/PlayerEntityParser.java @@ -8,15 +8,15 @@ public class PlayerEntityParser extends PlayerParser { super(name, useSender); } - public Object parse(ScriptEnvironment env, String input) { + public Object parse(CommandEnvironment env, String input) { NetHandlerPlayServer net = (NetHandlerPlayServer)super.parse(env, input); EntityNPC entity = net.getEntity(); if(entity == null) - throw new ScriptException("Spieler-Objekt von '%s' wurde nicht gefunden", input); + throw new RunException("Spieler-Objekt von '%s' wurde nicht gefunden", input); return entity; } - public Object getDefault(ScriptEnvironment env) { + public Object getDefault(CommandEnvironment env) { NetHandlerPlayServer net = (NetHandlerPlayServer)super.getDefault(env); return net == null ? null : net.getEntity(); } diff --git a/java/src/game/command/PlayerParser.java b/java/src/game/command/PlayerParser.java index 861785e..a976ac6 100644 --- a/java/src/game/command/PlayerParser.java +++ b/java/src/game/command/PlayerParser.java @@ -12,18 +12,18 @@ public class PlayerParser extends CompletingParser { this.useSender = useSender; } - public Object parse(ScriptEnvironment env, String input) { + public Object parse(CommandEnvironment env, String input) { NetHandlerPlayServer net = env.getServer().getPlayer(input); if(net == null) - throw new ScriptException("Spieler '%s' wurde nicht gefunden", input); + throw new RunException("Spieler '%s' wurde nicht gefunden", input); return net; } - public Object getDefault(ScriptEnvironment env) { + public Object getDefault(CommandEnvironment env) { return this.useSender && env.getExecutor() instanceof NetHandlerPlayServer ? (NetHandlerPlayServer)env.getExecutor() : null; } - public String[] getCompletions(ScriptEnvironment env) { + public String[] getCompletions(CommandEnvironment env) { List comp = env.getServer().getAllUsernames(); return comp.toArray(new String[comp.size()]); } diff --git a/java/src/game/command/ScriptException.java b/java/src/game/command/RunException.java similarity index 62% rename from java/src/game/command/ScriptException.java rename to java/src/game/command/RunException.java index f6db961..ca97655 100644 --- a/java/src/game/command/ScriptException.java +++ b/java/src/game/command/RunException.java @@ -1,22 +1,22 @@ package game.command; -public class ScriptException extends RuntimeException { - public ScriptException(String desc) { +public class RunException extends RuntimeException { + public RunException(String desc) { super(desc); this.setStackTrace(new StackTraceElement[0]); } - public ScriptException(String fmt, Object ... args) { + public RunException(String fmt, Object ... args) { super(String.format(fmt, args)); this.setStackTrace(new StackTraceElement[0]); } - public ScriptException(Throwable cause, String desc) { + public RunException(Throwable cause, String desc) { super(desc, cause); this.setStackTrace(new StackTraceElement[0]); } - public ScriptException(Throwable cause, String fmt, Object ... args) { + public RunException(Throwable cause, String fmt, Object ... args) { super(String.format(fmt, args), cause); this.setStackTrace(new StackTraceElement[0]); } diff --git a/java/src/game/command/ScriptExecutable.java b/java/src/game/command/ScriptExecutable.java deleted file mode 100644 index 32167d5..0000000 --- a/java/src/game/command/ScriptExecutable.java +++ /dev/null @@ -1,165 +0,0 @@ -package game.command; - -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import game.collect.Lists; -import game.collect.Maps; - -import game.command.DoubleParser.DefType; -import game.world.Vec3; -import game.world.World; - -public abstract class ScriptExecutable implements Executable { - private final String name; - private final Map parameters = Maps.newHashMap(); - private final List argList = Lists.newArrayList(); - - private int parPos = 0; - private boolean parReq = true; - - protected ScriptExecutable(String name) { - this.name = name; - } - - protected ScriptExecutable setParamsOptional() { - this.parReq = false; - return this; - } - - protected ScriptExecutable addParameter(String name, ArgCombiner combiner, ArgumentParser ... parsers) { - Parameter param = new Parameter(name, (char)0, this.parPos++, this.parReq, Lists.newArrayList(parsers), combiner); - this.parameters.put(name, param); - this.argList.add(param); - return this; - } - - protected ScriptExecutable addParameter(String name, char shortName, ArgCombiner combiner, ArgumentParser ... parsers) { - Parameter param = new Parameter(name, shortName, -1, false, Lists.newArrayList(parsers), combiner); - this.parameters.put(name, param); - this.argList.add(param); - return this; - } - - protected ScriptExecutable addParameter(String name, ArgumentParser ... parsers) { - return this.addParameter(name, null, parsers); - } - - protected ScriptExecutable addParameter(String name, char shortName, ArgumentParser ... parsers) { - return this.addParameter(name, shortName, null, parsers); - } - - protected ScriptExecutable addParameter(ArgumentParser parser) { - return this.addParameter(parser.getName(), parser); - } - - protected ScriptExecutable addParameter(char shortName, ArgumentParser parser) { - return this.addParameter(parser.getName(), shortName, parser); - } - - protected ScriptExecutable addVector(String name, boolean defaulted) { - return this.addParameter(name, new ArgCombiner() { - public Vec3 combine(Double[] values) { - return new Vec3(values[0], values[1], values[2]); - } - - public Class getTypeClass() { - return Vec3.class; - } - - public Class getInputClass() { - return Double.class; - } - }, - new DoubleParser("x", defaulted ? DefType.X : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE), - new DoubleParser("y", defaulted ? DefType.Y : null, 0.0, (double)World.HEIGHT), - new DoubleParser("z", defaulted ? DefType.Z : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE)); - } - - protected ScriptExecutable addWorld(String name, boolean defaulted) { - return this.addParameter(new WorldParser(name, false, defaulted)); - } - - protected ScriptExecutable addInt(String name, char shortName, int min, int max, int def) { - return this.addParameter(shortName, new IntParser(name, false, def, min, max, def)); - } - - protected ScriptExecutable addInt(String name, int min, int max, int def) { - return this.addParameter(new IntParser(name, false, def, min, max, def)); - } - - protected ScriptExecutable addFlag(String name, char shortName) { - return this.addParameter(name, shortName); - } - -// protected ScriptExecutable addFlag(String name) { -// return this.addParameter(name, name.charAt(0)); -// } - - protected ScriptExecutable addEnum(String name, T def, Class clazz, T ... values) { - return this.addParameter(new EnumParser(name, clazz, def, values)); - } - - protected ScriptExecutable addEnum(String name, Class clazz, T ... values) { - return this.addEnum(name, null, clazz, values); - } - - protected ScriptExecutable addEnum(String name, T def, Class clazz, Collection values) { - return this.addEnum(name, def, clazz, values.toArray((T[])Array.newInstance(clazz, values.size()))); - } - - protected ScriptExecutable addEnum(String name, Class clazz, Collection values) { - return this.addEnum(name, null, clazz, values); - } - - protected ScriptExecutable addTag(String name) { - return this.addParameter(new TagParser(name, null)); - } - - protected ScriptExecutable addTag(String name, char shortName) { - return this.addParameter(shortName, new TagParser(name, null)); - } - -// public Object exec(ScriptEnvironment env, ScriptArgs args) { -// this.getClass().getDeclaredMethod(name, null) -// return null; -// } - - protected ScriptExecutable addPlayer(String name, boolean defaulted) { - return this.addParameter(new PlayerParser(name, defaulted)); - } - - protected ScriptExecutable addPlayerEntity(String name, boolean defaulted) { - return this.addParameter(new PlayerEntityParser(name, defaulted)); - } - - protected ScriptExecutable addEntity(String name, boolean defaulted) { - return this.addParameter(new EntityParser(name, defaulted, false)); - } - - protected ScriptExecutable addEntityList(String name, boolean defaulted) { - return this.addParameter(new EntityListParser(name, defaulted, false)); - } - - protected ScriptExecutable addLivingEntity(String name, boolean defaulted) { - return this.addParameter(new EntityParser(name, defaulted, true)); - } - - protected ScriptExecutable addLivingEntityList(String name, boolean defaulted) { - return this.addParameter(new EntityListParser(name, defaulted, true)); - } - - public Map getParameters() { - return this.parameters; - } - - public List getParamList() { - return this.argList; - } - - public String getName() { - return this.name; - } -} diff --git a/java/src/game/command/StringCompleter.java b/java/src/game/command/StringCompleter.java new file mode 100644 index 0000000..97e99be --- /dev/null +++ b/java/src/game/command/StringCompleter.java @@ -0,0 +1,5 @@ +package game.command; + +public interface StringCompleter { + String[] complete(CommandEnvironment env); +} diff --git a/java/src/game/command/StringParser.java b/java/src/game/command/StringParser.java index 0c04558..93d55ae 100644 --- a/java/src/game/command/StringParser.java +++ b/java/src/game/command/StringParser.java @@ -7,6 +7,7 @@ public class StringParser extends DefaultingParser { private final Integer minLength; private final Integer maxLength; private final CharValidator validator; + private final StringCompleter completer; public StringParser(String name, String def, boolean allowEmpty, Integer minLength, Integer maxLength, CharValidator validator, Object ... completions) { @@ -15,31 +16,46 @@ public class StringParser extends DefaultingParser { this.minLength = minLength; this.maxLength = maxLength; this.validator = validator; + this.completer = null; } - public String parse(ScriptEnvironment env, String input) { + public StringParser(String name, String def, boolean allowEmpty, Integer minLength, Integer maxLength, CharValidator validator, + StringCompleter completer) { + super(name, def); + this.allowEmpty = allowEmpty; + this.minLength = minLength; + this.maxLength = maxLength; + this.validator = validator; + this.completer = completer; + } + + public String parse(CommandEnvironment env, String input) { if(!this.allowEmpty && input.isEmpty()) - throw new ScriptException("Die Zeichenkette darf nicht leer sein"); + throw new RunException("Die Zeichenkette darf nicht leer sein"); if(this.minLength != null && input.length() < this.minLength) if(this.maxLength != null) - throw new ScriptException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')", + throw new RunException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')", this.minLength, this.maxLength, input.length(), input); else - throw new ScriptException("Die Zeichenkette muss mindestens %d Zeichen lang sein, habe %d ('%s')", + throw new RunException("Die Zeichenkette muss mindestens %d Zeichen lang sein, habe %d ('%s')", this.minLength, input.length(), input); if(this.maxLength != null && input.length() > this.maxLength) if(this.minLength != null) - throw new ScriptException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')", + throw new RunException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')", this.minLength, this.maxLength, input.length(), input); else - throw new ScriptException("Die Zeichenkette darf höchstens %d Zeichen lang sein, habe %d ('%s')", + throw new RunException("Die Zeichenkette darf höchstens %d Zeichen lang sein, habe %d ('%s')", this.maxLength, input.length(), input); if(this.validator != null && !this.validator.valid(input)) - throw new ScriptException("Die Zeichenkette '%s' enthält ungültige Zeichen", input); + throw new RunException("Die Zeichenkette '%s' enthält ungültige Zeichen", input); return input; } public Class getTypeClass() { return String.class; } + + public String[] getCompletions(CommandEnvironment env) { + return this.completer != null ? this.completer.complete(env) : super.getCompletions(env); + } } diff --git a/java/src/game/command/TagParser.java b/java/src/game/command/TagParser.java index b201d59..44327ff 100644 --- a/java/src/game/command/TagParser.java +++ b/java/src/game/command/TagParser.java @@ -9,13 +9,13 @@ public class TagParser extends DefaultingParser { super(name, def, completions); } - public NBTTagCompound parse(ScriptEnvironment env, String input) { + public NBTTagCompound parse(CommandEnvironment env, String input) { NBTTagCompound value; try { value = NBTParser.parseTag(input); } catch(NBTException e) { - throw new ScriptException(e, "Ungültiger NBT-Tag '%s'", input); + throw new RunException(e, "Ungültiger NBT-Tag '%s'", input); } return value; } diff --git a/java/src/game/command/WorldParser.java b/java/src/game/command/WorldParser.java index 7287ed5..69b5e8a 100644 --- a/java/src/game/command/WorldParser.java +++ b/java/src/game/command/WorldParser.java @@ -15,15 +15,15 @@ public class WorldParser extends DimensionParser { this.loadedOnly = loadedOnly; } - public WorldServer parse(ScriptEnvironment env, String input) { + public WorldServer parse(CommandEnvironment env, String input) { Dimension dim = (Dimension)super.parse(env, input); WorldServer world = this.loadedOnly ? env.getServer().getWorldNoLoad(dim.getDimensionId()) : env.getServer().getWorld(dim.getDimensionId()); if(world == null) - throw new ScriptException("Dimension '%s' ist nicht geladen", dim.getFormattedName(false)); + throw new RunException("Dimension '%s' ist nicht geladen", dim.getFormattedName(false)); return world; } - public WorldServer getDefault(ScriptEnvironment env) { + public WorldServer getDefault(CommandEnvironment env) { Dimension dim = (Dimension)super.getDefault(env); return this.loadedOnly ? env.getServer().getWorldNoLoad(dim.getDimensionId()) : env.getServer().getWorld(dim.getDimensionId()); // if(world == null) @@ -31,7 +31,7 @@ public class WorldParser extends DimensionParser { // return world; } - public String[] getCompletions(ScriptEnvironment env) { + public String[] getCompletions(CommandEnvironment env) { if(this.loadedOnly) { List loaded = Lists.newArrayList(); for(WorldServer world : env.getServer().getWorlds()) { diff --git a/java/src/game/command/commands/CommandAdmin.java b/java/src/game/command/commands/CommandAdmin.java new file mode 100644 index 0000000..5201c51 --- /dev/null +++ b/java/src/game/command/commands/CommandAdmin.java @@ -0,0 +1,29 @@ +package game.command.commands; + +import game.command.CommandEnvironment; +import game.command.RunException; +import game.command.Command; +import game.command.Executor; +import game.network.NetHandlerPlayServer; + +public class CommandAdmin extends Command { + public CommandAdmin() { + super("admin"); + + this.addPlayer("player", false); + } + + public void exec(CommandEnvironment env, Executor exec, NetHandlerPlayServer player) { + if(!(exec instanceof NetHandlerPlayServer)) + throw new RunException("Dieser Befehl kann nur von Spielern ausgeführt werden"); + else if(player == exec) + throw new RunException("Du kannst nicht deinen eigenen Admin-Status erneut setzen"); + else if(player.isLocal()) + throw new RunException("%s ist der Host-Spieler", player.getUser()); + else if(player.getAdmin()) + throw new RunException("%s ist bereits ein Admin", player.getUser()); + player.setAdmin(true); + player.logConsole("Du hast Administatorrechte von %s bekommen", exec.getExecId()); + exec.logConsole("%s ist jetzt ein Admin", player.getUser()); + } +} diff --git a/java/src/game/command/commands/CommandHelp.java b/java/src/game/command/commands/CommandHelp.java index 1992a5a..3d2b988 100644 --- a/java/src/game/command/commands/CommandHelp.java +++ b/java/src/game/command/commands/CommandHelp.java @@ -9,25 +9,25 @@ import game.collect.Lists; import game.command.ArgumentParser; import game.command.CachedExecutable; import game.command.Parameter; -import game.command.ScriptEnvironment; -import game.command.ScriptExecutable; -import game.command.ScriptExecutor; +import game.command.CommandEnvironment; +import game.command.Command; +import game.command.Executor; import game.util.Util; -public class CommandHelp extends ScriptExecutable { - public CommandHelp(ScriptEnvironment env) { +public class CommandHelp extends Command { + public CommandHelp(CommandEnvironment env) { super("help"); this.setParamsOptional(); this.addEnum("command", CachedExecutable.class, env.getExecutables().values()); } - public Object exec(ScriptEnvironment env, ScriptExecutor exec, CachedExecutable command) { + public void exec(CommandEnvironment env, Executor exec, CachedExecutable command) { if(command == null) { for(CachedExecutable cmd : env.getExecutables().values()) { this.exec(env, exec, cmd); } - return null; + return; } List list = Lists.newArrayList(); for(Entry entry : command.getParameters().entrySet()) { @@ -52,6 +52,5 @@ public class CommandHelp extends ScriptExecutable { }, param.getParsers())) + (param.isRequired() ? ">" : "]")); } exec.logConsole("%s %s", command.getName(), Util.buildLines(" ", list)); - return null; } } diff --git a/java/src/game/command/commands/CommandMilk.java b/java/src/game/command/commands/CommandMilk.java index 6401fd2..8419b7d 100644 --- a/java/src/game/command/commands/CommandMilk.java +++ b/java/src/game/command/commands/CommandMilk.java @@ -2,13 +2,13 @@ package game.command.commands; import java.util.List; import game.collect.Lists; -import game.command.ScriptEnvironment; -import game.command.ScriptExecutable; -import game.command.ScriptExecutor; +import game.command.CommandEnvironment; +import game.command.Command; +import game.command.Executor; import game.entity.types.EntityLiving; import game.potion.Potion; -public class CommandMilk extends ScriptExecutable { +public class CommandMilk extends Command { public CommandMilk() { super("milk"); @@ -24,7 +24,7 @@ public class CommandMilk extends ScriptExecutable { this.addFlag("negative", 'n'); } - public Object exec(ScriptEnvironment env, ScriptExecutor exec, List entities, Potion type, boolean negative) { + public Object exec(CommandEnvironment env, Executor exec, List entities, Potion type, boolean negative) { int done = 0; for(EntityLiving entity : entities) { if(type != null && entity.hasEffect(type)) { @@ -40,6 +40,6 @@ public class CommandMilk extends ScriptExecutable { } if(done > 1) exec.logConsole(type == null ? "Alle Effekte von %d Objekten entfernt" : "%d Effekte entfernt", entities.size()); - return null; + return done; } } diff --git a/java/src/game/command/commands/CommandOfflinetp.java b/java/src/game/command/commands/CommandOfflinetp.java new file mode 100644 index 0000000..cfb47a9 --- /dev/null +++ b/java/src/game/command/commands/CommandOfflinetp.java @@ -0,0 +1,38 @@ +package game.command.commands; + +import java.util.List; +import game.command.CommandEnvironment; +import game.command.Command; +import game.command.Executor; +import game.command.RunException; +import game.command.StringCompleter; +import game.entity.Entity; +import game.init.UniverseRegistry; +import game.network.NetHandlerPlayServer; +import game.world.Position; + +public class CommandOfflinetp extends Command { + public CommandOfflinetp() { + super("offlinetp"); + + this.addString("user", false, new StringCompleter() { + public String[] complete(CommandEnvironment env) { + return env.getServer().getUsers(); + } + }); + + this.addEntityList("entities", 'e', true); + } + + public Object exec(CommandEnvironment env, Executor exec, String user, List entities) { + NetHandlerPlayServer player = env.getServer().getPlayer(user); + Position pos = player != null ? player.getEntity().getPos() : env.getServer().getOfflinePosition(user); + if(pos == null) + throw new RunException("Spieler '%s' konnte nicht gefunden werden", user); + for(Entity entity : entities) { + entity.teleport(pos); + exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false)); + } + return entities.size(); + } +} diff --git a/java/src/game/command/commands/CommandPotion.java b/java/src/game/command/commands/CommandPotion.java index 96ba237..1f2196c 100644 --- a/java/src/game/command/commands/CommandPotion.java +++ b/java/src/game/command/commands/CommandPotion.java @@ -2,14 +2,14 @@ package game.command.commands; import java.util.List; import game.collect.Lists; -import game.command.ScriptEnvironment; -import game.command.ScriptExecutable; -import game.command.ScriptExecutor; +import game.command.CommandEnvironment; +import game.command.Command; +import game.command.Executor; import game.entity.types.EntityLiving; import game.potion.Potion; import game.potion.PotionEffect; -public class CommandPotion extends ScriptExecutable { +public class CommandPotion extends Command { public CommandPotion() { super("potion"); @@ -29,15 +29,20 @@ public class CommandPotion extends ScriptExecutable { this.addFlag("keep", 'k'); } - public Object exec(ScriptEnvironment env, ScriptExecutor exec, List entities, Potion type, int duration, int strength, boolean particles, boolean ambient, boolean keep) { + public Object exec(CommandEnvironment env, Executor exec, List entities, Potion type, int duration, int strength, boolean particles, boolean ambient, boolean keep) { + int done = 0; for(EntityLiving entity : entities) { - if(!keep && entity.hasEffect(type)) - entity.removeEffect(type.id); - entity.addEffect(new PotionEffect(type.id, duration * 20, strength - 1, ambient, particles)); - exec.logConsole("%d * %s für %d Sekunden an %s gegeben", strength, type.getDisplay(), duration, entity.getCommandName()); + PotionEffect effect = new PotionEffect(type.id, duration * 20, strength - 1, ambient, particles); + if(entity.isPotionApplicable(effect)) { + if(!keep && entity.hasEffect(type)) + entity.removeEffect(type.id); + entity.addEffect(effect); + exec.logConsole("%d * %s für %d Sekunden an %s gegeben", strength, type.getDisplay(), duration, entity.getCommandName()); + done++; + } } - if(entities.size() > 1) - exec.logConsole("%d Effekte vergeben", entities.size()); - return null; + if(done > 1) + exec.logConsole("%d Effekte vergeben", done); + return done; } } diff --git a/java/src/game/command/commands/CommandRevoke.java b/java/src/game/command/commands/CommandRevoke.java new file mode 100644 index 0000000..62452df --- /dev/null +++ b/java/src/game/command/commands/CommandRevoke.java @@ -0,0 +1,29 @@ +package game.command.commands; + +import game.command.CommandEnvironment; +import game.command.RunException; +import game.command.Command; +import game.command.Executor; +import game.network.NetHandlerPlayServer; + +public class CommandRevoke extends Command { + public CommandRevoke() { + super("revoke"); + + this.addPlayer("player", false); + } + + public void exec(CommandEnvironment env, Executor exec, NetHandlerPlayServer player) { + if(!(exec instanceof NetHandlerPlayServer) || !((NetHandlerPlayServer)exec).isLocal()) + throw new RunException("Dieser Befehl kann nur vom Host-Spieler ausgeführt werden"); + else if(player == exec) + throw new RunException("Du kannst nicht deinen eigenen Admin-Status entfernen"); + else if(player.isLocal()) + throw new RunException("%s ist der Host-Spieler", player.getUser()); + else if(!player.getAdmin()) + throw new RunException("%s ist kein Admin", player.getUser()); + player.setAdmin(false); + player.logConsole("Der Host hat deine Administatorrechte entfernt"); + exec.logConsole("%s ist jetzt kein Admin mehr", player.getUser()); + } +} diff --git a/java/src/game/command/commands/CommandSpawn.java b/java/src/game/command/commands/CommandSpawn.java index 709df71..d21707a 100644 --- a/java/src/game/command/commands/CommandSpawn.java +++ b/java/src/game/command/commands/CommandSpawn.java @@ -1,21 +1,24 @@ package game.command.commands; +import java.util.List; import java.util.Set; +import game.collect.Lists; import game.collect.Sets; -import game.command.ScriptEnvironment; -import game.command.ScriptException; -import game.command.ScriptExecutable; -import game.command.ScriptExecutor; +import game.command.CommandEnvironment; +import game.command.RunException; +import game.command.Command; +import game.command.Executor; import game.entity.Entity; import game.entity.types.EntityLiving; import game.init.EntityRegistry; import game.nbt.NBTTagCompound; +import game.util.Util; import game.world.Vec3; import game.world.WorldServer; -public class CommandSpawn extends ScriptExecutable { +public class CommandSpawn extends Command { public CommandSpawn() { super("spawn"); @@ -25,7 +28,7 @@ public class CommandSpawn extends ScriptExecutable { } this.addEnum("type", String.class, names); this.setParamsOptional(); - this.addVector("position", true); + this.addVector("position", true, true); this.addWorld("dim", true); this.addTag("tag"); @@ -34,11 +37,12 @@ public class CommandSpawn extends ScriptExecutable { this.addTag("postTag", 'p'); } - public Object exec(ScriptEnvironment env, ScriptExecutor exec, String type, Vec3 pos, WorldServer world, NBTTagCompound tag, boolean noinit, int count, NBTTagCompound postTag) { + public Object exec(CommandEnvironment env, Executor exec, String type, Vec3 pos, WorldServer world, NBTTagCompound tag, boolean noinit, int count, NBTTagCompound postTag) { + List spawned = Lists.newArrayList(); for(int z = 0; z < count; z++) { Entity entity = EntityRegistry.createEntityByName(type, world); if(entity == null) - throw new ScriptException("Objekt konnte nicht erzeugt werden"); + throw new RunException("Objekt konnte nicht erzeugt werden"); entity.setLocationAndAngles(pos.xCoord, pos.yCoord, pos.zCoord, world.rand.floatv() * 360.0f, 0.0f); if(tag != null) { NBTTagCompound ent = new NBTTagCompound(); @@ -55,8 +59,9 @@ public class CommandSpawn extends ScriptExecutable { ent.merge(postTag); entity.readFromNBT(ent); } + spawned.add("#" + entity.getId()); } exec.logConsole("%s%s bei %d, %d, %d in %s erschaffen", count == 1 ? "" : (count + "x "), EntityRegistry.getEntityName(type), (int)pos.xCoord, (int)pos.yCoord, (int)pos.zCoord, world.dimension.getFormattedName(false)); - return null; + return Util.buildLines(",", spawned); } } diff --git a/java/src/game/command/commands/CommandTele.java b/java/src/game/command/commands/CommandTele.java new file mode 100644 index 0000000..5b918c1 --- /dev/null +++ b/java/src/game/command/commands/CommandTele.java @@ -0,0 +1,31 @@ +package game.command.commands; + +import java.util.List; +import game.command.CommandEnvironment; +import game.dimension.Dimension; +import game.command.Command; +import game.command.Executor; +import game.entity.Entity; +import game.world.Vec3; + +public class CommandTele extends Command { + public CommandTele() { + super("tele"); + + this.addVector("position", false, true); + this.setParamsOptional(); + this.addDimension("dim", true); + this.addDouble("yaw", -180.0, 180.0); + this.addDouble("pitch", -89.0, 89.0); + + this.addEntityList("entities", 'e', true); + } + + public Object exec(CommandEnvironment env, Executor exec, Vec3 position, Dimension dim, Double yaw, Double pitch, List entities) { + for(Entity entity : entities) { + entity.teleport(position.xCoord, position.yCoord, position.zCoord, yaw == null ? entity.rotYaw : yaw.floatValue(), pitch == null ? entity.rotPitch : pitch.floatValue(), dim.getDimensionId()); + exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)position.xCoord, (int)position.yCoord, (int)position.zCoord, dim.getFormattedName(false)); + } + return entities.size(); + } +} diff --git a/java/src/game/command/commands/CommandTime.java b/java/src/game/command/commands/CommandTime.java new file mode 100644 index 0000000..0f31c8b --- /dev/null +++ b/java/src/game/command/commands/CommandTime.java @@ -0,0 +1,95 @@ +package game.command.commands; + +import game.command.CommandEnvironment; +import game.command.RunException; +import game.dimension.Dimension; +import game.command.Command; +import game.command.Executor; +import game.item.ItemSpaceNavigator; +import game.world.Position; +import game.world.WorldServer; + +public class CommandTime extends Command { + public CommandTime() { + super("time"); + + this.addString("time", false, "day", "night", "noon", "midnight", "sunrise", "sunset"); + + this.addFlag("absolute", 'a'); + } + + private long parseInt(String input, long max) { + long num; + try { + num = Long.parseLong(input); + } + catch(NumberFormatException e) { + throw new RunException("'%s' ist keine gültige Zahl", input); + } + if(num < 0) + throw new RunException("Die Zeit muss mindestens 0 betragen", num); + else if(num > max) + throw new RunException("Die Zeit darf höchstens %d betragen", num, max); + return num; + } + + private long parseDayTime(Dimension dim, String arg) { + if(arg.equalsIgnoreCase("sunrise")) + return dim.getRotationalPeriod() / 6L; + else if(arg.equalsIgnoreCase("day")) + return dim.getRotationalPeriod() * 5L / 24L; + else if(arg.equalsIgnoreCase("noon")) + return dim.getRotationalPeriod() / 2L; + else if(arg.equalsIgnoreCase("sunset")) + return dim.getRotationalPeriod() * 5L / 6L; + else if(arg.equalsIgnoreCase("night")) + return dim.getRotationalPeriod() * 21L / 24L; + else if(arg.equalsIgnoreCase("midnight")) + return 0L; + else if(arg.startsWith("@")) + return this.parseInt(arg.substring(1), dim.getRotationalPeriod() - 1); + else + return -1L; + } + + private long parseTime(Dimension dim, String arg) { + long t; + if(arg.toLowerCase().endsWith("y")) + t = dim.getOrbitalPeriod(); + else if(arg.toLowerCase().endsWith("d")) + t = dim.getRotationalPeriod(); + else if(arg.toLowerCase().endsWith("h")) + t = 1000L; + else + t = -1L; + arg = t == -1L ? arg : arg.substring(0, arg.length() - 1); + t = t < 1L ? 1L : t; + return t * this.parseInt(arg, Long.MAX_VALUE); + } + + public Object exec(CommandEnvironment env, Executor exec, String timeStr, boolean absolute) { + Position pos = exec.getExecPos(); + WorldServer world = pos == null ? env.getServer().getSpace() : env.getServer().getWorld(pos.dim); + long time = absolute ? 0L : world.getDayTime(); + long fwd = parseDayTime(world.dimension, timeStr); + if(fwd >= 0L) { + if(absolute) { + time += fwd; + } + else { + time -= world.getDayTime() % world.dimension.getRotationalPeriod(); + time += fwd; + time += time <= world.getDayTime() ? world.dimension.getRotationalPeriod() : 0L; + } + } + else { + time += parseTime(world.dimension, timeStr); + } + for(WorldServer dim : env.getServer().getWorlds()) { + dim.setDayTime(time); + dim.resetWeather(); + } + exec.logConsole("Zeit auf %s gesetzt", ItemSpaceNavigator.formatImperialTime(world, false)); + return time; + } +} diff --git a/java/src/game/command/commands/CommandTp.java b/java/src/game/command/commands/CommandTp.java new file mode 100644 index 0000000..56a1443 --- /dev/null +++ b/java/src/game/command/commands/CommandTp.java @@ -0,0 +1,28 @@ +package game.command.commands; + +import java.util.List; +import game.command.CommandEnvironment; +import game.command.Command; +import game.command.Executor; +import game.entity.Entity; +import game.init.UniverseRegistry; +import game.world.Position; + +public class CommandTp extends Command { + public CommandTp() { + super("tp"); + + this.addEntity("target", false); + + this.addEntityList("entities", 'e', true); + } + + public Object exec(CommandEnvironment env, Executor exec, Entity target, List entities) { + Position pos = target.getPos(); + for(Entity entity : entities) { + entity.teleport(pos); + exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false)); + } + return entities.size(); + } +} diff --git a/java/src/game/command/commands/CommandWarp.java b/java/src/game/command/commands/CommandWarp.java new file mode 100644 index 0000000..0fa9fa0 --- /dev/null +++ b/java/src/game/command/commands/CommandWarp.java @@ -0,0 +1,59 @@ +package game.command.commands; + +import java.util.List; +import game.command.CommandEnvironment; +import game.command.Command; +import game.command.Executor; +import game.command.RunException; +import game.command.StringCompleter; +import game.entity.Entity; +import game.init.Config; +import game.init.UniverseRegistry; +import game.world.BlockPos; +import game.world.Position; +import game.world.WorldServer; + +public class CommandWarp extends Command { + public CommandWarp() { + super("warp"); + + this.addString("warp", true, new StringCompleter() { + public String[] complete(CommandEnvironment env) { + String[] warps = new String[1 + env.getServer().getWarps().size()]; + warps[0] = "spawn"; + int pos = 1; + for(String warp : env.getServer().getWarps().keySet()) { + warps[pos++] = warp; + } + return warps; + } + }); + + this.addEntityList("entities", 'e', true); + } + + public Object exec(CommandEnvironment env, Executor exec, String warp, List entities) { + Position pos; + if(warp.equals("spawn")) { + WorldServer world = env.getServer().getWorld(Config.spawnDim); + world = world == null ? env.getServer().getSpace() : world; + int y = Config.spawnY; + while(world.getState(new BlockPos(Config.spawnX, y, Config.spawnZ)).getBlock().getMaterial().blocksMovement() && y < 511) + y++; + pos = new Position(Config.spawnX + 0.5d, (double)y, Config.spawnZ + 0.5d, + Config.spawnYaw, Config.spawnPitch, world.dimension.getDimensionId()); + } + else { + pos = env.getServer().getWarps().get(warp); + if(pos == null) + throw new RunException("Warp '%s' existiert nicht", warp); + else if(env.getServer().getWorld(pos.dim) == null) + throw new RunException("Warp '%s' hat kein Level (%s)", warp, pos.dim); + } + for(Entity entity : entities) { + entity.teleport(pos); + exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false)); + } + return entities.size(); + } +} diff --git a/java/src/game/command/commands/CommandWorld.java b/java/src/game/command/commands/CommandWorld.java new file mode 100644 index 0000000..a673dca --- /dev/null +++ b/java/src/game/command/commands/CommandWorld.java @@ -0,0 +1,38 @@ +package game.command.commands; + +import java.util.List; +import game.command.CommandEnvironment; +import game.command.Command; +import game.command.Executor; +import game.entity.Entity; +import game.world.BlockPos; +import game.world.WorldServer; + +public class CommandWorld extends Command { + public CommandWorld() { + super("world"); + + this.addWorld("dim", true); + + this.addEntityList("entities", 'e', true); + } + + public Object exec(CommandEnvironment env, Executor exec, WorldServer world, List entities) { + for(Entity entity : entities) { + BlockPos pos = entity.getPosition(); + pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos; + if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) { + while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511) + pos = pos.up(); + } + else { + while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0) + pos = pos.down(); + pos = pos.up(); + } + entity.teleport(pos, world.dimension.getDimensionId()); + exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), pos.getX(), pos.getY(), pos.getZ(), world.dimension.getFormattedName(false)); + } + return entities.size(); + } +} diff --git a/java/src/game/init/Config.java b/java/src/game/init/Config.java index 7059ea2..8b00d69 100755 --- a/java/src/game/init/Config.java +++ b/java/src/game/init/Config.java @@ -351,8 +351,8 @@ public abstract class Config { public static boolean snowStack = false; @Var(name = "authentication") public static boolean auth = false; - @Var(name = "teleportForAll") - public static boolean teleportAllowed = false; +// @Var(name = "teleportForAll") +// public static boolean teleportAllowed = false; @Var(name = "preload_chunks_all") // Vorsicht Lag!! public static boolean preloadAll = false; diff --git a/java/src/game/network/NetHandlerPlayServer.java b/java/src/game/network/NetHandlerPlayServer.java index 1853f26..304c0a6 100755 --- a/java/src/game/network/NetHandlerPlayServer.java +++ b/java/src/game/network/NetHandlerPlayServer.java @@ -23,8 +23,7 @@ import game.clipboard.Rotation; import game.clipboard.RotationValue; import game.clipboard.Vector; import game.color.TextColor; -import game.command.ScriptExecutor; -import game.dimension.Dimension; +import game.command.Executor; import game.entity.Entity; import game.entity.animal.EntityHorse; import game.entity.item.EntityItem; @@ -41,7 +40,6 @@ import game.init.EntityRegistry; import game.init.Items; import game.init.RotationRegistry; import game.init.SoundEvent; -import game.init.UniverseRegistry; import game.inventory.Container; import game.inventory.ContainerChest; import game.inventory.ContainerHorseInventory; @@ -52,7 +50,6 @@ import game.inventory.InventoryPlayer; import game.inventory.Slot; import game.inventory.SlotCrafting; import game.item.ItemControl; -import game.item.ItemSpaceNavigator; import game.item.ItemStack; import game.log.Log; import game.material.Material; @@ -128,7 +125,7 @@ import game.world.WorldServer; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; -public class NetHandlerPlayServer extends NetHandler implements ICrafting, ScriptExecutor +public class NetHandlerPlayServer extends NetHandler implements ICrafting, Executor { private static enum EditAction { SELECT("Auswahlmodus"), COPYPASTE("Kopiermodus"), TRANSFORM("Drehmodus"); @@ -335,10 +332,6 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip public boolean getAdmin() { return this.admin; } - - public void setAdmin(boolean admin) { - this.admin = admin; - } public void setPassword(String pass) { this.password = pass; @@ -1662,7 +1655,6 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip } this.addFeed(comp); } - this.addFeed(TextColor.YELLOW + "time" + TextColor.GRAY + " = " + TextColor.ORANGE + ItemSpaceNavigator.formatImperialTime(this.entity.getServerWorld(), false)); this.addFeed(TextColor.GREEN + "SVARs insgesamt registriert: %d", Config.VARS.size()); return true; } @@ -1672,10 +1664,6 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip // case 0: // break; // case 1: - if(args[0].equals("time")) { - this.addFeed(TextColor.YELLOW + "time" + TextColor.GRAY + " = " + TextColor.ORANGE + ItemSpaceNavigator.formatImperialTime(this.entity.getServerWorld(), false)); - return true; - } Config.Value cfg = Config.VARS.get(args[0]); if(cfg == null) return false; @@ -1692,29 +1680,6 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip // default: } else { - if(args[0].equals("time")) { - long time = this.entity.getServerWorld().getDayTime(); - Long fwd = parseDayTime(args[1]); - if(fwd == null) - return true; - if(fwd >= 0L) { - time -= this.entity.getServerWorld().getDayTime() % this.entity.getServerWorld().dimension.getRotationalPeriod(); - time += fwd; - time += time <= this.entity.getServerWorld().getDayTime() ? this.entity.getServerWorld().dimension.getRotationalPeriod() : 0L; - } - else { - Long add = parseTime(args[1]); - if(add == null) - return true; - time += add; - } - for(WorldServer dim : this.server.getWorlds()) { - dim.setDayTime(time); - dim.resetWeather(); - } - this.addFeed(TextColor.YELLOW + "time" + TextColor.GRAY + " -> " + TextColor.ORANGE + "%s", ItemSpaceNavigator.formatImperialTime(this.entity.getServerWorld(), false)); - return true; - } Config.Value cv = Config.VARS.get(args[0]); if(cv == null) return false; @@ -1757,221 +1722,172 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip return true; } - private boolean setAdmin(String line) { - if(!this.isAdmin() || !line.startsWith("!") || line.indexOf(' ') >= 0) - return false; - line = line.substring(1).trim(); - NetHandlerPlayServer conn = this.server.getPlayer(line); - if(conn == null) - return false; - if(conn.isAdmin() && (conn == this || !this.local)) { - this.addFeed(TextColor.DRED + "Kann diese Aktion nicht an einem Admin ausführen"); - return true; + public void setAdmin(boolean admin) { + this.admin = admin; + if(!this.isAdmin() && this.entity != null && this.entity.noclip) { + this.entity.noclip = false; + this.entity.flying &= this.entity.hasEffect(Potion.flying); + this.entity.fallDistance = 0.0F; + this.sendPlayerAbilities(); + this.addFeed(TextColor.RED + "NoClip wurde deaktiviert"); } - conn.setAdmin(!conn.getAdmin()); - EntityNPC player = conn.getEntity(); - if(!conn.isAdmin() && player.noclip) { -// player.setCheat(false); - player.noclip = false; - player.flying &= player.hasEffect(Potion.flying); - player.fallDistance = 0.0F; - conn.sendPlayerAbilities(); - conn.addFeed(TextColor.RED + "NoClip wurde deaktiviert"); - } - this.addFeed((conn.getAdmin() ? TextColor.GREEN : TextColor.RED) + "Admin-Status von " + conn.getUser() + " wurde " + - (conn.getAdmin() ? "gesetzt" : "zurückgenommen")); - return true; } - private Long parseInt(String input, long max) { - long num; - try { - num = Long.parseLong(input); - } - catch(NumberFormatException e) { - this.addFeed(TextColor.DRED + "'%s' ist keine gültige Zahl", input); - return null; - } +// private Long parseInt(String input, long max) { +// long num; +// try { +// num = Long.parseLong(input); +// } +// catch(NumberFormatException e) { +// this.addFeed(TextColor.DRED + "'%s' ist keine gültige Zahl", input); +// return null; +// } +// +// if(num < 0) { +// this.addFeed(TextColor.DRED + "Die Zeit muss mindestens 0 betragen", num); +// return null; +// } +// else if(num > max) { +// this.addFeed(TextColor.DRED + "Die Zeit darf höchstens %d betragen", num, max); +// return null; +// } +// else { +// return num; +// } +// } - if(num < 0) { - this.addFeed(TextColor.DRED + "Die Zeit muss mindestens 0 betragen", num); - return null; - } - else if(num > max) { - this.addFeed(TextColor.DRED + "Die Zeit darf höchstens %d betragen", num, max); - return null; - } - else { - return num; - } - } - - private Long parseDayTime(String arg) { - Dimension dim = this.entity.getServerWorld().dimension; - if(arg.equalsIgnoreCase("sunrise")) - return dim.getRotationalPeriod() / 6L; - else if(arg.equalsIgnoreCase("day")) - return dim.getRotationalPeriod() * 5L / 24L; - else if(arg.equalsIgnoreCase("noon")) - return dim.getRotationalPeriod() / 2L; - else if(arg.equalsIgnoreCase("sunset")) - return dim.getRotationalPeriod() * 5L / 6L; - else if(arg.equalsIgnoreCase("night")) - return dim.getRotationalPeriod() * 21L / 24L; - else if(arg.equalsIgnoreCase("midnight")) - return 0L; - else if(arg.startsWith("@")) - return this.parseInt(arg.substring(1), dim.getRotationalPeriod() - 1); - else - return -1L; - } - - private Long parseTime(String arg) { - Dimension dim = this.entity.getServerWorld().dimension; - long t; - if(arg.toLowerCase().endsWith("y")) - t = dim.getOrbitalPeriod(); - else if(arg.toLowerCase().endsWith("d")) - t = dim.getRotationalPeriod(); - else if(arg.toLowerCase().endsWith("h")) - t = 1000L; - else - t = -1L; - arg = t == -1L ? arg : arg.substring(0, arg.length() - 1); - t = t < 1L ? 1L : t; - Long l = this.parseInt(arg, Long.MAX_VALUE); - return l == null ? null : (t * l); - } - - private Double parseCoordinate(String str, boolean center) { - try { - return (double)Integer.parseInt(str) + (center ? 0.5 : 0.0); - } - catch(NumberFormatException e) { - this.addFeed(TextColor.DRED + "'%s' ist keine gültige Zahl", str); - return null; - } - } +// private Double parseCoordinate(String str, boolean center) { +// try { +// return (double)Integer.parseInt(str) + (center ? 0.5 : 0.0); +// } +// catch(NumberFormatException e) { +// this.addFeed(TextColor.DRED + "'%s' ist keine gültige Zahl", str); +// return null; +// } +// } - private boolean teleport(String line) { - if(!Config.teleportAllowed && !this.isAdmin()) - return false; - line = line.trim(); - String[] argv = line.split(" ", -1); +// private boolean teleport(String line) { +// if(!Config.teleportAllowed && !this.isAdmin()) +// return false; +// line = line.trim(); +// String[] argv = line.split(" ", -1); // if(line.isEmpty() || argv.length == 0 || argv.length == 2) { // this.addFeed(TextColor.DRED + "+Spieler, @Warp, *Dimension oder X Y Z [Dimension]"); // return true; // } - String tgt = argv[0]; - if(tgt.equals("#")) { - if(argv.length < 4) { - this.addFeed(TextColor.DRED + "# X Y Z [Dimension]"); - return true; - } - Double ax = parseCoordinate(argv[1], true); - if(ax == null) - return true; - Double ay = parseCoordinate(argv[2], false); - if(ay == null) - return true; - Double az = parseCoordinate(argv[3], true); - if(az == null) - return true; - int dimension = this.entity.worldObj.dimension.getDimensionId(); - if(argv.length > 4) { - WorldServer world; - try { - world = this.server.getWorld(Integer.parseInt(argv[4])); - } - catch(NumberFormatException e) { - world = this.server.getWorld(argv[4]); - } - if(world == null) { - this.addFeed(TextColor.DRED + "Dimension '%s' existiert nicht", argv[4]); - return true; - } - dimension = world.dimension.getDimensionId(); - } - this.entity.teleport(ax, ay, az, this.entity.rotYaw, this.entity.rotPitch, dimension); - } - if(tgt.startsWith("@")) { - tgt = tgt.substring(1); - if(tgt.equals("spawn")) { - WorldServer world = this.server.getWorld(Config.spawnDim); - world = world == null ? this.server.getSpace() : world; - int y = Config.spawnY; - while(world.getState(new BlockPos(Config.spawnX, y, Config.spawnZ)).getBlock().getMaterial().blocksMovement() && y < 511) - y++; - this.entity.teleport(Config.spawnX + 0.5d, (double)y, Config.spawnZ + 0.5d, - Config.spawnYaw, Config.spawnPitch, world.dimension.getDimensionId()); - } - else { - Position pos = this.server.getWarps().get(tgt); - if(pos == null) { - this.addFeed(TextColor.DRED + "Warp '%s' existiert nicht", tgt); - return true; - } - if(this.server.getWorld(pos.dim) == null) { - this.addFeed(TextColor.DRED + "Warp '%s' hat kein Level (%s)", tgt, pos.dim); - return true; - } - this.entity.teleport(pos); - } - return true; - } - else if(tgt.startsWith("*")) { - tgt = tgt.substring(1); - WorldServer world; - try { - world = this.server.getWorld(Integer.parseInt(tgt)); - } - catch(NumberFormatException e) { - world = this.server.getWorld(tgt); - } - if(world == null) { - this.addFeed(TextColor.DRED + "Dimension '%s' existiert nicht", tgt); - return true; - } -// int dimension = world.dimension.getDimensionId(); -// int dimension = parseDimension(sender, tgt); - BlockPos pos = this.entity.getPosition(); -// WorldServer world = Server.getServer().getWorld(dimension); - pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos; - if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) { - while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511) - pos = pos.up(); - } - else { - while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0) - pos = pos.down(); - pos = pos.up(); - } - this.entity.teleport(pos, world.dimension.getDimensionId()); - return true; - } - else if(tgt.startsWith("+")) { - tgt = tgt.substring(1); - NetHandlerPlayServer conn = this.server.getPlayer(tgt); - if(conn == null) { - Position pos = this.server.getOfflinePosition(tgt); - if(pos == null) { - this.addFeed(TextColor.DRED + "Spieler '%s' konnte nicht gefunden werden", tgt); - return true; - } - this.entity.teleport(pos); - } - else { - EntityNPC dest = conn.getEntity(); - if(dest != null) - this.entity.teleport(dest.posX, dest.posY, dest.posZ, dest.rotYaw, dest.rotPitch, dest.worldObj.dimension.getDimensionId()); - } - return true; - } - return false; - } +// String tgt = argv[0]; +// if(tgt.equals("#")) { +// if(argv.length < 4) { +// this.addFeed(TextColor.DRED + "# X Y Z [Dimension]"); +// return true; +// } +// Double ax = parseCoordinate(argv[1], true); +// if(ax == null) +// return true; +// Double ay = parseCoordinate(argv[2], false); +// if(ay == null) +// return true; +// Double az = parseCoordinate(argv[3], true); +// if(az == null) +// return true; +// int dimension = this.entity.worldObj.dimension.getDimensionId(); +// if(argv.length > 4) { +// WorldServer world; +// try { +// world = this.server.getWorld(Integer.parseInt(argv[4])); +// } +// catch(NumberFormatException e) { +// world = this.server.getWorld(argv[4]); +// } +// if(world == null) { +// this.addFeed(TextColor.DRED + "Dimension '%s' existiert nicht", argv[4]); +// return true; +// } +// dimension = world.dimension.getDimensionId(); +// } +// this.entity.teleport(ax, ay, az, this.entity.rotYaw, this.entity.rotPitch, dimension); +// } +// if(tgt.startsWith("@")) { +// tgt = tgt.substring(1); +// if(tgt.equals("spawn")) { +// WorldServer world = this.server.getWorld(Config.spawnDim); +// world = world == null ? this.server.getSpace() : world; +// int y = Config.spawnY; +// while(world.getState(new BlockPos(Config.spawnX, y, Config.spawnZ)).getBlock().getMaterial().blocksMovement() && y < 511) +// y++; +// this.entity.teleport(Config.spawnX + 0.5d, (double)y, Config.spawnZ + 0.5d, +// Config.spawnYaw, Config.spawnPitch, world.dimension.getDimensionId()); +// } +// else { +// Position pos = this.server.getWarps().get(tgt); +// if(pos == null) { +// this.addFeed(TextColor.DRED + "Warp '%s' existiert nicht", tgt); +// return true; +// } +// if(this.server.getWorld(pos.dim) == null) { +// this.addFeed(TextColor.DRED + "Warp '%s' hat kein Level (%s)", tgt, pos.dim); +// return true; +// } +// this.entity.teleport(pos); +// } +// return true; +// } +// else if(tgt.startsWith("*")) { +// tgt = tgt.substring(1); +// WorldServer world; +// try { +// world = this.server.getWorld(Integer.parseInt(tgt)); +// } +// catch(NumberFormatException e) { +// world = this.server.getWorld(tgt); +// } +// if(world == null) { +// this.addFeed(TextColor.DRED + "Dimension '%s' existiert nicht", tgt); +// return true; +// } +//// int dimension = world.dimension.getDimensionId(); +//// int dimension = parseDimension(sender, tgt); +// BlockPos pos = this.entity.getPosition(); +//// WorldServer world = Server.getServer().getWorld(dimension); +// pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos; +// if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) { +// while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511) +// pos = pos.up(); +// } +// else { +// while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0) +// pos = pos.down(); +// pos = pos.up(); +// } +// this.entity.teleport(pos, world.dimension.getDimensionId()); +// return true; +// } +// else if(tgt.startsWith("+")) { +// tgt = tgt.substring(1); +// NetHandlerPlayServer conn = this.server.getPlayer(tgt); +// if(conn == null) { +// Position pos = this.server.getOfflinePosition(tgt); +// if(pos == null) { +// this.addFeed(TextColor.DRED + "Spieler '%s' konnte nicht gefunden werden", tgt); +// return true; +// } +// this.entity.teleport(pos); +// } +// else { +// EntityNPC dest = conn.getEntity(); +// if(dest != null) +// this.entity.teleport(dest.posX, dest.posY, dest.posZ, dest.rotYaw, dest.rotPitch, dest.worldObj.dimension.getDimensionId()); +// } +// return true; +// } +// return false; +// } private void runCommand(String command) { - this.server.getScriptEnvironment().execute(command, this); + if(this.isAdmin()) + this.server.getScriptEnvironment().execute(command, this); + else + this.addFeed(TextColor.DRED + "Nur Admins können Befehle ausführen"); } private List completeCommand(String command) { @@ -2007,7 +1923,7 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip } switch(packetIn.getType()) { case COMMAND: - if(!this.teleport(msg) && !this.setVar(msg) && !this.setAdmin(msg)) + if(!this.setVar(msg)) this.runCommand(msg); // this.addFeed(TextColor.RED + "Befehl wurde nicht gefunden"); break; @@ -2032,27 +1948,27 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip } } - private Iterable getWarpList(char pre) { - switch(pre) { - case '+': - return Lists.newArrayList(this.server.getUsers()); - case '@': - List warps = Lists.newArrayList("spawn"); - for(String warp : this.server.getWarps().keySet()) { - warps.add(warp); - } - return warps; - case '*': - return UniverseRegistry.getWorldNames(); - } - return Lists.newArrayList(); - } +// private Iterable getWarpList(char pre) { +// switch(pre) { +// case '+': +// return Lists.newArrayList(this.server.getUsers()); +// case '@': +// List warps = Lists.newArrayList("spawn"); +// for(String warp : this.server.getWarps().keySet()) { +// warps.add(warp); +// } +// return warps; +// case '*': +// return UniverseRegistry.getWorldNames(); +// } +// return Lists.newArrayList(); +// } - private static List getVarList() { - List list = Lists.newArrayList(Config.VARS.keySet()); - list.add("time"); - return list; - } +// private static List getVarList() { +// List list = ; +// list.add("time"); +// return list; +// } private List getVarCompletion(String var) { Config.Value v = Config.VARS.get(var); @@ -2068,37 +1984,27 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip public void processComplete(CPacketComplete packetIn) { NetHandler.checkThread(packetIn, this, this.server); + if(!this.isAdmin()) { + this.entity.connection.sendPacket(new S3APacketTabComplete(new String[0])); + return; + } this.pointedEntity = packetIn.getEntityId(); this.pointedPosition = packetIn.getPosition(); if(packetIn.getMessage().startsWith(" ")) { this.entity.connection.sendPacket(new S3APacketTabComplete(new String[0])); return; } - List list = Lists.newArrayList(); // Command.getCompletions(this.playerEntity, packetIn.getMessage()); - -// for (String s : ) -// { -// list.add(s); -// } - -// if(list == null) { -// list = Lists.newArrayList(); + List list = Lists.newArrayList(); String s = packetIn.getMessage(); - char pre = s.startsWith("#") || s.startsWith("!") || s.startsWith("+") || s.startsWith("*") || s.startsWith("@") ? s.charAt(0) : 0; - s = pre == 0 ? s : s.substring(1); String[] argv = s.split(" ", -1); s = argv[argv.length - 1]; - Iterable res = pre == '#' && (Config.teleportAllowed || this.isAdmin()) ? (argv.length == 5 ? UniverseRegistry.getWorldNames() : Lists.newArrayList()) : ((pre == '+' || pre == '*' || pre == '@') && (Config.teleportAllowed || this.isAdmin()) ? (argv.length == 1 ? this.getWarpList(pre) : Lists.newArrayList()) : (pre == '!' && this.isAdmin() ? this.server.getAllUsernames() : ((this.isAdmin() ? (argv.length == 1 ? getVarList() : (argv.length == 2 ? (argv[0].equals("time") ? Lists.newArrayList("day", "night", "noon", "midnight", "sunrise", "sunset") : getVarCompletion(argv[0])) : Lists.newArrayList())) : Lists.newArrayList())))); + Iterable res = argv.length == 1 ? Lists.newArrayList(Config.VARS.keySet()) : (argv.length == 2 ? getVarCompletion(argv[0]) : Lists.newArrayList()); for(String s1 : res) { if(s1.regionMatches(true, 0, s, 0, s.length())) - list.add((argv.length == 1 && pre != 0 ? pre : "") + s1); + list.add(s1); } -// if(list.isEmpty()) { list.addAll(this.completeCommand(packetIn.getMessage())); -// } -// } - - this.entity.connection.sendPacket(new S3APacketTabComplete((String[])list.toArray(new String[list.size()]))); + this.entity.connection.sendPacket(new S3APacketTabComplete(list.toArray(new String[list.size()]))); } private static boolean isFinite(double value) {