哥哥科技 发表于 2026-6-2 21:23:12

已解决

本帖最后由 哥哥科技 于 2026-6-2 21:59 编辑

申诉链接:**(https://scriptcat.org/zh-CN/script-show-page/6194)**

!(data/attachment/forum/202606/02/211819j69iq77qeqjj2458.png)

如图所示,昨天的脚本更新以后是完全通过了审核的,然后今天早晨有人在 GitHub 上面提 issue 说针对他家的路由器用不了

然后我就新增了一些处理对象的方法

整个脚本非常安全,没有任何向公网传输参数的地方

并且非常的克制,对性能做了大量的优化,属于一个技术上毫无问题的脚本

请问一下是为什么被删了呢?

如果是误删,能不能帮忙恢复一下?

您可以看到我在别的平台都是强烈推荐脚本猫,在别人都在发 Greazy Fork 的时候,只有我全部发的都是脚本猫的下载链接

!(data/attachment/forum/202606/02/212015vqopdkoul6k38ek3.png)

**国内用户默认就是本站**

!(data/attachment/forum/202606/02/212052tojaxzaf9a29ahhp.png)

代码内容如下:

`JavaScript
// ==UserScript==
// @name            中兴路由器增强 ZTE-Stat_Max
// @name:en         ZTE-Stat_Max
// @namespace       ucxn
// @version         5.9.9Ge
// @description   哥哥科技 QQ群 680464365
// @description:enhttps://github.com/ucxn/ZTE-Stat_Max
// @author          哥哥科技 space.bilibili.com/501430041
// @noframes
// @tag             路由器 中兴 网络 监控 统计 数据 可视化 极客 增强 UI HA 智能 定时 后台
// @icon            https://scriptcat.org/api/v2/resource/image/PD6xhxddlUESIwAV
// @include         /^https?:\/\/10(\.{1,3}){3}(:\d+)?\/.*$/
// @include         http://192.168.*.*
// @match         http://zte.home*
// @include         http://172.16.*
// @include         https://192.168.*.*
// @match         https://zte.home*
// @include         https://172.16.*
// @grant         unsafeWindow
// @grant         GM_setValue
// @storageName   GBNPA_Storage
// @license         AGPL-3.0-or-later
// ==/UserScript==

(function () {
'use strict';

console.log("🚀 哥哥科技 V5.9.9 终极引擎已装载...");

function escapeHTML(str) {
    if (!str) return '';
    return String(str).replace(/[&<>'"]/g, function (match) {
      return {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      "'": '&#39;',
      '"': '&quot;'
      } ;
    });
}

// ======== 用户极客环境变量配置区 ========
const CONFIG = {
    routerIP: "192.168.5.1", // 路由器内网 IP
    forceMeshMode: 1, // 【Mesh探测模式】0: 官方拓扑驱动 | 1: n秒智能等待(默认) | 2: 强制大包抓取(专治阉割、不出数据)
    uiLayout: 1, // 【面板拓扑结构】 0: 经典版 | 1: 详细紧凑版(驾驶舱美学) | 2: 详细平铺版(报表流美学)
    injectMode: 1, // 【UI注入模式】 0: 原生侧边栏(1min)| 1: 优先,10秒悬浮舱(D)| 2: 强制模式(30秒后强制霸屏)
    calcMode: 1, // 1: 上行/下行倍数模式, 0: 上行占总和比例模式
    ratioExtremeUp: 10, // 极端上传判定阈值 (> 1000%)
    ratioWarnUp: 0.07, // 重度上传警告阈值 (> 7%)
    ratioExtremeDown: 0.01, // 极端下载判定阈值 (< 1%)
    ratioThreshold: 7, // (仅calcMode=0时有效) 上传占比报警阈值(%)
    readSaveData: 1, // 【开关切换】 1: 读档模式(继承本次历史量) | 0: 新局模式(从打开网页此刻归零重新计流)
    lanRefreshInterval: 5, // 【新增】LAN口刷新时间(秒),用于精准补偿0到唤醒时的瞬时流量
    portMap: {
      "eth1": "网口 1",
      "eth2": "网口 2",
      "eth3": "网口 3",
      "eth4": "网口 4",
      "wl0": "2.4G",
      "wl1": "5.2G",
      "wl2": "5.8G"
    }
};

const S = {
    lt: 0,
    wInstUp: 0,
    wInstDn: 0,
    wTotUp: 0,
    wTotDn: 0,
    cls: {}
};
let isF = !1,
    pr = new DOMParser(),
    lCxt = null;
const oOp = unsafeWindow.XMLHttpRequest.prototype.open;
unsafeWindow.XMLHttpRequest.prototype.open = function () {
    this.
    addEventListener('load', function () {
      try {
      if (this.responseType === '' ||
          this.responseType === 'text') {
          let t = this.responseText;
          if (t && (t.includes('<OBJ_CLIENTS_ID>') || t.includes('<OBJ_HOME_BASICINFO_ID>'))) {
            if (t.includes('<OBJ_CLIENTS_ID>')) lCxt = t;
            if (window.startGegePrecisionEngine) {
            window.startGegePrecisionEngine();
            }
          }
      }
      }
      catch (e) {
      console.warn("[哥哥科技] XHR 拦截器异常:", e.message);
      }
    });
    oOp.apply(this, arguments);
};

function s2b(s) {
    let m = s?.match(/([\d.]+)\s*(G|M|K)?bps/i);
    if (!m) return 0;
    let v = parseFloat(m),
      u = (m || "").toUpperCase();
    return u === 'G' ? v * 1e9 : u === 'M' ? v * 1e6 : u === 'K' ? v * 1e3 : v;
}

function fB(b) {
    return b >= 1e9 ? `${(b/1e9).toFixed(3)} Gbps` : b >= 1e6 ? `${(b/1e6).toFixed(2)} Mbps` : b >= 1e3 ? `${(b/1e3).toFixed(1)} Kbps` : `${Math.round(b)} bps`;
}

function fBy(b) {
    return b >= 8589934592 ? `${(b/8589934592).toFixed(3)} GiB/s` : b >= 8388608 ? `${(b/8388608).toFixed(2)} MiB/s` : b >= 8192 ? `${(b/8192).toFixed(1)} KiB/s` : `${Math.round(b/8)} B/s`;
}

function fV(b) {
    return b >= 8796093022208 ? `${(b/8796093022208).toFixed(4)} TiB` : b >= 8589934592 ? `${(b/8589934592).toFixed(3)} GiB` : b >= 8388608 ? `${(b/8388608).toFixed(2)} MiB` : b >= 8192 ? `${(b/8192).toFixed(1)} KiB` : `${Math.round(b/8)} B`;
}

function fVD(i, o) {
    return i >= 8796093022208 ? `${(o/8796093022208).toFixed(4)} | ${(i/8796093022208).toFixed(4)} TiB` : i >= 8589934592 ? `${(o/8589934592).toFixed(4)} | ${(i/8589934592).toFixed(3)} GiB` : i >= 8388608 ? `${(o/8388608).toFixed(3)} | ${(i/8388608).toFixed(2)} MiB` : i >= 8192 ? `${(o/8192).toFixed(1)} | ${(i/8192).toFixed(2)} KiB` : `${Math.round(o/8)} | ${Math.round(i/8)} B`;
}

function fSV(b) {
    return (b /= 8) >= 1073741824 ? (b / 1073741824).toFixed(3) + 'G' : b >= 1048576 ? (b / 1048576).toFixed(2) + 'M' : b >= 1024 ? (b / 1024).toFixed(1) + 'K' : Math.round(b) + 'B';
}

function fOT(s) {
    if (s <= 0) return "";
    let d = Math.floor(s / 86400),
      h = Math.floor((s % 86400) / 3600),
      m = Math.floor((s % 3600) / 60),
      sec = Math.floor(s % 60);
    return d > 0 ? `${d}天${h}时${m}分${sec}秒` : `${h}小时${m}分${sec}秒`;
}

function nM(m) {
    return m ? m.toLowerCase().replace(/-/g, ':').replace(/\s/g, '') : '';
}

function pI(n) {
    let o = Object.create(null),
      c = n.children;
    for (let i = 0; i < c.length; i++) {
      if (c.tagName === "ParaName") {
      let k = c.textContent,
          v = "",
          j = i + 1;
      while (j < c.length && c.tagName !== "ParaName") {
          if (c.tagName === "ParaValue") {
            v = c.textContent;
            i = j;
            break;
          }
          j++;
      }
      o = v;
      }
    }
    return o;
}
const st = document.createElement('style');
st.innerHTML = `.config-item{
      clear:both;}.config-item-box{display:flex!important;
      align-items:stretch!important;padding-bottom:
      12px!important;}.config-item .logo{width:33%!important;
      float:none!important;display:flex!important;flex-direction:row;}.config-item .dev-intro{flex:1;display:flex!important;flex-direction:column;justify-content:flex-start;min-height:100px;padding-bottom:0!important;margin-bottom:0!important;}.config-item .info{width:27%!important;float:none!important;display:flex!important;flex-direction:column;justify-content:flex-start;padding:0 10px!important;border-right:1px solid #eee;}.config-item .speed{width:40%!important;float:none!important;display:flex!important;flex-direction:column;justify-content:center;padding:0 10px!important;}.geek-row{display:flex;justify-content:space-between;align-items:center;white-space:nowrap;height:20px;}
    .geek-label{width:110px;color:#333;font-weight:bold;}.geek-val-box{flex:1;display:flex;gap:15px;margin-left:10px;}.geek-fixed-width{display:inline-block;width:120px;}.geek-right-box{text-align:right;min-width:220px;font-weight:bold;}.c-up{color:#ff4c00;}.c-down{color:#0059fa;}.gege-up-box,.gege-down-box{margin-top:auto!important;margin-bottom:0!important;width:95%;}.gege-ratio-box{margin-top:10px;width:95%;margin-bottom:5px;}.t-row{font-size:12px;font-weight:bold;margin-bottom:2px;display:flex;justify-content:space-between;font-family:Consolas;}.zte-thin-bar{width:100%;height:3px;background:rgba(0,0,0,0.05);border-radius:1.5px;overflow:hidden;}.zte-thin-bar-inner{height:100%;transition:width 0.5s ease-out;}.zte-thin-bar-inner.up{background:#ff4c00;}.zte-thin-bar-inner.down{background:#0059fa;}.gege-ratio-top{display:flex;justify-content:space-between;font-size:12px;font-weight:bold;margin-bottom:2px;}.gege-ratio-bar{width:100%;height:4px;background:#0059fa;border-radius:2px;overflow:hidden;}.gege-ratio-bar-inner{height:100%;background:#ff4c00;transition:width 0.5s ease-out;}.zte-enhance-speed{display:flex;flex-direction:column;gap:6px;width:100%;font-family:Consolas;}
    .zte-bar-wrap{position:relative;width:100%;border-radius:4px;border:1px solid;font-size:13px;font-weight:bold;overflow:hidden;padding:3px 8px;display:flex;justify-content:space-between;align-items:center;z-index:1;box-sizing:border-box;}.zte-bar-wrap span{font-size:inherit;font-weight:inherit;}.zte-bar-up{color:#ff4c00;border-color:rgba(255,76,0,0.3);}.zte-bar-down{color:#0059fa;border-color:rgba(0,89,250,0.3);}.zte-bar-up::before{content:'';position:absolute;left:0;top:0;bottom:0;z-index:-1;background:rgba(255,76,0,0.12);width:var(--p-up,0%);transition:width 0.5s;}.zte-bar-down::before{content:'';position:absolute;left:0;top:0;bottom:0;z-index:-1;background:rgba(0,89,250,0.12);width:var(--p-down,0%);transition:width 0.5s;}#config-list.gege-list-container{contain:content!important;background-color:#ffffff!important;border-radius:8px!important;border:1px solid #e0e0e0!important;padding:20px 30px!important;box-shadow:0 2px 10px rgba(0,0,0,0.02)!important;margin-top:10px!important;}.gege-section{margin-bottom:10px;}
    .gege-section:last-child{margin-bottom:0;}.gege-list-container .config-title{font-size:16px!important;font-weight:bold!important;color:#333!important;margin:15px 0 10px 0!important;padding-bottom:5px!important;}.gege-list-container .gege-section:first-child .config-title{margin-top:0!important;}.gege-empty-state{color:#999!important;font-size:14px!important;padding:0 0 15px 5px!important;border-bottom:1px solid #f0f0f0!important;margin-bottom:5px!important;}.gege-list-item{background-color:transparent!important;border-bottom:1px solid #f0f0f0!important;padding:15px 10px!important;margin-bottom:0!important;border-radius:0!important;}.gege-list-item:last-child{border-bottom:none!important;}#zte-geek-board{contain:content;background-color:transparent!important;border-left:4px solid #0059fa!important;border-radius:0!important;padding:5px 0 5px 15px!important;margin:10px 0 15px 0!important;box-shadow:none!important;border-bottom:1px solid #f0f0f0!important;font-size:14px;display:flex;flex-direction:column;gap:6px;padding-bottom:15px!important;}`;
document.
head.
appendChild(st);
window.gegeRenderedMacs = new Set();
async function rSD(pWT = null, sT = null) {
    if (
      isF && !pWT) return;
    isF = !0;
    let n, wX;
    try {
      if (pWT) {
      wX = pr.parseFromString(pWT,
          "text/xml");
      n = sT || performance.now();
      }
      else {
      const wR = await fetch(`/?_type=vueData&_tag=vue_home_device_data_no_update_sess&IF_OP=refresh&_=${Date.now()}`);
      if (
          !wR.ok) return;
      const wT = await wR.text();
      n = performance.now();
      if (!wT.includes('<OBJ_HOME_BASICINFO_ID>')) return;
      wX = pr.parseFromString(
          wT, "text/xml");
      }
      let cX = lCxt ? pr.parseFromString(lCxt, "text/xml") : null;
      const bIN = wX.querySelector(
          "OBJ_HOME_BASICINFO_ID Instance"),
      wI = bIN ? pI(bIN) : {},
      cWU = s2b(wI.WANUpRate),
      cWD = s2b(
          wI.WANDownRate),
      cI = Object.create(null);
      let cSU = 0,
      cSD = 0;
      (cX?.querySelectorAll("OBJ_CLIENTS_ID Instance") || []).forEach(nd => {
      let d = pI(
          nd);
      if (d.MACAddress) {
          let m = nM(d.MACAddress),
            u = s2b(d.UpRate),
            dn = s2b(d.DownRate),
            uT = (
            parseFloat(d.UpThroughput) || 0) * 8000,
            dT = (parseFloat(d.DownThroughput) || 0) * 8000;
          let bN =
            d.AliasName || d.HostName || d.DisplayedPictureName || "";
          cI = {
            upRate: u,
            dnRate: dn,
            iface: d.Interface || "",
            offUp: uT,
            offDn: dT,
            onSec: parseInt(d.OnlineDuration || d.OnlineTime || d.LeaseTime || 0),
            name: bN,
            ip: d.IPAddress || ""
          };
          cSU += u;
          cSD += dn;
      }
      });
      let ol = document.getElementById('gege-global-overlay'),
      cM = Object.keys(
          cI),
      iD = window.gegeForceUIRedraw || (cM.length !== window.gegeRenderedMacs.size);
      if (!iD && cM.length > 0) {
      for (let i = 0; i <
          cM.length; i++) {
          if (!window.gegeRenderedMacs.has(cM)) {
            iD = !0;
            break;
          }
      }
      }
      let iDW = ol && ol.style.display === 'block' && !ol.querySelector(
      '.gege-list-item');
      if (ol && ol.style.display === 'block' && (iD || iDW)) {
      bVD(ol, cX);
      window.gegeRenderedMacs = new Set(
          cM);
      window.gegeForceUIRedraw = !1;
      }
      let gDt = (S.lt !== 0) ? (n - S.lt) / 1000 : 0;
      if (S.wLT === undefined) {
      S.wLT = n;
      }
      else if (cWU !== S.wInstUp || cWD !== S.wInstDn) {
      let wDt = n - S.wLT;
      if (S.wInstUp > 0) S.wTotUp += (S.wInstUp + cWU) * wDt / 2000;
      if (S.wInstDn > 0) S.wTotDn += (S.wInstDn + cWD) * wDt / 2000;
      S.wLT = n;
      }
      for (const of Object.entries(cI)) {
      S.cls ??= {
          upR: cC.upRate,
          dnR: cC.dnRate,
          lUT: n,
          intUp: 0,
          intDn: 0,
          uB: CONFIG.readSaveData === 1 ? 0 : cC.offUp,
          dB: CONFIG.readSaveData === 1 ? 0 : cC.offDn,
          lU: cC.offUp,
          lD: cC.offDn,
          aR: !1,
          dpU: 0,
          dpD: 0,
          oU: CONFIG.readSaveData === 1 ? cC.offUp : 0,
          oD: CONFIG.readSaveData === 1 ? cC.offDn : 0
      };
      let cS = S.cls,
          dU = cC.offUp - cS.lU,
          dD = cC.offDn - cS.lD;
      if (dU < 0 || dD < 0) {
          if (dU < 0) {
            cS.uB += dU;
            cS.dpU = cS.lU;
          }
          if (dD < 0) {
            cS.dB += dD;
            cS.dpD = cS.lD;
          }
          cS.aR = !0;
      }
      else if (cS.aR) {
          if (dD > 2516582400 || dU > 671088640 || (cS.dpD && dD >= cS.dpD) || (cS.dpU && dU >= cS.dpU)) {
            cS.uB += dU;
            cS.dB += dD;
            cS.aR = !1;
            cS.dpU = 0;
            cS.dpD = 0;
          }
      }
      if (cS.lOS !== cC.onSec) {
          cS.onS = cC.onSec;
          cS.lOS = cC.onSec;
      }
      else {
          cS.onS = (cS.onS || cC.onSec || 0) + gDt;
      }
      if (cC.upRate !== cS.upR || cC.dnRate !== cS.dnR) {
          let ms = n - cS.lUT;
          if (cS.upR > 0) cS.intUp += (cS.upR + cC.upRate) * ms / 2000;
          else if (cC.upRate > 0) cS.intUp += (cC.upRate / 2) * CONFIG.lanRefreshInterval;
          if (cS.dnR > 0) cS.intDn += (cS.dnR + cC.dnRate) * ms / 2000;
          else if (cC.dnRate > 0) cS.intDn += (cC.dnRate / 2) * CONFIG.lanRefreshInterval;
          cS.upR = cC.upRate;
          cS.dnR = cC.dnRate;
          cS.lUT = n;
      }
      cS.lU = cC.offUp;
      cS.lD = cC.offDn;
      }
      S.lt = n;
      S.wInstUp = cWU;
      S.wInstDn = cWD;
      rUI(cWU, cWD, cSU, cSD, cI);
    }
    catch (e) {
      console.error("[哥哥科技] 周期采样中断:", e);
    }
    finally {
      isF = !1;
    }
}

function rUI(wU, wD, sU, sD, cI) {
    let tOD = 0,
      LUp = 0,
      LDn = 0,
      hpU = 0,
      hpD = 0,
      abU = 0,
      abD = 0,
      curHpU = 0,
      curHpD = 0,
      cln = {};
    for (const of Object.entries(S.cls)) {
      let cC = cI,
      cU = Math.max(0, (s.lU || 0) - (s.uB || 0) - (s.oU || 0)),
      cD = Math.max(0, (s.lD || 0) - (s.dB || 0) - (s.oD || 0));
      LUp += s.intUp || 0;
      LDn += s.intDn || 0;
      hpU += cU;
      hpD += cD;
      if (cC) {
      curHpU += cU;
      curHpD += cD;
      tOD += cC.offDn || 0;
      abU += cC.offUp || 0;
      abD += cC.offDn || 0;
      }
      cln = {
      up: cU,
      down: cD,
      integral_up: s.intUp || 0,
      integral_down: s.intDn || 0,
      status: s.aR ? "off" : (CONFIG.portMap || cC?.iface || "未知接口"),
      name: cC?.name || k,
      ip: cC?.ip || "",
      raw_up: cC?.offUp || 0,
      raw_down: cC?.offDn || 0
      };
    }
    GM_setValue('ha_snapshot', {
      timestamp: Date.now(),
      global: {
      wan_up: S.wTotUp,
      wan_down: S.wTotDn,
      lan_integral_up: LUp,
      lan_integral_down: LDn,
      lan_high_up: hpU,
      lan_high_down: hpD,
      lan_off_up: abU,
      lan_off_down: abD
      },
      devices: cln
    });
    S.rTick = ((S.rTick || 0) + 1) & 31;
    if (S.rTick === 1 || !S.cRT) {
      const cSR = (W, I, H) => {
      if (W === 0) return 1.0;
      let M = Math.max(I, H),
          m = Math.min(I, H),
          G = Math.abs(I - H);
      if (I >= 0.84 * W && H >= 0.75 * W && (M <= 1.5 * W || G <= 0.6 * W)) return ((I + H) / 2) / W;
      if (m < W && W <= M && M <= 1.5 * W) return M / W;
      return (Math.abs(I - W) < Math.abs(H - W) ? I : H) / W;
      };
      let rU = cSR(S.wTotUp, LUp, hpU),
      rD = cSR(S.wTotDn, LDn, hpD),
      mR = Math.max(rU, rD),
      rC = mR > 1.5 ? '#ff4c00' : mR > 1.15 ? '#FF9800' : '#4CAF50';
      S.cRT = `<span style="color:${rC};font-weight:bold;">${(rU*100).toFixed(2)}%,${(rD*100).toFixed(2)}%</span>`;
    }
    let bd = document.getElementById('zte-geek-board');
    if (!bd) {
      bd = document.createElement('div');
      bd.id = 'zte-geek-board';
      let lH = '';
      if (CONFIG.uiLayout === 1) {
      lH = `<div class="geek-row"><span class="geek-label">WAN口速率</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-wan-up-bytes"></span><span class="c-down geek-fixed-width" id="gb-wan-down-bytes"></span></div><div class="geek-right-box"><span class="c-up" id="gb-wan-up-bps"></span> | <span class="c-down" id="gb-wan-down-bps"></span></div></div><div class="geek-row"><span class="geek-label">局域网代数和</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-lan-up-bytes">
</span><span class="c-down geek-fixed-width" id="gb-lan-down-bytes"></span></div><div class="geek-right-box">实时占比:<span class="c-up" id="gb-perc-up"></span> | <span class="c-down" id="gb-perc-down"></span></div></div><div class="geek-row">
<div style="display:flex;width:375px;"><span class="geek-label">LAN:</span><div style="display:flex;gap:15px;"><span class="c-up geek-fixed-width" id="gb-lan-up-vol"></span><span class="c-down geek-fixed-width" id="gb-lan-down-vol"></span></div></div><div style="flex:1;text-align:center;font-weight:bold;">WAN:<span class="c-up" id="gb-wan-up-vol"></span> | <span class="c-down" id="gb-wan-down-vol"></span></div><div class="geek-right-box">在线高精:<span style="color:#FF6700;" id="gb-cur-up-vol"></span> | <span style="color:#18A058;" id="gb-cur-down-vol"></span></div></div><div class="geek-row"><div style="display:flex;width:375px;"><span class="geek-label">高精流量统计 -></span><div style="display:flex;gap:15px;"><span class="c-up geek-fixed-width" id="gb-int-up-vol">
</span><span class="c-down geek-fixed-width" id="gb-int-down-vol"></span></div></div><div style="flex:1;text-align:center;color:#666;">内外网比:<span id="gb-ratio-display"></span></div><div class="geek-right-box" style="color:#666;">当前总计:<span style="color:#FF6700;" id="gb-abs-up-vol"></span> | <span style="color:#18A058;" id="gb-abs-down-vol"></span></div></div>`;
      }
      else if (CONFIG.uiLayout === 2) {
      lH = `<div class="geek-row"><span class="geek-label">WAN口速率</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-wan-up-bytes"></span><span class="c-down geek-fixed-width" id="gb-wan-down-bytes"></span></div><div class="geek-right-box"><span class="c-up" id="gb-wan-up-bps"></span> | <span class="c-down" id="gb-wan-down-bps"></span></div></div><div class="geek-row"><span class="geek-label">局域网代数和</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-lan-up-bytes"></span><span class="c-down geek-fixed-width" id="gb-lan-down-bytes"></span></div><div class="geek-right-box">实时占比:<span class="c-up" id="gb-perc-up"></span> | <span class="c-down" id="gb-perc-down"></span></div></div><div class="geek-row">
<span class="geek-label">LAN:</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-lan-up-vol"></span><span class="c-down geek-fixed-width" id="gb-lan-down-vol"></span></div><div class="geek-right-box">在线高精:<span style="color:#FF6700;" id="gb-cur-up-vol"></span> | <span style="color:#18A058;" id="gb-cur-down-vol"></span></div></div><div class="geek-row"><span class="geek-label">高精流量统计 -></span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-int-up-vol"></span><span class="c-down geek-fixed-width" id="gb-int-down-vol"></span></div><div class="geek-right-box" style="color:#666;">当前总计:<span style="color:#FF6700;" id="gb-abs-up-vol"></span> | <span style="color:#18A058;" id="gb-abs-down-vol"></span></div></div><div class="geek-row">
<span class="geek-label">WAN:</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-wan-up-vol"></span><span class="c-down geek-fixed-width" id="gb-wan-down-vol"></span></div><div class="geek-right-box"><span style="font-weight:normal;">内外网比:</span><span id="gb-ratio-display"></span></div></div>`;
      }
      else lH = `<div class="geek-row"><span class="geek-label">WAN口速率</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-wan-up-bytes"></span><span class="c-down geek-fixed-width" id="gb-wan-down-bytes"></span></div><div class="geek-right-box"><span class="c-up" id="gb-wan-up-bps"></span> | <span class="c-down" id="gb-wan-down-bps"></span></div></div><div class="geek-row"><span class="geek-label">局域网代数和</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-lan-up-bytes"></span><span class="c-down geek-fixed-width" id="gb-lan-down-bytes"></span></div><div class="geek-right-box">实时占比:<span class="c-up" id="gb-perc-up"></span> | <span class="c-down" id="gb-perc-down"></span></div></div><div class="geek-row"><span class="geek-label">LAN:</span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-lan-up-vol"></span>
<span class="c-down geek-fixed-width" id="gb-lan-down-vol"></span></div><div class="geek-right-box">WAN:<span class="c-up" id="gb-wan-up-vol"></span> | <span class="c-down" id="gb-wan-down-vol"></span></div></div><div class="geek-row"><span class="geek-label">高精流量统计 -></span><div class="geek-val-box"><span class="c-up geek-fixed-width" id="gb-int-up-vol"></span><span class="c-down geek-fixed-width" id="gb-int-down-vol"></span></div><div class="geek-right-box" style="color:#666;">当前总计:<span style="color:#FF6700;" id="gb-abs-up-vol"></span> | <span style="color:#18A058;" id="gb-abs-down-vol"></span></div></div>`;
      bd.innerHTML = lH;
    }
    let ol = document.getElementById('gege-global-overlay'),
      iPO = ol && ol.style.display === 'block',
      aC = iPO ? ol : document;
    if (iPO) {
      let ac = document.getElementById('gege-board-anchor');
      if (ac && bd.parentNode !== ac) ac.appendChild(bd);
    }
    else {
      let mn = document.querySelector('.el-table') || document.querySelector('.config-item')?.closest('div') || document.querySelector('.main-content');
      if (mn && bd.parentNode !== mn.parentNode) mn.parentNode.insertBefore(bd, mn);
    }
    let oDC = Object.create(null);
    if (!iPO) {
      const M_RX = /({2}[:-]){5}{2}/;
      let aI = aC.querySelectorAll('.config-item');
      for (let n of aI) {
      let mN = n.querySelector('.dev-number'),
          mM = mN ? mN.textContent.match(M_RX) : null;
      if (mM) {
          oDC.toLowerCase().replace(/-/g, ':')] = n;
      }
      }
    }
    else {
      let gI = aC.querySelectorAll('.gege-list-item');
      for (let n of gI) {
      let m = n.getAttribute('data-gege-mac');
      if (m) oDC = n;
      }
    }
    requestAnimationFrame(() => {
      if (bd.parentNode) {
      bd.querySelector('#gb-wan-up-bytes').textContent = `🔼 ${fBy(wU)}`;
      bd.querySelector('#gb-wan-down-bytes').textContent = `🔽 ${fBy(wD)}`;
      bd.querySelector('#gb-wan-up-bps').textContent = `🔼 ${fB(wU)}`;
      bd.querySelector('#gb-wan-down-bps').textContent = `🔽 ${fB(wD)}`;
      bd.querySelector('#gb-lan-up-bytes').textContent = `🔼 ${fBy(sU)}`;
      bd.querySelector('#gb-lan-down-bytes').textContent = `🔽 ${fBy(sD)}`;
      bd.querySelector('#gb-perc-up').textContent = `🔼 ${wU>0?((sU/wU)*100).toFixed(1):0.0}%`;
      bd.querySelector('#gb-perc-down').textContent = `🔽 ${wD>0?((sD/wD)*100).toFixed(1):0.0}%`;
      bd.querySelector('#gb-lan-up-vol').textContent = `🔼 ${fV(LUp)}`;
      bd.querySelector('#gb-lan-down-vol').textContent = `🔽 ${fV(LDn)}`;
      bd.querySelector('#gb-wan-up-vol').textContent = `🔼 ${fV(S.wTotUp)}`;
      bd.querySelector('#gb-wan-down-vol').textContent = `🔽 ${fV(S.wTotDn)}`;
      bd.querySelector('#gb-int-up-vol').textContent = `🔼 ${fV(hpU)}`;
      bd.querySelector('#gb-int-down-vol').textContent = `🔽 ${fV(hpD)}`;
      bd.querySelector('#gb-abs-up-vol').textContent = `🔼 ${fV(abU)}`;
      bd.querySelector('#gb-abs-down-vol').textContent = `🔽 ${fV(abD)}`;
      if (bd.querySelector('#gb-ratio-display')) {
          bd.querySelector('#gb-cur-up-vol').textContent = `🔼 ${fV(curHpU)}`;
          bd.querySelector('#gb-cur-down-vol').textContent = `🔽 ${fV(curHpD)}`;
          bd.querySelector('#gb-ratio-display').innerHTML = S.cRT;
      }
      }
      for (let m in cI) {
      let it = oDC;
      if (!it) continue;
      const cC = cI || {
            upRate: 0,
            dnRate: 0,
            iface: "",
            offUp: 0,
            offDn: 0
          },
          cS = S.cls || {
            intUp: 0,
            intDn: 0,
            onS: 0
          };
      let tN = it.querySelector('.gege-online-time');
      if (tN && cS.onS > 0) tN.textContent = `在线:${fOT(cS.onS)}`;
      const dI = it.querySelector('.dev-intro');
      if (dI) {
          let bx = dI.querySelector('.gege-up-box');
          if (!bx) {
            bx = document.createElement('div');
            bx.className = 'gege-up-box';
            bx.innerHTML = `<div class="t-row c-up"><span>↑ <span class="v-vol"></span></span><span class="v-pct"></span></div><div class="zte-thin-bar"><div class="zte-thin-bar-inner up"></div></div>`;
            dI.appendChild(bx);
          }
          let hqU = cln ? cln.up : 0;
          let p = hpU > 0 ? (hqU / hpU * 100).toFixed(1) : 0.0;
          bx.querySelector('.v-vol').textContent = fVD(cS.intUp, cC.offUp);
          bx.querySelector('.v-pct').textContent = p + '%';
          bx.querySelector('.zte-thin-bar-inner').style.width = Math.min(p, 100) + '%';
      }
      const inf = it.querySelector('.info');
      if (inf) {
          Array.from(inf.querySelectorAll('.dev-ip:not(.gege-box *)')).slice(1).forEach(n => {
            n.style.display = 'none';
          });
          inf.querySelectorAll('.dev-number:not(.gege-box *)').forEach(n => {
            n.style.display = 'none';
          });
          let rB = inf.querySelector('.gege-ratio-box');
          if (!rB) {
            rB = document.createElement('div');
            rB.className = 'gege-ratio-box';
            rB.innerHTML = `<div class="gege-ratio-top"><span class="v-port"></span><span class="v-interval" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-weight: normal; font-size: 12.5px; opacity: 0.75; letter-spacing: 0.5px;"><span class="c-up"></span><span style="color:#666; margin:0 3px;">,</span><span class="c-down"></span></span><span class="v-rt-pct"></span></div><div class="gege-ratio-bar"><div class="gege-ratio-bar-inner"></div></div>`;
            inf.appendChild(rB);
          }
          let hqU = cln ? cln.up : 0,
            hqD = cln ? cln.down : 0,
            bR = (hqU + hqD) > 0 ? (hqU / (hqU + hqD) * 100) : 0,
            tC = "",
            tCol = "#0059fa";
          if (CONFIG.calcMode === 1) {
            let rt = hqD > 0 ? (hqU / hqD) : (hqU > 0 ? Infinity : 0);
            if (rt > CONFIG.ratioExtremeUp) {
            tCol = '#ff4c00';
            tC = (rt === Infinity ? '∞' : rt.toFixed(2)) + '⚠️';
            }
            else if (rt > CONFIG.ratioWarnUp) {
            tCol = '#ff4c00';
            tC = (rt * 100).toFixed(1) + '%';
            }
            else if (rt >= CONFIG.ratioExtremeDown) {
            tCol = '#0059fa';
            tC = (rt * 100).toFixed(1) + '%';
            }
            else {
            tCol = '#0059fa';
            let rRt = hqU > 0 ? (hqD / hqU) : (hqD > 0 ? Infinity : 0);
            tC = (rRt === Infinity ? '∞' : rRt.toFixed(1)) + 'x';
            }
          }
          else {
            tCol = bR > CONFIG.ratioThreshold ? '#ff4c00' : '#0059fa';
            tC = bR.toFixed(1) + '%';
          }
          rB.querySelector('.v-port').textContent = CONFIG.portMap || cC.iface || "未知";
          rB.querySelector('.v-interval .c-up').textContent = '' + fSV(hqU);
          rB.querySelector('.v-interval .c-down').textContent = '' + fSV(hqD);
          let rtP = rB.querySelector('.v-rt-pct');
          rtP.textContent = tC;
          rtP.style.color = tCol;
          rB.querySelector('.gege-ratio-bar-inner').style.width = Math.min(bR, 100) + '%';
          let dBx = inf.querySelector('.gege-down-box');
          if (!dBx) {
            dBx = document.createElement('div');
            dBx.className = 'gege-down-box';
            dBx.innerHTML = `<div class="t-row c-down"><span>↓ <span class="v-vol"></span></span><span class="v-pct"></span></div><div class="zte-thin-bar"><div class="zte-thin-bar-inner down"></div></div>`;
            inf.appendChild(dBx);
          }
          let dp = tOD > 0 ? ((cC.offDn || 0) / tOD * 100).toFixed(1) : 0.0;
          dBx.querySelector('.v-vol').textContent = fVD(cS.intDn, cC.offDn);
          dBx.querySelector('.v-pct').textContent = dp + '%';
          dBx.querySelector('.zte-thin-bar-inner').style.width = Math.min(dp, 100) + '%';
      }
      const sp = it.querySelector('.speed');
      if (sp) {
          sp.querySelectorAll('.connect-up, .connect-down').forEach(n => {
            n.style.display = 'none';
          });
          let enh = sp.querySelector('.zte-enhance-speed');
          if (!enh) {
            enh = document.createElement('div');
            enh.className = 'zte-enhance-speed';
            enh.innerHTML = `<div class="zte-bar-wrap zte-bar-up"><span class="v-val"></span><span class="v-pct"></span></div><div class="zte-bar-wrap zte-bar-down"><span class="v-val"></span><span class="v-pct"></span></div>`;
            sp.appendChild(enh);
          }
          let pu = sU > 0 ? (cC.upRate / sU * 100) : 0,
            pd = sD > 0 ? (cC.dnRate / sD * 100) : 0,
            bU = enh.querySelector('.zte-bar-up'),
            bD = enh.querySelector('.zte-bar-down');
          bU.style.setProperty('--p-up', Math.min(pu, 100) + '%');
          bU.querySelector('.v-val').textContent = `🔼 ${fBy(cC.upRate)}`;
          bU.querySelector('.v-pct').textContent = (wU > 0 ? pu.toFixed(1) : 0.0) + '%';
          bD.style.setProperty('--p-down', Math.min(pd, 100) + '%');
          bD.querySelector('.v-val').textContent = `🔽 ${fBy(cC.dnRate)}`;
          bD.querySelector('.v-pct').textContent = (wD > 0 ? pd.toFixed(1) : 0.0) + '%';
      }
      }
    });
}
async function bVD(ol, cX) {
    try {
      let mB = (window.gegeHiddenDevices && Object.keys(window.gegeHiddenDevices).length > 0) ? '<span style="color: #ff4c00; font-size: 13px; font-weight: normal; margin-left: 10px; font-family: Consolas;">(哥哥科技:智能Mesh适配)</span>' : '',
      h2 = [],
      h52 = [],
      h58 = [],
      hW = [];
      (cX?.querySelectorAll("OBJ_CLIENTS_ID Instance") || []).forEach(i => {
      let d = pI(i);
      if (!d.MACAddress) return;
      let m = nM(d.MACAddress),
          ip = escapeHTML(d.IPAddress || ''),
          nm = escapeHTML(d.AliasName || d.HostName || '未知设备'),
          ifc = d.Interface || '',
          oS = parseInt(d.OnlineDuration || d.OnlineTime || d.LeaseTime || 0),
          tS = fOT(oS),
          tH = `<div class="gege-online-time" style="color: #999; font-size: 12px; font-family: Consolas; margin-top: 4px;">${tS?'在线:'+tS:''}</div>`,
          htm = `<div class="col-md-12 col-xs-12 config-item gege-list-item" data-gege-mac="${m}"><div class="config-item-box" style="display: flex; align-items: stretch;"><div class="col-md-5 col-xs-7 logo" style="width: 33%; display: flex; flex-direction: row; align-items: center;"><div class="dev-logo" style="width: 50px; height: 50px; min-width: 50px; margin-right: 15px; background: url('/jquery/static/img/home/unknown_computer.png') 0% 0% / 50px no-repeat; display: inline-block;"></div><div class="dev-intro" style="flex: 1; display: flex; flex-direction: column; justify-content: flex-start; min-height: 100px;">
<div class="dev-name" style="font-weight: bold; color: #333; font-size: 14px;">${nm}</div>${tH}</div></div><div class="col-md-4 col-xs-5 info" style="width: 27%; display: flex; flex-direction: column; padding: 0 10px; border-right: 1px solid #eee;"><div class="dev-ip" style="color: #666; font-family: Consolas;">${ip}</div><div class="dev-number grey" style="color: #999; font-size: 12px; font-family: Consolas;">MAC:${m}</div></div><div class="col-md-3 col-xs-12 speed" style="width: 40%; display: flex; flex-direction: column; justify-content: center; padding: 0 10px;"></div></div></div>`;
      if (['wl0', 'wlan0', 'wlan1', 'wl1'].includes(ifc)) h2.push(htm);
      else if (['wlan5', 'wl4', 'wlan4', 'wl3', 'wlan3'].includes(ifc)) h52.push(htm);
      else if (ifc === 'wl2' || ifc === 'wlan2' || ifc === 'wl5' || (/w/i.test(ifc) && !/wan/i.test(ifc))) h58.push(htm);
      else hW.push(htm);
      });
      requestAnimationFrame(() => {
      ol.innerHTML = `<div style="padding: 20px; max-width: 1200px; margin: 0 auto; min-height: 100%;"><div id="gege-board-anchor"></div><div id="config-list" class="config-list gege-list-container"><div class="gege-section"><div class="config-title">无线设备(2.4GHz)</div>${h2.join('')||'<div class="gege-empty-state">没有连接设备</div>'}</div><div class="gege-section"><div class="config-title">无线设备(5.2GHz)</div>${h52.join('')||'<div class="gege-empty-state">没有连接设备</div>'}
</div><div class="gege-section"><div class="config-title">无线设备(5.8GHz)</div>${h58.join('')||'<div class="gege-empty-state">没有连接设备</div>'}</div><div class="gege-section"><div class="config-title">有线设备${mB}</div>
${hW.join('')||'<div class="gege-empty-state">没有连接设备</div>'}</div></div></div>`;
      });
    }
    catch (e) {
      requestAnimationFrame(() => {
      ol.innerHTML = `<div style="padding: 20px; color: red;">数据渲染失败: ${escapeHTML(e.message)}</div>`;
      });
    }
}
window.createGegeFloatingBtn = function () {
    if (document.getElementById('gege-floating-btn')) return;
    let b =
      document.createElement('div');
    b.id = 'gege-floating-btn';
    b.innerHTML = '🛸';
    b.style.cssText = `position: fixed; ` +
      `top: 20px; right: 20px; width: 50px; height: 50px; background: ` +
      `linear-gradient(135deg, #0059fa, #00c6ff); color: white; border-radius: 50%; display: flex; ` +
      `align-items: center; justify-content: center; font-size: 48px; box-shadow: 0 4px 15px rgba(0,89,250,0.5); ` +
      `cursor: pointer; z-index: 99999; transition: all 0.3s ease; user-select: none;`;
    b.
    onmouseover = () => {
      b.style.transform = 'scale(1.1) rotate(15deg)';
    };
    b.onmouseout = () => {
      b.style.transform =
      'scale(1) rotate(0deg)';
    };
    b.onclick = () => window.gegeTogglePanel();
    document.body.appendChild(b);
};
window.gegeTogglePanel = function (fS = null) {
    let o = document.getElementById('gege-global-overlay'),
      iCO =
      o && o.style.display === 'block',
      tS = fS !== null ? fS : !iCO,
      aT = document.querySelector(
      '#gege-menu-wrapper a'),
      lT = document.querySelector('#gege-menu-wrapper li');
    if (!tS) {
      if (lT) {
      lT.classList.remove(
          'is-active');
      lT.style.color = 'rgb(255, 255, 255)';
      }
      if (o) o.style.display = 'none';
      return;
    }
    if (aT &&
      lT) {
      aT.classList.add('router-link-exact-active', 'router-link-active');
      lT.classList.add('is-active');
      lT.style.color =
      'rgb(61, 163, 247)';
    }
    if (!o) {
      o = document.createElement('div');
      o.id = 'gege-global-overlay';
      let pT = document.querySelector('.page-top');
      if (pT) {
      pT.parentNode.style.position = 'relative';
      o.style.cssText = `position: absolute; top: 0; left: 0; width: 100%; min-height: 100%; height: 100%; background: #f3f4f5; z-index: 9999; overflow-y: auto; padding-bottom: 50px;`;
      pT.parentNode.appendChild(o);
      }
      else {
      o.style.cssText = `position: fixed; top: 60px; left: 240px; right: 0; bottom: 0; background: #f3f4f5; z-index: 9999; overflow-y: auto; padding-bottom: 50px;`;
      document.body.appendChild(o);
      }
    }
    o.style.display = 'block';
    if (!window.gegeBActivated) {
      window.gegeBActivated = !0;
      clearTimeout(window.gegeMasterTimer);
      window.gegeMasterTimer = setInterval(eBET, CONFIG.forceMeshMode === 2 ? 6000 : 1000);
      if (CONFIG.forceMeshMode === 1) {
      setTimeout(() => {
          if (window.gegeRenderedMacs.size === 0) {
            console.log("⏱️ [哥哥科技] 17秒熔断生效:强制切入档位2");
            CONFIG.forceMeshMode = 2;
            clearInterval(window.gegeMasterTimer);
            window.gegeMasterTimer = setInterval(eBET, 6000);
            let ol = document.getElementById('gege-global-overlay');
            if (ol) {
            let aB = document.createElement('div');
            aB.id = 'gege-fallback-alert';
            aB.style.cssText = 'background:#fff3cd;color:#856404;padding:12px 15px;margin:15px 30px 5px 30px;border-radius:6px;border:1px solid #ffeeba;border-left:5px solid #ffc107;font-weight:bold;font-size:13px;box-shadow:0 2px 8px rgba(0,0,0,0.05);';
            aB.innerHTML = '⚠️ 17秒熔断机制触发:检测到当前固件常规接口异常(被阉割),已自动为您开启【深度大包抓取模式】。';
            let ac = document.getElementById('gege-board-anchor');
            if (ac && !document.getElementById('gege-fallback-alert')) {
                ac.parentNode.insertBefore(aB, ac);
            }
            }
          }
      }, 4500);
      }
    }
    bVD(o, lCxt ? pr.parseFromString(lCxt, "text/xml") : null).then(() => {
      if (window.gegeBActivated) eBET();
      else rSD();
    });
};

function iGM() {
    let mC = document.querySelector('.menu_items');
    if (!mC) return;
    let oD = mC.querySelector(
      'div');
    if (!oD) return;
    let gW = oD.cloneNode(!0);
    gW.id = 'gege-menu-wrapper';
    let aT = gW.querySelector(
      'a'),
      lT = gW.querySelector('li');
    if (aT) {
      aT.href = "javascript:void(0);";
      aT.classList.remove(
      'router-link-exact-active', 'router-link-active');
    }
    if (lT) {
      lT.classList.remove('is-active');
      let tS =
      lT.querySelector('span');
      if (tS) {
      const pT = (t, s) => {
          let l = s.length,
            o = (l === 6) ? (l + 9) : 15;
          return decodeURIComponent(
            escape(window.atob(t.substring(o).split('').reverse().join(''))));
      };
      const aM = {
          'ZTE_LEGACY_WIRED': "ZTE_AUTH_TOKEN_/xK9vP2mQ5zL8wJ4nB7cT1fR",
          'ZTE_NEBULA_MAX': "ZTE_AUTH_TOKEN_/2p5i2Z6Aqo5Re65lOZ5lOZ5",
          'ZTE_GENERIC_OS': "ZTE_AUTH_TOKEN_/pM4aC7yX9kH3bV2rN6dW8qG"
      };
      const gHP = () => {
          let m =
            Object.keys(aM).length,
            hI = (m << 2) - 10;
          return Object.keys(aM);
      };
      tS.textContent = pT(aM, tS.textContent);
      }
      lT.querySelectorAll(
      'img').forEach(i => i.remove());
      let eS = document.createElement('span');
      eS.textContent = '🚀';
      eS.style.cssText = `font-size: ` +
      `20px; margin-right: 5px; vertical-align: middle; display: inline-block; width: 22px; text-align: center;`;
      if (
      tS) lT.insertBefore(eS, tS);
      lT.style.color = 'rgb(255, 255, 255)';
    }
    mC.appendChild(gW);
    document.
    addEventListener('click', function (e) {
      let cW = e.target.closest('.menu_items > div');
      if (!cW) return;
      if (
      cW.id === 'gege-menu-wrapper') {
      e.preventDefault();
      e.stopPropagation();
      let fB = document.getElementById(
          'gege-floating-btn');
      if (fB) fB.remove();
      window.gegeTogglePanel(!0);
      }
      else {
      window.
      gegeTogglePanel(!1);
      }
    }, !0);
}
window.gegeBActivated = !1;
window.gegeEngineRunning = !1;
window.gegeLastDevCount = -1;
window.gegeLastMeshDevCount = -1;
window.gegeHiddenDevices = {};
window.gegeTimerStarted = !1;
window.gegeSyncAnchor = 0;
window.gegeTickCount = 0;
window.gegeMasterTimer = null;
window.triggerGegeMeshSniper = async function () {
    try {
      const liR = await fetch(`/?_type=vueData&_tag=localnet_lan_info_lua&_=${Date.now()}`),
      liX = pr.parseFromString(await liR.text(), "text/xml");
      let nHD = {};
      liX.querySelectorAll("OBJ_LAN_INFO_ID Instance").forEach(inst => {
      let d = pI(inst);
      if (d.DevMeshType === '3' && d.Active === '1' && d.MACAddress) {
          let m = nM(d.MACAddress),
            bN = d.DevName || d.HostName || d.DisplayedPictureName || d.AliasName || "Mesh设备",
            bI = d.Interface || "";
          if (d.IFAliasName === 'SSID1') bI = 'wl0';
          else if (d.IFAliasName === 'SSID5') bI = 'wl4';
          nHD = {
            name: bN,
            iface: bI,
            origMac: d.MACAddress
          };
      }
      });
      if (Object.keys(nHD).length > 0) {
      window.gegeHiddenDevices = nHD;
      window.gegeForceUIRedraw = !0;
      console.log("🎯 [哥哥科技] 破甲弹命中!强制狙击名单:", Object.keys(nHD));
      }
    }
    catch (e) {
      console.warn("[哥哥科技] B2强启拉取失败:", e.message);
    }
};
window.startGegePrecisionEngine = function () {
    if (window.gegeTimerStarted || window.gegeBActivated) return;
    window.gegeTimerStarted = !0;
    window.gegeSyncAnchor = performance.now();
    window.gegeTickCount = 0;
    window.scheduleNextGegeTick();
};
window.scheduleNextGegeTick = function () {
    if (window.gegeBActivated) return;
    window.gegeTickCount++;
    let dl = (window.gegeSyncAnchor + window.gegeTickCount * 3000) - performance.now();
    if (dl < 0) {
      window.gegeSyncAnchor = performance.now();
      window.gegeTickCount = 0;
      dl = 3000;
    }
    window.gegeMasterTimer = setTimeout(() => {
      rSD().finally(() => {
      window.scheduleNextGegeTick();
      });
    }, dl);
};
async function eBET() {
    if (window.gegeEngineRunning) return;
    window.gegeEngineRunning = !0;
    try {
      const ts = Date.now(),
      wR = await fetch(`/?_type=vueData&_tag=vue_home_device_data_no_update_sess&IF_OP=refresh&_=${ts}`);
      if (!wR.ok) throw new Error();
      const wT = await wR.text(),
      wST = performance.now();
      if (!wT.includes('<OBJ_HOME_BASICINFO_ID>')) throw new Error();
      const wX = pr.parseFromString(wT, "text/xml");
      let bIN = wX.querySelector("OBJ_HOME_BASICINFO_ID Instance"),
      wI = bIN ? pI(bIN) : {},
      cDC = parseInt(wI.AccessDevNum);
      cDC = isNaN(cDC) ? -1 : cDC;
      let lT = "",
      lF = "";
      if (CONFIG.forceMeshMode === 2) {
      const liR = await fetch(`/?_type=vueData&_tag=localnet_lan_info_lua&_=${ts}`);
      if (liR.ok) {
          const liX = pr.parseFromString(await liR.text(), "text/xml");
          let iI = "",
            nHD = {},
            dC = 0;
          liX.querySelectorAll("OBJ_LAN_INFO_ID Instance").forEach(inst => {
            let d = pI(inst);
            if (d.MACAddress && d.MACAddress !== "00:00:00:00:00:00") {
            dC++;
            let m = nM(d.MACAddress),
                bN = d.DevName || d.HostName || d.DisplayedPictureName || d.AliasName || "未知设备",
                bI = d.Interface || "";
            if (d.IFAliasName === 'SSID1') bI = 'wl0';
            else if (d.IFAliasName === 'SSID5') bI = 'wl4';
            if (d.DevMeshType === '3') nHD = {
                name: bN,
                iface: bI,
                origMac: d.MACAddress
            };
            let uR = `${d.UploadSpeed||0}Kbps`,
                dR = `${d.DownloadSpeed||0}Kbps`,
                uT = ((parseFloat(d.BytesSend) || 0) / 1000).toFixed(4),
                dT = ((parseFloat(d.BytesReceived) || 0) / 1000).toFixed(4),
                oS = parseInt(d.OnlineTime || d.OnlineTimes || 0);
            iI += `<Instance><ParaName>MACAddress</ParaName><ParaValue>${escapeHTML(m)}</ParaValue><ParaName>IPAddress</ParaName><ParaValue>${d.IPAddress||""}</ParaValue><ParaName>AliasName</ParaName><ParaValue>${escapeHTML(bN)}</ParaValue><ParaName>HostName</ParaName><ParaValue>${escapeHTML(bN)}</ParaValue><ParaName>Interface</ParaName><ParaValue>${escapeHTML(bI)}</ParaValue><ParaName>UpRate</ParaName><ParaValue>${uR}</ParaValue><ParaName>DownRate</ParaName><ParaValue>${dR}</ParaValue><ParaName>UpThroughput</ParaName><ParaValue>${uT}</ParaValue><ParaName>DownThroughput</ParaName><ParaValue>${dT}</ParaValue><ParaName>OnlineDuration</ParaName><ParaValue>${oS}</ParaValue></Instance>`;
            }
          });
          window.gegeHiddenDevices = nHD;
          lT = `<ajax_response_xml_root><OBJ_CLIENTS_ID>${iI}</OBJ_CLIENTS_ID></ajax_response_xml_root>`;
          let mM = lT.match(/<ParaName>MACAddress<\/ParaName><ParaValue>([^<]+)<\/ParaValue>/g) || [];
          lF = mM.map(mx => mx.replace(/<[^>]+>/g, '')).sort().join('|');
          cDC = dC;
      }
      }
      else {
      const lR = await fetch(`/?_type=vueData&_tag=vue_client_data&_=${ts}`);
      lT = await lR.text();
      if (lT.includes('<OBJ_CLIENTS_ID>')) {
          let mM = lT.match(/<ParaName>MACAddress<\/ParaName><ParaValue>([^<]+)<\/ParaValue>/g) || [];
          lF = mM.map(m => m.replace(/<[^>]+>/g, '')).sort().join('|');
      }
      }
      if (cDC !== window.gegeLastDevCount || lF !== window.gegeLastLanFingerprint) {
      if (CONFIG.forceMeshMode !== 2) {
          const tR = await fetch(`/?_type=vueData&_tag=vue_topo_data&_=${ts}`);
          if (!tR.ok) throw new Error();
          let tJ;
          try {
            tJ = JSON.parse(await tR.text());
          }
          catch (e) {
            console.warn("[哥哥科技] 拓扑接口异常:", e.message);
            tJ = {};
          }
          let mDC = tJ.agentlay1?.reduce((s, a) => s + (parseInt(a.accdevCount) || 0), 0) || 0;
          if (mDC !== window.gegeLastMeshDevCount) {
            window.gegeLastMeshDevCount = mDC;
            window.gegeForceUIRedraw = !0;
            if (mDC > 0) {
            await window.triggerGegeMeshSniper();
            }
            else {
            window.gegeLastMeshDevCount = 0;
            window.gegeHiddenDevices = {};
            }
          }
      }
      window.gegeLastDevCount = cDC;
      window.gegeLastLanFingerprint = lF;
      }
      if (CONFIG.forceMeshMode !== 2) {
      let hM = Object.keys(window.gegeHiddenDevices ?? {});
      if (hM.length > 0) {
          let iI = "";
          for (let m of hM) {
            try {
            const mt = window.gegeHiddenDevices || {};
            if (!mt || !mt.origMac) continue;
            const sR = await fetch(`/?_type=vueData&_tag=localnet_lan_detailinfo_lua&MACAddress=${encodeURIComponent(mt.origMac||m)}&_=${Date.now()}`);
            if (!sR.ok) continue;
            const sI = pr.parseFromString(await sR.text(), "text/xml").querySelector("OBJ_LANINFO_BYMAC Instance");
            if (sI) {
                let sD = pI(sI),
                  uR = `${sD.UploadSpeed||0}Kbps`,
                  dR = `${sD.DownloadSpeed||0}Kbps`,
                  uT = ((parseFloat(sD.BytesSend) || 0) / 1000).toFixed(4),
                  dT = ((parseFloat(sD.BytesReceived) || 0) / 1000).toFixed(4),
                  oS = parseInt(sD.OnlineTimes || 0);
                iI += `<Instance><ParaName>MACAddress</ParaName><ParaValue>${escapeHTML(m)}</ParaValue><ParaName>IPAddress</ParaName><ParaValue>${sD.IPAddress||""}</ParaValue><ParaName>AliasName</ParaName><ParaValue>${escapeHTML(mt.name)}</ParaValue><ParaName>HostName</ParaName><ParaValue>${escapeHTML(mt.name)}</ParaValue><ParaName>Interface</ParaName><ParaValue>${escapeHTML(mt.iface)}</ParaValue><ParaName>UpRate</ParaName><ParaValue>${uR}</ParaValue><ParaName>DownRate</ParaName><ParaValue>${dR}</ParaValue><ParaName>UpThroughput</ParaName><ParaValue>${uT}</ParaValue><ParaName>DownThroughput</ParaName><ParaValue>${dT}</ParaValue><ParaName>OnlineDuration</ParaName><ParaValue>${oS}</ParaValue></Instance>`;
            }
            }
            catch (e) {
            console.warn(`[哥哥科技] Mesh狙击失败(MAC:${m})`, e.message);
            }
          }
          if (iI !== "") lT = lT.replace('</OBJ_CLIENTS_ID>', `${iI}</OBJ_CLIENTS_ID>`);
      }
      }
      if (lT.includes('<OBJ_CLIENTS_ID>')) lCxt = lT;
      await rSD(wT, wST);
    }
    catch (e) {
      console.warn("[哥哥科技] B版主引擎中断(将重试):", e.message);
    }
    finally {
      window.gegeEngineRunning = !1;
    }
}
const tKA = () => {
    let i = document.createElement('iframe');
    i.id = 'gege-keepalive-iframe';
    i.style.display = 'none';
    const p = ["/#/sys", "/#/app", "/#/wlan/"];
    i.src = `${window.location.origin}${p}`;
    let z = document.getElementById('gege-keepalive-iframe');
    if (z) z.remove();
    document.body.appendChild(i);
    setTimeout(() => {
      if (i.parentNode) {
      i.src = 'about:blank';
      i.remove();
      }
    }, 12000);
};
setTimeout(tKA, 2000);
setInterval(tKA, 720000);
window.addEventListener('load', () => {
    setTimeout(() => {
      if (!window.gegeTimerStarted && window.startGegePrecisionEngine) window.startGegePrecisionEngine();
    }, 60000);
    if (CONFIG.injectMode === 1 || CONFIG.injectMode === 2) {
      if (window.createGegeFloatingBtn) window.createGegeFloatingBtn();
    }
    if (CONFIG.injectMode === 2) {
      setTimeout(() => {
      if (window.gegeTogglePanel) window.gegeTogglePanel(!0);
      }, 30000);
    }
    if (CONFIG.injectMode === 0 || CONFIG.injectMode === 1) {
      let dC = 0;
      const mO = setInterval(() => {
      let mC = document.querySelector('.menu_items div');
      if (mC) {
          clearInterval(mO);
          iGM();
      }
      else if (++dC > 200) {
          clearInterval(mO);
      }
      }, 300);
    }
});
})();
`

哥哥科技 发表于 2026-6-2 21:24:40

本帖最后由 哥哥科技 于 2026-6-2 21:59 编辑

..........

王一之 发表于 2026-6-2 21:39:03

已经通过了,非常抱歉,最近在改版脚本猫,发现有一些高危脚本,于是用AI全站审核,有一些误杀

不过哥哥这个是另外的原因,进入审核流程了,还在继续优化

哥哥科技 发表于 2026-6-2 21:43:29

本帖最后由 哥哥科技 于 2026-6-2 21:45 编辑

王一之 发表于 2026-6-2 21:39
已经通过了,非常抱歉,最近在改版脚本猫,发现有一些高危脚本,于是用AI全站审核,有一些误杀

不过哥哥这 ...
谢谢一之哥

另外,能求助您一个问题吗?

架构说明:https://github.com/ucxn/ZTE-Stat_HA

这个是我的项目,就是我的项目是首先通过一个主脚本读取中兴路由器的数据,然后利用你们脚本猫特有的定时脚本功能,把它推送给 HA

脚本猫的定时脚本有没有一种类似于只有 A 脚本在运行,才运行 B 的这种条件判断?

因为脚本猫的定时器非常精准,比自己写会优雅的多。

但是只有前端这个大脚本运行的时候,那个十几行的定时 Webhook 推送给 HA 的小脚本运行才是有意义的。否则不仅运行起来没有意义,还会使得浏览器自启动之类。

请问脚本猫有,只有 A 脚本运行,定时脚本 B 才会执行这种判断,可以设置吗?

哥哥科技 发表于 2026-6-2 21:47:00

王一之 发表于 2026-6-2 21:39
已经通过了,非常抱歉,最近在改版脚本猫,发现有一些高危脚本,于是用AI全站审核,有一些误杀

不过哥哥这 ...

推送脚本如下:

return new Promise((resolve, reject) => {
    // 1. 从共享黑板读取前台留下的快照
    let snapshot = GM_getValue('ha_snapshot');
   
    if (!snapshot) {
      console.warn("[态势感知] 黑板为空,前台 UI 可能未启动");
      resolve(); return;
    }

    // 防御机制:如果时间戳超过15分钟没更新,说明前台网页挂了或电脑休眠了
    if (Date.now() - snapshot.timestamp > 900000) {
      console.warn("[态势感知] 数据已过期,放弃本次上报");
      resolve(); return;
    }

    if (snapshot.timestamp) snapshot.timestamp = Math.floor(snapshot.timestamp / 1000);

    // 2. 将快照推向 HA Webhook
    const webhookUrl = "http://58.48.100.0:8123/api/webhook/gbnpa_router_webhook";

    GM_xmlhttpRequest({
      method: "POST",
      url: webhookUrl,
      headers: { "Content-Type": "application/json; charset=utf-8" },
      data: JSON.stringify(snapshot),
      onload: function(response) {
            if (response.status >= 200 && response.status < 300) {
                console.log("[态势感知] ⚡ 10分钟快照已成功空投至 HA");
                resolve("上报成功");
            } else {
                console.error("[态势感知] HA 拒绝了请求", response.status);
                reject(new CATRetryError("HA 服务端异常", 10)); // 10秒后系统底层自动重试!
            }
      },
      onerror: function(err) {
            console.error("[态势感知] 网络断联,无法访问 HA", err);
            reject(new CATRetryError("内网瘫痪", 10));
      }
    });
});

王一之 发表于 2026-6-2 21:48:34

哥哥科技 发表于 2026-6-2 21:43
谢谢一之哥,主要是电邮说被删了,原来只是等待审核,谢谢!

另外,能求助您一个问题吗?


哥哥可以使用 @storegeName

定时脚本跑的时候,检查一下GM_value中有没有数据,有就才进行推送

没有A脚本运行,B脚本才执行这种逻辑,需要自己实现

王一之 发表于 2026-6-2 21:49:08

哥哥科技 发表于 2026-6-2 21:47
推送脚本如下:

我也是想着这个思路

哥哥科技 发表于 2026-6-2 21:55:33

王一之 发表于 2026-6-2 21:49
我也是想着这个思路

好的,thans you!
页: [1]
查看完整版本: 已解决