@Override public Construct get(Construct index, Target t) { if (!associative_mode) { try { return array.get(Static.getInt32(index, t)); } catch (IndexOutOfBoundsException e) { throw ConfigRuntimeException.BuildException( "The element at index \"" + index.val() + "\" does not exist", ExceptionType.IndexOverflowException, t, e); } } else { if (associative_array.containsKey(normalizeConstruct(index))) { Construct val = associative_array.get(normalizeConstruct(index)); if (val instanceof CEntry) { return ((CEntry) val).construct(); } return val; } else { // Create this so we can at least attach a stacktrace. @SuppressWarnings({"ThrowableInstanceNotThrown", "ThrowableInstanceNeverThrown"}) IndexOutOfBoundsException ioobe = new IndexOutOfBoundsException(); throw ConfigRuntimeException.BuildException( "The element at index \"" + index.val() + "\" does not exist", ExceptionType.IndexOverflowException, t, ioobe); } } }
/** * Removes the value at the specified key * * @param construct * @return */ public Construct remove(Construct construct) { String c = normalizeConstruct(construct); Construct ret; if (!associative_mode) { try { ret = array.remove(Integer.parseInt(c)); next_index--; } catch (NumberFormatException e) { throw ConfigRuntimeException.BuildException( "Expecting an integer, but received \"" + c + "\" (were you expecting an associative array? This array is a normal array.)", ExceptionType.CastException, construct.getTarget()); } catch (IndexOutOfBoundsException e) { throw ConfigRuntimeException.BuildException( "Cannot remove the value at '" + c + "', as no such index exists in the array", ExceptionType.RangeException, construct.getTarget()); } } else { ret = associative_array.remove(c); } regenValue(new HashSet<CArray>()); return ret; }
public CArray exception(ConfigRuntimeException e, Target t) { CArray ex = new CArray(t); ex.push(new CString(e.getExceptionType().toString(), t)); ex.push(new CString(e.getMessage(), t)); ex.push(new CString((e.getFile() != null ? e.getFile().getAbsolutePath() : "null"), t)); ex.push(new CInt(e.getLineNum(), t)); return ex; }
public void compileMS(MCPlayer player, Environment env) { for (FileInfo fi : ms) { boolean exception = false; try { env.getEnv(CommandHelperEnvironment.class) .SetCommandSender(Static.getServer().getConsole()); MethodScriptCompiler.registerAutoIncludes(env, null); MethodScriptCompiler.execute( MethodScriptCompiler.compile(MethodScriptCompiler.lex(fi.contents, fi.file, true)), env, null, null); } catch (ConfigCompileException e) { exception = true; ConfigRuntimeException.React( e, fi.file.getAbsolutePath() + " could not be compiled, due to a compile error.", player); } catch (ConfigRuntimeException e) { exception = true; ConfigRuntimeException.React(e, env); } catch (CancelCommandException e) { if (e.getMessage() != null && !"".equals(e.getMessage().trim())) { logger.log(Level.INFO, e.getMessage()); } } catch (ProgramFlowManipulationException e) { exception = true; ConfigRuntimeException.React( ConfigRuntimeException.CreateUncatchableException( "Cannot break program flow in main files.", e.getTarget()), env); } finally { env.getEnv(CommandHelperEnvironment.class).SetCommandSender(null); } if (exception) { if (Prefs.HaltOnFailure()) { logger.log( Level.SEVERE, TermColors.RED + "[CommandHelper]: Compilation halted due to unrecoverable failure." + TermColors.reset()); return; } } } logger.log( Level.INFO, TermColors.YELLOW + "[CommandHelper]: MethodScript files processed" + TermColors.reset()); if (player != null) { player.sendMessage(MCChatColor.YELLOW + "[CommandHelper]: MethodScript files processed"); } }
@Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { String parameter = args[0].val(); Construct value = args[1]; boolean throwOnFailure = false; if (args.length == 3) { throwOnFailure = Static.getBoolean(args[3]); } if (environment.getEnv(GlobalEnv.class).GetEvent() == null) { throw new ConfigRuntimeException( this.getName() + " must be called from within an event handler", ExceptionType.BindException, t); } Event e = environment.getEnv(GlobalEnv.class).GetEvent().getEventDriver(); if (environment .getEnv(GlobalEnv.class) .GetEvent() .getBoundEvent() .getPriority() .equals(Priority.MONITOR)) { throw new ConfigRuntimeException( "Monitor level handlers may not modify an event!", ExceptionType.BindException, t); } ActiveEvent active = environment.getEnv(GlobalEnv.class).GetEvent(); boolean success = false; if (!active.isLocked(parameter)) { try { success = e.modifyEvent( parameter, value, environment.getEnv(GlobalEnv.class).GetEvent().getUnderlyingEvent()); } catch (ConfigRuntimeException ex) { ex.setFile(t.file()); ex.setLineNum(t.line()); ex.setColumn(t.col()); throw ex; } } else { success = false; } if (throwOnFailure && !success) { throw new ConfigRuntimeException( "Event parameter is already locked!", ExceptionType.BindException, t); } return CBoolean.get(success); }
/** * @param index * @param c */ public void set(Construct index, Construct c, Target t) { if (!associative_mode) { try { int indx = Static.getInt32(index, t); if (indx > next_index || indx < 0) { throw ConfigRuntimeException.BuildException( "", ExceptionType.IndexOverflowException, Target.UNKNOWN); } else if (indx == next_index) { this.push(c, t); } else { array.set(indx, c); } } catch (ConfigRuntimeException e) { // Not a number. Convert to associative. associative_array = new TreeMap<String, Construct>(comparator); for (int i = 0; i < array.size(); i++) { associative_array.put(Integer.toString(i), array.get(i)); } associative_mode = true; array = null; // null out the original array container so it can be GC'd } } if (associative_mode) { associative_array.put(normalizeConstruct(index), c); } if (c instanceof CArray) { ((CArray) c).parent = this; } regenValue(new HashSet<CArray>()); }
/** * Reverses the array in place, if it is a normal array, otherwise, if associative, it throws an * exception. */ public void reverse() { if (!associative_mode) { Collections.reverse(array); regenValue(new HashSet<CArray>()); } else { throw ConfigRuntimeException.BuildException( "Cannot reverse an associative array.", ExceptionType.CastException, getTarget()); } }
public CDouble(String value, Target t) { super(value, ConstructType.INT, t); try { val = Double.parseDouble(value); } catch (NumberFormatException e) { throw ConfigRuntimeException.BuildException( "Could not cast " + value + " to double", ExceptionType.FormatException, t); } }
private String normalizeConstruct(Construct c) { if (c instanceof CArray) { throw ConfigRuntimeException.BuildException( "Arrays cannot be used as the key in an associative array", ExceptionType.CastException, c.getTarget()); } else if (c instanceof CString || c instanceof CInt) { return c.val(); } else if (c instanceof CNull) { return ""; } else if (c instanceof CBoolean) { if (((CBoolean) c).getBoolean()) { return "1"; } else { return "0"; } } else if (c instanceof CLabel) { return normalizeConstruct(((CLabel) c).cVal()); } else { return c.val(); } }
public void compileMSA(List<Script> scripts, MCPlayer player) { for (FileInfo fi : msa) { List<Script> tempScripts; try { tempScripts = MethodScriptCompiler.preprocess( MethodScriptCompiler.lex(fi.contents, fi.file, false)); for (Script s : tempScripts) { try { try { s.compile(); s.checkAmbiguous((ArrayList<Script>) scripts); scripts.add(s); } catch (ConfigCompileException e) { ConfigRuntimeException.React( e, "Compile error in script. Compilation will attempt to continue, however.", player); } } catch (RuntimeException ee) { throw new RuntimeException( "While processing a script, " + "(" + fi.file() + ") an unexpected exception occurred. (No further information" + " is available, unfortunately.)", ee); } } } catch (ConfigCompileException e) { ConfigRuntimeException.React( e, "Could not compile file " + fi.file + " compilation will halt.", player); return; } } int errors = 0; for (Script s : scripts) { if (s.compilerError) { errors++; } } if (errors > 0) { System.out.println( TermColors.YELLOW + "[CommandHelper]: " + (scripts.size() - errors) + " alias(es) defined, " + TermColors.RED + "with " + errors + " aliases with compile errors." + TermColors.reset()); if (player != null) { player.sendMessage( MCChatColor.YELLOW + "[CommandHelper]: " + (scripts.size() - errors) + " alias(es) defined, " + MCChatColor.RED + "with " + errors + " aliases with compile errors."); } } else { System.out.println( TermColors.YELLOW + "[CommandHelper]: " + scripts.size() + " alias(es) defined." + TermColors.reset()); if (player != null) { player.sendMessage( MCChatColor.YELLOW + "[CommandHelper]: " + scripts.size() + " alias(es) defined."); } } }
/** * This is the workhorse function. It takes a given command, then converts it into the actual * command(s). If the command maps to a defined alias, it will run the specified alias. It will * search through the global list of aliases, as well as the aliases defined for that specific * player. This function doesn't handle the /alias command however. * * @param command * @return */ public boolean alias(String command, final MCCommandSender player, List<Script> playerCommands) { GlobalEnv gEnv; try { gEnv = new GlobalEnv( parent.executionQueue, parent.profiler, parent.persistenceNetwork, parent.permissionsResolver, MethodScriptFileLocations.getDefault().getConfigDirectory(), new Profiles(MethodScriptFileLocations.getDefault().getSQLProfilesFile())); } catch (IOException ex) { Logger.getLogger(AliasCore.class.getName()).log(Level.SEVERE, null, ex); return false; } catch (Profiles.InvalidProfileException ex) { throw ConfigRuntimeException.CreateUncatchableException(ex.getMessage(), Target.UNKNOWN); } CommandHelperEnvironment cEnv = new CommandHelperEnvironment(); cEnv.SetCommandSender(player); Environment env = Environment.createEnvironment(gEnv, cEnv); if (player instanceof MCBlockCommandSender) { cEnv.SetBlockCommandSender((MCBlockCommandSender) player); } if (scripts == null) { throw ConfigRuntimeException.CreateUncatchableException( "Cannot run alias commands, no config file is loaded", Target.UNKNOWN); } boolean match = false; try { // catch RuntimeException // If player is null, we are running the test harness, so don't // actually add the player to the array. if (player != null && player instanceof MCPlayer && echoCommand.contains(((MCPlayer) player).getName())) { // we are running one of the expanded commands, so exit with false return false; } // Global aliases override personal ones, so check the list first for (Script s : scripts) { try { if (s.match(command)) { this.addPlayerReference(player); if (Prefs.ConsoleLogCommands() && s.doLog()) { StringBuilder b = new StringBuilder("CH: Running original command "); if (player instanceof MCPlayer) { b.append("on player ").append(((MCPlayer) player).getName()); } else { b.append("from a MCCommandSender"); } b.append(" ----> ").append(command); Static.getLogger().log(Level.INFO, b.toString()); } try { env.getEnv(CommandHelperEnvironment.class).SetCommand(command); ProfilePoint alias = env.getEnv(GlobalEnv.class) .GetProfiler() .start("Global Alias - \"" + command + "\"", LogLevel.ERROR); try { s.run( s.getVariables(command), env, new MethodScriptComplete() { @Override public void done(String output) { try { if (output != null) { if (!output.trim().isEmpty() && output.trim().startsWith("/")) { if (Prefs.DebugMode()) { if (player instanceof MCPlayer) { Static.getLogger() .log( Level.INFO, "[CommandHelper]: Executing command on " + ((MCPlayer) player).getName() + ": " + output.trim()); } else { Static.getLogger() .log( Level.INFO, "[CommandHelper]: Executing command from console equivalent: " + output.trim()); } } if (player instanceof MCPlayer) { ((MCPlayer) player).chat(output.trim()); } else { Static.getServer() .dispatchCommand(player, output.trim().substring(1)); } } } } catch (Throwable e) { System.err.println(e.getMessage()); player.sendMessage(MCChatColor.RED + e.getMessage()); } finally { Static.getAliasCore().removePlayerReference(player); } } }); } finally { alias.stop(); } } catch (ConfigRuntimeException ex) { ex.setEnv(env); ConfigRuntimeException.React(ex, env); } catch (Throwable e) { // This is not a simple user script error, this is a deeper problem, so we always // handle this. System.err.println( "An unexpected exception occured: " + e.getClass().getSimpleName()); player.sendMessage( "An unexpected exception occured: " + MCChatColor.RED + e.getClass().getSimpleName()); e.printStackTrace(); } finally { Static.getAliasCore().removePlayerReference(player); } match = true; break; } } catch (Exception e) { System.err.println("An unexpected exception occured inside the command " + s.toString()); e.printStackTrace(); } } if (player instanceof MCPlayer) { if (match == false && playerCommands != null) { // if we are still looking, look in the aliases for this player for (Script ac : playerCommands) { // RunnableAlias b = ac.getRunnableAliases(command, player); try { ac.compile(); if (ac.match(command)) { Static.getAliasCore().addPlayerReference(player); ProfilePoint alias = env.getEnv(GlobalEnv.class) .GetProfiler() .start( "User Alias (" + player.getName() + ") - \"" + command + "\"", LogLevel.ERROR); try { ac.run( ac.getVariables(command), env, new MethodScriptComplete() { @Override public void done(String output) { if (output != null) { if (!output.trim().isEmpty() && output.trim().startsWith("/")) { if (Prefs.DebugMode()) { Static.getLogger() .log( Level.INFO, "[CommandHelper]: Executing command on " + ((MCPlayer) player).getName() + ": " + output.trim()); } ((MCPlayer) player).chat(output.trim()); } } Static.getAliasCore().removePlayerReference(player); } }); } finally { alias.stop(); } match = true; break; } } catch (ConfigRuntimeException e) { // Unlike system scripts, this should just report the problem to the player // env.getEnv(CommandHelperEnvironment.class).SetCommandSender(player); Static.getAliasCore().removePlayerReference(player); e.setEnv(env); ConfigRuntimeException.React(e, env); match = true; } catch (ConfigCompileException e) { // Something strange happened, and a bad alias was added // to the database. Our best course of action is to just // skip it. } } } } } catch (Throwable e) { // Not only did an error happen, an error happened in our error handler throw new InternalException( TermColors.RED + "An unexpected error occured in the CommandHelper plugin. " + "Further, this is likely an error with the error handler, so it may be caused by your script, " + "however, there is no more information at this point. Check your script, but also report this " + "as a bug in CommandHelper. Also, it's possible that some commands will no longer work. As a temporary " + "workaround, restart the server, and avoid doing whatever it is you did to make this happen.\nThe error is as follows: " + e.toString() + "\n" + TermColors.reset() + "Stack Trace:\n" + StringUtil.joinString(Arrays.asList(e.getStackTrace()), "\n", 0)); } return match; }