Files
xyzw_web_helper/MD说明文件夹/俱乐部信息修复完成v2.1.1.md
2025-10-17 20:56:50 +08:00

6.6 KiB
Raw Blame History

俱乐部信息修复完成 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

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个

  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. 响应命令名可能与请求不同

很多游戏服务器会在响应命令后添加 respResp 后缀:

  • role_getroleinforole_getroleinforesp
  • legion_getinfolegion_getinforesp
  • activity_getactivity_getresp

解决方案:在 handleGameMessage 中使用 || 同时支持两种命令名。

2. ProtoMsg 的 packet 结构

ProtoMsg {
  _raw: {...},        // 原始数据
  _rawData: {...},    // 未解码数据
  rawData: {...},     // 已解码数据(优先使用)
  cmd: '...'          // 命令名(可能在这里)
}

获取 cmd 的优先级

const cmd = message.cmd || message._raw?.cmd || message.rawData?.cmd

3. 调试技巧

当怀疑消息未被处理时:

  1. 在 WebSocket 消息接收处打印完整 packet 结构
  2. 在 messageListener 中打印 message.cmd
  3. 在 handleGameMessage 中打印识别到的 cmd
  4. 对比请求命令名和响应命令名

4. 月度任务的类似问题

之前月度任务也遇到相同问题:

  • activity_getactivity_getresp
  • 解决方案:在 xyzwWebSocket.jsresponseToCommandMap 中添加映射

两种解决方案对比

方案 适用场景 优点 缺点
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
状态 完成并验证通过

🎊 俱乐部信息功能现已完全正常!请刷新页面体验! 🚀