This repository has been archived by the owner on Feb 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hide modding-related types from TypeHelper.FindType (#67)
* Fix #64 * Add a debug log * Add a configuration to disable this feature * Document why I remove NML and harmony
- Loading branch information
Showing
6 changed files
with
107 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using BaseX; | ||
using HarmonyLib; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Reflection; | ||
|
||
namespace NeosModLoader | ||
{ | ||
internal static class AssemblyHider | ||
{ | ||
private static HashSet<Assembly>? neosAssemblies; | ||
private static HashSet<Assembly>? modAssemblies; | ||
|
||
/// <summary> | ||
/// Patch Neos's type lookup code to not see mod-related types. This is needed, because users can pass | ||
/// arbitrary strings to TypeHelper.FindType(), which can be used to detect if someone is running mods. | ||
/// </summary> | ||
/// <param name="harmony">Our NML harmony instance</param> | ||
/// <param name="initialAssemblies">Assemblies that were loaded when NML first started</param> | ||
internal static void PatchNeos(Harmony harmony, HashSet<Assembly> initialAssemblies) | ||
{ | ||
if (ModLoaderConfiguration.Get().HideModTypes) | ||
{ | ||
neosAssemblies = GetNeosAssemblies(initialAssemblies); | ||
modAssemblies = GetModAssemblies(); | ||
MethodInfo target = AccessTools.DeclaredMethod(typeof(TypeHelper), nameof(TypeHelper.FindType)); | ||
MethodInfo patch = AccessTools.DeclaredMethod(typeof(AssemblyHider), nameof(FindTypePostfix)); | ||
harmony.Patch(target, postfix: new HarmonyMethod(patch)); | ||
} | ||
} | ||
|
||
private static HashSet<Assembly> GetNeosAssemblies(HashSet<Assembly> initialAssemblies) | ||
{ | ||
// Remove NML itself, as its types should be hidden but it's guaranteed to be loaded. | ||
initialAssemblies.Remove(Assembly.GetExecutingAssembly()); | ||
|
||
// Remove Harmony, as users who aren't using nml_libs will already have it loaded. | ||
initialAssemblies.Remove(typeof(Harmony).Assembly); | ||
|
||
return initialAssemblies; | ||
} | ||
|
||
private static HashSet<Assembly> GetModAssemblies() | ||
{ | ||
// start with ALL assemblies | ||
HashSet<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies().ToHashSet(); | ||
|
||
// remove assemblies that already existed before NML loaded | ||
assemblies.ExceptWith(neosAssemblies); | ||
|
||
return assemblies; | ||
} | ||
|
||
private static void FindTypePostfix(ref Type? __result) | ||
{ | ||
if (__result != null && !neosAssemblies!.Contains(__result.Assembly)) | ||
{ | ||
if (!modAssemblies!.Contains(__result.Assembly)) | ||
{ | ||
// an assembly was in neither neosAssemblies nor modAssemblies | ||
// this implies someone late-loaded an assembly after NML, and it was later used in-game | ||
// this is super weird, and probably shouldn't ever happen... but if it does, I want to know about it. | ||
Logger.WarnInternal($"The \"{__result}\" type does not appear to part of Neos or a mod. It is unclear whether it should be hidden or not."); | ||
} | ||
else | ||
{ | ||
Type type = __result; | ||
Logger.DebugFuncInternal(() => $"Hid type \"{type}\" from Neos"); | ||
} | ||
|
||
// Pretend the type doesn't exist | ||
__result = null; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using HarmonyLib; | ||
using System.Collections.Generic; | ||
using System.Reflection; | ||
|
||
namespace NeosModLoader | ||
{ | ||
// this class does all the harmony-related NML work. | ||
// this is needed to avoid importing harmony in ExecutionHook, where it may not be loaded yet. | ||
internal class HarmonyWorker | ||
{ | ||
internal static void LoadModsAndHideModAssemblies(HashSet<Assembly> initialAssemblies) | ||
{ | ||
Harmony harmony = new("com.neosmodloader"); | ||
ModLoader.LoadMods(harmony); | ||
AssemblyHider.PatchNeos(harmony, initialAssemblies); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters