From add173e50982dd15cb33aa3ac00dedfb0af068b5 Mon Sep 17 00:00:00 2001 From: NotArandomGUY <01game01play@gmail.com> Date: Thu, 21 Mar 2024 04:12:26 +0800 Subject: [PATCH] Entity force sync --- src/kcpServer/client.ts | 6 ++- src/kcpServer/packets/EntityForceSync.ts | 54 ++++++++++++++++++++++++ src/kcpServer/packets/SceneEntityMove.ts | 1 - src/kcpServer/utils/protoCleanup.ts | 21 +++++---- 4 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 src/kcpServer/packets/EntityForceSync.ts diff --git a/src/kcpServer/client.ts b/src/kcpServer/client.ts index 336e26de..184cb7f7 100644 --- a/src/kcpServer/client.ts +++ b/src/kcpServer/client.ts @@ -130,6 +130,10 @@ export default class Client extends BaseClass { // Send packet async sendPacket(packetName: string, packetHead: PacketHead, obj: object) { - await this.server.socket.sendPacket(this.conv, packetName, packetHead, noCleanupPackets.includes(packetName) ? obj : protoCleanup(obj)) + try { + await this.server.socket.sendPacket(this.conv, packetName, packetHead, noCleanupPackets.includes(packetName) ? obj : protoCleanup(obj)) + } catch (err) { + logger.error('generic.param1', err) + } } } \ No newline at end of file diff --git a/src/kcpServer/packets/EntityForceSync.ts b/src/kcpServer/packets/EntityForceSync.ts new file mode 100644 index 00000000..d938df48 --- /dev/null +++ b/src/kcpServer/packets/EntityForceSync.ts @@ -0,0 +1,54 @@ +import Packet, { PacketContext, PacketInterface } from '#/packet' +import { ClientStateEnum } from '@/types/enum' +import { MotionInfo } from '@/types/proto' +import { RetcodeEnum } from '@/types/proto/enum' + +export interface EntityForceSyncReq { + roomId: number + entityId: number + motionInfo: MotionInfo + sceneTime: number +} + +export interface EntityForceSyncRsp { + retcode: RetcodeEnum + entityId?: number + failMotion?: MotionInfo + sceneTime?: number +} + +class EntityForceSyncPacket extends Packet implements PacketInterface { + constructor() { + super('EntityForceSync', { + reqState: ClientStateEnum.IN_GAME, + reqStatePass: true + }) + } + + async request(context: PacketContext, data: EntityForceSyncReq): Promise { + const { currentScene } = context.player + const { entityManager } = currentScene + const { entityId, motionInfo, sceneTime } = data + const entity = entityManager.getEntity(entityId, true) + + if (!entity) { + await this.response(context, { retcode: RetcodeEnum.RET_ENTITY_NOT_EXIST }) + return + } + + entity.motion.update(motionInfo, sceneTime) + + await this.response(context, { + retcode: RetcodeEnum.RET_SUCC, + entityId, + sceneTime + }) + } + + async response(context: PacketContext, data: EntityForceSyncRsp): Promise { + await super.response(context, data) + } +} + +let packet: EntityForceSyncPacket +export default (() => packet = packet || new EntityForceSyncPacket())() \ No newline at end of file diff --git a/src/kcpServer/packets/SceneEntityMove.ts b/src/kcpServer/packets/SceneEntityMove.ts index 851bc4a0..83823b13 100644 --- a/src/kcpServer/packets/SceneEntityMove.ts +++ b/src/kcpServer/packets/SceneEntityMove.ts @@ -50,7 +50,6 @@ class SceneEntityMovePacket extends Packet implements PacketInterface { await this.response(context, { retcode: RetcodeEnum.RET_SUCC, entityId, - failMotion: motionInfo, sceneTime, reliableSeq }) diff --git a/src/kcpServer/utils/protoCleanup.ts b/src/kcpServer/utils/protoCleanup.ts index 95248659..591b30aa 100644 --- a/src/kcpServer/utils/protoCleanup.ts +++ b/src/kcpServer/utils/protoCleanup.ts @@ -1,3 +1,7 @@ +import Logger from '@/logger' + +const logger = new Logger('PROTOU', 0xc2f542) + function keepValue(val: any): boolean { if (val == null) return false @@ -17,22 +21,23 @@ function keepValue(val: any): boolean { } } -export default function protoCleanup(obj: any) { - obj = { ...obj } // clone +export default function protoCleanup(obj: any, layer: number = 0) { + if (layer > 32) { + logger.warn('deep nesting detected:', obj) + throw new Error('Abort') + } + + // Clone object + obj = { ...obj } for (const k in obj) { const v = obj[k] - if (!keepValue(v)) { delete obj[k] continue } - if ( - v != null && - typeof v === 'object' && - !Array.isArray(v) - ) obj[k] = protoCleanup(v) + if (v != null && typeof v === 'object' && !Array.isArray(v)) obj[k] = protoCleanup(v, layer + 1) } return obj