Search in sources :

Example 1 with Extension

use of com.laytonsmith.core.extensions.Extension in project CommandHelper by EngineHub.

the class Script method eval.

/**
 * Given the parse tree and environment, executes the tree.
 *
 * @param c
 * @param env
 * @return
 * @throws CancelCommandException
 */
public Construct eval(ParseTree c, final Environment env) throws CancelCommandException {
    if (env.getEnv(GlobalEnv.class).IsInterrupted()) {
        // unconditionally.
        throw new CancelCommandException("", Target.UNKNOWN);
    }
    final Construct m = c.getData();
    CurrentEnv = env;
    if (m.getCType() != ConstructType.FUNCTION) {
        if (m.getCType() == ConstructType.VARIABLE) {
            return new CString(m.val(), m.getTarget());
        } else {
            return m;
        }
    }
    StackTraceManager stManager = env.getEnv(GlobalEnv.class).GetStackTraceManager();
    boolean addedRootStackElement = false;
    try {
        // If it's an unknown target, this is not user generated code, and we want to skip adding the element here.
        if (stManager.isStackEmpty() && !m.getTarget().equals(Target.UNKNOWN)) {
            stManager.addStackTraceElement(new ConfigRuntimeException.StackTraceElement("<<main code>>", m.getTarget()));
            addedRootStackElement = true;
        }
        stManager.setCurrentTarget(c.getTarget());
        env.getEnv(GlobalEnv.class).SetScript(this);
        if (m.val().charAt(0) == '_' && m.val().charAt(1) != '_') {
            // Not really a function, so we can't put it in Function.
            Procedure p = getProc(m.val());
            if (p == null) {
                throw new CREInvalidProcedureException("Unknown procedure \"" + m.val() + "\"", m.getTarget());
            }
            Environment newEnv = env;
            try {
                newEnv = env.clone();
            } catch (CloneNotSupportedException e) {
            }
            ProfilePoint pp = env.getEnv(GlobalEnv.class).GetProfiler().start(m.val() + " execution", LogLevel.INFO);
            Construct ret;
            try {
                ret = p.cexecute(c.getChildren(), newEnv, m.getTarget());
            } finally {
                pp.stop();
            }
            return ret;
        }
        final Function f;
        try {
            f = (Function) FunctionList.getFunction(m);
        } catch (ConfigCompileException e) {
            // Turn it into a config runtime exception. This shouldn't ever happen though.
            throw ConfigRuntimeException.CreateUncatchableException("Unable to find function " + m.val(), m.getTarget());
        }
        ArrayList<Construct> args = new ArrayList<>();
        try {
            if (f.isRestricted() && !Static.hasCHPermission(f.getName(), env)) {
                throw new CREInsufficientPermissionException("You do not have permission to use the " + f.getName() + " function.", m.getTarget());
            }
            if (f.useSpecialExec()) {
                ProfilePoint p = null;
                if (f.shouldProfile() && env.getEnv(GlobalEnv.class).GetProfiler() != null && env.getEnv(GlobalEnv.class).GetProfiler().isLoggable(f.profileAt())) {
                    p = env.getEnv(GlobalEnv.class).GetProfiler().start(f.profileMessageS(c.getChildren()), f.profileAt());
                }
                Construct ret;
                try {
                    ret = f.execs(m.getTarget(), env, this, c.getChildren().toArray(new ParseTree[] {}));
                } finally {
                    if (p != null) {
                        p.stop();
                    }
                }
                return ret;
            }
            for (ParseTree c2 : c.getChildren()) {
                args.add(eval(c2, env));
            }
            Object[] a = args.toArray();
            Construct[] ca = new Construct[a.length];
            for (int i = 0; i < a.length; i++) {
                ca[i] = (Construct) a[i];
                // CArray, CBoolean, CDouble, CInt, CNull, CString, CVoid, CEntry, CLabel (only to sconcat).
                if (!(ca[i] instanceof CArray || ca[i] instanceof CBoolean || ca[i] instanceof CDouble || ca[i] instanceof CInt || ca[i] instanceof CNull || ca[i] instanceof CString || ca[i] instanceof CVoid || ca[i] instanceof IVariable || ca[i] instanceof CEntry || ca[i] instanceof CLabel) && (!f.getName().equals("__autoconcat__") && (ca[i] instanceof CLabel))) {
                    throw new CRECastException("Invalid Construct (" + ca[i].getClass() + ") being passed as an argument to a function (" + f.getName() + ")", m.getTarget());
                }
                while (f.preResolveVariables() && ca[i] instanceof IVariable) {
                    IVariable cur = (IVariable) ca[i];
                    ca[i] = env.getEnv(GlobalEnv.class).GetVarList().get(cur.getVariableName(), cur.getTarget()).ival();
                }
            }
            {
                // It takes a moment to generate the toString of some things, so lets not do it
                // if we actually aren't going to profile
                ProfilePoint p = null;
                if (f.shouldProfile() && env.getEnv(GlobalEnv.class).GetProfiler() != null && env.getEnv(GlobalEnv.class).GetProfiler().isLoggable(f.profileAt())) {
                    p = env.getEnv(GlobalEnv.class).GetProfiler().start(f.profileMessage(ca), f.profileAt());
                }
                Construct ret;
                try {
                    ret = f.exec(m.getTarget(), env, ca);
                } finally {
                    if (p != null) {
                        p.stop();
                    }
                }
                return ret;
            }
        // We want to catch and rethrow the ones we know how to catch, and then
        // catch and report anything else.
        } catch (ConfigRuntimeException | ProgramFlowManipulationException e) {
            if (e instanceof AbstractCREException) {
                ((AbstractCREException) e).freezeStackTraceElements(stManager);
            }
            throw e;
        } catch (InvalidEnvironmentException e) {
            if (!e.isDataSet()) {
                e.setData(f.getName());
            }
            throw e;
        } catch (Exception e) {
            String brand = Implementation.GetServerType().getBranding();
            SimpleVersion version = Static.getVersion();
            String culprit = brand;
            outer: for (ExtensionTracker tracker : ExtensionManager.getTrackers().values()) {
                for (FunctionBase b : tracker.getFunctions()) {
                    if (b.getName().equals(f.getName())) {
                        // name instead of the core plugin's name.
                        for (Extension extension : tracker.getExtensions()) {
                            culprit = extension.getName();
                            break outer;
                        }
                    }
                }
            }
            String emsg = TermColors.RED + "Uh oh! You've found an error in " + TermColors.CYAN + culprit + TermColors.RED + ".\n" + "This happened while running your code, so you may be able to find a workaround," + " but is ultimately an issue in " + culprit + ".\n" + "The following code caused the error:\n" + TermColors.WHITE;
            List<String> args2 = new ArrayList<>();
            Map<String, String> vars = new HashMap<>();
            for (Construct cc : args) {
                if (cc instanceof IVariable) {
                    Construct ccc = env.getEnv(GlobalEnv.class).GetVarList().get(((IVariable) cc).getVariableName(), cc.getTarget()).ival();
                    String vval = ccc.val();
                    if (ccc instanceof CString) {
                        vval = ccc.asString().getQuote();
                    }
                    vars.put(((IVariable) cc).getVariableName(), vval);
                }
                if (cc == null) {
                    args2.add("java-null");
                } else if (cc instanceof CString) {
                    args2.add(cc.asString().getQuote());
                } else if (cc instanceof IVariable) {
                    args2.add(((IVariable) cc).getVariableName());
                } else {
                    args2.add(cc.val());
                }
            }
            if (!vars.isEmpty()) {
                emsg += StringUtils.Join(vars, " = ", "\n") + "\n";
            }
            emsg += f.getName() + "(";
            emsg += StringUtils.Join(args2, ", ");
            emsg += ")\n";
            emsg += TermColors.RED + "on or around " + TermColors.YELLOW + m.getTarget().file() + TermColors.WHITE + ":" + TermColors.CYAN + m.getTarget().line() + TermColors.RED + ".\n";
            // Server might not be available in this platform, so let's be sure to ignore those exceptions
            String modVersion;
            try {
                modVersion = StaticLayer.GetConvertor().GetServer().getAPIVersion();
            } catch (Exception ex) {
                modVersion = Implementation.GetServerType().name();
            }
            String extensionData = "";
            for (ExtensionTracker tracker : ExtensionManager.getTrackers().values()) {
                for (Extension extension : tracker.getExtensions()) {
                    try {
                        extensionData += TermColors.CYAN + extension.getName() + TermColors.RED + " (" + TermColors.RESET + extension.getVersion() + TermColors.RED + ")\n";
                    } catch (AbstractMethodError ex) {
                        // This happens with an old style extensions. Just skip it.
                        extensionData += TermColors.CYAN + "Unknown Extension" + TermColors.RED + "\n";
                    }
                }
            }
            if (extensionData.isEmpty()) {
                extensionData = "NONE\n";
            }
            emsg += "Please report this to the developers, and be sure to include the version numbers:\n" + TermColors.CYAN + "Server" + TermColors.RED + " version: " + TermColors.RESET + modVersion + TermColors.RED + ";\n" + TermColors.CYAN + brand + TermColors.RED + " version: " + TermColors.RESET + version + TermColors.RED + ";\n" + "Loaded extensions and versions:\n" + extensionData + "Here's the stacktrace:\n" + TermColors.RESET + Static.GetStacktraceString(e);
            Static.getLogger().log(Level.SEVERE, emsg);
            throw new CancelCommandException(null, Target.UNKNOWN);
        }
    } finally {
        if (addedRootStackElement && stManager.isStackSingle()) {
            stManager.popStackTraceElement();
        }
    }
}
Also used : CLabel(com.laytonsmith.core.constructs.CLabel) InvalidEnvironmentException(com.laytonsmith.core.environments.InvalidEnvironmentException) FunctionBase(com.laytonsmith.core.functions.FunctionBase) IVariable(com.laytonsmith.core.constructs.IVariable) ArrayList(java.util.ArrayList) CArray(com.laytonsmith.core.constructs.CArray) CREInvalidProcedureException(com.laytonsmith.core.exceptions.CRE.CREInvalidProcedureException) ExtensionTracker(com.laytonsmith.core.extensions.ExtensionTracker) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CString(com.laytonsmith.core.constructs.CString) ConfigCompileException(com.laytonsmith.core.exceptions.ConfigCompileException) CString(com.laytonsmith.core.constructs.CString) Function(com.laytonsmith.core.functions.Function) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) SimpleVersion(com.laytonsmith.PureUtilities.SimpleVersion) FunctionList(com.laytonsmith.core.functions.FunctionList) List(java.util.List) ArrayList(java.util.ArrayList) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) CREInsufficientPermissionException(com.laytonsmith.core.exceptions.CRE.CREInsufficientPermissionException) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) CBoolean(com.laytonsmith.core.constructs.CBoolean) CDouble(com.laytonsmith.core.constructs.CDouble) ProgramFlowManipulationException(com.laytonsmith.core.exceptions.ProgramFlowManipulationException) StackTraceManager(com.laytonsmith.core.exceptions.StackTraceManager) ProfilePoint(com.laytonsmith.core.profiler.ProfilePoint) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) ProgramFlowManipulationException(com.laytonsmith.core.exceptions.ProgramFlowManipulationException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) InvalidEnvironmentException(com.laytonsmith.core.environments.InvalidEnvironmentException) ConfigCompileException(com.laytonsmith.core.exceptions.ConfigCompileException) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) CREInsufficientPermissionException(com.laytonsmith.core.exceptions.CRE.CREInsufficientPermissionException) LoopBreakException(com.laytonsmith.core.exceptions.LoopBreakException) CREInvalidProcedureException(com.laytonsmith.core.exceptions.CRE.CREInvalidProcedureException) LoopContinueException(com.laytonsmith.core.exceptions.LoopContinueException) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) ConfigCompileGroupException(com.laytonsmith.core.exceptions.ConfigCompileGroupException) ProfilePoint(com.laytonsmith.core.profiler.ProfilePoint) CVoid(com.laytonsmith.core.constructs.CVoid) Extension(com.laytonsmith.core.extensions.Extension) CInt(com.laytonsmith.core.constructs.CInt) Construct(com.laytonsmith.core.constructs.Construct) CommandHelperEnvironment(com.laytonsmith.core.environments.CommandHelperEnvironment) Environment(com.laytonsmith.core.environments.Environment) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) CEntry(com.laytonsmith.core.constructs.CEntry) Map(java.util.Map) HashMap(java.util.HashMap) CNull(com.laytonsmith.core.constructs.CNull)

Example 2 with Extension

use of com.laytonsmith.core.extensions.Extension in project CommandHelper by EngineHub.

the class EventUtils method GetMatchingEvents.

/**
 * Returns a set of events that should be triggered by this event.
 *
 * @param type
 * @param eventName
 * @param e
 * @return
 */
public static SortedSet<BoundEvent> GetMatchingEvents(Driver type, String eventName, BindableEvent e, Event driver) {
    SortedSet<BoundEvent> toRun = new TreeSet<>();
    // This is the set of bounded events of this driver type.
    // We must now look through the bound events to see if they are
    // the eventName, and if so, we will also run the prefilter.
    SortedSet<BoundEvent> bounded = GetEvents(type);
    if (bounded != null) {
        // Wrap this in a new set, so we can safely iterate it with async threads
        bounded = new TreeSet<>(bounded);
        for (BoundEvent b : bounded) {
            try {
                boolean matches = false;
                try {
                    matches = driver.matches(b.getPrefilter(), e);
                } catch (ConfigRuntimeException ex) {
                    // This can happen in limited cases, but still needs to be
                    // handled properly. This would happen if, for instance, a
                    // prefilter was configured improperly with bad runtime data.
                    // We use the environment from the bound event.
                    ConfigRuntimeException.HandleUncaughtException(ex, b.getEnvironment());
                } catch (NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError err) {
                    // This happens when a CH extension depends on a not-included or binary outdated class.
                    // Log the error and continue since there's nothing we can do about it.
                    String chBrand = Implementation.GetServerType().getBranding();
                    String chVersion = Static.getVersion().toString();
                    String culprit = chBrand;
                    outerLoop: for (ExtensionTracker tracker : ExtensionManager.getTrackers().values()) {
                        for (Event event : tracker.getEvents()) {
                            if (event.getName().equals(driver.getName())) {
                                for (Extension extension : tracker.getExtensions()) {
                                    culprit = extension.getName();
                                    break outerLoop;
                                }
                            }
                        }
                    }
                    String modVersion;
                    try {
                        modVersion = StaticLayer.GetConvertor().GetServer().getAPIVersion();
                    } catch (Exception ex) {
                        modVersion = Implementation.GetServerType().name();
                    }
                    String extensionData = "";
                    for (ExtensionTracker tracker : ExtensionManager.getTrackers().values()) {
                        for (Extension extension : tracker.getExtensions()) {
                            try {
                                extensionData += TermColors.CYAN + extension.getName() + TermColors.RED + " (" + TermColors.RESET + extension.getVersion() + TermColors.RED + ")\n";
                            } catch (AbstractMethodError ex) {
                                // This happens with an old style extensions. Just skip it.
                                extensionData += TermColors.CYAN + "Unknown Extension" + TermColors.RED + "\n";
                            }
                        }
                    }
                    if (extensionData.isEmpty()) {
                        extensionData = "NONE\n";
                    }
                    String driverEventName = driver.getName();
                    String jarName = new File(driver.getSourceJar().getFile()).getName();
                    String emsg = TermColors.RED + "Uh oh! You've found an error in the eventhandler for event " + TermColors.CYAN + driverEventName + TermColors.RED + ", implemented in " + TermColors.CYAN + culprit + " (" + jarName + ")" + TermColors.RED + ".\n" + "Please report this to the developers, and be sure to include the version numbers:\n" + TermColors.CYAN + "Server" + TermColors.RED + " version: " + TermColors.RESET + modVersion + TermColors.RED + ";\n" + TermColors.CYAN + chBrand + TermColors.RED + " version: " + TermColors.RESET + chVersion + TermColors.RED + ";\n" + "Loaded extensions and versions:\n" + extensionData + "Here's the stacktrace:\n" + TermColors.RESET + Static.GetStacktraceString(err);
                    Static.getLogger().log(Level.SEVERE, emsg);
                    // If we can't match it, it's not a match.
                    continue;
                }
                if (b.getEventName().equals(eventName) && matches) {
                    toRun.add(b);
                }
            } catch (PrefilterNonMatchException ex) {
            // Not running this one
            }
        }
    }
    return toRun;
}
Also used : PrefilterNonMatchException(com.laytonsmith.core.exceptions.PrefilterNonMatchException) ExtensionTracker(com.laytonsmith.core.extensions.ExtensionTracker) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CString(com.laytonsmith.core.constructs.CString) EventException(com.laytonsmith.core.exceptions.EventException) CREBindException(com.laytonsmith.core.exceptions.CRE.CREBindException) CREEventException(com.laytonsmith.core.exceptions.CRE.CREEventException) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) PrefilterNonMatchException(com.laytonsmith.core.exceptions.PrefilterNonMatchException) Extension(com.laytonsmith.core.extensions.Extension) TreeSet(java.util.TreeSet) File(java.io.File)

Aggregations

CString (com.laytonsmith.core.constructs.CString)2 ConfigRuntimeException (com.laytonsmith.core.exceptions.ConfigRuntimeException)2 FunctionReturnException (com.laytonsmith.core.exceptions.FunctionReturnException)2 Extension (com.laytonsmith.core.extensions.Extension)2 ExtensionTracker (com.laytonsmith.core.extensions.ExtensionTracker)2 SimpleVersion (com.laytonsmith.PureUtilities.SimpleVersion)1 CArray (com.laytonsmith.core.constructs.CArray)1 CBoolean (com.laytonsmith.core.constructs.CBoolean)1 CDouble (com.laytonsmith.core.constructs.CDouble)1 CEntry (com.laytonsmith.core.constructs.CEntry)1 CInt (com.laytonsmith.core.constructs.CInt)1 CLabel (com.laytonsmith.core.constructs.CLabel)1 CNull (com.laytonsmith.core.constructs.CNull)1 CVoid (com.laytonsmith.core.constructs.CVoid)1 Construct (com.laytonsmith.core.constructs.Construct)1 IVariable (com.laytonsmith.core.constructs.IVariable)1 CommandHelperEnvironment (com.laytonsmith.core.environments.CommandHelperEnvironment)1 Environment (com.laytonsmith.core.environments.Environment)1 GlobalEnv (com.laytonsmith.core.environments.GlobalEnv)1 InvalidEnvironmentException (com.laytonsmith.core.environments.InvalidEnvironmentException)1