Skip to content

Commit 0d7ba3a

Browse files
committed
Fix BepInEx 6 for Unity 4.x games and below
1 parent 42b8b96 commit 0d7ba3a

5 files changed

Lines changed: 75 additions & 21 deletions

File tree

BepInEx.Core/BepInEx.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
<ItemGroup>
2323
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All"/>
2424
<PackageReference Include="HarmonyX" Version="2.10.0"/>
25-
<PackageReference Include="MonoMod.Utils" Version="22.3.23.4"/>
2625
<PackageReference Include="SemanticVersioning" Version="2.0.2"/>
26+
<PackageReference Include="MonoMod.Utils" Version="22.5.1.1" />
2727
</ItemGroup>
2828
<ItemGroup>
2929
<Compile Remove="Contract\IPlugin.cs"/>

BepInEx.Preloader.Core/BepInEx.Preloader.Core.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<ItemGroup>
2323
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="All"/>
2424
<PackageReference Include="HarmonyX" Version="2.10.0"/>
25-
<PackageReference Include="MonoMod.RuntimeDetour" Version="22.3.23.4"/>
26-
<PackageReference Include="MonoMod.Utils" Version="22.3.23.4"/>
25+
<PackageReference Include="MonoMod.RuntimeDetour" Version="22.5.1.1" />
26+
<PackageReference Include="MonoMod.Utils" Version="22.5.1.1" />
2727
</ItemGroup>
2828
</Project>

BepInEx.Preloader.Unity/EntrypointPatcher.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ public bool PatchEntrypoint(ref AssemblyDefinition assembly, string filename)
110110
var ins = il.Body.Instructions.First();
111111

112112
il.InsertBefore(ins,
113-
il.Create(OpCodes
114-
.Ldnull)); // gameExePath (always null, we initialize the Paths class in Entrypoint)
113+
il.Create(OpCodes.Ldnull)); // gameExePath (always null, we initialize the Paths class in Entrypoint)
115114

116115
il.InsertBefore(ins,
117116
il.Create(OpCodes.Call,

BepInEx.Unity/BepInEx.Unity.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<LangVersion>10</LangVersion>
88
</PropertyGroup>
99
<PropertyGroup Condition="'$(TargetFramework)' == 'net35'">
10-
<!-- Output only net35 version to distribution; netstadnard is only used for generating NuGet package -->
10+
<!-- Output only net35 version to distribution; netstandard is only used for generating NuGet package -->
1111
<OutputPath>..\bin\Unity\</OutputPath>
1212
<DocumentationFile>$(OutputPath)\BepInEx.Unity.xml</DocumentationFile>
1313
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>

BepInEx.Unity/Bootstrap/UnityChainloader.cs

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Diagnostics;
1+
using System;
2+
using System.Diagnostics;
23
using System.IO;
34
using System.Reflection;
45
using System.Runtime.CompilerServices;
@@ -10,6 +11,10 @@
1011
using MonoMod.Utils;
1112
using UnityEngine;
1213
using Logger = BepInEx.Logging.Logger;
14+
using Object = UnityEngine.Object;
15+
16+
[assembly: InternalsVisibleTo("UnityEngine")]
17+
[assembly: InternalsVisibleTo("UnityEngine.Core")]
1318

1419
namespace BepInEx.Unity.Bootstrap;
1520

@@ -53,31 +58,81 @@ private static string UnityVersion
5358
get => Application.unityVersion;
5459
}
5560

56-
private static void StaticStart(string gameExePath = null)
61+
private static Version UnityVersionAsVersion => new Version(UnityVersion.Substring(0, UnityVersion.LastIndexOf('.') + 2));
62+
63+
private static bool staticStartHasBeenCalled = false;
64+
65+
/// <summary>
66+
/// 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
67+
/// </summary>
68+
[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)]
69+
public static void StaticStart(string gameExePath = null)
5770
{
58-
var instance = new UnityChainloader();
59-
instance.Initialize(gameExePath);
60-
instance.Execute();
71+
try
72+
{
73+
if (staticStartHasBeenCalled)
74+
throw new InvalidOperationException("Cannot call StaticStart again");
75+
76+
Logger.Log(LogLevel.Debug, "Entering chainloader StaticStart");
77+
78+
var instance = new UnityChainloader();
79+
instance.Initialize(gameExePath);
80+
instance.Execute();
81+
82+
staticStartHasBeenCalled = true;
83+
84+
Logger.Log(LogLevel.Debug, "Exiting chainloader StaticStart");
85+
}
86+
catch (Exception ex)
87+
{
88+
Logger.Log(LogLevel.Fatal, $"Unable to complete chainloader StaticStart: {ex.Message}");
89+
Logger.Log(LogLevel.Fatal, ex.StackTrace);
90+
}
6191
}
6292

6393

6494
public override void Initialize(string gameExePath = null)
6595
{
66-
Instance = this;
96+
try
97+
{
98+
Logger.Log(LogLevel.Debug, "Entering chainloader initialize");
99+
100+
Instance = this;
101+
102+
UnityTomlTypeConverters.AddUnityEngineConverters();
103+
104+
Logger.Log(LogLevel.Debug, "Creating Manager object");
105+
106+
ManagerObject = new GameObject("BepInEx_Manager") { hideFlags = HideFlags.HideAndDontSave };
107+
Object.DontDestroyOnLoad(ManagerObject);
108+
109+
Logger.Log(LogLevel.Debug, "Getting game product name");
110+
111+
var productNameProp = typeof(Application).GetProperty("productName", BindingFlags.Public | BindingFlags.Static);
67112

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

70-
ThreadingHelper.Initialize();
115+
if (UnityVersionAsVersion.Major >= 5)
116+
{
117+
Logger.Log(LogLevel.Debug, "Initializing ThreadingHelper");
118+
ThreadingHelper.Initialize();
119+
}
120+
else
121+
{
122+
Logger.Log(LogLevel.Debug, "Skipping ThreadingHelper init due to unity version (<= 4)");
123+
}
71124

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

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

80-
base.Initialize(gameExePath);
129+
Logger.Log(LogLevel.Debug, "Exiting chainloader initialize");
130+
}
131+
catch (Exception ex)
132+
{
133+
Logger.Log(LogLevel.Fatal, $"Unable to complete chainloader init: {ex.Message}");
134+
Logger.Log(LogLevel.Fatal, ex.StackTrace);
135+
}
81136
}
82137

83138
protected override void InitializeLoggers()

0 commit comments

Comments
 (0)