import { NodeIQQNTWrapperSession } from '@/napcat-core/wrapper'; import { ServiceNamingMapping } from '@/napcat-core/services/index'; import { NTEventWrapper } from './event'; /** * 创建 Service 方法的代理 * 拦截所有方法调用,通过 EventWrapper 进行调用 */ function createServiceMethodProxy( serviceName: S, originalService: ServiceNamingMapping[S], eventWrapper: NTEventWrapper ): ServiceNamingMapping[S] { return new Proxy(originalService as object, { get(target, prop, receiver) { const originalValue = Reflect.get(target, prop, receiver); // 如果不是函数,直接返回原始值 if (typeof originalValue !== 'function') { return originalValue; } const methodName = prop as string; // 返回一个包装函数,通过 EventWrapper 调用 return function (this: unknown, ...args: unknown[]) { // 构造 EventWrapper 需要的路径格式: ServiceName/MethodName const eventPath = `${serviceName}/${methodName}`; // 尝试通过 EventWrapper 调用 try { // 使用 callNoListenerEvent 的底层实现逻辑 const eventFunc = (eventWrapper as any).createEventFunction(eventPath); if (eventFunc) { return eventFunc(...args); } } catch { // 如果 EventWrapper 调用失败,回退到原始调用 } // 回退到原始方法调用 return originalValue.apply(originalService, args); }; }, }) as ServiceNamingMapping[S]; } /** * 创建 Session 的双层代理 * 第一层:拦截 getXXXService 方法 * 第二层:拦截 Service 上的具体方法调用 */ export function createSessionProxy( session: NodeIQQNTWrapperSession, eventWrapper: NTEventWrapper ): NodeIQQNTWrapperSession { // 缓存已代理的 Service,避免重复创建 const serviceProxyCache = new Map(); return new Proxy(session, { get(target, prop, receiver) { const propName = prop as string; // 检查是否是 getXXXService 方法 if (typeof propName === 'string' && propName.startsWith('get') && propName.endsWith('Service')) { // 提取 Service 名称: getMsgService -> NodeIKernelMsgService const servicePart = propName.slice(3); // 移除 'get' 前缀 const serviceName = `NodeIKernel${servicePart}` as keyof ServiceNamingMapping; // 返回一个函数,该函数返回代理后的 Service return function () { // 检查缓存 if (serviceProxyCache.has(serviceName)) { return serviceProxyCache.get(serviceName); } // 获取原始 Service const originalGetter = Reflect.get(target, prop, receiver) as () => unknown; const originalService = originalGetter.call(target); // 检查是否在 ServiceNamingMapping 中定义 if (isKnownService(serviceName)) { // 创建 Service 方法代理 const proxiedService = createServiceMethodProxy( serviceName, originalService as ServiceNamingMapping[typeof serviceName], eventWrapper ); serviceProxyCache.set(serviceName, proxiedService); return proxiedService; } // 未知的 Service,直接返回原始对象 serviceProxyCache.set(serviceName, originalService); return originalService; }; } // 非 getXXXService 方法,直接返回原始值 return Reflect.get(target, prop, receiver); }, }); } /** * 检查 Service 名称是否在已知的映射中 */ function isKnownService(serviceName: string): serviceName is keyof ServiceNamingMapping { const knownServices: string[] = [ 'NodeIKernelAvatarService', 'NodeIKernelBuddyService', 'NodeIKernelFileAssistantService', 'NodeIKernelGroupService', 'NodeIKernelLoginService', 'NodeIKernelMsgService', 'NodeIKernelOnlineStatusService', 'NodeIKernelProfileLikeService', 'NodeIKernelProfileService', 'NodeIKernelTicketService', 'NodeIKernelStorageCleanService', 'NodeIKernelRobotService', 'NodeIKernelRichMediaService', 'NodeIKernelDbToolsService', 'NodeIKernelTipOffService', 'NodeIKernelSearchService', 'NodeIKernelCollectionService', ]; return knownServices.includes(serviceName); } /** * 创建带有 EventWrapper 集成的 InstanceContext * 这是推荐的使用方式,在创建 context 时自动代理 session */ export function createProxiedSession( session: NodeIQQNTWrapperSession, eventWrapper: NTEventWrapper ): NodeIQQNTWrapperSession { return createSessionProxy(session, eventWrapper); }