# Zulip 集成系统文档

## 概述

Zulip 集成系统是一个为 2D 社交 MMO 游戏设计的跨平台聊天解决方案。该系统实现了游戏内外的无缝互通，让不玩游戏的 Zulip 社群成员也能与游戏内玩家实时交流。

### 核心设计理念

系统采用 **统一网关 (Unified Gateway)** 架构，利用 Zulip 的 Stream-Topic 线程模型与游戏世界的空间概念进行映射：

| 游戏概念 | Zulip 概念 | 示例 |
|---------|-----------|------|
| Game World / Map | Stream | #Novice_Village |
| Interactive Object / Event | Topic | Notice Board, Tavern Gossip |
| Whisper / Party | Private Message | 私聊消息 |

### 架构优势

1. **客户端极度简化**: Godot 客户端无需处理 HTTP 请求、Long Polling 或复杂 JSON 解析
2. **安全性**: Zulip API Key 永不下发到客户端，位置欺诈完全消除
3. **协议统一**: 单一 WebSocket 协议，网络层代码减半

## 系统架构

```
┌─────────────────┐     WebSocket      ┌─────────────────────────────────────┐
│  Godot Client   │◄──────────────────►│     NestJS 中间件服务器              │
│  (Game Client)  │   Game Protocol    │  ┌─────────────────────────────────┐│
└─────────────────┘                    │  │  WebSocket Gateway              ││
                                       │  │  ├─ Session Manager             ││
                                       │  │  ├─ Message Filter              ││
                                       │  │  └─ Zulip Client Pool           ││
                                       │  └─────────────────────────────────┘│
                                       └──────────────┬──────────────────────┘
                                                      │ REST API / Long Polling
                                                      ▼
                                       ┌─────────────────────────────────────┐
                                       │         Zulip Server                │
                                       │  ├─ REST API                        │
                                       │  └─ Event Queue                     │
                                       └─────────────────────────────────────┘
```

## 核心组件

### 1. WebSocket Gateway (`zulip-websocket.gateway.ts`)

统一网关，处理所有 Godot 客户端连接，实现游戏协议到 Zulip 协议的转换。

**主要功能:**
- 连接认证和会话管理
- 消息路由和协议转换
- 权限控制和上下文注入

**支持的消息类型:**
- `login`: 玩家登录
- `chat`: 发送聊天消息
- `position_update`: 位置更新
- `logout`: 玩家登出

### 2. Session Manager (`session-manager.service.ts`)

会话管理器，维护 Socket_ID 与 Zulip_Queue_ID 的绑定关系。

**主要功能:**
- 会话创建/销毁
- 玩家位置跟踪
- 上下文注入（根据位置确定 Stream/Topic）
- 空间过滤（获取指定地图的所有 Socket）

### 3. Zulip Client Pool (`zulip-client-pool.service.ts`)

Zulip 客户端池，为每个用户维护专用的 Zulip 客户端实例。

**主要功能:**
- API Key 管理
- 事件队列注册
- 消息发送/接收
- 客户端生命周期管理

### 4. Message Filter (`message-filter.service.ts`)

消息过滤器，实施内容审核和频率控制。

**主要功能:**
- 敏感词过滤
- 频率限制（默认 10 条/分钟）
- 消息长度限制（默认 1000 字符）
- 重复内容检测
- 权限验证

### 5. Config Manager (`config-manager.service.ts`)

配置管理器，管理地图映射配置和系统参数。

**主要功能:**
- 地图到 Stream 的映射
- 交互对象到 Topic 的映射
- 配置热重载
- 配置验证

### 6. Stream Initializer Service (`stream-initializer.service.ts`)

Stream 初始化服务，在系统启动时自动检查并创建缺失的 Zulip Streams。

**主要功能:**
- 启动时自动检查所有地图对应的 Streams
- 自动创建缺失的 Streams
- 使用 Bot API Key 或管理员账号创建 Streams
- 记录初始化结果和错误

**权限说明:**
- Bot 账号可能缺少创建 Stream 的权限
- 建议使用管理员账号手动创建 Streams
- 或在 Zulip 服务器中为 Bot 授予相应权限

### 7. Monitoring Service (`monitoring.service.ts`)

监控服务，提供系统健康检查和指标收集。

**主要功能:**
- 连接指标监控
- 消息指标监控
- 系统健康检查
- 告警通知

## 消息协议

### 客户端发送格式

#### 登录消息
```json
{
  "type": "login",
  "token": "user_game_token"
}
```

#### 聊天消息
```json
{
  "t": "chat",
  "content": "Hello",
  "scope": "local"
}
```

#### 位置更新
```json
{
  "t": "position",
  "x": 100,
  "y": 200,
  "mapId": "novice_village"
}
```

### 客户端接收格式

#### 聊天渲染消息
```json
{
  "t": "chat_render",
  "from": "User_B",
  "txt": "Hi",
  "bubble": true
}
```

#### 登录确认
```json
{
  "t": "login_success",
  "sessionId": "session_123",
  "currentMap": "novice_village"
}
```

#### 错误消息
```json
{
  "t": "error",
  "code": "RATE_LIMIT",
  "message": "消息发送过于频繁，请稍后再试"
}
```

## 配置说明

### 环境变量配置

```bash
# Zulip 服务器配置
ZULIP_SERVER_URL=https://your-zulip-server.com
ZULIP_BOT_EMAIL=bot@your-zulip-server.com
ZULIP_BOT_API_KEY=your-bot-api-key

# WebSocket 配置
WEBSOCKET_PORT=3001
WEBSOCKET_NAMESPACE=/game

# 消息配置
MESSAGE_RATE_LIMIT=10          # 消息频率限制（条/分钟）
MESSAGE_MAX_LENGTH=1000        # 消息最大长度

# 会话配置
SESSION_TIMEOUT=30             # 会话超时时间（分钟）
CLEANUP_INTERVAL=5             # 清理间隔（分钟）
```

### Stream 初始化

系统在启动时会自动检查并尝试创建缺失的 Zulip Streams。

**注意事项:**

- Bot 账号可能缺少创建 Stream 的权限
- 建议使用管理员账号预先创建所有 Streams
- 或在 Zulip 服务器中为 Bot 授予 "Create streams" 权限

**手动创建 Streams:**

```bash
# 使用测试脚本创建所有地图区域的 Streams
node test-stream-initialization.js
```

详细配置说明请参考 [配置管理指南](./configuration.md)。

### 地图映射配置

配置文件位置: `config/zulip/map-config.json`

系统支持 9 个地图区域，每个区域对应一个 Zulip Stream：

1. **鲸之港 (Whale Port)** - 中心城区，默认出生点
2. **南瓜谷 (Pumpkin Valley)** - 新手学习区
3. **Offer 城 (Offer City)** - 职业发展区
4. **模型工厂 (Model Factory)** - AI/代码构建区
5. **内核岛 (Kernel Island)** - 核心技术研究区
6. **摸鱼海滩 (Moyu Beach)** - 休闲娱乐区
7. **天梯峰 (Ladder Peak)** - 挑战竞赛区
8. **星河湾 (Galaxy Bay)** - 创意设计区
9. **数据遗迹 (Data Ruins)** - 数据库归档区

配置示例：

```json
{
  "version": "2.0.0",
  "description": "基于像素大地图的 Zulip 映射配置",
  "maps": [
    {
      "mapId": "whale_port",
      "mapName": "鲸之港",
      "zulipStream": "Whale Port",
      "description": "中心城区，交通枢纽与主要聚会点",
      "interactionObjects": [
        {
          "objectId": "whale_statue",
          "objectName": "鲸鱼雕像",
          "zulipTopic": "Announcements",
          "position": { "x": 600, "y": 400 }
        }
      ]
    }
  ]
}
```

## 数据流程

### 发送消息流程 (游戏 → Zulip)

1. 玩家在游戏中输入消息
2. Godot 客户端通过 WebSocket 发送 `chat` 消息
3. WebSocket Gateway 接收消息
4. Session Manager 获取玩家当前位置
5. 上下文注入：根据位置确定目标 Stream/Topic
6. Message Filter 进行内容过滤和频率检查
7. Zulip Client Pool 使用用户的 API Key 发送消息到 Zulip
8. 返回发送确认给客户端

### 接收消息流程 (Zulip → 游戏)

1. Zulip 服务器推送消息事件到 Event Queue
2. Zulip Event Processor 接收并处理事件
3. Session Manager 进行空间过滤，确定目标玩家
4. 消息转换为游戏协议格式
5. WebSocket Gateway 推送 `chat_render` 消息给目标客户端
6. Godot 客户端显示聊天气泡

## 错误处理

### 错误码说明

| 错误码 | 说明 | 处理建议 |
|-------|------|---------|
| `AUTH_FAILED` | 认证失败 | 检查 Token 有效性 |
| `RATE_LIMIT` | 频率限制 | 等待后重试 |
| `CONTENT_FILTERED` | 内容被过滤 | 修改消息内容 |
| `PERMISSION_DENIED` | 权限不足 | 检查用户权限 |
| `ZULIP_ERROR` | Zulip 服务错误 | 系统自动重试 |
| `SESSION_EXPIRED` | 会话过期 | 重新登录 |

### 降级策略

当 Zulip 服务不可用时，系统会自动切换到本地聊天模式：
- 消息仅在游戏内传播
- 不同步到 Zulip
- 服务恢复后自动切换回正常模式

## 安全机制

### API Key 安全

- API Key 加密存储在数据库中
- 永不下发到客户端
- 支持强制刷新机制

### 消息安全

- 敏感词过滤
- 频率限制防刷屏
- 位置验证防欺诈
- 消息长度限制

### 连接安全

- Token 验证
- 会话超时自动断开
- 异常连接检测和拒绝

## 监控指标

### 连接指标
- `zulip.connections.active`: 活跃连接数
- `zulip.connections.total`: 总连接数
- `zulip.connections.errors`: 连接错误数

### 消息指标
- `zulip.messages.sent`: 发送消息数
- `zulip.messages.received`: 接收消息数
- `zulip.messages.filtered`: 被过滤消息数
- `zulip.messages.latency`: 消息延迟

### 系统指标
- `zulip.sessions.active`: 活跃会话数
- `zulip.zulip_clients.active`: 活跃 Zulip 客户端数
- `zulip.event_queues.active`: 活跃事件队列数

## 相关文档

- [zulip-js 库使用指南](./zulip-js.md)
- [API 接口文档](./api.md)
- [WebSocket 协议详解](./websocket-protocol.md)
- [配置管理指南](./configuration.md)

## 更新日志

### v1.1.0 (2026-01-06)
- **修复 JWT Token 验证和 API Key 管理**
  - 修复 `LoginService.generateTokenPair()` 的 JWT 签名冲突问题
  - `ZulipService` 现在复用 `LoginService.verifyToken()` 进行 Token 验证
  - 修复消息发送时使用错误的硬编码 API Key 问题
  - 现在正确从 Redis 读取用户注册时存储的真实 API Key
  - 添加 `AuthModule` 到 `ZulipModule` 的依赖注入
  - 消息发送功能现已完全正常工作 ✅

### v1.0.1 (2025-12-25)
- 更新地图配置为 9 区域系统
- 添加 Stream Initializer Service 自动初始化服务
- 更新默认出生点为鲸之港 (Whale Port)
- 添加地图区域描述字段
- 修复上下文注入使用 ConfigManager
- 改进错误处理和日志记录

### v1.0.0 (2025-12-25)
- 初始版本发布
- 实现 WebSocket Gateway 统一网关
- 实现 Session Manager 会话管理
- 实现 Zulip Client Pool 客户端池
- 实现 Message Filter 消息过滤
- 实现 Config Manager 配置管理
- 实现 Monitoring Service 监控服务
- 完成集成测试覆盖
