private string FindManagedFolder(string path) { if (Utils.IsMacPlatform()) { var dir = $"{path}/Contents/Resources/Data/Managed"; if (Directory.Exists(dir)) { return(dir); } } foreach (var di in new DirectoryInfo(path).GetDirectories()) { if ((di.Attributes & FileAttributes.ReparsePoint) != 0) { continue; } var dir = di.FullName; if (dir.EndsWith("Managed") && (File.Exists(Path.Combine(dir, "Assembly-CSharp.dll")) || File.Exists(Path.Combine(dir, "UnityEngine.dll")))) { return(dir); } var result = FindManagedFolder(dir); if (!string.IsNullOrEmpty(result)) { return(result); } } return(null); }
private string FindManagedFolder(string path) { if (Utils.IsMacPlatform()) { var dir = $"{path}/Contents/Resources/Data/Managed"; if (Directory.Exists(dir)) { return(dir); } } foreach (var dir in Directory.GetDirectories(path)) { if (dir.EndsWith("Managed")) { if (File.Exists(Path.Combine(dir, "Assembly-CSharp.dll")) || File.Exists(Path.Combine(dir, "UnityEngine.dll"))) { return(dir); } } var result = FindManagedFolder(dir); if (!string.IsNullOrEmpty(result)) { return(result); } } return(null); }
private string FindManagedFolder(string str) { if (Utils.IsMacPlatform()) { var path = $"{str}/Contents/Resources/Data/Managed"; if (Directory.Exists(path)) { return(path); } InactiveForm(); Log.Print("选择游戏主目录(包含Contents子目录)。"); return(null); } var regex = new Regex(".*_Data$"); var directory = new DirectoryInfo(str); foreach (var dir in directory.GetDirectories()) { var match = regex.Match(dir.Name); if (!match.Success) { continue; } var path = Path.Combine(str, $"{dir.Name}{Path.DirectorySeparatorChar}Managed"); if (Directory.Exists(path)) { return(path); } } InactiveForm(); Log.Print("选择游戏主目录(包含Data子目录)。"); return(null); }
private string FindGameFolder(string str) { var disks = new[] { @"C:\", @"D:\", @"E:\", @"F:\" }; var roots = new[] { "Games", "Program files", "Program files (x86)", "" }; var folders = new[] { @"Steam\SteamApps\common", @"GoG Galaxy\Games", "" }; if (Environment.OSVersion.Platform == PlatformID.Unix) { disks = new[] { Environment.GetEnvironmentVariable("HOME") }; roots = new[] { "Library/Application Support", ".steam" }; folders = new[] { "Steam/SteamApps/common", "steam/steamapps/common", "Steam/steamapps/common" }; } foreach (var disk in disks) { foreach (var root in roots) { foreach (var folder in folders) { var path = Path.Combine(disk, root); path = Path.Combine(path, folder); path = Path.Combine(path, str); if (!Directory.Exists(path)) { continue; } if (!Utils.IsMacPlatform()) { return(path); } foreach (var dir in Directory.GetDirectories(path)) { if (!dir.EndsWith(".app")) { continue; } path = Path.Combine(path, dir); break; } return(path); } } } return(null); }
private void RefreshForm() { if (!IsValid(selectedGame)) { InactiveForm(); return; } btnInstall.Text = "安装MOD管理器模块到游戏"; btnRestore.Enabled = false; gamePath = ""; if (string.IsNullOrEmpty(selectedGameParams.Path) || !Directory.Exists(selectedGameParams.Path)) { var result = FindGameFolder(selectedGame.Folder); if (string.IsNullOrEmpty(result)) { InactiveForm(); btnOpenFolder.ForeColor = Color.Red; btnOpenFolder.Text = "选择游戏主目录"; folderBrowserDialog.SelectedPath = null; Log.Print($"游戏主目录“{selectedGame.Folder}”不存在!"); return; } Log.Print($"已检测到游戏主目录“{result}”。"); selectedGameParams.Path = result; } if (!Utils.IsUnixPlatform() && !Directory.GetFiles(selectedGameParams.Path, "*.exe", SearchOption.TopDirectoryOnly).Any()) { InactiveForm(); Log.Print("请选择游戏可执行文件所在的目录。"); return; } if (Utils.IsMacPlatform() && !selectedGameParams.Path.EndsWith(".app")) { InactiveForm(); Log.Print("请选择游戏可执行文件(扩展名为.app)所在的目录。"); return; } Utils.TryParseEntryPoint(selectedGame.EntryPoint, out var assemblyName); gamePath = selectedGameParams.Path; btnOpenFolder.ForeColor = Color.Green; btnOpenFolder.Text = new DirectoryInfo(gamePath).Name; folderBrowserDialog.SelectedPath = gamePath; managedPath = FindManagedFolder(gamePath); managerPath = Path.Combine(managedPath, nameof(UnityModManager)); entryAssemblyPath = Path.Combine(managedPath, assemblyName); injectedEntryAssemblyPath = entryAssemblyPath; managerAssemblyPath = Path.Combine(managerPath, typeof(UnityModManager).Module.Name); entryPoint = selectedGame.EntryPoint; injectedEntryPoint = selectedGame.EntryPoint; assemblyDef = null; injectedAssemblyDef = null; managerDef = null; doorstopPath = Path.Combine(gamePath, doorstopFilename); doorstopConfigPath = Path.Combine(gamePath, doorstopConfigFilename); libraryPaths = new List <string>(); var gameSupportVersion = !string.IsNullOrEmpty(selectedGame.MinimalManagerVersion) ? Utils.ParseVersion(selectedGame.MinimalManagerVersion) : VER_0_22; foreach (var item in libraryFiles.Where(item => (item.Value & LibIncParam.Minimal_lt_0_22) <= 0 || gameSupportVersion < VER_0_22)) { libraryPaths.Add(Path.Combine(managerPath, item.Key)); } if (!string.IsNullOrEmpty(selectedGame.GameExe)) { if (selectedGame.GameExe.Contains('*')) { foreach (var file in new DirectoryInfo(gamePath).GetFiles(selectedGame.GameExe, SearchOption.TopDirectoryOnly)) { selectedGame.GameExe = file.Name; } } gameExePath = Path.Combine(gamePath, selectedGame.GameExe); } else { gameExePath = string.Empty; } var path = new DirectoryInfo(Application.StartupPath).FullName; if (path.StartsWith(gamePath)) { InactiveForm(); Log.Print("DUMM目录不能放在游戏主目录及其子目录下,请先关闭DUMM,再将DUMM目录移动到单独的目录下再试!"); return; } try { assemblyDef = ModuleDefMD.Load(File.ReadAllBytes(entryAssemblyPath)); } catch (Exception e) { InactiveForm(); Log.Print(e + Environment.NewLine + entryAssemblyPath); return; } var useOldPatchTarget = false; GameInfo.filepathInGame = Path.Combine(managerPath, "Config.xml"); if (File.Exists(GameInfo.filepathInGame)) { var gameConfig = GameInfo.ImportFromGame(); if (gameConfig == null || !Utils.TryParseEntryPoint(gameConfig.EntryPoint, out assemblyName)) { InactiveForm(); return; } injectedEntryPoint = gameConfig.EntryPoint; injectedEntryAssemblyPath = Path.Combine(managedPath, assemblyName); } else if (!string.IsNullOrEmpty(selectedGame.OldPatchTarget)) { if (!Utils.TryParseEntryPoint(selectedGame.OldPatchTarget, out assemblyName)) { InactiveForm(); return; } useOldPatchTarget = true; injectedEntryPoint = selectedGame.OldPatchTarget; injectedEntryAssemblyPath = Path.Combine(managedPath, assemblyName); } try { injectedAssemblyDef = injectedEntryAssemblyPath == entryAssemblyPath ? assemblyDef : ModuleDefMD.Load(File.ReadAllBytes(injectedEntryAssemblyPath)); if (File.Exists(managerAssemblyPath)) { managerDef = ModuleDefMD.Load(File.ReadAllBytes(managerAssemblyPath)); } } catch (Exception e) { InactiveForm(); Log.Print(e + Environment.NewLine + injectedEntryAssemblyPath + Environment.NewLine + managerAssemblyPath); return; } var disabledMethods = new List <InstallType>(); var unavailableMethods = new List <InstallType>(); var managerType = typeof(UnityModManager); var starterType = typeof(UnityModManagerStarter); Rescan: var v0_12_Installed = injectedAssemblyDef.Types.FirstOrDefault(x => x.Name == managerType.Name); var newWayInstalled = injectedAssemblyDef.Types.FirstOrDefault(x => x.Name == starterType.Name); var hasInjectedAssembly = v0_12_Installed != null || newWayInstalled != null; if (useOldPatchTarget && !hasInjectedAssembly) { useOldPatchTarget = false; injectedEntryPoint = selectedGame.EntryPoint; injectedEntryAssemblyPath = entryAssemblyPath; injectedAssemblyDef = assemblyDef; goto Rescan; } if (Utils.IsUnixPlatform() || !File.Exists(gameExePath)) { unavailableMethods.Add(InstallType.DoorstopProxy); selectedGameParams.InstallType = InstallType.Assembly; } else if (File.Exists(doorstopPath)) { disabledMethods.Add(InstallType.Assembly); selectedGameParams.InstallType = InstallType.DoorstopProxy; } if (hasInjectedAssembly) { disabledMethods.Add(InstallType.DoorstopProxy); selectedGameParams.InstallType = InstallType.Assembly; } foreach (var ctrl in installTypeGroup.Controls) { if (!(ctrl is RadioButton btn)) { continue; } if (unavailableMethods.Exists(x => x.ToString() == btn.Name)) { btn.Visible = false; btn.Enabled = false; continue; } if (disabledMethods.Exists(x => x.ToString() == btn.Name)) { btn.Visible = true; btn.Enabled = false; continue; } btn.Visible = true; btn.Enabled = true; btn.Checked = btn.Name == selectedGameParams.InstallType.ToString(); } if (selectedGameParams.InstallType == InstallType.Assembly) { btnRestore.Enabled = IsDirty(injectedAssemblyDef) && File.Exists($"{injectedEntryAssemblyPath}{Utils.FileSuffixCache}"); } tabControl.TabPages[1].Enabled = true; managerDef ??= injectedAssemblyDef; var managerInstalled = managerDef.Types.FirstOrDefault(x => x.Name == managerType.Name); if (managerInstalled != null && (hasInjectedAssembly || selectedGameParams.InstallType == InstallType.DoorstopProxy)) { btnInstall.Text = "更新MOD管理器模块"; btnInstall.Enabled = false; btnRemove.Enabled = true; Version version2; if (v0_12_Installed != null) { var versionString = managerInstalled.Fields.First(x => x.Name == nameof(UnityModManager.version)).Constant.Value.ToString(); version2 = Utils.ParseVersion(versionString); } else { version2 = managerDef.Assembly.Version; } installedVersion.Text = version2.ToString(); if (version > version2 && v0_12_Installed == null) { btnInstall.Enabled = true; } } else { installedVersion.Text = "-"; btnInstall.Enabled = true; btnRemove.Enabled = false; } }
private void RefreshForm() { if (!IsValid(selectedGame)) { InactiveForm(); return; } btnInstall.Text = "Install"; btnRestore.Enabled = false; additionallyGroupBox.Visible = false; gamePath = ""; if (string.IsNullOrEmpty(selectedGameParams.Path) || !Directory.Exists(selectedGameParams.Path)) { var result = FindGameFolder(selectedGame.Folder); if (string.IsNullOrEmpty(result)) { InactiveForm(); btnOpenFolder.ForeColor = System.Drawing.Color.FromArgb(192, 0, 0); btnOpenFolder.Text = "Please find Autonauts.exe"; openFileDialog1.Reset(); Log.Print($"Game folder '{selectedGame.Folder}' not found."); return; } Log.Print($"Game path detected as '{result}'."); selectedGameParams.Path = result; } if (!Utils.IsUnixPlatform() && !Directory.GetFiles(selectedGameParams.Path, "*.exe", SearchOption.TopDirectoryOnly).Any()) { InactiveForm(); Log.Print("Select the game folder where an exe file is located."); return; } if (Utils.IsMacPlatform() && !selectedGameParams.Path.EndsWith(".app")) { InactiveForm(); Log.Print("Select the game folder where name ending with '.app'."); return; } Utils.TryParseEntryPoint(selectedGame.EntryPoint, out var assemblyName); gamePath = selectedGameParams.Path; btnOpenFolder.ForeColor = System.Drawing.Color.Black; btnOpenFolder.Text = "Change Autonauts Location"; openFileDialog1.InitialDirectory = gamePath; managedPath = FindManagedFolder(gamePath); if (managedPath == null) { InactiveForm(); Log.Print("Select Autonauts.exe"); return; } managerPath = Path.Combine(managedPath, nameof(UnityModManager)); entryAssemblyPath = Path.Combine(managedPath, assemblyName); injectedEntryAssemblyPath = entryAssemblyPath; managerAssemblyPath = Path.Combine(managerPath, typeof(UnityModManager).Module.Name); entryPoint = selectedGame.EntryPoint; injectedEntryPoint = selectedGame.EntryPoint; assemblyDef = null; injectedAssemblyDef = null; managerDef = null; if (!string.IsNullOrEmpty(selectedGame.GameExe)) { if (selectedGame.GameExe.Contains('*')) { foreach (var file in new DirectoryInfo(gamePath).GetFiles(selectedGame.GameExe, SearchOption.TopDirectoryOnly)) { selectedGame.GameExe = file.Name; } } gameExePath = Path.Combine(gamePath, selectedGame.GameExe); } else { gameExePath = string.Empty; } doorstopPath = Path.Combine(gamePath, doorstopFilename); doorstopConfigPath = Path.Combine(gamePath, doorstopConfigFilename); libraryPaths = new string[libraryFiles.Length]; for (int i = 0; i < libraryFiles.Length; i++) { libraryPaths[i] = Path.Combine(managerPath, libraryFiles[i]); } var parent = new DirectoryInfo(Application.StartupPath).Parent; for (int i = 0; i < 3; i++) { if (parent == null) { break; } if (parent.FullName == gamePath) { InactiveForm(); Log.Print("UMM Installer should not be located in the game folder."); return; } parent = parent.Parent; } //machineConfigPath = string.Empty; //machineDoc = null; //if (!string.IsNullOrEmpty(selectedGame.MachineConfig)) //{ // machineConfigPath = Path.Combine(gamePath, selectedGame.MachineConfig); // try // { // machineDoc = XDocument.Load(machineConfigPath); // } // catch (Exception e) // { // InactiveForm(); // Log.Print(e.ToString()); // return; // } //} try { assemblyDef = ModuleDefMD.Load(File.ReadAllBytes(entryAssemblyPath)); } catch (Exception e) { InactiveForm(); Log.Print(e.ToString()); return; } var useOldPatchTarget = false; GameInfo.filepathInGame = Path.Combine(managerPath, "Config.xml"); if (File.Exists(GameInfo.filepathInGame)) { var gameConfig = GameInfo.ImportFromGame(); if (gameConfig == null || !Utils.TryParseEntryPoint(gameConfig.EntryPoint, out assemblyName)) { InactiveForm(); return; } injectedEntryPoint = gameConfig.EntryPoint; injectedEntryAssemblyPath = Path.Combine(managedPath, assemblyName); } else if (!string.IsNullOrEmpty(selectedGame.OldPatchTarget)) { if (!Utils.TryParseEntryPoint(selectedGame.OldPatchTarget, out assemblyName)) { InactiveForm(); return; } useOldPatchTarget = true; injectedEntryPoint = selectedGame.OldPatchTarget; injectedEntryAssemblyPath = Path.Combine(managedPath, assemblyName); } try { if (injectedEntryAssemblyPath == entryAssemblyPath) { injectedAssemblyDef = assemblyDef; } else { injectedAssemblyDef = ModuleDefMD.Load(File.ReadAllBytes(injectedEntryAssemblyPath)); } if (File.Exists(managerAssemblyPath)) { managerDef = ModuleDefMD.Load(File.ReadAllBytes(managerAssemblyPath)); } } catch (Exception e) { InactiveForm(); Log.Print(e.ToString()); return; } var disabledMethods = new List <InstallType>(); var unavailableMethods = new List <InstallType>(); var managerType = typeof(UnityModManager); var starterType = typeof(Injection.UnityModManagerStarter); Rescan: var v0_12_Installed = injectedAssemblyDef.Types.FirstOrDefault(x => x.Name == managerType.Name); var newWayInstalled = injectedAssemblyDef.Types.FirstOrDefault(x => x.Name == starterType.Name); var hasInjectedAssembly = v0_12_Installed != null || newWayInstalled != null; if (useOldPatchTarget && !hasInjectedAssembly) { useOldPatchTarget = false; injectedEntryPoint = selectedGame.EntryPoint; injectedEntryAssemblyPath = entryAssemblyPath; injectedAssemblyDef = assemblyDef; goto Rescan; } //if (machineDoc == null) //{ // unavailableMethods.Add(InstallType.Config); // selectedGameParams.InstallType = InstallType.Assembly; //} //else if (hasInjectedAssembly) //{ // disabledMethods.Add(InstallType.Config); // selectedGameParams.InstallType = InstallType.Assembly; //} //else if (machineDoc.Descendants("cryptoClass").Any(x => x.HasAttributes && x.FirstAttribute.Name.LocalName == "ummRngWrapper")) //{ // disabledMethods.Add(InstallType.Assembly); // selectedGameParams.InstallType = InstallType.Config; //} if (Utils.IsUnixPlatform() || !File.Exists(gameExePath)) { unavailableMethods.Add(InstallType.DoorstopProxy); selectedGameParams.InstallType = InstallType.Assembly; } else if (File.Exists(doorstopPath)) { disabledMethods.Add(InstallType.Assembly); selectedGameParams.InstallType = InstallType.DoorstopProxy; } if (hasInjectedAssembly) { disabledMethods.Add(InstallType.DoorstopProxy); selectedGameParams.InstallType = InstallType.Assembly; } //if (selectedGameParams.InstallType == InstallType.Config) //{ // btnRestore.Enabled = IsDirty(machineDoc) && File.Exists($"{machineConfigPath}.original_"); //} if (selectedGameParams.InstallType == InstallType.Assembly) { btnRestore.Enabled = IsDirty(injectedAssemblyDef) && File.Exists($"{injectedEntryAssemblyPath}.original_"); } tabControl.TabPages[1].Enabled = true; managerDef = managerDef ?? injectedAssemblyDef; var managerInstalled = managerDef.Types.FirstOrDefault(x => x.Name == managerType.Name); if (managerInstalled != null && (hasInjectedAssembly || selectedGameParams.InstallType == InstallType.DoorstopProxy)) { btnInstall.Text = "Update"; btnInstall.Enabled = false; btnRemove.Enabled = true; Version version2; if (v0_12_Installed != null) { var versionString = managerInstalled.Fields.First(x => x.Name == nameof(UnityModManager.version)).Constant.Value.ToString(); version2 = Utils.ParseVersion(versionString); } else { version2 = managerDef.Assembly.Version; } installedVersion.Text = version2.ToString(); if (version > version2 && v0_12_Installed == null) { btnInstall.Enabled = true; } } else { installedVersion.Text = "-"; btnInstall.Enabled = true; btnRemove.Enabled = false; } if (!string.IsNullOrEmpty(selectedGame.Additionally)) { notesTextBox.Text = selectedGame.Additionally; additionallyGroupBox.Visible = true; } }