Пример #1
0
        public void Generate()
        {
            if (Directory.Exists(FullPath))
            {
                Modder.Log($"[DbgIlGen] Clearing {FullPath}");
                DeleteRecursive(FullPath);
            }

            Directory.CreateDirectory(FullPath);
            Thread.Sleep(0); // Required to stay in sync with filesystem... thanks, .NET Framework!

            CustomAttribute debuggable = Modder.Module.Assembly.GetCustomAttribute("System.Diagnostics.DebuggableAttribute");

            if (debuggable != null)
            {
                Modder.Module.Assembly.CustomAttributes.Remove(debuggable);
            }
            debuggable = new CustomAttribute(Modder.Module.ImportReference(m_DebuggableAttribute_ctor));
            debuggable.ConstructorArguments.Add(new CustomAttributeArgument(
                                                    Modder.Module.ImportReference(typeof(DebuggableAttribute.DebuggingModes)),
                                                    DebuggableAttribute.DebuggingModes.Default |
                                                    DebuggableAttribute.DebuggingModes.DisableOptimizations |
                                                    DebuggableAttribute.DebuggingModes.EnableEditAndContinue
                                                    ));
            Modder.Module.Assembly.AddAttribute(debuggable);

            GenerateMetadata();

            foreach (TypeDefinition type in Modder.Module.Types)
            {
                GenerateFor(type);
            }
        }
Пример #2
0
        public static void RelinkModule(string from, string toName)
        {
            MonoModder self = Modder;

            from   = from.Inject(MonoModExt.SharedData);
            toName = toName.Inject(MonoModExt.SharedData);

            bool             retrying = false;
            ModuleDefinition to       = null;

RETRY:
            if (toName + ".dll" == self.Module.Name)
            {
                to = self.Module;
            }
            else if (self.DependencyCache.TryGetValue(toName, out to))
            {
            }
            else if (!retrying)
            {
                self.MapDependency(self.Module, toName);
                retrying = true;
                goto RETRY;
            }

            if (to != null)
            {
                self.Log($"[MonoModRules] RelinkModule: {from} -> {toName}");
                self.RelinkModuleMap[from] = to;
            }
        }
Пример #3
0
        public static void RelinkMember(string from, string toType, string toMember)
        {
            MonoModder self = Modder;

            self.Log($"[MonoModRules] RelinkMember: {from} -> {toType}::{toMember}");
            self.RelinkMap[from] = new RelinkMapEntry(toType, toMember);
        }
Пример #4
0
        public static void RelinkType(string from, string to)
        {
            MonoModder self = Modder;

            self.Log($"[MonoModRules] RelinkType: {from} -> {to}");
            self.RelinkMap[from] = to;
        }
Пример #5
0
            public static void RelinkType(MonoModder self, string from, string to)
            {
                from = from.Inject(MonoModder.Data);
                to   = to.Inject(MonoModder.Data);

                self.Log($"[MonoModRules] RelinkType: {from} -> {to}");
                self.RelinkMap[from] = to;
            }
Пример #6
0
            public static void RelinkMember(MonoModder self, string from, string toType, string toMember)
            {
                from     = from.Inject(MonoModder.Data);
                toType   = toType.Inject(MonoModder.Data);
                toMember = toMember.Inject(MonoModder.Data);

                self.Log($"[MonoModRules] RelinkMember: {from} -> {toType}::{toMember}");
                self.RelinkMap[from] = Tuple.Create(toType, toMember);
            }
Пример #7
0
        public static void RelinkMember(string from, string toType, string toMember)
        {
            MonoModder self = Modder;

            from     = from.Inject(MonoModExt.SharedData);
            toType   = toType.Inject(MonoModExt.SharedData);
            toMember = toMember.Inject(MonoModExt.SharedData);

            self.Log($"[MonoModRules] RelinkMember: {from} -> {toType}::{toMember}");
            self.RelinkMap[from] = new RelinkMapEntry(toType, toMember);
        }
Пример #8
0
            public static void Patch(MonoModder self, string id, bool patch)
            {
                id = id.Inject(MonoModder.Data);

                self.Log($"[MonoModRules] Patch: {id}: {patch}");
                if (patch && self.SkipList.Contains(id))
                {
                    self.SkipList.Remove(id);
                }
                else if (!patch && !self.SkipList.Contains(id))
                {
                    self.SkipList.Add(id);
                }
            }
        /// <summary>Generates the HOOKS-Assembly-CSharp.dll the same as Partiality</summary>
        void GenerateHooks()
        {
            string pathIn  = Path.Combine(Paths.ManagedPath, "Assembly-CSharp.dll");
            string pathOut = Path.Combine(Path.GetDirectoryName(Info.Location), "HOOKS-Assembly-CSharp.dll");

            if (File.Exists(pathOut))
            {
                // Only Regenerate if Managed is newer than HOOKS
                if (File.GetLastWriteTime(pathOut) > File.GetLastWriteTime(pathIn))
                {
                    return;
                }

                File.Delete(pathOut);
            }

            using (MonoModder mm = new MonoModder {
                InputPath = pathIn,
                OutputPath = pathOut,
                PublicEverything = true,
                DependencyDirs = new List <string>()
                {
                    Paths.ManagedPath, Paths.BepInExAssemblyDirectory
                },
            }) {
                mm.Read();
                mm.MapDependencies();
                mm.Log("[HookGen] Starting HookGenerator");
                HookGenerator gen = new HookGenerator(mm, Path.GetFileName(pathOut));
                using (ModuleDefinition mOut = gen.OutputModule) {
                    gen.HookPrivate = true;
                    gen.Generate();
                    mOut.Write(pathOut);
                }
                mm.Log("[HookGen] Done.");
            }
        }
Пример #10
0
        static void Main(string[] args)
        {
            Console.WriteLine("MonoMod.RuntimeDetour.HookGen " + typeof(Program).Assembly.GetName().Version);
            Console.WriteLine("using MonoMod " + typeof(MonoModder).Assembly.GetName().Version);
            Console.WriteLine("using MonoMod.RuntimeDetour " + typeof(Detour).Assembly.GetName().Version);

            if (args.Length == 0)
            {
                Console.WriteLine("No valid arguments (assembly path) passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return;
            }

            string pathIn;
            string pathOut;

            int pathInI = 0;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "--namespace" && i + 2 < args.Length)
                {
                    i++;
                    Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_NAMESPACE", args[i]);
                }
                else if (args[i] == "--orig")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_ORIG", "1");
                }
                else if (args[i] == "--private")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_HOOKGEN_PRIVATE", "1");
                }
                else
                {
                    pathInI = i;
                    break;
                }
            }

            if (pathInI >= args.Length)
            {
                Console.WriteLine("No assembly path passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return;
            }

            pathIn  = args[pathInI];
            pathOut = args.Length != 1 && pathInI != args.Length - 1 ? args[args.Length - 1] : null;

            pathOut = pathOut ?? Path.Combine(Path.GetDirectoryName(pathIn), "MMHOOK_" + Path.ChangeExtension(Path.GetFileName(pathIn), "dll"));

            using (MonoModder mm = new MonoModder()
            {
                InputPath = pathIn,
                OutputPath = pathOut
            }) {
                mm.Read();

                mm.MapDependencies();

                if (File.Exists(pathOut))
                {
                    mm.Log($"[HookGen] Clearing {pathOut}");
                    File.Delete(pathOut);
                }

                mm.Log("[HookGen] Starting HookGenerator");
                HookGenerator gen = new HookGenerator(mm, Path.GetFileName(pathOut));
                using (ModuleDefinition mOut = gen.OutputModule) {
                    gen.Generate();
                    mOut.Write(pathOut);
                }

                mm.Log("[HookGen] Done.");
            }

            if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
            {
                Console.ReadKey();
            }
        }
Пример #11
0
        public static void Main(string[] args)
        {
#if CECIL0_9
            throw new NotSupportedException();
#else
            Console.WriteLine("MonoMod.DebugIL " + typeof(Program).Assembly.GetName().Version);

            if (args.Length == 0)
            {
                Console.WriteLine("No valid arguments (assembly path) passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return;
            }

            string pathIn;
            string pathOut;

            int pathInI = 0;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "--relative")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_DEBUGIL_RELATIVE", "1");
                    pathInI = i + 1;
                }
                else if (args[i] == "--skip-maxstack")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_DEBUGIL_SKIP_MAXSTACK", "1");
                    pathInI = i + 1;
                }
            }

            if (pathInI >= args.Length)
            {
                Console.WriteLine("No assembly path passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return;
            }

            pathIn  = args[pathInI];
            pathOut = args.Length != 1 && pathInI != args.Length - 1 ? args[args.Length - 1] : null;

            pathOut = pathOut ?? Path.Combine(Path.GetDirectoryName(pathIn), "MMDBGIL_" + Path.GetFileName(pathIn));

            using (MonoModder mm = new MonoModder()
            {
                InputPath = pathIn,
                OutputPath = pathOut
            }) {
                mm.Read();

                mm.Log("[DbgILGen] DebugILGenerator.Generate(mm);");
                DebugILGenerator.Generate(mm);

                mm.Write();

                mm.Log("[DbgILGen] Done.");
            }

            if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
            {
                Console.ReadKey();
            }
#endif
        }
Пример #12
0
        public static void Main(string[] args)
        {
            Console.WriteLine("MonoMod " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);

            if (args.Length == 0)
            {
                Console.WriteLine("No valid arguments (assembly path) passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return;
            }

            string pathIn;
            string pathOut;

            if (args.Length > 1 &&
                args[0] == "--generate-debug-il" ||
                args[0] == "--gen-dbg-il")
            {
                Console.WriteLine("[DbgILGen] Generating debug hierarchy and debug data (pdb / mdb).");

                pathIn  = args[1];
                pathOut = args.Length != 2 ? args[args.Length - 1] : Path.Combine(Path.GetDirectoryName(pathIn), "MMDBGIL_" + Path.GetFileName(pathIn));

                using (MonoModder mm = new MonoModder()
                {
                    InputPath = pathIn,
                    OutputPath = pathOut
                }) {
                    mm.Read(false);

                    mm.Log("[DbgILGen] DebugILGenerator.Generate(mm);");
                    DebugILGenerator.Generate(mm);

                    mm.Write();

                    mm.Log("[DbgILGen] Done.");
                }

                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return;
            }

            int pathInI = 0;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "--dependency-missing-throw=0" || args[i] == "--lean-dependencies")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW", "0");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cleanup=0" || args[i] == "--skip-cleanup")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_CLEANUP", "0");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cleanup-all=1" || args[i] == "--cleanup-all")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_CLEANUP_ALL", "1");
                    pathInI = i + 1;
                }
                else if (args[i] == "--verbose=1" || args[i] == "--verbose" || args[i] == "-v")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_VERBOSE", "1");
                    pathInI = i + 1;
                }
            }

            if (pathInI >= args.Length)
            {
                Console.WriteLine("No assembly path passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return;
            }

            pathIn  = args[pathInI];
            pathOut = args.Length != 1 && pathInI != args.Length - 1 ? args[args.Length - 1] : Path.Combine(Path.GetDirectoryName(pathIn), "MONOMODDED_" + Path.GetFileName(pathIn));

            if (File.Exists(pathOut))
            {
                File.Delete(pathOut);
            }

            try {
                using (MonoModder mm = new MonoModder()
                {
                    InputPath = pathIn,
                    OutputPath = pathOut,
                    Verbose = Environment.GetEnvironmentVariable("MONOMOD_VERBOSE") == "1"
                }) {
                    mm.Read(false);

                    if (args.Length <= 2)
                    {
                        mm.Log("[Main] Scanning for mods in directory.");
                        mm.ReadMod(Directory.GetParent(pathIn).FullName);
                    }
                    else
                    {
                        mm.Log("[Main] Reading mods list from arguments.");
                        for (int i = pathInI + 1; i < args.Length - 2; i++)
                        {
                            mm.ReadMod(args[i]);
                        }
                    }

                    mm.Read(true);

                    mm.Log("[Main] mm.AutoPatch();");
                    mm.AutoPatch();

                    mm.Write();

                    mm.Log("[Main] Done.");
                }
            } catch (Exception e) {
                Console.WriteLine(e);
            }

            if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
            {
                Console.ReadKey();
            }
        }
        public static void PatchGame()
        {
            string executablePath      = Assembly.GetEntryAssembly().Location;
            string executableDirectory = Directory.GetParent(executablePath).FullName;
            string monoModPath         = Path.Combine(executableDirectory, "MonoMod.exe");
            string hookGenPath         = Path.Combine(executableDirectory, "MonoMod.RuntimeDetour.HookGen.exe");
            string runtimeDetourDLL    = "MonoMod.RuntimeDetour.dll";
            string mmUtilsDLL          = "MonoMod.Utils.dll";
            string jsonDLL             = "YamlDotNet.dll";

            string gameDirectory   = Directory.GetParent(GameManager.exePath).FullName;
            string hashesFolder    = Path.Combine(gameDirectory, "DustDevilHashes");
            string modDependencies = Path.Combine(gameDirectory, "ModDependencies");
            string dataDirectory   = Path.Combine(gameDirectory, Path.GetFileNameWithoutExtension(GameManager.exePath) + "_Data");
            string managedFolder   = Path.Combine(dataDirectory, "Managed");
            string codeDll         = Path.Combine(managedFolder, "Assembly-CSharp.dll");
            string hookGenDLL      = Path.Combine(managedFolder, "HOOKS-Assembly-CSharp.dll");
            string engineDll       = Path.Combine(managedFolder, "UnityEngine.dll");
            string coreModuleDLL   = Path.Combine(managedFolder, "UnityEngine.CoreModule.dll");

            string backupFolder = managedFolder + "_backup";

            Process currentProcess = Process.GetCurrentProcess();
            Process monomodProcess = new Process();

            monomodProcess.StartInfo.FileName = monoModPath;
            //monomodProcess.StartInfo.CreateNoWindow = true;
            monomodProcess.StartInfo.UseShellExecute        = false;
            monomodProcess.StartInfo.RedirectStandardOutput = true;

            //Create backup if there isn't one
            if (!Directory.Exists(backupFolder))
            {
                Directory.CreateDirectory(backupFolder);
                CopyFilesRecursively(managedFolder, backupFolder);
            }

            //Install the default patch for Partiality
            {
                string engineDLLName = "UnityEngine.dll";

                if (File.Exists(coreModuleDLL))
                {
                    engineDLLName = "UnityEngine.CoreModule.dll";
                    engineDll     = coreModuleDLL;
                }

                string moddedDLL             = Path.Combine(Path.GetDirectoryName(engineDll), "patched" + engineDLLName);
                string defaultPatchLocation  = Path.Combine(executableDirectory, "PartialityPatch.dll");
                string partialityModLocation = Path.Combine(Path.GetDirectoryName(engineDll), "Partiality.dll");

                bool shouldPatch = false;

                if (!File.Exists(Path.Combine(hashesFolder, "ENGINEHASH.hash")))
                {
                    shouldPatch = true;
                }
                else
                {
                    shouldPatch = !ModMetadata.CompareHashes(defaultPatchLocation, Path.Combine(hashesFolder, "ENGINEHASH.hash"));
                }

                //Delete mod if it exists
                if (File.Exists(partialityModLocation))
                {
                    File.Delete(partialityModLocation);
                }
                //Copy mod to folder with assembly-chsharp.dll
                File.Copy(Path.Combine(executableDirectory, "Partiality.dll"), partialityModLocation);

                if (shouldPatch)
                {
                    //Restore backup
                    File.Delete(engineDll);
                    File.Copy(Path.Combine(backupFolder, engineDLLName), engineDll);

                    //Set monomod arguments to "[UnityEngine.dll] [PartialityPatch.dll] [patched_UnityEngine.dll]"

                    monomodProcess.StartInfo.Arguments = ('"' + engineDll + '"') + " " + ('"' + defaultPatchLocation + '"') + " " + ('"' + moddedDLL + '"');

                    monomodProcess.Start();
                    string mmoutput = monomodProcess.StandardOutput.ReadToEnd();
                    Console.WriteLine(mmoutput);
                    monomodProcess.WaitForExit();

                    int exitCode = monomodProcess.ExitCode;
                    Console.WriteLine("MMEC:" + exitCode);
                    Console.WriteLine(mmoutput);

                    //Replace file
                    if (File.Exists(moddedDLL))
                    {
                        //Move modded .dll over original .dll
                        File.Delete(engineDll);
                        File.Copy(moddedDLL, engineDll);
                        File.Delete(moddedDLL);
                    }

                    byte[] newHash = ChecksumHasher.ComputeHash(File.ReadAllBytes(defaultPatchLocation));
                    File.WriteAllBytes(Path.Combine(hashesFolder, "ENGINEHASH.hash"), newHash);
                }
            }

            //Install custom patches
            {
                string[] files = Directory.GetFiles(modDependencies);


                //Copy mod dependencies
                foreach (string dependency in files)
                {
                    string fileName = Path.GetFileName(dependency);
                    //Delete the dependency if it already exists
                    if (File.Exists(Path.Combine(managedFolder, fileName)))
                    {
                        File.Delete(Path.Combine(managedFolder, fileName));
                    }
                    //Copy the file
                    File.Copy(dependency, Path.Combine(managedFolder, fileName));
                }

                bool   shouldPatch    = false;
                string moddedDLL      = Path.Combine(Path.GetDirectoryName(engineDll), "patched_Assembly-CSharp.dll");
                string epListLocation = Path.Combine(hashesFolder, "ENABLEDPATCHES.enp");


                //Check if we have the same enabled/disabled mods as last time, if we do, then
                {
                    string totalEnabledPatches = "Partiality+";
                    foreach (ModMetadata md in GameManager.modMetas)
                    {
                        if ((md.isStandalone || md.isPatch) && md.isEnabled)
                        {
                            totalEnabledPatches += Path.GetFileNameWithoutExtension(md.modPath) + "+";
                        }
                    }

                    DebugLogger.Log(totalEnabledPatches);

                    if (File.Exists(epListLocation))
                    {
                        string getList = File.ReadAllText(epListLocation);
                        shouldPatch = getList != totalEnabledPatches;
                        if (shouldPatch)
                        {
                            File.WriteAllText(epListLocation, totalEnabledPatches);
                        }
                    }
                    else
                    {
                        shouldPatch = true;
                        File.WriteAllText(epListLocation, totalEnabledPatches);
                    }
                }

                //If all the same mods are enabled, check if any mods are dirty. If they are, we gotta re-patch.
                if (!shouldPatch)
                {
                    foreach (ModMetadata md in GameManager.modMetas)
                    {
                        if (md.isDirty)
                        {
                            shouldPatch = true;
                            break;
                        }
                    }
                }

                if (shouldPatch)
                {
                    DebugLogger.Log("Patching Assembly-CSharp");

                    string backupDll = Path.Combine(backupFolder, "Assembly-CSharp.dll");

                    foreach (ModMetadata md in GameManager.modMetas)
                    {
                        if (md.isStandalone && md.isEnabled)
                        {
                            backupDll = md.modPath;
                        }
                    }

                    //Restore backup
                    File.Delete(codeDll);
                    File.Copy(backupDll, codeDll);

                    List <string> failedPatches = new List <string>();

                    foreach (ModMetadata md in GameManager.modMetas)
                    {
                        if (md.isPatch && md.isEnabled)
                        {
                            monomodProcess.StartInfo.Arguments = ('"' + codeDll + '"') + " " + ('"' + md.modPath + '"') + " " + ('"' + moddedDLL + '"');

                            monomodProcess.Start();
                            string mmoutput = monomodProcess.StandardOutput.ReadToEnd();
                            monomodProcess.WaitForExit();

                            int exitCode = monomodProcess.ExitCode;
                            DebugLogger.Log("MMEC:" + exitCode);
                            DebugLogger.Log(mmoutput);

                            if (exitCode != 0)
                            {
                                failedPatches.Add(Path.GetFileNameWithoutExtension(md.modPath));
                            }

                            //Replace file
                            if (File.Exists(moddedDLL))
                            {
                                //Move modded .dll over original .dll
                                File.Delete(codeDll);
                                File.Copy(moddedDLL, codeDll);
                                File.Delete(moddedDLL);
                            }
                        }
                    }

                    if (failedPatches.Count > 0)
                    {
                        Eto.Forms.MessageBox.Show("Some mods failed to apply correctly! Please send your LOG.txt (in the Partiality folder) to someone who can help, probably from the people who made the mod.");
                    }

                    //Set mods to all not be dirty, and save them.
                    foreach (ModMetadata md in GameManager.modMetas)
                    {
                        md.isDirty = false;
                    }

                    try {
                        GameManager.SaveAllMetadata();
                    } catch (System.Exception e) {
                        DebugLogger.Log(e);
                    }
                }
            }

            //HookGen stuff
            {
                //Delete Legacy DLL
                if (File.Exists(Path.Combine(managedFolder, "HOOKS-Assembly-CSharp.dll")))
                {
                    File.Delete(Path.Combine(managedFolder, "HOOKS-Assembly-CSharp.dll"));
                }

                if (File.Exists(hookGenDLL))
                {
                    File.Delete(hookGenDLL);
                }

                //Delete files if they existed, so we can update them.
                if (File.Exists(Path.Combine(managedFolder, runtimeDetourDLL)))
                {
                    File.Delete(Path.Combine(managedFolder, runtimeDetourDLL));
                }
                if (File.Exists(Path.Combine(managedFolder, mmUtilsDLL)))
                {
                    File.Delete(Path.Combine(managedFolder, mmUtilsDLL));
                }
                if (File.Exists(Path.Combine(managedFolder, jsonDLL)))
                {
                    File.Delete(Path.Combine(managedFolder, jsonDLL));
                }

                //Copy files
                File.Copy(Path.Combine(executableDirectory, runtimeDetourDLL), Path.Combine(managedFolder, runtimeDetourDLL));
                File.Copy(Path.Combine(executableDirectory, mmUtilsDLL), Path.Combine(managedFolder, mmUtilsDLL));
                File.Copy(Path.Combine(executableDirectory, jsonDLL), Path.Combine(managedFolder, jsonDLL));

                string pathIn  = codeDll;
                string pathOut = hookGenDLL;

                using (MonoModder mm = new MonoModder {
                    InputPath = pathIn,
                    OutputPath = pathOut
                }) {
                    mm.Read();
                    mm.MapDependencies();
                    if (File.Exists(pathOut))
                    {
                        mm.Log(string.Format("Clearing {0}", pathOut));
                        File.Delete(pathOut);
                    }
                    mm.Log("[HookGen] Starting HookGenerator");
                    HookGenerator gen = new HookGenerator(mm, Path.GetFileName(pathOut));
                    using (ModuleDefinition mOut = gen.OutputModule) {
                        gen.HookPrivate = true;
                        gen.Generate();
                        mOut.Write(pathOut);
                    }
                    mm.Log("[HookGen] Done.");
                }
            }

            //File.WriteAllText( gameDirectory + "\\PARTIALITY_OUTPUT.txt", );
        }
Пример #14
0
        public static int Main(string[] args)
        {
            Console.WriteLine("MonoMod " + typeof(Program).GetTypeInfo().Assembly.GetName().Version);

            if (args.Length == 0)
            {
                Console.WriteLine("No valid arguments (assembly path) passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return(0);
            }

            string pathIn;
            string pathOut;

            int pathInI = 0;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "--dependency-missing-throw=0" || args[i] == "--lean-dependencies")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW", "0");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cleanup=0" || args[i] == "--skip-cleanup")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_CLEANUP", "0");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cleanup-all=1" || args[i] == "--cleanup-all")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_CLEANUP_ALL", "1");
                    pathInI = i + 1;
                }
                else if (args[i] == "--verbose=1" || args[i] == "--verbose" || args[i] == "-v")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_LOG_VERBOSE", "1");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cache=0" || args[i] == "--uncached")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_RELINKER_CACHED", "0");
                    pathInI = i + 1;
                }
            }

            if (pathInI >= args.Length)
            {
                Console.WriteLine("No assembly path passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return(0);
            }

            pathIn  = args[pathInI];
            pathOut = args.Length != 1 && pathInI != args.Length - 1 ? args[args.Length - 1] : null;
            pathOut = pathOut ?? Path.Combine(Path.GetDirectoryName(pathIn), "MONOMODDED_" + Path.GetFileName(pathIn));

            if (File.Exists(pathOut))
            {
                File.Delete(pathOut);
            }

#if !DEBUG
            try {
#endif
            using (MonoModder mm = new MonoModder()
            {
                InputPath = pathIn,
                OutputPath = pathOut
            }) {
                mm.Read();

                if (args.Length <= 2)
                {
                    mm.Log("[Main] Scanning for mods in directory.");
                    mm.ReadMod(Directory.GetParent(pathIn).FullName);
                }
                else
                {
                    mm.Log("[Main] Reading mods list from arguments.");
                    for (int i = pathInI + 1; i < args.Length - 1; i++)
                    {
                        mm.ReadMod(args[i]);
                    }
                }

                mm.MapDependencies();

                mm.Log("[Main] mm.AutoPatch();");
                mm.AutoPatch();

                mm.Write();

                mm.Log("[Main] Done.");
            }
#if !DEBUG
        }

        catch (Exception e) {
            Console.WriteLine(e);
            if (System.Diagnostics.Debugger.IsAttached)     // Keep window open when running in IDE
            {
                Console.ReadKey();
            }
            return(-1);
        }
#endif

            if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
            {
                Console.ReadKey();
            }
            return(0);
        }
Пример #15
0
        public static Type ExecuteRules(this MonoModder self, TypeDefinition orig)
        {
            ModuleDefinition wrapper = ModuleDefinition.CreateModule(
                $"{orig.Module.Name.Substring(0, orig.Module.Name.Length - 4)}.MonoModRules -ID:{MMILProxyManager.GetId(self)} -MMILRT",
                new ModuleParameters()
            {
                Architecture     = orig.Module.Architecture,
                AssemblyResolver = self.AssemblyResolver,
                Kind             = ModuleKind.Dll,
                MetadataResolver = orig.Module.MetadataResolver,
                Runtime          = orig.Module.Runtime
            }
                );
            MonoModder wrapperMod = new MonoModder()
            {
                Module = wrapper,

                Logger = msg => self.Log("[MonoModRule] " + msg),

                CleanupEnabled = false,

                DependencyDirs            = self.DependencyDirs,
                MissingDependencyResolver = self.MissingDependencyResolver
            };

            wrapperMod.WriterParameters.WriteSymbols         = false;
            wrapperMod.WriterParameters.SymbolWriterProvider = null;

            // Only add a copy of the map - adding the MMILRT asm itself to the map only causes issues.
            wrapperMod.DependencyCache.AddRange(self.DependencyCache);
            foreach (KeyValuePair <ModuleDefinition, List <ModuleDefinition> > mapping in self.DependencyMap)
            {
                wrapperMod.DependencyMap[mapping.Key] = new List <ModuleDefinition>(mapping.Value);
            }

            // Required as the relinker only deep-relinks if the method the type comes from is a mod.
            // Fixes nasty reference import sharing issues.
            wrapperMod.Mods.Add(self.Module);

            wrapperMod.Relinker = (mtp, context) =>
                                  mtp is TypeReference && ((TypeReference)mtp).IsMMILType() ?
                                  MMILProxyManager.RelinkToProxy(wrapperMod, (TypeReference)mtp) :
                                  mtp is TypeReference && ((TypeReference)mtp).FullName == orig.FullName ?
                                  wrapper.GetType(orig.FullName) :
                                  wrapperMod.DefaultRelinker(mtp, context);

            wrapperMod.PrePatchType(orig, forceAdd: true);
            wrapperMod.PatchType(orig);
            TypeDefinition rulesCecil = wrapper.GetType(orig.FullName);

            wrapperMod.PatchRefsInType(rulesCecil);

            Assembly asm;

            using (MemoryStream asmStream = new MemoryStream()) {
                wrapperMod.Write(asmStream);
                asm = Assembly.Load(asmStream.GetBuffer());
            }

            /**//*
             * using (FileStream debugStream = File.OpenWrite(Path.Combine(
             *  self.DependencyDirs[0], $"{orig.Module.Name.Substring(0, orig.Module.Name.Length - 4)}.MonoModRules-MMILRT.dll")))
             *  wrapperMod.Write(debugStream);
             * /**/

            Type rules = asm.GetType(orig.FullName);

            RuntimeHelpers.RunClassConstructor(rules.TypeHandle);

            return(rules);
        }
Пример #16
0
        public static int Main(string[] args)
        {
            Console.WriteLine("MonoMod " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);

            if (args.Length == 0)
            {
                Console.WriteLine("No valid arguments (assembly path) passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return(0);
            }

            if (args[0] == "--test")
            {
                Console.WriteLine("[QuickDebugTest] Running...");
                int result = QuickDebugTest.Run(args);
                if (result == 0)
                {
                    Console.WriteLine("[QuickDebugTest] Passed!");
                }
                else
                {
                    Console.WriteLine($"[QuickDebugTest] Failed: {result}");
                }
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return(result);
            }

            string pathIn;
            string pathOut;

            int pathInI = 0;

            bool generateDebugIL = false;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "--dependency-missing-throw=0" || args[i] == "--lean-dependencies")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_DEPENDENCY_MISSING_THROW", "0");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cleanup=0" || args[i] == "--skip-cleanup")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_CLEANUP", "0");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cleanup-all=1" || args[i] == "--cleanup-all")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_CLEANUP_ALL", "1");
                    pathInI = i + 1;
                }
                else if (args[i] == "--verbose=1" || args[i] == "--verbose" || args[i] == "-v")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_LOG_VERBOSE", "1");
                    pathInI = i + 1;
                }
                else if (args[i] == "--cache=0" || args[i] == "--uncached")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_RELINKER_CACHED", "0");
                    pathInI = i + 1;
                }
                else if (args[i] == "--generate-debug-il" || args[i] == "--gen-dbg-il")
                {
                    generateDebugIL = true;
                    pathInI         = i + 1;
                }
                else if (args[i] == "--debug-il-relative" || args[i] == "--dbg-il-relative")
                {
                    Environment.SetEnvironmentVariable("MONOMOD_DEBUGIL_RELATIVE", "1");
                    pathInI = i + 1;
                }
            }

            if (pathInI >= args.Length)
            {
                Console.WriteLine("No assembly path passed.");
                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return(0);
            }

            pathIn  = args[pathInI];
            pathOut = args.Length != 1 && pathInI != args.Length - 1 ? args[args.Length - 1] : null;

            if (generateDebugIL)
            {
                Console.WriteLine("[DbgILGen] Generating debug hierarchy and debug data (pdb / mdb).");

                pathOut = pathOut ?? Path.Combine(Path.GetDirectoryName(pathIn), "MMDBGIL_" + Path.GetFileName(pathIn));

                using (MonoModder mm = new MonoModder()
                {
                    InputPath = pathIn,
                    OutputPath = pathOut
                }) {
                    mm.Read();

                    mm.Log("[DbgILGen] DebugILGenerator.Generate(mm);");
                    DebugILGenerator.Generate(mm);

                    mm.Write();

                    mm.Log("[DbgILGen] Done.");
                }

                if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
                {
                    Console.ReadKey();
                }
                return(0);
            }

            pathOut = pathOut ?? Path.Combine(Path.GetDirectoryName(pathIn), "MONOMODDED_" + Path.GetFileName(pathIn));

            if (File.Exists(pathOut))
            {
                File.Delete(pathOut);
            }

#if !DEBUG
            try {
#endif
            using (MonoModder mm = new MonoModder()
            {
                InputPath = pathIn,
                OutputPath = pathOut
            }) {
                mm.Read();

                if (args.Length <= 2)
                {
                    mm.Log("[Main] Scanning for mods in directory.");
                    mm.ReadMod(Directory.GetParent(pathIn).FullName);
                }
                else
                {
                    mm.Log("[Main] Reading mods list from arguments.");
                    for (int i = pathInI + 1; i < args.Length - 1; i++)
                    {
                        mm.ReadMod(args[i]);
                    }
                }

                mm.MapDependencies();

                mm.Log("[Main] mm.AutoPatch();");
                mm.AutoPatch();

                mm.Write();

                mm.Log("[Main] Done.");
            }
#if !DEBUG
        }

        catch (Exception e) {
            Console.WriteLine(e);
            if (System.Diagnostics.Debugger.IsAttached)     // Keep window open when running in IDE
            {
                Console.ReadKey();
            }
            return(-1);
        }
#endif

            if (System.Diagnostics.Debugger.IsAttached) // Keep window open when running in IDE
            {
                Console.ReadKey();
            }
            return(0);
        }