Greasy Fork

DeepSeek自动重试

检测到"服务器繁忙"时自动点击重试按钮

目前为 2025-02-07 提交的版本。查看 最新版本

// ==UserScript==
// @name         DeepSeek自动重试
// @namespace    http://tampermonkey.net/
// @version      0.8
// @description  检测到"服务器繁忙"时自动点击重试按钮
// @author       dy
// @match        https://chat.deepseek.com/*
// @grant        none
// @license      none
// ==/UserScript==

(function() {
    'use strict';

    // 配置项
    const CONFIG = {
        BUSY_TEXT: '服务器繁忙,请稍后再试。',
        RATE_LIMIT_TEXT: '你发送消息的频率过快,请稍后再发',
        CHECK_INTERVAL: 1000,
        MAX_RETRIES: 10,
        MIN_DELAY: 1500,
        MAX_DELAY: 3000,
        DEBOUNCE_DELAY: 5000  // 防抖延迟时间
    };

    // 状态管理
    const state = {
        retryCount: 0,
        isRetrying: false,
        isPaused: false,
        activeNotification: null,
        debounceTimer: null,
        lastRetryTime: 0,
        observer: null
    };

    // 创建提示元素
    function createNotification(message, temporary = true) {
        // 如果已有提示且不是临时的,直接返回
        if (state.activeNotification && !temporary) {
            return state.activeNotification;
        }

        const notification = document.createElement('div');
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 9999;
            transition: opacity 0.3s;
        `;
        
        if (!temporary) {
            const closeButton = document.createElement('span');
            closeButton.innerHTML = '×';
            closeButton.style.cssText = `
                margin-left: 10px;
                cursor: pointer;
                font-weight: bold;
            `;
            closeButton.onclick = () => {
                notification.remove();
                state.activeNotification = null;
                state.retryCount = 0;
                state.isPaused = false;
            };
            notification.appendChild(closeButton);
        }

        notification.textContent = message;
        document.body.appendChild(notification);
        
        if (!temporary) {
            state.activeNotification = notification;
        }
        
        return notification;
    }

    // 查找重试按钮
    function findRetryButton() {
        // 在当前活动元素的父级中查找
        let parent = document.activeElement;
        while (parent && !parent.querySelector('.ds-icon-button')) {
            parent = parent.parentElement;
        }

        // 如果在当前活动元素中没找到,尝试在整个聊天区域查找
        if (!parent) {
            const chatArea = document.querySelector('.f6004764');
            if (chatArea) {
                parent = chatArea;
            }
        }

        if (!parent) return null;

        const btns = Array.from(parent.querySelectorAll('.ds-icon-button'));
        return btns.find(btn => {
            const svg = btn.querySelector('svg');
            return svg && svg.querySelector('#重新生成');
        });
    }

    // 创建 MutationObserver 来监控页面变化
    function setupObserver() {
        if (state.observer) {
            state.observer.disconnect();
        }

        state.observer = new MutationObserver((mutations) => {
            for (const mutation of mutations) {
                if (mutation.type === 'childList' || mutation.type === 'characterData') {
                    autoRetry();
                }
            }
        });

        // 监控整个聊天区域
        const chatArea = document.querySelector('.f72b0bab');
        if (chatArea) {
            state.observer.observe(chatArea, {
                childList: true,
                subtree: true,
                characterData: true
            });
        }
    }

    // 检查服务器繁忙
    function checkBusyStatus() {
        // 检查频率限制
        const rateLimitElements = document.querySelectorAll('.ds-toast__content');
        for (const el of rateLimitElements) {
            if (el.textContent && el.textContent.includes(CONFIG.RATE_LIMIT_TEXT)) {
                state.isPaused = true;
                createNotification('检测到频率过快,稍等一会吧', false);
                return true;
            }
        }

        // 检查服务器繁忙
        // 首先获取聊天内容区域
        const chatArea = document.querySelector('.f6004764');
        if (!chatArea) return false;

        // 使用更精确的选择器查找服务器繁忙消息
        const busyMessages = chatArea.querySelectorAll('.ds-markdown.ds-markdown--block p');
        for (const el of busyMessages) {
            if (!el.textContent || el.textContent.trim() !== CONFIG.BUSY_TEXT) {
                continue;
            }
            
            // 检查是否在用户消息中
            let parent = el;
            while (parent && parent !== chatArea) {
                if (parent.classList.contains('fa81')) {
                    return false;
                }
                parent = parent.parentElement;
            }
            
            // 检查是否有重试按钮
            const hasRetryButton = findRetryButton();
            if (hasRetryButton) {
                return true;
            }
        }
        
        return false;
    }

    // 自动重试主函数
    function autoRetry() {
        if (state.isPaused) return;

        if (checkBusyStatus()) {
            const now = Date.now();
            if (!state.isRetrying && (now - state.lastRetryTime) >= CONFIG.DEBOUNCE_DELAY) {
                state.retryCount++;
                state.isRetrying = true;
                state.lastRetryTime = now;

                const retryButton = findRetryButton();
                
                if (retryButton) {
                    if (state.retryCount >= CONFIG.MAX_RETRIES) {
                        createNotification('已达到最大重试次数,DeepSeek可能当前算力不足', false);
                        return;
                    }

                    const notification = createNotification(`检测到服务器繁忙,即将自动重试(${state.retryCount}/${CONFIG.MAX_RETRIES})...`);
                    
                    // 随机延迟
                    const delay = Math.floor(Math.random() * (CONFIG.MAX_DELAY - CONFIG.MIN_DELAY + 1)) + CONFIG.MIN_DELAY;
                    
                    clearTimeout(state.debounceTimer);
                    state.debounceTimer = setTimeout(() => {
                        console.log('找到重试按钮,自动点击');
                        retryButton.dispatchEvent(new MouseEvent('click', {
                            view: window,
                            bubbles: true,
                            cancelable: true
                        }));
                        
                        notification.style.opacity = '0';
                        setTimeout(() => notification.remove(), 300);
                        state.isRetrying = false;
                    }, delay);
                }
            }
        } else {
            state.isRetrying = false;
        }
    }

    // 初始化
    function init() {
        // 设置 MutationObserver
        setupObserver();
        
        // 页面加载完成后检查一次
        autoRetry();
        
        // 定期检查作为备份机制
        setInterval(autoRetry, CONFIG.CHECK_INTERVAL);
        
        // 监听页面变化重新设置 observer
        const bodyObserver = new MutationObserver(() => {
            if (!document.querySelector('.f72b0bab')) {
                setupObserver();
            }
        });
        
        bodyObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

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