433 lines
10 KiB
Markdown
433 lines
10 KiB
Markdown
|
|
# 问题修复:批量发车添加账号激活逻辑 v3.9.8
|
|||
|
|
|
|||
|
|
## 🚀 概述
|
|||
|
|
|
|||
|
|
**问题**:
|
|||
|
|
- v3.9.7 修改后,统计准确了 ✅
|
|||
|
|
- 但服务器**完全不响应** `car_getrolecar` 命令 ❌
|
|||
|
|
- 所有6个账号都超时(20秒)
|
|||
|
|
|
|||
|
|
**根本原因**:
|
|||
|
|
- 批量自动化连接后直接查询车辆
|
|||
|
|
- 服务器需要先"激活"账号状态,才会响应游戏命令
|
|||
|
|
- 缺少初始化步骤
|
|||
|
|
|
|||
|
|
**解决方案**:
|
|||
|
|
- 在查询车辆前先获取角色信息(`role_getroleinfo`)
|
|||
|
|
- 模拟正常游戏流程
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 问题分析
|
|||
|
|
|
|||
|
|
### v3.9.7 的问题(统计正确,但查询失败)
|
|||
|
|
|
|||
|
|
**批量自动化流程**:
|
|||
|
|
```
|
|||
|
|
1. WebSocket连接成功 ✅
|
|||
|
|
2. 等待2秒 ✅
|
|||
|
|
3. 📤 发送消息: car_getrolecar {} ← 发送了
|
|||
|
|
4. 💓 发送心跳消息 ← 心跳正常
|
|||
|
|
5. 💓 发送心跳消息 ← 继续心跳
|
|||
|
|
6. 💓 发送心跳消息 ← 还是心跳
|
|||
|
|
7. ❌ 20秒后超时 ← 没有收到 car_getrolecarresp!
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**服务器行为**:
|
|||
|
|
- ✅ WebSocket连接正常
|
|||
|
|
- ✅ 心跳消息正常收发
|
|||
|
|
- ❌ **完全忽略** `car_getrolecar` 命令
|
|||
|
|
- ❌ **不返回任何响应**(既不是成功也不是错误)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 游戏功能模块为什么成功?
|
|||
|
|
|
|||
|
|
**游戏功能模块的流程**:
|
|||
|
|
```
|
|||
|
|
1. WebSocket连接成功 ✅
|
|||
|
|
2. 用户在页面上点击"查询车辆"
|
|||
|
|
3. 此时账号可能已经在其他页面获取过角色信息
|
|||
|
|
4. 📤 发送消息: car_getrolecar {}
|
|||
|
|
5. 📨 [token_xxx] car_getrolecarresp ← 立即收到响应!
|
|||
|
|
6. ✅ 查询到 4 辆车
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键差异**:
|
|||
|
|
- 游戏功能模块的账号通常已经"激活"过
|
|||
|
|
- 批量自动化是新连接,直接查询
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 正常游戏的初始化流程
|
|||
|
|
|
|||
|
|
**观察正常游戏行为**:
|
|||
|
|
```
|
|||
|
|
1. WebSocket连接成功
|
|||
|
|
2. 📤 发送消息: role_getroleinfo {} ← 获取角色信息(账号"激活")
|
|||
|
|
3. 📨 role_getroleinforesp ← 服务器响应
|
|||
|
|
4. 之后所有游戏命令都能正常响应
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**服务器逻辑推测**:
|
|||
|
|
```javascript
|
|||
|
|
// 服务器端伪代码
|
|||
|
|
if (!session.isActivated) {
|
|||
|
|
// 账号未激活,忽略游戏命令
|
|||
|
|
if (cmd !== 'role_getroleinfo') {
|
|||
|
|
return; // 不响应
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 账号已激活,正常处理游戏命令
|
|||
|
|
handleGameCommand(cmd, params);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🛠️ 解决方案 v3.9.8
|
|||
|
|
|
|||
|
|
### 核心改进:模拟正常游戏流程
|
|||
|
|
|
|||
|
|
**在查询车辆前,先获取角色信息来激活账号**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 修改详情
|
|||
|
|
|
|||
|
|
**位置**:`src/stores/batchTaskStore.js` 第1149-1164行
|
|||
|
|
|
|||
|
|
#### 修改前(v3.9.7)
|
|||
|
|
```javascript
|
|||
|
|
try {
|
|||
|
|
// 第1步:查询车辆
|
|||
|
|
console.log(`🚗 [${tokenId}] 开始查询俱乐部车辆...`)
|
|||
|
|
const queryResponse = await tokenStore.sendMessageAsync(
|
|||
|
|
tokenId,
|
|||
|
|
'car_getrolecar',
|
|||
|
|
{},
|
|||
|
|
20000
|
|||
|
|
)
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**问题**:
|
|||
|
|
- ❌ 连接后直接查询车辆
|
|||
|
|
- ❌ 账号未激活
|
|||
|
|
- ❌ 服务器不响应
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 修改后(v3.9.8)
|
|||
|
|
```javascript
|
|||
|
|
try {
|
|||
|
|
// 第0步:先获取角色信息(激活账号)
|
|||
|
|
console.log(`👤 [${tokenId}] 获取角色信息(激活账号)...`)
|
|||
|
|
try {
|
|||
|
|
await tokenStore.sendMessageAsync(tokenId, 'role_getroleinfo', {}, 5000)
|
|||
|
|
console.log(`✅ [${tokenId}] 角色信息获取成功`)
|
|||
|
|
} catch (error) {
|
|||
|
|
console.warn(`⚠️ [${tokenId}] 角色信息获取失败: ${error.message},继续尝试查询车辆`)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 等待一下,让服务器处理
|
|||
|
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
|||
|
|
|
|||
|
|
// 第1步:查询车辆
|
|||
|
|
console.log(`🚗 [${tokenId}] 开始查询俱乐部车辆...`)
|
|||
|
|
const queryResponse = await tokenStore.sendMessageAsync(
|
|||
|
|
tokenId,
|
|||
|
|
'car_getrolecar',
|
|||
|
|
{},
|
|||
|
|
20000
|
|||
|
|
)
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**改进**:
|
|||
|
|
- ✅ 先获取角色信息(激活账号)
|
|||
|
|
- ✅ 使用 try-catch 包裹,即使获取失败也继续
|
|||
|
|
- ✅ 等待1秒让服务器处理
|
|||
|
|
- ✅ 然后再查询车辆
|
|||
|
|
- ✅ 模拟正常游戏流程
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ 优势
|
|||
|
|
|
|||
|
|
### 1. 模拟正常游戏流程
|
|||
|
|
- ✅ 先获取角色信息,激活账号状态
|
|||
|
|
- ✅ 然后再执行游戏命令
|
|||
|
|
- ✅ 符合服务器的预期行为
|
|||
|
|
|
|||
|
|
### 2. 容错性强
|
|||
|
|
- ✅ 角色信息获取失败也不会中断流程
|
|||
|
|
- ✅ 只是警告,然后继续尝试查询车辆
|
|||
|
|
- ✅ 最大程度保证任务执行
|
|||
|
|
|
|||
|
|
### 3. 适度延迟
|
|||
|
|
- ✅ 只增加1秒延迟(等待服务器处理)
|
|||
|
|
- ✅ 不会显著影响整体执行速度
|
|||
|
|
- ✅ 角色信息获取本身也很快(< 1秒)
|
|||
|
|
|
|||
|
|
### 4. 易于调试
|
|||
|
|
- ✅ 清晰的日志输出
|
|||
|
|
- ✅ 可以看到账号激活是否成功
|
|||
|
|
- ✅ 便于排查问题
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 预期效果
|
|||
|
|
|
|||
|
|
### v3.9.7(修改前)
|
|||
|
|
```
|
|||
|
|
✅ WebSocket连接成功
|
|||
|
|
⏳ 等待连接稳定... (2秒)
|
|||
|
|
📤 发送消息: car_getrolecar {}
|
|||
|
|
💓 心跳消息... (不断收发)
|
|||
|
|
❌ 20秒后超时,服务器完全不响应
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**问题**:服务器忽略 `car_getrolecar` 命令
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### v3.9.8(修改后)
|
|||
|
|
```
|
|||
|
|
✅ WebSocket连接成功
|
|||
|
|
⏳ 等待连接稳定... (2秒)
|
|||
|
|
👤 获取角色信息(激活账号)...
|
|||
|
|
📤 发送消息: role_getroleinfo {}
|
|||
|
|
📨 role_getroleinforesp ← 服务器响应
|
|||
|
|
✅ 角色信息获取成功
|
|||
|
|
⏳ 等待1秒让服务器处理...
|
|||
|
|
📤 发送消息: car_getrolecar {}
|
|||
|
|
📨 car_getrolecarresp ← 服务器响应!
|
|||
|
|
✅ 查询到 4 辆车 ← 预期快速成功!
|
|||
|
|
🔄 开始批量刷新车辆...
|
|||
|
|
✅ 刷新车辆成功
|
|||
|
|
🎁 开始批量收获...
|
|||
|
|
✅ 收获车辆成功
|
|||
|
|
🚀 开始批量发送...
|
|||
|
|
✅ 发送车辆成功
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**改进**:
|
|||
|
|
- ✅ 服务器正常响应 `car_getrolecar`
|
|||
|
|
- ✅ 查询车辆快速成功(1-2秒)
|
|||
|
|
- ✅ 整体流程顺畅可靠
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧪 验证步骤
|
|||
|
|
|
|||
|
|
### 1. 清除浏览器缓存
|
|||
|
|
```
|
|||
|
|
F12 → Application → Storage → Clear site data
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**原因**:确保使用新的代码逻辑
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. 重启开发服务器
|
|||
|
|
```bash
|
|||
|
|
# Ctrl+C 停止
|
|||
|
|
# 然后重新启动
|
|||
|
|
npm run dev
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. 批量测试
|
|||
|
|
1. 打开批量自动化面板
|
|||
|
|
2. 选择**2-6个账号**
|
|||
|
|
3. 只勾选**"发车"**任务
|
|||
|
|
4. 点击"开始执行"
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 4. 观察日志
|
|||
|
|
|
|||
|
|
#### 期望结果(成功✅)
|
|||
|
|
```
|
|||
|
|
🎯 开始执行 Token: 805服-0-xxx
|
|||
|
|
✅ WebSocket连接成功
|
|||
|
|
⏳ 等待连接稳定...
|
|||
|
|
📌 执行任务 [1/1]: sendCar
|
|||
|
|
|
|||
|
|
👤 [token_xxx] 获取角色信息(激活账号)... ← 新增步骤
|
|||
|
|
✅ [token_xxx] 角色信息获取成功 ← 新增日志
|
|||
|
|
|
|||
|
|
🚗 [token_xxx] 开始查询俱乐部车辆...
|
|||
|
|
✅ [token_xxx] 查询到 4 辆车 ← 应该1-2秒内完成!
|
|||
|
|
|
|||
|
|
🔄 [token_xxx] 开始批量刷新车辆(1次)...
|
|||
|
|
✅ [token_xxx] 刷新车辆成功: carId
|
|||
|
|
|
|||
|
|
🎁 [token_xxx] 开始批量收获...
|
|||
|
|
✅ [token_xxx] 收获车辆成功: carId
|
|||
|
|
|
|||
|
|
🚀 [token_xxx] 开始批量发送...
|
|||
|
|
✅ [token_xxx] 发送车辆成功: carId
|
|||
|
|
|
|||
|
|
✅ Token完成: 805服-0-xxx
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键指标**:
|
|||
|
|
- ✅ 看到"获取角色信息(激活账号)"日志
|
|||
|
|
- ✅ 看到"角色信息获取成功"日志
|
|||
|
|
- ✅ 查询车辆应该在1-2秒内完成(而不是20秒超时)
|
|||
|
|
- ✅ 整体流程顺畅
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 如果仍然失败(unlikely)
|
|||
|
|
|
|||
|
|
**日志模式**:
|
|||
|
|
```
|
|||
|
|
👤 [token_xxx] 获取角色信息(激活账号)...
|
|||
|
|
⚠️ [token_xxx] 角色信息获取失败: 请求超时: role_getroleinfo (5000ms),继续尝试查询车辆
|
|||
|
|
🚗 [token_xxx] 开始查询俱乐部车辆...
|
|||
|
|
❌ 20秒后超时
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**说明**:
|
|||
|
|
- 即使角色信息获取失败了,也会尝试查询车辆
|
|||
|
|
- 如果查询车辆还是超时,说明问题更复杂
|
|||
|
|
|
|||
|
|
**可能原因**:
|
|||
|
|
1. 服务器端限制更严格(需要更多初始化命令)
|
|||
|
|
2. 反批量检测(需要增加账号间隔)
|
|||
|
|
3. 账号未加入俱乐部(这是之前的结论)
|
|||
|
|
|
|||
|
|
**下一步方案**:
|
|||
|
|
- 增加更多初始化命令(如获取队伍信息、背包信息等)
|
|||
|
|
- 增加账号间隔(3秒 → 10秒)
|
|||
|
|
- 降低并发(6 → 1)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 文件修改清单
|
|||
|
|
|
|||
|
|
### 修改文件
|
|||
|
|
1. ✅ `src/stores/batchTaskStore.js`
|
|||
|
|
- 第1150-1160行:添加账号激活逻辑
|
|||
|
|
|
|||
|
|
### 新增文档
|
|||
|
|
1. ✅ `MD说明/问题修复-批量发车激活账号v3.9.8.md` - 本文档
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔄 版本信息
|
|||
|
|
|
|||
|
|
- **版本号**:v3.9.8
|
|||
|
|
- **修复日期**:2025-10-08
|
|||
|
|
- **影响范围**:批量自动化 - 发车任务
|
|||
|
|
- **向后兼容**:✅ 完全兼容
|
|||
|
|
- **破坏性变更**:❌ 无
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 技术要点
|
|||
|
|
|
|||
|
|
### 为什么服务器需要账号激活?
|
|||
|
|
|
|||
|
|
**服务器端状态管理**:
|
|||
|
|
```javascript
|
|||
|
|
// 服务器端伪代码
|
|||
|
|
class GameSession {
|
|||
|
|
constructor(websocket) {
|
|||
|
|
this.ws = websocket;
|
|||
|
|
this.isActivated = false; // 初始未激活
|
|||
|
|
this.roleInfo = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
handleCommand(cmd, params) {
|
|||
|
|
// 心跳消息总是处理
|
|||
|
|
if (cmd === 'heart_beat') {
|
|||
|
|
return this.sendHeartbeatResponse();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 角色信息请求可以激活账号
|
|||
|
|
if (cmd === 'role_getroleinfo') {
|
|||
|
|
this.roleInfo = this.loadRoleInfo();
|
|||
|
|
this.isActivated = true; // 激活账号
|
|||
|
|
return this.sendRoleInfoResponse();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 其他游戏命令需要账号已激活
|
|||
|
|
if (!this.isActivated) {
|
|||
|
|
console.log(`忽略命令 ${cmd}:账号未激活`);
|
|||
|
|
return; // 不响应,不报错,直接忽略
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 正常处理游戏命令
|
|||
|
|
this.handleGameCommand(cmd, params);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**设计目的**:
|
|||
|
|
1. **安全性**:防止未认证的连接执行游戏命令
|
|||
|
|
2. **状态一致性**:确保服务器加载了完整的角色数据
|
|||
|
|
3. **反作弊**:检测异常连接行为
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 为什么游戏功能模块不需要这个逻辑?
|
|||
|
|
|
|||
|
|
**原因**:
|
|||
|
|
1. 用户通常在多个页面之间切换
|
|||
|
|
2. 账号可能已经在其他页面获取过角色信息
|
|||
|
|
3. WebSocket连接可能是复用的
|
|||
|
|
4. 即使是新连接,用户也会先浏览其他功能(如队伍、背包等)
|
|||
|
|
5. 这些操作会自动触发角色信息获取
|
|||
|
|
|
|||
|
|
**批量自动化的特殊性**:
|
|||
|
|
1. 完全自动化,没有用户交互
|
|||
|
|
2. 每次都是新连接
|
|||
|
|
3. 直接执行特定命令
|
|||
|
|
4. 更像"机器人"行为
|
|||
|
|
|
|||
|
|
**解决方案**:
|
|||
|
|
- 模拟正常游戏流程
|
|||
|
|
- 先获取角色信息,激活账号
|
|||
|
|
- 然后再执行游戏命令
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 总结
|
|||
|
|
|
|||
|
|
### 问题本质
|
|||
|
|
- **批量自动化连接后直接查询车辆**
|
|||
|
|
- **服务器需要先激活账号状态**
|
|||
|
|
- **缺少初始化步骤,导致命令被忽略**
|
|||
|
|
|
|||
|
|
### 解决方案
|
|||
|
|
- **在查询车辆前先获取角色信息**
|
|||
|
|
- **模拟正常游戏流程**
|
|||
|
|
- **让服务器"激活"账号状态**
|
|||
|
|
|
|||
|
|
### 预期结果
|
|||
|
|
- ✅ 服务器正常响应 `car_getrolecar` 命令
|
|||
|
|
- ✅ 查询车辆快速成功(1-2秒)
|
|||
|
|
- ✅ 批量发车功能完美运行
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 下一步
|
|||
|
|
|
|||
|
|
1. **清除浏览器缓存**
|
|||
|
|
2. **重启开发服务器**
|
|||
|
|
3. **批量测试2-6个账号**
|
|||
|
|
4. **观察日志,确认账号激活成功**
|
|||
|
|
5. **验证查询车辆是否快速响应**
|
|||
|
|
|
|||
|
|
如果测试成功,说明问题已完美解决!🎉
|
|||
|
|
|
|||
|
|
如果仍然失败,我们有后备方案(增加更多初始化命令或增加延迟)。
|
|||
|
|
|