// ==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();
})();