1using MonoMod.RuntimeDetour;
 
    2using MonoMod.RuntimeDetour.HookGen;
 
    5using System.Collections.Generic;
 
    6using System.Diagnostics;
 
    8using System.Reflection;
 
    9using System.Reflection.Emit;
 
   10using Terraria.ModLoader.Core;
 
   11using Terraria.ModLoader.Default;
 
   17        private static Dictionary<Type, string> 
defaultAliases = 
new Dictionary<Type, string> {
 
   18            { typeof(
object), 
"object" },
 
   19            { typeof(
bool), 
"bool" },
 
   20            { typeof(
float), 
"float" },
 
   21            { typeof(
double), 
"double" },
 
   22            { typeof(decimal), 
"decimal" },
 
   23            { typeof(
byte), 
"byte" },
 
   24            { typeof(sbyte), 
"sbyte" },
 
   25            { typeof(
short), 
"short" },
 
   26            { typeof(ushort), 
"ushort" },
 
   27            { typeof(
int), 
"int" },
 
   28            { typeof(uint), 
"uint" },
 
   29            { typeof(
long), 
"long" },
 
   30            { typeof(ulong), 
"ulong" },
 
   31            { typeof(
char), 
"char" },
 
   32            { typeof(
string), 
"string" }
 
   35        private static DetourModManager 
manager = 
new DetourModManager();
 
   39        internal static void Initialize() {
 
   43            HookEndpointManager.OnAdd += (m, d) => {
 
   44                Logging.tML.Debug($
"Hook On.{StringRep(m)} added by {GetOwnerName(d)}");
 
   47            HookEndpointManager.OnRemove += (m, d) => {
 
   48                Logging.tML.Debug($
"Hook On.{StringRep(m)} removed by {GetOwnerName(d)}");
 
   51            HookEndpointManager.OnModify += (m, d) => {
 
   52                Logging.tML.Debug($
"Hook IL.{StringRep(m)} modified by {GetOwnerName(d)}");
 
   55            HookEndpointManager.OnUnmodify += (m, d) => {
 
   56                Logging.tML.Debug($
"Hook IL.{StringRep(m)} unmodified by {GetOwnerName(d)}");
 
   60            manager.OnHook += (
asm, from, to, target) => {
 
   62                Logging.tML.Debug($
"Hook {StringRep(from)} -> {StringRep(to)} by {asm.GetName().Name}");
 
   65            manager.OnILHook += (
asm, from, manipulator) => {
 
   67                Logging.tML.Debug($
"ILHook {StringRep(from)} by {asm.GetName().Name}");
 
   70            manager.OnDetour += (
asm, from, to) => {
 
   72                Logging.tML.Debug($
"Detour {StringRep(from)} -> {StringRep(to)} by {asm.GetName().Name}");
 
   75            manager.OnNativeDetour += (
asm, method, from, to) => {
 
   77                Logging.tML.Debug($
"NativeDetour {StringRep(method)} [{from} -> {to}] by {asm.GetName().Name}");
 
   87            throw new UnauthorizedAccessException(
 
   88                $
"Native detouring permissions not granted to {asm.GetName().Name}. \n" +
 
   89                $
"Mods should use HookEndpointManager for compatibility. \n" +
 
   90                $
"If Detour or NativeDetour are required, call MonoModHooks.RequestNativeAccess()");
 
   94            var stack = 
new StackTrace();
 
   95            var 
asm = stack.GetFrame(1).GetMethod().DeclaringType.Assembly;
 
   97            Logging.tML.Warn($
"Granted native detouring access to {asm.GetName().Name}");
 
  101            return d.Method.DeclaringType.Assembly.GetName().Name;
 
  105            var paramString = 
string.Join(
", ", m.GetParameters().Select(p => {
 
  106                var t = p.ParameterType;
 
  110                    s = p.IsOut ? 
"out " : 
"ref ";
 
  111                    t = t.GetElementType();
 
  114                return s + (
defaultAliases.TryGetValue(t, out 
string n) ? n : t.Name);
 
  117            var owner = m.DeclaringType?.FullName ??
 
  118                (m is DynamicMethod ? 
"dynamic" : 
"unknown");
 
  119            return $
"{owner}::{m.Name}({paramString})";
 
  122        internal static void RemoveAll(Mod mod) {
 
  123            if (mod is ModLoaderMod)
 
  126            int hooks = 0, detours = 0, ndetours = 0;
 
  127            bool OnHookUndo(
object obj) {
 
  131            bool OnDetourUndo(
object obj) {
 
  135            bool OnNativeDetourUndo(
object obj) {
 
  140            Hook.OnUndo += OnHookUndo;
 
  141            Detour.OnUndo += OnDetourUndo;
 
  142            NativeDetour.OnUndo += OnNativeDetourUndo;
 
  144            foreach (var 
asm in AssemblyManager.GetModAssemblies(mod.Name))
 
  147            Hook.OnUndo -= OnHookUndo;
 
  148            Detour.OnUndo -= OnDetourUndo;
 
  149            NativeDetour.OnUndo -= OnNativeDetourUndo;
 
  151            if (hooks > 0 || detours > 0 || ndetours > 0)
 
  152                Logging.tML.Debug($
"Unloaded {hooks} hooks, {detours} detours and {ndetours} native detours from {mod.Name}");
 
static string GetOwnerName(Delegate d)
 
static Dictionary< Type, string > defaultAliases
 
static string StringRep(MethodBase m)
 
static bool isInitialized
 
static void NativeAccessCheck(Assembly asm)
 
static void RequestNativeAccess()
 
static HashSet< Assembly > NativeDetouringGranted
 
static DetourModManager manager