Exemple #1
0
        //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);
        }
Exemple #3
0
        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);
        }