private void GenerateHookDict() { List <String> modsToUnload = new List <String> (); modHooks = new Dictionary <string, MethodDefinition[]> (); hooks = new Dictionary <string, Dictionary <string, List <BaseModWithId> > > (); foreach (String modId in loader.modOrder) { BaseMod mod = null; try { mod = loader.modInstances [modId]; } catch { continue; } if (mod != null) { Dictionary <string, List <BaseModWithId> > methodHooks; List <BaseModWithId> hookedMods; MethodDefinition[] requestedHooks; try { requestedHooks = (MethodDefinition[])mod.GetType().GetMethod("GetHooks").Invoke(null, new object[] { types, SharedConstants.getExeVersionInt() }); } catch (Exception ex) { Console.WriteLine(ex); modsToUnload.Add(modId); continue; } modHooks.Add(modId, requestedHooks); foreach (MethodDefinition hookedMethod in requestedHooks) { //TODO: FIx for overloaded methods! if (!hooks.TryGetValue(hookedMethod.DeclaringType.Name, out methodHooks)) { methodHooks = new Dictionary <string, List <BaseModWithId> > (); hooks.Add(hookedMethod.DeclaringType.Name, methodHooks); } if (!methodHooks.TryGetValue(hookedMethod.Name, out hookedMods)) { hookedMods = new List <BaseModWithId> (); methodHooks.Add(hookedMethod.Name, hookedMods); } hookedMods.Add(new BaseModWithId(mod, modId)); } } } Unload(modsToUnload); Console.WriteLine("Hooks:"); foreach (string hookedTypeName in hooks.Keys) { Console.WriteLine(hookedTypeName); foreach (string hookedMethodName in hooks[hookedTypeName].Keys) { Console.WriteLine("\t" + hookedMethodName); foreach (BaseModWithId modWithId in hooks[hookedTypeName][hookedMethodName]) { Console.WriteLine("\t\t" + modWithId.id); } } } }
private Mod _loadModStatic(TypeDefinitionCollection types, String filepath) { ResolveEventHandler resolver = new ResolveEventHandler(CurrentDomainOnAssemblyResolve); AppDomain.CurrentDomain.AssemblyResolve += resolver; Assembly modAsm = null; try { modAsm = Assembly.LoadFile(filepath); } catch (BadImageFormatException) { AppDomain.CurrentDomain.AssemblyResolve -= resolver; return(null); } Type modClass = (from _modClass in modAsm.GetTypes() where _modClass.InheritsFrom(typeof(ScrollsModLoader.Interfaces.BaseMod)) select _modClass).First(); //no mod classes?? if (modClass == null) { AppDomain.CurrentDomain.AssemblyResolve -= resolver; return(null); } //get hooks MethodDefinition[] hooks = null; try { hooks = (MethodDefinition[])modClass.GetMethod("GetHooks").Invoke(null, new object[] { types, SharedConstants.getExeVersionInt() }); } catch (Exception e) { Console.WriteLine("Error executing GetHooks for mod: " + filepath); Console.WriteLine(e); AppDomain.CurrentDomain.AssemblyResolve -= resolver; return(null); } TypeDefinition[] typeDefs = new TypeDefinition[types.Count]; types.CopyTo(typeDefs, 0); //check hooks foreach (MethodDefinition hook in hooks) { //type/method does not exists if (hook == null) { Console.WriteLine("ERROR: GetHooks contains 'null'! "); Console.WriteLine("=> Disabling " + filepath); AppDomain.CurrentDomain.AssemblyResolve -= resolver; return(null); } if ((from type in typeDefs where type.Equals(hook.DeclaringType) //Code above avoids NullReferenceException when hook is null. select type).Count() == 0) { //disable mod Console.WriteLine("ERROR: Mod hooks unexistant method! " + filepath); AppDomain.CurrentDomain.AssemblyResolve -= resolver; return(null); } } //add hooks foreach (MethodDefinition hook in hooks) { ScrollsFilter.AddHook(hook); } //mod object for local mods on ModManager Mod mod = new Mod(); try { mod.id = "00000000000000000000000000000000"; mod.name = (String)modClass.GetMethod("GetName").Invoke(null, null); mod.version = (int)modClass.GetMethod("GetVersion").Invoke(null, null); mod.versionCode = "" + mod.version; mod.description = ""; } catch (Exception e) { Console.WriteLine("Error getting Name or Version: "); Console.WriteLine(e); AppDomain.CurrentDomain.AssemblyResolve -= resolver; return(null); } AppDomain.CurrentDomain.AssemblyResolve -= resolver; return(mod); }