Skip to content

Commit

Permalink
Fix BepInEx 6 for Unity 4.x games and below
Browse files Browse the repository at this point in the history
  • Loading branch information
bbepis committed Aug 4, 2022
1 parent 42b8b96 commit 0d7ba3a
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 21 deletions.
2 changes: 1 addition & 1 deletion BepInEx.Core/BepInEx.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All"/>
<PackageReference Include="HarmonyX" Version="2.10.0"/>
<PackageReference Include="MonoMod.Utils" Version="22.3.23.4"/>
<PackageReference Include="SemanticVersioning" Version="2.0.2"/>
<PackageReference Include="MonoMod.Utils" Version="22.5.1.1" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Contract\IPlugin.cs"/>
Expand Down
4 changes: 2 additions & 2 deletions BepInEx.Preloader.Core/BepInEx.Preloader.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All"/>
<PackageReference Include="HarmonyX" Version="2.10.0"/>
<PackageReference Include="MonoMod.RuntimeDetour" Version="22.3.23.4"/>
<PackageReference Include="MonoMod.Utils" Version="22.3.23.4"/>
<PackageReference Include="MonoMod.RuntimeDetour" Version="22.5.1.1" />
<PackageReference Include="MonoMod.Utils" Version="22.5.1.1" />
</ItemGroup>
</Project>
3 changes: 1 addition & 2 deletions BepInEx.Preloader.Unity/EntrypointPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ public bool PatchEntrypoint(ref AssemblyDefinition assembly, string filename)
var ins = il.Body.Instructions.First();

il.InsertBefore(ins,
il.Create(OpCodes
.Ldnull)); // gameExePath (always null, we initialize the Paths class in Entrypoint)
il.Create(OpCodes.Ldnull)); // gameExePath (always null, we initialize the Paths class in Entrypoint)

il.InsertBefore(ins,
il.Create(OpCodes.Call,
Expand Down
2 changes: 1 addition & 1 deletion BepInEx.Unity/BepInEx.Unity.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<LangVersion>10</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net35'">
<!-- Output only net35 version to distribution; netstadnard is only used for generating NuGet package -->
<!-- Output only net35 version to distribution; netstandard is only used for generating NuGet package -->
<OutputPath>..\bin\Unity\</OutputPath>
<DocumentationFile>$(OutputPath)\BepInEx.Unity.xml</DocumentationFile>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
Expand Down
85 changes: 70 additions & 15 deletions BepInEx.Unity/Bootstrap/UnityChainloader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
Expand All @@ -10,6 +11,10 @@
using MonoMod.Utils;
using UnityEngine;
using Logger = BepInEx.Logging.Logger;
using Object = UnityEngine.Object;

[assembly: InternalsVisibleTo("UnityEngine")]
[assembly: InternalsVisibleTo("UnityEngine.Core")]

namespace BepInEx.Unity.Bootstrap;

Expand Down Expand Up @@ -53,31 +58,81 @@ private static string UnityVersion
get => Application.unityVersion;
}

private static void StaticStart(string gameExePath = null)
private static Version UnityVersionAsVersion => new Version(UnityVersion.Substring(0, UnityVersion.LastIndexOf('.') + 2));

private static bool staticStartHasBeenCalled = false;

/// <summary>
/// This method is public so that BepInEx can correctly initialize on some versions of Unity that do not respect InternalsVisibleToAttribute. Do not call this yourself
/// </summary>
[Obsolete("This method is public so that BepInEx can correctly initialize on some versions of Unity that do not respect InternalsVisibleToAttribute. DO NOT CALL", true)]
public static void StaticStart(string gameExePath = null)
{
var instance = new UnityChainloader();
instance.Initialize(gameExePath);
instance.Execute();
try
{
if (staticStartHasBeenCalled)
throw new InvalidOperationException("Cannot call StaticStart again");

Logger.Log(LogLevel.Debug, "Entering chainloader StaticStart");

var instance = new UnityChainloader();
instance.Initialize(gameExePath);
instance.Execute();

staticStartHasBeenCalled = true;

Logger.Log(LogLevel.Debug, "Exiting chainloader StaticStart");
}
catch (Exception ex)
{
Logger.Log(LogLevel.Fatal, $"Unable to complete chainloader StaticStart: {ex.Message}");
Logger.Log(LogLevel.Fatal, ex.StackTrace);
}
}


public override void Initialize(string gameExePath = null)
{
Instance = this;
try
{
Logger.Log(LogLevel.Debug, "Entering chainloader initialize");

Instance = this;

UnityTomlTypeConverters.AddUnityEngineConverters();

Logger.Log(LogLevel.Debug, "Creating Manager object");

ManagerObject = new GameObject("BepInEx_Manager") { hideFlags = HideFlags.HideAndDontSave };
Object.DontDestroyOnLoad(ManagerObject);

Logger.Log(LogLevel.Debug, "Getting game product name");

var productNameProp = typeof(Application).GetProperty("productName", BindingFlags.Public | BindingFlags.Static);

UnityTomlTypeConverters.AddUnityEngineConverters();
_consoleTitle = $"{CurrentAssemblyName} {CurrentAssemblyVersion} - {productNameProp?.GetValue(null, null) ?? Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName)}";

ThreadingHelper.Initialize();
if (UnityVersionAsVersion.Major >= 5)
{
Logger.Log(LogLevel.Debug, "Initializing ThreadingHelper");
ThreadingHelper.Initialize();
}
else
{
Logger.Log(LogLevel.Debug, "Skipping ThreadingHelper init due to unity version (<= 4)");
}

ManagerObject = new GameObject("BepInEx_Manager") { hideFlags = HideFlags.HideAndDontSave };
Object.DontDestroyOnLoad(ManagerObject);
Logger.Log(LogLevel.Debug, "Falling back to BaseChainloader initializer");

var productNameProp =
typeof(Application).GetProperty("productName", BindingFlags.Public | BindingFlags.Static);
_consoleTitle =
$"{CurrentAssemblyName} {CurrentAssemblyVersion} - {productNameProp?.GetValue(null, null) ?? Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName)}";
base.Initialize(gameExePath);

base.Initialize(gameExePath);
Logger.Log(LogLevel.Debug, "Exiting chainloader initialize");
}
catch (Exception ex)
{
Logger.Log(LogLevel.Fatal, $"Unable to complete chainloader init: {ex.Message}");
Logger.Log(LogLevel.Fatal, ex.StackTrace);
}
}

protected override void InitializeLoggers()
Expand Down

0 comments on commit 0d7ba3a

Please sign in to comment.