package game.command; import java.util.List; import java.util.Map; import game.block.Block; import game.collect.Maps; import game.entity.Entity; import game.entity.npc.EntityNPC; import game.entity.types.EntityLiving; import game.item.Item; import game.item.ItemStack; import game.world.BlockPos; import game.world.State; import game.world.Vec3; import game.world.WorldPos; public class ScriptArgs { private final String command; private final Map arguments; protected ScriptArgs(Map arguments, String command) { this.arguments = arguments; this.command = command; } private static String joinArgs(Iterable iter) { StringBuilder sb = new StringBuilder("'"); for(T obj : iter) { if(sb.length() > 1) sb.append("', '"); sb.append(String.valueOf(obj)); } return sb.append("'").toString(); } public static ScriptArgs parseArgs(ScriptEnvironment env, String str, String[] argv, CachedExecutable cached) { Map parameters = cached.getParameters(); List positionals = cached.getPositionals(); // String[] argv = ArgumentParser.splitString(str); Map args = Maps.newHashMap(); int ppos = 0; boolean parse = true; for(int z = 1; z < argv.length; z++) { String arg = argv[z]; Parameter param = null; boolean pos = false; if(parse && arg.equals("--")) { parse = false; continue; } else if(parse && (arg.startsWith("--") || (arg.startsWith("-") && arg.length() == 2))) { param = parameters.get(arg.substring(arg.startsWith("--") ? 2 : 1)); if(param != null && param.isPositional() && !args.containsKey(param.getName())) { for(int n = 0; n < positionals.size(); n++) { if(param == positionals.get(n)) { positionals.remove(n); break; } } } } else if(ppos < positionals.size()) { param = positionals.get(ppos++); pos = true; } else { throw new ScriptException("Position %d: Parameter '%s' ist überflüssig", z, arg); } if(param == null) throw new ScriptException("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()); 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()); else throw new ScriptException("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)]; int apos = 0; for(int n = pos ? 0 : 1; n < nargs + (pos ? 0 : 1); n++) { String par = inputs[n] = argv[z + n]; 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); else throw new ScriptException("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, param.getName()); else throw new ScriptException(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)); z += nargs; } for(Parameter param : parameters.values()) { if(!args.containsKey(param.getName())) { if(param.isRequired()) { for(ArgumentParser parser : param.getParsers()) { if(parser.getDefault(env) == null) throw new ScriptException("Argument '%s' muss angegeben werden", param.getName()); } } Map params = Maps.newHashMapWithExpectedSize(param.getParsers().size()); for(ArgumentParser parser : param.getParsers()) { params.put(parser.getName(), parser.getDefault(env)); } args.put(param.getName(), new ScriptArg(param, -1, null, params)); } } return new ScriptArgs(args, str); } public ScriptArg getArg(String name) { return this.arguments.get(name); } public boolean hasArg(String name) { return this.arguments.containsKey(name); } protected T getDefault(String name, String par, T def) { ScriptArg arg = this.arguments.get(name); if(arg == null) return def; Object value = arg.getValues().get(par); return value == null ? def : (T)value; } protected T getDefault(String name, T def) { return this.getDefault(name, name, def); } protected T getUnchecked(String name, String par) { return this.getDefault(name, par, null); } protected T getUnchecked(String name) { return this.getDefault(name, null); } public boolean getBool(String name, boolean def) { return this.getDefault(name, def); } public boolean getBool(String name) { return this.getUnchecked(name); } public > T getEnum(String name, T def) { return this.getDefault(name, def); } public > T getEnum(String name) { return this.getUnchecked(name); } public int getInt(String name, int def) { return this.getDefault(name, def); } public int getInt(String name) { return this.getUnchecked(name); } public long getLong(String name, long def) { return this.getDefault(name, def); } public long getLong(String name) { return this.getUnchecked(name); } public double getDouble(String name, double def) { return this.getDefault(name, def); } public double getDouble(String name) { return this.getUnchecked(name); } public String getString(String name, String def) { return this.getDefault(name, def); } public String getString(String name) { return this.getUnchecked(name); } public String[] getStrings(String name, String[] def) { return this.getDefault(name, def); } public String[] getStrings(String name) { return this.getUnchecked(name); } public Entity getEntity(String name, Entity def) { return this.getDefault(name, def); } public Entity getEntity(String name) { return this.getUnchecked(name); } public EntityLiving getLiving(String name, EntityLiving def) { return this.getDefault(name, def); } public EntityLiving getLiving(String name) { return this.getUnchecked(name); } public EntityNPC getNpc(String name, EntityNPC def) { return this.getDefault(name, def); } public EntityNPC getNpc(String name) { return this.getUnchecked(name); } public Block getBlock(String name, Block def) { return this.getDefault(name, def); } public Block getBlock(String name) { return this.getUnchecked(name); } public State getState(String name, State def) { return this.getDefault(name, def); } public State getState(String name) { return this.getUnchecked(name); } public Item getItem(String name, Item def) { return this.getDefault(name, def); } public Item getItem(String name) { return this.getUnchecked(name); } public ItemStack getStack(String name, ItemStack def) { return this.getDefault(name, def); } public ItemStack getStack(String name) { return this.getUnchecked(name); } public BlockPos getColumnPos(String name, BlockPos def) { return this.hasArg(name) ? this.getColumnPos(name) : def; } public BlockPos getColumnPos(String name) { return new BlockPos(this.getUnchecked(name, "x"), 0, this.getUnchecked(name, "z")); } public BlockPos getBlockPos(String name, BlockPos def) { return this.hasArg(name) ? this.getBlockPos(name) : def; } public BlockPos getBlockPos(String name) { return new BlockPos(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z")); } public WorldPos getWorldPos(String name, WorldPos def) { return this.hasArg(name) ? this.getWorldPos(name) : def; } public WorldPos getWorldPos(String name) { return new WorldPos(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z"), this.getUnchecked(name, "dim")); } public Vec3 getVector2D(String name, Vec3 def) { return this.hasArg(name) ? this.getVector2D(name) : def; } public Vec3 getVector2D(String name) { return new Vec3(this.getUnchecked(name, "x"), 0.0, this.getUnchecked(name, "z")); } public Vec3 getVector(String name, Vec3 def) { return this.hasArg(name) ? this.getVector(name) : def; } public Vec3 getVector(String name) { return new Vec3(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z")); } }