20 KiB
20 KiB
批量自动化 - 一键补差详细流程
📋 流程概览
任务名称: 一键补差 (dailyFix)
总步骤数: 25个步骤(包含诊断)
子操作数: 约70+个
预计执行时间: 60-90秒/角色
统一超时: 1000ms(1秒)
操作间隔: 200ms(0.2秒)
🔍 完整执行流程
⚙️ 准备阶段
步骤0:初始化任务状态
dailyTaskStateStore.initTokenTaskState(tokenId)
- 说明: 初始化本地任务跟踪状态
- 用途: 记录哪些消耗资源的任务已完成,避免重复执行
步骤0.1:获取执行前任务状态 🆕
await client.sendWithPromise('role_getroleinfo', {}, 1000)
- 指令:
role_getroleinfo - 参数:
{} - 超时: 1000ms
- 用途: 获取当前角色的每日任务完成状态
- 输出: 控制台显示
📊 执行前任务状态: { "1": 0, "2": -1, ... } - 延迟: 200ms
📝 第一阶段:基础日常任务(1-11)
步骤1:分享游戏
await client.sendWithPromise('system_mysharecallback', {
isSkipShareCard: true,
type: 2
}, 1000)
- 指令:
system_mysharecallback - 参数:
{ isSkipShareCard: true, type: 2 } - 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
- 错误处理: 失败不中断,继续执行
步骤2:赠送好友金币
await client.sendWithPromise('friend_batch', {}, 1000)
- 指令:
friend_batch - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
步骤3:免费招募
await client.sendWithPromise('hero_recruit', {
recruitType: 3,
recruitNumber: 1
}, 1000)
- 指令:
hero_recruit - 参数:
{ recruitType: 3, recruitNumber: 1 }recruitType: 3= 免费招募recruitNumber: 1= 招募1次
- 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
步骤4:付费招募 ⚠️
await executeSubTask(tokenId, 'paid_recruit', '付费招募',
async () => await client.sendWithPromise('hero_recruit', {
recruitType: 1,
recruitNumber: 1
}, 1000),
true // 消耗资源
)
- 指令:
hero_recruit - 参数:
{ recruitType: 1, recruitNumber: 1 }recruitType: 1= 付费招募recruitNumber: 1= 招募1次
- 超时: 1000ms
- 消耗资源: ✅ 是(会被跟踪)
- 跳过逻辑: 如果今天已完成,自动跳过
- 延迟: 200ms(未跳过时)
步骤5:免费点金(3次)⚠️
// 循环3次
for (let i = 0; i < 3; i++) {
await executeSubTask(tokenId, `buy_gold_${i+1}`, `免费点金 ${i+1}/3`,
async () => await client.sendWithPromise('system_buygold', { buyNum: 1 }, 1000),
true // 消耗资源
)
}
- 指令:
system_buygold× 3 - 参数:
{ buyNum: 1 } - 超时: 1000ms
- 消耗资源: ✅ 是(每次都会被跟踪)
- 跳过逻辑: 每次独立判断,已完成的会跳过
- 子任务:
- 免费点金 1/3 (
buy_gold_1) - 免费点金 2/3 (
buy_gold_2) - 免费点金 3/3 (
buy_gold_3)
- 免费点金 1/3 (
- 延迟: 每次200ms(未跳过时)
步骤6:开启木质宝箱×10 ⚠️
await executeSubTask(tokenId, 'open_box', '开启木质宝箱×10',
async () => await client.sendWithPromise('item_openbox', {
itemId: 2001,
number: 10
}, 1000),
true // 消耗资源
)
- 指令:
item_openbox - 参数:
{ itemId: 2001, number: 10 }itemId: 2001= 木质宝箱number: 10= 开启10个
- 超时: 1000ms
- 消耗资源: ✅ 是
- 跳过逻辑: 如果今天已完成,自动跳过
- 延迟: 200ms(未跳过时)
步骤7:福利签到
await client.sendWithPromise('system_signinreward', {}, 1000)
- 指令:
system_signinreward - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
步骤8:领取每日礼包
await client.sendWithPromise('discount_claimreward', {}, 1000)
- 指令:
discount_claimreward - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
步骤9:领取免费礼包
await client.sendWithPromise('card_claimreward', {}, 1000)
- 指令:
card_claimreward - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
步骤10:领取永久卡礼包
await client.sendWithPromise('card_claimreward', { cardId: 4003 }, 1000)
- 指令:
card_claimreward - 参数:
{ cardId: 4003 }cardId: 4003= 永久卡
- 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
步骤11:领取邮件奖励
await client.sendWithPromise('mail_claimallattachment', { category: 0 }, 1000)
- 指令:
mail_claimallattachment - 参数:
{ category: 0 }category: 0= 所有类别
- 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
🎣 第二阶段:免费活动(12-14)
步骤12:免费钓鱼(3次)⚠️
// 循环3次
for (let i = 0; i < 3; i++) {
await executeSubTask(tokenId, `fish_${i+1}`, `免费钓鱼 ${i+1}/3`,
async () => await client.sendWithPromise('artifact_lottery', {
lotteryNumber: 1,
newFree: true,
type: 1
}, 1000),
true // 消耗资源
)
}
- 指令:
artifact_lottery× 3 - 参数:
{ lotteryNumber: 1, newFree: true, type: 1 }lotteryNumber: 1= 钓鱼1次newFree: true= 使用免费次数type: 1= 普通钓鱼
- 超时: 1000ms
- 消耗资源: ✅ 是(每次都会被跟踪)
- 跳过逻辑: 每次独立判断
- 子任务:
- 免费钓鱼 1/3 (
fish_1) - 免费钓鱼 2/3 (
fish_2) - 免费钓鱼 3/3 (
fish_3)
- 免费钓鱼 1/3 (
- 延迟: 每次200ms(未跳过时)
步骤13:灯神免费扫荡(4个国家)
// 循环4个国家
const kingdoms = ['魏国', '蜀国', '吴国', '群雄']
for (let gid = 1; gid <= 4; gid++) {
await client.sendWithPromise('genie_sweep', { genieId: gid }, 1000)
}
- 指令:
genie_sweep× 4 - 参数:
{ genieId: 1/2/3/4 }genieId: 1= 魏国genieId: 2= 蜀国genieId: 3= 吴国genieId: 4= 群雄
- 超时: 1000ms
- 消耗资源: ❌ 否
- 子任务:
- 魏国灯神免费扫荡
- 蜀国灯神免费扫荡
- 吴国灯神免费扫荡
- 群雄灯神免费扫荡
- 延迟: 每次200ms
步骤14:领取免费扫荡卷(3次)
// 循环3次
for (let i = 0; i < 3; i++) {
await client.sendWithPromise('genie_buysweep', {}, 1000)
}
- 指令:
genie_buysweep× 3 - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 子任务:
- 领取免费扫荡卷 1/3
- 领取免费扫荡卷 2/3
- 领取免费扫荡卷 3/3
- 延迟: 每次200ms
🛒 第三阶段:购买和战斗(15-18)
步骤15:黑市一键采购 ⚠️
await executeSubTask(tokenId, 'black_market', '黑市一键采购',
async () => await client.sendWithPromise('store_purchase', { goodsId: 1 }, 1000),
true // 消耗资源
)
- 指令:
store_purchase - 参数:
{ goodsId: 1 }goodsId: 1= 第一个商品(通常是黑市刷新的商品)
- 超时: 1000ms
- 消耗资源: ✅ 是
- 跳过逻辑: 如果今天已完成,自动跳过
- 延迟: 200ms(未跳过时)
步骤16:竞技场战斗(3次,用阵容1)⚠️
// 1. 切换到阵容1
await switchToFormation(client, 1)
// 2. 开始竞技场
await client.sendWithPromise('arena_startarea', {}, 1000)
// 3. 进行3场战斗
for (let i = 1; i <= 3; i++) {
await executeSubTask(tokenId, `arena_${i}`, `竞技场战斗 ${i}/3`,
async () => {
// 获取目标
const targets = await client.sendWithPromise('arena_getareatarget', {
refresh: false
}, 1000)
const targetId = targets?.roleList?.[0]?.roleId
if (!targetId) throw new Error('未找到目标')
// 开始战斗
await client.sendWithPromise('fight_startareaarena', { targetId }, 1000)
return { targetId }
},
true // 消耗资源
)
}
- 前置操作: 切换到阵容1
- 指令序列:
role_setformation(切换阵容)arena_startarea(开始竞技场)arena_getareatarget× 3 (获取目标)fight_startareaarena× 3 (开始战斗)
- 超时: 每个操作1000ms
- 消耗资源: ✅ 是(每场战斗独立跟踪)
- 跳过逻辑: 每场战斗独立判断
- 子任务:
- 竞技场战斗 1/3 (
arena_1) - 竞技场战斗 2/3 (
arena_2) - 竞技场战斗 3/3 (
arena_3)
- 竞技场战斗 1/3 (
- 延迟: 每次200ms(未跳过时)
步骤17:军团BOSS(用阵容1)
// 1. 切换到阵容1
await switchToFormation(client, 1)
// 2. 打军团BOSS
await client.sendWithPromise('fight_startlegionboss', {}, 1000)
- 前置操作: 切换到阵容1
- 指令:
fight_startlegionboss - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 延迟: 200ms
步骤18:每日BOSS/咸王考验(3次,用阵容1)
// 1. 切换到阵容1
await switchToFormation(client, 1)
// 2. 获取今日BOSS ID
const todayBossId = getTodayBossId() // 根据星期几确定BOSS ID
// 3. 进行3场战斗
for (let i = 1; i <= 3; i++) {
await client.sendWithPromise('fight_startboss', { bossId: todayBossId }, 1000)
}
- 前置操作: 切换到阵容1,获取今日BOSS ID
- 指令:
fight_startboss× 3 - 参数:
{ bossId: todayBossId }todayBossId根据星期几自动计算
- 超时: 1000ms
- 消耗资源: ❌ 否
- 子任务:
- 每日BOSS 1/3
- 每日BOSS 2/3
- 每日BOSS 3/3
- 延迟: 每次200ms
🤖 第四阶段:盐罐机器人(19)
步骤19:重启盐罐机器人服务
步骤19.1:停止盐罐机器人
await client.sendWithPromise('bottlehelper_stop', { bottleType: -1 }, 1000)
- 指令:
bottlehelper_stop - 参数:
{ bottleType: -1 }bottleType: -1= 全部类型
- 超时: 1000ms
- 错误处理: 如果机器人未启动,跳过此步骤(不影响后续流程)
- 延迟: 500ms
步骤19.2:启动盐罐机器人
await client.sendWithPromise('bottlehelper_start', { bottleType: -1 }, 1000)
- 指令:
bottlehelper_start - 参数:
{ bottleType: -1 }bottleType: -1= 全部类型
- 超时: 1000ms
- 延迟: 500ms
步骤19.3:领取盐罐奖励
await client.sendWithPromise('bottlehelper_claim', {}, 1000)
- 指令:
bottlehelper_claim - 参数:
{} - 超时: 1000ms
- 延迟: 200ms
🎁 第五阶段:领取奖励(20-22)
步骤20:领取任务奖励(1-10)
重要:等待服务器状态更新
console.log('⏳ 等待服务器更新任务状态(1秒)...')
await new Promise(resolve => setTimeout(resolve, 1000))
- 延迟: 1000ms
- 原因:
- 完成任务和领取奖励是两个独立操作
- 服务器需要时间同步任务完成状态
- 如果不等待,可能出现"任务已完成但领取失败"
- 第二次运行才能成功
领取任务奖励1-10
// 循环10次
for (let taskId = 1; taskId <= 10; taskId++) {
await client.sendWithPromise('task_claimdailypoint', { taskId }, 1000)
}
- 指令:
task_claimdailypoint× 10 - 参数:
{ taskId: 1~10 } - 超时: 1000ms
- 消耗资源: ❌ 否
- 子任务:
- 领取任务奖励1
- 领取任务奖励2
- 领取任务奖励3
- 领取任务奖励4
- 领取任务奖励5
- 领取任务奖励6
- 领取任务奖励7
- 领取任务奖励8
- 领取任务奖励9
- 领取任务奖励10
- 延迟: 每次200ms
步骤21:领取日常任务奖励
await client.sendWithPromise('task_claimdailyreward', {}, 1000)
- 指令:
task_claimdailyreward - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 说明: 领取每日任务的总积分奖励
- 延迟: 200ms
步骤22:领取周常任务奖励
await client.sendWithPromise('task_claimweekreward', {}, 1000)
- 指令:
task_claimweekreward - 参数:
{} - 超时: 1000ms
- 消耗资源: ❌ 否
- 说明: 领取周常任务的总积分奖励
- 延迟: 200ms
📊 诊断阶段 🆕
步骤23:获取执行后任务状态
await client.sendWithPromise('role_getroleinfo', {}, 1000)
- 指令:
role_getroleinfo - 参数:
{} - 超时: 1000ms
- 用途: 获取执行后的每日任务完成状态
- 输出: 控制台显示
📊 执行后任务状态: { "1": -1, "2": -1, ... }
步骤24:对比任务状态变化
// 对比执行前后的状态
for (const taskId of allTaskIds) {
const before = beforeTaskStatus[taskId] || 0
const after = afterTaskStatus[taskId] || 0
const changed = before !== after
if (changed) {
console.log(`任务${taskId}: ${before} → ${after} ✅`)
} else {
console.log(`任务${taskId}: ${after} (无变化)`)
}
}
- 输出: 控制台显示任务状态对比分析
- 包含信息:
- 哪些任务从"未完成"变为"已完成"
- 哪些任务执行前后都是"未完成"(问题任务)
- 统计信息:已完成数/总任务数,本次改变数
步骤25:生成统计报告
const completedCount = Object.values(afterTaskStatus).filter(v => v === -1).length
const totalCount = Object.keys(afterTaskStatus).length
const changedCount = taskStatusComparison.filter(t => t.changed).length
console.log(`📊 统计: 已完成 ${completedCount}/${totalCount},本次改变 ${changedCount} 个任务`)
- 输出: 最终统计信息
- 返回: 将诊断结果添加到返回数据中
📊 统计信息
执行时间分析
| 阶段 | 操作数 | 预计时间 |
|---|---|---|
| 准备阶段 | 2 | 2秒 |
| 基础日常 (1-11) | 11 | 14秒 |
| 免费活动 (12-14) | 10 | 13秒 |
| 购买战斗 (15-18) | 13 | 17秒 |
| 盐罐机器人 (19) | 3 | 2.2秒 |
| 领取奖励 (20-22) | 12 | 14.4秒 |
| 诊断阶段 (23-25) | 2 | 2秒 |
| 总计 | 53 | 64.6秒 |
实际时间: 60-90秒(考虑网络延迟和服务器响应时间)
资源消耗任务
共有 12个 会消耗资源的任务,执行前会检查是否已完成:
| 序号 | 任务名称 | 任务ID | 可跳过 |
|---|---|---|---|
| 1 | 付费招募 | paid_recruit |
✅ |
| 2 | 免费点金 1/3 | buy_gold_1 |
✅ |
| 3 | 免费点金 2/3 | buy_gold_2 |
✅ |
| 4 | 免费点金 3/3 | buy_gold_3 |
✅ |
| 5 | 开启木质宝箱×10 | open_box |
✅ |
| 6 | 免费钓鱼 1/3 | fish_1 |
✅ |
| 7 | 免费钓鱼 2/3 | fish_2 |
✅ |
| 8 | 免费钓鱼 3/3 | fish_3 |
✅ |
| 9 | 黑市一键采购 | black_market |
✅ |
| 10 | 竞技场战斗 1/3 | arena_1 |
✅ |
| 11 | 竞技场战斗 2/3 | arena_2 |
✅ |
| 12 | 竞技场战斗 3/3 | arena_3 |
✅ |
跳过机制:
- 如果某个任务今天已完成,会自动跳过
- 控制台显示:
⏭️ 跳过已完成的任务: XXX - 避免重复消耗资源
⚙️ 辅助函数
switchToFormation(client, formationId)
async function switchToFormation(client, formationId) {
await client.sendWithPromise('role_setformation', {
formationId: formationId
}, 1000)
}
- 用途: 切换阵容
- 参数:
formationId(1-10) - 超时: 1000ms
- 使用场景: 竞技场战斗、军团BOSS、每日BOSS前
getTodayBossId()
function getTodayBossId() {
const dayOfWeek = new Date().getDay() // 0-6 (周日-周六)
const bossIds = [7, 1, 2, 3, 4, 5, 6] // BOSS ID映射
return bossIds[dayOfWeek]
}
- 用途: 根据星期几获取今日BOSS ID
- 返回: BOSS ID (1-7)
- 映射关系:
- 周日 → BOSS 7
- 周一 → BOSS 1
- 周二 → BOSS 2
- 周三 → BOSS 3
- 周四 → BOSS 4
- 周五 → BOSS 5
- 周六 → BOSS 6
executeSubTask(tokenId, taskId, taskName, executor, consumesResources)
async function executeSubTask(tokenId, taskId, taskName, executor, consumesResources) {
// 1. 检查是否已完成(如果消耗资源)
if (consumesResources && dailyTaskStateStore.isTaskCompleted(tokenId, taskId)) {
console.log(`⏭️ 跳过已完成的任务: ${taskName}`)
return { task: taskName, taskId, skipped: true, success: true, message: '已完成,跳过执行' }
}
// 2. 执行任务
try {
const result = await executor()
dailyTaskStateStore.markTaskCompleted(tokenId, taskId, true, null)
console.log(`✅ ${taskName} - 成功`)
return { task: taskName, taskId, success: true, data: result, skipped: false }
} catch (error) {
dailyTaskStateStore.markTaskFailed(tokenId, taskId, error.message)
console.log(`❌ ${taskName} - 失败: ${error.message}`)
return { task: taskName, taskId, success: false, error: error.message, skipped: false }
}
}
- 用途: 执行单个子任务,支持跳过已完成的资源消耗任务
- 参数:
tokenId: Token IDtaskId: 任务ID(用于跟踪)taskName: 任务名称executor: 执行函数consumesResources: 是否消耗资源
- 返回: 任务执行结果对象
🎯 流程特点
1. 智能跳过机制
- ✅ 自动跳过已完成的资源消耗任务
- ✅ 避免重复浪费金币、宝箱等资源
- ✅ 可以多次运行一键补差,只会执行未完成的任务
2. 错误容错机制
- ✅ 单个任务失败不会中断整体流程
- ✅ 所有错误都会被记录
- ✅ 继续执行后续任务
3. 状态同步延迟
- ✅ 在领取任务奖励前等待1秒
- ✅ 确保服务器状态已同步
- ✅ 提高任务奖励领取成功率
4. 任务状态诊断 🆕
- ✅ 执行前获取任务状态
- ✅ 执行后获取任务状态
- ✅ 自动对比分析
- ✅ 显示哪些任务未完成
- ✅ 帮助定位问题
5. 统一超时设置
- ✅ 所有操作统一1000ms超时
- ✅ 简化配置,易于维护
- ✅ 平衡速度和稳定性
📝 控制台输出示例
正常执行流程
🔍 正在获取执行前的任务完成状态...
📊 执行前任务状态: {
"1": 0,
"2": -1,
"3": 0,
"4": -1,
...
}
📋 一键补差包含以下子任务:
1. 分享游戏
2. 赠送好友金币
...
总计:22大类,约70+个子操作
超时时间:统一1000ms
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 分享游戏 - 成功
✅ 赠送好友金币 - 成功
✅ 免费招募 - 成功
⏭️ 跳过已完成的任务: 付费招募
✅ 免费点金 1/3 - 成功
⏭️ 跳过已完成的任务: 免费点金 2/3
⏭️ 跳过已完成的任务: 免费点金 3/3
...
⏳ 等待服务器更新任务状态(1秒)...
✅ 领取任务奖励1 - 成功
✅ 领取任务奖励2 - 成功
...
🔍 正在获取执行后的任务完成状态...
📊 执行后任务状态: {
"1": -1,
"2": -1,
...
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 每日任务完成状态对比分析
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
任务1: 未完成 → 已完成 ✅ 已完成
任务2: 已完成 (无变化) ✅ 已完成
任务3: 未完成 → 已完成 ✅ 已完成
...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 统计: 已完成 10/10,本次改变 8 个任务
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
出现错误时
✅ 分享游戏 - 成功
❌ 赠送好友金币 - 失败: 好友列表为空
✅ 免费招募 - 成功
...(继续执行后续任务)
🔧 代码位置
文件: src/stores/batchTaskStore.js
函数: executeTask
分支: case 'dailyFix'
行数: 约424-881行
📚 相关文档
- 一键补差完整子任务清单.md - 任务列表概览
- 功能更新-任务状态诊断.md - 诊断功能详解
- 游戏内每日任务ID对应表.md - 任务ID对应关系
- 问题修复-任务奖励领取失败.md - 1秒延迟的原因
- 功能更新-任务状态跟踪.md - 资源跳过机制
文档创建日期: 2025-10-07
版本: v3.3.0
状态: ✅ 最新