// ==UserScript== // @name DeepSeek繁忙自动点击重试 // @namespace http://tampermonkey.net/ // @version 2025-04-28 // @license MIT // @description DeepSeek提示繁忙,自动点击重试,并显示操作状态通知 // @author Dingning // @include *://chat.deepseek.com/* // @icon https://registry.npmmirror.com/@lobehub/icons-static-png/latest/files/dark/deepseek-color.png // @grant none // @downloadURL https://update.greasyfork.icu/scripts/526532/DeepSeek%E7%B9%81%E5%BF%99%E8%87%AA%E5%8A%A8%E7%82%B9%E5%87%BB%E9%87%8D%E8%AF%95.user.js // @updateURL https://update.greasyfork.icu/scripts/526532/DeepSeek%E7%B9%81%E5%BF%99%E8%87%AA%E5%8A%A8%E7%82%B9%E5%87%BB%E9%87%8D%E8%AF%95.meta.js // ==/UserScript== (function () { "use strict"; // 配置参数 let CHECK_INTERVAL = 1; let retryDelay = 1; let maxRetryDelay = 60; let retryCount = 0; let threshold = 5; let normalDelayIncrement = 2; let fastFrequencyDelayIncrement = 30; let retryTimeoutId = null; let configPanel; let countdownTimer = null; let remainingTime = 0; let isMonitoring = true; let isPanelExpanded = true; // 添加全局样式 const addGlobalStyles = () => { const style = document.createElement('style'); style.textContent = ` input::placeholder { color: #999!important; opacity: 1!important; } input { color: #333!important; } .toggle-btn.paused { background: #ff3b30!important; } .collapse-btn { padding: 6px 10px; border: none; border-radius: 4px; background: #007aff; color: white; cursor: pointer; font-size: 12px; transition: background 0.2s ease; } .collapse-btn:hover { background: #0063cc; } `; document.head.appendChild(style); }; const checkAndRetry = () => { if (!isMonitoring) return; const loadingElements = document.querySelectorAll(".ds-loading"); const hasLoading = loadingElements.length > 0; const contentList = document.querySelectorAll(".ds-markdown"); let hasBusyMessage = false; const busyMessages = [ '

服务器繁忙,请稍后再试。

', '

The server is busy. Please try again later.

', ]; const lastContent = contentList.length > 0? contentList[contentList.length - 1].innerHTML : ""; if (busyMessages.includes(lastContent)) hasBusyMessage = true; if (!hasLoading &&!hasBusyMessage) { if (retryCount > 0) createNotification("已重置重试次数和重试延迟", "success"); retryCount = 0; retryDelay = 1; if (configPanel) configPanel.style.display = "none"; } else if (hasBusyMessage) { if (configPanel) { configPanel.style.display = "block"; updateStatusDisplay(); } } if (hasBusyMessage &&!retryTimeoutId) { startCountdown(retryDelay); retryTimeoutId = setTimeout(() => { const retryBtn = Array.from(document.querySelectorAll(".ds-icon-button")) .reverse() .find(btn => btn.querySelector("svg #重新生成")); if (retryBtn) { retryBtn.click(); retryCount++; createNotification(`已点击重试,重试次数: ${retryCount}`, "success"); const toastContents = document.querySelectorAll(".ds-toast__content"); for (const toast of toastContents) { if (toast.textContent === "你发送消息的频率过快,请稍后再发") { retryDelay = Math.min(retryDelay + fastFrequencyDelayIncrement, maxRetryDelay); createNotification(`检测到频率过快,延迟调整为 ${retryDelay} 秒`, "warning"); break; } } if (retryCount >= threshold) { retryDelay = Math.min(retryDelay + normalDelayIncrement, maxRetryDelay); createNotification(`重试次数过多,延迟调整为 ${retryDelay} 秒`, "warning"); } } clearTimeout(retryTimeoutId); retryTimeoutId = null; }, retryDelay * 1000); } }; // 通知系统 const createNotificationContainer = () => { const container = document.createElement("div"); container.id = "retry-notifications"; container.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 10000; display: flex; flex-direction: column; gap: 10px; max-width: 300px; `; document.body.appendChild(container); return container; }; const createNotification = (message, type = "info") => { const notification = document.createElement("div"); notification.className = `retry-notification ${type}`; notification.style.cssText = ` padding: 12px 16px; background: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); font-size: 14px; color: #333; opacity: 0; transform: translateX(100%); transition: all 0.3s ease; display: flex; align-items: center; gap: 8px; border-left: 4px solid ${{ success: "#52c41a", warning: "#faad14", info: "#1890ff" }[type]}; `; const icon = document.createElement("span"); icon.textContent = { success: "✅", warning: "⚠️", info: "ℹ️" }[type]; notification.appendChild(icon); const text = document.createElement("span"); text.textContent = message; notification.appendChild(text); const container = document.getElementById("retry-notifications") || createNotificationContainer(); container.appendChild(notification); setTimeout(() => { notification.style.opacity = "1"; notification.style.transform = "translateX(0)"; }, 50); setTimeout(() => { notification.style.opacity = "0"; setTimeout(() => notification.remove(), 300); }, 3000); }; // 配置面板 const createConfigPanel = () => { const panel = document.createElement("div"); panel.id = "config-panel"; panel.style.cssText = ` position: fixed; bottom: 20px; right: 20px; z-index: 10000; background: rgba(255, 255, 255, 0.95); color: #414158; border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); padding: 20px; display: flex; flex-direction: column; gap: 16px; max-width: 300px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.2); font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; display: none; `; // 折叠按钮 const collapseBtn = document.createElement("button"); collapseBtn.textContent = isPanelExpanded? "折叠" : "展开"; collapseBtn.className = "collapse-btn"; collapseBtn.addEventListener("click", () => { isPanelExpanded =!isPanelExpanded; collapseBtn.textContent = isPanelExpanded? "折叠" : "展开"; if (isPanelExpanded) { panel.style.height = "auto"; panel.style.padding = "20px"; buttonContainer.style.marginTop = "10px"; saveButton.style.display = "block"; panel.querySelectorAll('.config-item').forEach(item => item.style.display = "flex"); } else { panel.style.height = "auto"; panel.style.padding = "10px"; buttonContainer.style.marginTop = "0px"; saveButton.style.display = "none"; panel.querySelectorAll('.config-item').forEach(item => item.style.display = "none"); } }); panel.appendChild(collapseBtn); // 状态显示 const statusContainer = document.createElement("div"); statusContainer.style.cssText = ` background: rgba(245, 245, 247, 0.8); border-radius: 8px; padding: 12px; min-width: 100px; `; const createStatusRow = (title, value, id) => { const row = document.createElement("div"); row.style.cssText = ` display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; font-size: 13px; `; const titleSpan = document.createElement("span"); titleSpan.textContent = title; titleSpan.style.color = "#666"; const valueSpan = document.createElement("span"); valueSpan.id = id; valueSpan.textContent = value; valueSpan.style.cssText = ` font-weight: 500; color: #1a1a1a; `; row.append(titleSpan, valueSpan); return row; }; statusContainer.append( createStatusRow("检测状态", isMonitoring? "运行中" : "已暂停", "monitor-status"), createStatusRow("当前重试次数", retryCount, "retry-count"), createStatusRow("下次尝试", "等待中", "countdown") ); panel.appendChild(statusContainer); // 配置项 const createInputRow = (label, value) => { const row = document.createElement("div"); row.style.cssText = ` display: flex; align-items: center; justify-content: space-between; gap: 10px; `; const labelEl = document.createElement("label"); labelEl.textContent = label; labelEl.style.cssText = ` font-size: 13px; color: #666; flex: 1; `; const input = document.createElement("input"); input.type = "number"; input.value = value; input.placeholder = "输入数值"; input.style.cssText = ` width: 80px; padding: 6px 8px; border: 1px solid #ddd; border-radius: 6px; font-size: 13px; background: rgba(255, 255, 255, 0.8); `; row.append(labelEl, input); return { row, input }; }; const configs = [ { label: "检查间隔 (秒)", value: CHECK_INTERVAL, action: v => CHECK_INTERVAL = v }, { label: "初始延迟 (秒)", value: retryDelay, action: v => retryDelay = v }, { label: "最大延迟 (秒)", value: maxRetryDelay, action: v => maxRetryDelay = v }, { label: "重试阈值", value: threshold, action: v => threshold = v }, { label: "正常增量 (秒)", value: normalDelayIncrement, action: v => normalDelayIncrement = v }, { label: "过快增量 (秒)", value: fastFrequencyDelayIncrement, action: v => fastFrequencyDelayIncrement = v } ]; configs.forEach(({ label, value, action }, index) => { const { row, input } = createInputRow(label, value); row.classList.add('config-item'); if (!isPanelExpanded) { row.style.display = "none"; } input.addEventListener("input", () => { action(parseInt(input.value) || 1); clearInterval(checkIntervalId); checkIntervalId = setInterval(checkAndRetry, CHECK_INTERVAL * 1000); }); panel.appendChild(row); }); // 控制按钮和保存按钮容器 const buttonContainer = document.createElement("div"); buttonContainer.style.cssText = ` margin-top: 10px; display: flex; gap: 10px; `; const toggleBtn = document.createElement("button"); toggleBtn.textContent = "暂停检测"; toggleBtn.className = "toggle-btn"; toggleBtn.style.cssText = ` flex: 1; padding: 10px; border: none; border-radius: 8px; background: #007aff; color: white; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.2s ease; `; toggleBtn.addEventListener("click", () => { isMonitoring =!isMonitoring; toggleBtn.textContent = isMonitoring? "暂停检测" : "继续检测"; toggleBtn.classList.toggle("paused",!isMonitoring); createNotification(isMonitoring? "已恢复自动检测" : "已暂停自动检测", isMonitoring? "success" : "warning"); if (isMonitoring) { clearInterval(checkIntervalId); checkIntervalId = setInterval(checkAndRetry, CHECK_INTERVAL * 1000); } else { clearInterval(checkIntervalId); clearTimeout(retryTimeoutId); retryTimeoutId = null; remainingTime = 0; } updateStatusDisplay(); }); buttonContainer.appendChild(toggleBtn); // 打开配置按钮(在折叠状态下显示) const openConfigBtn = document.createElement("button"); openConfigBtn.textContent = "打开配置"; openConfigBtn.style.cssText = ` padding: 10px 18px; border: none; border-radius: 8px; background: #007aff; color: white; cursor: pointer; font-size: 14px; font-weight: 500; transition: background 0.2s ease; `; openConfigBtn.addEventListener("click", () => { isPanelExpanded = true; collapseBtn.textContent = "折叠"; panel.style.height = "auto"; panel.style.padding = "20px"; panel.querySelectorAll('.config-item').forEach(item => item.style.display = "block"); }); // 保存按钮 const saveButton = document.createElement("button"); saveButton.textContent = "保存配置"; saveButton.style.cssText = ` padding: 10px 18px; border: none; border-radius: 8px; background: #007aff; color: white; cursor: pointer; font-size: 14px; font-weight: 500; transition: background 0.2s ease; `; saveButton.addEventListener("mouseenter", () => saveButton.style.background = "#0063cc"); saveButton.addEventListener("mouseleave", () => saveButton.style.background = "#007aff"); saveButton.addEventListener("click", () => createNotification("配置已保存", "success")); if (isPanelExpanded) { buttonContainer.appendChild(saveButton); } else { buttonContainer.appendChild(openConfigBtn); } panel.appendChild(buttonContainer); document.body.appendChild(panel); return panel; }; // 倒计时管理 const startCountdown = (seconds) => { clearInterval(countdownTimer); remainingTime = seconds; countdownTimer = setInterval(() => { remainingTime = Math.max(0, remainingTime - 1); updateStatusDisplay(); if (remainingTime <= 0) clearInterval(countdownTimer); }, 1000); }; const updateStatusDisplay = () => { document.getElementById("countdown").textContent = remainingTime > 0? `${remainingTime}秒` : "等待中"; document.getElementById("retry-count").textContent = retryCount; document.getElementById("monitor-status").textContent = isMonitoring? "运行中" : "已暂停"; }; // 初始化 addGlobalStyles(); let checkIntervalId = setInterval(checkAndRetry, CHECK_INTERVAL * 1000); configPanel = createConfigPanel(); window.addEventListener("beforeunload", () => { clearInterval(checkIntervalId); clearInterval(countdownTimer); }); })();