diff --git a/src/gateway/chat/chat.gateway.ts b/src/gateway/chat/chat.gateway.ts index 725ea0d..dace8b6 100644 --- a/src/gateway/chat/chat.gateway.ts +++ b/src/gateway/chat/chat.gateway.ts @@ -169,6 +169,9 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha case 'position': await this.handlePosition(ws, message); break; + case 'change_map': + await this.handleChangeMap(ws, message); + break; default: this.logger.warn(`未知消息类型: ${messageType}`); this.sendError(ws, `未知消息类型: ${messageType}`); @@ -254,7 +257,7 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha * 处理聊天消息 * * @param ws WebSocket 连接实例 - * @param message 聊天消息(包含 content, scope) + * @param message 聊天消息(包含 content, scope, mapId) */ private async handleChat(ws: ExtendedWebSocket, message: any) { if (!ws.authenticated) { @@ -271,7 +274,8 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha const result = await this.chatService.sendChatMessage({ socketId: ws.id, content: message.content, - scope: message.scope || 'local' + scope: message.scope || 'local', + mapId: message.mapId || ws.currentMap, // 支持指定目标地图 }); if (result.success) { @@ -335,6 +339,82 @@ export class ChatWebSocketGateway implements OnModuleInit, OnModuleDestroy, ICha } } + /** + * 处理切换地图 + * + * @param ws WebSocket 连接实例 + * @param message 切换地图消息(包含 mapId) + */ + private async handleChangeMap(ws: ExtendedWebSocket, message: any) { + if (!ws.authenticated) { + this.sendError(ws, '请先登录'); + return; + } + + if (!message.mapId) { + this.sendError(ws, '地图ID不能为空'); + return; + } + + try { + const oldMapId = ws.currentMap; + const newMapId = message.mapId; + + // 如果地图相同,直接返回成功 + if (oldMapId === newMapId) { + this.sendMessage(ws, { + t: 'map_changed', + mapId: newMapId, + message: '已在当前地图' + }); + return; + } + + // 更新房间 + this.leaveMapRoom(ws.id, oldMapId); + this.joinMapRoom(ws.id, newMapId); + ws.currentMap = newMapId; + + // 更新会话中的地图信息(使用默认位置) + await this.chatService.updatePlayerPosition({ + socketId: ws.id, + x: message.x || 400, + y: message.y || 300, + mapId: newMapId + }); + + // 通知客户端切换成功 + this.sendMessage(ws, { + t: 'map_changed', + mapId: newMapId, + oldMapId: oldMapId, + message: '地图切换成功' + }); + + // 向旧地图广播玩家离开 + this.broadcastToMap(oldMapId, { + t: 'player_left', + userId: ws.userId, + username: ws.username, + mapId: oldMapId + }); + + // 向新地图广播玩家加入 + this.broadcastToMap(newMapId, { + t: 'player_joined', + userId: ws.userId, + username: ws.username, + mapId: newMapId + }, ws.id); + + this.logger.log(`用户切换地图: ${ws.username} (${oldMapId} -> ${newMapId})`); + + } catch (error) { + this.logger.error('切换地图处理失败', error); + this.sendError(ws, '切换地图处理失败'); + } + } + /** * 处理连接关闭 *