예제 #1
0
        public void ModifyGnomoria()
        {
            Reference.GnomodiaDirectory.GetFile(RuntimeModController.Log.LogfileName).Delete();

            var sourceExe = Reference.GameDirectory.GetFile(Reference.OriginalExecutable);
            var moddedExe = Reference.GnomodiaDirectory.GetFile(Reference.ModdedExecutable);
            var sourceLib = Reference.GameDirectory.GetFile(Reference.OriginalLibrary);
            var moddedLib = Reference.GnomodiaDirectory.GetFile(Reference.ModdedLibrary);

            var gameInjector = new GnomoriaExeInjector(sourceExe);
            var libInjector  = new Injector(sourceLib);

            gameInjector.InitializeGnomodia(Reference.GnomodiaDirectory.GetFile(Reference.GnomodiaLibrary));
            gameInjector.InjectMapGenerationCalls();
            gameInjector.InjectSaveLoadCalls();
            //gameInjector.Debug_ManipulateStuff();

            foreach (var mod in ModManager.CreateOrGetAllMods())
            {
                var interceptedMethods =
                    from method in mod.GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
                    where method.GetCustomAttributes(typeof(InterceptMethodAttribute), false).Any()
                    select new { Method = method, Attribute = method.GetCustomAttributes(typeof(InterceptMethodAttribute), false).Cast <InterceptMethodAttribute>().Single() };

                foreach (var interceptedMethod in interceptedMethods)
                {
                    var           attribute = interceptedMethod.Attribute;
                    IModification mh        = new MethodHook(attribute.InterceptedMethod, interceptedMethod.Method, attribute.HookType, attribute.HookFlags);
                    if (gameInjector.AssemblyContainsType(mh.TargetType))
                    {
                        gameInjector.InjectModification(mh);
                    }
                    else if (libInjector.AssemblyContainsType(mh.TargetType))
                    {
                        libInjector.InjectModification(mh);
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("Cannot change behavior of type {0}!", mh.TargetType));
                    }
                }
            }

            gameInjector.Write(moddedExe);
            libInjector.Write(moddedLib);
        }
예제 #2
0
 private void ProcessMod(IMod mod)
 {
     if (processedMods.Contains(mod))
     {
         return;
     }
     if (currentlyProcessing.Contains(mod))
     {
         throw new InvalidOperationException("Can't process mod [" + mod.Name + "], already processing it. Circular dependency?");
     }
     currentlyProcessing.Add(mod);
     mod.Initialize_PreGeneration();
     if (mod.InitBefore.Count() > 0)
     {
         throw new NotImplementedException("Mod.InitAfter and Mod.InitBefore are not yet supported. Sorry.");
     }
     foreach (var dependency in mod.Dependencies)
     {
         ProcessMod(all_mods_to_process.Union(all_possible_dependencies).Single(depModInstance => depModInstance.GetType() == dependency.Type));
     }
     foreach (var change in mod.Modifications)
     {
         if (game_injector.AssemblyContainsType(change.TargetType))
         {
             game_injector.Inject_Modification(change);
         }
         else if (lib_injector.AssemblyContainsType(change.TargetType))
         {
             lib_injector.Inject_Modification(change);
         }
         else
         {
             throw new InvalidOperationException("Cannot change behavoir of type [" + change.TargetType + "]!");
         }
     }
     processedMods.Add(mod);
     currentlyProcessing.Remove(mod);
 }