Пример #1
0
        /// <summary>
        /// Registers a class containing methods for [PLibPatch] and [PLibMethod] handlers.
        /// All methods, public and private, of the type will be searched for annotations.
        /// However, nested and derived types will not be searched, nor will inherited methods.
        ///
        /// This method cannot be used to register a class from another mod, as the annotations
        /// on those methods would have a different assembly qualified name and would thus
        /// not be recognized.
        /// </summary>
        /// <param name="type">The type to register.</param>
        public static void RegisterPatchClass(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            // Some others used this call before the library was initialized
            if (!PLibInit)
            {
                InitLibrary(false);
                LogWarning("PUtil.InitLibrary was not called before using RegisterPatchClass!");
            }
            int count = 0;

            foreach (var method in type.GetMethods(PPatchManager.FLAGS | BindingFlags.Static))
            {
                foreach (var attrib in method.GetCustomAttributes(true))
                {
                    if (attrib is IPLibAnnotation pm)
                    {
                        PPatchManager.AddHandler(pm.Runtime, pm.CreateInstance(method));
                        count++;
                    }
                }
            }
            if (count > 0)
            {
                PRegistry.LogPatchDebug("Registered {0:D} handler(s) for {1}".F(count,
                                                                                Assembly.GetCallingAssembly().GetNameSafe() ?? "?"));
            }
            else
            {
                PRegistry.LogPatchWarning("RegisterPatchClass could not find any handlers!");
            }
        }
Пример #2
0
#pragma warning restore IDE0051 // Remove unused private members

        #endregion

        #region Infrastructure

        /// <summary>
        /// Returns a patch method from this class. It must be static.
        /// </summary>
        /// <param name="name">The patch method name.</param>
        /// <returns>The matching method.</returns>
        private static HarmonyMethod PatchMethod(string name)
        {
            var method = typeof(PLibPatches).GetMethod(name, BindingFlags.
                                                       NonPublic | BindingFlags.Static);

            if (method == null)
            {
                PRegistry.LogPatchWarning("No PLibPatches method found: " + name);
            }
            return(new HarmonyMethod(method));
        }
Пример #3
0
        /// <summary>
        /// Executes all post-load handlers.
        /// </summary>
        internal static void ExecutePostload()
        {
            IList <PostLoadHandler> postload = null;

            lock (PSharedData.GetLock(PRegistry.KEY_POSTLOAD_LOCK)) {
                // Get list holding postload information
                var list = PSharedData.GetData <IList <PostLoadHandler> >(PRegistry.
                                                                          KEY_POSTLOAD_TABLE);
                if (list != null)
                {
                    postload = new List <PostLoadHandler>(list);
                }
            }
            // If there were any, run them
            if (postload != null)
            {
                var hInst = Harmony.HarmonyInstance.Create("PLib.PostLoad");
                PRegistry.LogPatchDebug("Executing {0:D} post-load handler(s)".F(postload.
                                                                                 Count));
                foreach (var handler in postload)
                {
                    try {
                        handler?.Invoke(hInst);
                    } catch (Exception e) {
                        var method = handler.Method;
                        // Say which mod's postload crashed
                        if (method != null)
                        {
                            PRegistry.LogPatchWarning("Postload handler for {0} failed:".F(
                                                          method.DeclaringType.Assembly?.GetName()?.Name ?? "?"));
                        }
                        LogException(e);
                    }
                }
            }
        }