Tolerate unloadable types in ServerShared reflection scans

CultCache discovers DatabaseEntry types by scanning every loaded
assembly. Outside Unity, plugin assemblies that reference UnityEngine
throw ReflectionTypeLoadException and took the whole scan down; keep the
types that do load. Also fix GetAllGenericChildClasses reading and
writing the ChildClasses cache instead of its own.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-11 23:14:34 +02:00
commit 97a9e7a598

View file

@ -8,13 +8,23 @@ using System.Threading.Tasks;
public static class ReflectionExtensions
{
// Every type that can be loaded from every assembly in the domain. An assembly whose dependencies are missing
// (a Unity plugin referencing UnityEngine when running outside Unity) still yields the types that do load.
private static IEnumerable<Type> LoadableTypes()
{
return AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly =>
{
try { return assembly.GetTypes(); }
catch (ReflectionTypeLoadException e) { return e.Types.Where(t => t != null); }
});
}
private static Dictionary<Type,Type[]> InterfaceClasses = new Dictionary<Type, Type[]>();
public static Type[] GetAllInterfaceClasses(this Type type)
{
if (InterfaceClasses.ContainsKey(type))
return InterfaceClasses[type];
return InterfaceClasses[type] = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(ass => ass.GetTypes()).Where(t => t.IsClass && t.GetInterfaces().Contains(type)).ToArray();
return InterfaceClasses[type] = LoadableTypes().Where(t => t.IsClass && t.GetInterfaces().Contains(type)).ToArray();
}
private static Dictionary<Type,Type[]> ParentTypes = new Dictionary<Type, Type[]>();
@ -56,17 +66,15 @@ public static class ReflectionExtensions
{
if (ChildClasses.ContainsKey(type))
return ChildClasses[type];
return ChildClasses[type] = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(ass => ass.GetTypes()).Where(type.IsAssignableFrom).ToArray();
return ChildClasses[type] = LoadableTypes().Where(type.IsAssignableFrom).ToArray();
}
private static Dictionary<Type,Type[]> GenericChildClasses = new Dictionary<Type, Type[]>();
public static Type[] GetAllGenericChildClasses(this Type genericType)
{
if (GenericChildClasses.ContainsKey(genericType))
return ChildClasses[genericType];
return ChildClasses[genericType] = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(ass => ass.GetTypes()).Where(type=>type.IsAssignableToGenericType(genericType)).ToArray();
return GenericChildClasses[genericType];
return GenericChildClasses[genericType] = LoadableTypes().Where(type=>type.IsAssignableToGenericType(genericType)).ToArray();
}
public static bool IsAssignableToGenericType(this Type givenType, Type genericType)