/// <summary> /// Unloads all loaded mods. /// </summary> internal static void Unload() { if (HookManager.ModDef != null) { HookManager.ModDef.OnUnload(); } Unloading = true; Logging.LogInfo("Unloading mods..."); HookManager.CanCallHooks = false; HookManager.Clear(); EntityDefLoader.ResetEntityHandlers(); ResourceLoader.Unload(); ContentLoader.Reset(); foreach (var v in ModData.mods.Values) { v.Unload(); } ModData.mods.Clear(); errors.Clear(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); Logging.LogInfo("Mods finished unloading."); Unloading = false; }
/// <summary> /// Loads a mod from an <see cref="System.Reflection.Assembly"/> and returns its <see cref="ModDef"/>. /// </summary> /// <param name="asm">The mod's <see cref="System.Reflection.Assembly"/></param> /// <param name="info">The mod's <see cref="ModInfo"/></param> /// <returns>The <see cref="ModDef"/> of the mod</returns> static ModDef LoadModFromAssembly(Assembly asm, ModInfo info) { var mdType = asm.GetType(info.ModDefTypeName, false); if (mdType == null) { errors.Add(new LoaderError(info, "ModDef type not found", info.ModDefTypeName)); return(null); } var mod = Activator.CreateInstance(mdType) as ModDef; if (mod == null) { errors.Add(new LoaderError(info, "Could not instantiate ModDef implementation", mdType)); return(null); } mod.Assembly = asm; mod.Info = info; // required by the entity def loader ModData.mods.Add(mod.Info, mod); ModData.modsFromInternalName.Add(mod.Info.InternalName, mod); mod.ContentHandler = mod.CreateContentHandlerInternally(); mod.ContentHandler.Adopt(mod.Info); errors.AddRange(ResourceLoader.Load(mod)); errors.AddRange(ContentLoader.Load(mod)); errors.AddRange(EntityDefLoader.Load(mod)); return(mod); }
/// <summary> /// Loads all mods from the Prism mod directory and returns a list containing any loader errors encountered. /// </summary> /// <returns>Any <see cref="LoaderError"/>'s encountered while loading.</returns> internal static IEnumerable <LoaderError> Load() { Loading = true; Logging.LogInfo("Loading mods..."); errors.Clear(); if (!Directory.Exists(PrismApi.ModDirectory)) { Directory.CreateDirectory(PrismApi.ModDirectory); } EntityDefLoader.SetupEntityHandlers(); ResourceLoader.Setup(); ContentLoader.Setup(); var dirs = Directory.EnumerateDirectories(PrismApi.ModDirectory); // The mod .dll in the DebugModDir should be one in the output directory of the Visual Studio mod project. // Because the VS debugger knows which .dll it should use (and has a .pdb file), Edit & Continue and other // hackery should be automatically activated. foreach (string s in DebugModDir == null ? dirs : new[] { DebugModDir }.Concat(dirs)) { var prevModCount = ModData.mods.Count; var d = LoadMod(s); var newModCount = ModData.mods.Count; if (newModCount > prevModCount) //Make sure a new mod was actually added to ModData.mods so we don't get a "Sequence is empty" error on ModData.mods.Last() { if (d == null) { var i = ModData.mods.Last().Key; ModData.mods.Remove(i); ModData.modsFromInternalName.Remove(i.InternalName); } if (d != null) { //ModData.mods .Add(d.Info , d); //ModData.modsFromInternalName.Add(d.Info.InternalName, d); try { d.OnLoad(); } catch (Exception e) { errors.Add(new LoaderError(d.Info, "An exception occured in ModDef.OnLoad()", e)); // Temporary until we have a proper way to see loader errors if (ExceptionHandler.DetailedExceptions) { MessageBox.ShowError("An exception has occured:\n" + e); } } } } else { errors.Add(new LoaderError(s, String.Format("New entry was not added to ModData.mods while loading mod from path '{0}', see previous errors. Mods loaded" /* once again, : added automatically */, s), ModData.mods)); } } HookManager.Create(); HookManager.CanCallHooks = true; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); Loading = false; Logging.LogInfo("Mods finished loading."); HookManager.ModDef.OnAllModsLoaded(); for (int i = 0; i < errors.Count; i++) { Logging.LogWarning(errors[i].ToString()); } if (errors.Count > 0) { Trace.WriteLine("Some problems occured when loading mods. See the prism.log file for details."); ModLoader.ShowAllErrors(); } return(errors); }