// ==UserScript== // @name NetChk_Triangle_IronLock v37 beta // @version 37.5.31.b3 // @namespace https://greasyfork.org/zh-CN/users/1593463-nander // @license CC BY-NC-SA 4.0 // @description 深度修复隐藏逻辑,确保点击隐藏后立即生效并持久化 // @author Gemini // @match *://*/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_openInTab // @grant GM_registerMenuCommand // @connect * // @run-at document-start // @downloadURL https://update.greasyfork.icu/scripts/575373/NetChk_Triangle_IronLock%20v37%20beta.user.js // @updateURL https://update.greasyfork.icu/scripts/575373/NetChk_Triangle_IronLock%20v37%20beta.meta.js // ==/UserScript== (function() { 'use strict'; const COLORS = { bg: '#1a1a1a', border: '#333333', textMain: '#ffffff', text80: '#cccccc', text60: '#999999', text40: '#666666', vscBlue: '#005a9e', nckCN: '#4ade80', nckGL: '#60a5fa', nckERR: '#f87171', nckWarn: '#fbbf24' }; const STYLES = ` #nck-main { position: fixed !important; z-index: 2147483647 !important; background: ${COLORS.bg} !important; border: 1px solid ${COLORS.border} !important; border-radius: 2px !important; height: 24px !important; display: flex !important; align-items: stretch !important; box-sizing: border-box !important; cursor: default !important; user-select: none !important; font-family: "Cascadia Code", Consolas, monospace !important; box-shadow: 0 2px 8px rgba(0,0,0,0.5) !important; transition: opacity 0.3s, background 0.3s; } #nck-panel-container { position: absolute !important; display: none !important; left: 50% !important; transform: translateX(-50%) !important; width: 210px !important; } #nck-panel-container::before { content: ''; position: absolute; left: 0; right: 0; height: 10px; } .dir-down { top: 24px !important; padding-top: 5px !important; } .dir-down::before { top: -10px; } .dir-up { bottom: 24px !important; padding-bottom: 5px !important; } .dir-up::before { bottom: -10px; } #nck-main:hover #nck-panel-container, #nck-main.keep-open #nck-panel-container { display: block !important; } #nck-panel { background: ${COLORS.bg} !important; border: 1px solid ${COLORS.border} !important; padding: 6px !important; box-shadow: 0 4px 15px rgba(0,0,0,0.7) !important; } .panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; border-bottom: 1px solid #333; padding-bottom: 3px; } .panel-ver { font-size: 8px; color: ${COLORS.text40}; font-weight: bold; } .ip-link-btn { cursor: pointer; color: ${COLORS.text60}; font-size: 8px; padding: 0 4px; border: 1px solid #444; background: #252526; } .ip-row { background: #222; padding: 4px 6px; margin-bottom: 3px; border: 1px solid #2d2d2d; } .ip-row-info { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2px; } .ip-label { font-size: 8px; color: ${COLORS.text40}; font-weight: bold; } .ip-label b { color: ${COLORS.text60}; margin-left: 5px; font-weight: normal; } .ip-ms { font-size: 9px; font-weight: 900; opacity: 0.9;} .ip-val { color: ${COLORS.text80}; font-size: 10px; font-family: "Cascadia Code", monospace; word-break: break-all; line-height: 1.2; display: block; border-top: 1px solid #2d2d2d; padding-top: 3px; margin-top: 2px; } .ms-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; margin: 5px 0; } .ms-node { font-size: 9px; text-align: center; color: ${COLORS.text40}; background: #252526; padding: 3px 0; border: 1px solid #333; } .ms-node.active { color: ${COLORS.text80}; border-color: #444; } .ms-node b { display: block; font-size: 7px; opacity: 0.6; margin-bottom: 1px; } .btn-group { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; margin-top: 5px; } .t-btn { background: #2a2a2a; color: ${COLORS.text60}; font-size: 8px; padding: 4px 0; text-align: center; cursor: pointer; border: 1px solid #333; transition: 0.1s; } .t-btn:hover { background: #333; color: #fff; } .t-btn.active { background: ${COLORS.vscBlue} !important; color: #fff !important; border-color: #007acc !important; } #nck-trigger { display: flex; align-items: center; padding: 0 8px; flex-grow: 1; cursor: pointer; gap: 6px; } .info-code { color: #fff; font-size: 10px; font-weight: bold; } .info-ms { font-size: 10px; font-weight: 900;min-width: 30px; } .ms-cn { color: ${COLORS.nckCN}; } .ms-gl { color: ${COLORS.nckGL}; } .nck-led { width: 4px; height: 4px; border-radius: 1px; background: #333; transition: 0.3s; } .led-checking { background: ${COLORS.nckWarn} !important; box-shadow: 0 0 4px ${COLORS.nckWarn}; } .led-ok-cn { background: ${COLORS.nckCN} !important; box-shadow: 0 0 3px ${COLORS.nckCN}; } .led-ok-gl { background: ${COLORS.nckGL} !important; box-shadow: 0 0 3px ${COLORS.nckGL}; } .led-err { background: ${COLORS.nckERR} !important; } #nck-bay { width: 24px; border-left: 1px solid ${COLORS.border}; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: 0.2s; } #nck-bay:hover { background: #2a2a2a; } .bay-play { width: 0; height: 0; border-top: 4px solid transparent; border-bottom: 4px solid transparent; border-left: 6px solid #555; transition: 0.2s; } .ctrl-active .bay-play { border-left-color: ${COLORS.nckCN} !important; } @keyframes success-flash { 0% { background: #1a1a1a; } 50% { background: #1a4a2a; } 100% { background: #1a1a1a; } } .state-success { animation: success-flash 0.4s ease; } .state-success .bay-play { border-left-color: ${COLORS.nckCN} !important; transform: scale(1.2); } @keyframes error-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } } .state-error { animation: error-shake 0.2s 2; border-color: ${COLORS.nckERR} !important; } .state-error .bay-play { border-left-color: ${COLORS.nckERR} !important; } .hidden { display: none !important; } `; let state = { isProcessing: false, nodes: { cn: { ip: '...', ms: '--', state: 'init' }, gl: { ip: '...', ms: '--', state: 'init' }, code: 'VSC' }, targets: [ { id: 'BD', url: 'https://www.baidu.com/favicon.ico' }, { id: 'GH', url: 'https://github.com/favicon.ico' }, { id: 'CF', url: 'https://1.1.1.1/cdn-cgi/trace' } ], conf: { visible: GM_getValue('nck_v378_vis', true), matrix: GM_getValue('nck_v378_mtx', true), longShow: GM_getValue('nck_v378_long', false), locked: GM_getValue('nck_v378_lock', false), bindCtrl: GM_getValue('nck_v378_ctrl', true), bayOn: GM_getValue('nck_v378_bay', true), pingShow: GM_getValue('nck_v378_ping', true), lang: GM_getValue('nck_v378_lang', 'zh') }, langLib: { zh: { mtx:'矩阵', bay:'弹仓', keep:'驻留', lock:'锁定', ctrl:'劫持', lang:'中文', hide:'隐藏', ping:'数值' }, en: { mtx:'MTX', bay:'BAY', keep:'KEEP', lock:'LOCK', ctrl:'CTRL', lang:'EN', hide:'HIDE', ping:'PING' } } }; function syncUI() { const box = document.getElementById('nck-main'); if (!box) return; // 深度修复:强制设置 display 属性,确保可见性受控 if (state.conf.visible) { box.style.setProperty('display', 'flex', 'important'); } else { box.style.setProperty('display', 'none', 'important'); } box.classList.toggle('keep-open', state.conf.longShow); const bay = document.getElementById('nck-bay'); if (bay) { bay.classList.toggle('hidden', !state.conf.bayOn); bay.classList.toggle('ctrl-active', state.conf.bindCtrl); } // 刷新内容 const msCN = state.nodes.cn.ms ; const msGL = state.nodes.gl.ms ; // 在 syncUI 函数内部找到 infoBox 渲染逻辑并替换: const infoBox = document.getElementById('nck-info-box'); if (infoBox) { // 确保即使在加载中,也有占位符或正确的数值显示 const displayCN = state.conf.pingShow ? (state.nodes.cn.ms || '--') : ''; const displayGL = state.conf.pingShow ? (state.nodes.gl.ms || '--') : ''; infoBox.innerHTML = ` ${state.nodes.code || 'VSC'} ${displayCN} ${displayGL}`; } // LED const ledCN = document.getElementById('led-cn'); const ledGL = document.getElementById('led-gl'); if (ledCN) ledCN.className = 'nck-led' + (state.nodes.cn.state === 'ok' ? ' led-ok-cn' : (state.nodes.cn.state === 'checking' ? ' led-checking' : '')); if (ledGL) ledGL.className = 'nck-led' + (state.nodes.gl.state === 'ok' ? ' led-ok-gl' : (state.nodes.gl.state === 'checking' ? ' led-checking' : '')); // 面板文本 const valCN = document.getElementById('ip-cn-val'); const valGL = document.getElementById('ip-gl-val'); if (valCN) valCN.innerText = state.nodes.cn.ip; if (valGL) valGL.innerText = state.nodes.gl.ip; // 2. 【新增/修复】刷新面板内部的延迟数值 (Label) const labelCN = document.getElementById('ip-cn-ms-label'); const labelGL = document.getElementById('ip-gl-ms-label'); if (labelCN) labelCN.innerText = msCN; // 更新面板 CN 行的延迟 if (labelGL) labelGL.innerText = msGL; // 更新面板 GLB 行的延迟 // 按钮 const L = state.langLib[state.conf.lang]; const btnConfigs = [ { id: 't-matrix', key: 'matrix', text: L.mtx }, { id: 't-bayOn', key: 'bayOn', text: L.bay }, { id: 't-longShow', key: 'longShow', text: L.keep }, { id: 't-locked', key: 'locked', text: L.lock }, { id: 't-bindCtrl', key: 'bindCtrl', text: L.ctrl }, { id: 't-pingShow', key: 'pingShow', text: L.ping }, { id: 't-lang', key: null, text: L.lang }, { id: 't-hide', key: null, text: L.hide } ]; btnConfigs.forEach(cfg => { const el = document.getElementById(cfg.id); if (el) { el.innerText = cfg.text; if (cfg.key) el.classList.toggle('active', state.conf[cfg.key]); } }); const matrixArea = document.getElementById('matrix-area'); if (matrixArea) matrixArea.classList.toggle('hidden', !state.conf.matrix); renderMatrix(); updatePanelPos(); } function centerBox() { const box = document.getElementById('nck-main'); if (box) { const x = (window.innerWidth - box.offsetWidth) / 2; const y = (window.innerHeight - box.offsetHeight) / 2; box.style.left = x + 'px'; box.style.top = y + 'px'; GM_setValue('nck_v378_pos', { x, y }); updatePanelPos(); } } function renderMatrix() { const grid = document.getElementById('grid-1'); if (grid) grid.innerHTML = state.targets.map(t => `