예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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;
            }
        }
예제 #6
0
        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;
            }
        }