Auto retry when server busy detected by text or SVG icon, with toggle UI and cooldown.
当前为
// ==UserScript==
// @name DeepSeek Auto-Retry with Text & SVG Detection
// @version 1.4
// @description Auto retry when server busy detected by text or SVG icon, with toggle UI and cooldown.
// @author Blakken
// @match https://chat.deepseek.com/*
// @grant none
// @license MIT
// @namespace https://greasyfork.org/users/1477546
// ==/UserScript==
(function() {
"use strict";
// Config
const config = {
autoRetryEnabled: true,
cooldown: 15000, // 15 secondes entre retries
interval: 1000, // vérification toutes les 1 seconde
errorTextToDetect: "Server busy, please try again later.",
// Le SVG path exact pour la détection du bouton retry (tu peux adapter)
retrySvgPath: "M12 .5C18.351.5 23.5 5.649 23.5 12S18.351 23.5 12 23.5.5 18.351.5 12 5.649.5 12 .5zm-.225 4.8a.7.7 0 0 0-.528.224.703.703 0 0 0-.213.517.84.84 0 0 0 .056.304c.037.09.087.168.146.235l.809.831a.782.782 0 0 0-.147-.01 1.112 1.112 0 0 0-.157-.012 4.69 4.69 0 0 0-2.436.673 5.26 5.26 0 0 0-1.82 1.832c-.456.763-.685 1.617-.685 2.56 0 .966.232 1.845.696 2.639A5.33 5.33 0 0 0 9.36 16.99c.779.464 1.648.697 2.606.697.95 0 1.816-.233 2.595-.697a5.326 5.326 0 0 0 1.875-1.886 5.03 5.03 0 0 0 .696-2.606.716.716 0 0 0-.247-.55.754.754 0 0 0-.55-.236.78.78 0 0 0-.573.235.731.731 0 0 0-.236.551 3.46 3.46 0 0 1-.483 1.808c-.314.539-.741.97-1.28 1.292a3.44 3.44 0 0 1-1.797.482 3.44 3.44 0 0 1-1.797-.482 3.679 3.679 0 0 1-1.291-1.292 3.521 3.521 0 0 1-.472-1.808c0-.659.158-1.258.472-1.797a3.588 3.588 0 0 1 1.29-1.28 3.44 3.44 0 0 1 1.798-.484c.164 0 .3.008.404.023l-1.111 1.112a.722.722 0 0 0-.225.528c0 .21.07.386.213.528a.718.718 0 0 0 1.033-.012l2.246-2.246a.66.66 0 0 0 .203-.527.753.753 0 0 0-.203-.54l-2.223-2.268a.847.847 0 0 0-.247-.169.62.62 0 0 0-.28-.067z",
};
let lastRetryTime = 0;
let retryCount = 0;
// Affiche le compteur visible sur la page
function createCounterUI() {
let ui = document.getElementById("autoRetryCounterUI");
if (ui) return ui;
ui = document.createElement("div");
ui.id = "autoRetryCounterUI";
ui.style.position = "fixed";
ui.style.bottom = "40px";
ui.style.right = "20px";
ui.style.padding = "8px 12px";
ui.style.backgroundColor = "rgba(0,0,0,0.7)";
ui.style.color = "#fff";
ui.style.fontSize = "14px";
ui.style.borderRadius = "6px";
ui.style.zIndex = "999999";
ui.style.fontFamily = "Arial, sans-serif";
ui.style.userSelect = "none";
ui.style.cursor = "default";
document.body.appendChild(ui);
return ui;
}
// Met à jour le texte du compteur
function updateCounterUI() {
const ui = createCounterUI();
ui.textContent = `Auto-Retry Count: ${retryCount} (Status: ${config.autoRetryEnabled ? "ON" : "OFF"})`;
}
// Création du toggle pour activer/désactiver l’auto retry
function createToggleUI() {
let toggle = document.getElementById("autoRetryToggleUI");
if (toggle) return toggle;
toggle = document.createElement("div");
toggle.id = "autoRetryToggleUI";
toggle.style.position = "fixed";
toggle.style.bottom = "10px";
toggle.style.right = "20px";
toggle.style.backgroundColor = "rgba(0,0,0,0.7)";
toggle.style.color = "#fff";
toggle.style.padding = "6px 12px";
toggle.style.borderRadius = "6px";
toggle.style.zIndex = "999999";
toggle.style.fontFamily = "Arial, sans-serif";
toggle.style.userSelect = "none";
const label = document.createElement("label");
label.style.cursor = "pointer";
label.style.userSelect = "none";
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.checked = config.autoRetryEnabled;
checkbox.style.marginRight = "6px";
checkbox.addEventListener("change", () => {
config.autoRetryEnabled = checkbox.checked;
updateCounterUI();
console.log(`[AutoRetry] Auto-Retry turned ${config.autoRetryEnabled ? "ON" : "OFF"}`);
});
label.appendChild(checkbox);
label.appendChild(document.createTextNode("Auto-Retry"));
toggle.appendChild(label);
document.body.appendChild(toggle);
return toggle;
}
// Trouve le bouton retry en détectant la présence du SVG spécifique (path)
function findRetryButton() {
// On cherche tous les boutons svg avec un path
const buttons = document.querySelectorAll("button, div.ds-icon-button, div");
for (const btn of buttons) {
const svg = btn.querySelector("svg path");
if (!svg) continue;
const d = svg.getAttribute("d");
if (!d) continue;
if (d.trim() === config.retrySvgPath.trim()) {
return btn;
}
}
return null;
}
// Vérifie si le message d’erreur "Server busy" est visible dans la page
function isServerBusyDetected() {
// Détecte la présence du texte d’erreur dans les spans ou divs
const elementsWithError = Array.from(document.querySelectorAll("span, div"))
.filter(el => el.textContent.trim() === config.errorTextToDetect);
if (elementsWithError.length > 0) {
return true;
}
// Ou détecte la présence du SVG d'icône serveur busy visible
// (cette fonction est ici si tu veux la double détection)
const svgPaths = document.querySelectorAll("svg path");
for (const path of svgPaths) {
if (path.getAttribute("d")?.trim() === config.retrySvgPath.trim()) {
return true;
}
}
return false;
}
// Tente le retry si conditions OK (cooldown, autoRetryEnabled, erreur détectée)
function tryAutoRetry() {
if (!config.autoRetryEnabled) return;
if (!isServerBusyDetected()) return;
const now = Date.now();
if (now - lastRetryTime < config.cooldown) return;
const btn = findRetryButton();
if (!btn) {
console.log("[AutoRetry] Retry button not found.");
return;
}
btn.click();
retryCount++;
lastRetryTime = now;
updateCounterUI();
console.log("[AutoRetry] Retry clicked. Count:", retryCount);
}
// Initialisation
function initialize() {
createCounterUI();
createToggleUI();
updateCounterUI();
setInterval(tryAutoRetry, config.interval);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initialize);
} else {
initialize();
}
})();