您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
页面右下角显示ChatGPT PoW算力值,判断降智程度
当前为
// ==UserScript== // @name ChatGPT 降智监控(实时) // @namespace http://tampermonkey.net/ // @version 1.8 // @description 页面右下角显示ChatGPT PoW算力值,判断降智程度 // @match https://chatgpt.com/* // @grant none // @license GPT Plus升级 & 降智解决+V:ChatGPT4V // @run-at document-idle // ==/UserScript== (function() { 'use strict'; let powDifficulty = "N/A"; // 记录最新的算力值 let containerInitialized = false; // 用于避免重复创建浮动面板 // 1. 拦截 fetch,用于获取 PoW difficulty const originalFetch = window.fetch; window.fetch = async function(resource, options) { const response = await originalFetch(resource, options); const url = typeof resource === "string" ? resource : resource?.url; // 如果是 /sentinel/chat-requirements 接口,则更新算力值 if (url && url.includes("/sentinel/chat-requirements") && options?.method === "POST") { try { const clonedResponse = response.clone(); clonedResponse.json().then(data => { powDifficulty = data?.proofofwork?.difficulty || "N/A"; updatePowText(); // 更新显示的算力值 }); } catch (error) { console.error("获取 PoW 失败:", error); } } return response; }; // 2. 主动请求一次 /sentinel/chat-requirements setTimeout(() => { fetchPowValue(); }, 2000); function fetchPowValue() { fetch("https://chatgpt.com/sentinel/chat-requirements", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({}) }) .then(res => res.json()) .then(data => { powDifficulty = data?.proofofwork?.difficulty || "N/A"; updatePowText(); }) .catch(err => { console.error("主动请求 PoW 失败:", err); }); } // 3. 初始化 UI 面板 function initPowUI() { if (containerInitialized) return; containerInitialized = true; // 3.1 毛玻璃外框 const floatContainer = document.createElement('div'); floatContainer.id = "pow-float-container"; Object.assign(floatContainer.style, { position: 'fixed', bottom: '-5px', right: '25px', zIndex: 0, padding: '12px 16px', borderRadius: '12px', backdropFilter: 'none', backgroundColor: 'transparent', border: 'none', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px', fontFamily: 'Roboto, Arial, Helvetica, sans-serif', color: '#333', // 让外层容器不拦截点击事件 pointerEvents: 'none' }); // 3.2 让真正需要交互的区域使用 pointer-events: auto const powWrapper = document.createElement('div'); powWrapper.id = 'pow-wrapper'; powWrapper.style.position = 'relative'; powWrapper.style.pointerEvents = 'auto'; // 允许点击/悬浮 // 3.3 显示“波动图标 + 文本”的容器 const powText = document.createElement('div'); powText.id = 'pow-text'; powText.style.fontWeight = 'bold'; powText.style.display = 'inline-flex'; powText.style.alignItems = 'center'; powText.style.gap = '6px'; powText.style.whiteSpace = 'nowrap'; // 3.4 自定义 Tooltip const tooltip = document.createElement('div'); tooltip.id = 'custom-tooltip'; // 初始隐藏 + 定位 tooltip.style.display = 'none'; tooltip.style.position = 'absolute'; tooltip.style.bottom = '100%'; tooltip.style.left = '50%'; tooltip.style.transform = 'translate(-50%, -8px)'; // 外观样式 tooltip.style.background = '#333'; tooltip.style.color = '#fff'; tooltip.style.padding = '8px 12px'; tooltip.style.borderRadius = '6px'; tooltip.style.fontSize = '12px'; tooltip.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)'; // 保持单行不自动换行,但用多个 <div> 实现“不同颜色之间换行” tooltip.style.whiteSpace = 'nowrap'; // 多行提示(每条颜色独占一行) tooltip.innerHTML = ` <div id="line-green" style="color: #00FF00;">绿色:全模型智商在线,且4o可答对推理问题</div> <div id="line-yellow" style="color: #FFFF00;">黄色:降智概率高,且未降智也不如绿色(4o会答错推理问题)</div> <div id="line-red" style="color: #FF0000;">红色:全模型智商下线,4o无法画图且会答错推理问题↓<br>带小数点的数字比大小都会答错,o系列全模型短耗时、伪推理</div> `; // 3.5 拼装 powWrapper.appendChild(powText); powWrapper.appendChild(tooltip); floatContainer.appendChild(powWrapper); document.body.appendChild(floatContainer); // 3.6 悬浮事件:显示 / 隐藏 tooltip,并自动贴右边 powWrapper.addEventListener('mouseenter', () => { // 先显示,才能测量真实宽度 tooltip.style.display = 'block'; // 下一帧再测量 requestAnimationFrame(() => { const rect = tooltip.getBoundingClientRect(); const margin = 8; // 与右边保持一点间距 // 如果 tooltip 右边超出窗口,就往左挪 if (rect.right > window.innerWidth - margin) { const overflowRight = rect.right - (window.innerWidth - margin); tooltip.style.transform = `translate(calc(-50% - ${overflowRight}px), -8px)`; } }); }); powWrapper.addEventListener('mouseleave', () => { tooltip.style.display = 'none'; // 还原初始 transform tooltip.style.transform = 'translate(-50%, -8px)'; }); } // 4. 更新算力值文本(脉冲扩展图标 + 同色文字) function updatePowText() { const powText = document.getElementById('pow-text'); if (!powText) return; const { color, label, trimmedHex } = parsePowDifficulty(powDifficulty); // 生成脉冲扩展图标 const iconHTML = getPulseExpandIcon(color); // 同色文字 powText.innerHTML = ` ${iconHTML} <span style="color:${color};"> ${trimmedHex} ${label} </span> `; } // 5. 监听 DOM 变化, 防止面板丢失 initPowUI(); const observer = new MutationObserver(() => { const container = document.getElementById("pow-float-container"); if (!container) { containerInitialized = false; initPowUI(); } }); observer.observe(document.documentElement, { childList: true, subtree: true }); // ========== 辅助函数:解析 difficulty 并返回三档信息 ========== function parsePowDifficulty(difficulty) { if (difficulty === "N/A") { return { color: "#999", label: "N/A", trimmedHex: "N/A" }; } let hex = difficulty.replace(/^0x/i, ""); let trimmed = hex.replace(/^0+/, ""); if (!trimmed) trimmed = "0"; const length = trimmed.length; let color, label; if (length >= 5) { color = "#00FF00"; // 绿色 label = "智商Top"; } else if (length === 4) { color = "#FFFF00"; // 黄色 label = "高风险"; } else { color = "#FF0000"; // 红色 label = "强降智"; } return { color, label, trimmedHex: trimmed }; } // ========== 辅助函数:生成脉冲扩展图标 ========== function getPulseExpandIcon(color) { return ` <svg width="16" height="16" viewBox="0 0 64 64" style="vertical-align:middle;"> <circle cx="32" cy="32" r="4" fill="${color}"> <animate attributeName="r" dur="1.5s" values="4;10;4" repeatCount="indefinite"/> </circle> <circle cx="32" cy="32" r="10" fill="none" stroke="${color}" stroke-width="2"> <animate attributeName="r" dur="2s" values="10;20;10" repeatCount="indefinite"/> </circle> <circle cx="32" cy="32" r="20" fill="none" stroke="${color}" stroke-width="2"> <animate attributeName="r" dur="3s" values="20;30;20" repeatCount="indefinite"/> </circle> </svg> `; } })();