public void Generate() { if (RDRefHide) { // Generate the hook wrappers before generating anything else. // This is required to prevent mods from depending on HookGen itself. if (td_HookExtensionsWrapper == null) { Modder.LogVerbose($"[HookGen] Generating hook extensions wrapper {HookExtName}"); int namespaceIndex = HookExtName.LastIndexOf("."); td_HookExtensionsWrapper = new TypeDefinition( namespaceIndex < 0 ? "" : HookExtName.Substring(0, namespaceIndex), namespaceIndex < 0 ? HookExtName : HookExtName.Substring(namespaceIndex + 1), td_HookExtensions.Attributes, OutputModule.TypeSystem.Object ); foreach (CustomAttribute attrib in td_HookExtensions.CustomAttributes) { td_HookExtensionsWrapper.CustomAttributes.Add(attrib.Relink(Relinker, td_HookExtensionsWrapper)); } // Proxy all public methods, events and properties from HookExtensions to HookExtWrapper. GenerateProxy(td_HookExtensions, td_HookExtensionsWrapper, null, null, null); // Generate the nested delegate type. MethodDefinition md_ILManipulator_Invoke = td_HookExtensions.NestedTypes.FirstOrDefault(n => n.Name == "ILManipulatorMini").FindMethod("Invoke"); md_ILManipulator_Invoke.IsStatic = true; // Prevent "self" parameter from being generated in new delegate type. TypeDefinition td_ILManipulatorWrapper = GenerateDelegateFor(md_ILManipulator_Invoke); td_ILManipulatorWrapper.Name = "ILManipulator"; td_HookExtensionsWrapper.NestedTypes.Add(td_ILManipulatorWrapper); t_ILManipulator = td_ILManipulatorWrapper; OutputModule.Types.Add(td_HookExtensionsWrapper); } } foreach (TypeDefinition type in Modder.Module.Types) { GenerateFor(type, out TypeDefinition hookType, out TypeDefinition hookILType); if (hookType == null || hookILType == null) { continue; } OutputModule.Types.Add(hookType); OutputModule.Types.Add(hookILType); } }
public void GenerateFor(TypeDefinition type, out TypeDefinition hookType, out TypeDefinition hookILType) { hookType = hookILType = null; if (type.HasGenericParameters || type.IsRuntimeSpecialName || type.Name.StartsWith("<", StringComparison.Ordinal)) { return; } if (!HookPrivate && type.IsNotPublic) { return; } Modder.LogVerbose($"[HookGen] Generating for type {type.FullName}"); hookType = new TypeDefinition( type.IsNested ? null : (Namespace + (string.IsNullOrEmpty(type.Namespace) ? "" : ("." + type.Namespace))), type.Name, (type.IsNested ? TypeAttributes.NestedPublic : TypeAttributes.Public) | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.Class, OutputModule.TypeSystem.Object ); hookILType = new TypeDefinition( type.IsNested ? null : (NamespaceIL + (string.IsNullOrEmpty(type.Namespace) ? "" : ("." + type.Namespace))), type.Name, (type.IsNested ? TypeAttributes.NestedPublic : TypeAttributes.Public) | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.Class, OutputModule.TypeSystem.Object ); bool add = false; foreach (MethodDefinition method in type.Methods) { add |= GenerateFor(hookType, hookILType, method); } foreach (TypeDefinition nested in type.NestedTypes) { GenerateFor(nested, out TypeDefinition hookNestedType, out TypeDefinition hookNestedILType); if (hookNestedType == null || hookNestedILType == null) { continue; } add = true; hookType.NestedTypes.Add(hookNestedType); hookILType.NestedTypes.Add(hookNestedILType); } if (!add) { hookType = hookILType = null; } }
public TypeDefinition GenerateFor(TypeDefinition type) { if (type.HasGenericParameters || type.IsRuntimeSpecialName || type.Name.StartsWith("<")) { return(null); } Modder.LogVerbose($"[HookGen] Generating for type {type.FullName}"); TypeDefinition hookType = new TypeDefinition( type.IsNested ? null : (Namespace + (string.IsNullOrEmpty(type.Namespace) ? "" : ("." + type.Namespace))), type.Name, (type.IsNested ? TypeAttributes.NestedPublic : TypeAttributes.Public) | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.Class, OutputModule.TypeSystem.Object ); bool add = false; foreach (MethodDefinition method in type.Methods) { add |= GenerateFor(hookType, method); } foreach (TypeDefinition nested in type.NestedTypes) { TypeDefinition hookNested = GenerateFor(nested); if (hookNested == null) { continue; } add = true; hookType.NestedTypes.Add(hookNested); } if (!add) { return(null); } return(hookType); }