فهرست منبع

Upgrade patcher to work with any game

Bepis 6 سال پیش
والد
کامیت
e8bee855d2

+ 7 - 15
BepInEx.Patcher/BepInEx.Patcher.csproj

@@ -38,6 +38,9 @@
     <WarningLevel>4</WarningLevel>
     <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject>BepInEx.Patcher.Program</StartupObject>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
       <HintPath>..\packages\Mono.Cecil.0.10.0\lib\net35\Mono.Cecil.dll</HintPath>
@@ -51,28 +54,17 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="EmbeddedResource.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
+  <ItemGroup />
   <ItemGroup>
-    <EmbeddedResource Include="Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-    </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Resources\0Harmony.dll" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Resources\BepInEx.dll" />
+    <EmbeddedResource Include="..\bin\0Harmony.dll" />
+    <EmbeddedResource Include="..\bin\BepInEx.dll" />
   </ItemGroup>
   <Import Project="..\BepInEx.Common\BepInEx.Common.projitems" Label="Shared" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

+ 26 - 0
BepInEx.Patcher/EmbeddedResource.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+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;
+            }
+        }
+    }
+}

+ 70 - 13
BepInEx.Patcher/Program.cs

@@ -3,39 +3,88 @@ 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 Error(string message)
+        static void WriteError(string message)
         {
-            Console.WriteLine($"Error: {message}");
-            Console.WriteLine("Press any key to continue...");
-            Console.ReadKey();
-            Environment.Exit(1);
+            Console.ForegroundColor = ConsoleColor.Red;
+            Console.WriteLine("Failed");
+            Console.ResetColor();
+            Console.WriteLine(message);
+        }
+
+        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;
+            int patchCount = 0;
+
             foreach (string exePath in Directory.GetFiles(Directory.GetCurrentDirectory()))
             {
+                string gameName = Path.GetFileNameWithoutExtension(exePath);
 
-                string managedDir = Environment.CurrentDirectory + $@"\{Path.GetFileNameWithoutExtension(exePath)}_Data\Managed";
+                string managedDir = Environment.CurrentDirectory + $@"\{gameName}_Data\Managed";
                 string unityOutputDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.dll");
 
                 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);
+                }
+            }
+
+            Console.WriteLine();
+
+            if (!hasFound)
+                Console.WriteLine("Didn't find any games to patch! Exiting.");
+            else
+                Console.WriteLine($"Patched {patchCount} assemblies!");
+
+            System.Threading.Thread.Sleep(2000);
+        }
+
+        static bool PatchUnityExe(string managedDir, string unityOutputDLL, out string message)
+        {
+            message = null;
+
+            try
+            {
                 string unityOriginalDLL = Path.GetFullPath($"{managedDir}\\UnityEngine.dll.bak");
                 if (!File.Exists(unityOriginalDLL))
                     File.Copy(unityOutputDLL, unityOriginalDLL);
 
                 string harmony = Path.GetFullPath($"{managedDir}\\0Harmony.dll");
-                File.WriteAllBytes(harmony, Resources._0Harmony);
+                File.WriteAllBytes(harmony, EmbeddedResource.Get("BepInEx.Patcher.0Harmony.dll"));
 
                 string injectedDLL = Path.GetFullPath($"{managedDir}\\BepInEx.dll");
-                File.WriteAllBytes(injectedDLL, Resources.BepInEx);
+                File.WriteAllBytes(injectedDLL, EmbeddedResource.Get("BepInEx.Patcher.BepInEx.dll"));
 
                 var defaultResolver = new DefaultAssemblyResolver();
                 defaultResolver.AddSearchDirectory(managedDir);
@@ -44,13 +93,21 @@ namespace BepInEx.Patcher
                     AssemblyResolver = defaultResolver
                 };
 
-                AssemblyDefinition unity = AssemblyDefinition.ReadAssembly(unityOriginalDLL, rp);
-                AssemblyDefinition injected = AssemblyDefinition.ReadAssembly(injectedDLL, rp);
-
-                InjectAssembly(unity, injected);
+                using (AssemblyDefinition unity = AssemblyDefinition.ReadAssembly(unityOriginalDLL, rp))
+                using (AssemblyDefinition injected = AssemblyDefinition.ReadAssembly(injectedDLL, rp))
+                {
+                    InjectAssembly(unity, injected);
             
-                unity.Write(unityOutputDLL);
+                    unity.Write(unityOutputDLL);
+                }
             }
+            catch (Exception e)
+            {
+                message = e.ToString();
+                return false;
+            }
+
+            return true;
         }
 
         static void InjectAssembly(AssemblyDefinition unity, AssemblyDefinition injected)

+ 3 - 3
BepInEx.Patcher/Properties/AssemblyInfo.cs

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("BepInEx.Patcher")]
-[assembly: AssemblyCopyright("Copyright ©  2018")]
+[assembly: AssemblyCopyright("Copyright © Bepis 2018")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
 // 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("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("3.1.0.0")]
+[assembly: AssemblyFileVersion("3.1.0.0")]

+ 0 - 83
BepInEx.Patcher/Resources.Designer.cs

@@ -1,83 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.42000
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace BepInEx.Patcher {
-    using System;
-    
-    
-    /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
-    /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-        
-        private static global::System.Resources.ResourceManager resourceMan;
-        
-        private static global::System.Globalization.CultureInfo resourceCulture;
-        
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-        
-        /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BepInEx.Patcher.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-        
-        /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized resource of type System.Byte[].
-        /// </summary>
-        internal static byte[] _0Harmony {
-            get {
-                object obj = ResourceManager.GetObject("_0Harmony", resourceCulture);
-                return ((byte[])(obj));
-            }
-        }
-        
-        /// <summary>
-        ///   Looks up a localized resource of type System.Byte[].
-        /// </summary>
-        internal static byte[] BepInEx {
-            get {
-                object obj = ResourceManager.GetObject("BepInEx", resourceCulture);
-                return ((byte[])(obj));
-            }
-        }
-    }
-}

+ 0 - 68
BepInEx.Patcher/Resources.resx

@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
-  <data name="BepInEx" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\bin\BepInEx.dll;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </data>
-  <data name="_0Harmony" type="System.Resources.ResXFileRef, System.Windows.Forms">
-    <value>..\bin\0Harmony.dll;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </data>
-</root>