/// <summary> /// Initializes the method information. /// </summary> /// <exception cref="System.NullReferenceException">Method info not returned.</exception> private void InitMethodInfo() { if (!this.methodInfoInitialized) { //Log.DevDebug(this, "InitMethodInfo"); try { this.methodInfo = MonoDetour.FindMethod(this.SourceClass, this.MethodName, this.GetType(), this.SignatureMethodName); if (this.methodInfo == null) { throw new NullReferenceException("Method info not returned"); } } catch (Exception ex) { Log.Error(this, "InitMethodInfo", ex, this.MethodName, this.GetType(), this.SignatureMethodName); this.methodInfo = null; } finally { this.methodInfoInitialized = true; } } }
/// <summary> /// Gets the information for the method in the source class. /// </summary> /// <param name="sourceClass">The source class.</param> /// <returns>The method information.</returns> /// <exception cref="System.NullReferenceException">Method info not returned.</exception> private MethodInfo GetMethodInfo(Type sourceClass) { if (!Global.Settings.AllowReflection(this.MinGameVersion, this.MaxGameVersion)) { return(null); } if (this.AppliesToCLass(sourceClass)) { MethodInfo methodInfo; if (this.methods.TryGetValue(sourceClass, out methodInfo)) { return(methodInfo); } try { Log.DevDebug(this, "GetMethodInfo", sourceClass); methodInfo = MonoDetour.FindMethod(sourceClass, this.MethodName, this.GetType(), this.SignatureMethodName); if (methodInfo == null) { throw new NullReferenceException("Method info not returned"); } this.methods[sourceClass] = methodInfo; return(methodInfo); } catch (Exception ex) { Log.Warning(this, "GetMethodInfo", "Failed", sourceClass, ex.GetType(), ex.Message); this.methods[sourceClass] = null; return(null); } } if (!this.unhandledClasses.Contains(sourceClass)) { this.unhandledClasses.Add(sourceClass); Log.Warning(this, "GetMethodInfo", "Failed", sourceClass); } return(null); }
/// <summary> /// Detours the method. /// </summary> public void Detour() { if (this.CanDetour) { bool revert = false; foreach (Type originalClass in this.detours.Keys) { if (this.CanDetourClass(originalClass) && !this.detours[originalClass].Error) { MonoDetour detour = null; try { detour = this.detours[originalClass].Detour; Log.DevDebug(this, "Detour", originalClass, detour); if (detour == null) { detour = new MonoDetour(originalClass, this.GetType(), this.OriginalMethodName, this.ReplacementMethodName); this.detours[originalClass].Detour = detour; Log.DevDebug(this, "Detour", "Created", originalClass, detour); } if (!detour.IsDetoured) { detour.Detour(); Log.Info(this, "Detour", "Detoured", originalClass, this.OriginalMethodName, this.ReplacementMethodName); } } catch (Exception ex) { if (detour != null) { try { detour.Revert(); } catch { } } this.detours[originalClass].Detour = null; this.detours[originalClass].Error = true; if (originalClass == this.OriginalClassType) { this.error = true; revert = true; Log.Error(this, "Detour", ex, originalClass); } else { Log.DevDebug(this, "Detour", "NoDetour", ex.GetType(), ex.Message); } } } } if (revert) { this.Revert(); } } }