Skip to content
This repository has been archived by the owner on Feb 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #82 from neos-modding-group/hide-yo-types/hide-yo-…
Browse files Browse the repository at this point in the history
…kids

Hide mod types from two more type-searching methods
  • Loading branch information
EIA485 authored Feb 26, 2023
2 parents e6325e0 + e0bf8f1 commit fae05dc
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
67 changes: 56 additions & 11 deletions NeosModLoader/AssemblyHider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BaseX;
using FrooxEngine;
using HarmonyLib;
using System;
using System.Collections.Generic;
Expand All @@ -23,9 +24,21 @@ internal static void PatchNeos(Harmony harmony, HashSet<Assembly> initialAssembl
{
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));

// TypeHelper.FindType explicitly does a type search
MethodInfo findTypeTarget = AccessTools.DeclaredMethod(typeof(TypeHelper), nameof(TypeHelper.FindType));
MethodInfo findTypePatch = AccessTools.DeclaredMethod(typeof(AssemblyHider), nameof(FindTypePostfix));
harmony.Patch(findTypeTarget, postfix: new HarmonyMethod(findTypePatch));

// WorkerManager.IsValidGenericType checks a type for validity, and if it returns `true` it reveals that the type exists
MethodInfo isValidGenericTypeTarget = AccessTools.DeclaredMethod(typeof(WorkerManager), nameof(WorkerManager.IsValidGenericType));
MethodInfo isValidGenericTypePatch = AccessTools.DeclaredMethod(typeof(AssemblyHider), nameof(IsValidTypePostfix));
harmony.Patch(isValidGenericTypeTarget, postfix: new HarmonyMethod(isValidGenericTypePatch));

// WorkerManager.GetType uses FindType, but upon failure fails back to doing a (strangely) exhausitive reflection-based search for the type
MethodInfo getTypeTarget = AccessTools.DeclaredMethod(typeof(WorkerManager), nameof(WorkerManager.GetType));
MethodInfo getTypePatch = AccessTools.DeclaredMethod(typeof(AssemblyHider), nameof(FindTypePostfix));
harmony.Patch(getTypeTarget, postfix: new HarmonyMethod(getTypePatch));
}
}

Expand All @@ -51,24 +64,56 @@ private static HashSet<Assembly> GetModAssemblies()
return assemblies;
}

private static void FindTypePostfix(ref Type? __result)
private static bool IsModType(Type type)
{
if (__result != null && !neosAssemblies!.Contains(__result.Assembly))
if (neosAssemblies!.Contains(type.Assembly))
{
// the type belongs to a Neos assembly
return false; // don't hide the type
}
else
{
if (!modAssemblies!.Contains(__result.Assembly))
if (modAssemblies!.Contains(type.Assembly))
{
// known type from a mod assembly
Logger.DebugInternal($"Hid type \"{type}\" from Neos");
return true; // hide the type
}
else
{
// 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.
// since this is an edge case users may want to handle in different ways, the HideLateTypes nml config option allows them to choose.
bool hideLate = ModLoaderConfiguration.Get().HideLateTypes;
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. due to the HideLateTypes config option being {hideLate} it will be {(hideLate ? "Hidden" : "Shown")}");
if (hideLate) __result = null;
Logger.WarnInternal($"The \"{type}\" type does not appear to part of Neos or a mod. It is unclear whether it should be hidden or not. Due to the HideLateTypes config option being {hideLate} it will be {(hideLate ? "Hidden" : "Shown")}");
return hideLate; // hide the type only if hideLate == true
}
else
}
}

// postfix for a method that searches for a type, and returns a reference to it if found (TypeHelper.FindType and WorkerManager.GetType)
private static void FindTypePostfix(ref Type? __result)
{
if (__result != null)
{
// we only need to think about types if the method actually returned a non-null result
if (IsModType(__result))
{
__result = null;
}
}
}

// postfix for a method that validates a type (WorkerManager.IsValidGenericType)
private static void IsValidTypePostfix(ref bool __result, Type type)
{
if (__result == true)
{
// we only need to think about types if the method actually returned a true result
if (IsModType(type))
{
Logger.DebugInternal($"Hid type \"{__result}\" from Neos");
__result = null; // Pretend the type doesn't exist
__result = false;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion NeosModLoader/ModLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace NeosModLoader
{
public class ModLoader
{
internal const string VERSION_CONSTANT = "1.12.4";
internal const string VERSION_CONSTANT = "1.12.5";
/// <summary>
/// NeosModLoader's version
/// </summary>
Expand Down

0 comments on commit fae05dc

Please sign in to comment.