// ==UserScript==
// @name 游戏盈亏监控脚本
// @namespace https://greasyfork.org/users/your-id
// @version 1.0.0
// @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: 60000, // 检查间隔(毫秒)
profitThreshold: null, // 盈利阈值
lossThreshold: null, // 亏损阈值
monitoring: false,
currentIndex: 0,
columnIndex: 7, // 游戏盈亏所在列下标(从0开始)
retryCount: 0, // 重试计数器
maxRetries: 3 // 最大重试次数
};
// 创建UI控制面板
function createControlPanel() {
const panel = document.createElement('div');
panel.style.position = 'fixed';
panel.style.top = '20px';
panel.style.right = '20px';
panel.style.zIndex = '9999';
panel.style.backgroundColor = '#fff';
panel.style.padding = '10px';
panel.style.border = '1px solid #ddd';
panel.style.borderRadius = '5px';
panel.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)';
panel.innerHTML = `
游戏盈亏监控
状态: 未启动
`;
document.body.appendChild(panel);
// 事件监听
document.getElementById('toggleMonitor').addEventListener('click', toggleMonitoring);
}
// 切换监控状态
function toggleMonitoring() {
const profitThreshold = parseFloat(document.getElementById('profitThresholdInput').value);
const lossThreshold = parseFloat(document.getElementById('lossThresholdInput').value);
if (isNaN(profitThreshold) && isNaN(lossThreshold)) {
alert('请至少设置一个有效的阈值');
return;
}
config.profitThreshold = isNaN(profitThreshold) ? null : profitThreshold;
config.lossThreshold = isNaN(lossThreshold) ? null : Math.abs(lossThreshold);
config.monitoring = !config.monitoring;
const btn = document.getElementById('toggleMonitor');
const status = document.getElementById('statusText');
if (config.monitoring) {
btn.textContent = '停止监控';
btn.style.backgroundColor = '#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.backgroundColor = '#409EFF';
status.textContent = '状态: 已停止';
config.retryCount = 0;
}
}
// 主监控流程
function startMonitoring() {
if (!config.monitoring) return;
// 1. 设置查询时间范围
setTimeRange();
// 2. 点击查询按钮
setTimeout(() => {
const queryBtns = document.querySelectorAll('.filter-container button.el-button');
let queryBtn = null;
// 找到第一个非禁用的查询按钮
for (let btn of queryBtns) {
if (!btn.classList.contains('is-disabled') && btn.textContent.includes('查询')) {
queryBtn = btn;
break;
}
}
if (queryBtn) {
queryBtn.click();
config.retryCount = 0; // 重置重试计数器
// 3. 等待数据加载后开始检查用户
setTimeout(checkUsers, 3000);
} else {
console.log('未找到查询按钮');
if (config.retryCount++ < config.maxRetries) {
setTimeout(startMonitoring, 1000);
} else {
alert('多次尝试后仍未找到查询按钮,请手动检查页面');
toggleMonitoring();
}
}
}, 1000);
}
// 设置查询时间范围
function setTimeRange() {
const minutes = parseInt(document.getElementById('minutesInput').value) || 40;
const now = new Date();
const startTime = new Date(now.getTime() - minutes * 60000);
// 格式化时间 YYYY-MM-DD HH:mm:ss
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(now);
// 触发变更事件
timeInputs[0].dispatchEvent(new Event('input', { bubbles: true }));
timeInputs[1].dispatchEvent(new Event('input', { bubbles: true }));
}
}
// 检查用户列表
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) {
// 所有用户检查完成,重新开始
setTimeout(startMonitoring, config.checkInterval);
return;
}
const currentRow = userRows[config.currentIndex];
const userNameElement = currentRow.querySelector('.el-tooltip[style*="color: rgb(24, 144, 255)"]');
if (userNameElement) {
// 确保元素可见(滚动到视图)
userNameElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
// 创建并触发点击事件
setTimeout(() => {
const clickEvent = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});
userNameElement.dispatchEvent(clickEvent);
// 等待详情弹窗打开
setTimeout(() => {
checkUserProfit(currentRow, userNameElement.textContent.trim());
}, 1500);
}, 500);
} else {
// 没有找到用户元素,跳过
config.currentIndex++;
setTimeout(checkNextUser, 500);
}
}
// 检查用户盈亏
function checkUserProfit(row, userName) {
// 查找第7列盈亏数据
const profitCell = document.querySelector(`.el-dialog__body .el-table__row td:nth-child(${config.columnIndex + 1}) .cell`);
if (!profitCell) {
console.log('未找到盈亏数据,尝试重新获取...');
if (config.retryCount++ < config.maxRetries) {
setTimeout(() => checkUserProfit(row, userName), 1000);
return;
}
console.log(`用户 ${userName} 详情弹窗可能未正确打开`);
closeDialog();
config.currentIndex++;
setTimeout(checkNextUser, 500);
return;
}
const text = profitCell.textContent.trim();
const isProfit = text.includes('+');
const value = parseFloat(text.replace(/[^\d.-]/g, ''));
if (isNaN(value)) {
console.log(`用户 ${userName} 盈亏数据解析失败: ${text}`);
closeDialog();
config.currentIndex++;
setTimeout(checkNextUser, 500);
return;
}
let alertMsg = '';
if (isProfit && config.profitThreshold && value >= config.profitThreshold) {
alertMsg = `用户 ${userName} 盈利达到 +${value},超过阈值 ${config.profitThreshold}`;
} else if (!isProfit && config.lossThreshold && Math.abs(value) >= config.lossThreshold) {
alertMsg = `用户 ${userName} 亏损达到 ${value},超过阈值 ${config.lossThreshold}`;
}
if (alertMsg) {
alert(alertMsg);
console.warn(alertMsg);
}
// 关闭详情弹窗
closeDialog();
// 检查下一个用户
config.currentIndex++;
setTimeout(checkNextUser, 1000);
}
// 关闭详情弹窗
function closeDialog() {
const closeBtn = document.querySelector('.el-dialog__headerbtn');
if (closeBtn) {
closeBtn.click();
}
config.retryCount = 0;
}
// 初始化
function init() {
// 确保页面主体已加载
const checkExist = setInterval(() => {
if (document.querySelector('.el-table')) {
clearInterval(checkExist);
createControlPanel();
console.log('游戏盈亏监控脚本已加载,请设置阈值后启动监控');
}
}, 500);
}
// 页面加载完成后初始化
if (document.readyState === 'complete') {
init();
} else {
window.addEventListener('load', init);
}
})();