Files
Workspace/Assets/Modules/ShrinkModFramework/Runtime/Integration/ShrinkModOptionalRuntimeIntegration.cs
T

146 lines
6.2 KiB
C#

using System;
using System.Linq;
using System.Reflection;
using UnityEngine;
namespace ShrinkModFramework
{
internal static class ShrinkModOptionalRuntimeIntegration
{
public static void RegisterModInstance(IShrinkMod modInstance, ShrinkModInfo modInfo, bool verboseLogging)
{
if (modInstance == null || modInfo == null)
return;
var modType = modInstance.GetType();
TryRegisterEventBusInstance(modType, modInstance, modInfo.ModId, verboseLogging);
TryRegisterCommandInstance(modType, modInstance, modInfo.ModId, verboseLogging);
TryRegisterNetworkInstance(modType, modInstance, modInfo.ModId, verboseLogging);
}
public static void RefreshGlobalBindings(bool verboseLogging)
{
TryRefreshNetworkEventBusBridge(verboseLogging);
}
private static void TryRegisterEventBusInstance(Type modType, object modInstance, string modId, bool verboseLogging)
{
if (!HasAttribute(modType, "ShrinkEventBus.EventBusSubscriberAttribute", "ShrinkEventBus.Runtime"))
return;
try
{
var eventBusType = FindType("ShrinkEventBus.EventBus", "ShrinkEventBus.Runtime");
var autoRegisterMethod = eventBusType?.GetMethod("AutoRegister",
BindingFlags.Public | BindingFlags.Static,
null,
new[] { typeof(object) },
null);
if (autoRegisterMethod == null)
return;
autoRegisterMethod.Invoke(null, new[] { modInstance });
if (verboseLogging)
Debug.Log($"[ShrinkModFramework] 模组 {modId} 已接入 ShrinkEventBus 实例订阅。");
}
catch (Exception ex)
{
Debug.LogWarning($"[ShrinkModFramework] 模组 {modId} 接入 ShrinkEventBus 失败:{ex.Message}");
}
}
private static void TryRegisterCommandInstance(Type modType, object modInstance, string modId, bool verboseLogging)
{
if (!HasAttribute(modType, "ShrinkCommand.ShrinkCommandSubscriberAttribute", "ShrinkCommand.Runtime"))
return;
try
{
var runtimeType = FindType("ShrinkCommand.ShrinkCommandRuntime", "ShrinkCommand.Runtime");
var service = runtimeType?.GetProperty("Default", BindingFlags.Public | BindingFlags.Static)?.GetValue(null);
var registerMethod = service?.GetType().GetMethod("RegisterCommands",
BindingFlags.Public | BindingFlags.Instance,
null,
new[] { typeof(object) },
null);
if (registerMethod == null)
return;
registerMethod.Invoke(service, new[] { modInstance });
if (verboseLogging)
Debug.Log($"[ShrinkModFramework] 模组 {modId} 已接入 ShrinkCommand 默认服务。");
}
catch (Exception ex)
{
Debug.LogWarning($"[ShrinkModFramework] 模组 {modId} 接入 ShrinkCommand 失败:{ex.Message}");
}
}
private static void TryRegisterNetworkInstance(Type modType, object modInstance, string modId, bool verboseLogging)
{
if (!HasAttribute(modType, "ShrinkNetwork.ShrinkNetworkSubscriberAttribute", "ShrinkNetwork.Runtime"))
return;
try
{
var runtimeType = FindType("ShrinkNetwork.ShrinkNetworkRuntime", "ShrinkNetwork.Runtime");
var service = runtimeType?.GetProperty("Default", BindingFlags.Public | BindingFlags.Static)?.GetValue(null);
var registerMethod = service?.GetType().GetMethod("RegisterHandlers",
BindingFlags.Public | BindingFlags.Instance,
null,
new[] { typeof(object) },
null);
if (registerMethod == null)
return;
registerMethod.Invoke(service, new[] { modInstance });
if (verboseLogging)
Debug.Log($"[ShrinkModFramework] 模组 {modId} 已接入 ShrinkNetwork 默认服务。");
}
catch (Exception ex)
{
Debug.LogWarning($"[ShrinkModFramework] 模组 {modId} 接入 ShrinkNetwork 失败:{ex.Message}");
}
}
private static void TryRefreshNetworkEventBusBridge(bool verboseLogging)
{
try
{
var bridgeType = FindType("ShrinkNetwork.Integration.ShrinkNetworkEventBusBridge",
"ShrinkNetwork.Integration.EventBus");
var refreshMethod = bridgeType?.GetMethod("RefreshBindings",
BindingFlags.Public | BindingFlags.Static,
null,
Type.EmptyTypes,
null);
if (refreshMethod == null)
return;
refreshMethod.Invoke(null, null);
if (verboseLogging)
Debug.Log("[ShrinkModFramework] 已刷新 ShrinkNetwork.Integration.EventBus 绑定。");
}
catch (Exception ex)
{
Debug.LogWarning($"[ShrinkModFramework] 刷新 ShrinkNetwork.Integration.EventBus 绑定失败:{ex.Message}");
}
}
private static bool HasAttribute(Type targetType, string attributeFullName, string assemblyName)
{
var attributeType = FindType(attributeFullName, assemblyName);
return attributeType != null && targetType.GetCustomAttribute(attributeType, false) != null;
}
private static Type FindType(string fullName, string assemblyName)
{
return Type.GetType($"{fullName}, {assemblyName}", false) ??
AppDomain.CurrentDomain.GetAssemblies()
.Where(assembly => string.Equals(assembly.GetName().Name, assemblyName, StringComparison.Ordinal))
.Select(assembly => assembly.GetType(fullName, false))
.FirstOrDefault(type => type != null);
}
}
}