Пример #1
0
        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 {
                        int exeversion = SharedConstants.getGameVersion().getMinor();
                        requestedHooks = (MethodDefinition[])mod.GetType().GetMethod("GetHooks").Invoke(null, new object[] { types, exeversion });
                    } 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);
                    }
                }
            }
        }
Пример #2
0
        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 {
                int exeversion = SharedConstants.getGameVersion().getMinor();
                hooks = (MethodDefinition[])modClass.GetMethod("GetHooks").Invoke(null, new object[] { types, exeversion });
            } 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);
        }