// ==UserScript== // @name 游戏盈亏监控 // @namespace https://greasyfork.org/users/your-id // @version 2.0.1 // @description 监控游戏平台的用户盈亏数据,当盈利/亏损超过设定阈值时弹窗提醒。适用于后台管理系统。大数据量优化的高效监控脚本,支持并行处理 // @author Cisco // @match https://7777m.topcms.org/* // @match https://*.topcms.org/* // @icon https://7777m.topcms.org/favicon.ico // @license MIT // @grant GM_notification // @grant GM_xmlhttpRequest // @run-at document-end // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 配置参数 const config = { checkInterval: 2000, // 检查间隔(毫秒) profitThreshold: null, // 盈利阈值 lossThreshold: null, // 亏损阈值 monitoring: false, currentIndex: 0, columnIndex: 7, // 盈亏数据列下标(从0开始) currentPage: 1, totalPages: 1, totalItems: 0, itemsPerPage: 10, retryCount: 0, maxRetries: 3 }; // 创建控制面板 function createControlPanel() { const panel = document.createElement('div'); panel.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 9999; background: white; padding: 15px; border: 1px solid #ddd; border-radius: 5px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); font-family: Arial, sans-serif; width: 280px; `; panel.innerHTML = `

游戏盈亏监控

状态: 未启动
进度: 0/0
页数: 1/1
`; document.body.appendChild(panel); document.getElementById('toggleMonitor').addEventListener('click', toggleMonitoring); } // 切换监控状态 function toggleMonitoring() { const profitVal = parseFloat(document.getElementById('profitThresholdInput').value); const lossVal = parseFloat(document.getElementById('lossThresholdInput').value); if (isNaN(profitVal) && isNaN(lossVal)) { alert('请至少设置一个阈值'); return; } config.profitThreshold = isNaN(profitVal) ? null : profitVal; config.lossThreshold = isNaN(lossVal) ? null : Math.abs(lossVal); config.monitoring = !config.monitoring; const btn = document.getElementById('toggleMonitor'); const status = document.getElementById('statusText'); if (config.monitoring) { btn.textContent = '停止监控'; btn.style.background = '#F56C6C'; let statusMsg = '监控中 ('; if (config.profitThreshold) statusMsg += `盈>${config.profitThreshold}`; if (config.lossThreshold) statusMsg += `${config.profitThreshold ? ' ' : ''}亏>${config.lossThreshold}`; status.textContent = statusMsg + ')'; startMonitoring(); } else { btn.textContent = '开始监控'; btn.style.background = '#409EFF'; status.textContent = '已停止'; } } // 主监控流程 function startMonitoring() { if (!config.monitoring) return; // 重置到第一页 const firstPageBtn = document.querySelector('.el-pager .number:first-child'); if (firstPageBtn && !firstPageBtn.classList.contains('active')) { simulateClick(firstPageBtn); setTimeout(() => initMonitoring(), 2000); } else { initMonitoring(); } } function initMonitoring() { updatePaginationInfo(); config.currentPage = 1; config.currentIndex = 0; setTimeRange(); setTimeout(() => clickQueryButton(), 1000); } // 更新分页信息 function updatePaginationInfo() { const pagination = document.querySelector('.el-pagination'); if (!pagination) { config.totalPages = 1; config.totalItems = document.querySelectorAll('.el-table__row:not(.el-table__row--level)').length; return; } // 获取总条数 const totalText = pagination.querySelector('.el-pagination__total')?.textContent || ''; config.totalItems = parseInt(totalText.match(/\d+/)?.[0] || 0); // 获取每页条数 const sizeText = pagination.querySelector('.el-select-dropdown__item.selected span')?.textContent || '10'; config.itemsPerPage = parseInt(sizeText.match(/\d+/)?.[0] || 10); // 计算总页数 config.totalPages = Math.ceil(config.totalItems / config.itemsPerPage); // 更新UI显示 document.getElementById('totalItems').textContent = config.totalItems; document.getElementById('totalPages').textContent = config.totalPages; updateProgressDisplay(); } // 更新进度显示 function updateProgressDisplay() { const currentPos = (config.currentPage - 1) * config.itemsPerPage + config.currentIndex + 1; document.getElementById('currentPosition').textContent = currentPos; document.getElementById('displayPage').textContent = config.currentPage; } // 设置时间范围(关键修改点) function setTimeRange() { const minutes = parseInt(document.getElementById('minutesInput').value) || 40; const now = new Date(); const startTime = new Date(now.getTime() - minutes * 60000); // 固定结束时间为当天23:59:59 const endTime = new Date(now); endTime.setHours(23, 59, 59, 0); const formatTime = (date) => { const pad = num => num.toString().padStart(2, '0'); return `${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`; }; const timeInputs = document.querySelectorAll('.el-range-input'); if (timeInputs.length >= 2) { timeInputs[0].value = formatTime(startTime); timeInputs[1].value = formatTime(endTime); // 固定结束时间 timeInputs.forEach(input => input.dispatchEvent(new Event('input', { bubbles: true }))); } } // 点击查询按钮 function clickQueryButton() { const queryBtn = [...document.querySelectorAll('.filter-container button.el-button')] .find(btn => !btn.classList.contains('is-disabled') && btn.textContent.includes('查询')); if (queryBtn) { simulateClick(queryBtn); setTimeout(() => checkUsers(), 3000); } else { console.log('未找到查询按钮'); if (config.retryCount++ < config.maxRetries) { setTimeout(clickQueryButton, 1000); } else { alert('无法找到查询按钮'); toggleMonitoring(); } } } // 检查用户列表 function checkUsers() { const userRows = document.querySelectorAll('.el-table__row:not(.el-table__row--level)'); if (userRows.length === 0) { console.log('未找到用户数据'); setTimeout(startMonitoring, config.checkInterval); return; } config.currentIndex = 0; checkNextUser(); } // 检查下一个用户 function checkNextUser() { if (!config.monitoring) return; const userRows = document.querySelectorAll('.el-table__row:not(.el-table__row--level)'); // 当前页检查完成 if (config.currentIndex >= userRows.length) { if (config.currentPage < config.totalPages) { goToNextPage(); } else { console.log('所有数据检查完成'); setTimeout(startMonitoring, config.checkInterval); } return; } const currentRow = userRows[config.currentIndex]; const userNameElement = currentRow.querySelector('.el-tooltip[style*="color: rgb(24, 144, 255)"]'); if (userNameElement) { scrollAndClick(userNameElement, () => { setTimeout(() => checkUserProfit(currentRow, userNameElement.textContent.trim()), 1500); }); } else { config.currentIndex++; setTimeout(checkNextUser, 500); } } // 检查用户盈亏 function checkUserProfit(row, userName) { const profitCell = document.querySelector(`.el-dialog__body .el-table__row td:nth-child(${config.columnIndex + 1}) .cell`); if (!profitCell) { console.log('未找到盈亏数据'); closeDialog(); proceedToNext(); return; } const text = profitCell.textContent.trim(); const isProfit = text.includes('+'); const value = parseFloat(text.replace(/[^\d.-]/g, '')); if (!isNaN(value)) { if (isProfit && config.profitThreshold && value >= config.profitThreshold) { notify(`用户 ${userName} 盈利超标: +${value}`, 'profit'); } else if (!isProfit && config.lossThreshold && Math.abs(value) >= config.lossThreshold) { notify(`用户 ${userName} 亏损超标: ${value}`, 'loss'); } } closeDialog(); proceedToNext(); } // 处理下一个检查 function proceedToNext() { config.currentIndex++; updateProgressDisplay(); setTimeout(checkNextUser, 800); } // 翻到下一页 function goToNextPage() { const nextBtn = document.querySelector('.el-pagination .btn-next:not([disabled])'); if (nextBtn) { simulateClick(nextBtn); setTimeout(() => { config.currentPage++; config.currentIndex = 0; updatePaginationInfo(); checkUsers(); }, 2500); } } // 关闭对话框 function closeDialog() { const closeBtn = document.querySelector('.el-dialog__headerbtn'); if (closeBtn) simulateClick(closeBtn); } // 通知提醒 function notify(message, type) { alert(message); if (typeof GM_notification !== 'undefined') { GM_notification({ title: type === 'profit' ? '盈利报警' : '亏损报警', text: message, timeout: 5000 }); } console.warn(message); } // 模拟点击(兼容Element UI) function simulateClick(element) { ['mousedown', 'mouseup', 'click'].forEach(event => { element.dispatchEvent(new MouseEvent(event, { bubbles: true })); }); } // 滚动并点击元素 function scrollAndClick(element, callback) { element.scrollIntoView({ behavior: 'smooth', block: 'center' }); setTimeout(() => { simulateClick(element); if (callback) callback(); }, 800); } // 初始化 function init() { // 等待表格加载 const checkTable = setInterval(() => { if (document.querySelector('.el-table')) { clearInterval(checkTable); createControlPanel(); console.log('脚本初始化完成'); } }, 500); } // 启动脚本 if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } })();