{"version":3,"sources":["../../../src/adaptors/dao3/server.ts"],"sourcesContent":["import EventEmitter from 'eventemitter3'\r\nimport { isRemoteAdaptorData } from '../../remote'\r\nimport { isRemoteValueEvent } from '../../remoteValue/exposeToRemote'\r\nimport { type AdaptorPackageData } from '../../adaptor'\r\n\r\ninterface GamePlayerEntityLike {\r\n  player: {\r\n    userKey: string\r\n  }\r\n}\r\n\r\ninterface RemoteChannel<T extends GamePlayerEntityLike> {\r\n  onServerEvent(fn: (e: { args: unknown; entity: T }) => void): void\r\n}\r\n\r\n/**\r\n * 这是 [dao3 游戏](https://dao3.fun/) 代码服务端适配器。\r\n * ```ts\r\n * const remoteManager = new ServerSideRemoteChannelEventManager(remoteChannel)\r\n *\r\n * world.onPlayerLeave(\r\n *   remoteManager.onPlayerLeave.bind(remoteManager)\r\n * )\r\n *\r\n * export const remoteAdaptor = {\r\n *   every: remoteManager.onEvery.bind(remoteManager),\r\n *   off: remoteManager.off.bind(remoteManager),\r\n *   on: remoteManager.on.bind(remoteManager),\r\n *   once: remoteManager.once.bind(remoteManager),\r\n *   emit: (e) => {\r\n *     const entity = remoteManager.getEntity(e.targetDeviceId)\r\n *     if (!entity) {\r\n *       console.error('entity not found')\r\n *       return\r\n *     }\r\n *     remoteChannel.sendClientEvent(entity, e as unknown as JSONValue)\r\n *   },\r\n * } satisfies Adaptor\r\n *\r\n * export const remote = new Remote<RemoteFuncsFromServer, RemoteFuncsFromClient>(\r\n *   remoteAdaptor,\r\n *   {\r\n *     deviceId: 'server',\r\n *   }\r\n * )\r\n *\r\n * remote.register('initConnection', async () => {\r\n *   // 什么也不干，单纯的让客户端在服务端“备案”\r\n * })\r\n *\r\n * export const getEntity = remoteManager.getEntity.bind(remoteManager)\r\n * export const getIdByEntity = remoteManager.getIdByEntity.bind(remoteManager)\r\n * export const waitForRegister = remoteManager.waitForRegister.bind(remoteManager)\r\n * export const remoteTo = remoteManager.remoteTo.bind(remoteManager)\r\n * ```\r\n */\r\nexport class ServerSideRemoteChannelEventManager<\r\n  T extends GamePlayerEntityLike,\r\n> extends EventEmitter<{\r\n  [key: string]: [AdaptorPackageData]\r\n}> {\r\n  entityMap: [string, T][] = []\r\n\r\n  constructor(remoteChannel: RemoteChannel<T>) {\r\n    super()\r\n    remoteChannel.onServerEvent((e) => {\r\n      const { args } = e\r\n      if (!isRemoteAdaptorData(args)) {\r\n        return\r\n      }\r\n      const prevItem = this.entityMap.find(\r\n        (item) => item[1].player.userKey === e.entity.player.userKey\r\n      )\r\n      if (prevItem) {\r\n        prevItem[0] = args.deviceId\r\n        prevItem[1] = e.entity\r\n      } else {\r\n        this.entityMap.push([args.deviceId, e.entity])\r\n      }\r\n      if (!isRemoteValueEvent(args.name)) {\r\n        this.emit('__remote_every__', args)\r\n      }\r\n      this.emit(args.name, args)\r\n    })\r\n  }\r\n\r\n  onPlayerLeave(e: { entity: T }) {\r\n    this.entityMap = this.entityMap.filter(\r\n      (item) => item[1].player.userKey !== e.entity.player.userKey\r\n    )\r\n  }\r\n\r\n  onEvery(fn: (args: AdaptorPackageData) => void): void {\r\n    this.on('__remote_every__', fn)\r\n  }\r\n\r\n  waitForRegister(entity: T) {\r\n    return new Promise<void>((resolve) => {\r\n      if (\r\n        this.entityMap.some(\r\n          ([_, en]) => en.player.userKey === entity.player.userKey\r\n        )\r\n      ) {\r\n        resolve()\r\n        return\r\n      }\r\n      this.once('__remote_every__', () => {\r\n        resolve()\r\n      })\r\n    })\r\n  }\r\n\r\n  getEntity(deviceId: string): T | undefined {\r\n    return this.entityMap.find((item) => item[0] === deviceId)?.[1]\r\n  }\r\n\r\n  getIdByEntity(entity: T): string | undefined {\r\n    return this.entityMap.find(\r\n      (item) => item[1].player.userKey === entity.player.userKey\r\n    )?.[0]\r\n  }\r\n\r\n  remoteTo(config: { target: T }): {\r\n    targetDeviceId: string\r\n  }\r\n  remoteTo(config: { target: T; timeoutMs: number }): {\r\n    targetDeviceId: string\r\n    timeoutMs: number\r\n  }\r\n  remoteTo({ target, ...rest }: { target: T; timeoutMs?: number }) {\r\n    return {\r\n      targetDeviceId: this.getIdByEntity(target),\r\n      ...rest,\r\n    }\r\n  }\r\n}\r\n"],"mappings":"AAAA,OAAOA,MAAkB,gBACzB,OAAS,uBAAAC,MAA2B,eACpC,OAAS,sBAAAC,MAA0B,mCAsD5B,MAAMC,UAEHH,CAEP,CACD,UAA2B,CAAC,EAE5B,YAAYI,EAAiC,CAC3C,MAAM,EACNA,EAAc,cAAe,GAAM,CACjC,KAAM,CAAE,KAAAC,CAAK,EAAI,EACjB,GAAI,CAACJ,EAAoBI,CAAI,EAC3B,OAEF,MAAMC,EAAW,KAAK,UAAU,KAC7BC,GAASA,EAAK,CAAC,EAAE,OAAO,UAAY,EAAE,OAAO,OAAO,OACvD,EACID,GACFA,EAAS,CAAC,EAAID,EAAK,SACnBC,EAAS,CAAC,EAAI,EAAE,QAEhB,KAAK,UAAU,KAAK,CAACD,EAAK,SAAU,EAAE,MAAM,CAAC,EAE1CH,EAAmBG,EAAK,IAAI,GAC/B,KAAK,KAAK,mBAAoBA,CAAI,EAEpC,KAAK,KAAKA,EAAK,KAAMA,CAAI,CAC3B,CAAC,CACH,CAEA,cAAcG,EAAkB,CAC9B,KAAK,UAAY,KAAK,UAAU,OAC7BD,GAASA,EAAK,CAAC,EAAE,OAAO,UAAYC,EAAE,OAAO,OAAO,OACvD,CACF,CAEA,QAAQC,EAA8C,CACpD,KAAK,GAAG,mBAAoBA,CAAE,CAChC,CAEA,gBAAgBC,EAAW,CACzB,OAAO,IAAI,QAAeC,GAAY,CACpC,GACE,KAAK,UAAU,KACb,CAAC,CAACC,EAAGC,CAAE,IAAMA,EAAG,OAAO,UAAYH,EAAO,OAAO,OACnD,EACA,CACAC,EAAQ,EACR,MACF,CACA,KAAK,KAAK,mBAAoB,IAAM,CAClCA,EAAQ,CACV,CAAC,CACH,CAAC,CACH,CAEA,UAAUG,EAAiC,CAhH7C,IAAAC,EAiHI,OAAOA,EAAA,KAAK,UAAU,KAAMR,GAASA,EAAK,CAAC,IAAMO,CAAQ,IAAlD,YAAAC,EAAsD,EAC/D,CAEA,cAAcL,EAA+B,CApH/C,IAAAK,EAqHI,OAAOA,EAAA,KAAK,UAAU,KACnBR,GAASA,EAAK,CAAC,EAAE,OAAO,UAAYG,EAAO,OAAO,OACrD,IAFO,YAAAK,EAEH,EACN,CASA,SAAS,CAAE,OAAAC,EAAQ,GAAGC,CAAK,EAAsC,CAC/D,MAAO,CACL,eAAgB,KAAK,cAAcD,CAAM,EACzC,GAAGC,CACL,CACF,CACF","names":["EventEmitter","isRemoteAdaptorData","isRemoteValueEvent","ServerSideRemoteChannelEventManager","remoteChannel","args","prevItem","item","e","fn","entity","resolve","_","en","deviceId","_a","target","rest"]}