@@ -101,7 +102,7 @@
size="small"
/>
-
+
@@ -111,7 +112,7 @@
size="small"
/>
-
+
@@ -121,7 +122,7 @@
size="small"
/>
-
+
@@ -130,35 +131,41 @@
v-model:value="settings.claimBottle"
/>
-
+
领挂机
-
+
竞技场
-
+
开宝箱
-
+
领取邮件奖励
-
+
+ 黑市购买物品
+
+
+
付费招募
-
+
-
-
@@ -223,22 +238,23 @@
任务执行日志
-
+
-
{{ logItem.time }}
-
{{ logItem.message }}
@@ -253,12 +269,13 @@
import { ref, reactive, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useTokenStore } from '@/stores/tokenStore'
import { useMessage } from 'naive-ui'
-import {
- Settings,
+import {
+ Settings,
Calendar,
CheckmarkCircle,
EllipseOutline,
- DocumentText
+ DocumentText,
+ Refresh
} from '@vicons/ionicons5'
const tokenStore = useTokenStore()
@@ -271,7 +288,7 @@ const showLog = ref(false)
const busy = ref(false)
const logContainer = ref(null)
-// 任务设置 - 基于参考代码
+// 任务设置
const settings = reactive({
arenaFormation: 1,
bossFormation: 1,
@@ -281,10 +298,11 @@ const settings = reactive({
openBox: true,
arenaEnable: true,
claimHangUp: true,
- claimEmail: true
+ claimEmail: true,
+ blackMarketPurchase: true
})
-// 每日任务列表 - 基于参考代码
+// 每日任务列表
const tasks = ref([
{ id: 1, name: '登录一次游戏', completed: false, loading: false },
{ id: 2, name: '分享一次游戏', completed: false, loading: false },
@@ -302,7 +320,7 @@ const tasks = ref([
const formationOptions = [1,2,3,4].map(v => ({ label: `阵容${v}`, value: v }))
const bossTimesOptions = [0,1,2,3,4].map(v => ({ label: `${v}次`, value: v }))
-// 计算属性 - 基于参考代码逻辑
+// 计算属性
const roleInfo = computed(() => {
return tokenStore.selectedTokenRoleInfo
})
@@ -311,23 +329,29 @@ const roleDailyPoint = computed(() => {
return roleInfo.value?.role?.dailyTask?.dailyPoint ?? 0
})
-// 进度 - 基于参考代码
const dailyPoint = computed(() => Math.min(roleDailyPoint.value, 100))
const isFull = computed(() => dailyPoint.value >= 100)
const progressColor = computed(() => isFull.value ? '#10b981' : '#3b82f6')
-// 日志系统 - 基于参考代码的log函数
+// WebSocket连接状态
+const isConnected = computed(() => {
+ if (!tokenStore.selectedToken) return false
+ const status = tokenStore.getWebSocketStatus(tokenStore.selectedToken.id)
+ return status === 'connected'
+})
+
+// 日志系统
const logList = ref([])
const LOG_MAX = 500
const log = (message, type = 'info') => {
const time = new Date().toLocaleTimeString()
logList.value.push({ time, message, type })
-
+
if (logList.value.length > LOG_MAX) {
logList.value.splice(0, logList.value.length - LOG_MAX)
}
-
+
nextTick(() => {
if (logContainer.value) {
logContainer.value.scrollTop = logContainer.value.scrollHeight
@@ -335,292 +359,532 @@ const log = (message, type = 'info') => {
})
}
-// 超时执行器 - 使用tokenStore的sendMessageWithPromise
-const callWithRetry = async (fn, opt = {}) => {
- const timeoutMs = opt?.timeoutMs ?? 10000 // 降低超时时间到10秒
- const retries = opt?.retries ?? 1
- const delayMs = opt?.delayMs ?? 600
-
- for (let attempt = 0; attempt <= retries; attempt++) {
- try {
- const r = await Promise.race([
- fn(),
- new Promise((_, rej) => setTimeout(() => rej(new Error(`请求超时(${timeoutMs}ms)`)), timeoutMs))
- ])
- return r
- } catch (err) {
- if (attempt === retries) throw err
- await new Promise(res => setTimeout(res, delayMs * (attempt + 1)))
- }
- }
- throw new Error('unexpected')
-}
-
-// 消息错误处理 - 基于参考代码的onRaw函数
-const onRaw = (evt) => {
- const err = evt?._raw?.error
- if (err) log(String(err), 'error')
-}
-
-// 同步服务器任务完成状态 - 基于参考代码的 syncCompleteFromServer 函数
+// 同步服务器任务完成状态
const syncCompleteFromServer = (resp) => {
- if (!resp?.role?.dailyTask?.complete) return
+ if (!resp?.role?.dailyTask?.complete) {
+ log('角色信息中无任务完成数据', 'warning')
+ return
+ }
+
const complete = resp.role.dailyTask.complete
const isDone = (v) => v === -1
-
+
+ log('开始同步任务完成状态...')
+ log(`服务器返回的任务完成数据: ${JSON.stringify(complete)}`)
+
+ let syncedCount = 0
+ let completedCount = 0
+
+ // 先重置所有任务为未完成,然后根据服务器数据更新
+ tasks.value.forEach(task => {
+ task.completed = false
+ })
+
+ // 同步服务器返回的完成状态
Object.keys(complete).forEach(k => {
const id = Number(k)
const idx = tasks.value.findIndex(t => t.id === id)
- if (idx >= 0) tasks.value[idx].completed = isDone(complete[k])
+
+ if (idx >= 0) {
+ const isCompleted = isDone(complete[k])
+ tasks.value[idx].completed = isCompleted
+ syncedCount++
+
+ if (isCompleted) {
+ completedCount++
+ }
+
+ log(`任务${id} "${tasks.value[idx].name}": ${isCompleted ? '已完成' : '未完成'}`,
+ isCompleted ? 'success' : 'info')
+ } else {
+ log(`服务器返回未知任务ID: ${id} (完成值: ${complete[k]})`, 'warning')
+ }
})
+
+ // 检查本地定义但服务器未返回的任务
+ tasks.value.forEach(task => {
+ if (!(task.id.toString() in complete)) {
+ log(`本地任务${task.id} "${task.name}" 在服务器数据中缺失`, 'warning')
+ }
+ })
+
+ log(`任务状态同步完成: ${completedCount}/${syncedCount} 已完成`)
+ log(`当前进度: ${roleDailyPoint.value}/100`)
}
-// 刷新角色信息 - 使用tokenStore的方法
+// 刷新角色信息
const refreshRoleInfo = async () => {
if (!tokenStore.selectedToken) {
throw new Error('没有选中的Token')
}
+
const tokenId = tokenStore.selectedToken.id
-
+ log('正在获取角色信息...')
+
try {
- // 直接使用sendMessageWithPromise方法
- log('正在获取角色信息...')
-
- // 先检查tokenStore方法是否存在
- if (typeof tokenStore.sendMessageWithPromise !== 'function') {
- throw new Error('sendMessageWithPromise方法不存在')
- }
-
- const response = await tokenStore.sendMessageWithPromise(tokenId, 'role_getroleinfo', {}, 8000)
+ const response = await tokenStore.sendGetRoleInfo(tokenId)
log('角色信息获取成功', 'success')
-
- // 更新gameData以便其他组件使用
+
+ // 同步任务状态
if (response) {
- tokenStore.gameData.roleInfo = response
+ syncCompleteFromServer(response)
}
-
+
return response
} catch (error) {
log(`获取角色信息失败: ${error.message}`, 'error')
- console.error('详细错误信息:', error)
throw error
}
}
-// 一键补差 - 简化测试版本
+// 执行单个游戏指令的封装
+const executeGameCommand = async (tokenId, cmd, params = {}, description = '', timeout = 8000) => {
+ try {
+ if (description) log(`执行: ${description}`)
+
+ const result = await tokenStore.sendMessageWithPromise(tokenId, cmd, params, timeout)
+
+ if (description) log(`${description} - 成功`, 'success')
+ return result
+ } catch (error) {
+ if (description) log(`${description} - 失败: ${error.message}`, 'error')
+ throw error
+ }
+}
+
+// 检查是否今日可用(简化版本)
+const isTodayAvailable = (statisticsTime) => {
+ if (!statisticsTime) return true
+
+ // 如果有时间戳,检查是否为今天
+ const today = new Date().toDateString()
+ const recordDate = new Date(statisticsTime).toDateString()
+
+ return today !== recordDate
+}
+
+// 获取今日BOSS ID
+const getTodayBossId = () => {
+ const DAY_BOSS_MAP = [9904, 9905, 9901, 9902, 9903, 9904, 9905] // 周日~周六
+ const dayOfWeek = new Date().getDay()
+ return DAY_BOSS_MAP[dayOfWeek]
+}
+
+// 智能阵容切换辅助函数
+const switchToFormationIfNeeded = async (tokenId, targetFormation, formationName, logFn) => {
+ try {
+ // 首先尝试从本地缓存获取当前阵容信息
+ const cachedTeamInfo = tokenStore.gameData?.presetTeam?.presetTeamInfo
+ let currentFormation = cachedTeamInfo?.useTeamId
+
+ if (currentFormation) {
+ logFn(`从缓存获取当前阵容: ${currentFormation}`)
+ } else {
+ // 缓存中没有数据,从服务器获取
+ logFn(`缓存中无阵容信息,从服务器获取...`)
+ const teamInfo = await executeGameCommand(tokenId, 'presetteam_getinfo', {}, '获取阵容信息')
+ currentFormation = teamInfo?.presetTeamInfo?.useTeamId
+ logFn(`从服务器获取当前阵容: ${currentFormation}`)
+ }
+
+ if (currentFormation === targetFormation) {
+ logFn(`当前已是${formationName}${targetFormation},无需切换`, 'success')
+ return false // 不需要切换
+ }
+
+ logFn(`当前阵容: ${currentFormation}, 目标阵容: ${targetFormation},开始切换...`)
+ await executeGameCommand(tokenId, 'presetteam_saveteam',
+ { teamId: targetFormation }, `切换到${formationName}${targetFormation}`)
+
+ logFn(`成功切换到${formationName}${targetFormation}`, 'success')
+ return true // 已切换
+ } catch (error) {
+ logFn(`阵容检查失败,直接切换: ${error.message}`, 'warning')
+ // 如果检查失败,还是执行切换操作
+ try {
+ await executeGameCommand(tokenId, 'presetteam_saveteam',
+ { teamId: targetFormation }, `强制切换到${formationName}${targetFormation}`)
+ return true
+ } catch (fallbackError) {
+ logFn(`强制切换也失败: ${fallbackError.message}`, 'error')
+ throw fallbackError
+ }
+ }
+}
+
+// 每日任务执行器
+const executeDailyTasks = async (roleInfoResp, logFn, progressFn) => {
+ const tokenId = tokenStore.selectedToken.id
+ const roleData = roleInfoResp?.role
+
+ if (!roleData) {
+ throw new Error('角色数据不存在')
+ }
+
+ logFn('开始执行每日任务补差')
+
+ // 检查已完成的任务
+ const completedTasks = roleData.dailyTask?.complete ?? {}
+ const isTaskCompleted = (taskId) => completedTasks[taskId] === -1
+
+ // 统计数据
+ const statistics = roleData.statistics ?? {}
+ const statisticsTime = roleData.statisticsTime ?? {}
+
+ // 构建任务列表
+ const taskList = []
+
+ // 1. 基础任务(根据完成状态决定是否执行)
+
+ // 分享游戏 (任务ID: 2)
+ if (!isTaskCompleted(2)) {
+ taskList.push({
+ name: '分享一次游戏',
+ execute: () => executeGameCommand(tokenId, 'system_mysharecallback',
+ { isSkipShareCard: true, type: 2 }, '分享游戏')
+ })
+ }
+
+ // 赠送好友金币 (任务ID: 3)
+ if (!isTaskCompleted(3)) {
+ taskList.push({
+ name: '赠送好友金币',
+ execute: () => executeGameCommand(tokenId, 'friend_batch', {}, '赠送好友金币')
+ })
+ }
+
+ // 招募 (任务ID: 4)
+ if (!isTaskCompleted(4)) {
+ taskList.push({
+ name: '免费招募',
+ execute: () => executeGameCommand(tokenId, 'hero_recruit',
+ { recruitType: 3, recruitNumber: 1 }, '免费招募')
+ })
+
+ if (settings.payRecruit) {
+ taskList.push({
+ name: '付费招募',
+ execute: () => executeGameCommand(tokenId, 'hero_recruit',
+ { recruitType: 1, recruitNumber: 1 }, '付费招募')
+ })
+ }
+ }
+
+ // 点金 (任务ID: 6)
+ if (!isTaskCompleted(6) && isTodayAvailable(statisticsTime['buy:gold'])) {
+ for (let i = 0; i < 3; i++) {
+ taskList.push({
+ name: `免费点金 ${i + 1}/3`,
+ execute: () => executeGameCommand(tokenId, 'system_buygold',
+ { buyNum: 1 }, `免费点金 ${i + 1}`)
+ })
+ }
+ }
+
+ // 挂机奖励 (任务ID: 5)
+ if (!isTaskCompleted(5) && settings.claimHangUp) {
+ // 先加钟4次
+ for (let i = 0; i < 4; i++) {
+ taskList.push({
+ name: `挂机加钟 ${i + 1}/4`,
+ execute: () => executeGameCommand(tokenId, 'system_mysharecallback',
+ { isSkipShareCard: true, type: 2 }, `挂机加钟 ${i + 1}`)
+ })
+ }
+
+ // 然后领取奖励
+ taskList.push({
+ name: '领取挂机奖励',
+ execute: () => executeGameCommand(tokenId, 'system_claimhangupreward', {}, '领取挂机奖励')
+ })
+
+ // 最后再加1次钟
+ taskList.push({
+ name: '挂机加钟 5/5',
+ execute: () => executeGameCommand(tokenId, 'system_mysharecallback',
+ { isSkipShareCard: true, type: 2 }, '挂机加钟 5')
+ })
+ }
+
+ // 开宝箱 (任务ID: 7)
+ if (!isTaskCompleted(7) && settings.openBox) {
+ taskList.push({
+ name: '开启木质宝箱',
+ execute: () => executeGameCommand(tokenId, 'item_openbox',
+ { itemId: 2001, number: 10 }, '开启木质宝箱10个')
+ })
+ }
+
+ // 盐罐 (任务ID: 14)
+ if (!isTaskCompleted(14) && settings.claimBottle) {
+ taskList.push({
+ name: '领取盐罐奖励',
+ execute: () => executeGameCommand(tokenId, 'bottlehelper_claim', {}, '领取盐罐奖励')
+ })
+ }
+
+ // 2. 竞技场 (任务ID: 13)
+ if (!isTaskCompleted(13) && settings.arenaEnable) {
+ taskList.push({
+ name: '竞技场战斗',
+ execute: async () => {
+ logFn('开始竞技场战斗流程')
+
+ // 智能切换到竞技场阵容
+ await switchToFormationIfNeeded(tokenId, settings.arenaFormation, '竞技场阵容', logFn)
+
+ // 开始竞技场
+ await executeGameCommand(tokenId, 'arena_startarea', {}, '开始竞技场')
+
+ // 进行3场战斗
+ for (let i = 1; i <= 3; i++) {
+ logFn(`竞技场战斗 ${i}/3`)
+
+ // 获取目标
+ const targets = await executeGameCommand(tokenId, 'arena_getareatarget',
+ { refresh: false }, `获取竞技场目标${i}`)
+
+ const targetId = targets?.roleList?.[0]?.roleId
+ if (targetId) {
+ await executeGameCommand(tokenId, 'fight_startareaarena',
+ { targetId }, `竞技场战斗${i}`, 10000)
+ } else {
+ logFn(`竞技场战斗${i} - 未找到目标`, 'warning')
+ }
+
+ // 战斗间隔
+ await new Promise(resolve => setTimeout(resolve, 1000))
+ }
+ }
+ })
+ }
+
+ // 3. BOSS战斗
+ if (settings.bossTimes > 0) {
+ // 军团BOSS
+ const alreadyLegionBoss = statistics['legion:boss'] ?? 0
+ const remainingLegionBoss = Math.max(settings.bossTimes - alreadyLegionBoss, 0)
+
+ if (remainingLegionBoss > 0) {
+ // 为军团BOSS智能切换阵容
+ taskList.push({
+ name: '军团BOSS阵容检查',
+ execute: () => switchToFormationIfNeeded(tokenId, settings.bossFormation, 'BOSS阵容', logFn)
+ })
+
+ for (let i = 0; i < remainingLegionBoss; i++) {
+ taskList.push({
+ name: `军团BOSS ${i + 1}/${remainingLegionBoss}`,
+ execute: () => executeGameCommand(tokenId, 'fight_startlegionboss', {}, `军团BOSS ${i + 1}`, 12000)
+ })
+ }
+ }
+
+ // 每日BOSS
+ const todayBossId = getTodayBossId()
+ if (remainingLegionBoss === 0) {
+ // 如果没有军团BOSS,为每日BOSS切换阵容
+ taskList.push({
+ name: '每日BOSS阵容检查',
+ execute: () => switchToFormationIfNeeded(tokenId, settings.bossFormation, 'BOSS阵容', logFn)
+ })
+ }
+
+ for (let i = 0; i < 3; i++) {
+ taskList.push({
+ name: `每日BOSS ${i + 1}/3`,
+ execute: () => executeGameCommand(tokenId, 'fight_startboss',
+ { bossId: todayBossId }, `每日BOSS ${i + 1}`, 12000)
+ })
+ }
+ }
+
+ // 4. 固定奖励领取
+ const fixedRewards = [
+ { name: '福利签到', cmd: 'system_signinreward' },
+ { name: '俱乐部签到', cmd: 'legion_signin' },
+ { name: '领取每日礼包', cmd: 'discount_claimreward' },
+ { name: '领取免费礼包', cmd: 'card_claimreward' },
+ { name: '领取永久卡礼包', cmd: 'card_claimreward', params: { cardId: 4003 } }
+ ]
+
+ if (settings.claimEmail) {
+ fixedRewards.push({ name: '领取邮件奖励', cmd: 'mail_claimallattachment' })
+ }
+
+ fixedRewards.forEach(reward => {
+ taskList.push({
+ name: reward.name,
+ execute: () => executeGameCommand(tokenId, reward.cmd, reward.params || {}, reward.name)
+ })
+ })
+
+ // 5. 免费活动
+ // 免费钓鱼
+ if (isTodayAvailable(statisticsTime['artifact:normal:lottery:time'])) {
+ for (let i = 0; i < 3; i++) {
+ taskList.push({
+ name: `免费钓鱼 ${i + 1}/3`,
+ execute: () => executeGameCommand(tokenId, 'artifact_lottery',
+ { lotteryNumber: 1, newFree: true, type: 1 }, `免费钓鱼 ${i + 1}`)
+ })
+ }
+ }
+
+ // 灯神免费扫荡
+ const kingdoms = ['魏国', '蜀国', '吴国', '群雄']
+ for (let gid = 1; gid <= 4; gid++) {
+ if (isTodayAvailable(statisticsTime[`genie:daily:free:${gid}`])) {
+ taskList.push({
+ name: `${kingdoms[gid-1]}灯神免费扫荡`,
+ execute: () => executeGameCommand(tokenId, 'genie_sweep',
+ { genieId: gid }, `${kingdoms[gid-1]}灯神免费扫荡`)
+ })
+ }
+ }
+
+ // 灯神免费扫荡卷
+ for (let i = 0; i < 3; i++) {
+ taskList.push({
+ name: `领取免费扫荡卷 ${i + 1}/3`,
+ execute: () => executeGameCommand(tokenId, 'genie_buysweep', {}, `领取免费扫荡卷 ${i + 1}`)
+ })
+ }
+
+ // 6. 黑市购买任务 (任务ID: 12)
+ if (!isTaskCompleted(12) && settings.blackMarketPurchase) {
+ taskList.push({
+ name: '黑市购买1次物品',
+ execute: () => executeGameCommand(tokenId, 'store_purchase', { goodsId: 1 }, '黑市购买1次物品')
+ })
+ }
+
+ // 7. 任务奖励领取
+ for (let taskId = 1; taskId <= 10; taskId++) {
+ taskList.push({
+ name: `领取任务奖励${taskId}`,
+ execute: () => executeGameCommand(tokenId, 'task_claimdailypoint',
+ { taskId }, `领取任务奖励${taskId}`, 5000)
+ })
+ }
+
+ // 日常和周常奖励
+ taskList.push(
+ {
+ name: '领取日常任务奖励',
+ execute: () => executeGameCommand(tokenId, 'task_claimdailyreward', {}, '领取日常任务奖励')
+ },
+ {
+ name: '领取周常任务奖励',
+ execute: () => executeGameCommand(tokenId, 'task_claimweekreward', {}, '领取周常任务奖励')
+ }
+ )
+
+ // 执行任务列表
+ const totalTasks = taskList.length
+ logFn(`共有 ${totalTasks} 个任务待执行`)
+
+ for (let i = 0; i < taskList.length; i++) {
+ const task = taskList[i]
+
+ try {
+ await task.execute()
+
+ // 更新进度
+ const progress = Math.floor(((i + 1) / totalTasks) * 100)
+ if (progressFn) progressFn(tokenId, progress)
+
+ // 任务间隔
+ await new Promise(resolve => setTimeout(resolve, 500))
+
+ } catch (error) {
+ logFn(`任务执行失败: ${task.name} - ${error.message}`, 'error')
+ // 继续执行下一个任务
+ }
+ }
+
+ // 确保进度为100%
+ if (progressFn) progressFn(tokenId, 100)
+ logFn('所有任务执行完成', 'success')
+
+ // 最后刷新一次角色信息
+ await new Promise(resolve => setTimeout(resolve, 2000))
+ await refreshRoleInfo()
+}
+
+// 一键补差主函数
const runDailyFix = async () => {
if (!tokenStore.selectedToken || busy.value) {
- log('没有选中Token或正在执行中', 'error')
+ message.warning('没有选中Token或正在执行中')
return
}
-
+
+ if (!isConnected.value) {
+ message.error('WebSocket连接未建立,请检查连接状态')
+ return
+ }
+
busy.value = true
showLog.value = true
logList.value = []
-
- log('开始执行任务...')
-
- const tokenId = tokenStore.selectedToken.id
- log(`当前Token ID: ${tokenId}`)
-
- // 检查tokenStore方法
- log(`检查tokenStore方法:`)
- log(`- sendMessageWithPromise: ${typeof tokenStore.sendMessageWithPromise}`)
- log(`- getWebSocketStatus: ${typeof tokenStore.getWebSocketStatus}`)
- log(`- selectedToken: ${!!tokenStore.selectedToken}`)
-
- // 检查WebSocket连接状态
- const wsStatus = tokenStore.getWebSocketStatus(tokenId)
- log(`WebSocket状态: ${JSON.stringify(wsStatus)}`)
-
- // 修复状态检查逻辑 - wsStatus可能直接是字符串,也可能是对象
- const actualStatus = typeof wsStatus === 'string' ? wsStatus : wsStatus?.status
- log(`实际状态: ${actualStatus}`)
-
- if (actualStatus !== 'connected') {
- log('WebSocket未连接,无法继续执行', 'error')
- busy.value = false
- return
- }
-
+
try {
- log('尝试获取游戏内角色信息...')
- log('发送 role_getroleinfo 命令到游戏服务器...')
- log('期望响应: role_getroleinforesp')
-
- // 先检查WebSocket客户端是否能接收到消息
- tokenStore.setMessageListener((message) => {
- if (message?.cmd) {
- log(`收到游戏消息: ${message.cmd}`, 'info')
- }
+ log('=== 开始执行一键补差任务 ===')
+
+
+ // 1. 获取角色信息
+ const roleInfo = await refreshRoleInfo()
+
+ if (!roleInfo?.role) {
+ throw new Error('获取角色信息失败或数据异常')
+ }
+
+
+ log(`当前每日任务进度: ${roleInfo.role.dailyTask?.dailyPoint || 0}/100`)
+
+ // 2. 执行任务
+ log('第二步: 开始执行每日任务...')
+ await executeDailyTasks(roleInfo, log, (tokenId, progress) => {
+ log(`任务进度: ${progress}%`)
})
-
- // 增加超时时间,因为游戏服务器响应可能较慢
- const roleInfo = await tokenStore.sendMessageWithPromise(tokenId, 'role_getroleinfo', {}, 10000)
-
- if (roleInfo) {
- log('游戏角色信息获取成功!', 'success')
-
- // 显示角色基本信息(如果存在)
- if (roleInfo.role) {
- log(`角色等级: ${roleInfo.role.level || '未知'}`)
- log(`角色名称: ${roleInfo.role.name || '未知'}`)
- log(`每日任务进度: ${roleInfo.role.dailyTask?.dailyPoint || 0}/100`)
+
+ log('=== 任务执行完成 ===', 'success')
+ message.success('每日任务补差执行完成')
+
+ // 3. 最终刷新角色信息
+ setTimeout(async () => {
+ try {
+ await refreshRoleInfo()
+ log('最终角色信息刷新完成', 'success')
+ } catch (error) {
+ log(`最终刷新失败: ${error.message}`, 'warning')
}
-
- // 现在尝试执行一个简单的游戏指令
- log('尝试执行游戏内签到...')
- const signInResult = await tokenStore.sendMessageWithPromise(tokenId, 'system_signinreward', {}, 8000)
-
- if (signInResult) {
- log('游戏签到执行成功!', 'success')
- log(`签到奖励: ${signInResult.reward ? '有奖励' : '无奖励或已签到'}`)
- }
-
- message.success('游戏指令测试成功!')
- } else {
- log('未收到游戏角色数据', 'error')
- message.warning('未收到游戏服务器响应')
- }
-
+ }, 3000)
+
} catch (error) {
- log(`游戏指令执行失败: ${error.message}`, 'error')
-
- // 分析可能的原因
- if (error.message.includes('超时') || error.message.includes('timeout')) {
- log('可能原因:游戏服务器响应超时', 'error')
- log('建议:检查网络连接或稍后重试', 'error')
- } else if (error.message.includes('Unknown cmd')) {
- log('可能原因:游戏指令未在WebSocket客户端中注册', 'error')
- } else {
- log('可能原因:WebSocket连接异常或游戏服务器拒绝请求', 'error')
- }
-
- message.error(`游戏指令执行失败: ${error.message}`)
+ log(`任务执行失败: ${error.message}`, 'error')
+ console.error('详细错误信息:', error)
+ message.error(`任务执行失败: ${error.message}`)
} finally {
busy.value = false
}
}
-// 简化的执行器函数 - 直接使用tokenStore方法
-const U = async (roleInfoResp, logFn, progress) => {
- const tokenId = tokenStore.selectedToken.id
-
- logFn?.('开始执行每日任务')
-
- // 检查已完成的任务
- const completedTasks = roleInfoResp.role?.dailyTask?.complete ?? {}
- const isTaskCompleted = (taskId) => completedTasks[taskId] === -1
-
- // 执行任务列表
- const taskList = []
-
- // 基础任务
- if (!isTaskCompleted(2)) { // 分享游戏
- taskList.push({ name: '分享一次游戏', cmd: 'system_mysharecallback', params: { isSkipShareCard: true, type: 2 } })
- }
-
- if (!isTaskCompleted(3)) { // 赠送好友
- taskList.push({ name: '赠送好友金币', cmd: 'friend_batch' })
- }
-
- if (!isTaskCompleted(4)) { // 招募
- taskList.push({ name: '免费招募', cmd: 'hero_recruit' })
- }
-
- if (!isTaskCompleted(6)) { // 点金
- taskList.push({ name: '免费点金', cmd: 'system_buygold' })
- }
-
- if (!isTaskCompleted(5) && settings.claimHangUp) { // 挂机奖励
- taskList.push({ name: '领取挂机奖励', cmd: 'system_claimhangupreward' })
- }
-
- if (!isTaskCompleted(7) && settings.openBox) { // 开宝箱
- taskList.push({ name: '开启宝箱', cmd: 'item_openbox', params: { itemId: 2001, number: 10 } })
- }
-
- if (!isTaskCompleted(14) && settings.claimBottle) { // 盐罐
- taskList.push({ name: '领取盐罐奖励', cmd: 'bottlehelper_claim' })
+// 刷新任务状态
+const handleRefreshTaskStatus = async () => {
+ if (!isConnected.value) {
+ message.warning('WebSocket未连接,无法刷新任务状态')
+ return
}
- // 常规奖励
- taskList.push(
- { name: '福利签到', cmd: 'system_signinreward' },
- { name: '俱乐部签到', cmd: 'legion_signin' },
- { name: '领取每日礼包', cmd: 'discount_claimreward' },
- { name: '领取免费礼包', cmd: 'card_claimreward' }
- )
-
- if (settings.claimEmail) {
- taskList.push({ name: '领取邮件奖励', cmd: 'mail_claimallattachment' })
+ try {
+ log('手动刷新任务状态...')
+ await refreshRoleInfo()
+ message.success('任务状态刷新成功')
+ } catch (error) {
+ log(`刷新失败: ${error.message}`, 'error')
+ message.error(`刷新失败: ${error.message}`)
}
-
- // 任务奖励领取
- for (let i = 1; i <= 10; i++) {
- taskList.push({ name: `领取任务奖励${i}`, cmd: 'task_claimdailypoint', params: { taskId: i } })
- }
- taskList.push(
- { name: '领取日常任务奖励', cmd: 'task_claimdailyreward' },
- { name: '领取周常任务奖励', cmd: 'task_claimweekreward' }
- )
-
- // 竞技场
- if (!isTaskCompleted(13) && settings.arenaEnable) {
- logFn?.('开始竞技场战斗')
- try {
- // 获取队伍信息
- const teamInfo = await tokenStore.sendMessageWithPromise(tokenId, 'presetteam_getinfo', {}, 5000)
-
- // 切换阵容(如果需要)
- if (teamInfo?.presetTeamInfo?.useTeamId !== settings.arenaFormation) {
- await tokenStore.sendMessageWithPromise(tokenId, 'presetteam_saveteam', { teamId: settings.arenaFormation }, 5000)
- logFn?.(`切换到竞技场阵容 ${settings.arenaFormation}`)
- }
-
- // 开始竞技场
- await tokenStore.sendMessageWithPromise(tokenId, 'arena_startarea', {}, 5000)
-
- // 进行3场战斗
- for (let i = 1; i <= 3; i++) {
- logFn?.(`竞技场战斗 ${i}/3`)
- const targets = await tokenStore.sendMessageWithPromise(tokenId, 'arena_getareatarget', {}, 5000)
- const targetId = targets?.roleList?.[0]?.roleId
-
- if (targetId) {
- await tokenStore.sendMessageWithPromise(tokenId, 'fight_startareaarena', { targetId }, 8000)
- logFn?.(`完成竞技场战斗 ${i}`, 'success')
- }
- }
- } catch (error) {
- logFn?.(`竞技场战斗失败: ${error.message}`, 'error')
- }
- }
-
- // 执行任务列表
- const total = taskList.length
- for (let i = 0; i < taskList.length; i++) {
- const task = taskList[i]
- logFn?.(task.name)
-
- try {
- await tokenStore.sendMessageWithPromise(tokenId, task.cmd, task.params || {}, 5000)
- logFn?.(`${task.name} 成功`, 'success')
- } catch (error) {
- logFn?.(`${task.name} 失败: ${error.message}`, 'error')
- }
-
- // 更新进度
- const progress_pct = Math.floor(((i + 1) / total) * 100)
- if (progress && tokenId) progress(tokenId, progress_pct)
-
- // 小延迟避免过快
- await new Promise(resolve => setTimeout(resolve, 300))
- }
-
- // 确保进度为100%
- if (progress && tokenId) progress(tokenId, 100)
- logFn?.('所有任务执行完成', 'success')
}
// 辅助函数
@@ -632,21 +896,21 @@ const loadSettings = (roleId) => {
try {
const raw = localStorage.getItem(`daily-settings:${roleId}`)
return raw ? JSON.parse(raw) : null
- } catch (error) {
+ } catch (error) {
console.error('Failed to load settings:', error)
- return null
+ return null
}
}
const saveSettings = (roleId, s) => {
- try {
- localStorage.setItem(`daily-settings:${roleId}`, JSON.stringify(s))
+ try {
+ localStorage.setItem(`daily-settings:${roleId}`, JSON.stringify(s))
} catch (error) {
console.error('Failed to save settings:', error)
}
}
-// 监听设置变化 - 基于参考代码的watch逻辑
+// 监听设置变化
watch(settings, (cur) => {
const role = getCurrentRole()
if (role) saveSettings(role.roleId, cur)
@@ -655,29 +919,41 @@ watch(settings, (cur) => {
// 监听token选择变化
watch(() => tokenStore.selectedToken, async (newToken, oldToken) => {
if (newToken && newToken !== oldToken) {
+ log(`切换到Token: ${newToken.name}`)
+
// 加载新token的设置
const saved = loadSettings(newToken.id)
if (saved) Object.assign(settings, saved)
-
- // 同步任务状态
- syncCompleteFromServer(tokenStore.selectedTokenRoleInfo)
+
+ // 如果WebSocket已连接,尝试获取最新角色信息
+ if (isConnected.value) {
+ try {
+ await refreshRoleInfo()
+ } catch (error) {
+ console.warn('切换token后获取角色信息失败:', error.message)
+ }
+ }
}
}, { immediate: true })
-// 生命周期 - 基于参考代码的onMounted函数
+// 监听角色信息变化,自动同步任务状态
+watch(() => tokenStore.selectedTokenRoleInfo, (newRoleInfo) => {
+ if (newRoleInfo?.role?.dailyTask?.complete) {
+ log('角色信息更新,同步任务状态')
+ syncCompleteFromServer(newRoleInfo)
+ }
+}, { immediate: true, deep: true })
+
+// 生命周期
onMounted(async () => {
- // 首次拉取角色信息(如果有选中的token)
- if (tokenStore.selectedToken) {
+ log('组件初始化完成')
+
+ // 首次拉取角色信息(如果有选中的token且已连接)
+ if (tokenStore.selectedToken && isConnected.value) {
try {
await refreshRoleInfo()
} catch (error) {
console.warn('初始化时获取角色信息失败:', error.message)
- // 如果获取失败,尝试发送普通消息(不等待响应)
- try {
- tokenStore.sendMessage(tokenStore.selectedToken.id, 'role_getroleinfo', {})
- } catch (sendError) {
- console.warn('发送角色信息请求失败:', sendError.message)
- }
}
}
@@ -687,13 +963,11 @@ onMounted(async () => {
if (saved) Object.assign(settings, saved)
}
- // 同步完成态(使用现有的角色信息)
- syncCompleteFromServer(tokenStore.selectedTokenRoleInfo)
+ // 初始化时的任务状态同步会通过 watch selectedTokenRoleInfo 自动处理
})
-// 清理监听 - 基于参考代码的onBeforeUnmount
onBeforeUnmount(() => {
- tokenStore.setMessageListener(undefined)
+ log('组件即将卸载')
})
@@ -851,7 +1125,34 @@ onBeforeUnmount(() => {
.modal-header {
display: flex;
align-items: center;
+ justify-content: space-between;
gap: var(--spacing-sm);
+ width: 100%;
+}
+
+.refresh-button {
+ display: flex;
+ align-items: center;
+ gap: var(--spacing-xs);
+ padding: var(--spacing-xs) var(--spacing-sm);
+ border: 1px solid var(--border-light);
+ border-radius: var(--border-radius-medium);
+ background: white;
+ color: var(--text-secondary);
+ font-size: var(--font-size-sm);
+ cursor: pointer;
+ transition: all var(--transition-fast);
+
+ &:hover:not(:disabled) {
+ background: var(--bg-tertiary);
+ border-color: var(--primary-color);
+ color: var(--primary-color);
+ }
+
+ &:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
}
.settings-content {
@@ -941,7 +1242,7 @@ onBeforeUnmount(() => {
background: var(--bg-tertiary);
border-radius: var(--border-radius-medium);
padding: var(--spacing-md);
- max-height: 300px;
+ max-height: 400px;
overflow-y: auto;
}
@@ -968,6 +1269,10 @@ onBeforeUnmount(() => {
&.success {
color: var(--success-color);
}
+
+ &.warning {
+ color: #f59e0b;
+ }
}
// 响应式设计
@@ -982,4 +1287,4 @@ onBeforeUnmount(() => {
justify-content: center;
}
}
-
\ No newline at end of file
+
diff --git a/src/components/TeamStatus.vue b/src/components/TeamStatus.vue
index 382ed26..7447315 100644
--- a/src/components/TeamStatus.vue
+++ b/src/components/TeamStatus.vue
@@ -2,30 +2,30 @@