package game.command; import java.util.List; import java.util.Map; import java.util.function.Function; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import game.Server; import game.color.TextColor; public class ScriptEnvironment { private final Server server; private final Map executables = Maps.newTreeMap(); private final List replacers = Lists.newArrayList(); private ScriptExecutor currentExecutor; private Object previousOutput; public ScriptEnvironment(Server server) { this.server = server; } public void registerExecutable(Executable executable) { CachedExecutable cached = CachedExecutable.cacheExecutable(executable); 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); } catch(Throwable e) { throw new ScriptException(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); return o.toString(); } }); } public void registerReplacer(String var, Function function) { this.replacers.add(new PatternReplacer(var, true, function)); } public void registerVariable(String var, Variable variable) { this.replacers.add(new PatternReplacer(var, false, new Function() { public String apply(String ign) { return variable.get(); } })); } public Server getServer() { return this.server; } public ScriptExecutor getExecutor() { return this.currentExecutor; } private String substitute(String str) { StringBuffer sb = new StringBuffer(str); for(PatternReplacer replacer : this.replacers) { replacer.replaceVar(sb); } return sb.toString(); } private Object execute(String cmd, boolean setPrev) { String line = this.substitute(cmd); String[][] cmds = ArgumentParser.splitString(line); Object o = null; for(String[] argv : cmds) { CachedExecutable cached = this.executables.get(argv[0]); if(cached == null) throw new ScriptException("Skript '%s' existiert nicht", argv[0]); ScriptArgs args = ScriptArgs.parseArgs(this, cmd, argv, cached); o = cached.getExecutable().exec(this, args); if(setPrev) this.previousOutput = o; } return o; } public void execute(String cmd, ScriptExecutor exec) { this.currentExecutor = exec; try { this.execute(cmd, true); } catch(ScriptException e) { Throwable cause = e; do { exec.logConsole(TextColor.RED + cause.getMessage()); cause = cause.getCause(); } while(cause != null); } catch(Throwable t) { exec.logConsole(TextColor.RED + "Fehler: %s", t.getMessage()); } finally { this.currentExecutor = null; this.previousOutput = null; } } public void complete(String cmd, ScriptExecutor exec) { } public void registerDefaults() { this.registerVariable("id", new Variable() { public String get() { return ScriptEnvironment.this.currentExecutor.getExecId(); } }); this.registerVariable("name", new Variable() { public String get() { return ScriptEnvironment.this.currentExecutor.getExecName(); } }); this.registerVariable("chain", new Variable() { public String get() { return ScriptEnvironment.this.previousOutput == null ? null : ScriptEnvironment.this.previousOutput.toString(); } }); } }