@esengine/network 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/NetworkPlugin.d.ts +100 -0
- package/dist/NetworkPlugin.d.ts.map +1 -0
- package/dist/components/NetworkIdentity.d.ts +51 -0
- package/dist/components/NetworkIdentity.d.ts.map +1 -0
- package/dist/components/NetworkTransform.d.ts +71 -0
- package/dist/components/NetworkTransform.d.ts.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1348 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/NetworkNodes.d.ts +77 -0
- package/dist/nodes/NetworkNodes.d.ts.map +1 -0
- package/dist/nodes/index.d.ts +9 -0
- package/dist/nodes/index.d.ts.map +1 -0
- package/dist/services/NetworkService.d.ts +62 -0
- package/dist/services/NetworkService.d.ts.map +1 -0
- package/dist/sync/ClientPrediction.d.ts +158 -0
- package/dist/sync/ClientPrediction.d.ts.map +1 -0
- package/dist/sync/IInterpolator.d.ts +62 -0
- package/dist/sync/IInterpolator.d.ts.map +1 -0
- package/dist/sync/IStateSnapshot.d.ts +116 -0
- package/dist/sync/IStateSnapshot.d.ts.map +1 -0
- package/dist/sync/SnapshotBuffer.d.ts +58 -0
- package/dist/sync/SnapshotBuffer.d.ts.map +1 -0
- package/dist/sync/TransformInterpolator.d.ts +47 -0
- package/dist/sync/TransformInterpolator.d.ts.map +1 -0
- package/dist/sync/index.d.ts +15 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/systems/NetworkInputSystem.d.ts +32 -0
- package/dist/systems/NetworkInputSystem.d.ts.map +1 -0
- package/dist/systems/NetworkSpawnSystem.d.ts +37 -0
- package/dist/systems/NetworkSpawnSystem.d.ts.map +1 -0
- package/dist/systems/NetworkSyncSystem.d.ts +39 -0
- package/dist/systems/NetworkSyncSystem.d.ts.map +1 -0
- package/dist/tokens.d.ts +29 -0
- package/dist/tokens.d.ts.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/tokens.ts","../src/NetworkPlugin.ts","../src/services/NetworkService.ts","../src/systems/NetworkSyncSystem.ts","../src/components/NetworkIdentity.ts","../src/components/NetworkTransform.ts","../src/systems/NetworkSpawnSystem.ts","../src/systems/NetworkInputSystem.ts","../src/sync/SnapshotBuffer.ts","../src/sync/IInterpolator.ts","../src/sync/TransformInterpolator.ts","../src/sync/ClientPrediction.ts","../src/nodes/NetworkNodes.ts"],"sourcesContent":["/**\n * @esengine/network\n *\n * 基于 TSRPC 的网络同步模块(客户端)\n * TSRPC-based network synchronization module (client)\n */\n\n// ============================================================================\n// Re-export from protocols | 从协议包重新导出\n// ============================================================================\n\nexport type {\n ServiceType,\n Vec2,\n IEntityState,\n IPlayerInput,\n MsgSync,\n MsgInput,\n MsgSpawn,\n MsgDespawn,\n ReqJoin,\n ResJoin\n} from '@esengine/network-protocols';\n\nexport { serviceProto } from '@esengine/network-protocols';\n\n// ============================================================================\n// Tokens | 服务令牌\n// ============================================================================\n\nexport {\n NetworkServiceToken,\n NetworkSyncSystemToken,\n NetworkSpawnSystemToken,\n NetworkInputSystemToken\n} from './tokens';\n\n// ============================================================================\n// Plugin | 插件\n// ============================================================================\n\nexport { NetworkPlugin } from './NetworkPlugin';\n\n// ============================================================================\n// Services | 服务\n// ============================================================================\n\nexport { NetworkService, ENetworkState } from './services/NetworkService';\nexport type { INetworkCallbacks } from './services/NetworkService';\n\n// ============================================================================\n// Components | 组件\n// ============================================================================\n\nexport { NetworkIdentity } from './components/NetworkIdentity';\nexport { NetworkTransform } from './components/NetworkTransform';\n\n// ============================================================================\n// Systems | 系统\n// ============================================================================\n\nexport { NetworkSyncSystem } from './systems/NetworkSyncSystem';\nexport { NetworkSpawnSystem } from './systems/NetworkSpawnSystem';\nexport type { PrefabFactory } from './systems/NetworkSpawnSystem';\nexport { NetworkInputSystem } from './systems/NetworkInputSystem';\n\n// ============================================================================\n// State Sync | 状态同步\n// ============================================================================\n\nexport type {\n IStateSnapshot,\n ITransformState,\n ITransformStateWithVelocity,\n ISnapshotBufferConfig,\n ISnapshotBuffer\n} from './sync';\n\nexport type {\n IInterpolator,\n IExtrapolator,\n IInputSnapshot,\n IPredictedState,\n IPredictor,\n ClientPredictionConfig\n} from './sync';\n\nexport {\n lerp,\n lerpAngle,\n smoothDamp,\n SnapshotBuffer,\n createSnapshotBuffer,\n TransformInterpolator,\n HermiteTransformInterpolator,\n createTransformInterpolator,\n createHermiteTransformInterpolator,\n ClientPrediction,\n createClientPrediction\n} from './sync';\n\n// ============================================================================\n// Blueprint Nodes | 蓝图节点\n// ============================================================================\n\nexport {\n IsLocalPlayerTemplate,\n IsServerTemplate,\n HasAuthorityTemplate,\n GetNetworkIdTemplate,\n GetLocalPlayerIdTemplate,\n IsLocalPlayerExecutor,\n IsServerExecutor,\n HasAuthorityExecutor,\n GetNetworkIdExecutor,\n GetLocalPlayerIdExecutor,\n NetworkNodeDefinitions\n} from './nodes';\n","/**\n * Network 模块服务令牌\n * Network module service tokens\n */\n\nimport { createServiceToken } from '@esengine/ecs-framework';\nimport type { NetworkService } from './services/NetworkService';\nimport type { NetworkSyncSystem } from './systems/NetworkSyncSystem';\nimport type { NetworkSpawnSystem } from './systems/NetworkSpawnSystem';\nimport type { NetworkInputSystem } from './systems/NetworkInputSystem';\n\n// ============================================================================\n// Network 模块导出的令牌 | Tokens exported by Network module\n// ============================================================================\n\n/**\n * 网络服务令牌\n * Network service token\n */\nexport const NetworkServiceToken = createServiceToken<NetworkService>('networkService');\n\n/**\n * 网络同步系统令牌\n * Network sync system token\n */\nexport const NetworkSyncSystemToken = createServiceToken<NetworkSyncSystem>('networkSyncSystem');\n\n/**\n * 网络生成系统令牌\n * Network spawn system token\n */\nexport const NetworkSpawnSystemToken = createServiceToken<NetworkSpawnSystem>('networkSpawnSystem');\n\n/**\n * 网络输入系统令牌\n * Network input system token\n */\nexport const NetworkInputSystemToken = createServiceToken<NetworkInputSystem>('networkInputSystem');\n","import { type IPlugin, Core, type ServiceContainer, type Scene } from '@esengine/ecs-framework';\nimport { NetworkService } from './services/NetworkService';\nimport { NetworkSyncSystem } from './systems/NetworkSyncSystem';\nimport { NetworkSpawnSystem, type PrefabFactory } from './systems/NetworkSpawnSystem';\nimport { NetworkInputSystem } from './systems/NetworkInputSystem';\n\n/**\n * 网络插件\n * Network plugin\n *\n * 提供基于 TSRPC 的网络同步功能。\n * Provides TSRPC-based network synchronization.\n *\n * @example\n * ```typescript\n * import { Core } from '@esengine/ecs-framework';\n * import { NetworkPlugin } from '@esengine/network';\n *\n * const networkPlugin = new NetworkPlugin();\n * await Core.installPlugin(networkPlugin);\n *\n * // 连接到服务器 | Connect to server\n * await networkPlugin.connect('ws://localhost:3000', 'Player1');\n *\n * // 注册预制体 | Register prefab\n * networkPlugin.registerPrefab('player', (scene, spawn) => {\n * const entity = scene.createEntity('Player');\n * return entity;\n * });\n * ```\n */\nexport class NetworkPlugin implements IPlugin {\n public readonly name = '@esengine/network';\n public readonly version = '1.0.0';\n\n private _networkService!: NetworkService;\n private _syncSystem!: NetworkSyncSystem;\n private _spawnSystem!: NetworkSpawnSystem;\n private _inputSystem!: NetworkInputSystem;\n\n /**\n * 网络服务\n * Network service\n */\n get networkService(): NetworkService {\n return this._networkService;\n }\n\n /**\n * 同步系统\n * Sync system\n */\n get syncSystem(): NetworkSyncSystem {\n return this._syncSystem;\n }\n\n /**\n * 生成系统\n * Spawn system\n */\n get spawnSystem(): NetworkSpawnSystem {\n return this._spawnSystem;\n }\n\n /**\n * 输入系统\n * Input system\n */\n get inputSystem(): NetworkInputSystem {\n return this._inputSystem;\n }\n\n /**\n * 是否已连接\n * Is connected\n */\n get isConnected(): boolean {\n return this._networkService?.isConnected ?? false;\n }\n\n /**\n * 安装插件\n * Install plugin\n */\n install(_core: Core, _services: ServiceContainer): void {\n this._networkService = new NetworkService();\n\n // 当场景加载时添加系统\n // Add systems when scene loads\n const scene = Core.scene;\n if (scene) {\n this._setupSystems(scene as Scene);\n }\n }\n\n /**\n * 卸载插件\n * Uninstall plugin\n */\n uninstall(): void {\n this._networkService?.disconnect();\n }\n\n private _setupSystems(scene: Scene): void {\n this._syncSystem = new NetworkSyncSystem(this._networkService);\n this._spawnSystem = new NetworkSpawnSystem(this._networkService, this._syncSystem);\n this._inputSystem = new NetworkInputSystem(this._networkService);\n\n scene.addSystem(this._syncSystem);\n scene.addSystem(this._spawnSystem);\n scene.addSystem(this._inputSystem);\n }\n\n /**\n * 连接到服务器\n * Connect to server\n */\n public async connect(serverUrl: string, playerName: string, roomId?: string): Promise<boolean> {\n return this._networkService.connect(serverUrl, playerName, roomId);\n }\n\n /**\n * 断开连接\n * Disconnect\n */\n public async disconnect(): Promise<void> {\n await this._networkService.disconnect();\n }\n\n /**\n * 注册预制体工厂\n * Register prefab factory\n */\n public registerPrefab(prefabType: string, factory: PrefabFactory): void {\n this._spawnSystem?.registerPrefab(prefabType, factory);\n }\n\n /**\n * 发送移动输入\n * Send move input\n */\n public sendMoveInput(x: number, y: number): void {\n this._inputSystem?.addMoveInput(x, y);\n }\n\n /**\n * 发送动作输入\n * Send action input\n */\n public sendActionInput(action: string): void {\n this._inputSystem?.addActionInput(action);\n }\n}\n","import { WsClient } from 'tsrpc-browser';\nimport {\n serviceProto,\n type ServiceType,\n type MsgSync,\n type MsgSpawn,\n type MsgDespawn,\n type IPlayerInput\n} from '@esengine/network-protocols';\n\n/**\n * 连接状态\n * Connection state\n */\nexport const enum ENetworkState {\n Disconnected = 0,\n Connecting = 1,\n Connected = 2\n}\n\n/**\n * 网络事件回调\n * Network event callbacks\n */\nexport interface INetworkCallbacks {\n onConnected?: (clientId: number, roomId: string) => void;\n onDisconnected?: () => void;\n onSync?: (msg: MsgSync) => void;\n onSpawn?: (msg: MsgSpawn) => void;\n onDespawn?: (msg: MsgDespawn) => void;\n onError?: (error: Error) => void;\n}\n\n/**\n * 创建 TSRPC 客户端\n * Create TSRPC client\n */\nfunction createClient(serverUrl: string): WsClient<ServiceType> {\n return new WsClient(serviceProto, {\n server: serverUrl,\n json: true,\n logLevel: 'warn'\n });\n}\n\n/**\n * 网络服务\n * Network service\n *\n * 基于 TSRPC 的网络服务封装,提供类型安全的网络通信。\n * TSRPC-based network service wrapper with type-safe communication.\n */\nexport class NetworkService {\n private _client: WsClient<ServiceType> | null = null;\n private _state: ENetworkState = ENetworkState.Disconnected;\n private _clientId: number = 0;\n private _roomId: string = '';\n private _callbacks: INetworkCallbacks = {};\n\n get state(): ENetworkState {\n return this._state;\n }\n\n get clientId(): number {\n return this._clientId;\n }\n\n get roomId(): string {\n return this._roomId;\n }\n\n get isConnected(): boolean {\n return this._state === ENetworkState.Connected;\n }\n\n /**\n * 设置回调\n * Set callbacks\n */\n setCallbacks(callbacks: INetworkCallbacks): void {\n this._callbacks = { ...this._callbacks, ...callbacks };\n }\n\n /**\n * 连接到服务器\n * Connect to server\n */\n async connect(serverUrl: string, playerName: string, roomId?: string): Promise<boolean> {\n if (this._state !== ENetworkState.Disconnected) {\n return false;\n }\n\n this._state = ENetworkState.Connecting;\n this._client = createClient(serverUrl);\n this._setupListeners();\n\n // 连接\n // Connect\n const connectResult = await this._client.connect();\n if (!connectResult.isSucc) {\n this._state = ENetworkState.Disconnected;\n this._callbacks.onError?.(new Error(connectResult.errMsg));\n return false;\n }\n\n // 加入房间\n // Join room\n const joinResult = await this._client.callApi('Join', {\n playerName,\n roomId\n });\n\n if (!joinResult.isSucc) {\n await this._client.disconnect();\n this._state = ENetworkState.Disconnected;\n this._callbacks.onError?.(new Error(joinResult.err.message));\n return false;\n }\n\n this._clientId = joinResult.res.clientId;\n this._roomId = joinResult.res.roomId;\n this._state = ENetworkState.Connected;\n this._callbacks.onConnected?.(this._clientId, this._roomId);\n\n return true;\n }\n\n /**\n * 断开连接\n * Disconnect\n */\n async disconnect(): Promise<void> {\n if (this._client) {\n await this._client.disconnect();\n }\n this._state = ENetworkState.Disconnected;\n this._clientId = 0;\n this._roomId = '';\n this._client = null;\n }\n\n /**\n * 发送输入\n * Send input\n */\n sendInput(input: IPlayerInput): void {\n if (!this.isConnected || !this._client) return;\n this._client.sendMsg('Input', { input });\n }\n\n private _setupListeners(): void {\n if (!this._client) return;\n\n this._client.listenMsg('Sync', (msg) => {\n this._callbacks.onSync?.(msg);\n });\n\n this._client.listenMsg('Spawn', (msg) => {\n this._callbacks.onSpawn?.(msg);\n });\n\n this._client.listenMsg('Despawn', (msg) => {\n this._callbacks.onDespawn?.(msg);\n });\n\n this._client.flows.postDisconnectFlow.push((v) => {\n this._state = ENetworkState.Disconnected;\n this._callbacks.onDisconnected?.();\n return v;\n });\n }\n}\n","import { EntitySystem, Matcher, Time, type Entity } from '@esengine/ecs-framework';\nimport type { MsgSync } from '@esengine/network-protocols';\nimport { NetworkIdentity } from '../components/NetworkIdentity';\nimport { NetworkTransform } from '../components/NetworkTransform';\nimport type { NetworkService } from '../services/NetworkService';\n\n/**\n * 网络同步系统\n * Network sync system\n *\n * 处理网络实体的状态同步和插值。\n * Handles state synchronization and interpolation for networked entities.\n */\nexport class NetworkSyncSystem extends EntitySystem {\n private _networkService: NetworkService;\n private _netIdToEntity: Map<number, number> = new Map();\n\n constructor(networkService: NetworkService) {\n super(Matcher.all(NetworkIdentity, NetworkTransform));\n this._networkService = networkService;\n }\n\n protected override onInitialize(): void {\n this._networkService.setCallbacks({\n onSync: this._handleSync.bind(this)\n });\n }\n\n /**\n * 处理实体列表\n * Process entities\n */\n protected override process(entities: readonly Entity[]): void {\n const deltaTime = Time.deltaTime;\n\n for (const entity of entities) {\n const transform = this.requireComponent(entity, NetworkTransform);\n const identity = this.requireComponent(entity, NetworkIdentity);\n\n // 只有非本地玩家需要插值\n // Only non-local players need interpolation\n if (!identity.bHasAuthority && transform.bInterpolate) {\n this._interpolate(transform, deltaTime);\n }\n }\n }\n\n /**\n * 注册网络实体\n * Register network entity\n */\n public registerEntity(netId: number, entityId: number): void {\n this._netIdToEntity.set(netId, entityId);\n }\n\n /**\n * 注销网络实体\n * Unregister network entity\n */\n public unregisterEntity(netId: number): void {\n this._netIdToEntity.delete(netId);\n }\n\n /**\n * 根据网络 ID 获取实体 ID\n * Get entity ID by network ID\n */\n public getEntityId(netId: number): number | undefined {\n return this._netIdToEntity.get(netId);\n }\n\n private _handleSync(msg: MsgSync): void {\n for (const state of msg.entities) {\n const entityId = this._netIdToEntity.get(state.netId);\n if (entityId === undefined) continue;\n\n const entity = this.scene?.findEntityById(entityId);\n if (!entity) continue;\n\n const transform = entity.getComponent(NetworkTransform);\n if (transform && state.pos) {\n transform.setTarget(state.pos.x, state.pos.y, state.rot);\n }\n }\n }\n\n private _interpolate(transform: NetworkTransform, deltaTime: number): void {\n const t = Math.min(1, transform.lerpSpeed * deltaTime);\n\n transform.currentX += (transform.targetX - transform.currentX) * t;\n transform.currentY += (transform.targetY - transform.currentY) * t;\n\n // 角度插值需要处理环绕\n // Angle interpolation needs to handle wrap-around\n let angleDiff = transform.targetRotation - transform.currentRotation;\n while (angleDiff > Math.PI) angleDiff -= Math.PI * 2;\n while (angleDiff < -Math.PI) angleDiff += Math.PI * 2;\n transform.currentRotation += angleDiff * t;\n }\n\n protected override onDestroy(): void {\n this._netIdToEntity.clear();\n }\n}\n","import { Component, ECSComponent, Serialize, Serializable, Property } from '@esengine/ecs-framework';\n\n/**\n * 网络身份组件\n * Network identity component\n *\n * 标识一个实体在网络上的唯一身份。\n * Identifies an entity's unique identity on the network.\n */\n@ECSComponent('NetworkIdentity')\n@Serializable({ version: 1, typeId: 'NetworkIdentity' })\nexport class NetworkIdentity extends Component {\n /**\n * 网络实体 ID\n * Network entity ID\n */\n @Serialize()\n @Property({ type: 'integer', label: 'Net ID', readOnly: true })\n public netId: number = 0;\n\n /**\n * 所有者客户端 ID\n * Owner client ID\n */\n @Serialize()\n @Property({ type: 'integer', label: 'Owner ID', readOnly: true })\n public ownerId: number = 0;\n\n /**\n * 是否为本地玩家拥有\n * Is owned by local player\n */\n public bIsLocalPlayer: boolean = false;\n\n /**\n * 是否有权限控制\n * Has authority\n */\n public bHasAuthority: boolean = false;\n\n /**\n * 预制体类型\n * Prefab type\n */\n @Serialize()\n @Property({ type: 'string', label: 'Prefab Type' })\n public prefabType: string = '';\n\n /**\n * 同步间隔 (ms)\n * Sync interval in milliseconds\n */\n @Serialize()\n @Property({ type: 'number', label: 'Sync Interval', min: 16 })\n public syncInterval: number = 100;\n\n /**\n * 上次同步时间\n * Last sync time\n */\n public lastSyncTime: number = 0;\n\n /**\n * 检查是否需要同步\n * Check if sync is needed\n */\n public needsSync(now: number): boolean {\n return now - this.lastSyncTime >= this.syncInterval;\n }\n}\n","import { Component, ECSComponent, Serialize, Serializable, Property } from '@esengine/ecs-framework';\n\n/**\n * 网络变换组件\n * Network transform component\n *\n * 同步实体的位置和旋转。支持插值平滑。\n * Syncs entity position and rotation with interpolation smoothing.\n */\n@ECSComponent('NetworkTransform', { requires: ['NetworkIdentity'] })\n@Serializable({ version: 1, typeId: 'NetworkTransform' })\nexport class NetworkTransform extends Component {\n /**\n * 目标位置 X\n * Target position X\n */\n public targetX: number = 0;\n\n /**\n * 目标位置 Y\n * Target position Y\n */\n public targetY: number = 0;\n\n /**\n * 目标旋转\n * Target rotation\n */\n public targetRotation: number = 0;\n\n /**\n * 当前位置 X\n * Current position X\n */\n public currentX: number = 0;\n\n /**\n * 当前位置 Y\n * Current position Y\n */\n public currentY: number = 0;\n\n /**\n * 当前旋转\n * Current rotation\n */\n public currentRotation: number = 0;\n\n /**\n * 插值速度\n * Interpolation speed\n */\n @Serialize()\n @Property({ type: 'number', label: 'Lerp Speed', min: 0.1, max: 50 })\n public lerpSpeed: number = 10;\n\n /**\n * 是否启用插值\n * Enable interpolation\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Interpolate' })\n public bInterpolate: boolean = true;\n\n /**\n * 同步间隔 (ms)\n * Sync interval in milliseconds\n */\n @Serialize()\n @Property({ type: 'number', label: 'Sync Interval', min: 16 })\n public syncInterval: number = 50;\n\n /**\n * 上次同步时间\n * Last sync time\n */\n public lastSyncTime: number = 0;\n\n /**\n * 设置目标位置\n * Set target position\n */\n public setTarget(x: number, y: number, rotation?: number): void {\n this.targetX = x;\n this.targetY = y;\n if (rotation !== undefined) {\n this.targetRotation = rotation;\n }\n }\n\n /**\n * 立即跳转到目标位置\n * Snap to target position immediately\n */\n public snap(): void {\n this.currentX = this.targetX;\n this.currentY = this.targetY;\n this.currentRotation = this.targetRotation;\n }\n}\n","import { EntitySystem, Entity, type Scene, Matcher } from '@esengine/ecs-framework';\nimport type { MsgSpawn, MsgDespawn } from '@esengine/network-protocols';\nimport { NetworkIdentity } from '../components/NetworkIdentity';\nimport { NetworkTransform } from '../components/NetworkTransform';\nimport type { NetworkService } from '../services/NetworkService';\nimport type { NetworkSyncSystem } from './NetworkSyncSystem';\n\n/**\n * 预制体工厂函数类型\n * Prefab factory function type\n */\nexport type PrefabFactory = (scene: Scene, spawn: MsgSpawn) => Entity;\n\n/**\n * 网络生成系统\n * Network spawn system\n *\n * 处理网络实体的生成和销毁。\n * Handles spawning and despawning of networked entities.\n */\nexport class NetworkSpawnSystem extends EntitySystem {\n private _networkService: NetworkService;\n private _syncSystem: NetworkSyncSystem;\n private _prefabFactories: Map<string, PrefabFactory> = new Map();\n\n constructor(networkService: NetworkService, syncSystem: NetworkSyncSystem) {\n // 不查询任何实体,此系统只响应网络消息\n // Don't query any entities, this system only responds to network messages\n super(Matcher.nothing());\n this._networkService = networkService;\n this._syncSystem = syncSystem;\n }\n\n protected override onInitialize(): void {\n this._networkService.setCallbacks({\n onSpawn: this._handleSpawn.bind(this),\n onDespawn: this._handleDespawn.bind(this)\n });\n }\n\n /**\n * 注册预制体工厂\n * Register prefab factory\n */\n public registerPrefab(prefabType: string, factory: PrefabFactory): void {\n this._prefabFactories.set(prefabType, factory);\n }\n\n /**\n * 注销预制体工厂\n * Unregister prefab factory\n */\n public unregisterPrefab(prefabType: string): void {\n this._prefabFactories.delete(prefabType);\n }\n\n private _handleSpawn(msg: MsgSpawn): void {\n if (!this.scene) return;\n\n const factory = this._prefabFactories.get(msg.prefab);\n if (!factory) {\n this.logger.warn(`Unknown prefab: ${msg.prefab}`);\n return;\n }\n\n const entity = factory(this.scene, msg);\n\n // 添加网络组件\n // Add network components\n const identity = entity.addComponent(new NetworkIdentity());\n identity.netId = msg.netId;\n identity.ownerId = msg.ownerId;\n identity.prefabType = msg.prefab;\n identity.bHasAuthority = msg.ownerId === this._networkService.clientId;\n identity.bIsLocalPlayer = identity.bHasAuthority;\n\n const transform = entity.addComponent(new NetworkTransform());\n transform.setTarget(msg.pos.x, msg.pos.y, msg.rot);\n transform.snap();\n\n // 注册到同步系统\n // Register to sync system\n this._syncSystem.registerEntity(msg.netId, entity.id);\n }\n\n private _handleDespawn(msg: MsgDespawn): void {\n const entityId = this._syncSystem.getEntityId(msg.netId);\n if (entityId === undefined) return;\n\n const entity = this.scene?.findEntityById(entityId);\n if (entity) {\n entity.destroy();\n }\n\n this._syncSystem.unregisterEntity(msg.netId);\n }\n\n protected override onDestroy(): void {\n this._prefabFactories.clear();\n }\n}\n","import { EntitySystem, Matcher } from '@esengine/ecs-framework';\nimport type { IPlayerInput } from '@esengine/network-protocols';\nimport type { NetworkService } from '../services/NetworkService';\n\n/**\n * 网络输入系统\n * Network input system\n *\n * 收集本地玩家输入并发送到服务器。\n * Collects local player input and sends to server.\n */\nexport class NetworkInputSystem extends EntitySystem {\n private _networkService: NetworkService;\n private _frame: number = 0;\n private _inputQueue: IPlayerInput[] = [];\n\n constructor(networkService: NetworkService) {\n // 不查询任何实体,此系统只处理输入\n // Don't query any entities, this system only handles input\n super(Matcher.nothing());\n this._networkService = networkService;\n }\n\n /**\n * 处理输入队列\n * Process input queue\n */\n protected override process(): void {\n if (!this._networkService.isConnected) return;\n\n this._frame++;\n\n // 发送队列中的输入\n // Send queued inputs\n while (this._inputQueue.length > 0) {\n const input = this._inputQueue.shift()!;\n input.frame = this._frame;\n this._networkService.sendInput(input);\n }\n }\n\n /**\n * 添加移动输入\n * Add move input\n */\n public addMoveInput(x: number, y: number): void {\n this._inputQueue.push({\n frame: 0,\n moveDir: { x, y }\n });\n }\n\n /**\n * 添加动作输入\n * Add action input\n */\n public addActionInput(action: string): void {\n const lastInput = this._inputQueue[this._inputQueue.length - 1];\n if (lastInput) {\n lastInput.actions = lastInput.actions || [];\n lastInput.actions.push(action);\n } else {\n this._inputQueue.push({\n frame: 0,\n actions: [action]\n });\n }\n }\n\n protected override onDestroy(): void {\n this._inputQueue.length = 0;\n }\n}\n","/**\n * @zh 快照缓冲区实现\n * @en Snapshot Buffer Implementation\n *\n * @zh 用于存储和插值网络状态快照\n * @en Stores and interpolates network state snapshots\n */\n\nimport type { IStateSnapshot, ISnapshotBuffer, ISnapshotBufferConfig } from './IStateSnapshot';\n\n// =============================================================================\n// 快照缓冲区实现 | Snapshot Buffer Implementation\n// =============================================================================\n\n/**\n * @zh 快照缓冲区\n * @en Snapshot buffer\n */\nexport class SnapshotBuffer<T> implements ISnapshotBuffer<T> {\n private readonly _buffer: IStateSnapshot<T>[] = [];\n private readonly _maxSize: number;\n private readonly _interpolationDelay: number;\n\n constructor(config: ISnapshotBufferConfig) {\n this._maxSize = config.maxSize;\n this._interpolationDelay = config.interpolationDelay;\n }\n\n get size(): number {\n return this._buffer.length;\n }\n\n /**\n * @zh 获取插值延迟\n * @en Get interpolation delay\n */\n get interpolationDelay(): number {\n return this._interpolationDelay;\n }\n\n /**\n * @zh 添加快照\n * @en Add snapshot\n */\n push(snapshot: IStateSnapshot<T>): void {\n // Insert in sorted order by timestamp\n let insertIndex = this._buffer.length;\n for (let i = this._buffer.length - 1; i >= 0; i--) {\n if (this._buffer[i].timestamp <= snapshot.timestamp) {\n insertIndex = i + 1;\n break;\n }\n if (i === 0) {\n insertIndex = 0;\n }\n }\n\n this._buffer.splice(insertIndex, 0, snapshot);\n\n // Remove old snapshots if buffer is full\n while (this._buffer.length > this._maxSize) {\n this._buffer.shift();\n }\n }\n\n /**\n * @zh 获取用于插值的两个快照\n * @en Get two snapshots for interpolation\n */\n getInterpolationSnapshots(renderTime: number): [IStateSnapshot<T>, IStateSnapshot<T>, number] | null {\n if (this._buffer.length < 2) {\n return null;\n }\n\n // Apply interpolation delay\n const targetTime = renderTime - this._interpolationDelay;\n\n // Find the two snapshots that bracket the target time\n for (let i = 0; i < this._buffer.length - 1; i++) {\n const prev = this._buffer[i];\n const next = this._buffer[i + 1];\n\n if (prev.timestamp <= targetTime && next.timestamp >= targetTime) {\n const duration = next.timestamp - prev.timestamp;\n const t = duration > 0 ? (targetTime - prev.timestamp) / duration : 0;\n return [prev, next, Math.max(0, Math.min(1, t))];\n }\n }\n\n // If target time is beyond buffer, extrapolate from last two snapshots\n if (targetTime > this._buffer[this._buffer.length - 1].timestamp) {\n const prev = this._buffer[this._buffer.length - 2];\n const next = this._buffer[this._buffer.length - 1];\n const duration = next.timestamp - prev.timestamp;\n const t = duration > 0 ? (targetTime - prev.timestamp) / duration : 1;\n // Clamp extrapolation to prevent wild values\n return [prev, next, Math.min(t, 2)];\n }\n\n // Target time is before buffer start\n return null;\n }\n\n /**\n * @zh 获取最新快照\n * @en Get latest snapshot\n */\n getLatest(): IStateSnapshot<T> | null {\n return this._buffer.length > 0 ? this._buffer[this._buffer.length - 1] : null;\n }\n\n /**\n * @zh 获取特定时间之后的所有快照\n * @en Get all snapshots after a specific time\n */\n getSnapshotsAfter(timestamp: number): IStateSnapshot<T>[] {\n return this._buffer.filter(s => s.timestamp > timestamp);\n }\n\n /**\n * @zh 清空缓冲区\n * @en Clear buffer\n */\n clear(): void {\n this._buffer.length = 0;\n }\n}\n\n// =============================================================================\n// 工厂函数 | Factory Functions\n// =============================================================================\n\n/**\n * @zh 创建快照缓冲区\n * @en Create snapshot buffer\n *\n * @param maxSize - @zh 最大快照数量(默认 30)@en Maximum snapshot count (default 30)\n * @param interpolationDelay - @zh 插值延迟毫秒(默认 100)@en Interpolation delay in ms (default 100)\n */\nexport function createSnapshotBuffer<T>(\n maxSize: number = 30,\n interpolationDelay: number = 100\n): SnapshotBuffer<T> {\n return new SnapshotBuffer<T>({ maxSize, interpolationDelay });\n}\n","/**\n * @zh 插值器接口\n * @en Interpolator Interface\n *\n * @zh 提供状态插值的抽象\n * @en Provides abstraction for state interpolation\n */\n\n// =============================================================================\n// 插值器接口 | Interpolator Interface\n// =============================================================================\n\n/**\n * @zh 插值器接口\n * @en Interpolator interface\n */\nexport interface IInterpolator<T> {\n /**\n * @zh 在两个状态之间插值\n * @en Interpolate between two states\n *\n * @param from - @zh 起始状态 @en Start state\n * @param to - @zh 目标状态 @en Target state\n * @param t - @zh 插值因子 (0-1) @en Interpolation factor (0-1)\n * @returns @zh 插值后的状态 @en Interpolated state\n */\n interpolate(from: T, to: T, t: number): T;\n}\n\n/**\n * @zh 外推器接口\n * @en Extrapolator interface\n */\nexport interface IExtrapolator<T> {\n /**\n * @zh 基于当前状态外推\n * @en Extrapolate based on current state\n *\n * @param state - @zh 当前状态 @en Current state\n * @param deltaTime - @zh 外推时间(秒)@en Extrapolation time in seconds\n * @returns @zh 外推后的状态 @en Extrapolated state\n */\n extrapolate(state: T, deltaTime: number): T;\n}\n\n// =============================================================================\n// 内置插值器 | Built-in Interpolators\n// =============================================================================\n\n/**\n * @zh 线性插值函数\n * @en Linear interpolation function\n */\nexport function lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\n/**\n * @zh 角度插值函数(处理环绕)\n * @en Angle interpolation function (handles wrap-around)\n */\nexport function lerpAngle(a: number, b: number, t: number): number {\n let diff = b - a;\n while (diff > Math.PI) diff -= Math.PI * 2;\n while (diff < -Math.PI) diff += Math.PI * 2;\n return a + diff * t;\n}\n\n/**\n * @zh 平滑阻尼插值\n * @en Smooth damp interpolation\n *\n * @param current - @zh 当前值 @en Current value\n * @param target - @zh 目标值 @en Target value\n * @param velocity - @zh 当前速度(将被修改)@en Current velocity (will be modified)\n * @param smoothTime - @zh 平滑时间 @en Smooth time\n * @param deltaTime - @zh 帧时间 @en Delta time\n * @param maxSpeed - @zh 最大速度 @en Maximum speed\n * @returns @zh [新值, 新速度] @en [new value, new velocity]\n */\nexport function smoothDamp(\n current: number,\n target: number,\n velocity: number,\n smoothTime: number,\n deltaTime: number,\n maxSpeed: number = Infinity\n): [number, number] {\n smoothTime = Math.max(0.0001, smoothTime);\n const omega = 2 / smoothTime;\n const x = omega * deltaTime;\n const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x);\n\n let change = current - target;\n const maxChange = maxSpeed * smoothTime;\n change = Math.max(-maxChange, Math.min(maxChange, change));\n\n const temp = (velocity + omega * change) * deltaTime;\n let newVelocity = (velocity - omega * temp) * exp;\n let newValue = target + (change + temp) * exp;\n\n // Prevent overshoot\n if ((target - current > 0) === (newValue > target)) {\n newValue = target;\n newVelocity = (newValue - target) / deltaTime;\n }\n\n return [newValue, newVelocity];\n}\n","/**\n * @zh 变换插值器\n * @en Transform Interpolator\n *\n * @zh 用于网络变换状态的插值\n * @en Interpolates network transform states\n */\n\nimport type { ITransformState, ITransformStateWithVelocity } from './IStateSnapshot';\nimport type { IInterpolator, IExtrapolator } from './IInterpolator';\nimport { lerp, lerpAngle } from './IInterpolator';\n\n// =============================================================================\n// 变换插值器 | Transform Interpolator\n// =============================================================================\n\n/**\n * @zh 变换状态插值器\n * @en Transform state interpolator\n */\nexport class TransformInterpolator implements IInterpolator<ITransformState>, IExtrapolator<ITransformStateWithVelocity> {\n /**\n * @zh 在两个变换状态之间插值\n * @en Interpolate between two transform states\n */\n interpolate(from: ITransformState, to: ITransformState, t: number): ITransformState {\n return {\n x: lerp(from.x, to.x, t),\n y: lerp(from.y, to.y, t),\n rotation: lerpAngle(from.rotation, to.rotation, t)\n };\n }\n\n /**\n * @zh 基于速度外推变换状态\n * @en Extrapolate transform state based on velocity\n */\n extrapolate(state: ITransformStateWithVelocity, deltaTime: number): ITransformStateWithVelocity {\n return {\n x: state.x + state.velocityX * deltaTime,\n y: state.y + state.velocityY * deltaTime,\n rotation: state.rotation + state.angularVelocity * deltaTime,\n velocityX: state.velocityX,\n velocityY: state.velocityY,\n angularVelocity: state.angularVelocity\n };\n }\n}\n\n// =============================================================================\n// 赫尔米特插值器 | Hermite Interpolator\n// =============================================================================\n\n/**\n * @zh 赫尔米特变换插值器(更平滑的曲线)\n * @en Hermite transform interpolator (smoother curves)\n */\nexport class HermiteTransformInterpolator implements IInterpolator<ITransformStateWithVelocity> {\n /**\n * @zh 使用赫尔米特插值\n * @en Use Hermite interpolation\n */\n interpolate(\n from: ITransformStateWithVelocity,\n to: ITransformStateWithVelocity,\n t: number\n ): ITransformStateWithVelocity {\n const t2 = t * t;\n const t3 = t2 * t;\n\n // Hermite basis functions\n const h00 = 2 * t3 - 3 * t2 + 1;\n const h10 = t3 - 2 * t2 + t;\n const h01 = -2 * t3 + 3 * t2;\n const h11 = t3 - t2;\n\n // Estimate time interval (assume 100ms between snapshots)\n const dt = 0.1;\n\n const x = h00 * from.x + h10 * from.velocityX * dt + h01 * to.x + h11 * to.velocityX * dt;\n const y = h00 * from.y + h10 * from.velocityY * dt + h01 * to.y + h11 * to.velocityY * dt;\n\n // Derive velocity from position derivatives\n const dh00 = 6 * t2 - 6 * t;\n const dh10 = 3 * t2 - 4 * t + 1;\n const dh01 = -6 * t2 + 6 * t;\n const dh11 = 3 * t2 - 2 * t;\n\n const velocityX = (dh00 * from.x + dh10 * from.velocityX * dt + dh01 * to.x + dh11 * to.velocityX * dt) / dt;\n const velocityY = (dh00 * from.y + dh10 * from.velocityY * dt + dh01 * to.y + dh11 * to.velocityY * dt) / dt;\n\n return {\n x,\n y,\n rotation: lerpAngle(from.rotation, to.rotation, t),\n velocityX,\n velocityY,\n angularVelocity: lerp(from.angularVelocity, to.angularVelocity, t)\n };\n }\n}\n\n// =============================================================================\n// 工厂函数 | Factory Functions\n// =============================================================================\n\n/**\n * @zh 创建变换插值器\n * @en Create transform interpolator\n */\nexport function createTransformInterpolator(): TransformInterpolator {\n return new TransformInterpolator();\n}\n\n/**\n * @zh 创建赫尔米特变换插值器\n * @en Create Hermite transform interpolator\n */\nexport function createHermiteTransformInterpolator(): HermiteTransformInterpolator {\n return new HermiteTransformInterpolator();\n}\n","/**\n * @zh 客户端预测\n * @en Client Prediction\n *\n * @zh 提供客户端输入预测和服务器校正\n * @en Provides client-side input prediction and server reconciliation\n */\n\n// =============================================================================\n// 输入快照接口 | Input Snapshot Interface\n// =============================================================================\n\n/**\n * @zh 输入快照\n * @en Input snapshot\n */\nexport interface IInputSnapshot<TInput> {\n /**\n * @zh 输入序列号\n * @en Input sequence number\n */\n readonly sequence: number;\n\n /**\n * @zh 输入数据\n * @en Input data\n */\n readonly input: TInput;\n\n /**\n * @zh 输入时间戳\n * @en Input timestamp\n */\n readonly timestamp: number;\n}\n\n/**\n * @zh 预测状态\n * @en Predicted state\n */\nexport interface IPredictedState<TState> {\n /**\n * @zh 状态数据\n * @en State data\n */\n readonly state: TState;\n\n /**\n * @zh 对应的输入序列号\n * @en Corresponding input sequence number\n */\n readonly sequence: number;\n}\n\n// =============================================================================\n// 预测器接口 | Predictor Interface\n// =============================================================================\n\n/**\n * @zh 状态预测器接口\n * @en State predictor interface\n */\nexport interface IPredictor<TState, TInput> {\n /**\n * @zh 根据当前状态和输入预测下一状态\n * @en Predict next state based on current state and input\n *\n * @param state - @zh 当前状态 @en Current state\n * @param input - @zh 输入 @en Input\n * @param deltaTime - @zh 时间间隔 @en Delta time\n * @returns @zh 预测的状态 @en Predicted state\n */\n predict(state: TState, input: TInput, deltaTime: number): TState;\n}\n\n// =============================================================================\n// 客户端预测管理器 | Client Prediction Manager\n// =============================================================================\n\n/**\n * @zh 客户端预测配置\n * @en Client prediction configuration\n */\nexport interface ClientPredictionConfig {\n /**\n * @zh 最大未确认输入数量\n * @en Maximum unacknowledged inputs\n */\n maxUnacknowledgedInputs: number;\n\n /**\n * @zh 校正阈值(超过此值才进行平滑校正)\n * @en Reconciliation threshold (smooth correction only above this value)\n */\n reconciliationThreshold: number;\n\n /**\n * @zh 校正平滑速度\n * @en Reconciliation smoothing speed\n */\n reconciliationSpeed: number;\n}\n\n/**\n * @zh 客户端预测管理器\n * @en Client prediction manager\n */\nexport class ClientPrediction<TState, TInput> {\n private readonly _predictor: IPredictor<TState, TInput>;\n private readonly _config: ClientPredictionConfig;\n private readonly _pendingInputs: IInputSnapshot<TInput>[] = [];\n private _lastAcknowledgedSequence: number = 0;\n private _currentSequence: number = 0;\n private _lastServerState: TState | null = null;\n private _predictedState: TState | null = null;\n private _correctionOffset: { x: number; y: number } = { x: 0, y: 0 };\n\n constructor(predictor: IPredictor<TState, TInput>, config?: Partial<ClientPredictionConfig>) {\n this._predictor = predictor;\n this._config = {\n maxUnacknowledgedInputs: 60,\n reconciliationThreshold: 0.1,\n reconciliationSpeed: 10,\n ...config\n };\n }\n\n /**\n * @zh 获取当前预测状态\n * @en Get current predicted state\n */\n get predictedState(): TState | null {\n return this._predictedState;\n }\n\n /**\n * @zh 获取校正偏移\n * @en Get correction offset\n */\n get correctionOffset(): { x: number; y: number } {\n return this._correctionOffset;\n }\n\n /**\n * @zh 获取待确认输入数量\n * @en Get pending input count\n */\n get pendingInputCount(): number {\n return this._pendingInputs.length;\n }\n\n /**\n * @zh 记录并预测输入\n * @en Record and predict input\n *\n * @param input - @zh 输入数据 @en Input data\n * @param currentState - @zh 当前状态 @en Current state\n * @param deltaTime - @zh 时间间隔 @en Delta time\n * @returns @zh 预测的状态 @en Predicted state\n */\n recordInput(input: TInput, currentState: TState, deltaTime: number): TState {\n this._currentSequence++;\n\n const inputSnapshot: IInputSnapshot<TInput> = {\n sequence: this._currentSequence,\n input,\n timestamp: Date.now()\n };\n\n this._pendingInputs.push(inputSnapshot);\n\n // Remove old inputs if buffer is full\n while (this._pendingInputs.length > this._config.maxUnacknowledgedInputs) {\n this._pendingInputs.shift();\n }\n\n // Predict new state\n this._predictedState = this._predictor.predict(currentState, input, deltaTime);\n\n return this._predictedState;\n }\n\n /**\n * @zh 获取下一个要发送的输入\n * @en Get next input to send\n */\n getInputToSend(): IInputSnapshot<TInput> | null {\n return this._pendingInputs.length > 0 ? this._pendingInputs[this._pendingInputs.length - 1] : null;\n }\n\n /**\n * @zh 获取当前序列号\n * @en Get current sequence number\n */\n get currentSequence(): number {\n return this._currentSequence;\n }\n\n /**\n * @zh 处理服务器状态并进行校正\n * @en Process server state and reconcile\n *\n * @param serverState - @zh 服务器状态 @en Server state\n * @param acknowledgedSequence - @zh 已确认的输入序列号 @en Acknowledged input sequence\n * @param stateGetter - @zh 获取状态位置的函数 @en Function to get state position\n * @param deltaTime - @zh 帧时间 @en Frame delta time\n */\n reconcile(\n serverState: TState,\n acknowledgedSequence: number,\n stateGetter: (state: TState) => { x: number; y: number },\n deltaTime: number\n ): TState {\n this._lastServerState = serverState;\n this._lastAcknowledgedSequence = acknowledgedSequence;\n\n // Remove acknowledged inputs\n while (this._pendingInputs.length > 0 && this._pendingInputs[0].sequence <= acknowledgedSequence) {\n this._pendingInputs.shift();\n }\n\n // Re-predict from server state using unacknowledged inputs\n let state = serverState;\n for (const inputSnapshot of this._pendingInputs) {\n state = this._predictor.predict(state, inputSnapshot.input, deltaTime);\n }\n\n // Calculate error\n const serverPos = stateGetter(serverState);\n const predictedPos = stateGetter(state);\n const errorX = serverPos.x - predictedPos.x;\n const errorY = serverPos.y - predictedPos.y;\n const errorMagnitude = Math.sqrt(errorX * errorX + errorY * errorY);\n\n // Apply correction\n if (errorMagnitude > this._config.reconciliationThreshold) {\n // Smooth correction over time\n const t = Math.min(1, this._config.reconciliationSpeed * deltaTime);\n this._correctionOffset.x += errorX * t;\n this._correctionOffset.y += errorY * t;\n }\n\n // Decay correction offset\n const decayRate = 0.9;\n this._correctionOffset.x *= decayRate;\n this._correctionOffset.y *= decayRate;\n\n this._predictedState = state;\n return state;\n }\n\n /**\n * @zh 清空预测状态\n * @en Clear prediction state\n */\n clear(): void {\n this._pendingInputs.length = 0;\n this._lastAcknowledgedSequence = 0;\n this._currentSequence = 0;\n this._lastServerState = null;\n this._predictedState = null;\n this._correctionOffset = { x: 0, y: 0 };\n }\n}\n\n// =============================================================================\n// 工厂函数 | Factory Functions\n// =============================================================================\n\n/**\n * @zh 创建客户端预测管理器\n * @en Create client prediction manager\n */\nexport function createClientPrediction<TState, TInput>(\n predictor: IPredictor<TState, TInput>,\n config?: Partial<ClientPredictionConfig>\n): ClientPrediction<TState, TInput> {\n return new ClientPrediction(predictor, config);\n}\n","/**\n * @zh 网络蓝图节点\n * @en Network Blueprint Nodes\n *\n * @zh 提供网络功能的蓝图节点\n * @en Provides blueprint nodes for network functionality\n */\n\nimport type { BlueprintNodeTemplate, BlueprintNode, INodeExecutor, ExecutionResult } from '@esengine/blueprint';\n\n// =============================================================================\n// 执行上下文接口 | Execution Context Interface\n// =============================================================================\n\n/**\n * @zh 网络上下文\n * @en Network context\n */\ninterface NetworkContext {\n entity: {\n getComponent<T>(type: new (...args: unknown[]) => T): T | null;\n };\n isServer: boolean;\n localPlayerId: number;\n evaluateInput(nodeId: string, pinName: string, defaultValue?: unknown): unknown;\n setOutputs(nodeId: string, outputs: Record<string, unknown>): void;\n}\n\n// =============================================================================\n// IsLocalPlayer 节点 | IsLocalPlayer Node\n// =============================================================================\n\n/**\n * @zh IsLocalPlayer 节点模板\n * @en IsLocalPlayer node template\n */\nexport const IsLocalPlayerTemplate: BlueprintNodeTemplate = {\n type: 'IsLocalPlayer',\n title: 'Is Local Player',\n category: 'entity',\n description: 'Check if this entity is the local player / 检查此实体是否是本地玩家',\n keywords: ['network', 'local', 'player', 'authority', 'owner'],\n menuPath: ['Network', 'Is Local Player'],\n isPure: true,\n inputs: [],\n outputs: [\n {\n name: 'isLocal',\n displayName: 'Is Local',\n type: 'bool'\n }\n ],\n color: '#ff9800'\n};\n\n/**\n * @zh IsLocalPlayer 节点执行器\n * @en IsLocalPlayer node executor\n */\nexport class IsLocalPlayerExecutor implements INodeExecutor {\n execute(node: BlueprintNode, context: unknown): ExecutionResult {\n const ctx = context as NetworkContext;\n\n // Try to get NetworkIdentity component\n let isLocal = false;\n if (ctx.entity) {\n const identity = ctx.entity.getComponent(class NetworkIdentity {\n bIsLocalPlayer: boolean = false;\n });\n if (identity) {\n isLocal = identity.bIsLocalPlayer;\n }\n }\n\n return {\n outputs: {\n isLocal\n }\n };\n }\n}\n\n// =============================================================================\n// IsServer 节点 | IsServer Node\n// =============================================================================\n\n/**\n * @zh IsServer 节点模板\n * @en IsServer node template\n */\nexport const IsServerTemplate: BlueprintNodeTemplate = {\n type: 'IsServer',\n title: 'Is Server',\n category: 'entity',\n description: 'Check if running on server / 检查是否在服务器上运行',\n keywords: ['network', 'server', 'authority', 'host'],\n menuPath: ['Network', 'Is Server'],\n isPure: true,\n inputs: [],\n outputs: [\n {\n name: 'isServer',\n displayName: 'Is Server',\n type: 'bool'\n }\n ],\n color: '#ff9800'\n};\n\n/**\n * @zh IsServer 节点执行器\n * @en IsServer node executor\n */\nexport class IsServerExecutor implements INodeExecutor {\n execute(_node: BlueprintNode, context: unknown): ExecutionResult {\n const ctx = context as NetworkContext;\n\n return {\n outputs: {\n isServer: ctx.isServer ?? false\n }\n };\n }\n}\n\n// =============================================================================\n// HasAuthority 节点 | HasAuthority Node\n// =============================================================================\n\n/**\n * @zh HasAuthority 节点模板\n * @en HasAuthority node template\n */\nexport const HasAuthorityTemplate: BlueprintNodeTemplate = {\n type: 'HasAuthority',\n title: 'Has Authority',\n category: 'entity',\n description: 'Check if this entity has authority / 检查此实体是否有权限控制',\n keywords: ['network', 'authority', 'control', 'owner'],\n menuPath: ['Network', 'Has Authority'],\n isPure: true,\n inputs: [],\n outputs: [\n {\n name: 'hasAuthority',\n displayName: 'Has Authority',\n type: 'bool'\n }\n ],\n color: '#ff9800'\n};\n\n/**\n * @zh HasAuthority 节点执行器\n * @en HasAuthority node executor\n */\nexport class HasAuthorityExecutor implements INodeExecutor {\n execute(node: BlueprintNode, context: unknown): ExecutionResult {\n const ctx = context as NetworkContext;\n\n let hasAuthority = false;\n if (ctx.entity) {\n const identity = ctx.entity.getComponent(class NetworkIdentity {\n bHasAuthority: boolean = false;\n });\n if (identity) {\n hasAuthority = identity.bHasAuthority;\n }\n }\n\n return {\n outputs: {\n hasAuthority\n }\n };\n }\n}\n\n// =============================================================================\n// GetNetworkId 节点 | GetNetworkId Node\n// =============================================================================\n\n/**\n * @zh GetNetworkId 节点模板\n * @en GetNetworkId node template\n */\nexport const GetNetworkIdTemplate: BlueprintNodeTemplate = {\n type: 'GetNetworkId',\n title: 'Get Network ID',\n category: 'entity',\n description: 'Get the network ID of this entity / 获取此实体的网络 ID',\n keywords: ['network', 'id', 'netid', 'identity'],\n menuPath: ['Network', 'Get Network ID'],\n isPure: true,\n inputs: [],\n outputs: [\n {\n name: 'netId',\n displayName: 'Net ID',\n type: 'int'\n },\n {\n name: 'ownerId',\n displayName: 'Owner ID',\n type: 'int'\n }\n ],\n color: '#ff9800'\n};\n\n/**\n * @zh GetNetworkId 节点执行器\n * @en GetNetworkId node executor\n */\nexport class GetNetworkIdExecutor implements INodeExecutor {\n execute(node: BlueprintNode, context: unknown): ExecutionResult {\n const ctx = context as NetworkContext;\n\n let netId = 0;\n let ownerId = 0;\n\n if (ctx.entity) {\n const identity = ctx.entity.getComponent(class NetworkIdentity {\n netId: number = 0;\n ownerId: number = 0;\n });\n if (identity) {\n netId = identity.netId;\n ownerId = identity.ownerId;\n }\n }\n\n return {\n outputs: {\n netId,\n ownerId\n }\n };\n }\n}\n\n// =============================================================================\n// GetLocalPlayerId 节点 | GetLocalPlayerId Node\n// =============================================================================\n\n/**\n * @zh GetLocalPlayerId 节点模板\n * @en GetLocalPlayerId node template\n */\nexport const GetLocalPlayerIdTemplate: BlueprintNodeTemplate = {\n type: 'GetLocalPlayerId',\n title: 'Get Local Player ID',\n category: 'entity',\n description: 'Get the local player ID / 获取本地玩家 ID',\n keywords: ['network', 'local', 'player', 'id'],\n menuPath: ['Network', 'Get Local Player ID'],\n isPure: true,\n inputs: [],\n outputs: [\n {\n name: 'playerId',\n displayName: 'Player ID',\n type: 'int'\n }\n ],\n color: '#ff9800'\n};\n\n/**\n * @zh GetLocalPlayerId 节点执行器\n * @en GetLocalPlayerId node executor\n */\nexport class GetLocalPlayerIdExecutor implements INodeExecutor {\n execute(_node: BlueprintNode, context: unknown): ExecutionResult {\n const ctx = context as NetworkContext;\n\n return {\n outputs: {\n playerId: ctx.localPlayerId ?? 0\n }\n };\n }\n}\n\n// =============================================================================\n// 节点定义集合 | Node Definition Collection\n// =============================================================================\n\n/**\n * @zh 网络节点定义集合\n * @en Network node definition collection\n */\nexport const NetworkNodeDefinitions = {\n templates: [\n IsLocalPlayerTemplate,\n IsServerTemplate,\n HasAuthorityTemplate,\n GetNetworkIdTemplate,\n GetLocalPlayerIdTemplate\n ],\n executors: new Map<string, INodeExecutor>([\n ['IsLocalPlayer', new IsLocalPlayerExecutor()],\n ['IsServer', new IsServerExecutor()],\n ['HasAuthority', new HasAuthorityExecutor()],\n ['GetNetworkId', new GetNetworkIdExecutor()],\n ['GetLocalPlayerId', new GetLocalPlayerIdExecutor()]\n ])\n};\n"],"mappings":"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","names":["serviceProto","createServiceToken","NetworkServiceToken","NetworkSyncSystemToken","NetworkSpawnSystemToken","NetworkInputSystemToken","Core","WsClient","serviceProto","ENetworkState","createClient","serverUrl","WsClient","serviceProto","server","json","logLevel","NetworkService","_client","_state","_clientId","_roomId","_callbacks","state","clientId","roomId","isConnected","setCallbacks","callbacks","connect","playerName","_setupListeners","connectResult","isSucc","onError","Error","errMsg","joinResult","callApi","disconnect","err","message","res","onConnected","sendInput","input","sendMsg","listenMsg","msg","onSync","onSpawn","onDespawn","flows","postDisconnectFlow","push","v","onDisconnected","EntitySystem","Matcher","Time","Component","ECSComponent","Serialize","Serializable","Property","NetworkIdentity","Component","netId","ownerId","bIsLocalPlayer","bHasAuthority","prefabType","syncInterval","lastSyncTime","needsSync","now","type","label","readOnly","min","version","typeId","Component","ECSComponent","Serialize","Serializable","Property","NetworkTransform","Component","targetX","targetY","targetRotation","currentX","currentY","currentRotation","lerpSpeed","bInterpolate","syncInterval","lastSyncTime","setTarget","x","y","rotation","undefined","snap","type","label","min","max","requires","version","typeId","NetworkSyncSystem","EntitySystem","networkService","Matcher","all","NetworkIdentity","NetworkTransform","_networkService","_netIdToEntity","Map","onInitialize","setCallbacks","onSync","_handleSync","bind","process","entities","deltaTime","Time","entity","transform","requireComponent","identity","bHasAuthority","bInterpolate","_interpolate","registerEntity","netId","entityId","set","unregisterEntity","delete","getEntityId","get","msg","state","undefined","scene","findEntityById","getComponent","pos","setTarget","x","y","rot","t","Math","min","lerpSpeed","currentX","targetX","currentY","targetY","angleDiff","targetRotation","currentRotation","PI","onDestroy","clear","EntitySystem","Matcher","NetworkSpawnSystem","EntitySystem","networkService","syncSystem","Matcher","nothing","_networkService","_syncSystem","_prefabFactories","Map","onInitialize","setCallbacks","onSpawn","_handleSpawn","bind","onDespawn","_handleDespawn","registerPrefab","prefabType","factory","set","unregisterPrefab","delete","msg","scene","get","prefab","logger","warn","entity","identity","addComponent","NetworkIdentity","netId","ownerId","bHasAuthority","clientId","bIsLocalPlayer","transform","NetworkTransform","setTarget","pos","x","y","rot","snap","registerEntity","id","entityId","getEntityId","undefined","findEntityById","destroy","unregisterEntity","onDestroy","clear","EntitySystem","Matcher","NetworkInputSystem","EntitySystem","networkService","Matcher","nothing","_networkService","_frame","_inputQueue","process","isConnected","length","input","shift","frame","sendInput","addMoveInput","x","y","push","moveDir","addActionInput","action","lastInput","actions","onDestroy","NetworkPlugin","name","version","_networkService","_syncSystem","_spawnSystem","_inputSystem","networkService","syncSystem","spawnSystem","inputSystem","isConnected","install","_core","_services","NetworkService","scene","Core","_setupSystems","uninstall","disconnect","NetworkSyncSystem","NetworkSpawnSystem","NetworkInputSystem","addSystem","connect","serverUrl","playerName","roomId","registerPrefab","prefabType","factory","sendMoveInput","x","y","addMoveInput","sendActionInput","action","addActionInput","SnapshotBuffer","config","_buffer","_maxSize","_interpolationDelay","maxSize","interpolationDelay","size","length","push","snapshot","insertIndex","i","timestamp","splice","shift","getInterpolationSnapshots","renderTime","targetTime","prev","next","duration","t","Math","max","min","getLatest","getSnapshotsAfter","filter","s","clear","createSnapshotBuffer","lerp","a","b","t","lerpAngle","diff","Math","PI","smoothDamp","current","target","velocity","smoothTime","deltaTime","maxSpeed","Infinity","max","omega","x","exp","change","maxChange","min","temp","newVelocity","newValue","TransformInterpolator","interpolate","from","to","t","x","lerp","y","rotation","lerpAngle","extrapolate","state","deltaTime","velocityX","velocityY","angularVelocity","HermiteTransformInterpolator","t2","t3","h00","h10","h01","h11","dt","dh00","dh10","dh01","dh11","createTransformInterpolator","createHermiteTransformInterpolator","ClientPrediction","predictor","config","_predictor","_config","_pendingInputs","_lastAcknowledgedSequence","_currentSequence","_lastServerState","_predictedState","_correctionOffset","x","y","maxUnacknowledgedInputs","reconciliationThreshold","reconciliationSpeed","predictedState","correctionOffset","pendingInputCount","length","recordInput","input","currentState","deltaTime","inputSnapshot","sequence","timestamp","Date","now","push","shift","predict","getInputToSend","currentSequence","reconcile","serverState","acknowledgedSequence","stateGetter","state","serverPos","predictedPos","errorX","errorY","errorMagnitude","Math","sqrt","t","min","decayRate","clear","createClientPrediction","IsLocalPlayerTemplate","type","title","category","description","keywords","menuPath","isPure","inputs","outputs","name","displayName","color","IsLocalPlayerExecutor","execute","node","context","ctx","isLocal","entity","identity","getComponent","NetworkIdentity","bIsLocalPlayer","IsServerTemplate","IsServerExecutor","_node","isServer","HasAuthorityTemplate","HasAuthorityExecutor","hasAuthority","bHasAuthority","GetNetworkIdTemplate","GetNetworkIdExecutor","netId","ownerId","GetLocalPlayerIdTemplate","GetLocalPlayerIdExecutor","playerId","localPlayerId","NetworkNodeDefinitions","templates","executors","Map"]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zh 网络蓝图节点
|
|
3
|
+
* @en Network Blueprint Nodes
|
|
4
|
+
*
|
|
5
|
+
* @zh 提供网络功能的蓝图节点
|
|
6
|
+
* @en Provides blueprint nodes for network functionality
|
|
7
|
+
*/
|
|
8
|
+
import type { BlueprintNodeTemplate, BlueprintNode, INodeExecutor, ExecutionResult } from '@esengine/blueprint';
|
|
9
|
+
/**
|
|
10
|
+
* @zh IsLocalPlayer 节点模板
|
|
11
|
+
* @en IsLocalPlayer node template
|
|
12
|
+
*/
|
|
13
|
+
export declare const IsLocalPlayerTemplate: BlueprintNodeTemplate;
|
|
14
|
+
/**
|
|
15
|
+
* @zh IsLocalPlayer 节点执行器
|
|
16
|
+
* @en IsLocalPlayer node executor
|
|
17
|
+
*/
|
|
18
|
+
export declare class IsLocalPlayerExecutor implements INodeExecutor {
|
|
19
|
+
execute(node: BlueprintNode, context: unknown): ExecutionResult;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* @zh IsServer 节点模板
|
|
23
|
+
* @en IsServer node template
|
|
24
|
+
*/
|
|
25
|
+
export declare const IsServerTemplate: BlueprintNodeTemplate;
|
|
26
|
+
/**
|
|
27
|
+
* @zh IsServer 节点执行器
|
|
28
|
+
* @en IsServer node executor
|
|
29
|
+
*/
|
|
30
|
+
export declare class IsServerExecutor implements INodeExecutor {
|
|
31
|
+
execute(_node: BlueprintNode, context: unknown): ExecutionResult;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @zh HasAuthority 节点模板
|
|
35
|
+
* @en HasAuthority node template
|
|
36
|
+
*/
|
|
37
|
+
export declare const HasAuthorityTemplate: BlueprintNodeTemplate;
|
|
38
|
+
/**
|
|
39
|
+
* @zh HasAuthority 节点执行器
|
|
40
|
+
* @en HasAuthority node executor
|
|
41
|
+
*/
|
|
42
|
+
export declare class HasAuthorityExecutor implements INodeExecutor {
|
|
43
|
+
execute(node: BlueprintNode, context: unknown): ExecutionResult;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @zh GetNetworkId 节点模板
|
|
47
|
+
* @en GetNetworkId node template
|
|
48
|
+
*/
|
|
49
|
+
export declare const GetNetworkIdTemplate: BlueprintNodeTemplate;
|
|
50
|
+
/**
|
|
51
|
+
* @zh GetNetworkId 节点执行器
|
|
52
|
+
* @en GetNetworkId node executor
|
|
53
|
+
*/
|
|
54
|
+
export declare class GetNetworkIdExecutor implements INodeExecutor {
|
|
55
|
+
execute(node: BlueprintNode, context: unknown): ExecutionResult;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* @zh GetLocalPlayerId 节点模板
|
|
59
|
+
* @en GetLocalPlayerId node template
|
|
60
|
+
*/
|
|
61
|
+
export declare const GetLocalPlayerIdTemplate: BlueprintNodeTemplate;
|
|
62
|
+
/**
|
|
63
|
+
* @zh GetLocalPlayerId 节点执行器
|
|
64
|
+
* @en GetLocalPlayerId node executor
|
|
65
|
+
*/
|
|
66
|
+
export declare class GetLocalPlayerIdExecutor implements INodeExecutor {
|
|
67
|
+
execute(_node: BlueprintNode, context: unknown): ExecutionResult;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @zh 网络节点定义集合
|
|
71
|
+
* @en Network node definition collection
|
|
72
|
+
*/
|
|
73
|
+
export declare const NetworkNodeDefinitions: {
|
|
74
|
+
templates: BlueprintNodeTemplate[];
|
|
75
|
+
executors: Map<string, INodeExecutor>;
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=NetworkNodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkNodes.d.ts","sourceRoot":"","sources":["../../src/nodes/NetworkNodes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAwBhH;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,qBAiBnC,CAAC;AAEF;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACvD,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;CAoBlE;AAMD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,qBAiB9B,CAAC;AAEF;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IAClD,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;CASnE;AAMD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,qBAiBlC,CAAC;AAEF;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,aAAa;IACtD,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;CAmBlE;AAMD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,qBAsBlC,CAAC;AAEF;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,aAAa;IACtD,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;CAwBlE;AAMD;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,qBAiBtC,CAAC;AAEF;;;GAGG;AACH,qBAAa,wBAAyB,YAAW,aAAa;IAC1D,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,eAAe;CASnE;AAMD;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;CAelC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zh 网络蓝图节点模块
|
|
3
|
+
* @en Network Blueprint Nodes Module
|
|
4
|
+
*
|
|
5
|
+
* @zh 提供网络功能的蓝图节点
|
|
6
|
+
* @en Provides blueprint nodes for network functionality
|
|
7
|
+
*/
|
|
8
|
+
export { IsLocalPlayerTemplate, IsServerTemplate, HasAuthorityTemplate, GetNetworkIdTemplate, GetLocalPlayerIdTemplate, IsLocalPlayerExecutor, IsServerExecutor, HasAuthorityExecutor, GetNetworkIdExecutor, GetLocalPlayerIdExecutor, NetworkNodeDefinitions } from './NetworkNodes';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nodes/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEH,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EAExB,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EAExB,sBAAsB,EACzB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type MsgSync, type MsgSpawn, type MsgDespawn, type IPlayerInput } from '@esengine/network-protocols';
|
|
2
|
+
/**
|
|
3
|
+
* 连接状态
|
|
4
|
+
* Connection state
|
|
5
|
+
*/
|
|
6
|
+
export declare const enum ENetworkState {
|
|
7
|
+
Disconnected = 0,
|
|
8
|
+
Connecting = 1,
|
|
9
|
+
Connected = 2
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 网络事件回调
|
|
13
|
+
* Network event callbacks
|
|
14
|
+
*/
|
|
15
|
+
export interface INetworkCallbacks {
|
|
16
|
+
onConnected?: (clientId: number, roomId: string) => void;
|
|
17
|
+
onDisconnected?: () => void;
|
|
18
|
+
onSync?: (msg: MsgSync) => void;
|
|
19
|
+
onSpawn?: (msg: MsgSpawn) => void;
|
|
20
|
+
onDespawn?: (msg: MsgDespawn) => void;
|
|
21
|
+
onError?: (error: Error) => void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 网络服务
|
|
25
|
+
* Network service
|
|
26
|
+
*
|
|
27
|
+
* 基于 TSRPC 的网络服务封装,提供类型安全的网络通信。
|
|
28
|
+
* TSRPC-based network service wrapper with type-safe communication.
|
|
29
|
+
*/
|
|
30
|
+
export declare class NetworkService {
|
|
31
|
+
private _client;
|
|
32
|
+
private _state;
|
|
33
|
+
private _clientId;
|
|
34
|
+
private _roomId;
|
|
35
|
+
private _callbacks;
|
|
36
|
+
get state(): ENetworkState;
|
|
37
|
+
get clientId(): number;
|
|
38
|
+
get roomId(): string;
|
|
39
|
+
get isConnected(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* 设置回调
|
|
42
|
+
* Set callbacks
|
|
43
|
+
*/
|
|
44
|
+
setCallbacks(callbacks: INetworkCallbacks): void;
|
|
45
|
+
/**
|
|
46
|
+
* 连接到服务器
|
|
47
|
+
* Connect to server
|
|
48
|
+
*/
|
|
49
|
+
connect(serverUrl: string, playerName: string, roomId?: string): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* 断开连接
|
|
52
|
+
* Disconnect
|
|
53
|
+
*/
|
|
54
|
+
disconnect(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* 发送输入
|
|
57
|
+
* Send input
|
|
58
|
+
*/
|
|
59
|
+
sendInput(input: IPlayerInput): void;
|
|
60
|
+
private _setupListeners;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=NetworkService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkService.d.ts","sourceRoot":"","sources":["../../src/services/NetworkService.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACpB,MAAM,6BAA6B,CAAC;AAErC;;;GAGG;AACH,0BAAkB,aAAa;IAC3B,YAAY,IAAI;IAChB,UAAU,IAAI;IACd,SAAS,IAAI;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAC9B,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IAClC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACpC;AAcD;;;;;;GAMG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,MAAM,CAA6C;IAC3D,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,UAAU,CAAyB;IAE3C,IAAI,KAAK,IAAI,aAAa,CAEzB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAIhD;;;OAGG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAwCvF;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAKpC,OAAO,CAAC,eAAe;CAqB1B"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zh 客户端预测
|
|
3
|
+
* @en Client Prediction
|
|
4
|
+
*
|
|
5
|
+
* @zh 提供客户端输入预测和服务器校正
|
|
6
|
+
* @en Provides client-side input prediction and server reconciliation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @zh 输入快照
|
|
10
|
+
* @en Input snapshot
|
|
11
|
+
*/
|
|
12
|
+
export interface IInputSnapshot<TInput> {
|
|
13
|
+
/**
|
|
14
|
+
* @zh 输入序列号
|
|
15
|
+
* @en Input sequence number
|
|
16
|
+
*/
|
|
17
|
+
readonly sequence: number;
|
|
18
|
+
/**
|
|
19
|
+
* @zh 输入数据
|
|
20
|
+
* @en Input data
|
|
21
|
+
*/
|
|
22
|
+
readonly input: TInput;
|
|
23
|
+
/**
|
|
24
|
+
* @zh 输入时间戳
|
|
25
|
+
* @en Input timestamp
|
|
26
|
+
*/
|
|
27
|
+
readonly timestamp: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @zh 预测状态
|
|
31
|
+
* @en Predicted state
|
|
32
|
+
*/
|
|
33
|
+
export interface IPredictedState<TState> {
|
|
34
|
+
/**
|
|
35
|
+
* @zh 状态数据
|
|
36
|
+
* @en State data
|
|
37
|
+
*/
|
|
38
|
+
readonly state: TState;
|
|
39
|
+
/**
|
|
40
|
+
* @zh 对应的输入序列号
|
|
41
|
+
* @en Corresponding input sequence number
|
|
42
|
+
*/
|
|
43
|
+
readonly sequence: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* @zh 状态预测器接口
|
|
47
|
+
* @en State predictor interface
|
|
48
|
+
*/
|
|
49
|
+
export interface IPredictor<TState, TInput> {
|
|
50
|
+
/**
|
|
51
|
+
* @zh 根据当前状态和输入预测下一状态
|
|
52
|
+
* @en Predict next state based on current state and input
|
|
53
|
+
*
|
|
54
|
+
* @param state - @zh 当前状态 @en Current state
|
|
55
|
+
* @param input - @zh 输入 @en Input
|
|
56
|
+
* @param deltaTime - @zh 时间间隔 @en Delta time
|
|
57
|
+
* @returns @zh 预测的状态 @en Predicted state
|
|
58
|
+
*/
|
|
59
|
+
predict(state: TState, input: TInput, deltaTime: number): TState;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* @zh 客户端预测配置
|
|
63
|
+
* @en Client prediction configuration
|
|
64
|
+
*/
|
|
65
|
+
export interface ClientPredictionConfig {
|
|
66
|
+
/**
|
|
67
|
+
* @zh 最大未确认输入数量
|
|
68
|
+
* @en Maximum unacknowledged inputs
|
|
69
|
+
*/
|
|
70
|
+
maxUnacknowledgedInputs: number;
|
|
71
|
+
/**
|
|
72
|
+
* @zh 校正阈值(超过此值才进行平滑校正)
|
|
73
|
+
* @en Reconciliation threshold (smooth correction only above this value)
|
|
74
|
+
*/
|
|
75
|
+
reconciliationThreshold: number;
|
|
76
|
+
/**
|
|
77
|
+
* @zh 校正平滑速度
|
|
78
|
+
* @en Reconciliation smoothing speed
|
|
79
|
+
*/
|
|
80
|
+
reconciliationSpeed: number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @zh 客户端预测管理器
|
|
84
|
+
* @en Client prediction manager
|
|
85
|
+
*/
|
|
86
|
+
export declare class ClientPrediction<TState, TInput> {
|
|
87
|
+
private readonly _predictor;
|
|
88
|
+
private readonly _config;
|
|
89
|
+
private readonly _pendingInputs;
|
|
90
|
+
private _lastAcknowledgedSequence;
|
|
91
|
+
private _currentSequence;
|
|
92
|
+
private _lastServerState;
|
|
93
|
+
private _predictedState;
|
|
94
|
+
private _correctionOffset;
|
|
95
|
+
constructor(predictor: IPredictor<TState, TInput>, config?: Partial<ClientPredictionConfig>);
|
|
96
|
+
/**
|
|
97
|
+
* @zh 获取当前预测状态
|
|
98
|
+
* @en Get current predicted state
|
|
99
|
+
*/
|
|
100
|
+
get predictedState(): TState | null;
|
|
101
|
+
/**
|
|
102
|
+
* @zh 获取校正偏移
|
|
103
|
+
* @en Get correction offset
|
|
104
|
+
*/
|
|
105
|
+
get correctionOffset(): {
|
|
106
|
+
x: number;
|
|
107
|
+
y: number;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* @zh 获取待确认输入数量
|
|
111
|
+
* @en Get pending input count
|
|
112
|
+
*/
|
|
113
|
+
get pendingInputCount(): number;
|
|
114
|
+
/**
|
|
115
|
+
* @zh 记录并预测输入
|
|
116
|
+
* @en Record and predict input
|
|
117
|
+
*
|
|
118
|
+
* @param input - @zh 输入数据 @en Input data
|
|
119
|
+
* @param currentState - @zh 当前状态 @en Current state
|
|
120
|
+
* @param deltaTime - @zh 时间间隔 @en Delta time
|
|
121
|
+
* @returns @zh 预测的状态 @en Predicted state
|
|
122
|
+
*/
|
|
123
|
+
recordInput(input: TInput, currentState: TState, deltaTime: number): TState;
|
|
124
|
+
/**
|
|
125
|
+
* @zh 获取下一个要发送的输入
|
|
126
|
+
* @en Get next input to send
|
|
127
|
+
*/
|
|
128
|
+
getInputToSend(): IInputSnapshot<TInput> | null;
|
|
129
|
+
/**
|
|
130
|
+
* @zh 获取当前序列号
|
|
131
|
+
* @en Get current sequence number
|
|
132
|
+
*/
|
|
133
|
+
get currentSequence(): number;
|
|
134
|
+
/**
|
|
135
|
+
* @zh 处理服务器状态并进行校正
|
|
136
|
+
* @en Process server state and reconcile
|
|
137
|
+
*
|
|
138
|
+
* @param serverState - @zh 服务器状态 @en Server state
|
|
139
|
+
* @param acknowledgedSequence - @zh 已确认的输入序列号 @en Acknowledged input sequence
|
|
140
|
+
* @param stateGetter - @zh 获取状态位置的函数 @en Function to get state position
|
|
141
|
+
* @param deltaTime - @zh 帧时间 @en Frame delta time
|
|
142
|
+
*/
|
|
143
|
+
reconcile(serverState: TState, acknowledgedSequence: number, stateGetter: (state: TState) => {
|
|
144
|
+
x: number;
|
|
145
|
+
y: number;
|
|
146
|
+
}, deltaTime: number): TState;
|
|
147
|
+
/**
|
|
148
|
+
* @zh 清空预测状态
|
|
149
|
+
* @en Clear prediction state
|
|
150
|
+
*/
|
|
151
|
+
clear(): void;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* @zh 创建客户端预测管理器
|
|
155
|
+
* @en Create client prediction manager
|
|
156
|
+
*/
|
|
157
|
+
export declare function createClientPrediction<TState, TInput>(predictor: IPredictor<TState, TInput>, config?: Partial<ClientPredictionConfig>): ClientPrediction<TState, TInput>;
|
|
158
|
+
//# sourceMappingURL=ClientPrediction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientPrediction.d.ts","sourceRoot":"","sources":["../../src/sync/ClientPrediction.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,MAAM;IAClC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,MAAM;IACnC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAMD;;;GAGG;AACH,MAAM,WAAW,UAAU,CAAC,MAAM,EAAE,MAAM;IACtC;;;;;;;;OAQG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CACpE;AAMD;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACnC;;;OAGG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;CAC/B;AAED;;;GAGG;AACH,qBAAa,gBAAgB,CAAC,MAAM,EAAE,MAAM;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAC/D,OAAO,CAAC,yBAAyB,CAAa;IAC9C,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,iBAAiB,CAA4C;gBAEzD,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC;IAU3F;;;OAGG;IACH,IAAI,cAAc,IAAI,MAAM,GAAG,IAAI,CAElC;IAED;;;OAGG;IACH,IAAI,gBAAgB,IAAI;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAE/C;IAED;;;OAGG;IACH,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED;;;;;;;;OAQG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAsB3E;;;OAGG;IACH,cAAc,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,IAAI;IAI/C;;;OAGG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;;;;;;;OAQG;IACH,SAAS,CACL,WAAW,EAAE,MAAM,EACnB,oBAAoB,EAAE,MAAM,EAC5B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,EACxD,SAAS,EAAE,MAAM,GAClB,MAAM;IAuCT;;;OAGG;IACH,KAAK,IAAI,IAAI;CAQhB;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EACjD,SAAS,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,GACzC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAElC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zh 插值器接口
|
|
3
|
+
* @en Interpolator Interface
|
|
4
|
+
*
|
|
5
|
+
* @zh 提供状态插值的抽象
|
|
6
|
+
* @en Provides abstraction for state interpolation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* @zh 插值器接口
|
|
10
|
+
* @en Interpolator interface
|
|
11
|
+
*/
|
|
12
|
+
export interface IInterpolator<T> {
|
|
13
|
+
/**
|
|
14
|
+
* @zh 在两个状态之间插值
|
|
15
|
+
* @en Interpolate between two states
|
|
16
|
+
*
|
|
17
|
+
* @param from - @zh 起始状态 @en Start state
|
|
18
|
+
* @param to - @zh 目标状态 @en Target state
|
|
19
|
+
* @param t - @zh 插值因子 (0-1) @en Interpolation factor (0-1)
|
|
20
|
+
* @returns @zh 插值后的状态 @en Interpolated state
|
|
21
|
+
*/
|
|
22
|
+
interpolate(from: T, to: T, t: number): T;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* @zh 外推器接口
|
|
26
|
+
* @en Extrapolator interface
|
|
27
|
+
*/
|
|
28
|
+
export interface IExtrapolator<T> {
|
|
29
|
+
/**
|
|
30
|
+
* @zh 基于当前状态外推
|
|
31
|
+
* @en Extrapolate based on current state
|
|
32
|
+
*
|
|
33
|
+
* @param state - @zh 当前状态 @en Current state
|
|
34
|
+
* @param deltaTime - @zh 外推时间(秒)@en Extrapolation time in seconds
|
|
35
|
+
* @returns @zh 外推后的状态 @en Extrapolated state
|
|
36
|
+
*/
|
|
37
|
+
extrapolate(state: T, deltaTime: number): T;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* @zh 线性插值函数
|
|
41
|
+
* @en Linear interpolation function
|
|
42
|
+
*/
|
|
43
|
+
export declare function lerp(a: number, b: number, t: number): number;
|
|
44
|
+
/**
|
|
45
|
+
* @zh 角度插值函数(处理环绕)
|
|
46
|
+
* @en Angle interpolation function (handles wrap-around)
|
|
47
|
+
*/
|
|
48
|
+
export declare function lerpAngle(a: number, b: number, t: number): number;
|
|
49
|
+
/**
|
|
50
|
+
* @zh 平滑阻尼插值
|
|
51
|
+
* @en Smooth damp interpolation
|
|
52
|
+
*
|
|
53
|
+
* @param current - @zh 当前值 @en Current value
|
|
54
|
+
* @param target - @zh 目标值 @en Target value
|
|
55
|
+
* @param velocity - @zh 当前速度(将被修改)@en Current velocity (will be modified)
|
|
56
|
+
* @param smoothTime - @zh 平滑时间 @en Smooth time
|
|
57
|
+
* @param deltaTime - @zh 帧时间 @en Delta time
|
|
58
|
+
* @param maxSpeed - @zh 最大速度 @en Maximum speed
|
|
59
|
+
* @returns @zh [新值, 新速度] @en [new value, new velocity]
|
|
60
|
+
*/
|
|
61
|
+
export declare function smoothDamp(current: number, target: number, velocity: number, smoothTime: number, deltaTime: number, maxSpeed?: number): [number, number];
|
|
62
|
+
//# sourceMappingURL=IInterpolator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IInterpolator.d.ts","sourceRoot":"","sources":["../../src/sync/IInterpolator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;;GAGG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B;;;;;;;;OAQG;IACH,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B;;;;;;;OAOG;IACH,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC;CAC/C;AAMD;;;GAGG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CACtB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,MAAiB,GAC5B,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBlB"}
|