您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
强化自动化工具
当前为
// ==UserScript== // @name 猫猫放置强化助手 // @version v3.2 // @description 强化自动化工具 // @author YuoHira // @license MIT // @match https://www.moyu-idle.com/* // @match https://moyu-idle.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=moyu-idle.com // @grant none // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/pako.min.js // @namespace https://gf.qytechs.cn/users/397156 // ==/UserScript== (function() { 'use strict'; // —— 默认配置 —— let TARGET_LEVEL = 5; // 目标强化等级 let ENHANCE_INTERVAL = 1000; // 强化间隔(毫秒) let isAutoEnhancing = false; // 自动强化状态 let enhanceTimer = null; // 强化定时器 let storedEnhanceData = null; // 储存的强化数据(完整的请求对象) let currentEnhanceItem = null; // 当前强化物品信息 let DEBUG_MODE = false; // 调试模式(默认关闭) let PROTECT_START_LEVEL = 3; // 从几级开始使用保护材料 let BATCH_COUNT = 1; // 批量强化次数 let currentBatchCount = 0; // 当前剩余强化次数 let waitingForResult = false; // 等待强化结果 // —— 强化统计数据 —— let enhanceStats = { baseItem: '', // 基础物品名称 currentLevel: 0, // 当前等级 targetLevel: 0, // 目标等级 maxReachedLevel: 0, // 历史最大等级 levelStats: {}, // 每级统计 {level: {attempts: 0, success: 0}} totalAttempts: 0, // 总尝试次数 totalSuccess: 0, // 总成功次数 startTime: null // 开始时间 }; // —— 本地存储键名 —— const STORAGE_KEYS = { POSITION: 'enhanceHelper_position', TARGET_LEVEL: 'enhanceHelper_targetLevel', INTERVAL: 'enhanceHelper_interval', CURRENT_ITEM: 'enhanceHelper_currentItem', STORED_REQUEST: 'enhanceHelper_storedRequest', DEBUG_MODE: 'enhanceHelper_debugMode', PROTECT_START_LEVEL: 'enhanceHelper_protectStartLevel', IS_MINIMIZED: 'enhanceHelper_isMinimized', BATCH_COUNT: 'enhanceHelper_batchCount', CURRENT_BATCH_COUNT: 'enhanceHelper_currentBatchCount' }; // —— 界面状态 —— let isMinimized = false; // —— 加载本地配置 —— function loadConfig() { const savedTarget = localStorage.getItem(STORAGE_KEYS.TARGET_LEVEL); const savedInterval = localStorage.getItem(STORAGE_KEYS.INTERVAL); const savedCurrentItem = localStorage.getItem(STORAGE_KEYS.CURRENT_ITEM); const savedStoredRequest = localStorage.getItem(STORAGE_KEYS.STORED_REQUEST); const savedDebugMode = localStorage.getItem(STORAGE_KEYS.DEBUG_MODE); const savedProtectStartLevel = localStorage.getItem(STORAGE_KEYS.PROTECT_START_LEVEL); const savedIsMinimized = localStorage.getItem(STORAGE_KEYS.IS_MINIMIZED); const savedBatchCount = localStorage.getItem(STORAGE_KEYS.BATCH_COUNT); const savedCurrentBatchCount = localStorage.getItem(STORAGE_KEYS.CURRENT_BATCH_COUNT); if (savedTarget) TARGET_LEVEL = parseInt(savedTarget, 10); if (savedInterval) ENHANCE_INTERVAL = parseInt(savedInterval, 10); if (savedDebugMode) DEBUG_MODE = savedDebugMode === 'true'; if (savedProtectStartLevel) PROTECT_START_LEVEL = parseInt(savedProtectStartLevel, 10); if (savedIsMinimized) isMinimized = savedIsMinimized === 'true'; if (savedBatchCount) BATCH_COUNT = parseInt(savedBatchCount, 10); if (savedCurrentBatchCount) currentBatchCount = parseInt(savedCurrentBatchCount, 10); // 恢复当前强化物品 if (savedCurrentItem) { try { currentEnhanceItem = JSON.parse(savedCurrentItem); } catch (e) { currentEnhanceItem = null; } } // 恢复储存的请求数据 if (savedStoredRequest) { try { storedEnhanceData = JSON.parse(savedStoredRequest); } catch (e) { storedEnhanceData = null; } } } // —— 保存配置 —— function saveConfig() { localStorage.setItem(STORAGE_KEYS.TARGET_LEVEL, TARGET_LEVEL); localStorage.setItem(STORAGE_KEYS.INTERVAL, ENHANCE_INTERVAL); localStorage.setItem(STORAGE_KEYS.DEBUG_MODE, DEBUG_MODE); localStorage.setItem(STORAGE_KEYS.PROTECT_START_LEVEL, PROTECT_START_LEVEL); localStorage.setItem(STORAGE_KEYS.IS_MINIMIZED, isMinimized); localStorage.setItem(STORAGE_KEYS.BATCH_COUNT, BATCH_COUNT); localStorage.setItem(STORAGE_KEYS.CURRENT_BATCH_COUNT, currentBatchCount); } // —— 保存当前强化物品 —— function saveCurrentItem() { if (currentEnhanceItem) { localStorage.setItem(STORAGE_KEYS.CURRENT_ITEM, JSON.stringify(currentEnhanceItem)); } else { localStorage.removeItem(STORAGE_KEYS.CURRENT_ITEM); } } // —— 保存强化请求数据 —— function saveStoredRequest() { if (storedEnhanceData) { localStorage.setItem(STORAGE_KEYS.STORED_REQUEST, JSON.stringify(storedEnhanceData)); } else { localStorage.removeItem(STORAGE_KEYS.STORED_REQUEST); } } // —— 边界检查函数 —— function constrainPosition(x, y, panelWidth = 480, panelHeight = 400) { const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; // 确保面板至少有50px在可见范围内 const minVisible = 50; // 检查右边界(x是right值) if (x < 0) { x = 20; // 默认右边距 } else if (x > windowWidth - minVisible) { x = windowWidth - minVisible; } // 检查上下边界(y是top值) if (y < 0) { y = 20; // 默认上边距 } else if (y > windowHeight - minVisible) { y = windowHeight - minVisible; } return {x, y}; } // —— 保存位置 —— function savePosition(x, y) { const constrained = constrainPosition(x, y); localStorage.setItem(STORAGE_KEYS.POSITION, JSON.stringify(constrained)); } // —— 加载位置 —— function loadPosition() { const saved = localStorage.getItem(STORAGE_KEYS.POSITION); let position = {x: 20, y: 20}; // 默认位置 if (saved) { try { position = JSON.parse(saved); } catch (e) { position = {x: 20, y: 20}; } } // 加载时也进行边界检查,防止窗口大小改变后面板跑到屏幕外 return constrainPosition(position.x, position.y); } // —— 辅助:检测压缩格式 —— function detectCompression(buf) { const b = new Uint8Array(buf); if (b.length >= 2) { if (b[0] === 0x1f && b[1] === 0x8b) return 'gzip'; if (b[0] === 0x78 && (((b[0] << 8) | b[1]) % 31) === 0) return 'zlib'; } return 'deflate'; } // —— 判断是否为强化请求 —— function isEnhanceRequest(data) { if (typeof data === 'string') { try { // 检查是否包含 enhance:require 事件 return data.includes('"enhance:require"') || data.includes('enhance:require'); } catch (e) { return false; } } return false; } // —— 解析强化数据 —— function parseEnhanceData(data) { try { if (typeof data === 'string') { // 尝试解析Socket.IO格式的数据 const match = data.match(/\["enhance:require",(.+)\]/); if (match) { const payload = JSON.parse(match[1]); if (payload.data && payload.data.resourceId) { return { resourceId: payload.data.resourceId, protectedResourceId: payload.data.protectedResourceId || null, user: payload.user ? payload.user.name : 'Unknown', fullPayload: payload // 保存完整的payload用于重构请求 }; } } } } catch (e) { // 解析失败,忽略 } return null; } // —— 解析强化结果 —— function parseEnhanceResult(text) { try { const data = JSON.parse(text); if (data.data && data.data.hasOwnProperty('success') && data.data.enhanceResultId) { return { success: data.data.success, message: data.data.msg, resultId: data.data.enhanceResultId, user: data.user ? data.user.name : 'Unknown' }; } } catch (e) { // 不是强化结果,忽略 } return null; } // —— 解析物品等级 —— function parseItemLevel(itemId) { const match = itemId.match(/(.+?)\+(\d+)$/); if (match) { return { baseItem: match[1], level: parseInt(match[2], 10) }; } return { baseItem: itemId, level: 0 }; } // —— 初始化统计数据 —— function initStats(itemId, targetLevel) { const parsed = parseItemLevel(itemId); enhanceStats = { baseItem: parsed.baseItem, currentLevel: parsed.level, targetLevel: targetLevel, maxReachedLevel: parsed.level, // 初始化为当前等级 levelStats: {}, totalAttempts: 0, totalSuccess: 0, startTime: Date.now() }; // 初始化每级统计 - 始终从+1到目标等级 for (let i = 0; i < targetLevel; i++) { enhanceStats.levelStats[i] = { attempts: 0, success: 0 }; } } // —— 更新统计数据 —— function updateStats(result) { // 解析结果物品等级 const resultItem = parseItemLevel(result.resultId); // 记录这次尝试 const attemptLevel = enhanceStats.currentLevel; const levelStats = enhanceStats.levelStats[attemptLevel]; if (levelStats) { levelStats.attempts++; enhanceStats.totalAttempts++; if (result.success) { levelStats.success++; enhanceStats.totalSuccess++; } } // 更新当前等级为结果等级 enhanceStats.currentLevel = resultItem.level; // 更新历史最大等级 if (resultItem.level > enhanceStats.maxReachedLevel) { enhanceStats.maxReachedLevel = resultItem.level; } updateStatsDisplay(); } // —— 自动强化函数 —— function startAutoEnhance(ws) { if (enhanceTimer) { clearTimeout(enhanceTimer); } // 发送第一次强化请求 sendEnhanceRequest(ws); } // —— 发送强化请求 —— function sendEnhanceRequest(ws) { if (!isAutoEnhancing || !ws || ws.readyState !== WebSocket.OPEN || !currentEnhanceItem || !storedEnhanceData) { return; } // 检查是否达到目标等级 if (enhanceStats.currentLevel >= enhanceStats.targetLevel) { // 获取当前输入框的批量次数 const currentInputValue = parseInt(batchCountInput.value, 10); // 批量次数-1,直接修改输入框的值 if (currentInputValue > 1) { batchCountInput.value = currentInputValue - 1; BATCH_COUNT = currentInputValue - 1; // 同步内部变量 currentBatchCount = currentInputValue - 1; // 同步当前批量次数 saveConfig(); // 保存配置 // 获取基础物品ID(去掉+数字后缀) const currentItemInfo = parseItemLevel(currentEnhanceItem.resourceId); const baseItemId = currentItemInfo.baseItem; // 基础物品ID,不包含+数字 // 更新当前强化物品为基础版本 currentEnhanceItem.resourceId = baseItemId; saveCurrentItem(); // 保存更新后的物品信息 // 重置统计数据,准备下一轮强化(使用基础物品ID) initStats(baseItemId, TARGET_LEVEL); updateStatsDisplay(); updateItemDisplay(currentEnhanceItem, `批量剩余: ${currentInputValue - 1}`); updateMinimizedDisplay(); // Debug模式记录批量循环信息 if (DEBUG_MODE) { console.group('🔄 [强化助手] 批量强化循环'); console.log('批量信息:', { 完成轮次: BATCH_COUNT - (currentInputValue - 1) + 1, 剩余次数: currentInputValue - 1, 基础物品ID: baseItemId, 原强化物品ID: enhanceStats.baseItem + '+' + enhanceStats.targetLevel, 时间: new Date().toLocaleTimeString() }); console.groupEnd(); } // 继续发送强化请求 setTimeout(() => { sendEnhanceRequest(ws); }, ENHANCE_INTERVAL); return; } // 批量完成,停止自动强化并更新UI状态 isAutoEnhancing = false; stopAutoEnhance(); updateItemDisplay(currentEnhanceItem, '批量完成'); updateToggleButtonState(); updateMinimizedDisplay(); return; } // 构造当前物品的强化请求,使用完整保存的数据 const requestData = { user: storedEnhanceData.user, data: { resourceId: currentEnhanceItem.resourceId } }; // 根据当前等级和设置决定是否使用保护材料 if (storedEnhanceData.data && storedEnhanceData.data.protectedResourceId && enhanceStats.currentLevel >= PROTECT_START_LEVEL) { requestData.data.protectedResourceId = storedEnhanceData.data.protectedResourceId; } const enhanceRequest = `42["enhance:require",${JSON.stringify(requestData)}]`; // Debug模式记录自动强化请求 if (DEBUG_MODE) { console.group('🤖 [强化助手] 发送自动强化请求'); console.log('请求数据:', enhanceRequest); console.log('构造的请求对象:', requestData); console.log('目标物品:', { 物品ID: currentEnhanceItem.resourceId, 保护材料ID: requestData.data.protectedResourceId || '无', 当前等级: enhanceStats.currentLevel, 目标等级: enhanceStats.targetLevel, 批量进度: `${BATCH_COUNT - currentBatchCount + 1}/${BATCH_COUNT}`, 剩余次数: currentBatchCount, 保护设置: `≥${PROTECT_START_LEVEL}级使用`, 实际使用保护: requestData.data.protectedResourceId ? '是' : '否', 用户: requestData.user.name, 时间: new Date().toLocaleTimeString() }); console.groupEnd(); } waitingForResult = true; ws.__originalSend(enhanceRequest); } // —— 处理强化结果 —— function handleEnhanceResult(result) { waitingForResult = false; // 总是更新当前强化物品为结果物品(不管成功失败) const wasFirstCapture = !currentEnhanceItem; currentEnhanceItem = { resourceId: result.resultId, user: result.user }; // 保存到本地存储 saveCurrentItem(); // 如果是第一次捕获物品,启用按钮 if (wasFirstCapture) { updateItemDisplay(currentEnhanceItem); } else { // 更新UI显示当前物品 updateItemDisplay(currentEnhanceItem); // 更新统计数据(只有在自动强化时才统计) if (isAutoEnhancing) { updateStats(result); } } // 如果还在自动强化模式,延迟后继续 if (isAutoEnhancing) { enhanceTimer = setTimeout(() => { sendEnhanceRequest(window.currentWS); }, ENHANCE_INTERVAL); } } function stopAutoEnhance() { if (enhanceTimer) { clearTimeout(enhanceTimer); enhanceTimer = null; } waitingForResult = false; } // —— 初始化配置 —— loadConfig(); // Debug模式启动提示 if (DEBUG_MODE) { console.log('🐛 [强化助手] 调试模式已启用,将记录所有WebSocket强化请求和结果'); } // 如果有恢复的物品,延迟更新UI显示 if (currentEnhanceItem) { setTimeout(() => { updateItemDisplay(currentEnhanceItem); }, 100); } // 初始化保护显示 setTimeout(() => { updateProtectDisplay(); // 初始化保护等级提示 if (PROTECT_START_LEVEL === 0) { protectLevelHint.textContent = '不使用保护'; protectLevelHint.style.color = '#f44336'; } else { protectLevelHint.textContent = `≥${PROTECT_START_LEVEL}级使用保护`; protectLevelHint.style.color = '#aaa'; } // 如果有恢复的物品,更新显示 if (currentEnhanceItem) { updateItemDisplay(currentEnhanceItem); } // 如果页面加载时是收起状态,调整面板宽度和显示状态 if (isMinimized) { panel.style.width = '280px'; titleBar.style.display = 'none'; mainContent.style.display = 'none'; minimizedBar.style.display = 'flex'; } // 初始化收起状态显示 updateMinimizedDisplay(); }, 100); // —— 创建浮动控制面板 —— const panel = document.createElement('div'); panel.id = 'enhanceHelperPanel'; // 添加唯一ID const savedPos = loadPosition(); panel.style.cssText = ` position: fixed; top: ${savedPos.y}px; right: ${savedPos.x}px; width: 480px; padding: 12px; background: rgba(25,35,45,0.95); color: #fff; font-family: 'Consolas', 'Monaco', monospace; font-size: 12px; border-radius: 10px; z-index: 9999; cursor: move; border: 1px solid rgba(100,200,255,0.3); box-shadow: 0 6px 25px rgba(0,0,0,0.4); backdrop-filter: blur(5px); `; panel.innerHTML = ` <div id="enhanceHelper_titleBar" style="cursor: default; margin-bottom:10px; font-weight:bold; color:#64B5F6; display:${isMinimized ? 'none' : 'flex'}; align-items:center;"> <span>🛠️ 强化助手</span> <div style="margin-left:auto; display:flex; align-items:center; gap:6px;"> <button id="enhanceHelper_minimizeBtn" style=" padding:2px 6px; background:rgba(100,200,255,0.2); border:none; border-radius:3px; color:#64B5F6; cursor:pointer; font-size:10px; ">${isMinimized ? '📋' : '📌'}</button> <div style="font-size:10px; color:#888;">v2.5</div> </div> </div> <!-- 收起状态的小横条 --> <div id="enhanceHelper_minimizedBar" style="display:${isMinimized ? 'flex' : 'none'}; background:rgba(0,0,0,0.5); padding:6px 8px; border-radius:6px; margin-bottom:8px; font-size:11px; color:#FFA726; align-items:center; justify-content:space-between;"> <div id="enhanceHelper_minimizedStatus">等待强化结果...</div> <button id="enhanceHelper_expandBtn" style=" padding:2px 6px; background:rgba(100,200,255,0.2); border:none; border-radius:3px; color:#64B5F6; cursor:pointer; font-size:10px; margin-left:8px; ">📋</button> </div> <div id="enhanceHelper_mainContent" style="display:${isMinimized ? 'none' : 'block'};"> <!-- 主要内容区域:左右分布 --> <div style="display: flex; gap: 12px;"> <!-- 左侧控制区 --> <div style="flex: 1; min-width: 220px;"> <div style="background:rgba(0,0,0,0.3); padding:8px; border-radius:6px; margin-bottom:8px;"> <div style="font-size:10px; color:#aaa; margin-bottom:4px;">目标物品:</div> <div id="enhanceHelper_itemDisplay" style="color:#FFA726; font-weight:bold; min-height:16px;"> 等待强化结果... </div> <div id="enhanceHelper_protectMaterialDisplay" style="font-size:9px; color:#81C784; margin-top:4px; min-height:12px;"> <!-- 保护材料信息 --> </div> </div> <div style="display:flex; gap:8px; margin-bottom:8px;"> <label style="flex:1;"> 目标等级: <input id="enhanceHelper_targetInput" type="number" min="1" max="15" value="${TARGET_LEVEL}" style="width:100%; padding:4px; border-radius:4px; border:none; background:rgba(255,255,255,0.1); color:#fff; margin-top:2px;"> </label> <label style="flex:1;"> 间隔(ms): <input id="enhanceHelper_intervalInput" type="number" min="100" value="${ENHANCE_INTERVAL}" style="width:100%; padding:4px; border-radius:4px; border:none; background:rgba(255,255,255,0.1); color:#fff; margin-top:2px;"> </label> </div> <div style="display:flex; gap:8px; margin-bottom:8px;"> <label style="flex:1;"> 批量次数: <input id="enhanceHelper_batchCountInput" type="number" min="1" max="99" value="${BATCH_COUNT}" style="width:100%; padding:4px; border-radius:4px; border:none; background:rgba(255,255,255,0.1); color:#fff; margin-top:2px;" title="连续强化多少个物品到目标等级"> </label> <div style="flex:1; font-size:10px; color:#aaa; padding:4px;"> <div style="font-size:9px; color:#666;">剩余次数会自动减少</div> <div style="font-size:9px; color:#666;">1=单次强化</div> </div> </div> <div style="display:flex; gap:8px; margin-bottom:8px;"> <label style="flex:1;"> 保护等级: <input id="enhanceHelper_protectStartLevelInput" type="number" min="0" max="15" value="${PROTECT_START_LEVEL}" style="width:100%; padding:4px; border-radius:4px; border:none; background:rgba(255,255,255,0.1); color:#fff; margin-top:2px;" title="从几级开始使用保护材料 (0=不使用)"> </label> <div style="flex:1; font-size:10px; color:#aaa; padding:4px;"> <div id="enhanceHelper_protectLevelHint">≥${PROTECT_START_LEVEL}级使用保护</div> <div style="font-size:9px; color:#666;">0=不使用保护</div> </div> </div> <div style="margin-bottom:8px;"> <label style="display:flex; align-items:center; font-size:11px; color:#aaa; cursor:pointer;"> <input id="enhanceHelper_debugModeCheckbox" type="checkbox" ${DEBUG_MODE ? 'checked' : ''} style="margin-right:6px; transform:scale(0.9);"> <span>🐛 调试模式 (记录WS强化请求)</span> </label> </div> <button id="enhanceHelper_toggleBtn" style=" width:100%; padding:10px; background:linear-gradient(45deg, #4CAF50, #45a049); color:white; border:none; border-radius:6px; cursor:pointer; font-size:13px; font-weight:bold; transition: all 0.3s ease; " disabled>🚀 开始强化</button> <div style="display:flex; justify-content:space-between; font-size:10px; color:#aaa; margin-top:8px;"> <span>状态: <span id="enhanceHelper_status" style="color:#FFA726;">待机中</span></span> <span id="enhanceHelper_counter">就绪</span> </div> <button id="enhanceHelper_clearDataBtn" style=" width:100%; padding:6px; margin-top:6px; background:rgba(244,67,54,0.8); color:white; border:none; border-radius:4px; cursor:pointer; font-size:10px; transition: all 0.3s ease; ">🗑️ 清除保存数据</button> </div> <!-- 右侧统计区 --> <div style="flex: 1; min-width: 220px;"> <div style="background:rgba(0,0,0,0.3); padding:8px; border-radius:6px; height: 100%;"> <div style="font-size:10px; color:#aaa; margin-bottom:6px; display:flex; align-items:center;"> <span>📊 强化统计</span> </div> <div id="enhanceHelper_statsDisplay" style="font-size:10px; color:#FFA726;"> 等待开始强化... </div> </div> </div> </div> </div> `; document.body.appendChild(panel); // —— 获取控制元素 —— const targetInput = document.getElementById('enhanceHelper_targetInput'); const intervalInput = document.getElementById('enhanceHelper_intervalInput'); const batchCountInput = document.getElementById('enhanceHelper_batchCountInput'); const protectStartLevelInput = document.getElementById('enhanceHelper_protectStartLevelInput'); const debugCheckbox = document.getElementById('enhanceHelper_debugModeCheckbox'); const toggleBtn = document.getElementById('enhanceHelper_toggleBtn'); const statusSpan = document.getElementById('enhanceHelper_status'); const itemDisplay = document.getElementById('enhanceHelper_itemDisplay'); const protectMaterialDisplay = document.getElementById('enhanceHelper_protectMaterialDisplay'); const protectLevelHint = document.getElementById('enhanceHelper_protectLevelHint'); const counterSpan = document.getElementById('enhanceHelper_counter'); const statsDisplay = document.getElementById('enhanceHelper_statsDisplay'); const clearDataBtn = document.getElementById('enhanceHelper_clearDataBtn'); // 收起/展开相关元素 const titleBar = document.getElementById('enhanceHelper_titleBar'); const minimizeBtn = document.getElementById('enhanceHelper_minimizeBtn'); const expandBtn = document.getElementById('enhanceHelper_expandBtn'); const mainContent = document.getElementById('enhanceHelper_mainContent'); const minimizedBar = document.getElementById('enhanceHelper_minimizedBar'); const minimizedStatus = document.getElementById('enhanceHelper_minimizedStatus'); // —— 拖拽逻辑 —— (function makeDraggable(el) { let isDown = false, offsetX = 0, offsetY = 0, hasMoved = false; el.addEventListener('mousedown', e => { if (e.target.tagName === 'INPUT' || e.target.tagName === 'BUTTON') return; isDown = true; hasMoved = false; offsetX = e.clientX - el.offsetLeft; offsetY = e.clientY - el.offsetTop; }); document.addEventListener('mousemove', e => { if (!isDown) return; hasMoved = true; const newX = e.clientX - offsetX; const newY = e.clientY - offsetY; el.style.left = newX + 'px'; el.style.top = newY + 'px'; el.style.right = 'auto'; // 拖拽时清除right定位 }); document.addEventListener('mouseup', () => { if (isDown && hasMoved) { // 只有真正拖拽过才应用边界检查 setTimeout(() => { const rect = el.getBoundingClientRect(); const rightDistance = window.innerWidth - rect.right; const topDistance = rect.top; // 保存并应用边界约束后的位置 const constrained = constrainPosition(rightDistance, topDistance); savePosition(constrained.x, constrained.y); // 重新设置为right定位 el.style.right = constrained.x + 'px'; el.style.top = constrained.y + 'px'; el.style.left = 'auto'; }, 0); // 使用setTimeout避免干扰点击事件 } isDown = false; hasMoved = false; }); })(panel); // —— 更新保护材料显示 —— function updateProtectDisplay() { if (storedEnhanceData && storedEnhanceData.data && storedEnhanceData.data.protectedResourceId) { const protectMaterial = storedEnhanceData.data.protectedResourceId; if (PROTECT_START_LEVEL === 0) { protectMaterialDisplay.innerHTML = `🛡️ 保护: ${protectMaterial} <span style="color:#f44336;">(已禁用)</span>`; } else { protectMaterialDisplay.innerHTML = `🛡️ 保护: ${protectMaterial} <span style="color:#64B5F6;">(≥${PROTECT_START_LEVEL}级)</span>`; } } else { protectMaterialDisplay.textContent = '无保护材料'; } } // —— 更新UI显示 —— function updateItemDisplay(itemInfo, customStatus = null) { if (itemInfo) { itemDisplay.textContent = itemInfo.resourceId; // 保持英文原始名称 itemDisplay.title = `用户: ${itemInfo.user}`; toggleBtn.disabled = false; toggleBtn.style.opacity = '1'; statusSpan.textContent = customStatus || '就绪'; statusSpan.style.color = customStatus === '已完成' ? '#4CAF50' : '#4CAF50'; counterSpan.textContent = customStatus === '已完成' ? '完成' : '已捕获'; } else { itemDisplay.textContent = '等待强化结果...'; itemDisplay.title = ''; toggleBtn.disabled = true; toggleBtn.style.opacity = '0.5'; statusSpan.textContent = '等待中'; statusSpan.style.color = '#FFA726'; counterSpan.textContent = '就绪'; } // 更新保护材料显示 updateProtectDisplay(); // 更新收起状态显示 updateMinimizedDisplay(); } // —— 更新统计显示 —— function updateStatsDisplay() { if (!enhanceStats.baseItem) { statsDisplay.innerHTML = '等待开始强化...'; return; } const totalRate = enhanceStats.totalAttempts > 0 ? (enhanceStats.totalSuccess / enhanceStats.totalAttempts * 100).toFixed(1) : '0.0'; let html = ` <div style="margin-bottom:6px; padding-bottom:6px; border-bottom:1px solid rgba(255,255,255,0.1);"> <div style="color:#64B5F6; font-weight:bold; margin-bottom:2px;">${enhanceStats.baseItem}</div> <div style="font-size:11px; color:#FFA726;"> 进度: Lv${enhanceStats.currentLevel}/${enhanceStats.targetLevel} | 总计: ${enhanceStats.totalAttempts}次 (${totalRate}%) </div> </div> `; // 显示每级详细统计 - 每级一行,从高到低排序 const levels = Object.keys(enhanceStats.levelStats).sort((a, b) => parseInt(b) - parseInt(a)); if (levels.length > 0) { html += '<div>'; levels.forEach(level => { const stats = enhanceStats.levelStats[level]; const levelNum = parseInt(level); const targetLevelNum = levelNum + 1; const rate = stats.attempts > 0 ? (stats.success / stats.attempts * 100).toFixed(1) : '0.0'; const targetLevel = levelNum + 1; // 目标等级 (Lv1, Lv2, etc.) const currentItemLevel = enhanceStats.currentLevel; // 当前物品等级 const maxReachedLevel = enhanceStats.maxReachedLevel; // 历史最大等级 // 确定显示样式 let bgColor, textColor; if (targetLevel === currentItemLevel + 1) { // 当前正在强化的目标等级(蓝色)- 优先级最高 bgColor = 'rgba(100,181,246,0.2)'; textColor = '#64B5F6'; } else if (targetLevel <= maxReachedLevel) { // 历史上到过的等级(绿色) bgColor = 'rgba(76,175,80,0.1)'; textColor = '#81C784'; } else { // 还没到过的等级(灰色) bgColor = 'transparent'; textColor = '#666'; } const displayText = `${stats.attempts}次 (${rate}%)`; html += ` <div style=" display:flex; justify-content:space-between; align-items:center; padding:2px 4px; margin:1px 0; border-radius:3px; background:${bgColor}; font-size:9px; color:${textColor}; "> <span>Lv${targetLevelNum}</span> <span>${displayText}</span> </div> `; }); html += '</div>'; } statsDisplay.innerHTML = html; } // —— 收起/展开功能 —— function toggleMinimize() { isMinimized = !isMinimized; if (isMinimized) { titleBar.style.display = 'none'; mainContent.style.display = 'none'; minimizedBar.style.display = 'flex'; panel.style.width = '280px'; } else { titleBar.style.display = 'flex'; mainContent.style.display = 'block'; minimizedBar.style.display = 'none'; minimizeBtn.textContent = '📌'; panel.style.width = '480px'; } saveConfig(); updateMinimizedDisplay(); } // —— 更新收起状态显示 —— function updateMinimizedDisplay() { if (!isMinimized) return; let statusText = '等待强化结果...'; if (currentEnhanceItem) { const itemInfo = parseItemLevel(currentEnhanceItem.resourceId); const baseItem = itemInfo.baseItem.length > 15 ? itemInfo.baseItem.substring(0, 15) + '..' : itemInfo.baseItem; const currentLevel = itemInfo.level; if (isAutoEnhancing) { // 获取当前输入框的剩余次数 const remainingCount = parseInt(batchCountInput.value, 10); const batchInfo = remainingCount > 1 ? ` [剩余${remainingCount}次]` : ''; statusText = `🔨 ${baseItem} +${currentLevel} → +${TARGET_LEVEL}${batchInfo}`; } else { const status = enhanceStats.currentLevel >= enhanceStats.targetLevel ? '已完成' : '就绪'; statusText = `${status}: ${baseItem} +${currentLevel}`; if (status === '已完成') { statusText = `✅ ${baseItem} +${currentLevel} 已完成`; } } } minimizedStatus.textContent = statusText; } // —— 更新按钮状态 —— function updateToggleButtonState() { if (isAutoEnhancing) { toggleBtn.innerHTML = '⏹️ 停止强化'; toggleBtn.style.background = 'linear-gradient(45deg, #f44336, #d32f2f)'; statusSpan.textContent = '运行中'; statusSpan.style.color = '#4CAF50'; counterSpan.textContent = '活动中'; } else { toggleBtn.innerHTML = '🚀 开始强化'; toggleBtn.style.background = 'linear-gradient(45deg, #4CAF50, #45a049)'; if (enhanceStats.currentLevel >= enhanceStats.targetLevel && enhanceStats.baseItem) { statusSpan.textContent = '已完成'; statusSpan.style.color = '#4CAF50'; counterSpan.textContent = '完成'; } else { statusSpan.textContent = '已停止'; statusSpan.style.color = '#f44336'; counterSpan.textContent = '就绪'; } } } // —— 双击标题栏重置位置 —— titleBar.addEventListener('dblclick', () => { const defaultPos = {x: 20, y: 20}; panel.style.right = defaultPos.x + 'px'; panel.style.top = defaultPos.y + 'px'; panel.style.left = 'auto'; savePosition(defaultPos.x, defaultPos.y); // 显示重置提示 const oldTitle = titleBar.querySelector('span').textContent; titleBar.querySelector('span').textContent = '🔄 位置已重置'; setTimeout(() => { titleBar.querySelector('span').textContent = oldTitle; }, 1000); }); // —— 事件监听器 —— targetInput.addEventListener('change', e => { const v = parseInt(e.target.value, 10); if (!isNaN(v) && v > 0 && v <= 15) { TARGET_LEVEL = v; saveConfig(); } }); intervalInput.addEventListener('change', e => { const v = parseInt(e.target.value, 10); if (!isNaN(v) && v >= 100) { ENHANCE_INTERVAL = v; saveConfig(); } }); batchCountInput.addEventListener('change', e => { const v = parseInt(e.target.value, 10); if (!isNaN(v) && v >= 1 && v <= 99) { BATCH_COUNT = v; saveConfig(); } }); protectStartLevelInput.addEventListener('change', e => { const v = parseInt(e.target.value, 10); if (!isNaN(v) && v >= 0 && v <= 15) { PROTECT_START_LEVEL = v; saveConfig(); updateProtectDisplay(); // 更新保护显示 // 更新提示文本 if (v === 0) { protectLevelHint.textContent = '不使用保护'; protectLevelHint.style.color = '#f44336'; } else { protectLevelHint.textContent = `≥${v}级使用保护`; protectLevelHint.style.color = '#aaa'; } } }); debugCheckbox.addEventListener('change', e => { DEBUG_MODE = e.target.checked; saveConfig(); console.log(`[强化助手] 调试模式已${DEBUG_MODE ? '开启' : '关闭'}`); }); toggleBtn.addEventListener('click', () => { if (!isAutoEnhancing) { if (!currentEnhanceItem) { return; // 按钮应该是禁用状态 } // 获取当前批量次数设置 const inputBatchCount = parseInt(batchCountInput.value, 10); BATCH_COUNT = inputBatchCount; currentBatchCount = inputBatchCount; // 如果是批量强化(>1次),确保从基础物品开始 if (inputBatchCount > 1) { const currentItemInfo = parseItemLevel(currentEnhanceItem.resourceId); const baseItemId = currentItemInfo.baseItem; // 基础物品ID,不包含+数字 // 更新当前强化物品为基础版本 currentEnhanceItem.resourceId = baseItemId; saveCurrentItem(); // 保存更新后的物品信息 // 初始化统计数据(使用基础物品ID) initStats(baseItemId, TARGET_LEVEL); // Debug模式记录批量开始信息 if (DEBUG_MODE) { console.group('🚀 [强化助手] 开始批量强化'); console.log('批量设置:', { 批量次数: inputBatchCount, 基础物品ID: baseItemId, 原物品ID: currentItemInfo.baseItem + (currentItemInfo.level > 0 ? '+' + currentItemInfo.level : ''), 目标等级: TARGET_LEVEL, 时间: new Date().toLocaleTimeString() }); console.groupEnd(); } } else { // 单次强化,使用当前物品 initStats(currentEnhanceItem.resourceId, TARGET_LEVEL); } updateStatsDisplay(); // 开始自动强化 isAutoEnhancing = true; updateToggleButtonState(); updateMinimizedDisplay(); if (window.currentWS) { startAutoEnhance(window.currentWS); } } else { // 停止自动强化 isAutoEnhancing = false; stopAutoEnhance(); updateToggleButtonState(); updateMinimizedDisplay(); } }); // —— 收起/展开按钮事件 —— minimizeBtn.addEventListener('click', toggleMinimize); expandBtn.addEventListener('click', toggleMinimize); // —— 清除数据按钮事件 —— clearDataBtn.addEventListener('click', () => { if (confirm('确定要清除所有保存的数据吗?这将清除当前强化物品和请求数据。')) { // 清除内存中的数据 currentEnhanceItem = null; storedEnhanceData = null; currentBatchCount = 0; // 重置批量次数 // 重置批量次数输入框 batchCountInput.value = 1; BATCH_COUNT = 1; // 清除本地存储 localStorage.removeItem(STORAGE_KEYS.CURRENT_ITEM); localStorage.removeItem(STORAGE_KEYS.STORED_REQUEST); // 重置UI updateItemDisplay(null); updateProtectDisplay(); // 如果正在强化,停止强化 if (isAutoEnhancing) { isAutoEnhancing = false; stopAutoEnhance(); updateToggleButtonState(); } // 更新收起状态显示 updateMinimizedDisplay(); // 保存配置 saveConfig(); } }); // —— 拦截全局 WebSocket(增强助手命名空间) —— const NativeWS = window.WebSocket; // 检查是否已经被其他脚本拦截 if (!window.WebSocket.__enhanceHelperIntercepted) { const OriginalWebSocket = window.WebSocket; window.WebSocket = function(url, protocols) { const ws = protocols ? new OriginalWebSocket(url, protocols) : new OriginalWebSocket(url); // 保存当前WebSocket实例 window.currentWS = ws; // —— 拦截 send —— const originalSend = ws.send; ws.__originalSend = originalSend; // 保存原始方法供自动强化使用 ws.send = function(data) { // 检查是否为强化请求 if (isEnhanceRequest(data)) { const enhanceData = parseEnhanceData(data); if (enhanceData && enhanceData.fullPayload) { // 储存完整的强化数据供后续自动使用 storedEnhanceData = enhanceData.fullPayload; saveStoredRequest(); // 保存到本地存储 updateProtectDisplay(); // 更新保护材料显示 // 检测到手动强化指令,如果批量次数为0,设为1 if (currentBatchCount === 0) { currentBatchCount = 1; batchCountInput.value = 1; BATCH_COUNT = 1; saveConfig(); // 保存批量次数 updateMinimizedDisplay(); // 更新收起状态显示 } // Debug模式记录强化请求保存 if (DEBUG_MODE) { console.group('💾 [强化助手] 保存强化请求数据'); console.log('原始数据:', data); console.log('保存的完整数据:', storedEnhanceData); console.log('解析结果:', { 物品ID: enhanceData.resourceId, 保护材料ID: enhanceData.protectedResourceId || '无', 用户: enhanceData.user, 批量次数设置: currentBatchCount, 时间: new Date().toLocaleTimeString() }); console.groupEnd(); } } // Debug模式记录强化请求拦截 if (DEBUG_MODE) { console.group('🔨 [强化助手] 拦截到强化请求'); console.log('原始数据:', data); if (enhanceData) { console.log('解析结果:', { 物品ID: enhanceData.resourceId, 保护材料ID: enhanceData.protectedResourceId || '无', 用户: enhanceData.user, 时间: new Date().toLocaleTimeString() }); } console.groupEnd(); } } // 正常发送原始请求,不影响游戏运行 originalSend.call(this, data); }; // —— 拦截接收消息并解压 —— ws.addEventListener('message', ev => { if (ev.data instanceof ArrayBuffer) { try { const format = detectCompression(ev.data); let text; switch (format) { case 'gzip': text = pako.ungzip(new Uint8Array(ev.data), { to: 'string' }); break; case 'zlib': text = pako.inflate(new Uint8Array(ev.data), { to: 'string' }); break; default: text = pako.inflateRaw(new Uint8Array(ev.data), { to: 'string' }); } // 检查是否为强化结果(不管是否在等待,都要处理) const enhanceResult = parseEnhanceResult(text); if (enhanceResult) { // Debug模式记录强化结果 if (DEBUG_MODE) { console.group('✨ [强化助手] 拦截到强化结果'); console.log('原始数据:', text); console.log('解析结果:', { 成功: enhanceResult.success, 消息: enhanceResult.message, 结果物品ID: enhanceResult.resultId, 用户: enhanceResult.user, 时间: new Date().toLocaleTimeString() }); // 如果有保存的请求数据,也显示相关信息 if (storedEnhanceData && storedEnhanceData.data) { console.log('关联的请求信息:', { 原始物品ID: storedEnhanceData.data.resourceId, 保护材料ID: storedEnhanceData.data.protectedResourceId || '无' }); } console.groupEnd(); } handleEnhanceResult(enhanceResult); } } catch (err) { // 解压失败,忽略 } } }); // WebSocket关闭时清理 ws.addEventListener('close', () => { if (isAutoEnhancing) { stopAutoEnhance(); isAutoEnhancing = false; updateToggleButtonState(); statusSpan.textContent = '连接断开'; statusSpan.style.color = '#f44336'; counterSpan.textContent = '离线'; updateMinimizedDisplay(); } }); return ws; }; // 继承原型与静态属性 window.WebSocket.prototype = OriginalWebSocket.prototype; Object.getOwnPropertyNames(OriginalWebSocket).forEach(prop => { if (!(prop in window.WebSocket)) { window.WebSocket[prop] = OriginalWebSocket[prop]; } }); // 标记已被强化助手拦截 window.WebSocket.__enhanceHelperIntercepted = true; } // —— 窗口大小改变时检查面板位置 —— window.addEventListener('resize', () => { const rect = panel.getBoundingClientRect(); const rightDistance = window.innerWidth - rect.right; const topDistance = rect.top; // 检查并应用边界约束 const constrained = constrainPosition(rightDistance, topDistance); // 如果位置需要调整,立即应用 if (constrained.x !== rightDistance || constrained.y !== topDistance) { panel.style.right = constrained.x + 'px'; panel.style.top = constrained.y + 'px'; panel.style.left = 'auto'; savePosition(constrained.x, constrained.y); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址