use of com.laytonsmith.core.exceptions.ConfigRuntimeException in project CommandHelper by EngineHub.
the class ExampleScript method getOutput.
public String getOutput() throws IOException, DataSourceException, URISyntaxException {
if (output != null) {
return output;
}
Script s = Script.GenerateScript(script, Static.GLOBAL_PERMISSION);
Environment env;
try {
env = Static.GenerateStandaloneEnvironment();
} catch (Profiles.InvalidProfileException ex) {
throw new RuntimeException(ex);
}
Class[] interfaces = new Class[] { MCPlayer.class };
MCPlayer p = (MCPlayer) Proxy.newProxyInstance(ExampleScript.class.getClassLoader(), interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("getName") || method.getName().equals("getDisplayName")) {
return "Player";
}
if (method.getName().equals("sendMessage")) {
playerOutput.append(args[0].toString()).append("\n");
}
if (method.getName().equals("isOnline")) {
return true;
}
return genericReturn(method.getReturnType());
}
});
// TODO: Remove this dependency. Make MCPlayer implement a generic "User" and make that
// part of the GlobalEnv.
env.getEnv(CommandHelperEnvironment.class).SetPlayer(p);
final StringBuilder finalOutput = new StringBuilder();
String thrown = null;
try {
List<Variable> vars = new ArrayList<>();
try {
MethodScriptCompiler.execute(originalScript, new File("/" + functionName + ".ms"), true, env, new MethodScriptComplete() {
@Override
public void done(String output) {
if (output != null) {
finalOutput.append(output);
}
}
}, null, vars);
} catch (ConfigCompileException | ConfigCompileGroupException ex) {
// We already checked for compile errors, so this won't happen
}
} catch (ConfigRuntimeException e) {
String name = e.getClass().getName();
if (e instanceof AbstractCREException) {
name = ((AbstractCREException) e).getName();
}
thrown = "\n(Throws " + name + ": " + e.getMessage() + ")";
}
String playerOut = playerOutput.toString().trim();
String finalOut = finalOutput.toString().trim();
String out = (playerOut.isEmpty() ? "" : playerOut) + (finalOut.isEmpty() || !playerOut.trim().isEmpty() ? "" : ":" + finalOut);
if (thrown != null) {
out += thrown;
}
return out;
}
use of com.laytonsmith.core.exceptions.ConfigRuntimeException in project CommandHelper by EngineHub.
the class BukkitMCCommand method handleCustomCommand.
@Override
public boolean handleCustomCommand(MCCommandSender sender, String label, String[] args) {
if (Commands.onCommand.containsKey(cmd.getName().toLowerCase())) {
Target t = Target.UNKNOWN;
CArray cargs = new CArray(t);
for (String arg : args) {
cargs.push(new CString(arg, t), t);
}
CClosure closure = Commands.onCommand.get(cmd.getName().toLowerCase());
CommandHelperEnvironment cEnv = closure.getEnv().getEnv(CommandHelperEnvironment.class);
cEnv.SetCommandSender(sender);
cEnv.SetCommand("/" + label + StringUtils.Join(args, " "));
try {
closure.execute(new CString(label, t), new CString(sender.getName(), t), cargs, // reserved for an obgen style command array
new CArray(t));
} catch (FunctionReturnException e) {
Construct fret = e.getReturn();
if (fret instanceof CBoolean) {
return ((CBoolean) fret).getBoolean();
}
} catch (ConfigRuntimeException cre) {
cre.setEnv(closure.getEnv());
ConfigRuntimeException.HandleUncaughtException(cre, closure.getEnv());
}
return true;
} else {
return false;
}
}
use of com.laytonsmith.core.exceptions.ConfigRuntimeException in project CommandHelper by EngineHub.
the class CommandHelperListener method onPlayerCommandPreprocess.
/**
* Called when a player attempts to use a command
*
* @param event Relevant event details
*/
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
if (CommandHelperPlugin.self.interpreterListener.isInInterpreterMode(event.getPlayer().getName())) {
// They are in interpreter mode, so we want it to handle this, not everything else.
return;
}
MCPlayerCommandEvent mpce = new BukkitPlayerEvents.BukkitMCPlayerCommandEvent(event);
EventUtils.TriggerListener(Driver.PLAYER_COMMAND, "player_command", mpce);
if (mpce.isCancelled()) {
return;
}
String cmd = event.getMessage();
MCPlayer player = new BukkitMCPlayer(event.getPlayer());
BukkitDirtyRegisteredListener.PlayDirty();
if (!Prefs.PlayDirty()) {
if (event.isCancelled()) {
return;
}
}
try {
if (runAlias(event.getMessage(), player)) {
event.setCancelled(true);
if (Prefs.PlayDirty()) {
// Super cancel the event
BukkitDirtyRegisteredListener.setCancelled(event);
}
}
} catch (InternalException e) {
logger.log(Level.SEVERE, e.getMessage());
} catch (ConfigRuntimeException e) {
logger.log(Level.WARNING, e.getMessage());
} catch (Throwable e) {
player.sendMessage(MCChatColor.RED + "Command failed with following reason: " + e.getMessage());
// Obviously the command is registered, but it somehow failed. Cancel the event.
event.setCancelled(true);
e.printStackTrace();
}
}
use of com.laytonsmith.core.exceptions.ConfigRuntimeException in project CommandHelper by EngineHub.
the class MethodScriptCompiler method optimize.
/**
* Recurses down into the tree, attempting to optimize where possible. A few things have strong coupling, for
* information on these items, see the documentation included in the source.
*
* @param tree
* @return
*/
private static void optimize(ParseTree tree, Stack<List<Procedure>> procs, Set<ConfigCompileException> compilerErrors) {
if (tree.isOptimized()) {
// Don't need to re-run this
return;
}
// }
if (!(tree.getData() instanceof CFunction)) {
// There's no way to optimize something that's not a function
return;
}
// If it is a proc definition, we need to go ahead and see if we can add it to the const proc stack
if (tree.getData().val().equals("proc")) {
procs.push(new ArrayList<Procedure>());
}
CFunction cFunction = (CFunction) tree.getData();
Function func;
try {
func = (Function) FunctionList.getFunction(cFunction);
} catch (ConfigCompileException e) {
func = null;
}
if (func != null) {
if (func.getClass().getAnnotation(nolinking.class) != null) {
// It's an unlinking function, so we need to stop at this point
return;
}
}
if (cFunction instanceof CIdentifier) {
// Add the child to the identifier
ParseTree c = ((CIdentifier) cFunction).contained();
tree.addChild(c);
c.getData().setWasIdentifier(true);
}
List<ParseTree> children = tree.getChildren();
if (func instanceof Optimizable && ((Optimizable) func).optimizationOptions().contains(OptimizationOption.PRIORITY_OPTIMIZATION)) {
// would cause an error, even though the user did in fact provide code in that section.
try {
((Optimizable) func).optimizeDynamic(tree.getTarget(), children, tree.getFileOptions());
} catch (ConfigCompileException ex) {
// If an error occurs, we will skip the rest of this element
compilerErrors.add(ex);
return;
} catch (ConfigRuntimeException ex) {
compilerErrors.add(new ConfigCompileException(ex));
return;
}
}
for (int i = 0; i < children.size(); i++) {
ParseTree t = children.get(i);
if (t.getData() instanceof CFunction) {
if (t.getData().val().startsWith("_") || (func != null && func.useSpecialExec())) {
continue;
}
Function f;
try {
f = (Function) FunctionList.getFunction(t.getData());
} catch (ConfigCompileException ex) {
compilerErrors.add(ex);
return;
}
Set<OptimizationOption> options = NO_OPTIMIZATIONS;
if (f instanceof Optimizable) {
options = ((Optimizable) f).optimizationOptions();
}
if (options.contains(OptimizationOption.TERMINAL)) {
if (children.size() > i + 1) {
// First, a compiler warning
CHLog.GetLogger().Log(CHLog.Tags.COMPILER, LogLevel.WARNING, "Unreachable code. Consider removing this code.", children.get(i + 1).getTarget());
// Now, truncate the children
for (int j = children.size() - 1; j > i; j--) {
children.remove(j);
}
break;
}
}
}
}
boolean fullyStatic = true;
boolean hasIVars = false;
for (ParseTree node : children) {
if (node.getData() instanceof CFunction) {
optimize(node, procs, compilerErrors);
}
if (node.getData().isDynamic() && !(node.getData() instanceof IVariable)) {
fullyStatic = false;
}
if (node.getData() instanceof IVariable) {
hasIVars = true;
}
}
// In all cases, at this point, we are either unable to optimize, or we will
// optimize, so set our optimized variable at this point.
tree.setOptimized(true);
if (func == null) {
// It's a proc call. Let's see if we can optimize it
Procedure p = null;
loop: for (List<Procedure> proc : procs) {
for (Procedure pp : proc) {
if (pp.getName().equals(cFunction.val())) {
p = pp;
break loop;
}
}
}
if (p != null) {
try {
Construct c = DataHandling.proc.optimizeProcedure(p.getTarget(), p, children);
if (c != null) {
tree.setData(c);
tree.removeChildren();
return;
}
// else Nope, couldn't optimize.
} catch (ConfigRuntimeException ex) {
// Cool. Caught a runtime error at compile time :D
compilerErrors.add(new ConfigCompileException(ex));
}
}
// so we can't for sure say, but we do know we can't optimize this
return;
}
if (tree.getData().val().equals("proc")) {
// Check for too few arguments
if (children.size() < 2) {
compilerErrors.add(new ConfigCompileException("Incorrect number of arguments passed to proc", tree.getData().getTarget()));
return;
}
// We just went out of scope, so we need to pop the layer of Procedures that
// are internal to us
procs.pop();
// Let's see.
try {
ParseTree root = new ParseTree(new CFunction(__autoconcat__, Target.UNKNOWN), tree.getFileOptions());
Script fakeScript = Script.GenerateScript(root, "*");
Environment env = null;
try {
if (Implementation.GetServerType().equals(Implementation.Type.BUKKIT)) {
CommandHelperPlugin plugin = CommandHelperPlugin.self;
GlobalEnv gEnv = new GlobalEnv(plugin.executionQueue, plugin.profiler, plugin.persistenceNetwork, MethodScriptFileLocations.getDefault().getConfigDirectory(), plugin.profiles, new TaskManager());
env = Environment.createEnvironment(gEnv, new CommandHelperEnvironment());
} else {
env = Static.GenerateStandaloneEnvironment(false);
}
} catch (IOException | DataSourceException | URISyntaxException | Profiles.InvalidProfileException e) {
//
}
Procedure myProc = DataHandling.proc.getProcedure(tree.getTarget(), env, fakeScript, children.toArray(new ParseTree[children.size()]));
// Yep. So, we can move on with our lives now, and if it's used later, it could possibly be static.
procs.peek().add(myProc);
} catch (ConfigRuntimeException e) {
// Well, they have an error in there somewhere
compilerErrors.add(new ConfigCompileException(e));
} catch (NullPointerException e) {
// Nope, can't optimize.
return;
}
}
// the compiler trick functions know how to deal with it specially, even if everything isn't
// static, so do this first.
String oldFunctionName = func.getName();
Set<OptimizationOption> options = NO_OPTIMIZATIONS;
if (func instanceof Optimizable) {
options = ((Optimizable) func).optimizationOptions();
}
if (options.contains(OptimizationOption.OPTIMIZE_DYNAMIC)) {
try {
ParseTree tempNode;
try {
tempNode = ((Optimizable) func).optimizeDynamic(tree.getData().getTarget(), tree.getChildren(), tree.getFileOptions());
} catch (ConfigRuntimeException e) {
// Turn it into a compile exception, then rethrow
throw new ConfigCompileException(e);
}
if (tempNode == Optimizable.PULL_ME_UP) {
if (tree.hasChildren()) {
tempNode = tree.getChildAt(0);
} else {
tempNode = null;
}
}
if (tempNode == Optimizable.REMOVE_ME) {
tree.setData(new CFunction("p", Target.UNKNOWN));
tree.removeChildren();
} else if (tempNode != null) {
tree.setData(tempNode.getData());
tree.setOptimized(tempNode.isOptimized());
tree.setChildren(tempNode.getChildren());
tree.getData().setWasIdentifier(tempNode.getData().wasIdentifier());
optimize(tree, procs, compilerErrors);
tree.setOptimized(true);
// array, so if they have reversed this, make note of that now
if (tempNode.hasBeenMadeStatic()) {
fullyStatic = true;
}
}
// else it wasn't an optimization, but a compile check
} catch (ConfigCompileException ex) {
compilerErrors.add(ex);
}
}
if (!fullyStatic) {
return;
}
// specially from here forward
if (func.preResolveVariables() && hasIVars) {
// Well, this function isn't equipped to deal with IVariables.
return;
}
// don't want to run this now
if (tree.getData().getValue().equals(oldFunctionName) && (options.contains(OptimizationOption.OPTIMIZE_CONSTANT) || options.contains(OptimizationOption.CONSTANT_OFFLINE))) {
Construct[] constructs = new Construct[tree.getChildren().size()];
for (int i = 0; i < tree.getChildren().size(); i++) {
constructs[i] = tree.getChildAt(i).getData();
}
try {
try {
Construct result;
if (options.contains(OptimizationOption.CONSTANT_OFFLINE)) {
List<Integer> numArgsList = Arrays.asList(func.numArgs());
if (!numArgsList.contains(Integer.MAX_VALUE) && !numArgsList.contains(tree.getChildren().size())) {
compilerErrors.add(new ConfigCompileException("Incorrect number of arguments passed to " + tree.getData().val(), tree.getData().getTarget()));
result = null;
} else {
result = func.exec(tree.getData().getTarget(), null, constructs);
}
} else {
result = ((Optimizable) func).optimize(tree.getData().getTarget(), constructs);
}
// If the result is null, it was just a check, it can't optimize further.
if (result != null) {
result.setWasIdentifier(tree.getData().wasIdentifier());
tree.setData(result);
tree.removeChildren();
}
} catch (ConfigRuntimeException e) {
// Turn this into a ConfigCompileException, then rethrow
throw new ConfigCompileException(e);
}
} catch (ConfigCompileException ex) {
compilerErrors.add(ex);
}
}
// It doesn't know how to optimize. Oh well.
}
use of com.laytonsmith.core.exceptions.ConfigRuntimeException in project CommandHelper by EngineHub.
the class MethodScriptExecutionQueue method getExceptionHandler.
private Thread.UncaughtExceptionHandler getExceptionHandler() {
Thread.UncaughtExceptionHandler uceh = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
Environment env = Environment.createEnvironment(MethodScriptExecutionQueue.this.env);
if (e instanceof ConfigRuntimeException) {
// This should be handled by the default UEH
ConfigRuntimeException.HandleUncaughtException(((ConfigRuntimeException) e), env);
} else if (e instanceof FunctionReturnException) {
// ignored, so we want to warn them, but not trigger a flat out error.
if (!(((FunctionReturnException) e).getReturn() instanceof CVoid)) {
ConfigRuntimeException.DoWarning("Closure is returning a value in an execution queue task," + " which is unexpected behavior. It may return void however, which will" + " simply stop that one task. " + ((FunctionReturnException) e).getTarget().toString());
}
} else if (e instanceof CancelCommandException) {
// Ok. If there's a message, echo it to console.
String msg = ((CancelCommandException) e).getMessage().trim();
if (!"".equals(msg)) {
Target tt = ((CancelCommandException) e).getTarget();
new Echoes.console().exec(tt, env, new CString(msg, tt));
}
} else {
// handle, so let it bubble up further.
throw new RuntimeException(e);
}
}
};
return uceh;
}
Aggregations