private static Harmony CreateHarmony(string harmonyId)
        {
            var              stack              = new StackTrace();
            var              lastCaller         = stack.GetFrame(0).GetMethod();
            MethodBase       caller             = lastCaller;
            int              assemblyDepth      = 0;
            SameAssemblyName assemblyComparator = new SameAssemblyName(true, false, true, true);

            /* Search in the stack for the assembly that called
             * my caller(0Harmony 1.x)
             */
            for (int i = 1; i < stack.FrameCount && assemblyDepth < 2; ++i)
            {
                caller = stack.GetFrame(i).GetMethod();
                if (!assemblyComparator.Equals(lastCaller.DeclaringType.Assembly.GetName(), caller.DeclaringType.Assembly.GetName()))
                {
                    lastCaller = caller;
                    ++assemblyDepth;
                }
            }

            if (!Harmony.harmonyUsers.TryGetValue(caller.DeclaringType.Assembly.FullName, out var userStatus))
            {
                Harmony.harmonyUsers[caller.DeclaringType.Assembly.FullName] = new Harmony.HarmonyUser()
                {
                    checkBeforeUse = false, legacyCaller = true, instancesCreated = 0,
                };
            }
            return(new Harmony(harmonyId, caller));
        }
Ejemplo n.º 2
0
        internal ModReport(PluginInfo p, HashSet <AssemblyName> haveAssemblies, HarmonyModSupportException unsupportedLibs = null, bool enumerated = true)
        {
            plugin       = p;
            isEnumerated = enumerated;

            SameAssemblyName sameName = new SameAssemblyName();

            if (p.assemblyCount != 0)
            {
                p.GetAssemblies()
                .Do((assembly) =>
                {
                    var refs = assembly.GetReferencedAssemblies();
                    foreach (var assemblyName in refs)
                    {
                        switch (assemblyName.Name)
                        {
                        case "0Harmony":
                            needsHarmony  = assemblyName.Version;
                            m_usesHarmony = true;
                            break;

                        case "CitiesHarmony.API":
                            needsHarmonyAPI = assemblyName.Version;
                            m_usesHarmony   = true;
                            break;

                        case "CitiesHarmony.Harmony":
                            needsNewHarmony = assemblyName.Version;
                            m_usesHarmony   = true;
                            break;
                        }

                        if (!haveAssemblies.Contains(assemblyName))
                        {
                            m_missingAssemblies.Add(assemblyName);
                        }

                        if (unsupportedLibs != null)
                        {
                            unsupportedLibs.unsupportedAssemblies.ForEach((u) =>
                            {
                                if (sameName.Equals(u.assembly.GetName(), assemblyName))
                                {
                                    ReportProblem(ModReport.ProblemType.ExceptionThrown, unsupportedLibs, u.Message);
                                }
                            });
                        }
                    }
                });
            }
        }
Ejemplo n.º 3
0
        void ProhibitRemovingHarmony(MethodBase orginal, MethodBase caller, MethodInfo patchMethod)
        {
            SameAssemblyName sameAssembly = new SameAssemblyName();
            var myAssembly = Assembly.GetExecutingAssembly();

            if (sameAssembly.Equals(patchMethod.DeclaringType.Assembly.GetName(), myAssembly.GetName()) &&
                !sameAssembly.Equals(caller.DeclaringType.Assembly.GetName(), myAssembly.GetName()))
            {
                throw new HarmonyModACLException($"(Un)Patching {Versioning.PACKAGE_NAME} is prohibited");
            }
#if HEAVY_TRACE
            UnityEngine.Debug.Log($"[{Versioning.FULL_PACKAGE_NAME}] UnpatchACL allows because caller is self or patch is not mine.");
#endif
        }
Ejemplo n.º 4
0
        internal void ReportUnsupportedHarmony(HarmonyModSupportException e)
        {
            SameAssemblyName sameName = new SameAssemblyName();

            Array.ForEach(plugin.userModInstance.GetType().Assembly.GetReferencedAssemblies(),
                          (refa) =>
            {
                e.unsupportedAssemblies.ForEach((u) =>
                {
                    if (sameName.Equals(u.assembly.GetName(), refa))
                    {
                        ReportProblem(ModReport.ProblemType.ExceptionThrown, e, u.Message);
                    }
                });
            });
        }
Ejemplo n.º 5
0
        void ProhibitPatchingHarmony(MethodBase original, MethodBase caller)
        {
            SameAssemblyName sameAssembly = new SameAssemblyName();
            var myAssembly = Assembly.GetExecutingAssembly();

            if (sameAssembly.Equals(caller.DeclaringType.Assembly.GetName(), myAssembly.GetName()))
            {
                return;
            }
            var originalAssemblyName           = original.DeclaringType.Assembly.GetName();
            SameAssemblyName signatureComparer = new SameAssemblyName(false, true, false, false);

            if (signatureComparer.Equals(originalAssemblyName, myAssembly.GetName()) || originalAssemblyName.Name == "0Harmony")
            {
                throw new HarmonyModACLException($"(Un)Patching {Versioning.PACKAGE_NAME} is prohibited");
            }
        }