//private bool InjectConfig(Actions action, XDocument doc = null, bool write = true) //{ // var originalMachineConfigPath = $"{machineConfigPath}.original_"; // var gameConfigPath = GameInfo.filepathInGame; // var success = false; // switch (action) // { // case Actions.Install: // try // { // if (!Directory.Exists(managerPath)) // Directory.CreateDirectory(managerPath); // Utils.MakeBackup(machineConfigPath); // Utils.MakeBackup(libraryPaths); // if (!IsDirty(doc)) // { // File.Copy(machineConfigPath, originalMachineConfigPath, true); // } // MakeDirty(doc); // if (!InjectConfig(Actions.Remove, doc, false)) // { // Log.Print("Installation failed. Can't uninstall the previous version."); // goto EXIT; // } // Log.Print($"Applying patch to '{Path.GetFileName(machineConfigPath)}'..."); // foreach (var mapping in doc.Descendants("cryptoNameMapping")) // { // foreach(var cryptoClasses in mapping.Elements("cryptoClasses")) // { // if (!cryptoClasses.Elements("cryptoClass").Any(x => x.FirstAttribute.Name.LocalName == "ummRngWrapper")) // { // cryptoClasses.Add(new XElement("cryptoClass", new XAttribute("ummRngWrapper", "UnityModManagerNet.RngWrapper, UnityModManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"))); // } // } // if (!mapping.Elements("nameEntry").Any(x => x.LastAttribute.Value == "ummRngWrapper")) // { // //mapping.Add(new XElement("nameEntry", new XAttribute("name", "RandomNumberGenerator"), new XAttribute("class", "ummRngWrapper"))); // mapping.Add(new XElement("nameEntry", new XAttribute("name", "System.Security.Cryptography.RandomNumberGenerator"), new XAttribute("class", "ummRngWrapper"))); // } // break; // } // doc.Save(machineConfigPath); // DoactionLibraries(Actions.Install); // DoactionGameConfig(Actions.Install); // Log.Print("Installation was successful."); // success = true; // } // catch (Exception e) // { // Log.Print(e.ToString()); // Utils.RestoreBackup(machineConfigPath); // Utils.RestoreBackup(libraryPaths); // Utils.RestoreBackup(gameConfigPath); // Log.Print("Installation failed."); // } // break; // case Actions.Remove: // try // { // Utils.MakeBackup(gameConfigPath); // if (write) // { // Utils.MakeBackup(machineConfigPath); // Utils.MakeBackup(libraryPaths); // } // Log.Print("Removing patch..."); // MakeDirty(doc); // foreach (var mapping in doc.Descendants("cryptoNameMapping")) // { // foreach (var cryptoClasses in mapping.Elements("cryptoClasses")) // { // foreach (var cryptoClass in cryptoClasses.Elements("cryptoClass")) // { // if (cryptoClass.FirstAttribute.Name.LocalName == "ummRngWrapper") // { // cryptoClass.Remove(); // } // } // } // foreach (var nameEntry in mapping.Elements("nameEntry")) // { // if (nameEntry.LastAttribute.Value == "ummRngWrapper") // { // nameEntry.Remove(); // } // } // break; // } // if (write) // { // doc.Save(machineConfigPath); // DoactionLibraries(Actions.Remove); // DoactionGameConfig(Actions.Remove); // Log.Print("Removal was successful."); // } // success = true; // } // catch (Exception e) // { // Log.Print(e.ToString()); // if (write) // { // Utils.RestoreBackup(machineConfigPath); // Utils.RestoreBackup(libraryPaths); // Utils.RestoreBackup(gameConfigPath); // Log.Print("Removal failed."); // } // } // break; // } // EXIT: // if (write) // { // try // { // Utils.DeleteBackup(machineConfigPath); // Utils.DeleteBackup(libraryPaths); // Utils.DeleteBackup(gameConfigPath); // } // catch (Exception) // { // } // } // return success; //} private bool InjectAssembly(Actions action, ModuleDefMD assemblyDef, bool write = true) { var managerType = typeof(UnityModManager); var starterType = typeof(Injection.UnityModManagerStarter); var gameConfigPath = GameInfo.filepathInGame; var assemblyPath = Path.Combine(managedPath, assemblyDef.Name); var originalAssemblyPath = $"{assemblyPath}.original_"; var success = false; switch (action) { case Actions.Install: { try { Log.Print("======================================="); if (!Directory.Exists(managerPath)) { Directory.CreateDirectory(managerPath); } Utils.MakeBackup(assemblyPath); Utils.MakeBackup(libraryPaths); if (!IsDirty(assemblyDef)) { File.Copy(assemblyPath, originalAssemblyPath, true); MakeDirty(assemblyDef); } if (!InjectAssembly(Actions.Remove, injectedAssemblyDef, assemblyDef != injectedAssemblyDef)) { Log.Print("Installation failed. Can't uninstall the previous version."); goto EXIT; } Log.Print($"Applying patch to '{Path.GetFileName(assemblyPath)}'..."); if (!Utils.TryGetEntryPoint(assemblyDef, entryPoint, out var methodDef, out var insertionPlace, true)) { goto EXIT; } var starterDef = ModuleDefMD.Load(starterType.Module); var starter = starterDef.Types.First(x => x.Name == starterType.Name); starterDef.Types.Remove(starter); assemblyDef.Types.Add(starter); var instr = OpCodes.Call.ToInstruction(starter.Methods.First(x => x.Name == nameof(Injection.UnityModManagerStarter.Start))); if (insertionPlace == "before") { methodDef.Body.Instructions.Insert(0, instr); } else { methodDef.Body.Instructions.Insert(methodDef.Body.Instructions.Count - 1, instr); } assemblyDef.Write(assemblyPath); DoactionLibraries(Actions.Install); DoactionGameConfig(Actions.Install); Log.Print("Installation was successful."); success = true; } catch (Exception e) { Log.Print(e.ToString()); Utils.RestoreBackup(assemblyPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("Installation failed."); } } break; case Actions.Remove: { try { if (write) { Log.Print("======================================="); } Utils.MakeBackup(gameConfigPath); var v0_12_Installed = assemblyDef.Types.FirstOrDefault(x => x.Name == managerType.Name); var newWayInstalled = assemblyDef.Types.FirstOrDefault(x => x.Name == starterType.Name); if (v0_12_Installed != null || newWayInstalled != null) { if (write) { Utils.MakeBackup(assemblyPath); Utils.MakeBackup(libraryPaths); } Log.Print("Removing patch..."); Instruction instr = null; if (newWayInstalled != null) { instr = OpCodes.Call.ToInstruction(newWayInstalled.Methods.First(x => x.Name == nameof(Injection.UnityModManagerStarter.Start))); } else if (v0_12_Installed != null) { instr = OpCodes.Call.ToInstruction(v0_12_Installed.Methods.First(x => x.Name == nameof(UnityModManager.Start))); } if (!string.IsNullOrEmpty(injectedEntryPoint)) { if (!Utils.TryGetEntryPoint(assemblyDef, injectedEntryPoint, out var methodDef, out _, true)) { goto EXIT; } for (int i = 0; i < methodDef.Body.Instructions.Count; i++) { if (methodDef.Body.Instructions[i].OpCode == instr.OpCode && methodDef.Body.Instructions[i].Operand == instr.Operand) { methodDef.Body.Instructions.RemoveAt(i); break; } } } if (newWayInstalled != null) { assemblyDef.Types.Remove(newWayInstalled); } else if (v0_12_Installed != null) { assemblyDef.Types.Remove(v0_12_Installed); } if (!IsDirty(assemblyDef)) { MakeDirty(assemblyDef); } if (write) { assemblyDef.Write(assemblyPath); DoactionLibraries(Actions.Remove); DoactionGameConfig(Actions.Remove); Log.Print("Removal was successful."); } } success = true; } catch (Exception e) { Log.Print(e.ToString()); if (write) { Utils.RestoreBackup(assemblyPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("Removal failed."); } } } break; } EXIT: if (write) { try { Utils.DeleteBackup(assemblyPath); Utils.DeleteBackup(libraryPaths); Utils.DeleteBackup(gameConfigPath); } catch (Exception) { } } return(success); }
private bool InjectAssembly(Actions action, ModuleDefMD assemblyDef, bool write = true) { var managerType = typeof(UnityModManager); var starterType = typeof(UnityModManagerStarter); var gameConfigPath = GameInfo.filepathInGame; var assemblyPath = Path.Combine(managedPath, assemblyDef.Name); var originalAssemblyPath = $"{assemblyPath}{Utils.FileSuffixCache}"; var success = false; switch (action) { case Actions.Install: { try { Log.Print("======================================="); if (!Directory.Exists(managerPath)) { Directory.CreateDirectory(managerPath); } Utils.MakeBackup(assemblyPath); Utils.MakeBackup(libraryPaths); if (!IsDirty(assemblyDef)) { File.Copy(assemblyPath, originalAssemblyPath, true); MakeDirty(assemblyDef); } if (!InjectAssembly(Actions.Remove, injectedAssemblyDef, assemblyDef != injectedAssemblyDef)) { Log.Print("安装管理器模块到游戏失败,不能卸载上一个版本!"); goto EXIT; } Log.Print($"正在注入文件“{Path.GetFileName(assemblyPath)}”……"); if (!Utils.TryGetEntryPoint(assemblyDef, entryPoint, out var methodDef, out var insertionPlace, true)) { goto EXIT; } var starterDef = ModuleDefMD.Load(starterType.Module); var starter = starterDef.Types.First(x => x.Name == starterType.Name); starterDef.Types.Remove(starter); assemblyDef.Types.Add(starter); var instr = OpCodes.Call.ToInstruction(starter.Methods.First(x => x.Name == nameof(UnityModManagerStarter.Start))); if (insertionPlace == "before") { methodDef.Body.Instructions.Insert(0, instr); } else { methodDef.Body.Instructions.Insert(methodDef.Body.Instructions.Count - 1, instr); } assemblyDef.Write(assemblyPath); DoactionLibraries(Actions.Install); DoactionGameConfig(Actions.Install); Log.Print("安装管理器模块到游戏成功!"); success = true; } catch (Exception e) { Log.Print(e.ToString()); Utils.RestoreBackup(assemblyPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("安装管理器模块到游戏失败!"); } } break; case Actions.Remove: { try { if (write) { Log.Print("======================================="); } Utils.MakeBackup(gameConfigPath); var v0_12_Installed = assemblyDef.Types.FirstOrDefault(x => x.Name == managerType.Name); var newWayInstalled = assemblyDef.Types.FirstOrDefault(x => x.Name == starterType.Name); if (v0_12_Installed != null || newWayInstalled != null) { if (write) { Utils.MakeBackup(assemblyPath); Utils.MakeBackup(libraryPaths); } Log.Print("正在从游戏卸载管理器模块……"); Instruction instr = null; if (newWayInstalled != null) { instr = OpCodes.Call.ToInstruction(newWayInstalled.Methods.First(x => x.Name == nameof(UnityModManagerStarter.Start))); } else if (v0_12_Installed != null) { instr = OpCodes.Call.ToInstruction(v0_12_Installed.Methods.First(x => x.Name == nameof(UnityModManager.Start))); } if (!string.IsNullOrEmpty(injectedEntryPoint)) { if (!Utils.TryGetEntryPoint(assemblyDef, injectedEntryPoint, out var methodDef, out _, true)) { goto EXIT; } for (var i = 0; i < methodDef.Body.Instructions.Count; i++) { if (methodDef.Body.Instructions[i].OpCode != instr.OpCode || methodDef.Body.Instructions[i].Operand != instr.Operand) { continue; } methodDef.Body.Instructions.RemoveAt(i); break; } } if (newWayInstalled != null) { assemblyDef.Types.Remove(newWayInstalled); } else if (v0_12_Installed != null) { assemblyDef.Types.Remove(v0_12_Installed); } if (!IsDirty(assemblyDef)) { MakeDirty(assemblyDef); } if (write) { assemblyDef.Write(assemblyPath); DoactionLibraries(Actions.Remove); DoactionGameConfig(Actions.Remove); Log.Print("从游戏卸载管理器模块成功!"); } } success = true; } catch (Exception e) { Log.Print(e.ToString()); if (write) { Utils.RestoreBackup(assemblyPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("从游戏卸载管理器模块失败!"); } } } break; } EXIT: if (!write) { return(success); } Utils.DeleteBackup(assemblyPath); Utils.DeleteBackup(libraryPaths); Utils.DeleteBackup(gameConfigPath); return(success); }
private bool InstallDoorstop(Actions action, bool write = true) { var gameConfigPath = GameInfo.filepathInGame; var success = false; switch (action) { case Actions.Install: try { Log.Print("======================================="); if (!Directory.Exists(managerPath)) { Directory.CreateDirectory(managerPath); } Utils.MakeBackup(doorstopPath); Utils.MakeBackup(doorstopConfigPath); Utils.MakeBackup(libraryPaths); if (!InstallDoorstop(Actions.Remove, false)) { Log.Print("Installation failed. Can't uninstall the previous version."); goto EXIT; } Log.Print($"Copying files to game..."); var arch = Utils.UnmanagedDllIs64Bit(gameExePath); var filename = arch == true ? "winhttp_x64.dll" : "winhttp_x86.dll"; Log.Print($" '{filename}'"); File.Copy(filename, doorstopPath, true); Log.Print($" '{doorstopConfigFilename}'"); File.WriteAllText(doorstopConfigPath, "[UnityDoorstop]" + Environment.NewLine + "enabled = true" + Environment.NewLine + "targetAssembly = " + managerAssemblyPath); DoactionLibraries(Actions.Install); DoactionGameConfig(Actions.Install); Log.Print("Installation was successful."); success = true; } catch (Exception e) { Log.Print(e.ToString()); Utils.RestoreBackup(doorstopPath); Utils.RestoreBackup(doorstopConfigPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("Installation failed."); } break; case Actions.Remove: try { if (write) { Log.Print("======================================="); } Utils.MakeBackup(gameConfigPath); if (write) { Utils.MakeBackup(doorstopPath); Utils.MakeBackup(doorstopConfigPath); Utils.MakeBackup(libraryPaths); } Log.Print($"Deleting files from game..."); Log.Print($" '{doorstopFilename}'"); File.Delete(doorstopPath); Log.Print($" '{doorstopConfigFilename}'"); File.Delete(doorstopConfigPath); if (write) { DoactionLibraries(Actions.Remove); DoactionGameConfig(Actions.Remove); Log.Print("Removal was successful."); } success = true; } catch (Exception e) { Log.Print(e.ToString()); if (write) { Utils.RestoreBackup(doorstopPath); Utils.RestoreBackup(doorstopConfigPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("Removal failed."); } } break; } EXIT: if (write) { try { Utils.DeleteBackup(doorstopPath); Utils.DeleteBackup(doorstopConfigPath); Utils.DeleteBackup(libraryPaths); Utils.DeleteBackup(gameConfigPath); } catch (Exception) { } } return(success); }
private bool InstallDoorstop(Actions action, bool write = true) { var gameConfigPath = GameInfo.filepathInGame; var success = false; switch (action) { case Actions.Install: try { Log.Print("======================================="); if (!Directory.Exists(managerPath)) { Directory.CreateDirectory(managerPath); } Utils.MakeBackup(doorstopPath); Utils.MakeBackup(doorstopConfigPath); Utils.MakeBackup(libraryPaths); if (!InstallDoorstop(Actions.Remove, false)) { Log.Print("安装管理器模块到游戏失败,不能卸载上一个版本!"); goto EXIT; } Log.Print("正在复制文件到游戏……"); var arch = Utils.UnmanagedDllIs64Bit(gameExePath); var filename = arch == true ? doorstopFilenameX64 : doorstopFilenameX86; Log.Print($" '{filename}'"); File.Copy(filename, doorstopPath, true); Log.Print($" '{doorstopConfigFilename}'"); File.WriteAllText(doorstopConfigPath, $@"[UnityDoorstop]{Environment.NewLine}enabled = true{Environment.NewLine}targetAssembly = {managerAssemblyPath}"); DoactionLibraries(Actions.Install); DoactionGameConfig(Actions.Install); Log.Print("安装管理器模块到游戏成功!"); success = true; } catch (Exception e) { Log.Print(e.ToString()); Utils.RestoreBackup(doorstopPath); Utils.RestoreBackup(doorstopConfigPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("安装管理器模块到游戏失败!"); } break; case Actions.Remove: try { if (write) { Log.Print("======================================="); } Utils.MakeBackup(gameConfigPath); if (write) { Utils.MakeBackup(doorstopPath); Utils.MakeBackup(doorstopConfigPath); Utils.MakeBackup(libraryPaths); } Log.Print("正在从游戏目录删除文件……"); Log.Print($" '{doorstopFilename}'"); File.Delete(doorstopPath); Log.Print($" '{doorstopConfigFilename}'"); File.Delete(doorstopConfigPath); if (write) { DoactionLibraries(Actions.Remove); DoactionGameConfig(Actions.Remove); Log.Print("从游戏目录删除文件成功!"); } success = true; } catch (Exception e) { Log.Print(e.ToString()); if (write) { Utils.RestoreBackup(doorstopPath); Utils.RestoreBackup(doorstopConfigPath); Utils.RestoreBackup(libraryPaths); Utils.RestoreBackup(gameConfigPath); Log.Print("从游戏目录删除文件失败!"); } } break; } EXIT: if (write) { Utils.DeleteBackup(doorstopPath); Utils.DeleteBackup(doorstopConfigPath); Utils.DeleteBackup(libraryPaths); Utils.DeleteBackup(gameConfigPath); } return(success); }