diff --git a/packages/room/src/RoomObjectEventHandler.ts b/packages/room/src/RoomObjectEventHandler.ts index 4e7e2bb..e0b90b4 100644 --- a/packages/room/src/RoomObjectEventHandler.ts +++ b/packages/room/src/RoomObjectEventHandler.ts @@ -1501,11 +1501,37 @@ export class RoomObjectEventHandler implements IRoomCanvasMouseListener, IRoomOb return true; } + private _walkDebounceTimer: ReturnType = null; + private _lastWalkSentAt: number = 0; + private static readonly WALK_MIN_INTERVAL_MS = 100; + private sendWalkUpdate(x: number, y: number): void { if(!this._roomEngine || !GetCommunication().connection) return; - GetCommunication().connection.send(new RoomUnitWalkComposer(x, y)); + if(this._walkDebounceTimer) + { + clearTimeout(this._walkDebounceTimer); + this._walkDebounceTimer = null; + } + + const now = Date.now(); + const elapsed = now - this._lastWalkSentAt; + + if(elapsed >= RoomObjectEventHandler.WALK_MIN_INTERVAL_MS) + { + this._lastWalkSentAt = now; + GetCommunication().connection.send(new RoomUnitWalkComposer(x, y)); + } + else + { + this._walkDebounceTimer = setTimeout(() => + { + this._walkDebounceTimer = null; + this._lastWalkSentAt = Date.now(); + GetCommunication().connection.send(new RoomUnitWalkComposer(x, y)); + }, RoomObjectEventHandler.WALK_MIN_INTERVAL_MS - elapsed); + } } private handleMouseOverObject(category: number, roomId: number, event: RoomObjectMouseEvent): ObjectTileCursorUpdateMessage diff --git a/packages/utils/src/TextureUtils.ts b/packages/utils/src/TextureUtils.ts index c58f621..0b12996 100644 --- a/packages/utils/src/TextureUtils.ts +++ b/packages/utils/src/TextureUtils.ts @@ -15,12 +15,48 @@ export class TextureUtils public static async generateImage(options: ExtractImageOptions | Container | Texture): Promise { - return this.getExtractor().image(options); + if(!options) return null; + + if(options instanceof Texture) + { + if(options.destroyed || !options.source || options.source.destroyed) return null; + } + else if(options instanceof Container) + { + if(options.destroyed) return null; + } + + try + { + return await this.getExtractor().image(options); + } + catch(e) + { + return null; + } } public static async generateImageUrl(options: ExtractImageOptions | Container | Texture): Promise { - return this.getExtractor().base64(options); + if(!options) return null; + + if(options instanceof Texture) + { + if(options.destroyed || !options.source || options.source.destroyed) return null; + } + else if(options instanceof Container) + { + if(options.destroyed) return null; + } + + try + { + return await this.getExtractor().base64(options); + } + catch(e) + { + return null; + } } public static generateCanvas(options: ExtractOptions | Container | Texture): ICanvas