ONPJS

监控proof数量并在3分钟无变化时自动切换按钮状态

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         ONPJS
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  监控proof数量并在3分钟无变化时自动切换按钮状态
// @author       [email protected]
// @match        https://onprover.orochi.network/*
// @run-at       document-start
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @connect      onprover.orochi.network
// @connect      open.feishu.cn
// ==/UserScript==

(function() {
    'use strict';

    // 添加设备名称配置
    const DEVICE_NAME = 'P-1'; // 你可以修改这个设备名称
    const FEISHU_WEBHOOK = ''; //飞书 WEBHOOK

    let lastProofCount = null;
    let unchangedCount = 0;
    let isProving = true;
    let checkInterval = null;
    let isHandlingButtonState = false;
    let switchAttemptCount = 0; // 记录切换按钮尝试次数
    let lastSwitchProofCount = null; // 记录上次切换时的proof数量
    let cloudflareCheckInterval = null;
    if (FEISHU_WEBHOOK === '') {
       return;
    }
    // 发送飞书通知
    async function sendFeishuNotification(message) {
        try {
            await GM_xmlhttpRequest({
                method: 'POST',
                url: FEISHU_WEBHOOK,
                headers: {
                    'Content-Type': 'application/json'
                },
                data: JSON.stringify({
                    msg_type: 'text',
                    content: {
                        text: `[${DEVICE_NAME}] ${message}`
                    }
                })
            });
            console.log('飞书通知发送成功');
        } catch (error) {
            console.error('飞书通知发送失败:', error);
        }
    }

    // 检查是否在Cloudflare验证页面
    function isCloudflarePage() {
        return document.title.includes('Cloudflare') ||
               document.querySelector('#challenge-running') !== null ||
               document.querySelector('#challenge-stage') !== null;
    }

    // 等待Cloudflare验证完成
    function waitForCloudflare() {
        return new Promise((resolve) => {
            if (!isCloudflarePage()) {
                resolve();
                return;
            }

            console.log('检测到Cloudflare验证,等待验证完成...');

            let waitTime = 0;
            let notificationSent = false;

            const checkCloudflare = () => {
                if (!isCloudflarePage()) {
                    console.log('Cloudflare验证已完成');
                    // 重置通知状态
                    notificationSent = false;
                    resolve();
                    return;
                }

                waitTime += 1;

                // 当等待时间超过15秒且未发送过通知时发送通知
                if (waitTime >= 20 && !notificationSent) {
                    sendFeishuNotification(`Cloudflare验证时间超过15秒!当前已等待${waitTime}秒`);
                    notificationSent = true;
                }

                setTimeout(checkCloudflare, 1000);
            };

            checkCloudflare();
        });
    }

    // 获取当前proof数量
    function getProofCount() {
        const proofElement = document.querySelector('p.text-24.font-doto.text-zk-blue-300.font-bold');
        if (proofElement) {
            return parseInt(proofElement.textContent.trim());
        }
        return null;
    }

    // 获取当前按钮状态
    function getButtonState() {
        const buttons = document.querySelectorAll('button');
        for (const button of buttons) {
            if (button.textContent.includes('prove')) {
                return 'prove';
            } else if (button.textContent.includes('Stop proving')) {
                return 'stop';
            }
        }
        return null;
    }

    // 点击按钮的函数
    function clickButton() {
        const buttons = document.querySelectorAll('button');
        for (const button of buttons) {
            if (button.textContent.includes('prove') || button.textContent.includes('Stop proving')) {
                console.log('正在点击按钮:', button.textContent.trim());
                button.click();
                isProving = !isProving;
                break;
            }
        }
    }

    // 检查proof数量是否变化
    function checkProofCount() {
        const currentCount = getProofCount();

        if (currentCount === null) {
            console.log('无法获取proof数量,等待页面加载...');
            return;
        }

        if (lastProofCount === null) {
            lastProofCount = currentCount;
            console.log('初始化proof数量:', currentCount);
            return;
        }

        // 如果proof数量发生变化,重置所有计数器
        if (currentCount !== lastProofCount) {
            console.log(`Proof数量已变化: ${lastProofCount} -> ${currentCount}`);
            unchangedCount = 0;
            lastProofCount = currentCount;
            switchAttemptCount = 0;
            lastSwitchProofCount = null;
            return;
        }

        if (currentCount === lastProofCount) {
            unchangedCount++;
            console.log(`Proof数量未变化: ${currentCount}, 已持续${unchangedCount}次检查`);

            // 检查是否需要切换按钮状态或刷新页面
            if (!isHandlingButtonState) {
                const currentState = getButtonState();

                // 在Stop proving状态下,连续10次未变化时刷新页面
                if (currentState === 'stop' && unchangedCount >= 10) {
                    console.log('Stop proving状态下连续10次proof数量未变化,准备刷新页面');
                    // 保存当前状态
                    GM_setValue('lastProofCount', currentCount);
                    GM_setValue('switchAttemptCount', switchAttemptCount);
                    // 使用location.reload()进行页面刷新
                    window.location.reload();
                    return;
                }

                // 在prove状态下,连续2次未变化时切换到Stop proving
                if (currentState === 'prove' && unchangedCount === 2) {
                    console.log('Proof数量连续两次未变化且按钮为prove状态,准备切换到Stop proving状态');
                    isHandlingButtonState = true;
                    handleButtonState();
                    // 重置unchangedCount
                    unchangedCount = 0;
                }
            }
        }
    }

    // 等待按钮状态切换
    function waitForButtonState(targetState) {
        return new Promise((resolve) => {
            let attempts = 0;
            const maxAttempts = 30; // 最多等待30秒

            const checkButton = () => {
                const currentState = getButtonState();
                if (currentState === targetState) {
                    console.log(`按钮已切换到${targetState}状态`);
                    resolve(true);
                    return;
                }

                attempts++;
                if (attempts >= maxAttempts) {
                    console.log(`等待按钮切换到${targetState}状态超时`);
                    resolve(false);
                    return;
                }

                setTimeout(checkButton, 1000);
            };
            checkButton();
        });
    }

    // 处理按钮状态切换
    async function handleButtonState() {
        try {
            const currentState = getButtonState();
            console.log('当前按钮状态:', currentState);

            // 记录切换前的proof数量
            lastSwitchProofCount = getProofCount();

            if (currentState === 'prove') {
                // 如果当前是prove状态,点击切换到stop状态
                console.log('切换到Stop proving状态');
                clickButton();
                // 等待按钮状态变化
                await waitForButtonState('stop');
                // 额外等待5秒确保状态稳定
                await new Promise(resolve => setTimeout(resolve, 5000));
            } else if (currentState === 'stop') {
                // 如果当前是stop状态,等待一段时间后点击切换到prove状态
                console.log('当前是Stop proving状态,等待5秒后切换到prove状态');
                await new Promise(resolve => setTimeout(resolve, 5000));
                clickButton();
                // 等待按钮状态变化
                await waitForButtonState('prove');
                // 额外等待5秒确保状态稳定
                await new Promise(resolve => setTimeout(resolve, 5000));
            }

            // 重置计数器
            unchangedCount = 0;
            console.log('按钮状态切换完成,重置计数器');
        } finally {
            isHandlingButtonState = false;
        }
    }

    // 主循环
    function mainLoop() {
        checkProofCount();
    }

    // 等待页面加载完成
    async function waitForPageLoad() {
        // 等待Cloudflare验证完成
        await waitForCloudflare();

        return new Promise((resolve) => {
            let loadingAttempts = 0;
            let notificationSent = false;

            const checkPage = () => {
                const proofElement = document.querySelector('p.text-24.font-doto.text-zk-blue-300.font-bold');
                const buttons = document.querySelectorAll('button');

                if (proofElement && buttons.length > 0) {
                    console.log('页面加载完成,开始监控');
                    resolve();
                    return;
                }

                loadingAttempts++;
                console.log(`等待页面加载...${loadingAttempts}次`);

                // 当等待次数超过15次且未发送过通知时发送通知
                if (loadingAttempts >= 15 && !notificationSent) {
                    sendFeishuNotification(`页面加载时间过长!已尝试加载 ${loadingAttempts} 次`);
                    notificationSent = true;
                }

                setTimeout(checkPage, 1000);
            };
            checkPage();
        });
    }

    // 启动脚本
    async function startScript() {
        try {
            // 恢复之前保存的状态
            const savedProofCount = GM_getValue('lastProofCount');
            const savedSwitchAttemptCount = GM_getValue('switchAttemptCount');
            if (savedProofCount !== undefined) {
                lastProofCount = savedProofCount;
                switchAttemptCount = savedSwitchAttemptCount;
                console.log('恢复之前的状态:', { lastProofCount, switchAttemptCount });
            }

            await waitForPageLoad();

            // 清除可能存在的旧定时器
            if (checkInterval) {
                clearInterval(checkInterval);
            }

            // 设置新的定时器,每10秒执行一次
            checkInterval = setInterval(mainLoop, 10 * 1000);

            // 立即执行一次
            mainLoop();

            console.log('脚本已启动,每10秒检查一次');
        } catch (error) {
            console.error('脚本启动失败:', error);
        }
    }

    // 启动脚本
    startScript();
})();