Skip to content

Commit 7967ac7

Browse files
committed
Added BepInEx.SuppressGetTypesErrorsPatcher
1 parent 3a08eab commit 7967ac7

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{F2A30C40-4073-45AC-8325-E255BD2B011D}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>BepInEx</RootNamespace>
11+
<AssemblyName>BepInEx.SuppressGetTypesErrorsPatcher</AssemblyName>
12+
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<Deterministic>true</Deterministic>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>embedded</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>..\bin\BepInEx\patchers\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>embedded</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>..\bin\BepInEx\patchers\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
<DebugSymbols>true</DebugSymbols>
33+
</PropertyGroup>
34+
<ItemGroup>
35+
<Reference Include="0Harmony">
36+
<HintPath>..\lib\0Harmony.dll</HintPath>
37+
<Private>False</Private>
38+
</Reference>
39+
<Reference Include="BepInEx">
40+
<HintPath>..\lib\BepInEx.dll</HintPath>
41+
<Private>False</Private>
42+
</Reference>
43+
<Reference Include="Mono.Cecil">
44+
<HintPath>..\lib\Mono.Cecil.dll</HintPath>
45+
<Private>False</Private>
46+
</Reference>
47+
<Reference Include="System" />
48+
<Reference Include="System.Core" />
49+
<Reference Include="System.Xml.Linq" />
50+
<Reference Include="System.Data.DataSetExtensions" />
51+
<Reference Include="System.Data" />
52+
<Reference Include="System.Xml" />
53+
<Reference Include="UnityEngine">
54+
<HintPath>..\lib\UnityEngine.dll</HintPath>
55+
<Private>False</Private>
56+
</Reference>
57+
</ItemGroup>
58+
<ItemGroup>
59+
<Compile Include="SuppressGetTypesErrorsPatcher.cs" />
60+
<Compile Include="Properties\AssemblyInfo.cs" />
61+
</ItemGroup>
62+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
63+
</Project>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Reflection;
2+
using System.Runtime.InteropServices;
3+
using static BepInEx.SuppressGetTypesErrorsPatcher;
4+
5+
[assembly: AssemblyConfiguration("")]
6+
[assembly: AssemblyCompany("https://github.com/BepInEx/BepInEx.Utility")]
7+
[assembly: AssemblyCopyright("Copyright 2021")]
8+
[assembly: AssemblyTrademark("")]
9+
[assembly: AssemblyCulture("")]
10+
[assembly: ComVisible(false)]
11+
[assembly: AssemblyTitle(GUID)]
12+
[assembly: AssemblyProduct(GUID)]
13+
[assembly: AssemblyDescription(PluginName)]
14+
[assembly: AssemblyVersion(Version)]
15+
[assembly: AssemblyFileVersion(Version)]
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using BepInEx.Bootstrap;
6+
using HarmonyLib;
7+
using Mono.Cecil;
8+
9+
namespace BepInEx
10+
{
11+
public static class SuppressGetTypesErrorsPatcher
12+
{
13+
public const string GUID = "BepInEx.SuppressGetTypesErrorsPatcher";
14+
public const string PluginName = "Suppress Type.GetTypes Errors";
15+
public const string Version = "1.0";
16+
17+
// Needed to be a valid patcher
18+
public static IEnumerable<string> TargetDLLs { get; } = Enumerable.Empty<string>();
19+
20+
// Needed to be a valid patcher
21+
public static void Patch(AssemblyDefinition assembly) { }
22+
23+
public static void Finish()
24+
{
25+
// Need to run this in finalizer after all assemblies are patched or we might patch an assembly that gets replaced later
26+
Harmony.CreateAndPatchAll(typeof(SuppressGetTypesErrorsPatcher), GUID);
27+
}
28+
29+
[HarmonyPatch(typeof(Assembly), nameof(Assembly.GetTypes), new Type[0])]
30+
[HarmonyFinalizer]
31+
public static void HandleReflectionTypeLoad(ref Exception __exception, ref Type[] __result)
32+
{
33+
if (__exception == null)
34+
return;
35+
if (__exception is ReflectionTypeLoadException re)
36+
{
37+
__exception = null;
38+
__result = re.Types.Where(t => t != null).ToArray();
39+
UnityEngine.Debug.Log($"Encountered ReflectionTypeLoadException which was suppressed. Full error: \n${TypeLoader.TypeLoadExceptionToString(re)}");
40+
}
41+
}
42+
}
43+
}

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Prevents plugin hotkeys from triggering while typing in an input field.
2020
## MessageCenter
2121
A simple plugin that shows any log entries marked as "Message" on screen. Plugins generally use the "Message" log level for things that they want the user to read.
2222

23+
## SuppressGetTypesErrorsPatcher
24+
A patcher that hooks Assembly.GetTypes() and handles ReflectionTypeLoadException. Useful when game code is using Assembly.GetTypes() without handling the exception, and it crashes on plugin assemblies that have types that can't be loaded.
25+
2326
#### How to make my mod compatible?
2427
Use the `Logger` of your plugin and call its `LogMessage` method or `Log` method and pass in `LogLevel.Message` as a parameter. You don't have to reference this plugin, and everything will work fine if this plugin doesn't exist.
2528

0 commit comments

Comments
 (0)