// ==UserScript== // @name ChatShare节点和激活码助手🔥 // @namespace https://chatshare.ren/ // @version 1.0.0 // @description 检测ChatShare节点状态,选择最快节点,提供chatshare激活码方式,也可以直接切换到任意节点。 // @author ChatShare // @match *://chatgpt.com/* // @match *://chatshare.com/* // @match *://chatshare.biz/* // @match *://chatshare.ren/* // @match *://*.chatshare.biz/* // @match *://*.chatshare.one/* // @match *://chatshare.hk/* // @match *://chatshare.online/* // @match *://chatshare.pro/* // @match *://web.chatgpts.asia/* // @match *://chatshare.art/* // @match *://chatshare.cc/* // @match *://chatshare.art/* // @match *://chatshare.me/* // @match *://chatshare.art/* // @match *://chatshare.top/* // @match *://chatshare.work/* // @match *://chatshare.cn/* // @grant GM_xmlhttpRequest // @connect chatshare.biz // @connect node1.chatshare.biz // @connect node2.chatshare.biz // @connect node3.chatshare.biz // @connect node4.chatshare.biz // @connect node5.chatshare.biz // @connect node6.chatshare.biz // @connect node.chatshare.one // @connect web.chatgpts.asia // @run-at document-start // @noframes // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFSElEQVR4nMWXX4hdVxXGf2vfe89kJg61ia0DYzMTMWnoQ0FJtKmtJsFixT8DBSmYtGMLgq0PCqMEKwmxYzSGyUPBB7XRNi0FC6JtwYovgcS0klJD8SHakoExYhLQFkwn9/aeOfv7fDi3SStJ5o4muN4O7L32b33rz94H/s8WS10cvR3yVQaY++wnkESkwDK2sMy1EwXDtzRRziBhu+dGDG48smSA5kUP//wmAFIkrNwiGMOsBzYAQwTzEEeBY8BJO1fYtF+4laGPv/i/Afz1C1sAYwngZiKmsDcDI0DrHUtL4DRwMGAmUnVcCtpHPsrQbS/1DZDe+VFHblKziIjYBjwD3Iu5ARBwBjgJnAkwMAa+z+ZZqXEX8VZg0T784aUDzH3uk0DtVQvlVsMjwGpMB3gauAu8ieB2YDPwxR5gF/gQ+MeoNUFzACI4d+imvgDOp0BVRWo2AW62eRi8wvY/wNtrgGhDL+7a/gIcBLYBu4HrsPdSzr8K/JlcLk2BaCQstSxN2VptuYO93an7WES0UyORGg1Wfu0QKivyQhfb56yhn4B3Ynew1kD1oDTfJF20vi8NYBvjMVubbWHrOdtPhwaAYPVvfs8Hf1u32bJbDtXVbgFvAj4AOgTGzhPhGMdV/wCvbtmAJSyttzRiuWv7CdttAlY/f/iimwdvfQGiAfmtczg/jnOJ8/txtRbnvgAu6FSPtg1AC3wGPAvgWGRYqiSowLwC1Ru4GoFyFPc3ZM8DfGPLB1jZXlhe74sS6AAc+O6vL+tg6LaX2LP/SSA6tkpcYeee36/0D/C7Ve9BwZs97iLMEMDAE5N07z1wSQebvl/y3KkAGDIUsrHpRp8ACeDGw38kZdPMPtrILhvZ1yZ5TZJxvnwuW40GzSSaDa1vJq1oJXVbKZ9qpv5qoO6Cqr5ULB+zfNrygOX7LS+PlCgeu+eimz/1w0yWaTTScIqYTEERcDoiXovFauddAAA22CeRDyKD/Bnkbd32PNgUj09S/GwrUMt+x14hiWVFI1LEVyPidggi4hfOnuv3nr8AEGC5sj1j+4TtAcu7i4HlDwLLqRawMmtmnidn6JYLGIa7C/mbwHeAgYATQexPjVCVxcZd7SUACDCEfRyznXoMr8Sawf4lcDdwI7AKWAdss/0r2dOyr6kFpCn7hiyPRlDY5mM7z10W4F1KFT+/p6ZwDkgT2HuN19Tz3yXWG+NnJ8uR9h0FSStSRAFBwAmbpu3xbP/T9rzkp2zvtt2RzcvfG15EAaC8/8m6FkgmpWdsTyD/COtv9esnj1haZXvEtiXP2d5jc6es+3qHv8/2uO1v2d4hedA2H/n2vxZX4LwS+78E1PcDqprAOPZao9Gxs5PNkc6dXUKnIuI1Z8+lRijLo8AR2+OWqeeBS8n7bE8bd2x4Zc97FwcAaP307vqyiXi7QzBi7OyXGel8GkJEBAFUWUREIXlnL/LCvgBheZ9h2lLHyvxp5rrFAZZiG3e16zliBm3vsD0lu6i5ja0awppWrjrKmeOPjAL/UQP/rf1h11BPJHckT/dkL+vDjeXC0pRy3qGcB22x9oHZKwcAcPTh5UimzrWnexGXlrCFlAvlakq5eiiX3eLtSXnFAABe3j1c/0PgTp1z77NUKmesjHMulKuttq9X/eq+sgAAx35wTZ0OqWNrWqr2KVelqoqcF3DOL1r5dStfHQCoW03K9ApuWrnam/PCnHN+StZDRHSK1jLgCnXBpeymr/8dS+SFbmH7eiu/TkQnNRrkqmL20XVXFwBg7QOzRASSsDJFaxndssPso+uu9tH92b8BowSyPc/iZtEAAAAASUVORK5CYII= // @license MIT // ==/UserScript== (function () { "use strict"; if (window.top !== window) return; const PANEL_ID = "chatshare-userscript-node-panel"; const NODES = [ "chatshare.biz", "node1.chatshare.biz", "node2.chatshare.biz", "node3.chatshare.biz", "node4.chatshare.biz", "node5.chatshare.biz", "node6.chatshare.biz", "node.chatshare.one", "web.chatgpts.asia" ]; const TIMEOUT = 6500; let panel = null; let latest = null; let mounted = false; const nodeUrl = (host) => `https://${host}/`; function isCollapsed() { try { return sessionStorage.getItem("chatshare-userscript-collapsed") === "1"; } catch { return false; } } function setCollapsed(value) { try { sessionStorage.setItem("chatshare-userscript-collapsed", value ? "1" : "0"); } catch { // Storage may be disabled; the current page still remains usable. } } function checkNode(host) { return new Promise((resolve) => { const started = performance.now(); let settled = false; const finish = (result) => { if (settled) return; settled = true; resolve(result); }; const timer = setTimeout(() => finish({ host, url: nodeUrl(host), online: false, status: 0, latency: null, error: "timeout" }), TIMEOUT); GM_xmlhttpRequest({ method: "GET", url: nodeUrl(host), timeout: TIMEOUT, onload(response) { clearTimeout(timer); finish({ host, url: nodeUrl(host), online: response.status >= 200 && response.status < 500, status: response.status, latency: Math.round(performance.now() - started) }); }, onerror() { clearTimeout(timer); finish({ host, url: nodeUrl(host), online: false, status: 0, latency: null, error: "unreachable" }); }, ontimeout() { clearTimeout(timer); finish({ host, url: nodeUrl(host), online: false, status: 0, latency: null, error: "timeout" }); } }); }); } async function checkAllNodes() { const results = await Promise.all(NODES.map(checkNode)); results.sort((a, b) => { if (a.online !== b.online) return a.online ? -1 : 1; return (a.latency ?? Number.MAX_SAFE_INTEGER) - (b.latency ?? Number.MAX_SAFE_INTEGER); }); return { checkedAt: Date.now(), nodes: results, best: results.find((node) => node.online) || null }; } function createPanel() { if (document.getElementById(PANEL_ID)) return document.getElementById(PANEL_ID); const root = document.createElement("div"); root.id = PANEL_ID; root.innerHTML = `
ChatShare 节点助手 自动检测
正在检测节点...
有问题可发送任意邮件至 chatshare@126.com
`; return root; } function render(data) { if (!panel || !document.contains(panel)) return; latest = data; const nodes = panel.querySelector(".nodes"); nodes.innerHTML = data.nodes.map((node) => { const online = node.online ? "online" : "offline"; const label = node.online ? `${node.latency} ms` : (node.error === "timeout" ? "超时" : "不可用"); const best = data.best?.host === node.host; return `
${node.host}${best ? "最佳 · " : ""}${label}切换至此节点
`; }).join(""); panel.querySelector(".summary-text").textContent = data.best ? `最佳节点:${data.best.host}` : "暂时没有可用节点"; panel.querySelector(".updated").textContent = new Date(data.checkedAt).toLocaleTimeString(); panel.querySelector(".use-best").disabled = !data.best; } function bind() { if (!panel || panel.dataset.bound) return; panel.dataset.bound = "1"; panel.querySelector(".close").onclick = () => { setCollapsed(true); panel.classList.add("collapsed"); }; panel.querySelector(".status-dot").onclick = () => { setCollapsed(false); panel.classList.remove("collapsed"); }; panel.querySelector(".refresh").onclick = runCheck; panel.querySelector(".use-best").onclick = () => { if (latest?.best) location.href = latest.best.url; }; panel.querySelector(".nodes").onclick = (event) => { const item = event.target.closest(".node[data-url]"); if (item?.dataset.url) location.href = item.dataset.url; }; if (isCollapsed()) panel.classList.add("collapsed"); } async function runCheck() { if (!panel) return; const refresh = panel.querySelector(".refresh"); panel.querySelector(".summary-text").textContent = "正在检测节点..."; refresh.disabled = true; try { render(await checkAllNodes()); } catch { panel.querySelector(".summary-text").textContent = "检测失败,请点击重新检测"; } finally { if (panel && document.contains(panel)) panel.querySelector(".refresh").disabled = false; } } function ensurePanel() { if (!document.documentElement) return; const existing = document.getElementById(PANEL_ID); if (existing) { panel = existing; bind(); return; } panel = createPanel(); document.documentElement.appendChild(panel); bind(); if (!mounted) { mounted = true; runCheck(); } } ensurePanel(); const keepAlive = setInterval(ensurePanel, 500); const observer = new MutationObserver(ensurePanel); if (document.documentElement) observer.observe(document.documentElement, { childList: true, subtree: true }); window.addEventListener("unload", () => { clearInterval(keepAlive); observer.disconnect(); }); })();