// ==UserScript== // @name 乐斗辅助 // @namespace http://tampermonkey.net/ // @version 1.6.6 // @description 提供系统繁忙监控、定时刷新、碎片监控、骑士岛任务、自动抢地盘、武器血量高亮、黄历、购物道具仓库余量显示 // @author xiong1136108122 // @match https://dld.qzapp.z.qq.com/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js // @connect qzapp.z.qq.com // @connect fight.pet.qq.com // @connect dld.qzapp.z.qq.com // ==/UserScript== (function() { 'use strict'; // 配置存储 const CONFIG = { systemBusy: { enabled: GM_getValue('systemBusyEnabled', true), targetText: GM_getValue('systemBusyTargetText', '系统繁忙'), checkInterval: GM_getValue('systemBusyCheckInterval', 100), refreshCooldown: GM_getValue('systemBusyRefreshCooldown', 2000) }, autoRefresh: { enabled: GM_getValue('autoRefreshEnabled', false), interval: GM_getValue('autoRefreshInterval', 2), stopKeywords: GM_getValue('autoRefreshStopKeywords', ['不足','不够']) }, fragmentMonitor: { enabled: GM_getValue('fragmentMonitorEnabled', false), checkUrl: 'https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?zapp_uin=&B_UID=0&sid=&channel=0&g_ut=1&cmd=newAct&subtype=154', jumpUrl: 'https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?zapp_uin=&B_UID=0&sid=&channel=0&g_ut=1&cmd=newAct&subtype=155', triggerKeywords: GM_getValue('fragmentTriggerKeywords', ['王重阳', '王处一']), stopKeywords: GM_getValue('fragmentStopKeywords', ['数量:0', '碎片*5']), interval: GM_getValue('fragmentMonitorInterval', 2) }, knightIsland: { enabled: GM_getValue('knightIslandEnabled', true), checkInterval: GM_getValue('knightIslandCheckInterval', 90), // 90分钟检查一次 backgroundCheck: GM_getValue('knightIslandBackgroundCheck', true) // 新增:是否启用后台监控 }, territoryGrabber: { enabled: GM_getValue('territoryGrabberEnabled', false), targetLevel: GM_getValue('territoryGrabberTargetLevel', 30), retryLimit: GM_getValue('territoryGrabberRetryLimit', 3), baseDelay: GM_getValue('territoryGrabberBaseDelay', 2000), maxRandomDelay: GM_getValue('territoryGrabberMaxRandomDelay', 3000) }, hpHighlight: { enabled: GM_getValue('hpHighlightEnabled', true) }, goodsStock: { enabled: GM_getValue('goodsStockEnabled', true) } }; // 定时器变量 let module2Timer = null; let module3Timer = null; let module4Timer = null; let territoryGrabberRetryCount = 0; let dailyTaskCount = 0; const MAX_DAILY_TASKS = 3; // 创建控制面板UI function createControlPanel() { GM_addStyle(` #gameHelperPanel { position: fixed; bottom: 50px; right: 30px; width: 180px; background: rgba(0, 0, 0, 0.8); color: white; border-radius: 5px; padding: 8px; z-index: 9999; font-family: Arial, sans-serif; box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); } #gameHelperPanel h3 { margin-top: 0; padding-bottom: 5px; border-bottom: 1px solid #444; cursor: move; } .module { margin-bottom: 10px; padding: 8px; background: rgba(255, 255, 255, 0.1); border-radius: 3px; } .module-title { font-weight: bold; margin-bottom: 3px; display: flex; justify-content: space-between; align-items: center; cursor: pointer; font-size: 14px; } .module-content { padding-left: 10px; display: none; } .module.active .module-content { display: block; } .switch { position: relative; display: inline-block; width: 36px; height: 18px; } .switch input { opacity: 0; width: 0; height: 0; } .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .4s; border-radius: 18px; } .slider:before { position: absolute; content: ""; height: 14px; width: 14px; left: 2px; bottom: 2px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .slider { background-color: #2196F3; } input:checked + .slider:before { transform: translateX(16px); } .settings { font-size: 12px; margin-top: 5px; } .settings label { display: block; margin: 5px 0; } .settings input[type="text"], .settings input[type="number"] { width: 100%; padding: 3px; box-sizing: border-box; background: rgba(255, 255, 255, 0.2); border: 1px solid #444; color: white; } .settings button { background: #2196F3; color: white; border: none; padding: 3px 8px; border-radius: 3px; cursor: pointer; margin-top: 5px; } .knight-link { position: relative; } .knight-badge { position: absolute; top: -5px; right: -5px; font-size: 10px; color: gold; } .task-auto-info { color: #888; font-size: 12px; margin-top: 5px; } `); const panel = document.createElement('div'); panel.id = 'gameHelperPanel'; panel.innerHTML = `

请你愉快

繁忙乐斗
定时刷新
小二上酒
侠客行
自动领取并执行剩余任务
抢个地盘
`; document.body.appendChild(panel); // 获取并显示今日buff fetchBuffInfo(); // 绑定事件 document.querySelectorAll('.module-title').forEach(title => { title.addEventListener('click', function() { this.parentElement.classList.toggle('active'); }); }); document.getElementById('systemBusyToggle').addEventListener('change', function() { CONFIG.systemBusy.enabled = this.checked; GM_setValue('systemBusyEnabled', this.checked); if (this.checked) startSystemBusyMonitor(); else stopSystemBusyMonitor(); }); document.getElementById('autoRefreshToggle').addEventListener('change', function() { CONFIG.autoRefresh.enabled = this.checked; GM_setValue('autoRefreshEnabled', this.checked); if (this.checked) startAutoRefresh(); else stopAutoRefresh(); }); document.getElementById('fragmentMonitorToggle').addEventListener('change', function() { CONFIG.fragmentMonitor.enabled = this.checked; GM_setValue('fragmentMonitorEnabled', this.checked); if (this.checked) startFragmentMonitor(); else stopFragmentMonitor(); }); document.getElementById('knightIslandToggle').addEventListener('change', function() { CONFIG.knightIsland.enabled = this.checked; GM_setValue('knightIslandEnabled', this.checked); if (this.checked) initKnightIsland(); else deinitKnightIsland(); }); document.getElementById('territoryGrabberToggle').addEventListener('change', function() { CONFIG.territoryGrabber.enabled = this.checked; GM_setValue('territoryGrabberEnabled', this.checked); if (this.checked) startTerritoryGrabber(); else stopTerritoryGrabber(); }); document.getElementById('saveSystemBusySettings').addEventListener('click', saveSystemBusySettings); document.getElementById('saveAutoRefresh').addEventListener('click', saveAutoRefreshSettings); document.getElementById('saveFragmentMonitor').addEventListener('click', saveFragmentMonitorSettings); document.getElementById('saveKnightIsland').addEventListener('click', saveKnightIslandSettings); document.getElementById('saveTerritoryGrabber').addEventListener('click', saveTerritoryGrabberSettings); // 使面板可拖动 makePanelDraggable(panel); } /* ========== 通用功能 ========== */ function getPageText() { return document.body.innerText || document.body.textContent; } function makePanelDraggable(panel) { const title = panel.querySelector('h3'); let isDragging = false; let offsetX, offsetY; title.addEventListener('mousedown', function(e) { isDragging = true; offsetX = e.clientX - panel.getBoundingClientRect().left; offsetY = e.clientY - panel.getBoundingClientRect().top; panel.style.cursor = 'grabbing'; }); document.addEventListener('mousemove', function(e) { if (!isDragging) return; panel.style.left = (e.clientX - offsetX) + 'px'; panel.style.top = (e.clientY - offsetY) + 'px'; panel.style.right = 'auto'; panel.style.bottom = 'auto'; }); document.addEventListener('mouseup', function() { isDragging = false; panel.style.cursor = ''; }); } /* ========== 模块1:系统繁忙监控 ========== */ let systemBusyMonitorInterval = null; let lastRefreshTime = 0; function startSystemBusyMonitor() { stopSystemBusyMonitor(); Mylog("[系统繁忙监控] 已启动,正在检测 '" + CONFIG.systemBusy.targetText + "'..."); systemBusyMonitorInterval = setInterval(() => { const now = Date.now(); if (now - lastRefreshTime < CONFIG.systemBusy.refreshCooldown) { return; } if (document.body.innerText.includes(CONFIG.systemBusy.targetText)) { Mylog("[系统繁忙监控] 检测到 '" + CONFIG.systemBusy.targetText + "',准备刷新页面..."); lastRefreshTime = now; location.reload(); } }, CONFIG.systemBusy.checkInterval); } function stopSystemBusyMonitor() { if (systemBusyMonitorInterval) { clearInterval(systemBusyMonitorInterval); systemBusyMonitorInterval = null; } } function saveSystemBusySettings() { const targetText = document.getElementById('systemBusyTargetText').value.trim(); const checkInterval = parseInt(document.getElementById('systemBusyCheckInterval').value); const refreshCooldown = parseInt(document.getElementById('systemBusyRefreshCooldown').value); CONFIG.systemBusy.targetText = targetText; CONFIG.systemBusy.checkInterval = checkInterval; CONFIG.systemBusy.refreshCooldown = refreshCooldown; GM_setValue('systemBusyTargetText', targetText); GM_setValue('systemBusyCheckInterval', checkInterval); GM_setValue('systemBusyRefreshCooldown', refreshCooldown); if (CONFIG.systemBusy.enabled) { stopSystemBusyMonitor(); startSystemBusyMonitor(); } } /* ========== 模块2:定时刷新功能 ========== */ function startAutoRefresh() { stopAutoRefresh(); const interval = CONFIG.autoRefresh.interval * 1000; module2Timer = setInterval(() => { const bodyText = getPageText(); const shouldStop = CONFIG.autoRefresh.stopKeywords.some( keyword => bodyText.includes(keyword) ); if (shouldStop) { stopAutoRefresh(); CONFIG.autoRefresh.enabled = false; GM_setValue('autoRefreshEnabled', false); document.getElementById('autoRefreshToggle').checked = false; Mylog("[定时刷新] 已检测到停止关键词,自动关闭功能"); } else { Mylog("[定时刷新] 执行定时刷新"); window.location.reload(); } }, interval); } function stopAutoRefresh() { if (module2Timer) { clearInterval(module2Timer); module2Timer = null; } } function saveAutoRefreshSettings() { const interval = parseFloat(document.getElementById('autoRefreshInterval').value); const stopKeywords = document.getElementById('autoRefreshStopKeywords').value .split(/[,,]/) .map(s => s.trim()) .filter(s => s); CONFIG.autoRefresh.interval = interval; CONFIG.autoRefresh.stopKeywords = stopKeywords; GM_setValue('autoRefreshInterval', interval); GM_setValue('autoRefreshStopKeywords', stopKeywords); if (CONFIG.autoRefresh.enabled) { stopAutoRefresh(); startAutoRefresh(); } } /* ========== 模块3:客栈同福监控功能 ========== */ function startFragmentMonitor() { stopFragmentMonitor(); const interval = CONFIG.fragmentMonitor.interval * 3600 * 1000; checkTargetPage(); module3Timer = setInterval(checkTargetPage, interval); Mylog("[来福监控] 已启动,间隔:" + CONFIG.fragmentMonitor.interval + "小时"); } function stopFragmentMonitor() { if (module3Timer) { clearInterval(module3Timer); module3Timer = null; Mylog("[来福监控] 已停止"); } } function checkTargetPage() { Mylog("[来福监控] 开始检查目标页面"); GM_xmlhttpRequest({ method: 'GET', url: CONFIG.fragmentMonitor.checkUrl, onload: function(response) { const text = response.responseText; const shouldJump = CONFIG.fragmentMonitor.triggerKeywords.some( keyword => text.includes(keyword+"碎片") ) && !CONFIG.fragmentMonitor.stopKeywords.some( keyword => text.includes(keyword) ); if (shouldJump) { Mylog("[来福监控] 检测到目标碎片,准备跳转"); window.location.href = CONFIG.fragmentMonitor.jumpUrl; } else { Mylog("[来福监控] 未检测到目标碎片"); } }, onerror: function(error) { console.error("[来福监控] 检查失败:", error); } }); } function saveFragmentMonitorSettings() { const interval = parseInt(document.getElementById('fragmentMonitorInterval').value); const triggerKeywords = document.getElementById('fragmentTriggerKeywords').value .split(/[,,]/) .map(s => s.trim()) .filter(s => s); const stopKeywords = document.getElementById('fragmentStopKeywords').value .split(/[,,]/) .map(s => s.trim()) .filter(s => s); CONFIG.fragmentMonitor.interval = interval; CONFIG.fragmentMonitor.triggerKeywords = triggerKeywords; CONFIG.fragmentMonitor.stopKeywords = stopKeywords; GM_setValue('fragmentMonitorInterval', interval); GM_setValue('fragmentTriggerKeywords', triggerKeywords); GM_setValue('fragmentStopKeywords', stopKeywords); if (CONFIG.fragmentMonitor.enabled) { stopFragmentMonitor(); startFragmentMonitor(); } } /* ========== 模块4:侠客岛任务模块 ========== */ let knightIslandObserver = null; const TASK_DELAY = 5000; // 任务操作间隔5秒 let knightIslandCheckTimer = null; // 后台检查定时器 // 初始化侠客岛功能 function initKnightIsland() { // 如果当前是侠客岛页面,初始化页面功能 if (isKnightIslandPage()) { modifyKnightLinks(); // 设置观察者监控DOM变化 knightIslandObserver = new MutationObserver(function(mutations) { // 检查是否有内容变化涉及到任务列表 const shouldUpdate = mutations.some(mutation => { return Array.from(mutation.addedNodes).some(node => { return node.nodeType === 1 && (node.querySelector('a[href*="op=refreshmission"]') || node.textContent.includes('今日免费刷新剩余')); }); }); if (shouldUpdate) { modifyKnightLinks(); } }); knightIslandObserver.observe(document.body, { childList: true, subtree: true, characterData: true }); } // 启动自动领取检查 startAutoClaimCheck(); } // 检查是否是侠客岛页面 function isKnightIslandPage() { return location.href.includes('cmd=knight_island'); } // 修改任务链接样式和行为 function modifyKnightLinks() { // 先检查免费刷新次数 const refreshText = document.body.textContent.match(/今日免费刷新剩余:(\d+)次/); const freeRefreshCount = refreshText ? parseInt(refreshText[1]) : 0; // 获取所有刷新按钮 const refreshLinks = document.querySelectorAll('a[href*="op=refreshmission"]'); // 如果免费刷新次数为0,禁用所有刷新按钮 if (freeRefreshCount === 0) { refreshLinks.forEach(link => { link.style.opacity = '0.5'; link.style.pointerEvents = 'none'; link.style.cursor = 'not-allowed'; link.title = '今日免费刷新次数已用完'; // 替换原有点击事件 link.addEventListener('click', function(e) { e.preventDefault(); alert('今日免费刷新次数已用完!'); }); }); } else { // 如果还有免费次数,恢复按钮状态 refreshLinks.forEach(link => { link.style.opacity = ''; link.style.pointerEvents = ''; link.style.cursor = ''; link.title = ''; }); } const viewLinks = document.querySelectorAll('a[href*="op=viewmissiondetail"]'); viewLinks.forEach(link => { if (link.dataset.ledouProcessed) return; link.dataset.ledouProcessed = 'true'; // 添加闪电图标 const badge = document.createElement('span'); badge.textContent = '⚡'; badge.className = 'knight-badge'; link.classList.add('knight-link'); link.appendChild(badge); // 修改点击行为 link.addEventListener('click', function(e) { e.preventDefault(); const url = new URL(this.href); const params = Object.fromEntries(url.searchParams.entries()); try { executeTaskFlow( params.zapp_uin, params.sid, params.pos || '0', this.href ); } catch (error) { Mylog('任务执行出错:', error); } }); }); } // 修改后的执行任务流程函数 function executeTaskFlow(zapp_uin, sid, pos, originalUrl) { const baseUrl = `https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?zapp_uin=${zapp_uin}&sid=${sid}&channel=0&g_ut=1&cmd=knight_island&pos=${pos}`; // 前两个操作在后台执行 Promise.resolve() .then(() => safeRequest(`${baseUrl}&op=viewmissiondetail`)) .then(() => safeRequest(`${baseUrl}&op=autoassign`)) .then(() => safeRequest(`${baseUrl}&op=autoassign`))//执行两次防止系统繁忙无法开始 .then(() => { // begin操作在前台执行,触发页面刷新 window.location.href = `${baseUrl}&op=begin`; }) .catch(error => { Mylog('任务执行出错:', error); // 出错时返回原始页面 window.location.href = originalUrl; }); } // 刷新任务列表 function refreshMissionList(zapp_uin, sid) { const missionListUrl = `https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?zapp_uin=${zapp_uin}&sid=${sid}&channel=0&g_ut=1&cmd=knight_island&op=viewmissionindex`; safeRequest(missionListUrl) .then(response => { const parser = new DOMParser(); const doc = parser.parseFromString(response.responseText, 'text/html'); const newContent = doc.querySelector('#mission-list-container'); if (newContent && document.querySelector('#mission-list-container')) { document.querySelector('#mission-list-container').innerHTML = newContent.innerHTML; modifyKnightLinks(); } }) .catch(error => { Mylog('刷新任务列表失败:', error); }); } // 启动自动领取检查 function startAutoClaimCheck() { stopAutoClaimCheck(); // 立即检查一次 checkAndClaimRewards(); // 设置定时检查(每5分钟检查一次) knightIslandCheckTimer = setInterval(() => { checkAndClaimRewards(); }, 5 * 60 * 1000); } // 停止自动领取检查 function stopAutoClaimCheck() { if (knightIslandCheckTimer) { clearInterval(knightIslandCheckTimer); knightIslandCheckTimer = null; } } // 检查并领取奖励(全页面可用,不跳转) function checkAndClaimRewards() { if (!CONFIG.knightIsland.enabled) return; fetchKnightIslandData() .then(data => { if (data.hasRewards) { Mylog(`[侠客岛] 发现${data.rewardCount}个可领取奖励,开始远程领取`); // 直接通过API领取奖励 claimRewardsRemotely(data.rewardLinks); } }); } // 通过API直接领取奖励 function claimRewardsRemotely(rewardLinks) { rewardLinks.forEach((link, index) => { setTimeout(() => { const fullUrl = `https:${link.getAttribute('href')}`; GM_xmlhttpRequest({ method: "GET", url: fullUrl, onload: function(response) { Mylog(`[侠客岛] 远程领取成功: ${fullUrl}`); // 可以在这里添加领取成功后的处理逻辑 }, onerror: function(error) { Mylog(`[侠客岛] 远程领取失败: ${fullUrl}`, error); } }); }, index * TASK_DELAY); }); } // 获取侠客岛任务数据(增强版) function fetchKnightIslandData() { return new Promise((resolve) => { const missionUrl = "https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?cmd=knight_island&op=viewmissionindex"; GM_xmlhttpRequest({ method: "GET", url: missionUrl, onload: function(response) { try { const parser = new DOMParser(); const doc = parser.parseFromString(response.responseText, "text/html"); const rewardLinks = [...doc.querySelectorAll('a[href*="op=getmissionreward"]')]; resolve({ hasRewards: rewardLinks.length > 0, rewardCount: rewardLinks.length, rewardLinks: rewardLinks, missionUrl: missionUrl }); } catch (e) { console.error("[侠客岛] 解析任务数据失败:", e); resolve({ hasRewards: false }); } }, onerror: function(error) { console.error("[侠客岛] 获取任务数据失败:", error); resolve({ hasRewards: false }); } }); }); } // 清理侠客岛功能 function deinitKnightIsland() { if (knightIslandObserver) { knightIslandObserver.disconnect(); knightIslandObserver = null; } stopAutoClaimCheck(); const processedLinks = document.querySelectorAll('[data-ledou-processed]'); processedLinks.forEach(link => { delete link.dataset.ledouProcessed; const badge = link.querySelector('.knight-badge'); if (badge) badge.remove(); link.classList.remove('knight-link'); link.replaceWith(link.cloneNode(true)); }); } // 保存侠客岛设置 function saveKnightIslandSettings() { const checkInterval = parseInt(document.getElementById('knightIslandCheckInterval').value); const backgroundCheck = document.getElementById('knightIslandBackgroundCheck').checked; CONFIG.knightIsland.checkInterval = checkInterval; CONFIG.knightIsland.backgroundCheck = backgroundCheck; GM_setValue('knightIslandCheckInterval', checkInterval); GM_setValue('knightIslandBackgroundCheck', backgroundCheck); if (CONFIG.knightIsland.enabled && backgroundCheck) { startAutoClaimCheck(); } else { stopAutoClaimCheck(); } Mylog("[侠客岛] 设置已保存"); } // 辅助函数:延迟执行 function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 辅助函数:安全请求 function safeRequest(url) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: url, onload: resolve, onerror: reject }); }); } /* ========== 模块5:每日黄历 ========== */ function fetchBuffInfo() { GM_xmlhttpRequest({ method: "GET", url: "https://fight.pet.qq.com/cgi-bin/petpk?cmd=calender", onload: (response) => { try { const data = JSON.parse(response.responseText); const simplifiedBuff = simplifyBuff(data.buff); displayBuff(simplifiedBuff); } catch (e) { console.error(e); } } }); } const BUFF_MAPPING = { "斗神塔": "刷塔", "画卷": "画卷", "副本经验双倍": "副本", "乐斗经验双倍": "经验", "阅历双倍": "阅历", "暂无": "OvO" }; function simplifyBuff(buffText) { if (!buffText) return "OvO"; for (const [keyword, simplified] of Object.entries(BUFF_MAPPING)) { if (buffText.includes(keyword)) { return simplified; } } return buffText.length > 20 ? buffText.substring(0, 20) + "..." : buffText; } function displayBuff(buffText) { const title = document.getElementById('panelTitle'); if (title && !title.querySelector('.buff-info')) { const buffSpan = document.createElement('span'); buffSpan.className = 'buff-info'; buffSpan.style.marginLeft = '10px'; buffSpan.style.fontSize = '14px'; buffSpan.style.color = '#FFD700'; buffSpan.textContent = `[${buffText || "暂无"}]`; title.appendChild(buffSpan); } } /* ========== 模块6:抢地盘 ========== */ function startTerritoryGrabber() { territoryGrabberRetryCount = 0; Mylog("[抢地盘] 功能已启动,正在寻找目标地盘..."); executeTerritoryGrabber(); } function stopTerritoryGrabber() { Mylog("[抢地盘] 功能已停止"); territoryGrabberRetryCount = 0; } async function executeTerritoryGrabber() { if (!CONFIG.territoryGrabber.enabled) return; try { Mylog("[抢地盘] 正在获取地盘列表..."); const data = await getRecommendmanorData(); if (data.result === "0" && data.manors?.length > 0) { const targetManor = data.manors.find(manor => manor.ownerlevel === CONFIG.territoryGrabber.targetLevel.toString() ); if (targetManor) { Mylog(`[抢地盘] 找到${CONFIG.territoryGrabber.targetLevel}级NPC地盘: ${targetManor.name}, ID: ${targetManor.id}`); await randomDelay(); //无法解析成功失败活繁忙,执行2次避免失败 await attackManor(targetManor.id); await attackManor(targetManor.id); await getReward(); await getReward(); // 完成后自动关闭 CONFIG.territoryGrabber.enabled = false; GM_setValue('territoryGrabberEnabled', false); document.getElementById('territoryGrabberToggle').checked = false; Mylog("[抢地盘] 操作完成,功能已自动关闭"); } else { handleTerritoryRetry("未找到目标等级NPC地盘"); } } else { handleTerritoryRetry("获取地盘列表失败或列表为空"); } } catch (e) { console.error("[抢地盘] 操作失败:", e); handleTerritoryRetry(e.message); } } function handleTerritoryRetry(reason) { territoryGrabberRetryCount++; Mylog(`[抢地盘] ${reason},准备重试 (${territoryGrabberRetryCount}`); setTimeout(executeTerritoryGrabber, CONFIG.territoryGrabber.baseDelay); } function randomDelay() { const delay = CONFIG.territoryGrabber.baseDelay + Math.random() * CONFIG.territoryGrabber.maxRandomDelay; return new Promise(resolve => setTimeout(resolve, delay)); } function getRecommendmanorData() { return new Promise((resolve, reject) => { const apiUrl = 'https://fight.pet.qq.com/cgi-bin/petpk?cmd=recommendmanor&type=11&page=1'; GM_xmlhttpRequest({ method: "GET", url: apiUrl, timeout: 10000, onload: function(response) { try { if (!response.responseText || response.responseText.trim().startsWith('<')) { throw new Error('服务器返回无效响应'); } const data = JSON.parse(response.responseText); if (data.result !== "0") { throw new Error(data.msg || '服务器返回错误'); } if (!data.manors || !Array.isArray(data.manors)) { throw new Error('无效的地盘数据'); } resolve(data); } catch (e) { console.error('[抢地盘] 解析失败:', e); reject(e); } }, onerror: function(error) { reject(new Error(`请求失败: ${error.statusText}`)); }, ontimeout: function() { reject(new Error('请求超时')); } }); }); } function attackManor(manorId) { return new Promise((resolve, reject) => { const attackUrl = `https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?cmd=manorfight&fighttype=1&manorid=${manorId}`; Mylog(`[抢地盘] 正在抢夺地盘: ${manorId}`); GM_xmlhttpRequest({ method: "GET", url: attackUrl, onload: function(response) { try { const result = JSON.parse(response.responseText); if (result.result === "0") { Mylog("[抢地盘] 抢夺成功"); } else { Mylog("[抢地盘] 抢夺失败", result.msg || "未知错误"); } } catch (e) { console.error("[抢地盘] 抢夺结果失败:", e); } finally { resolve(); } }, onerror: function(error) { console.error("[抢地盘] 抢夺请求失败:", error); resolve(); } }); }); } function getReward() { return new Promise((resolve) => { const rewardUrl = "https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?cmd=manorget&type=1"; Mylog("[抢地盘] 正在尝试领取奖励..."); GM_xmlhttpRequest({ method: "GET", url: rewardUrl, onload: function(response) { try { const result = JSON.parse(response.responseText); if (result.result === "0") { Mylog("[抢地盘] 奖励领取成功"); } else { Mylog("[抢地盘] 奖励领取失败:", result.msg || "未知错误"); } } catch (e) { console.error("[抢地盘] 解析奖励结果失败:", e); } finally { resolve(); } }, onerror: function(error) { console.error("[抢地盘] 领取奖励请求失败:", error); resolve(); } }); }); } function saveTerritoryGrabberSettings() { const targetLevel = parseInt(document.getElementById('territoryGrabberTargetLevel').value); const retryLimit = parseInt(document.getElementById('territoryGrabberRetryLimit').value); const baseDelay = parseInt(document.getElementById('territoryGrabberBaseDelay').value); const maxRandomDelay = parseInt(document.getElementById('territoryGrabberMaxRandomDelay').value); CONFIG.territoryGrabber.targetLevel = targetLevel; CONFIG.territoryGrabber.retryLimit = retryLimit; CONFIG.territoryGrabber.baseDelay = baseDelay; CONFIG.territoryGrabber.maxRandomDelay = maxRandomDelay; GM_setValue('territoryGrabberTargetLevel', targetLevel); GM_setValue('territoryGrabberRetryLimit', retryLimit); GM_setValue('territoryGrabberBaseDelay', baseDelay); GM_setValue('territoryGrabberMaxRandomDelay', maxRandomDelay); Mylog("[抢地盘] 设置已保存"); } /* ========== 模块7:血量高亮 ========== */ function initHPHighlight() { if (!CONFIG.hpHighlight.enabled) return; GM_addStyle(` .tm-hp-change { display: inline; white-space: nowrap; } .tm-hp-plus { color: #00aa00; font-weight: bold; } /* 绿色 */ .tm-hp-minus { color: #ff0000; font-weight: bold; } /* 红色 */ .tm-key-weapon { color: #aa00aa; font-weight: bold; } /* 紫色 */ .tm-keyword-bold { color: #1ba784; font-weight: bold; } /* 蓝色 */ `); const hpRegexChange = /(HP[+-]\d+)/g; const hpRegexRemain = /(HP余\d+)/g; // 添加螺旋丸伤害规则 const spiralRegex = /(反弹给对方(\d+)的伤害!)/g; // 关键武器列表(使用正则表达式匹配) const weaponRegex = /(神·霸皇|盘古开天斧|神·大力神杯|神·雷神之锤|神·炼狱加特林|加特林|神·死寂|死神之镰|神·无限板砖|神·埃辛诺斯战刃|神·命运之枪|神·龙雀|神·马格南左轮|神·月光炮|神·电饭煲|神·星之杖|神·死亡笔记|生死簿|神·冈格尼尔|神·可乐切割枪|神·无敌飞鞋|神·花仙子)/g; // 新增关键字列表(可以根据需要添加更多关键字) const keywordRegex = /(帮派商会|帮派祭坛|全民乱斗|抢地盘|华山论剑|企鹅吉利兑|飞升大作战|群侠|祝福合集宝库|远方祝福|大侠回归三重好礼|侠客岛|任务|九宫宝库|符石百宝箱|客栈同福)/g; const safeReplace = (text) => { // 先处理关键字加粗 if (document.body.innerText.includes("【大乐斗】")) { text = text.replace(keywordRegex, (keyword) => `${keyword}` ); } // 处理武器名称 text = text.replace(weaponRegex, (weapon) => `${weapon}` ); // 然后处理HP变化 text = text.replace(hpRegexChange, (change) => `${change}` ); text = text.replace(hpRegexRemain, (remain) => `${remain}` ); // 处理反弹的伤害(将数字部分变为红色) text = text.replace(spiralRegex, (fullMatch, fullText, damage) => fullText.replace(damage, `${damage}`) ); return text; }; const processNode = (node) => { if (node.nodeType === Node.TEXT_NODE && !node.parentNode.classList.contains('tm-hp-processed') && (hpRegexChange.test(node.nodeValue) || hpRegexRemain.test(node.nodeValue) || weaponRegex.test(node.nodeValue) || spiralRegex.test(node.nodeValue) || keywordRegex.test(node.nodeValue))) { const wrapper = document.createElement('span'); wrapper.className = 'tm-hp-processed'; wrapper.innerHTML = safeReplace(node.nodeValue); node.parentNode.replaceChild(wrapper, node); } else if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains('tm-hp-processed')) { Array.from(node.childNodes).forEach(processNode); } }; processNode(document.body); } /* ========== 模块8:商品库存显示 ========== */ function initGoodsStock() { if (isViewGoodsPage()) { checkAndDisplayGoodsStock(); } } function deinitGoodsStock() { // 移除可能已存在的库存信息 const existingStock = document.getElementById('goods-stock-info'); if (existingStock) { existingStock.remove(); } } function saveGoodsStockSettings() { Mylog("[库存显示] 设置已保存"); } // 检查是否在商品查看页面 function isViewGoodsPage() { const urlParams = new URLSearchParams(window.location.search); return urlParams.get('cmd') === 'viewgoods'; } // 获取商品ID function getGoodsId() { const urlParams = new URLSearchParams(window.location.search); return urlParams.get('id'); } // 获取仓库中的商品数量 function getGoodsStock(goodsId, callback) { const apiUrl = `https://dld.qzapp.z.qq.com/qpet/cgi-bin/phonepk?zapp_uin=&sid=&channel=0&g_ut=1&cmd=owngoods&id=${goodsId}`; GM_xmlhttpRequest({ method: "GET", url: apiUrl, onload: function(response) { if (response.status === 200) { try { // 尝试解析响应 const parser = new DOMParser(); const doc = parser.parseFromString(response.responseText, "text/html"); const content = doc.body.textContent || ""; // 检查是否返回繁忙 if (content.includes("繁忙")) { callback(0, "API繁忙"); } else { // 尝试从响应中提取数量信息 const match = content.match(/数量:\s*(\d+)/); if (match && match[1]) { callback(parseInt(match[1]), null); } else { callback(0, "无法解析数量"); } } } catch (e) { callback(0, "解析响应失败"); } } else { callback(0, `请求失败: ${response.status}`); } }, onerror: function(error) { callback(0, "网络请求错误"); }, timeout: 10000 }); } // 在商品名称后面显示仓库数量 function displayStockInfo(goodsId, stock, error) { // 查找商品名称元素 - 第一个p标签内的第一个文本节点 const firstParagraph = document.querySelector('body > div > p:first-child'); if (firstParagraph) { // 查找商品名称文本节点 const textNodes = []; const walker = document.createTreeWalker(firstParagraph, NodeFilter.SHOW_TEXT, null, false); let node; while (node = walker.nextNode()) { textNodes.push(node); } if (textNodes.length > 0) { // 找到商品名称文本节点(通常是第一个) const goodsNameNode = textNodes[0]; // 移除可能已存在的库存信息 const existingStock = document.getElementById('goods-stock-info'); if (existingStock) { existingStock.remove(); } // 创建库存显示元素 const stockInfo = document.createElement('span'); stockInfo.id = 'goods-stock-info'; // 保持与页面原始样式一致 stockInfo.style.marginLeft = '5px'; stockInfo.style.fontSize = 'inherit'; stockInfo.style.fontFamily = 'inherit'; stockInfo.style.color = stock > 0 ? '#00aa00' : '#ff0000'; if (error) { stockInfo.textContent = `【背包数量:0】`; stockInfo.title = error; } else { stockInfo.textContent = `【背包数量:${stock}】`; } // 插入到商品名称后面 goodsNameNode.parentNode.insertBefore(stockInfo, goodsNameNode.nextSibling); } } } // 检查并显示商品库存 function checkAndDisplayGoodsStock() { if (!CONFIG.goodsStock.enabled) return; const goodsId = getGoodsId(); if (!goodsId) { console.log('未找到商品ID'); return; } getGoodsStock(goodsId, function(stock, error) { displayStockInfo(goodsId, stock, error); }); } function Mylog(message) { const now = new Date(); const timeStr = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`; console.log(`[${timeStr}] ${message}`); } // 初始化控制面板 createControlPanel(); // 初始化功能模块 if (CONFIG.systemBusy.enabled) startSystemBusyMonitor(); if (CONFIG.autoRefresh.enabled) startAutoRefresh(); if (CONFIG.fragmentMonitor.enabled) startFragmentMonitor(); if (CONFIG.knightIsland.enabled) initKnightIsland(); if (CONFIG.territoryGrabber.enabled) startTerritoryGrabber(); if (CONFIG.hpHighlight.enabled) initHPHighlight(); if (CONFIG.goodsStock.enabled && isViewGoodsPage()) checkAndDisplayGoodsStock(); })();