Beispiel #1
0
        /// <summary>
        /// Registers an assembly as loaded by a particular mod.
        /// </summary>
        /// <param name="assembly">The assembly to register.</param>
        /// <param name="owner">The owning mod.</param>
        internal void RegisterAssembly(Assembly assembly, ModDebugInfo owner)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly));
            }
            if (owner == null)
            {
                throw new ArgumentNullException(nameof(owner));
            }
            string fullName = assembly.FullName;
            var    oldMod   = modAssemblies.GetOrAdd(fullName, owner);

            if (oldMod != owner)
            {
                // Possible if multiple mods include the same dependency DLL
                DebugLogger.LogDebug("Assembly \"{0}\" is used by multiple mods:", fullName);
                DebugLogger.LogDebug("First loaded by {0} (used), also loaded by {1} (ignored)",
                                     oldMod.ModName, owner.ModName);
            }
            else
            {
                owner.ModAssemblies.Add(assembly);
            }
        }
Beispiel #2
0
 /// <summary>
 /// Retrieves the debug information for the specified mod, registering it if it has
 /// not been seen before.
 /// </summary>
 /// <param name="mod">The mod to retrieve.</param>
 /// <returns>The debug information about that mod.</returns>
 internal ModDebugInfo GetDebugInfo(Mod mod)
 {
     if (mod == null)
     {
         throw new ArgumentNullException(nameof(mod));
     }
     return(debugInfo.GetOrAdd(ModDebugInfo.GetIdentifier(mod), (_) =>
                               new ModDebugInfo(mod)));
 }
Beispiel #3
0
        /// <summary>
        /// Returns the owning mod of the specified assembly. Returns null if no mod appears to
        /// own this assembly.
        /// </summary>
        /// <param name="assembly">The assembly to query.</param>
        /// <returns>The owning mod, or null if no owning mod could be determined.</returns>
        internal ModDebugInfo OwnerOfAssembly(Assembly assembly)
        {
            ModDebugInfo mod = null;

            if (assembly != null)
            {
                modAssemblies.TryGetValue(assembly.FullName, out mod);
            }
            return(mod);
        }
Beispiel #4
0
        /// <summary>
        /// Disables the offending mod and restarts the game.
        /// </summary>
        /// <param name="info">The mod to disable, or null to not disable any mods.</param>
        private static void DisableAndRestart(ModDebugInfo info)
        {
            var manager = Global.Instance.modManager;

            if (info != null)
            {
                manager.EnableMod(info.Mod.label, false, manager);
                manager.Save();
            }
            App.instance.Restart();
        }
Beispiel #5
0
        /// <summary>
        /// Gets the mod that most recently appeared on the provided call stack.
        /// </summary>
        /// <param name="stackTrace">The call stack of the exception thrown.</param>
        /// <returns>The mod that is most likely at fault, or null if no mods appear on the stack.</returns>
        internal static ModDebugInfo GetFirstModOnCallStack(this StackTrace stackTrace)
        {
            ModDebugInfo mod = null;

            if (stackTrace != null)
            {
                var registry = ModDebugRegistry.Instance;
                int n        = stackTrace.FrameCount;
                // Search for first method that has a mod in the registry
                for (int i = 0; i < n && mod == null; i++)
                {
                    var method = stackTrace.GetFrame(i)?.GetMethod();
                    if (method != null)
                    {
                        mod = registry.OwnerOfType(method.DeclaringType);
                    }
                }
            }
            return(mod);
        }