コード例 #1
0
        internal static void LoadMod(IMod mod, bool updateModText)
        {
            ModHooks.Instance.GlobalSettings.ModEnabledSettings[mod.GetName()] = true;

            mod.Initialize();


            if (!ModHooks.Instance.LoadedModsWithVersions.ContainsKey(mod.GetType().Name))
            {
                ModHooks.Instance.LoadedModsWithVersions.Add(mod.GetType().Name, mod.GetVersion());
            }
            else
            {
                ModHooks.Instance.LoadedModsWithVersions[mod.GetType().Name] = mod.GetVersion();
            }

            if (ModHooks.Instance.LoadedMods.All(x => x != mod.GetType().Name))
            {
                ModHooks.Instance.LoadedMods.Add(mod.GetType().Name);
            }

            if (updateModText)
            {
                UpdateModText();
            }
        }
コード例 #2
0
ファイル: ModManager.cs プロジェクト: wty0512/Gnomodia
        private void SetInstances(IMod mod)
        {
            var fieldInstances =
                from field in mod.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
                where field.GetCustomAttributes(typeof(InstanceAttribute), false).Any()
                select field;

            foreach (var instanceMember in fieldInstances)
            {
                Type instanceType = instanceMember.FieldType;
                IMod instanceMod  = CreateOrGetAllMods().SingleOrDefault(m => m.GetType() == instanceType);
                if (instanceMod != null)
                {
                    instanceMember.SetValue(mod, instanceMod);
                }
            }
            var propertyInstances =
                from property in mod.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
                where property.GetCustomAttributes(typeof(InstanceAttribute), false).Any()
                select property;

            foreach (var instanceMember in propertyInstances)
            {
                Type instanceType = instanceMember.PropertyType;
                IMod instanceMod  = CreateOrGetAllMods().SingleOrDefault(m => m.GetType() == instanceType);
                if (instanceMod != null)
                {
                    instanceMember.SetValue(mod, mod, null);
                }
            }
        }
コード例 #3
0
		/// <summary>
		/// Register mod, if not already registered
		/// </summary>
		/// <param name="mod">Mod to be registered</param>
		public static void RegisterMod(IMod mod)
		{
			if (loadedModTypes.Contains(mod.GetType()))
			{
				return;
			}

			RegisterItems(mod.RegisterItems());
			RegisterRecipes(mod.RegisterRecipes());
			loadedModTypes.Add(mod.GetType());
		}
コード例 #4
0
ファイル: ModDataSaving.cs プロジェクト: wty0512/Gnomodia
        public ModSaveData GetDataFor(IMod mod)
        {
            ModSaveData result;

            if (modSaveData.TryGetValue(mod, out result))
            {
                return(result);
            }
            var textKey = mod.GetType().FullName;

            if (unloadedSaveData.TryGetValue(textKey, out result))
            {
                throw new Exception("This should never happen!");

                /*
                 #warning this should actually never happen anymore, since we look up existing mods while loading anyway.
                 * unloadedSaveData.Remove(textKey);
                 * modSaveData.Add(mod, result);
                 * return result;
                 */
            }
            result = new ModSaveData(mod);
            modSaveData.Add(mod, result);
            allSaveData.Add(result);
            return(result);
        }
コード例 #5
0
ファイル: ModManager.cs プロジェクト: wty0512/Gnomodia
        private void HookUpEvents(IMod mod)
        {
            // Get all event listeners from mod
            var eventMethods = (from method in mod.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public)
                                where method.GetCustomAttributes(typeof(EventListenerAttribute), false).Any()
                                select method).ToList();

            HookUpEvents(mod, eventMethods);
        }
コード例 #6
0
        public static void LoadFor(IMod mod)
        {
            var optionType = mod.GetType().GetFirstAttribute <ModOptionsAttribute>()?.ModOptionsType;

            if (optionType == null)
            {
                return;
            }
            var options = (AbstractOptions)Activator.CreateInstance(optionType);

            ModOptions.Add(mod.GetCleanId(), options);
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: FDKPIBC/SMAPI
        private void LoadMods(IModMetadata[] mods, JsonHelper jsonHelper, SContentManager contentManager)
#endif
        {
#if SMAPI_1_x
            this.Monitor.Log("Loading mods...");
#else
            this.Monitor.Log("Loading mods...", LogLevel.Trace);
#endif
            // load mod assemblies
            IDictionary <IModMetadata, string> skippedMods = new Dictionary <IModMetadata, string>();
            {
                void TrackSkip(IModMetadata mod, string reasonPhrase) => skippedMods[mod] = reasonPhrase;

                AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.TargetPlatform, this.Monitor);
                AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => modAssemblyLoader.ResolveAssembly(e.Name);
                foreach (IModMetadata metadata in mods)
                {
                    // get basic info
                    IManifest manifest     = metadata.Manifest;
                    string    assemblyPath = metadata.Manifest?.EntryDll != null
                        ? Path.Combine(metadata.DirectoryPath, metadata.Manifest.EntryDll)
                        : null;

                    this.Monitor.Log(assemblyPath != null
                        ? $"Loading {metadata.DisplayName} from {assemblyPath.Replace(Constants.ModPath, "").TrimStart(Path.DirectorySeparatorChar)}..."
                        : $"Loading {metadata.DisplayName}...", LogLevel.Trace);

                    // validate status
                    if (metadata.Status == ModMetadataStatus.Failed)
                    {
                        this.Monitor.Log($"   Failed: {metadata.Error}", LogLevel.Trace);
                        TrackSkip(metadata, metadata.Error);
                        continue;
                    }

                    // preprocess & load mod assembly
                    Assembly modAssembly;
                    try
                    {
                        modAssembly = modAssemblyLoader.Load(assemblyPath, assumeCompatible: metadata.Compatibility?.Compatibility == ModCompatibilityType.AssumeCompatible);
                    }
                    catch (IncompatibleInstructionException ex)
                    {
#if SMAPI_1_x
                        TrackSkip(metadata, $"it's not compatible with the latest version of the game or SMAPI (detected {ex.NounPhrase}). Please check for a newer version of the mod.");
#else
                        TrackSkip(metadata, $"it's no longer compatible (detected {ex.NounPhrase}). Please check for a newer version of the mod.");
#endif
                        continue;
                    }
                    catch (Exception ex)
                    {
                        TrackSkip(metadata, $"its DLL '{manifest.EntryDll}' couldn't be loaded:\n{ex.GetLogSummary()}");
                        continue;
                    }

                    // validate assembly
                    try
                    {
                        int modEntries = modAssembly.DefinedTypes.Count(type => typeof(Mod).IsAssignableFrom(type) && !type.IsAbstract);
                        if (modEntries == 0)
                        {
                            TrackSkip(metadata, $"its DLL has no '{nameof(Mod)}' subclass.");
                            continue;
                        }
                        if (modEntries > 1)
                        {
                            TrackSkip(metadata, $"its DLL contains multiple '{nameof(Mod)}' subclasses.");
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        TrackSkip(metadata, $"its DLL couldn't be loaded:\n{ex.GetLogSummary()}");
                        continue;
                    }

                    // initialise mod
                    try
                    {
                        // get implementation
                        TypeInfo modEntryType = modAssembly.DefinedTypes.First(type => typeof(Mod).IsAssignableFrom(type) && !type.IsAbstract);
                        Mod      mod          = (Mod)modAssembly.CreateInstance(modEntryType.ToString());
                        if (mod == null)
                        {
                            TrackSkip(metadata, "its entry class couldn't be instantiated.");
                            continue;
                        }

#if SMAPI_1_x
                        // prevent mods from using SMAPI 2.0 content interception before release
                        // ReSharper disable SuspiciousTypeConversion.Global
                        if (mod is IAssetEditor || mod is IAssetLoader)
                        {
                            TrackSkip(metadata, $"its entry class implements {nameof(IAssetEditor)} or {nameof(IAssetLoader)}. These are part of a prototype API that isn't available for mods to use yet.");
                        }
                        // ReSharper restore SuspiciousTypeConversion.Global
#endif

                        // inject data
                        {
                            IMonitor           monitor           = this.GetSecondaryMonitor(metadata.DisplayName);
                            ICommandHelper     commandHelper     = new CommandHelper(manifest.UniqueID, metadata.DisplayName, this.CommandManager);
                            IContentHelper     contentHelper     = new ContentHelper(contentManager, metadata.DirectoryPath, manifest.UniqueID, metadata.DisplayName, monitor);
                            IReflectionHelper  reflectionHelper  = new ReflectionHelper(manifest.UniqueID, this.Reflection);
                            IModRegistry       modRegistryHelper = new ModRegistryHelper(manifest.UniqueID, this.ModRegistry);
                            ITranslationHelper translationHelper = new TranslationHelper(manifest.UniqueID, manifest.Name, contentManager.GetLocale(), contentManager.GetCurrentLanguage());

                            mod.ModManifest = manifest;
                            mod.Helper      = new ModHelper(manifest.UniqueID, metadata.DirectoryPath, jsonHelper, contentHelper, commandHelper, modRegistryHelper, reflectionHelper, translationHelper);
                            mod.Monitor     = monitor;
#if SMAPI_1_x
                            mod.PathOnDisk = metadata.DirectoryPath;
#endif
                        }

                        // track mod
                        metadata.SetMod(mod);
                        this.ModRegistry.Add(metadata);
                    }
                    catch (Exception ex)
                    {
                        TrackSkip(metadata, $"initialisation failed:\n{ex.GetLogSummary()}");
                    }
                }
            }
            IModMetadata[] loadedMods = this.ModRegistry.GetMods().ToArray();

            // log skipped mods
#if !SMAPI_1_x
            this.Monitor.Newline();
#endif
            if (skippedMods.Any())
            {
                this.Monitor.Log($"Skipped {skippedMods.Count} mods:", LogLevel.Error);
                foreach (var pair in skippedMods.OrderBy(p => p.Key.DisplayName))
                {
                    IModMetadata mod    = pair.Key;
                    string       reason = pair.Value;

                    if (mod.Manifest?.Version != null)
                    {
                        this.Monitor.Log($"   {mod.DisplayName} {mod.Manifest.Version} because {reason}", LogLevel.Error);
                    }
                    else
                    {
                        this.Monitor.Log($"   {mod.DisplayName} because {reason}", LogLevel.Error);
                    }
                }
#if !SMAPI_1_x
                this.Monitor.Newline();
#endif
            }

            // log loaded mods
            this.Monitor.Log($"Loaded {loadedMods.Length} mods" + (loadedMods.Length > 0 ? ":" : "."), LogLevel.Info);
            foreach (IModMetadata metadata in loadedMods.OrderBy(p => p.DisplayName))
            {
                IManifest manifest = metadata.Manifest;
                this.Monitor.Log(
                    $"   {metadata.DisplayName} {manifest.Version}"
                    + (!string.IsNullOrWhiteSpace(manifest.Author) ? $" by {manifest.Author}" : "")
                    + (!string.IsNullOrWhiteSpace(manifest.Description) ? $" | {manifest.Description}" : ""),
                    LogLevel.Info
                    );
            }
#if !SMAPI_1_x
            this.Monitor.Newline();
#endif

            // initialise translations
            this.ReloadTranslations();

            // initialise loaded mods
            foreach (IModMetadata metadata in loadedMods)
            {
                // add interceptors
                if (metadata.Mod.Helper.Content is ContentHelper helper)
                {
                    this.ContentManager.Editors[metadata] = helper.ObservableAssetEditors;
                    this.ContentManager.Loaders[metadata] = helper.ObservableAssetLoaders;
                }

                // call entry method
                try
                {
                    IMod mod = metadata.Mod;
                    mod.Entry(mod.Helper);
#if SMAPI_1_x
                    (mod as Mod)?.Entry(); // deprecated since 1.0

                    // raise deprecation warning for old Entry() methods
                    if (this.DeprecationManager.IsVirtualMethodImplemented(mod.GetType(), typeof(Mod), nameof(Mod.Entry), new[] { typeof(object[]) }))
                    {
                        deprecationWarnings.Add(() => this.DeprecationManager.Warn(metadata.DisplayName, $"{nameof(Mod)}.{nameof(Mod.Entry)}(object[]) instead of {nameof(Mod)}.{nameof(Mod.Entry)}({nameof(IModHelper)})", "1.0", DeprecationLevel.PendingRemoval));
                    }
#else
                    if (!this.DeprecationManager.IsVirtualMethodImplemented(mod.GetType(), typeof(Mod), nameof(Mod.Entry), new[] { typeof(IModHelper) }))
                    {
                        this.Monitor.Log($"{metadata.DisplayName} doesn't implement Entry() and may not work correctly.", LogLevel.Error);
                    }
#endif
                }
                catch (Exception ex)
                {
                    this.Monitor.Log($"{metadata.DisplayName} failed on entry and might not work correctly. Technical details:\n{ex.GetLogSummary()}", LogLevel.Error);
                }
            }

            // reset cache when needed
            // only register listeners after Entry to avoid repeatedly reloading assets during load
            foreach (IModMetadata metadata in loadedMods)
            {
                if (metadata.Mod.Helper.Content is ContentHelper helper)
                {
                    // TODO: optimise by only reloading assets the new editors/loaders can intercept
                    helper.ObservableAssetEditors.CollectionChanged += (sender, e) =>
                    {
                        if (e.NewItems.Count > 0)
                        {
                            this.Monitor.Log("Detected new asset editor, resetting cache...", LogLevel.Trace);
                            this.ContentManager.InvalidateCache((key, type) => true);
                        }
                    };
                    helper.ObservableAssetLoaders.CollectionChanged += (sender, e) =>
                    {
                        if (e.NewItems.Count > 0)
                        {
                            this.Monitor.Log("Detected new asset loader, resetting cache...", LogLevel.Trace);
                            this.ContentManager.InvalidateCache((key, type) => true);
                        }
                    };
                }
            }
            this.Monitor.Log("Resetting cache to enable interception...", LogLevel.Trace);
            this.ContentManager.InvalidateCache((key, type) => true);
        }
コード例 #8
0
 public ModType(IMod mod)
 {
     m_modType = mod.GetType();
     m_modTypeName = TypeName;
 }
コード例 #9
0
 public ModType(IMod mod)
 {
     m_modType     = mod.GetType();
     m_modTypeName = TypeName;
 }
コード例 #10
0
ファイル: Mod.cs プロジェクト: LeviCline/osu
 public bool Equals(IMod other) => GetType() == other?.GetType();
コード例 #11
0
ファイル: Program.cs プロジェクト: sherlock221/SMAPI
        /// <summary>Load and hook up the given mods.</summary>
        /// <param name="mods">The mods to load.</param>
        /// <param name="jsonHelper">The JSON helper with which to read mods' JSON files.</param>
        /// <param name="contentManager">The content manager to use for mod content.</param>
        private void LoadMods(IModMetadata[] mods, JsonHelper jsonHelper, SContentManager contentManager)
        {
            this.Monitor.Log("Loading mods...", LogLevel.Trace);

            // load mod assemblies
            IDictionary <IModMetadata, string> skippedMods = new Dictionary <IModMetadata, string>();

            {
                void TrackSkip(IModMetadata mod, string reasonPhrase) => skippedMods[mod] = reasonPhrase;

                AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.TargetPlatform, this.Monitor);
                AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => modAssemblyLoader.ResolveAssembly(e.Name);
                foreach (IModMetadata metadata in mods)
                {
                    // get basic info
                    IManifest manifest     = metadata.Manifest;
                    string    assemblyPath = metadata.Manifest?.EntryDll != null
                        ? Path.Combine(metadata.DirectoryPath, metadata.Manifest.EntryDll)
                        : null;

                    this.Monitor.Log(assemblyPath != null
                        ? $"Loading {metadata.DisplayName} from {assemblyPath.Replace(Constants.ModPath, "").TrimStart(Path.DirectorySeparatorChar)}..."
                        : $"Loading {metadata.DisplayName}...", LogLevel.Trace);

                    // validate status
                    if (metadata.Status == ModMetadataStatus.Failed)
                    {
                        this.Monitor.Log($"   Failed: {metadata.Error}", LogLevel.Trace);
                        TrackSkip(metadata, metadata.Error);
                        continue;
                    }

                    // preprocess & load mod assembly
                    Assembly modAssembly;
                    try
                    {
                        modAssembly = modAssemblyLoader.Load(metadata, assemblyPath, assumeCompatible: metadata.DataRecord.GetCompatibility(metadata.Manifest.Version)?.Status == ModStatus.AssumeCompatible);
                    }
                    catch (IncompatibleInstructionException ex)
                    {
                        TrackSkip(metadata, $"it's no longer compatible (detected {ex.NounPhrase}). Please check for a newer version of the mod.");
                        continue;
                    }
                    catch (SAssemblyLoadFailedException ex)
                    {
                        TrackSkip(metadata, $"its DLL '{manifest.EntryDll}' couldn't be loaded: {ex.Message}");
                        continue;
                    }
                    catch (Exception ex)
                    {
                        TrackSkip(metadata, $"its DLL '{manifest.EntryDll}' couldn't be loaded:\n{ex.GetLogSummary()}");
                        continue;
                    }

                    // validate assembly
                    try
                    {
                        int modEntries = modAssembly.DefinedTypes.Count(type => typeof(Mod).IsAssignableFrom(type) && !type.IsAbstract);
                        if (modEntries == 0)
                        {
                            TrackSkip(metadata, $"its DLL has no '{nameof(Mod)}' subclass.");
                            continue;
                        }
                        if (modEntries > 1)
                        {
                            TrackSkip(metadata, $"its DLL contains multiple '{nameof(Mod)}' subclasses.");
                            continue;
                        }
                    }
                    catch (Exception ex)
                    {
                        TrackSkip(metadata, $"its DLL couldn't be loaded:\n{ex.GetLogSummary()}");
                        continue;
                    }

                    // initialise mod
                    try
                    {
                        // get implementation
                        TypeInfo modEntryType = modAssembly.DefinedTypes.First(type => typeof(Mod).IsAssignableFrom(type) && !type.IsAbstract);
                        Mod      mod          = (Mod)modAssembly.CreateInstance(modEntryType.ToString());
                        if (mod == null)
                        {
                            TrackSkip(metadata, "its entry class couldn't be instantiated.");
                            continue;
                        }

                        // inject data
                        {
                            IMonitor           monitor           = this.GetSecondaryMonitor(metadata.DisplayName);
                            ICommandHelper     commandHelper     = new CommandHelper(manifest.UniqueID, metadata.DisplayName, this.CommandManager);
                            IContentHelper     contentHelper     = new ContentHelper(contentManager, metadata.DirectoryPath, manifest.UniqueID, metadata.DisplayName, monitor);
                            IReflectionHelper  reflectionHelper  = new ReflectionHelper(manifest.UniqueID, metadata.DisplayName, this.Reflection);
                            IModRegistry       modRegistryHelper = new ModRegistryHelper(manifest.UniqueID, this.ModRegistry);
                            ITranslationHelper translationHelper = new TranslationHelper(manifest.UniqueID, manifest.Name, contentManager.GetLocale(), contentManager.GetCurrentLanguage());

                            mod.ModManifest = manifest;
                            mod.Helper      = new ModHelper(manifest.UniqueID, metadata.DirectoryPath, jsonHelper, contentHelper, commandHelper, modRegistryHelper, reflectionHelper, translationHelper);
                            mod.Monitor     = monitor;
                        }

                        // track mod
                        metadata.SetMod(mod);
                        this.ModRegistry.Add(metadata);
                    }
                    catch (Exception ex)
                    {
                        TrackSkip(metadata, $"initialisation failed:\n{ex.GetLogSummary()}");
                    }
                }
            }
            IModMetadata[] loadedMods = this.ModRegistry.GetMods().ToArray();

            // log skipped mods
            this.Monitor.Newline();
            if (skippedMods.Any())
            {
                this.Monitor.Log($"Skipped {skippedMods.Count} mods:", LogLevel.Error);
                foreach (var pair in skippedMods.OrderBy(p => p.Key.DisplayName))
                {
                    IModMetadata mod    = pair.Key;
                    string       reason = pair.Value;

                    if (mod.Manifest?.Version != null)
                    {
                        this.Monitor.Log($"   {mod.DisplayName} {mod.Manifest.Version} because {reason}", LogLevel.Error);
                    }
                    else
                    {
                        this.Monitor.Log($"   {mod.DisplayName} because {reason}", LogLevel.Error);
                    }
                }
                this.Monitor.Newline();
            }

            // log loaded mods
            this.Monitor.Log($"Loaded {loadedMods.Length} mods" + (loadedMods.Length > 0 ? ":" : "."), LogLevel.Info);
            foreach (IModMetadata metadata in loadedMods.OrderBy(p => p.DisplayName))
            {
                IManifest manifest = metadata.Manifest;
                this.Monitor.Log(
                    $"   {metadata.DisplayName} {manifest.Version}"
                    + (!string.IsNullOrWhiteSpace(manifest.Author) ? $" by {manifest.Author}" : "")
                    + (!string.IsNullOrWhiteSpace(manifest.Description) ? $" | {manifest.Description}" : ""),
                    LogLevel.Info
                    );
            }
            this.Monitor.Newline();

            // initialise translations
            this.ReloadTranslations();

            // initialise loaded mods
            foreach (IModMetadata metadata in loadedMods)
            {
                // add interceptors
                if (metadata.Mod.Helper.Content is ContentHelper helper)
                {
                    this.ContentManager.Editors[metadata] = helper.ObservableAssetEditors;
                    this.ContentManager.Loaders[metadata] = helper.ObservableAssetLoaders;
                }

                // call entry method
                try
                {
                    IMod mod = metadata.Mod;
                    mod.Entry(mod.Helper);
                    if (!this.DeprecationManager.IsVirtualMethodImplemented(mod.GetType(), typeof(Mod), nameof(Mod.Entry), new[] { typeof(IModHelper) }))
                    {
                        this.Monitor.Log($"{metadata.DisplayName} doesn't implement Entry() and may not work correctly.", LogLevel.Error);
                    }
                }
                catch (Exception ex)
                {
                    this.Monitor.Log($"{metadata.DisplayName} failed on entry and might not work correctly. Technical details:\n{ex.GetLogSummary()}", LogLevel.Error);
                }
            }

            // invalidate cache entries when needed
            // (These listeners are registered after Entry to avoid repeatedly reloading assets as mods initialise.)
            foreach (IModMetadata metadata in loadedMods)
            {
                if (metadata.Mod.Helper.Content is ContentHelper helper)
                {
                    helper.ObservableAssetEditors.CollectionChanged += (sender, e) =>
                    {
                        if (e.NewItems.Count > 0)
                        {
                            this.Monitor.Log("Invalidating cache entries for new asset editors...", LogLevel.Trace);
                            this.ContentManager.InvalidateCacheFor(e.NewItems.Cast <IAssetEditor>().ToArray(), new IAssetLoader[0]);
                        }
                    };
                    helper.ObservableAssetLoaders.CollectionChanged += (sender, e) =>
                    {
                        if (e.NewItems.Count > 0)
                        {
                            this.Monitor.Log("Invalidating cache entries for new asset loaders...", LogLevel.Trace);
                            this.ContentManager.InvalidateCacheFor(new IAssetEditor[0], e.NewItems.Cast <IAssetLoader>().ToArray());
                        }
                    };
                }
            }

            // reset cache now if any editors or loaders were added during entry
            IAssetEditor[] editors = loadedMods.SelectMany(p => ((ContentHelper)p.Mod.Helper.Content).AssetEditors).ToArray();
            IAssetLoader[] loaders = loadedMods.SelectMany(p => ((ContentHelper)p.Mod.Helper.Content).AssetLoaders).ToArray();
            if (editors.Any() || loaders.Any())
            {
                this.Monitor.Log("Invalidating cached assets for new editors & loaders...", LogLevel.Trace);
                this.ContentManager.InvalidateCacheFor(editors, loaders);
            }
        }
コード例 #12
0
        public static IMod LoadMod(IMod mod)
        {
            if (mod == null)
            {
                return(null);
            }
            var modType = mod.GetType();
            var attrib  = modType.GetFirstAttribute <ALoadOrderAttribute>();
            var name    = mod.GetCleanId();

            if (attrib != null)
            {
                foreach (var pair in ModIdReliance.ToArray())
                {
                    var i = pair.Value.FindIndex(m => m.GetCleanId() == name);
                    if (i != -1)
                    {
                        ModIdReliance[pair.Key][i] = mod;
                    }
                }
                foreach (var id in attrib.beforeIds)
                {
                    if (!ModIdReliance.ContainsKey(id.GetCleanId()))
                    {
                        ModIdReliance.Add(id, new List <IMod>());
                    }
                    if (!ModIdReliance[id].Contains(mod))
                    {
                        ModIdReliance[id].Add(mod);
                    }
                }
                foreach (var id in attrib.afterIds)
                {
                    if (!ModIdReliance.ContainsKey(name))
                    {
                        ModIdReliance.Add(name, new List <IMod>());
                    }
                    if (ModIdReliance[name].FindIndex(m => m.GetCleanId() == id.GetCleanId()) != -1)
                    {
                        ModIdReliance[name].Add(new Placeholder(id.GetCleanId()));
                    }
                }
                if (attrib.beforeIds.Count > 0)
                {
                    return(mod);
                }
            }
            try
            {
                if (!Pathfinder.IsModIdentifierValid(name, true))
                {
                    return(null); // never reached due to throw
                }
                Logger.Info("Loading mod '{0}'", name);
                CurrentMod = mod;
                mod.Load();
                UnloadedModIds.Remove(name);
                LoadedMods.Add(name, mod);
                GUI.ModOptions.Handler.LoadFor(mod);
                if (ModIdReliance.ContainsKey(name))
                {
                    foreach (var internalMod in ModIdReliance[name])
                    {
                        LoadMod(internalMod);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Mod '{0}' of file '{1}' failed to load:\n\t{2}", modType.FullName, Path.GetFileName(modType.Assembly.Location), ex);
                UnloadMod(mod);
                UnloadedModIds.Remove(name);
                CurrentMod = null;
                return(null);
            }
            CurrentMod = null;
            return(mod);
        }
コード例 #13
0
        public static void UnloadMod(IMod mod)
        {
            if (mod == null || mod is Placeholder)
            {
                return;
            }

            CurrentMod = mod;
            var name = Utility.ActiveModId;

            var attrib = mod.GetType().GetFirstAttribute <ALoadOrderAttribute>();

            if (attrib != null)
            {
                foreach (var ident in attrib.afterIds)
                {
                    var id = ident.GetCleanId();
                    if (LoadedMods.ContainsKey(id) &&
                        LoadedMods[id].GetType().GetFirstAttribute <AllowOrderUnloadAttribute>()?.Allowed == true)
                    {
                        UnloadMod(LoadedMods[id]);
                    }
                }
            }

            foreach (var e in
                     (from p in Extension.Handler.ModExtensions
                      where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                      select p.Key)
                     .ToArray()
                     )
            {
                Extension.Handler.UnregisterExtension(e);
            }

            foreach (var e in
                     (from p in Executable.Handler.ModExecutables
                      where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                      select p.Key)
                     .ToArray()
                     )
            {
                Executable.Handler.UnregisterExecutable(e);
            }

            foreach (var d in
                     (from p in Daemon.Handler.ModDaemons
                      where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                      select p.Key)
                     .ToArray()
                     )
            {
                Daemon.Handler.UnregisterDaemon(d);
            }

            List <string> clist;

            Command.Handler.ModIdToCommandKeyList.TryGetValue(name, out clist);
            if (clist != null)
            {
                foreach (var c in clist.ToArray())
                {
                    Command.Handler.UnregisterCommand(c);
                }
            }

            foreach (var g in
                     (from p in Mission.Handler.ModGoals
                      where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                      select p.Key)
                     .ToArray()
                     )
            {
                Mission.Handler.UnregisterMissionGoal(g);
            }

            foreach (var m in
                     (from p in Mission.Handler.ModMissions
                      where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                      select p.Key)
                     .ToArray()
                     )
            {
                Mission.Handler.UnregisterMission(m);
            }

            foreach (var p in
                     (from p in Port.Handler.PortTypes
                      where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                      select p.Key)
                     .ToArray()
                     )
            {
                Port.Handler.UnregisterPort(p);
            }

            var events = new List <Tuple <Action <PathfinderEvent>, string, string, int> >();

            foreach (var v in EventManager.eventListeners.Values)
            {
                events.AddRange(v.FindAll(t => t.Item3 == name));
            }
            foreach (var list in EventManager.eventListeners.ToArray())
            {
                foreach (var e in events)
                {
                    list.Value.Remove(e);
                }
            }

            GUI.ModOptions.Handler.ModOptions.Remove(name);

            mod.Unload();
            UnloadedModIds.Add(name);
            LoadedMods.Remove(name);
            CurrentMod = null;
        }
コード例 #14
0
ファイル: Mod.cs プロジェクト: Rychard/Faark.Gnomoria.Modding
 public ModDependency(IMod mod):base(mod)
 {
     MaxVersion = MinVersion = mod.GetType().Assembly.GetName().Version;
 }
コード例 #15
0
ファイル: ModRegistry.cs プロジェクト: LeonBlade/SMAPI
 /****
 ** Internal methods
 ****/
 /// <summary>Register a mod as a possible source of deprecation warnings.</summary>
 /// <param name="mod">The mod instance.</param>
 public void Add(IMod mod)
 {
     this.Mods.Add(mod);
     this.ModNamesByAssembly[mod.GetType().Assembly.FullName] = mod.ModManifest.Name;
 }
コード例 #16
0
 public ModDependency(IMod mod) : base(mod)
 {
     MaxVersion = MinVersion = mod.GetType().Assembly.GetName().Version;
 }
コード例 #17
0
ファイル: Manager.cs プロジェクト: feliers/Hacknet-Pathfinder
        public static void UnloadMod(IMod mod)
        {
            if (mod == null || mod is Placeholder)
            {
                return;
            }

            using (var _ = new CurrentModOverride(mod))
            {
                var name = Utility.ActiveModId;

                var attrib = mod.GetType().GetFirstAttribute <ModInfoAttribute>();
                if (attrib != null)
                {
                    foreach (var ident in attrib.AfterIds)
                    {
                        var id = ident.GetCleanId();
                        if (LoadedMods.ContainsKey(id) &&
                            LoadedMods[id].GetType().GetFirstAttribute <AllowOrderUnloadAttribute>()?.Allowed == true)
                        {
                            UnloadMod(LoadedMods[id]);
                        }
                    }
                }

                foreach (var e in
                         (from p in Extension.Handler.ModExtensions
                          where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                          select p.Key)
                         .ToArray()
                         )
                {
                    Logger.Verbose($"Unloading Extension '{e}'");
                    Extension.Handler.UnregisterExtension(e);
                }

                foreach (var e in
                         (from p in Executable.Handler.ModExecutables
                          where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                          select p.Key)
                         .ToArray()
                         )
                {
                    Logger.Verbose($"Unloading Executable '{e}'");
                    Executable.Handler.UnregisterExecutable(e);
                }

                foreach (var d in
                         (from p in Daemon.Handler.ModDaemons
                          where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                          select p.Key)
                         .ToArray()
                         )
                {
                    Logger.Verbose($"Unloading Daemon '{d}'");
                    Daemon.Handler.UnregisterDaemon(d);
                }

                Command.Handler.ModIdToCommandKeyList.TryGetValue(name, out List <string> clist);
                if (clist != null)
                {
                    foreach (var c in clist.ToArray())
                    {
                        Logger.Verbose($"Unloading Command '{c}'");
                        Command.Handler.UnregisterCommand(c);
                    }
                }

                foreach (var p in
                         (from p in Port.Handler.PortTypes
                          where p.Key.IndexOf('.') != -1 && p.Key.Remove(p.Key.IndexOf('.')) == name
                          select p.Key)
                         .ToArray()
                         )
                {
                    Logger.Verbose($"Unloading PortType '{p}'");
                    Port.Handler.UnregisterPort(p);
                }

                foreach (var pair in EventManager.eventListeners.Reverse())
                {
                    var listenerObjs = pair.Value.FindAll(l => l.ModId == name);
                    foreach (var obj in listenerObjs)
                    {
                        Logger.Verbose($"Unloading Event Listener '{obj.Options.DebugName}'");
                        EventManager.UnregisterListener(pair.Key, obj);
                    }
                }

                GUI.ModOptions.Handler.ModOptions.Remove(name);
                mod.Unload();
                UnloadedModIds.Add(name);
                LoadedMods.Remove(name);
            }
        }
コード例 #18
0
ファイル: ModDataSaving.cs プロジェクト: wty0512/Gnomodia
 /*
  * public void GetObjectData(SerializationInfo info, StreamingContext context)
  * {
  *  info.AddValue("ModType", ModType);
  *  info.AddValue("Data", data.Select(kvp => new msd_dataItem() { key = kvp.Key, value = kvp.Value }).ToArray());
  *  return;
  * }
  */
 public ModSaveData(IMod mod)
 {
     ModType   = mod.GetType().FullName;
     LoadedMod = mod;
 }
コード例 #19
0
ファイル: Manager.cs プロジェクト: feliers/Hacknet-Pathfinder
        public static IMod LoadMod(IMod mod)
        {
            if (mod == null)
            {
                return(null);
            }
            var modType = mod.GetType();
            var attrib  = modType.GetFirstAttribute <ModInfoAttribute>();
            var name    = mod.GetCleanId();

            if (attrib != null)
            {
                foreach (var pair in ModIdReliance.ToArray())
                {
                    var i = pair.Value.FindIndex(m => m.GetCleanId() == name);
                    if (i != -1)
                    {
                        ModIdReliance[pair.Key][i] = mod;
                    }
                }
                foreach (var id in attrib.BeforeIds)
                {
                    if (!ModIdReliance.ContainsKey(id.GetCleanId()))
                    {
                        ModIdReliance.Add(id, new List <IMod>());
                    }
                    if (!ModIdReliance[id].Contains(mod))
                    {
                        ModIdReliance[id].Add(mod);
                    }
                }
                foreach (var id in attrib.AfterIds)
                {
                    if (!ModIdReliance.ContainsKey(name))
                    {
                        ModIdReliance.Add(name, new List <IMod>());
                    }
                    if (ModIdReliance[name].FindIndex(m => m.GetCleanId() == id.GetCleanId()) != -1)
                    {
                        ModIdReliance[name].Add(new Placeholder(id.GetCleanId()));
                    }
                }
                if (attrib.BeforeIds.Count > 0)
                {
                    return(mod);
                }
            }
            try
            {
                if (!Pathfinder.IsModIdentifierValid(name, true))
                {
                    return(null); // never reached due to throw
                }
                Logger.Info("Loading mod '{0}'", name);
                using (var _ = new CurrentModOverride(mod))
                {
                    if (ModAttributeHandler.ModToEventMethods.TryGetValue(CurrentMod.GetType(), out var infos))
                    {
                        foreach (var i in infos)
                        {
                            var eventAttrib = i.GetFirstAttribute <EventAttribute>();
                            var paramType   = i.GetParameters()[0].ParameterType;
                            EventManager.RegisterListener(paramType, i.CreateDelegate <Action <PathfinderEvent> >(typeof(Action <>).MakeGenericType(paramType)), eventAttrib.Options);
                        }
                    }
                    mod.Load();
                    UnloadedModIds.Remove(name);
                    LoadedMods.Add(name, mod);
                    GUI.ModOptions.Handler.LoadFor(mod);
                    if (ModIdReliance.ContainsKey(name))
                    {
                        foreach (var internalMod in ModIdReliance[name])
                        {
                            LoadMod(internalMod);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("Mod '{0}' of file '{1}' failed to load:\n\t{2}", modType.FullName, Path.GetFileName(modType.Assembly.Location), ex);
                UnloadMod(mod);
                UnloadedModIds.Remove(name);
                return(null);
            }
            return(mod);
        }