private static void DetourMethodByAttribute(MemberInfo info, Attribute attrib) { var detourAttribute = attrib as DetourMethodAttribute; var destination = info as MethodInfo; if (destination == null || detourAttribute == null) { throw new Exception("Null or unexpected argument types!"); } var pair = new DetourPair(); try { try { pair = GetDetourPairFromAttribute(detourAttribute, destination); DetourProvider.CompatibleDetourWithExceptions(pair.source, pair.destination); } catch (Exception e) { DetourProvider.ThrowClearerDetourException(e, pair.source, info, "method"); } } catch (Exception e) { if (!TryCallDetourFallbackHandler(pair.source, destination, e)) { HugsLibController.Logger.ReportException(e); } } }
private static bool TryCallDetourFallbackHandler(MethodInfo attemptedSource, MemberInfo attemptedDestination, Exception detourException) { if (attemptedDestination.DeclaringType == null) { return(false); } // find a matching handler method var handlers = attemptedDestination.DeclaringType.GetMethods(AllBindingFlags).Where(m => m.TryGetAttributeSafely <DetourFallbackAttribute>() != null); MethodInfo matchingHandler = null; foreach (var handler in handlers) { var attribute = handler.TryGetAttributeSafely <DetourFallbackAttribute>(); if (attribute == null || (attribute.targetMemberNames.Length > 0 && !attribute.targetMemberNames.Contains(attemptedDestination.Name))) { continue; } matchingHandler = handler; break; } if (matchingHandler == null) { return(false); } // try get the method the detour was already routed to MethodInfo existingDestination = null; if (attemptedSource != null) { existingDestination = DetourProvider.TryGetExistingDetourDestination(attemptedSource); } // call the handler try { matchingHandler.Invoke(null, new object[] { attemptedDestination, existingDestination, detourException }); return(true); } catch (Exception e) { HugsLibController.Logger.Error("Exception while invoking detour fallback handler: {0} Exception was: {1}", matchingHandler.FullName(), e); } return(false); }
private static void ExplainFailure(string errorMessage, MethodInfo sourceMethod, MethodInfo destinationMethod) { failReason = string.Format("Dangerous detour detected! {0}. Reason: {1}", DetourProvider.DetourPairToString(sourceMethod, destinationMethod), errorMessage); }