Exemple #1
0
        private ModLoader.ModInfo _LoadOrIgnoreIfBlacklisted(string mods_dir_entry, HashSet <string> blacklist)
        {
            var filename = Path.GetFileName(mods_dir_entry);

            if (blacklist.Contains(mods_dir_entry))
            {
                Logger.Info($"Refusing to load blacklisted mod: {filename}");
                return(null);
            }
            Logger.Info($"Loading mod: {filename}");
            try {
                return(ModLoader.Load(mods_dir_entry));
            } catch (Exception e) {
                Logger.Error($"Exception while loading mod {filename}: [{e.GetType().Name}] {e.Message}");
                ErrorLoadingMod.Invoke(filename, e);

                foreach (var l in e.StackTrace.Split('\n'))
                {
                    Logger.ErrorIndent(l);
                }

                if (e.InnerException != null)
                {
                    Logger.ErrorIndent($"Inner exception: [{e.InnerException.GetType().Name}] {e.InnerException.Message}");
                    foreach (var l in e.InnerException.StackTrace.Split('\n'))
                    {
                        Logger.ErrorIndent(l);
                    }
                }
            }
            return(null);
        }
Exemple #2
0
        public void Unload(ModInfo info)
        {
            UnloadAll(info.EmbeddedMods);

            Logger.Info($"Unloading mod {info.Name}");
            if (info.HasScript)
            {
                try {
                    info.Triggers.InvokeUnloaded();
                } catch (LuaException e) {
                    Logger.Error(e.Message);
                    LuaError.Invoke(info, LuaEventMethod.Unloaded, e);

                    for (int i = 0; i < e.TracebackArray.Length; i++)
                    {
                        Logger.ErrorIndent("  " + e.TracebackArray[i]);
                    }
                }
            }

            info.Dispose();

            info.EmbeddedMods = new List <ModInfo>();
            PostUnloadMod.Invoke(info);
        }
Exemple #3
0
        public void ExecuteCommandAndPrintResult(string cmd)
        {
            if (PrintUsedCommand)
            {
                PrintLine("> " + cmd, color: new Color(87 / 255f, 87 / 255f, 87 / 255f));
            }
            try {
                PrintLine(ExecuteCommand(cmd));
            } catch (Exception e) {
                PrintError("Exception while executing command:");
                PrintError(e.Message);
                PrintError("More detailed info in the log.");

                Logger.Error($"Exception while running command '{cmd}':");
                Logger.Error(e.Message);
                var stlines = e.StackTrace.Split('\n');

                for (int i = 0; i < stlines.Length; i++)
                {
                    Logger.ErrorIndent(stlines[i]);
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Loads a mod.
        /// </summary>
        /// <param name="info">Preloaded mod info.</param>
        /// <param name="tree_history">Hash set of mod IDs in the dependency tree. This is used to detect cyclic dependencies.</param>
        internal static void LoadMod(ModInfo info, HashSet <string> tree_history = null)
        {
            Logger.Debug($"Loading: {info.Config.ID}");
            CurrentLoadingModID   = null;
            CurrentLoadingModName = null;

            var config = info.Config;

            if (Mods.ContainsKey(config.ID))
            {
                return;                                          // already loaded!
            }
            CurrentLoadingModID   = config.ID;
            CurrentLoadingModName = config.Name;

            var dll_name = config.DLL ?? "mod.dll";
            var dll_path = Path.Combine(info.Path, dll_name);

            if (!File.Exists(dll_path))
            {
                throw new InvalidConfigException(config.ID, $"Tried loading mod '{config.ID}' but it doesn't have the specified DLL file {dll_name}.");
            }

            if (config.Depends != null)
            {
                if (tree_history == null)
                {
                    tree_history = new HashSet <string>();
                }
                tree_history.Add(config.ID);

                for (var i = 0; i < config.Depends.Length; i++)
                {
                    var dep = config.Depends[i].Trim();
                    Logger.Debug($"'{config.ID}' dependency: '{dep}'");
                    ModInfo dep_info = null;
                    if (!FlatModInfos.TryGetValue(dep, out dep_info))
                    {
                        throw new MissingDependencyException(config.ID, dep);
                    }

                    if (tree_history != null && tree_history.Contains(dep))
                    {
                        throw new CyclicDependencyException(config.ID, dep);
                    }

                    LoadMod(dep_info, tree_history);
                }
            }

            AppDomain.CurrentDomain.AssemblyResolve += GenerateModAssemblyResolver(info.Path);

            Assembly asm;

            using (FileStream f = File.OpenRead(dll_path)) {
                asm = AssemblyRelinker.GetRelinkedAssembly(config.ID, dll_name, dll_path, f);
            }

            if (asm == null)
            {
                throw new ModLoadException(config.ID, "Failed loading/relinking assembly");
            }

            if (info.Config.ModType == ModConfig.Type.Library)
            {
                Logger.Debug($"Mod is a library; not creating any Mod instances");
                return;
            }

            Logger.Debug($"Searching for Mod subclasses");
            Type[] types = null;
            try {
                types = asm.GetTypes();
            } catch (ReflectionTypeLoadException e) {
                Logger.Error($"Failed loading types from mod:");
                if (e.LoaderExceptions == null)
                {
                    Logger.ErrorIndent("(No loader exceptions)");
                }
                else
                {
                    for (int i = 0; i < e.LoaderExceptions.Length; i++)
                    {
                        var ex = e.LoaderExceptions[i];
                        Logger.ErrorIndent($"- [{ex.GetType().Name}] {ex.Message}");
                    }
                }
                return;
            }
            Logger.Debug($"{types.Length} type(s)");
            for (int i = 0; i < types.Length; i++)
            {
                var type = types[i];
                if (!typeof(Mod).IsAssignableFrom(type) || type.IsAbstract)
                {
                    continue;
                }

                var mod_go = new GameObject($"Semi Mod '{config.ID}' GameObject");
                UnityEngine.Object.DontDestroyOnLoad(mod_go);
                ModsStorageObjects.Add(mod_go);
                Mod mod_instance = (Mod)mod_go.AddComponent(type);
                Logger.Debug($"Type name: {mod_instance.GetType().FullName}");
                mod_instance.Logger = new Logger(config.Name ?? config.ID);

                info.Instance   = mod_instance;
                config.Instance = mod_instance;
                Mods[config.ID] = info;

                mod_instance.Info = info;

                mod_instance.Loaded();
            }
        }