ChatGPT 降智监控(实时)

页面右下角实时显示 ChatGPT PoW 算力值,判断降智程度;修复首次刷新偶尔不显示问题

// ==UserScript==
// @name         ChatGPT 降智监控(实时)
// @namespace    http://tampermonkey.net/
// @version      2.3
// @description  页面右下角实时显示 ChatGPT PoW 算力值,判断降智程度;修复首次刷新偶尔不显示问题
// @match        https://chatgpt.com/*
// @match        https://openai.com/*
// @match        https://chat.chatgpt.com/*
// @match        https://*.openai.com/*
// @grant        none
// @license      GPT Plus升级 & 降智解决+V:ChatGPT4V
// @run-at       document-start     /* ← 提前注入脚本,确保能拦截首个 fetch */
// ==/UserScript==

(function () {
  'use strict';

  /* ========== 全局状态 ========== */
  let powDifficulty = 'N/A';          // 最新算力值
  let containerInitialized = false;   // 避免重复插入 UI

  /* ========== 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;

    if (url && url.includes('/sentinel/chat-requirements') && options?.method === 'POST') {
      try {
        const cloned = response.clone();
        cloned.json().then((data) => {
          powDifficulty = data?.proofofwork?.difficulty || 'N/A';
          updatePowText();
        });
      } catch (err) {
        console.error('获取 PoW 失败:', err);
      }
    }
    return response;
  };

  /* ========== 2. 首屏主动请求一次,防止页面暂时没发请求 ========== */
  setTimeout(fetchPowValue, 2000);

  function fetchPowValue() {
    fetch('https://chatgpt.com/sentinel/chat-requirements', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: '{}',
    })
      .then((r) => r.json())
      .then((d) => {
        powDifficulty = d?.proofofwork?.difficulty || 'N/A';
        updatePowText();
      })
      .catch((e) => console.error('主动请求 PoW 失败:', e));
  }

  /* ========== 3. 构建浮动面板(毛玻璃) ========== */
  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: '-2.5px',
      right: '25px',
      zIndex: 9999,                 // ↑ 抬高层级,避免被 prompt/toast 盖住
      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 可交互区域
    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';
    Object.assign(tooltip.style, {
      display: 'none',
      position: 'absolute',
      bottom: '100%',
      left: '50%',
      transform: 'translate(-50%, -8px)',
      background: '#333',
      color: '#fff',
      padding: '8px 12px',
      borderRadius: '6px',
      fontSize: '12px',
      boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
      whiteSpace: 'nowrap',
    });
    tooltip.innerHTML = `
      <div style="color:#00FF00;">绿色:全模型智商在线,且 4o 可答对推理问题</div>
      <div style="color:#FFFF00;">黄色:降智概率高,且未降智也不如绿色</div>
      <div style="color:#FF0000;">红色:全模型智商下线,推理 &amp; 画图大概率错误</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;
        if (rect.right > window.innerWidth - margin) {
          const overflow = rect.right - (window.innerWidth - margin);
          tooltip.style.transform = `translate(calc(-50% - ${overflow}px), -8px)`;
        }
      });
    });
    powWrapper.addEventListener('mouseleave', () => {
      tooltip.style.display = 'none';
      tooltip.style.transform = 'translate(-50%, -8px)';
    });
  }

  /* ========== 4. 根据 difficulty 刷新文本 + 图标 ========== */
  function updatePowText() {
    const el = document.getElementById('pow-text');
    if (!el) return;

    const { color, label, trimmedHex } = parsePowDifficulty(powDifficulty);
    el.innerHTML = `${getPulseExpandIcon(color)}
      <span style="color:${color};">${trimmedHex} ${label}</span>`;
  }

  /* ========== 5. 监控 DOM 树,面板丢失时自动重建 ========== */
  initPowUI();     // 初始创建
  updatePowText(); // 立刻画占位,让用户看得到

  new MutationObserver(() => {
    if (!document.getElementById('pow-float-container')) {
      containerInitialized = false;
      initPowUI();
      updatePowText();
    }
  }).observe(document.documentElement, { childList: true, subtree: true });

  /* ========== 辅助:解析难度 → 颜色 & 文案 ========== */
  function parsePowDifficulty(difficulty) {
    if (difficulty === 'N/A') {
      return { color: '#999999', label: 'N/A', trimmedHex: 'N/A' };
    }
    const trimmed = difficulty.replace(/^0x/i, '').replace(/^0+/, '') || '0';
    const len = trimmed.length;
    if (len >= 5) return { color: '#00FF00', label: '智商Top', trimmedHex: trimmed };
    if (len === 4) return { color: '#FFFF00', label: '高风险', trimmedHex: trimmed };
    return { color: '#FF0000', label: '强降智', trimmedHex: trimmed };
  }

  /* ========== 辅助:SVG 脉冲扩散动画 ========== */
  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>`;
  }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址