feat(zulip): 添加全面的 Zulip 集成系统
* **新增 Zulip 模块**:包含完整的集成服务,涵盖客户端池(client pool)、会话管理及事件处理。 * **新增 WebSocket 网关**:用于处理 Zulip 的实时事件监听与双向通信。 * **新增安全服务**:支持 API 密钥加密存储及凭据的安全管理。 * **新增配置管理服务**:支持配置热加载(hot-reload),实现动态配置更新。 * **新增错误处理与监控服务**:提升系统的可靠性与可观测性。 * **新增消息过滤服务**:用于内容校验及速率限制(流控)。 * **新增流初始化与会话清理服务**:优化资源管理与回收。 * **完善测试覆盖**:包含单元测试及端到端(e2e)集成测试。 * **完善详细文档**:包括 API 参考手册、配置指南及集成概述。 * **新增地图配置系统**:实现游戏地点与 Zulip Stream(频道)及 Topic(话题)的逻辑映射。 * **新增环境变量配置**:涵盖 Zulip 服务器地址、身份验证及监控相关设置。 * **更新 App 模块**:注册并启用新的 Zulip 集成模块。 * **更新 Redis 接口**:以支持增强型的会话管理功能。 * **实现 WebSocket 协议支持**:确保与 Zulip 之间的实时双向通信。
This commit is contained in:
149
config/zulip/README.md
Normal file
149
config/zulip/README.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Zulip配置目录
|
||||
|
||||
本目录包含Zulip集成系统的配置文件。
|
||||
|
||||
## 文件说明
|
||||
|
||||
### map-config.json
|
||||
|
||||
地图映射配置文件,定义游戏地图到Zulip Stream/Topic的映射关系。
|
||||
|
||||
#### 配置结构
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"lastModified": "2025-12-25T00:00:00.000Z",
|
||||
"description": "配置描述",
|
||||
"maps": [
|
||||
{
|
||||
"mapId": "地图唯一标识",
|
||||
"mapName": "地图显示名称",
|
||||
"zulipStream": "对应的Zulip Stream名称",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "交互对象唯一标识",
|
||||
"objectName": "交互对象显示名称",
|
||||
"zulipTopic": "对应的Zulip Topic名称",
|
||||
"position": { "x": 100, "y": 150 }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 字段说明
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| version | string | 否 | 配置版本号 |
|
||||
| lastModified | string | 否 | 最后修改时间(ISO 8601格式) |
|
||||
| description | string | 否 | 配置描述 |
|
||||
| maps | array | 是 | 地图配置数组 |
|
||||
|
||||
##### 地图配置 (MapConfig)
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| mapId | string | 是 | 地图唯一标识,如 "novice_village" |
|
||||
| mapName | string | 是 | 地图显示名称,如 "新手村" |
|
||||
| zulipStream | string | 是 | 对应的Zulip Stream名称 |
|
||||
| interactionObjects | array | 是 | 交互对象配置数组 |
|
||||
|
||||
##### 交互对象配置 (InteractionObject)
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| objectId | string | 是 | 交互对象唯一标识 |
|
||||
| objectName | string | 是 | 交互对象显示名称 |
|
||||
| zulipTopic | string | 是 | 对应的Zulip Topic名称 |
|
||||
| position | object | 是 | 对象在地图中的位置 |
|
||||
| position.x | number | 是 | X坐标 |
|
||||
| position.y | number | 是 | Y坐标 |
|
||||
|
||||
## 配置示例
|
||||
|
||||
### 新手村配置
|
||||
|
||||
```json
|
||||
{
|
||||
"mapId": "novice_village",
|
||||
"mapName": "新手村",
|
||||
"zulipStream": "Novice Village",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "notice_board",
|
||||
"objectName": "公告板",
|
||||
"zulipTopic": "Notice Board",
|
||||
"position": { "x": 100, "y": 150 }
|
||||
},
|
||||
{
|
||||
"objectId": "village_well",
|
||||
"objectName": "村井",
|
||||
"zulipTopic": "Village Well",
|
||||
"position": { "x": 200, "y": 200 }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 酒馆配置
|
||||
|
||||
```json
|
||||
{
|
||||
"mapId": "tavern",
|
||||
"mapName": "酒馆",
|
||||
"zulipStream": "Tavern",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "bar_counter",
|
||||
"objectName": "吧台",
|
||||
"zulipTopic": "Bar Counter",
|
||||
"position": { "x": 150, "y": 100 }
|
||||
},
|
||||
{
|
||||
"objectId": "fireplace",
|
||||
"objectName": "壁炉",
|
||||
"zulipTopic": "Fireplace Chat",
|
||||
"position": { "x": 300, "y": 200 }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 热重载
|
||||
|
||||
配置文件支持热重载,修改后无需重启服务即可生效。
|
||||
|
||||
### 启用配置监听
|
||||
|
||||
在代码中调用:
|
||||
|
||||
```typescript
|
||||
configManagerService.enableConfigWatcher();
|
||||
```
|
||||
|
||||
### 手动重载配置
|
||||
|
||||
```typescript
|
||||
await configManagerService.reloadConfig();
|
||||
```
|
||||
|
||||
## 验证配置
|
||||
|
||||
系统启动时会自动验证配置文件的有效性。验证规则包括:
|
||||
|
||||
1. mapId必须是非空字符串
|
||||
2. mapName必须是非空字符串
|
||||
3. zulipStream必须是非空字符串
|
||||
4. interactionObjects必须是数组
|
||||
5. 每个交互对象必须有有效的objectId、objectName、zulipTopic和position
|
||||
6. position.x和position.y必须是有效数字
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **Stream名称**: Zulip Stream名称区分大小写,请确保与Zulip服务器上的Stream名称完全匹配
|
||||
2. **Topic名称**: Topic名称同样区分大小写
|
||||
3. **位置坐标**: 位置坐标用于空间过滤,确保与游戏客户端的坐标系统一致
|
||||
4. **唯一性**: mapId和objectId在各自范围内必须唯一
|
||||
205
config/zulip/map-config.json
Normal file
205
config/zulip/map-config.json
Normal file
@@ -0,0 +1,205 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"lastModified": "2025-12-25T20:00:00.000Z",
|
||||
"description": "基于设计图的 Zulip 映射配置",
|
||||
"maps": [
|
||||
{
|
||||
"mapId": "whale_port",
|
||||
"mapName": "鲸之港",
|
||||
"zulipStream": "Whale Port",
|
||||
"description": "中心城区,交通枢纽与主要聚会点",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "whale_statue",
|
||||
"objectName": "鲸鱼雕像",
|
||||
"zulipTopic": "Announcements",
|
||||
"position": { "x": 600, "y": 400 }
|
||||
},
|
||||
{
|
||||
"objectId": "clock_tower",
|
||||
"objectName": "大本钟",
|
||||
"zulipTopic": "General Chat",
|
||||
"position": { "x": 550, "y": 350 }
|
||||
},
|
||||
{
|
||||
"objectId": "city_metro",
|
||||
"objectName": "地铁入口",
|
||||
"zulipTopic": "Transportation",
|
||||
"position": { "x": 600, "y": 550 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "offer_city",
|
||||
"mapName": "Offer 城",
|
||||
"zulipStream": "Offer City",
|
||||
"description": "职业发展、面试与商务区",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "skyscrapers",
|
||||
"objectName": "摩天大楼",
|
||||
"zulipTopic": "Career Talk",
|
||||
"position": { "x": 350, "y": 650 }
|
||||
},
|
||||
{
|
||||
"objectId": "business_center",
|
||||
"objectName": "商务中心",
|
||||
"zulipTopic": "Interview Prep",
|
||||
"position": { "x": 300, "y": 700 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "model_factory",
|
||||
"mapName": "模型工厂",
|
||||
"zulipStream": "Model Factory",
|
||||
"description": "AI模型训练、代码构建与工业区",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "assembly_line",
|
||||
"objectName": "流水线",
|
||||
"zulipTopic": "Code Review",
|
||||
"position": { "x": 400, "y": 200 }
|
||||
},
|
||||
{
|
||||
"objectId": "gear_tower",
|
||||
"objectName": "齿轮塔",
|
||||
"zulipTopic": "DevOps & CI/CD",
|
||||
"position": { "x": 450, "y": 180 }
|
||||
},
|
||||
{
|
||||
"objectId": "cable_car_station",
|
||||
"objectName": "缆车站",
|
||||
"zulipTopic": "Deployments",
|
||||
"position": { "x": 350, "y": 220 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "kernel_island",
|
||||
"mapName": "内核岛",
|
||||
"zulipStream": "Kernel Island",
|
||||
"description": "核心技术研究、底层原理与算法",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "crystal_core",
|
||||
"objectName": "能量水晶",
|
||||
"zulipTopic": "Core Algorithms",
|
||||
"position": { "x": 600, "y": 150 }
|
||||
},
|
||||
{
|
||||
"objectId": "floating_rocks",
|
||||
"objectName": "浮空石",
|
||||
"zulipTopic": "System Architecture",
|
||||
"position": { "x": 650, "y": 180 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "pumpkin_valley",
|
||||
"mapName": "南瓜谷",
|
||||
"zulipStream": "Pumpkin Valley",
|
||||
"description": "新手成长、基础资源与学习社区",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "pumpkin_patch",
|
||||
"objectName": "南瓜田",
|
||||
"zulipTopic": "Tutorials",
|
||||
"position": { "x": 150, "y": 400 }
|
||||
},
|
||||
{
|
||||
"objectId": "farm_house",
|
||||
"objectName": "农舍",
|
||||
"zulipTopic": "Study Group",
|
||||
"position": { "x": 200, "y": 450 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "moyu_beach",
|
||||
"mapName": "摸鱼海滩",
|
||||
"zulipStream": "Moyu Beach",
|
||||
"description": "休闲娱乐、水贴与非技术话题",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "beach_umbrella",
|
||||
"objectName": "遮阳伞",
|
||||
"zulipTopic": "Random Chat",
|
||||
"position": { "x": 850, "y": 200 }
|
||||
},
|
||||
{
|
||||
"objectId": "lighthouse",
|
||||
"objectName": "灯塔",
|
||||
"zulipTopic": "Music & Movies",
|
||||
"position": { "x": 800, "y": 100 }
|
||||
},
|
||||
{
|
||||
"objectId": "fishing_dock",
|
||||
"objectName": "栈桥",
|
||||
"zulipTopic": "Gaming",
|
||||
"position": { "x": 750, "y": 250 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "ladder_peak",
|
||||
"mapName": "天梯峰",
|
||||
"zulipStream": "Ladder Peak",
|
||||
"description": "挑战、竞赛与排行榜",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "summit_flag",
|
||||
"objectName": "峰顶旗帜",
|
||||
"zulipTopic": "Leaderboard",
|
||||
"position": { "x": 150, "y": 100 }
|
||||
},
|
||||
{
|
||||
"objectId": "snowy_path",
|
||||
"objectName": "雪径",
|
||||
"zulipTopic": "Challenges",
|
||||
"position": { "x": 200, "y": 150 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "galaxy_bay",
|
||||
"mapName": "星河湾",
|
||||
"zulipStream": "Galaxy Bay",
|
||||
"description": "创意、设计与灵感",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "starfish",
|
||||
"objectName": "巨型海星",
|
||||
"zulipTopic": "UI/UX Design",
|
||||
"position": { "x": 100, "y": 700 }
|
||||
},
|
||||
{
|
||||
"objectId": "palm_tree",
|
||||
"objectName": "椰子树",
|
||||
"zulipTopic": "Art & Assets",
|
||||
"position": { "x": 150, "y": 650 }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mapId": "data_ruins",
|
||||
"mapName": "数据遗迹",
|
||||
"zulipStream": "Data Ruins",
|
||||
"description": "数据库、归档与历史记录",
|
||||
"interactionObjects": [
|
||||
{
|
||||
"objectId": "ruined_gate",
|
||||
"objectName": "遗迹之门",
|
||||
"zulipTopic": "Database Schema",
|
||||
"position": { "x": 900, "y": 700 }
|
||||
},
|
||||
{
|
||||
"objectId": "ancient_monolith",
|
||||
"objectName": "石碑",
|
||||
"zulipTopic": "Archives",
|
||||
"position": { "x": 950, "y": 650 }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user