Beispiel #1
0
        internal static void RunActions(ModEntry mod, string phase)
        {
            try {
                phase = phase.ToLowerInvariant();
                var all = mod.Metadata.Actions;
                if (!QuickScanActions(all, phase))
                {
                    return;                              // TODO: move to ModScanner instead of rescanning every phase.
                }
                var log = mod.Log();
                log.Verbo("Scanning {0} actions", all.Length);
                var actions = FilterActions(all, phase, out int defaultCount);
                if (actions == null)
                {
                    return;
                }
                if (!InitActionHandlers())
                {
                    return;
                }

                log.Info("Running {0} actions ({1} defaults merged)", actions.Count, defaultCount);
                var modPrefix = mod.PrefixFilter;
                foreach (var dll in ActionHandlers)
                {
                    var handler = ActionMods[dll];
                    if (handler != mod)
                    {
                        handler.Log().Filters.Add(modPrefix);
                    }
                }
                foreach (var act in actions)
                {
                    foreach (var dll in ActionHandlers)
                    {
                        var result = RunActionHandler(mod, dll, act);
                        if (result is Exception ex && AbortOnError(log, act, ex))
                        {
                            return;
                        }
                    }
                }
                foreach (var dll in ActionHandlers)
                {
                    ActionMods[dll].Log().Filters.Remove(modPrefix);
                }
            } catch (Exception ex) { mod.Log().Error(ex); }
        }
Beispiel #2
0
        public static Assembly LoadDll(ModEntry mod, string path)
        {
            try {
                if (mod.ModAssemblies != null)
                {
                    foreach (var a in mod.ModAssemblies)
                    {
                        if (!a.IsDynamic && a.Location == path)
                        {
                            return(a);
                        }
                    }
                }

                /*if ( ! Tools.IsSafePath( path ) ) { // TODO: Make auto-scanned dll use relative path
                 * mod.Log().Error( "Invalid or unsafe path: {0}", path );
                 * return null;
                 * }*/
                mod.Log().Info("Loading {0}", path);
                var asm = Assembly.LoadFrom(path);
                if (asm == null)
                {
                    return(null);
                }
                if (mod.ModAssemblies == null)
                {
                    mod.ModAssemblies = new List <Assembly>();
                }
                if (!mod.ModAssemblies.Contains(asm))
                {
                    mod.ModAssemblies.Add(asm);
                }
                return(asm);
            } catch (Exception ex) { mod.Error(ex); return(null); }
        }
Beispiel #3
0
 public static Assembly LoadDll(ModEntry mod, string path)
 {
     try {
         if (mod.ModAssemblies != null)
         {
             foreach (var a in mod.ModAssemblies)
             {
                 if (!a.IsDynamic && a.Location == path)
                 {
                     return(a);
                 }
             }
         }
         mod.Log().Info("Loading {0}", path);
         var asm = Assembly.LoadFrom(path);
         if (asm == null)
         {
             return(null);
         }
         if (mod.ModAssemblies == null)
         {
             mod.ModAssemblies = new List <Assembly>();
         }
         if (!mod.ModAssemblies.Contains(asm))
         {
             mod.ModAssemblies.Add(asm);
         }
         return(asm);
     } catch (Exception ex) { mod.Error(ex); return(null); }
 }
Beispiel #4
0
 internal static ActionDef[] Resolve(ModEntry mod, ActionDef[] list)
 {
     try {
         ActionDef defValues = null;
         return(PreprocessActions(mod, list, ref defValues, 0));
     } catch (Exception ex) {
         mod.Log().Error(ex);
         return(new ActionDef[0]);
     }
 }
Beispiel #5
0
        internal static void RunActions(ModEntry mod, string phase)
        {
            try {
                var actions = FilterActions(mod.Metadata.Actions, phase.ToLowerInvariant());

                var log = mod.Log();
                log.Verbo("Running {0} actions", actions.Length);
                if (!InitActionHandlers())
                {
                    return;
                }

                var modPrefix = mod.PrefixFilter;
                foreach (var dll in ActionHandlers)
                {
                    var handler = ActionMods[dll];
                    if (handler != mod)
                    {
                        handler.Log().Filters.Add(modPrefix);
                    }
                }
                foreach (var act in actions)
                {
                    foreach (var dll in ActionHandlers)
                    {
                        var result = RunActionHandler(mod, dll, act);
                        if (result is Exception ex)
                        {
                            return;
                        }
                    }
                }
                foreach (var dll in ActionHandlers)
                {
                    ActionMods[dll].Log().Filters.Remove(modPrefix);
                }
            } catch (Exception ex) { mod.Log().Error(ex); }
        }
Beispiel #6
0
 private static void DisableAndRemoveMod(ModEntry mod, string reason, string log, params object[] augs)
 {
     lock ( mod ) {
         if (mod.Disabled)
         {
             return;
         }
         mod.Log().Info("Mod Disabled: " + log, augs);
         mod.Disabled = true;
         mod.AddNotice(TraceEventType.Error, reason, augs);
         EnabledMods.Remove(mod);
         ResolveModAgain = true;
     }
 }
Beispiel #7
0
        private static object RunActionHandler(ModEntry mod, DllMeta dll, ActionDef act)
        {
            try {
                var lib = ModPhases.LoadDll(mod, dll.Path);
                if (lib == null)
                {
                    return(false);
                }
                var handler = ActionMods[dll];
                object GetParamValue(ParameterInfo pi) => ParamValue(act, pi, mod, handler);

                object result;
                foreach (var type in dll.Methods["ActionMod"])
                {
                    result = ModPhases.CallInit(mod, lib, type, "ActionMod", GetParamValue);
                    if (result is bool success)
                    {
                        if (success)
                        {
                            return(true);
                        }
                    }
                    else if (result is Exception ex)
                    {
                        LogActionError(handler.Log(), act, ex);
                        if (InList(act.GetText("onerror"), "continue"))
                        {
                            continue;
                        }
                        if (InList(act.GetText("onerror"), "skip"))
                        {
                            return(null);
                        }
                        mod.Log().Info("Aborting Actions. Set OnError to \"Log,Continue\" or \"Log,Skip\" to ignore the error.");
                        return(ex);
                    }
                    else if (result != null)
                    {
                        handler.Log().Error("Unexpected ActionMod result: {0}", result.GetType());
                    }
                }
                return(null);
            } catch (Exception ex) { mod.Error(ex); return(null); }
        }
Beispiel #8
0
        private static ActionDef[] LoadInclude(ModEntry mod, string path, ref ActionDef defValues, int level)
        {
            if (!IsSafePath(path))
            {
                mod.Log().Error("Invalid or unsafe path: {0}", path);
                return(new ActionDef[0]);
            }
            if (level > 9)
            {
                throw new ApplicationException("Action includes too deep: " + path);
            }
            // todo: refactor mod path
            var actions = Json.Parse <ActionDef[]>(ReadText(Path.Combine(Path.GetDirectoryName(mod.Path), path)));

            ModMeta.NormDictArray(ref actions);
            try {
                return(PreprocessActions(mod, actions, ref defValues, level));
            } catch (ApplicationException ex) {
                throw new ApplicationException("Error when including " + path, ex);
            }
        }
Beispiel #9
0
        public static object CallInit(ModEntry mod, Assembly dll, string typeName, string methodName, Func <ParameterInfo, object> paramGetter)
        {
            try {
                Logger log = mod.Log();

                var type = dll.GetType(typeName);
                if (type == null)
                {
                    log.Error("Cannot find type {1} in {0}", dll.Location, typeName);
                    return(null);
                }

                var func = type.GetMethods(ModScanner.INIT_METHOD_FLAGS)?.FirstOrDefault(e => e.Name.Equals(methodName));
                if (func == null)
                {
                    log.Error("Cannot find {1}.{2} in {0}", dll.Location, typeName, methodName);
                    return(null);
                }

                var           args   = func.GetParameters().Select(paramGetter);
                Func <string> argTxt = () => string.Join(", ", args.Select(e => e?.GetType()?.Name ?? "null"));
                log.Log(methodName == "ActionMod" ? SourceLevels.Verbose : SourceLevels.Information,
                        "Calling {1}.{2}({3}) in {0}", dll.Location, typeName, methodName, argTxt);
                object target = null;
                if (!func.IsStatic)
                {
                    lock ( ModInstances ) {
                        if (!ModInstances.TryGetValue(type, out WeakReference <object> wref) || !wref.TryGetTarget(out target))
                        {
                            ModInstances[type] = new WeakReference <object>(target = Activator.CreateInstance(type));
                        }
                    }
                }
                var result = func.Invoke(target, args.ToArray());
                log.Trace("Done calling {1}.{2}", typeName, methodName);
                return(result);
            } catch (Exception ex) { return(ex); }
        }