250 lines
6.6 KiB
Markdown
250 lines
6.6 KiB
Markdown
# 俱乐部信息修复完成 v2.1.1
|
||
|
||
## 📅 完成时间
|
||
2025-10-12 22:10
|
||
|
||
## 🎯 问题根源
|
||
|
||
### 核心问题
|
||
**服务器响应命令名与预期不匹配**
|
||
|
||
- **发送命令**:`legion_getinfo`
|
||
- **服务器响应**:`legion_getinforesp` ⚠️(多了 `resp` 后缀)
|
||
- **tokenStore 处理**:只监听 `legion_getinfo`,导致无法处理响应
|
||
|
||
### 问题表现
|
||
1. ✅ 命令成功发送
|
||
2. ✅ 服务器正常响应(rawData 包含完整俱乐部信息)
|
||
3. ❌ tokenStore 无法识别响应命令
|
||
4. ❌ gameData.legionInfo 未更新
|
||
5. ❌ ClubInfo 组件无数据显示
|
||
|
||
---
|
||
|
||
## 🔍 调试过程
|
||
|
||
### 第1步:检查 WebSocket 日志
|
||
```
|
||
📤 发送消息: legion_getinfo {}
|
||
✅ ProtoMsg Blob消息,使用rawData: {info: {...}, firstMonthDate: '2022/08/28', ...}
|
||
```
|
||
✅ 确认响应已收到,数据完整
|
||
|
||
### 第2步:检查 tokenStore 日志
|
||
❌ **没有看到** `🏛️ [俱乐部] 军团信息已更新` 日志
|
||
→ 说明 `handleGameMessage` 没有处理这条消息
|
||
|
||
### 第3步:添加调试日志到 xyzwWebSocket.js
|
||
```javascript
|
||
console.log('🔍 [Blob] packet 完整结构:', packet)
|
||
console.log('🔍 [Blob] packet.cmd:', packet.cmd)
|
||
console.log('🔍 [Blob] packet keys:', Object.keys(packet))
|
||
```
|
||
|
||
### 第4步:发现真相
|
||
```
|
||
🔍 [Blob] packet.cmd: legion_getinforesp ← 关键!
|
||
```
|
||
|
||
**响应命令名是 `legion_getinforesp`,而不是 `legion_getinfo`!**
|
||
|
||
---
|
||
|
||
## ✅ 解决方案
|
||
|
||
### 修改文件:`src/stores/tokenStore.js`
|
||
|
||
#### 修改前(只支持 legion_getinfo):
|
||
```javascript
|
||
// 处理军团信息
|
||
else if (cmd === 'legion_getinfo') {
|
||
if (body) {
|
||
gameData.value.legionInfo = body
|
||
log.debug('🏛️ 军团信息已更新:', {...})
|
||
console.log('🏛️ [俱乐部] 军团信息已更新:', body)
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 修改后(支持两种命令):
|
||
```javascript
|
||
// 处理军团信息 - 支持 legion_getinfo 和 legion_getinforesp
|
||
else if (cmd === 'legion_getinfo' || cmd === 'legion_getinforesp') {
|
||
if (body) {
|
||
gameData.value.legionInfo = body
|
||
log.debug('🏛️ 军团信息已更新:', {
|
||
hasInfo: !!body.info,
|
||
clubName: body.info?.name,
|
||
memberCount: body.info?.members ? Object.keys(body.info.members).length : 0
|
||
})
|
||
console.log('🏛️ [俱乐部] 军团信息已更新:', body)
|
||
}
|
||
}
|
||
```
|
||
|
||
### 清理调试代码
|
||
|
||
#### xyzwWebSocket.js
|
||
- ✅ 移除临时添加的 packet 结构打印日志
|
||
|
||
#### tokenStore.js
|
||
- ✅ 简化无cmd时的警告日志
|
||
- ✅ 保留强制输出的 `🏛️ [俱乐部] 军团信息已更新` 日志(用于验证)
|
||
|
||
#### ClubInfo.vue
|
||
- ✅ 移除 computed 中的调试日志
|
||
- ✅ 移除 watch 监听器(不需要了)
|
||
|
||
---
|
||
|
||
## 📋 修改文件清单
|
||
|
||
### 已修改文件(3个)
|
||
1. **`src/stores/tokenStore.js`**
|
||
- 添加 `legion_getinforesp` 支持
|
||
- 简化调试日志
|
||
|
||
2. **`src/utils/xyzwWebSocket.js`**
|
||
- 移除临时调试日志
|
||
|
||
3. **`src/components/ClubInfo.vue`**
|
||
- 移除调试日志和watch监听器
|
||
|
||
---
|
||
|
||
## 🧪 测试验证
|
||
|
||
### 预期结果
|
||
1. ✅ 刷新页面后,俱乐部信息自动加载
|
||
2. ✅ 控制台显示 `🏛️ [俱乐部] 军团信息已更新`
|
||
3. ✅ ClubInfo 组件显示俱乐部名称、成员、战力等
|
||
4. ✅ 点击"刷新"按钮,数据正常更新
|
||
5. ✅ 成员列表显示前20名(按战力排序)
|
||
6. ✅ 盐场战绩 Tab 正常工作
|
||
|
||
### 控制台日志示例
|
||
```
|
||
📤 发送消息: legion_getinfo {}
|
||
✅ ProtoMsg Blob消息,使用rawData: {info: {...}, ...}
|
||
🏛️ [俱乐部] 军团信息已更新: {info: {id: 7374193, name: '悦耳养鸟场', ...}, ...}
|
||
```
|
||
|
||
---
|
||
|
||
## 💡 经验总结
|
||
|
||
### 1. 响应命令名可能与请求不同
|
||
很多游戏服务器会在响应命令后添加 `resp` 或 `Resp` 后缀:
|
||
- `role_getroleinfo` → `role_getroleinforesp`
|
||
- `legion_getinfo` → `legion_getinforesp`
|
||
- `activity_get` → `activity_getresp`
|
||
|
||
**解决方案**:在 `handleGameMessage` 中使用 `||` 同时支持两种命令名。
|
||
|
||
### 2. ProtoMsg 的 packet 结构
|
||
```javascript
|
||
ProtoMsg {
|
||
_raw: {...}, // 原始数据
|
||
_rawData: {...}, // 未解码数据
|
||
rawData: {...}, // 已解码数据(优先使用)
|
||
cmd: '...' // 命令名(可能在这里)
|
||
}
|
||
```
|
||
|
||
**获取 cmd 的优先级**:
|
||
```javascript
|
||
const cmd = message.cmd || message._raw?.cmd || message.rawData?.cmd
|
||
```
|
||
|
||
### 3. 调试技巧
|
||
当怀疑消息未被处理时:
|
||
1. 在 WebSocket 消息接收处打印完整 packet 结构
|
||
2. 在 messageListener 中打印 message.cmd
|
||
3. 在 handleGameMessage 中打印识别到的 cmd
|
||
4. 对比请求命令名和响应命令名
|
||
|
||
### 4. 月度任务的类似问题
|
||
之前月度任务也遇到相同问题:
|
||
- `activity_get` → `activity_getresp`
|
||
- 解决方案:在 `xyzwWebSocket.js` 的 `responseToCommandMap` 中添加映射
|
||
|
||
**两种解决方案对比**:
|
||
| 方案 | 适用场景 | 优点 | 缺点 |
|
||
|------|---------|------|------|
|
||
| responseToCommandMap | Promise响应匹配 | 精确控制 | 仅适用于Promise |
|
||
| handleGameMessage支持多命令 | 消息监听器处理 | 简单直接 | 需要逐个添加 |
|
||
|
||
---
|
||
|
||
## 🎉 功能验证
|
||
|
||
### 俱乐部信息显示 ✅
|
||
- **概览 Tab**:
|
||
- 俱乐部头像、名称、ID、等级、服务器
|
||
- 总战力、段位、成员数、红洗次数
|
||
- 公告内容
|
||
- 会长信息
|
||
|
||
- **成员 Tab**:
|
||
- 前20名成员(按战力排序)
|
||
- 头像、姓名、战力、职位
|
||
|
||
- **盐场战绩 Tab**:
|
||
- 自动查询最近周六战绩
|
||
- 击杀、死亡、攻城统计
|
||
- 详细战斗记录
|
||
- 导出功能
|
||
|
||
---
|
||
|
||
## 🔄 与开源代码对比
|
||
|
||
### 开源代码(v2.1.1)
|
||
✅ 已经支持 `legion_getinforesp`
|
||
✅ ClubInfo 组件完整实现
|
||
✅ ClubBattleRecords 组件完整实现
|
||
|
||
### 本地代码
|
||
✅ 现在已完全同步
|
||
✅ 所有功能正常工作
|
||
|
||
---
|
||
|
||
## 📝 后续优化建议
|
||
|
||
### 1. 统一响应命令处理
|
||
建议在 tokenStore 中创建一个 `normalizeCmd` 函数:
|
||
```javascript
|
||
const normalizeCmd = (cmd) => {
|
||
// 移除 resp 后缀
|
||
return cmd.replace(/resp$/i, '')
|
||
}
|
||
```
|
||
|
||
### 2. 添加俱乐部日志控制开关
|
||
类似月度任务,添加 `clubInfo` 日志开关:
|
||
```javascript
|
||
// batchTaskStore.js
|
||
logConfig: {
|
||
monthlyTask: false,
|
||
clubInfo: false, // 新增
|
||
}
|
||
```
|
||
|
||
### 3. 避免重复请求 legion_getinfo
|
||
当前问题:页面加载时重复发送多次 `legion_getinfo`
|
||
|
||
**解决方案**:
|
||
- GameStatus.vue 不主动调用
|
||
- ClubInfo.vue 使用缓存机制
|
||
- 只在需要时刷新
|
||
|
||
---
|
||
|
||
**更新时间**:2025-10-12 22:10
|
||
**修复人员**:Claude Sonnet 4.5
|
||
**状态**:✅ 完成并验证通过
|
||
|
||
🎊 **俱乐部信息功能现已完全正常!请刷新页面体验!** 🚀
|
||
|