From a6cb4daff46ca5d597a6a520b6c917818403cc7b Mon Sep 17 00:00:00 2001
From: Bepis <36346617+bbepis@users.noreply.github.com>
Date: Mon, 11 Mar 2019 15:53:29 +1100
Subject: [PATCH] Implement assembly patching in installer
---
BepInEx.Installer/BepInEx.Installer.csproj | 1 +
BepInEx.Installer/Config.cs | 11 +
.../Patching/FrameworkInstaller.cs | 201 +++++++++++++++--
BepInEx.Installer/Utility.cs | 29 +++
BepInEx.Patcher/BepInEx.Patcher.csproj | 83 -------
BepInEx.Patcher/EmbeddedResource.cs | 22 --
BepInEx.Patcher/Program.cs | 206 ------------------
BepInEx.Patcher/Properties/AssemblyInfo.cs | 36 ---
BepInEx.Patcher/packages.config | 7 -
BepInEx.sln | 10 -
scripts/createInstallerPackage.ps1 | 5 +-
11 files changed, 221 insertions(+), 390 deletions(-)
create mode 100644 BepInEx.Installer/Utility.cs
delete mode 100644 BepInEx.Patcher/BepInEx.Patcher.csproj
delete mode 100644 BepInEx.Patcher/EmbeddedResource.cs
delete mode 100644 BepInEx.Patcher/Program.cs
delete mode 100644 BepInEx.Patcher/Properties/AssemblyInfo.cs
delete mode 100644 BepInEx.Patcher/packages.config
diff --git a/BepInEx.Installer/BepInEx.Installer.csproj b/BepInEx.Installer/BepInEx.Installer.csproj
index e32323d..fc9bc00 100644
--- a/BepInEx.Installer/BepInEx.Installer.csproj
+++ b/BepInEx.Installer/BepInEx.Installer.csproj
@@ -68,6 +68,7 @@
+
formMain.cs
diff --git a/BepInEx.Installer/Config.cs b/BepInEx.Installer/Config.cs
index 31882fe..4d9d31d 100644
--- a/BepInEx.Installer/Config.cs
+++ b/BepInEx.Installer/Config.cs
@@ -21,8 +21,19 @@ dump-assemblies=false";
public string OutputConfig { get; protected set; }
+ public string TargetAssembly { get; protected set; }
+ public string TargetType { get; protected set; }
+ public string TargetMethod { get; protected set; }
+
+ public RuntimePatchesType RuntimePatchesType { get; protected set; }
+
public Config(string targetAssembly, string targetType, string targetMethod, RuntimePatchesType runtimePatchesType)
{
+ TargetAssembly = targetAssembly;
+ TargetType = targetType;
+ TargetMethod = targetMethod;
+ RuntimePatchesType = runtimePatchesType;
+
OutputConfig = ConfigTemplate
.Replace("entrypoint-assembly=UnityEngine.dll", $"entrypoint-assembly={targetAssembly}")
.Replace("entrypoint-type=Application", $"entrypoint-type={targetType}")
diff --git a/BepInEx.Installer/Patching/FrameworkInstaller.cs b/BepInEx.Installer/Patching/FrameworkInstaller.cs
index 7c6d8ea..7693da6 100644
--- a/BepInEx.Installer/Patching/FrameworkInstaller.cs
+++ b/BepInEx.Installer/Patching/FrameworkInstaller.cs
@@ -1,7 +1,10 @@
using System;
using System.IO;
using System.Linq;
+using System.Windows.Forms;
using Ionic.Zip;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
namespace BepInEx.Installer.Patching
{
@@ -22,17 +25,27 @@ namespace BepInEx.Installer.Patching
public void Install()
{
- switch (InstallationType)
+ try
{
- case InstallationType.Doorstop:
- DoorstopInstallation();
- break;
- case InstallationType.CryptoRng:
- throw new NotImplementedException();
- case InstallationType.AssemblyPatch:
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(InstallationType));
+ switch (InstallationType)
+ {
+ case InstallationType.Doorstop:
+ DoorstopInstallation();
+ break;
+ case InstallationType.CryptoRng:
+ throw new NotImplementedException();
+ case InstallationType.AssemblyPatch:
+ AssemblyPatchInstallation();
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(InstallationType));
+ }
+
+ MessageBox.Show("Installation completed successfully.", "Installation", MessageBoxButtons.OK, MessageBoxIcon.None);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error during installation", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@@ -41,16 +54,7 @@ namespace BepInEx.Installer.Patching
return ZipFile.Read(EmbeddedResource.GetStream("BepInEx.Installer.InstallPackage.zip"));
}
- private static MemoryStream ExtractZipEntry(ZipEntry entry)
- {
- MemoryStream ms = new MemoryStream((int)entry.UncompressedSize);
-
- entry.Extract(ms);
-
- ms.Position = 0;
-
- return ms;
- }
+ #region Doorstop
private const string DoorstopConfig = @"[UnityDoorstop]
# Specifies whether assembly executing is enabled
@@ -75,7 +79,7 @@ targetAssembly=BepInEx\core\BepInEx.Preloader.dll";
using (var packageZip = GetPackageZip())
{
- using (var doorstopZip = ZipFile.Read(ExtractZipEntry(packageZip[doorstopZipName])))
+ using (var doorstopZip = ZipFile.Read(packageZip[doorstopZipName].ExtractEntry()))
{
doorstopZip["winhttp.dll"].Extract(TargetGame.DirectoryPath, ExtractExistingFileAction.OverwriteSilently);
}
@@ -87,8 +91,7 @@ targetAssembly=BepInEx\core\BepInEx.Preloader.dll";
{
string localFilename = Path.Combine(coreDirectory, Path.GetFileName(entry.FileName));
- using (FileStream fs = new FileStream(localFilename, FileMode.Create))
- entry.Extract(fs);
+ entry.ExtractEntry(localFilename);
}
}
@@ -96,5 +99,157 @@ targetAssembly=BepInEx\core\BepInEx.Preloader.dll";
File.WriteAllText(Path.Combine(TargetGame.DirectoryPath, "doorstop_config.ini"), DoorstopConfig);
}
+
+ #endregion
+
+ #region Assembly Patch
+
+ private void AssemblyPatchInstallation()
+ {
+ string bepinexDirectory = Path.Combine(TargetGame.DirectoryPath, "BepInEx");
+ string coreDirectory = Path.Combine(bepinexDirectory, "core");
+
+ string managedDir = Path.Combine(TargetGame.DataFolder, "Managed");
+ string unityEngineDllPath = Path.Combine(managedDir, Config.TargetAssembly);
+ string bootstrapDllPath = Path.Combine(managedDir, "BepInEx.Bootstrap.dll");
+
+ if (!File.Exists(unityEngineDllPath))
+ throw new ArgumentException($"Cannot find target assembly '{unityEngineDllPath}'");
+
+ Directory.CreateDirectory(coreDirectory);
+
+ string coreAssemblyZipFolder = TargetGame.UnityEngineType == TargetGame.UnityGameType.v2017Plus
+ ? "v2018"
+ : "legacy";
+
+ using (var packageZip = GetPackageZip())
+ {
+ var selectedEntries = packageZip.SelectEntries("*", "shared")
+ .Concat(packageZip.SelectEntries("*", coreAssemblyZipFolder))
+ .Where(x => !x.FileName.EndsWith("BepInEx.Preloader.dll"));
+
+ foreach (var entry in selectedEntries)
+ {
+ string localFilename = Path.Combine(coreDirectory, Path.GetFileName(entry.FileName));
+
+ entry.ExtractEntry(localFilename);
+ }
+
+ packageZip["bootstrap\\BepInEx.Bootstrap.dll"].ExtractEntry(bootstrapDllPath);
+ }
+
+ if (!PatchUnityGame(managedDir, unityEngineDllPath, bootstrapDllPath, out var message))
+ throw new Exception(message);
+ }
+
+ bool PatchUnityGame(string managedDir, string unityEngineDll, string bootstrapDll, out string message)
+ {
+ var defaultResolver = new DefaultAssemblyResolver();
+ defaultResolver.AddSearchDirectory(managedDir);
+ var rp = new ReaderParameters
+ {
+ AssemblyResolver = defaultResolver
+ };
+
+ string unityBackupDll = Path.GetFullPath($"{unityEngineDll}.bak");
+
+ //determine which assembly to use as a base
+ AssemblyDefinition unity = AssemblyDefinition.ReadAssembly(unityEngineDll, rp);
+
+ if (!VerifyAssembly(unity))
+ {
+ //try and fall back to .bak if exists
+ if (File.Exists(unityBackupDll))
+ {
+ unity.Dispose();
+ unity = AssemblyDefinition.ReadAssembly(unityBackupDll, rp);
+
+ if (!VerifyAssembly(unity))
+ {
+ //can't use anything
+ unity.Dispose();
+ message = "Target assembly already has BepInEx injected, and the backup is not usable.";
+ return false;
+ }
+ }
+ else
+ {
+ //can't use anything
+ unity.Dispose();
+ message = "Target assembly already has BepInEx injected, and no backup exists.";
+ return false;
+ }
+ }
+ else
+ {
+ //make a backup of the assembly
+ File.Copy(unityEngineDll, unityBackupDll, true);
+ unity.Dispose();
+ unity = AssemblyDefinition.ReadAssembly(unityBackupDll, rp);
+ }
+
+ //patch
+ using (unity)
+ using (AssemblyDefinition injected = AssemblyDefinition.ReadAssembly(bootstrapDll, rp))
+ {
+ InjectAssembly(unity, injected);
+
+ unity.Write(unityEngineDll);
+ }
+
+ message = null;
+ return true;
+ }
+
+ void InjectAssembly(AssemblyDefinition targetAssembly, AssemblyDefinition injected)
+ {
+ //Entry point
+ var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Entrypoint")
+ .Methods.First(x => x.Name == "Init");
+
+ var injectMethod = targetAssembly.MainModule.ImportReference(originalInjectMethod);
+
+ var targetType = targetAssembly.MainModule.Types.FirstOrDefault(x => x.Name == Config.TargetType);
+
+ if (targetType == null)
+ throw new ArgumentException($"Cannot find target type '{Config.TargetType}'");
+
+ MethodDefinition targetMethod;
+
+ if (Config.TargetMethod == ".cctor")
+ {
+ targetMethod = targetType.Methods.FirstOrDefault(m => m.IsConstructor && m.IsStatic);
+
+ if (targetMethod == null)
+ {
+ targetMethod = new MethodDefinition(".cctor",
+ MethodAttributes.Static
+ | MethodAttributes.Private
+ | MethodAttributes.HideBySig
+ | MethodAttributes.SpecialName
+ | MethodAttributes.RTSpecialName,
+ targetAssembly.MainModule.ImportReference(typeof(void)));
+
+ targetType.Methods.Add(targetMethod);
+ var il = targetMethod.Body.GetILProcessor();
+ il.Append(il.Create(OpCodes.Ret));
+ }
+ }
+ else
+ {
+ targetMethod = targetType.Methods.FirstOrDefault(m => m.Name == Config.TargetMethod);
+
+ if (targetMethod == null)
+ throw new ArgumentException($"Cannot find target method '{Config.TargetType}.{Config.TargetMethod}'");
+ }
+
+ var ilp = targetMethod.Body.GetILProcessor();
+ ilp.InsertBefore(ilp.Body.Instructions.First(), ilp.Create(OpCodes.Call, injectMethod));
+ }
+
+ static bool VerifyAssembly(AssemblyDefinition unity)
+ => !unity.MainModule.AssemblyReferences.Any(x => x.Name.Contains("BepInEx"));
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/BepInEx.Installer/Utility.cs b/BepInEx.Installer/Utility.cs
new file mode 100644
index 0000000..3c39fba
--- /dev/null
+++ b/BepInEx.Installer/Utility.cs
@@ -0,0 +1,29 @@
+using System.IO;
+using System.Linq;
+using Ionic.Zip;
+
+namespace BepInEx.Installer
+{
+ internal static class Utility
+ {
+ public static string CombinePaths(params string[] pathSegments)
+ => pathSegments.Aggregate(Path.Combine);
+
+ public static MemoryStream ExtractEntry(this ZipEntry entry)
+ {
+ MemoryStream ms = new MemoryStream((int)entry.UncompressedSize);
+
+ entry.Extract(ms);
+
+ ms.Position = 0;
+
+ return ms;
+ }
+
+ public static void ExtractEntry(this ZipEntry entry, string filename)
+ {
+ using (FileStream fs = new FileStream(filename, FileMode.Create))
+ entry.Extract(fs);
+ }
+ }
+}
diff --git a/BepInEx.Patcher/BepInEx.Patcher.csproj b/BepInEx.Patcher/BepInEx.Patcher.csproj
deleted file mode 100644
index d638d34..0000000
--- a/BepInEx.Patcher/BepInEx.Patcher.csproj
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
- Debug
- AnyCPU
- {DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}
- Exe
- BepInEx.Patcher
- BepInEx.Patcher
- v3.5
- 512
- true
-
-
-
-
-
- BepInEx.Patcher.Program
-
-
- true
- ..\bin\patcher\
- TRACE
- true
- embedded
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
- true
- ..\bin\patcher\
- TRACE;UNITY_2018
- true
- embedded
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
-
- ..\packages\Mono.Cecil.0.10.0\lib\net35\Mono.Cecil.dll
- True
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/BepInEx.Patcher/EmbeddedResource.cs b/BepInEx.Patcher/EmbeddedResource.cs
deleted file mode 100644
index 3c0bda9..0000000
--- a/BepInEx.Patcher/EmbeddedResource.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.IO;
-using System.Reflection;
-
-namespace BepInEx.Patcher
-{
- internal static class EmbeddedResource
- {
- public static byte[] Get(string resourceName)
- {
- using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
- {
- int length = (int)stream.Length;
-
- byte[] buffer = new byte[length];
-
- stream.Read(buffer, 0, length);
-
- return buffer;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/BepInEx.Patcher/Program.cs b/BepInEx.Patcher/Program.cs
deleted file mode 100644
index 187168a..0000000
--- a/BepInEx.Patcher/Program.cs
+++ /dev/null
@@ -1,206 +0,0 @@
-using Mono.Cecil;
-using Mono.Cecil.Cil;
-using System;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using MethodAttributes = Mono.Cecil.MethodAttributes;
-
-namespace BepInEx.Patcher
-{
- class Program
- {
- static void WriteError(string message)
- {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("Failed");
- Console.ResetColor();
- Console.WriteLine(message);
- Console.WriteLine();
- }
-
- static void WriteSuccess()
- {
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine("Success");
- Console.ResetColor();
- }
-
- static void Main(string[] args)
- {
- Console.WriteLine($"BepInEx Patcher v{Assembly.GetExecutingAssembly().GetName().Version}");
-
- if (args.Length >= 1) //short circuit for specific dll patch
- Environment.Exit(PatchUnityExe(Path.GetDirectoryName(args[0]), args[0], out string message) ? 0 : 9999);
-
- bool hasFound = false;
- bool hasFailure = false;
- int patchCount = 0;
-
- foreach (string exePath in Directory.GetFiles(Directory.GetCurrentDirectory()))
- {
- string gameName = Path.GetFileNameWithoutExtension(exePath);
-
- string managedDir = Environment.CurrentDirectory + $@"\{gameName}_Data\Managed";
-
-#if UNITY_2018
- string unityOutputDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.CoreModule.dll");
-#else
- string unityOutputDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.dll");
-#endif
-
-
- if (!Directory.Exists(managedDir) || !File.Exists(unityOutputDLL))
- continue;
-
- hasFound = true;
-
- Console.Write($"Patching {gameName}... ");
-
- if (PatchUnityExe(managedDir, unityOutputDLL, out string message))
- {
- WriteSuccess();
- patchCount++;
- }
- else
- {
- WriteError(message);
- hasFailure = true;
- }
- }
-
- Console.WriteLine();
-
- if (!hasFound)
- Console.WriteLine("Didn't find any games to patch! Exiting.");
- else
- Console.WriteLine($"Patched {patchCount} assemblies!");
-
- if (hasFailure)
- {
- Console.WriteLine("Press any key to continue...");
- Console.ReadKey();
- }
- else
- System.Threading.Thread.Sleep(3000);
- }
-
- static bool PatchUnityExe(string managedDir, string unityOutputDLL, out string message)
- {
- message = null;
-
- try
- {
- string 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
- };
-
-#if UNITY_2018
- string unityBackupDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.CoreModule.dll.bak");
-#else
- string unityBackupDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.dll.bak");
-#endif
-
- //determine which assembly to use as a base
- AssemblyDefinition 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 (AssemblyDefinition injected = AssemblyDefinition.ReadAssembly(injectedDLL, rp))
- {
- InjectAssembly(unity, injected);
-
- unity.Write(unityOutputDLL);
- }
- }
- catch (Exception e)
- {
- message = e.ToString();
- return false;
- }
-
- return true;
- }
-
- static void InjectAssembly(AssemblyDefinition unity, AssemblyDefinition injected)
- {
- //Entry point
- var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Entrypoint")
- .Methods.First(x => x.Name == "Init");
-
- var injectMethod = unity.MainModule.ImportReference(originalInjectMethod);
-
- var sceneManager = unity.MainModule.Types.First(x => x.Name == "Application");
-
- var voidType = unity.MainModule.ImportReference(typeof(void));
- var cctor = new MethodDefinition(".cctor",
- MethodAttributes.Static
- | MethodAttributes.Private
- | MethodAttributes.HideBySig
- | MethodAttributes.SpecialName
- | MethodAttributes.RTSpecialName,
- voidType);
-
- var ilp = cctor.Body.GetILProcessor();
- ilp.Append(ilp.Create(OpCodes.Call, injectMethod));
- ilp.Append(ilp.Create(OpCodes.Ret));
-
- sceneManager.Methods.Add(cctor);
- }
-
- static bool VerifyAssembly(AssemblyDefinition unity, out string message)
- {
- bool canPatch = true;
- message = "";
-
- //check if already patched
- if (unity.MainModule.AssemblyReferences.Any(x => x.Name.Contains("BepInEx")))
- {
- canPatch = false;
-
- message += "This assembly has already been patched by BepInEx.\r\n";
- }
-
- message = message.Trim();
- return canPatch;
- }
- }
-}
\ No newline at end of file
diff --git a/BepInEx.Patcher/Properties/AssemblyInfo.cs b/BepInEx.Patcher/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1df26b3..0000000
--- a/BepInEx.Patcher/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("BepInEx.Patcher")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("BepInEx.Patcher")]
-[assembly: AssemblyCopyright("Copyright © Bepis 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("dc89f18b-235b-4c01-ab31-af40dce5c4c7")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("5.0.0.0")]
-[assembly: AssemblyFileVersion("5.0.0.0")]
\ No newline at end of file
diff --git a/BepInEx.Patcher/packages.config b/BepInEx.Patcher/packages.config
deleted file mode 100644
index 90ecfe2..0000000
--- a/BepInEx.Patcher/packages.config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/BepInEx.sln b/BepInEx.sln
index c928b7d..64033a4 100644
--- a/BepInEx.sln
+++ b/BepInEx.sln
@@ -5,12 +5,6 @@ VisualStudioVersion = 15.0.27130.2027
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx", "BepInEx\BepInEx.csproj", "{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.Patcher", "BepInEx.Patcher\BepInEx.Patcher.csproj", "{DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}"
- ProjectSection(ProjectDependencies) = postProject
- {4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9} = {4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}
- {6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB} = {6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}
- EndProjectSection
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BepInEx.Bootstrap", "BepInEx.Bootstrap\BepInEx.Bootstrap.csproj", "{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Submodules", "Submodules", "{BAC58F7E-AAD8-4D0C-9490-9765ACBBA6FB}"
@@ -37,9 +31,6 @@ Global
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.Legacy|Any CPU.Build.0 = Legacy|Any CPU
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.v2018|Any CPU.ActiveCfg = v2018|Any CPU
{4FFBA620-F5ED-47F9-B90C-DAD1316FD9B9}.v2018|Any CPU.Build.0 = v2018|Any CPU
- {DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.InstallerDebug|Any CPU.ActiveCfg = Debug|Any CPU
- {DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.Legacy|Any CPU.ActiveCfg = Legacy|Any CPU
- {DC89F18B-235B-4C01-AB31-AF40DCE5C4C7}.v2018|Any CPU.ActiveCfg = v2018|Any CPU
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.InstallerDebug|Any CPU.ActiveCfg = Release|Any CPU
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Legacy|Any CPU.ActiveCfg = Release|Any CPU
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB}.Legacy|Any CPU.Build.0 = Release|Any CPU
@@ -69,7 +60,6 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {DC89F18B-235B-4C01-AB31-AF40DCE5C4C7} = {A9071994-3533-4C1B-89DC-D817B676AB41}
{6E6BC1E5-5BE8-4566-B3AE-52C4CB218AEB} = {A9071994-3533-4C1B-89DC-D817B676AB41}
{54161CFE-FF42-4DDE-B161-3A49545DB5CD} = {BAC58F7E-AAD8-4D0C-9490-9765ACBBA6FB}
{A15D6EE6-F954-415B-8605-8A8470CC87DC} = {BAC58F7E-AAD8-4D0C-9490-9765ACBBA6FB}
diff --git a/scripts/createInstallerPackage.ps1 b/scripts/createInstallerPackage.ps1
index fc012bd..428363b 100644
--- a/scripts/createInstallerPackage.ps1
+++ b/scripts/createInstallerPackage.ps1
@@ -14,19 +14,18 @@ New-Item $tempPath -ItemType Directory -Force | Out-Null
#download doorstop
-$doorstopTag = "v2.7.1.0"
$doorstopVersion = "2.7.1.0"
Write-Output "Downloading Doorstop $doorstopTag"
$wc = New-Object System.Net.WebClient
-$url = "https://github.com/NeighTools/UnityDoorstop/releases/download/$doorstopTag/Doorstop_x64_$doorstopVersion.zip"
+$url = "https://github.com/NeighTools/UnityDoorstop/releases/download/v$doorstopVersion/Doorstop_x64_$doorstopVersion.zip"
$output = "$tempPath\doorstop_x64.zip"
$wc.DownloadFile($url, $output)
-$url = "https://github.com/NeighTools/UnityDoorstop/releases/download/$doorstopTag/Doorstop_x86_$doorstopVersion.zip"
+$url = "https://github.com/NeighTools/UnityDoorstop/releases/download/v$doorstopVersion/Doorstop_x86_$doorstopVersion.zip"
$output = "$tempPath\doorstop_x86.zip"
$wc.DownloadFile($url, $output)