# Zulip 游戏集成业务模块

Zulip 是游戏与Zulip社群平台的集成业务模块，提供完整的实时聊天、会话管理、消息过滤和WebSocket通信功能，实现游戏内聊天与Zulip社群的双向同步，支持基于位置的聊天上下文管理和业务规则驱动的消息过滤控制。

## 玩家登录和会话管理

### handlePlayerLogin()
验证游戏Token，创建Zulip客户端，建立会话映射关系，支持JWT认证和API Key获取。

### handlePlayerLogout()
清理玩家会话，注销Zulip事件队列，释放相关资源，确保连接正常断开。

### getSession()
根据socketId获取会话信息，并更新最后活动时间，支持会话状态查询。

### getSocketsInMap()
获取指定地图中所有在线玩家的Socket ID列表，用于消息分发和空间过滤。

## 消息发送和处理

### sendChatMessage()
处理游戏客户端发送的聊天消息，转发到对应的Zulip Stream/Topic，包含内容过滤和权限验证。

### processZulipMessage()
处理Zulip事件队列推送的消息，转换格式后发送给相关的游戏客户端，实现双向通信。

### updatePlayerPosition()
更新玩家在游戏世界中的位置信息，用于消息路由和上下文注入，支持地图切换。

## WebSocket网关功能

### handleConnection()
处理游戏客户端WebSocket连接建立，记录连接信息并初始化连接状态。

### handleDisconnect()
处理游戏客户端连接断开，清理相关资源并执行登出逻辑。

### handleLogin()
处理登录消息，验证Token并建立会话，返回登录结果和用户信息。

### handleChat()
处理聊天消息，验证用户认证状态和消息格式，调用业务服务发送消息。

### sendChatRender()
向指定客户端发送聊天渲染消息，用于显示气泡或聊天框。

### broadcastToMap()
向指定地图的所有客户端广播消息，支持区域性消息分发。

## 会话管理功能

### createSession()
创建会话并绑定Socket_ID与Zulip_Queue_ID，建立WebSocket连接与Zulip队列的映射关系。

### injectContext()
上下文注入，根据玩家位置确定消息应该发送到的Zulip Stream和Topic。

### destroySession()
清理玩家会话数据，从地图玩家列表中移除，释放相关资源。

### cleanupExpiredSessions()
定时清理超时的会话数据和相关资源，返回需要注销的Zulip队列ID列表。

## 消息过滤和安全

### validateMessage()
对消息进行综合验证，包括内容过滤、频率限制和权限验证。

### filterContent()
检查消息内容是否包含敏感词，进行内容过滤和替换。

### checkRateLimit()
检查用户是否超过消息发送频率限制，防止刷屏。

### validatePermission()
验证用户是否有权限向目标Stream发送消息，防止位置欺诈。

### logViolation()
记录用户的违规行为，用于监控和分析。

## WebSocket事件接口

### 'login'
客户端登录认证，建立游戏会话并获取Zulip访问权限。
- 输入: `{ type: 'login', token: string }`
- 输出: `{ t: 'login_success', sessionId: string, userId: string, username: string, currentMap: string }` 或 `{ t: 'login_error', message: string }`

### 'logout'
客户端主动登出，清理会话资源并断开连接。
- 输入: `{ type: 'logout' }`
- 输出: `{ t: 'logout_success', message: string }`

### 'chat'
发送聊天消息，支持本地和全局范围，自动同步到Zulip。
- 输入: `{ type: 'chat', content: string, scope?: 'local'|'global' }`
- 输出: `{ t: 'chat_sent', messageId: string, message: string }` 或 `{ t: 'chat_error', message: string }`

### 'position'
更新玩家位置信息，支持地图切换和位置广播。
- 输入: `{ type: 'position', x: number, y: number, mapId: string }`
- 输出: 广播给同地图其他玩家 `{ t: 'position_update', userId: string, username: string, x: number, y: number, mapId: string }`

### 'chat_render'
接收聊天消息渲染事件，用于显示其他玩家的聊天内容。
- 输入: 无（服务器推送）
- 输出: `{ t: 'chat_render', userId: string, username: string, content: string, timestamp: number, mapId: string }`

### 'connected'
连接建立确认事件，服务器主动发送连接状态。
- 输入: 无（服务器推送）
- 输出: `{ type: 'connected', message: string, socketId: string }`

### 'error'
错误事件通知，用于处理各种异常情况和错误信息。
- 输入: 无（服务器推送）
- 输出: `{ type: 'error', message: string }`

## REST API接口

### sendMessage()
通过REST API发送聊天消息到Zulip（推荐使用WebSocket接口）。

### getChatHistory()
获取指定地图或全局的聊天历史记录，支持分页查询。

### getSystemStatus()
获取WebSocket连接状态、Zulip集成状态等系统信息。

### getWebSocketInfo()
获取WebSocket连接的详细信息，包括连接地址、协议等。

## 使用的项目内部依赖

### ZulipCoreModule (来自 core/zulip_core)
提供Zulip核心技术服务，包括客户端池管理、配置管理和事件处理等底层技术实现。

### LoginCoreModule (来自 core/login_core)
提供用户认证和Token验证服务，支持JWT令牌验证和用户信息获取。

### RedisModule (来自 core/redis)
提供会话状态缓存和数据存储服务，支持会话持久化和快速查询。

### LoggerModule (来自 core/utils/logger)
提供统一的日志记录服务，支持结构化日志和性能监控。

### ZulipAccountsModule (来自 core/db/zulip_accounts)
提供Zulip账号关联管理功能，支持用户与Zulip账号的绑定关系。

### AuthModule (来自 business/auth)
提供JWT验证和用户认证服务，支持用户身份验证和权限控制。

### IZulipClientPoolService (来自 core/zulip_core/interfaces)
Zulip客户端池服务接口，用于管理用户专用的Zulip客户端实例。

### IZulipConfigService (来自 core/zulip_core/interfaces)
Zulip配置服务接口，用于获取地图到Stream的映射关系和配置信息。

### ApiKeySecurityService (来自 core/zulip_core/services)
API密钥安全服务，用于获取和管理用户的Zulip API Key。

### IRedisService (来自 core/redis)
Redis服务接口，用于会话数据存储、频率限制和违规记录管理。

### SendChatMessageDto (本模块)
发送聊天消息的数据传输对象，定义消息内容、范围和地图ID等字段。

### ChatMessageResponseDto (本模块)
聊天消息响应的数据传输对象，包含成功状态、消息ID和错误信息。

### SystemStatusResponseDto (本模块)
系统状态响应的数据传输对象，包含WebSocket状态、Zulip集成状态和系统信息。

## 核心特性

### 双向通信支持
- WebSocket实时通信：支持游戏客户端与服务器的实时双向通信
- Zulip集成同步：实现游戏内聊天与Zulip社群的双向消息同步
- 事件驱动架构：基于事件队列处理Zulip消息推送和游戏事件

### 会话状态管理
- Redis持久化存储：会话数据存储在Redis中，支持服务重启后状态恢复
- 自动过期清理：定时清理超时会话，释放系统资源
- 多地图支持：支持玩家在不同地图间切换，自动更新地图玩家列表

### 消息过滤和安全
- 敏感词过滤：支持block和replace两种级别的敏感词处理
- 频率限制控制：防止用户发送消息过于频繁导致刷屏
- 位置权限验证：防止用户向不匹配位置的Stream发送消息
- 违规行为记录：记录和统计用户违规行为，支持监控和分析

### 业务规则引擎
- 上下文注入机制：根据玩家位置自动确定消息的目标Stream和Topic
- 动态配置管理：支持地图到Stream映射关系的动态配置和热重载
- 权限分级控制：支持不同用户角色的权限控制和消息发送限制

## 潜在风险

### 会话数据丢失
- Redis服务故障可能导致会话数据丢失，影响用户体验
- 建议配置Redis主从复制和持久化策略
- 实现会话数据的定期备份和恢复机制

### 消息同步延迟
- Zulip服务器网络延迟可能影响消息同步实时性
- 大量并发消息可能导致事件队列处理延迟
- 建议监控消息处理延迟并设置合理的超时机制

### 频率限制绕过
- 恶意用户可能通过多个账号绕过频率限制
- IP级别的频率限制可能影响正常用户
- 建议结合用户行为分析和动态调整限制策略

### 敏感词过滤失效
- 新型敏感词和变体可能绕过现有过滤规则
- 过度严格的过滤可能影响正常交流
- 建议定期更新敏感词库并优化过滤算法

### WebSocket连接稳定性
- 网络不稳定可能导致WebSocket连接频繁断开重连
- 大量连接可能消耗过多服务器资源
- 建议实现连接池管理和自动重连机制

### 位置验证绕过
- 客户端修改可能绕过位置验证机制
- 服务端位置验证逻辑需要持续完善
- 建议结合多种验证手段和异常行为检测

## 使用示例

### WebSocket 客户端连接
```typescript
// 建立WebSocket连接
const socket = io('ws://localhost:3000/zulip');

// 监听连接事件
socket.on('connect', () => {
  console.log('Connected to Zulip WebSocket');
});

// 发送登录消息
socket.emit('login', {
  token: 'your-jwt-token'
});

// 发送聊天消息
socket.emit('chat', {
  content: '大家好！',
  scope: 'local',
  mapId: 'whale_port'
});

// 监听聊天消息
socket.on('chat_render', (data) => {
  console.log('收到消息:', data);
});
```

### REST API 调用
```typescript
// 发送聊天消息
const response = await fetch('/api/zulip/send-message', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your-jwt-token'
  },
  body: JSON.stringify({
    content: '测试消息',
    scope: 'global',
    mapId: 'whale_port'
  })
});

// 获取聊天历史
const history = await fetch('/api/zulip/chat-history?mapId=whale_port&limit=50');
const messages = await history.json();

// 获取系统状态
const status = await fetch('/api/zulip/system-status');
const systemInfo = await status.json();
```

### 服务集成示例
```typescript
@Injectable()
export class GameChatService {
  constructor(
    private readonly zulipService: ZulipService,
    private readonly sessionManager: SessionManagerService
  ) {}

  async handlePlayerMessage(playerId: string, message: string) {
    // 获取玩家会话
    const session = await this.sessionManager.getSession(playerId);
    
    // 发送消息到Zulip
    const result = await this.zulipService.sendChatMessage({
      gameUserId: playerId,
      content: message,
      scope: 'local',
      mapId: session.mapId
    });
    
    return result;
  }
}
```

## 版本信息
- **版本**: 1.3.0
- **作者**: angjustinl
- **创建时间**: 2025-12-20
- **最后修改**: 2026-01-12

## 最近修改记录
- 2026-01-12: 功能新增 - 添加完整的WebSocket事件接口文档，包含所有事件的输入输出格式说明 (修改者: moyin)
- 2026-01-07: 功能修改 - 更新业务逻辑和接口描述 (修改者: angjustinl)
- 2025-12-20: 功能新增 - 创建Zulip游戏集成业务模块文档 (修改者: angjustinl)