Пример #1
0
        private static bool PatchUnityExe(string managedDir, string unityOutputDLL, out string message)
        {
            message = null;

            try
            {
                var injectedDLL = Path.GetFullPath($"{managedDir}\\BepInEx.Bootstrap.dll");
                File.WriteAllBytes(injectedDLL, EmbeddedResource.Get("BepInEx.Patcher.BepInEx.Bootstrap.dll"));

                var defaultResolver = new DefaultAssemblyResolver();
                defaultResolver.AddSearchDirectory(managedDir);
                var rp = new ReaderParameters
                {
                    AssemblyResolver = defaultResolver
                };

                var unityBackupDLL = $"{GetUnityEngineAssembly(managedDir)}.bak";

                //determine which assembly to use as a base
                var unity = AssemblyDefinition.ReadAssembly(unityOutputDLL, rp);

                if (!VerifyAssembly(unity, out message))
                {
                    //try and fall back to .bak if exists
                    if (File.Exists(unityBackupDLL))
                    {
                        unity.Dispose();
                        unity = AssemblyDefinition.ReadAssembly(unityBackupDLL, rp);

                        if (!VerifyAssembly(unity, out message))
                        {
                            //can't use anything
                            unity.Dispose();
                            message += "\r\nThe backup is not usable.";
                            return(false);
                        }
                    }
                    else
                    {
                        //can't use anything
                        unity.Dispose();
                        message += "\r\nNo backup exists.";
                        return(false);
                    }
                }
                else
                {
                    //make a backup of the assembly
                    File.Copy(unityOutputDLL, unityBackupDLL, true);
                    unity.Dispose();
                    unity = AssemblyDefinition.ReadAssembly(unityBackupDLL, rp);
                }

                //patch
                using (unity)
                    using (var injected = AssemblyDefinition.ReadAssembly(injectedDLL, rp))
                    {
                        InjectAssembly(unity, injected);

                        unity.Write(unityOutputDLL);
                    }
            }
            catch (Exception e)
            {
                message = e.ToString();
                return(false);
            }

            return(true);
        }