6.6 KiB
6.6 KiB
俱乐部信息修复完成 v2.1.1
📅 完成时间
2025-10-12 22:10
🎯 问题根源
核心问题
服务器响应命令名与预期不匹配
- 发送命令:
legion_getinfo - 服务器响应:
legion_getinforesp⚠️(多了resp后缀) - tokenStore 处理:只监听
legion_getinfo,导致无法处理响应
问题表现
- ✅ 命令成功发送
- ✅ 服务器正常响应(rawData 包含完整俱乐部信息)
- ❌ tokenStore 无法识别响应命令
- ❌ gameData.legionInfo 未更新
- ❌ ClubInfo 组件无数据显示
🔍 调试过程
第1步:检查 WebSocket 日志
📤 发送消息: legion_getinfo {}
✅ ProtoMsg Blob消息,使用rawData: {info: {...}, firstMonthDate: '2022/08/28', ...}
✅ 确认响应已收到,数据完整
第2步:检查 tokenStore 日志
❌ 没有看到 🏛️ [俱乐部] 军团信息已更新 日志
→ 说明 handleGameMessage 没有处理这条消息
第3步:添加调试日志到 xyzwWebSocket.js
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):
// 处理军团信息
else if (cmd === 'legion_getinfo') {
if (body) {
gameData.value.legionInfo = body
log.debug('🏛️ 军团信息已更新:', {...})
console.log('🏛️ [俱乐部] 军团信息已更新:', body)
}
}
修改后(支持两种命令):
// 处理军团信息 - 支持 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个)
-
src/stores/tokenStore.js- 添加
legion_getinforesp支持 - 简化调试日志
- 添加
-
src/utils/xyzwWebSocket.js- 移除临时调试日志
-
src/components/ClubInfo.vue- 移除调试日志和watch监听器
🧪 测试验证
预期结果
- ✅ 刷新页面后,俱乐部信息自动加载
- ✅ 控制台显示
🏛️ [俱乐部] 军团信息已更新 - ✅ ClubInfo 组件显示俱乐部名称、成员、战力等
- ✅ 点击"刷新"按钮,数据正常更新
- ✅ 成员列表显示前20名(按战力排序)
- ✅ 盐场战绩 Tab 正常工作
控制台日志示例
📤 发送消息: legion_getinfo {}
✅ ProtoMsg Blob消息,使用rawData: {info: {...}, ...}
🏛️ [俱乐部] 军团信息已更新: {info: {id: 7374193, name: '悦耳养鸟场', ...}, ...}
💡 经验总结
1. 响应命令名可能与请求不同
很多游戏服务器会在响应命令后添加 resp 或 Resp 后缀:
role_getroleinfo→role_getroleinforesplegion_getinfo→legion_getinforespactivity_get→activity_getresp
解决方案:在 handleGameMessage 中使用 || 同时支持两种命令名。
2. ProtoMsg 的 packet 结构
ProtoMsg {
_raw: {...}, // 原始数据
_rawData: {...}, // 未解码数据
rawData: {...}, // 已解码数据(优先使用)
cmd: '...' // 命令名(可能在这里)
}
获取 cmd 的优先级:
const cmd = message.cmd || message._raw?.cmd || message.rawData?.cmd
3. 调试技巧
当怀疑消息未被处理时:
- 在 WebSocket 消息接收处打印完整 packet 结构
- 在 messageListener 中打印 message.cmd
- 在 handleGameMessage 中打印识别到的 cmd
- 对比请求命令名和响应命令名
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 函数:
const normalizeCmd = (cmd) => {
// 移除 resp 后缀
return cmd.replace(/resp$/i, '')
}
2. 添加俱乐部日志控制开关
类似月度任务,添加 clubInfo 日志开关:
// 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
状态:✅ 完成并验证通过
🎊 俱乐部信息功能现已完全正常!请刷新页面体验! 🚀