示例#1
0
        /// <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;
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }