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); } } }