// ==UserScript==
// @name [开发用] 特权环境完整诊断脚本
// @namespace cyc-diagnostic
// @version 4.0.0
// @author Cat Browser Dev
// @description 全面检测 cyc_privileges / cyc_http / cyc_monitor 及 GM API、Aria2
// @match :///*
// @grant none
// ==/UserScript==
(function() {
'use strict';const TEST_URL = 'https://jsonplaceholder.typicode.com/posts/1'; const MONITOR_PATTERN = 'jsonplaceholder.typicode.com'; let passed = 0; let failed = 0; // ── 页面显示面板 ── function createPanel() { const panel = document.createElement('div'); panel.id = 'cyc-diagnostic-panel'; panel.style.cssText = ` position: fixed; top: 10px; right: 10px; z-index: 2147483647; background: rgba(0,0,0,0.9); color: #eee; font-size: 12px; font-family: monospace; padding: 12px; border-radius: 8px; max-width: 440px; max-height: 85vh; overflow-y: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.6); line-height: 1.5; `; panel.innerHTML = '<div style="font-weight:bold;margin-bottom:8px;font-size:14px;">🔍 特权环境完整诊断 v4.0</div><div id="diag-results"></div><div id="diag-summary" style="margin-top:8px;font-weight:bold;font-size:14px;"></div>'; document.body.appendChild(panel); } function addLine(name, ok, detail) { const div = document.getElementById('diag-results'); if (!div) return; const line = document.createElement('div'); line.style.marginLeft = '4px'; line.innerHTML = (ok ? '✅' : '❌') + ' ' + name + (detail ? ' <span style="color:#aaa;font-size:11px;">' + detail + '</span>' : ''); div.appendChild(line); } function updateSummary() { const div = document.getElementById('diag-summary'); if (!div) return; const total = passed + failed; div.style.color = failed === 0 ? '#4caf50' : '#f44336'; div.textContent = '通过 ' + passed + ' / ' + total + (failed > 0 ? ' 失败 ' + failed : ' 全部通过 🎉'); } function log(name, ok, detail) { if (ok) passed++; else failed++; addLine(name, ok, detail); updateSummary(); } function wait(ms) { return new Promise(r => setTimeout(r, ms)); } // ── 环境诊断 ── function testEnvironment() { addLine('━━━ 环境诊断 ━━━', true, ''); const url = window.location.href; const isHttp = url.startsWith('http://') || url.startsWith('https://'); log('当前页面为 HTTP/HTTPS', isHttp, url.substring(0, 50)); log('运行在 Android WebView', navigator.userAgent.indexOf('Android') > -1, navigator.userAgent.substring(0, 40)); log('document.readyState', document.readyState === 'complete' || document.readyState === 'interactive', document.readyState); } // ── GM API 兼容性 ── function testGMApi() { addLine('━━━ GM API 兼容性 ━━━', true, ''); const gmMethods = [ 'GM_setValue', 'GM_getValue', 'GM_deleteValue', 'GM_listValues', 'GM_addStyle', 'GM_getResourceText', 'GM_getResourceURL', 'GM_xmlhttpRequest', 'GM_openInTab', 'GM_notification', 'GM_log', 'GM_info', 'GM_setClipboard', 'GM_registerMenuCommand' ]; let gmAvailable = 0; gmMethods.forEach(function(m) { const ok = typeof window[m] === 'function' || (m === 'GM_info' && typeof window[m] === 'object'); if (ok) gmAvailable++; log(m, ok, ok ? '' : '未定义'); }); log('GM API 可用数量', gmAvailable > 0, gmAvailable + '/' + gmMethods.length); if (typeof window.GM_setValue === 'function') { try { window.GM_setValue('__diag_test__', 'hello'); const val = window.GM_getValue('__diag_test__', ''); log('GM_setValue/getValue 读写', val === 'hello', '值: ' + val); window.GM_deleteValue('__diag_test__'); log('GM_deleteValue 删除', window.GM_getValue('__diag_test__', '') === '', ''); } catch(e) { log('GM 存储操作', false, e.message); } } if (typeof window.GM_addStyle === 'function') { try { window.GM_addStyle('.__diag_test_style__{display:none;}'); log('GM_addStyle 调用', true, ''); } catch(e) { log('GM_addStyle 调用', false, e.message); } } if (typeof window.GM_info === 'object') { log('GM_info.scriptHandler', window.GM_info.scriptHandler === 'Cat Browser', window.GM_info.scriptHandler || '空'); } } // ── 基础特权对象 ── function testBasicPrivileges() { addLine('━━━ 基础特权对象 ━━━', true, ''); const isHttp = window.location.href.startsWith('http'); const expected = isHttp; const privExists = typeof __cyc_privileges__ !== 'undefined'; log('__cyc_privileges__ 存在', privExists === expected, privExists ? '已注入' : '未注入(非HTTP页面正常)'); const httpExists = typeof __cyc_http__ !== 'undefined'; log('__cyc_http__ 存在', httpExists === expected, httpExists ? '已注入' : '未注入(非HTTP页面正常)'); const monitorExists = typeof __cyc_monitor__ !== 'undefined'; log('__cyc_monitor__ 存在', monitorExists === expected, monitorExists ? '已注入' : '未注入(非HTTP页面正常)'); if (privExists) { log('toast() 方法', typeof __cyc_privileges__.toast === 'function'); log('toastLong() 方法', typeof __cyc_privileges__.toastLong === 'function'); if (typeof __cyc_privileges__.toast === 'function') { __cyc_privileges__.toast('🔔 诊断脚本已启动'); } } if (httpExists) { log('__cyc_http__.request() 方法', typeof __cyc_http__.request === 'function'); } if (monitorExists) { ['subscribe', 'unsubscribe', 'unsubscribeAll'].forEach(function(m) { log('__cyc_monitor__.' + m + '() 方法', typeof __cyc_monitor__[m] === 'function'); }); } } // ── 跨域请求验证 ── function testHttpRequest() { addLine('━━━ 跨域请求验证 ━━━', true, ''); if (typeof __cyc_http__ === 'undefined') { log('跳过(__cyc_http__ 不可用)', true, '非HTTP页面'); return; } let done = false; window.__cyc_http_callback = function(id, success, resultJson) { if (id === 777 && !done) { done = true; try { const r = JSON.parse(resultJson); if (success && r.status === 200) { const data = JSON.parse(r.responseText); log('GET 请求成功', data && data.id === 1, 'id=' + (data ? data.id : '?') + ' status=' + r.status); } else { log('GET 请求成功', false, 'status=' + r.status + ' ' + r.statusText); } } catch(e) { log('响应处理异常', false, e.message); } } }; __cyc_http__.request(777, JSON.stringify({ url: TEST_URL, method: 'GET', timeout: 10000 })); log('GET 请求已发送', true, TEST_URL); } // ── 请求监控验证 ── function testMonitor() { addLine('━━━ 请求监控验证 ━━━', true, ''); if (typeof __cyc_monitor__ === 'undefined') { log('跳过(__cyc_monitor__ 不可用)', true, '非HTTP页面'); return; } let fired = false; window.__cyc_on_request = function(info) { if (!fired && info.url.indexOf(MONITOR_PATTERN) !== -1) { fired = true; log('监控回调触发', true, info.method + ' ' + info.url.substring(0, 40)); log('包含 requestHeaders', typeof info.requestHeaders === 'object', info.requestHeaders ? '是' : '否'); log('包含 responseHeaders', typeof info.responseHeaders === 'object', info.responseHeaders ? '是' : '否'); log('包含 duration', typeof info.duration === 'number', info.duration + 'ms'); log('包含 responseBody', typeof info.responseBody === 'string', '是'); __cyc_monitor__.unsubscribe(999, '__diag_monitor__'); log('取消订阅', true, '__diag_monitor__'); } }; __cyc_monitor__.subscribe(999, '__diag_monitor__', MONITOR_PATTERN); log('订阅 URL 模式', true, MONITOR_PATTERN); fetch(TEST_URL + '?t=' + Date.now()) .then(r => r.json()) .then(function() { setTimeout(function() { if (!fired) { log('监控回调触发', false, '超时未收到回调'); __cyc_monitor__.unsubscribe(999, '__diag_monitor__'); } }, 4000); }) .catch(function() { log('触发请求', false, 'fetch 失败'); }); } // ── 阶段A:网络调试 ── function testPhaseA() { addLine('━━━ 阶段A:网络调试 ━━━', true, ''); if (typeof __cyc_privileges__ === 'undefined') { log('跳过', true, '__cyc_privileges__ 不可用'); return; } log('setRecordBody() 方法', typeof __cyc_privileges__.setRecordBody === 'function'); } // ── 阶段B:资源嗅探 ── function testPhaseB() { addLine('━━━ 阶段B:资源嗅探 ━━━', true, ''); if (typeof __cyc_privileges__ === 'undefined') { log('跳过', true, '__cyc_privileges__ 不可用'); return; } ['getSniffedVideos', 'getSniffedAudios', 'getSniffedImages'].forEach(function(m) { log(m + '() 方法', typeof __cyc_privileges__[m] === 'function'); if (typeof __cyc_privileges__[m] === 'function') { try { const r = JSON.parse(__cyc_privileges__[m]()); log(m + '() 返回值', Array.isArray(r), '长度: ' + r.length); } catch(e) { log(m + '() 返回值', false, e.message); } } }); window.__cyc_on_resource_update = function(type, urls) { log('资源更新事件', true, type + ': ' + urls.length + ' 个'); }; log('__cyc_on_resource_update 回调', true, '已注册'); } // ── 阶段C:视频悬浮窗 ── function testPhaseC() { addLine('━━━ 阶段C:视频悬浮窗 ━━━', true, ''); if (typeof __cyc_privileges__ === 'undefined') { log('跳过', true, '__cyc_privileges__ 不可用'); return; } log('getCurrentVideo() 方法', typeof __cyc_privileges__.getCurrentVideo === 'function'); if (typeof __cyc_privileges__.getCurrentVideo === 'function') { const v = __cyc_privileges__.getCurrentVideo(); log('getCurrentVideo() 调用', true, v ? '有视频' : '无视频'); } log('playInFloatWindow() 方法', typeof __cyc_privileges__.playInFloatWindow === 'function'); } // ── 阶段D:下载能力 ── function testPhaseD() { addLine('━━━ 阶段D:下载能力 ━━━', true, ''); if (typeof __cyc_privileges__ === 'undefined') { log('跳过', true, '__cyc_privileges__ 不可用'); return; } log('download() 方法', typeof __cyc_privileges__.download === 'function'); log('batchDownload() 方法', typeof __cyc_privileges__.batchDownload === 'function'); } // ── 阶段E:Aria2 集成 ── function testPhaseE() { addLine('━━━ 阶段E:Aria2 集成 ━━━', true, ''); if (typeof __cyc_privileges__ === 'undefined') { log('跳过', true, '__cyc_privileges__ 不可用'); return; } const ariaMethods = [ 'aria2AddUri', 'aria2AddTorrent', 'aria2TellStatus', 'aria2Pause', 'aria2Unpause', 'aria2Remove' ]; let ariaAvailable = 0; ariaMethods.forEach(function(m) { const ok = typeof __cyc_privileges__[m] === 'function'; if (ok) ariaAvailable++; log(m + '() 方法', ok); }); log('Aria2 方法可用数量', ariaAvailable > 0, ariaAvailable + '/' + ariaMethods.length); // 功能验证(添加一个测试下载) if (typeof __cyc_privileges__.aria2AddUri === 'function') { try { const gid = __cyc_privileges__.aria2AddUri( 'https://httpbin.org/image/jpeg', '/storage/emulated/0/Download/aria2', 'test_diag_image.jpg' ); log('aria2AddUri() 调用', gid && gid.length > 0, 'GID: ' + (gid || '空')); if (gid) { setTimeout(function() { try { const statusStr = __cyc_privileges__.aria2TellStatus(gid); const status = JSON.parse(statusStr); log('aria2TellStatus() 调用', status && typeof status.status === 'string', '状态: ' + (status ? status.status : '?')); } catch(e) { log('aria2TellStatus() 调用', false, e.message); } }, 3000); } } catch(e) { log('aria2AddUri() 调用', false, e.message); } } } // ── 降级兼容测试 ── function testFallback() { addLine('━━━ 降级兼容测试 ━━━', true, ''); const privExists = typeof __cyc_privileges__ !== 'undefined'; const testCode = (function() { return true; })(); log('脚本基本语法正常', testCode, ''); if (!privExists) { log('特权对象不存在时脚本未崩溃', true, '降级兼容正常'); } else { log('特权对象可用(无需降级)', true, '正常'); } } // ── 主入口 ── async function runAll() { createPanel(); testEnvironment(); await wait(100); testGMApi(); await wait(100); testBasicPrivileges(); await wait(100); testHttpRequest(); testMonitor(); testPhaseA(); testPhaseB(); testPhaseC(); testPhaseD(); testPhaseE(); testFallback(); await wait(10000); if (typeof __cyc_privileges__ !== 'undefined') { __cyc_privileges__.toast('诊断完成: ' + passed + ' 通过 / ' + failed + ' 失败'); } } setTimeout(runAll, 1500);
})();



Comments NOTHING