Beispiel #1
0
        public static bool Init(bool forceLoad = true, Type type = Type.Auto) {
            if (_HarmonyASM == null)
                _HarmonyASM = _FindHarmony();
            if (_HarmonyASM == null && forceLoad)
                _HarmonyASM = Assembly.Load(new AssemblyName() {
                    Name = "0Harmony"
                });
            if (_HarmonyASM == null)
                return false;

            if (Initialized)
                return true;
            Initialized = true;

            if (type == Type.Auto)
                type = Type.AsOriginal;

            _DetourConfig = new DetourConfig() {
                Priority =
                    type == Type.AsOriginal ? int.MinValue / 4 :
                    type == Type.Override ? int.MaxValue / 4 :
                    0
            };

            CurrentType = type;

            try {
                foreach (MethodInfo methodRD in typeof(HarmonyDetourBridge).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)) {
                    bool critical = methodRD.GetCustomAttributes(typeof(CriticalAttribute), false).Any();

                    foreach (DetourToRDAttribute info in methodRD.GetCustomAttributes(typeof(DetourToRDAttribute), false))
                        foreach (MethodInfo methodH in GetHarmonyMethod(methodRD, info.Type, info.SkipParams, info.Name)) {
                            critical = false;
                            _Detours.Add(new Hook(methodH, methodRD));
                        }

                    foreach (DetourToHAttribute info in methodRD.GetCustomAttributes(typeof(DetourToHAttribute), false))
                        foreach (MethodInfo methodH in GetHarmonyMethod(methodRD, info.Type, info.SkipParams, info.Name)) {
                            critical = false;
                            _Detours.Add(new Detour(methodRD, methodH));
                        }

                    foreach (TranspileAttribute info in methodRD.GetCustomAttributes(typeof(TranspileAttribute), false)) {
                        foreach (MethodInfo methodH in GetHarmonyMethod(methodRD, info.Type, -1, info.Name)) {
                            using (DynamicMethodDefinition dmd = new DynamicMethodDefinition(methodH)) {
                                critical = false;
                                ILContext il = new ILContext(dmd.Definition) {
                                    ReferenceBag = RuntimeILReferenceBag.Instance
                                };
                                _Detours.Add(il);
                                il.Invoke((ILContext.Manipulator) methodRD.CreateDelegate<ILContext.Manipulator>());
                                if (il.IsReadOnly) {
                                    il.Dispose();
                                    _Detours.Remove(il);
                                    continue;
                                }
                                _Detours.Add(new Detour(methodH, dmd.Generate()));
                            }
                        }
                    }

                    if (critical)
                        throw new Exception($"Cannot apply HarmonyDetourBridge rule {methodRD.Name}");
                }
            } catch {
                _EarlyReset();
                throw;
            }
 
            return true;
        }