/* ============================================================================ * 自动抓包系统 v4.0 - Cocos Creator 2.x * 特性:定时扫描 WS / 多种 CMD 字段 / DOM 反馈 / 手动复制浮层 * ============================================================================ */ ;(function () { 'use strict'; // ==================== 基础工具 ==================== var BALL_R = 34; var ball = null; var mainPanel = null; var startToast = null; function getVS() { var w = 720, h = 1280; try { var vs = cc.view.getVisibleSize(); if (vs && vs.width) { w = vs.width; h = vs.height; } } catch (e) {} return { width: w, height: h }; } function currentScene() { try { if (cc.director.getScene) return cc.director.getScene(); } catch (e) {} try { return cc.director.getRunningScene(); } catch (e2) {} return null; } function ev(base, dft) { try { var t = cc.Node.EventType; if (t && t[base]) return t[base]; } catch (e) {} return dft; } function mkLabel(parent, text, size, rgba, x, y, w, align) { var n = new cc.Node('Lbl'); n.parent = parent; n.setContentSize(Math.max(10, w), size + 12); try { n.anchorX = (align === 'left' ? 0 : 0.5); n.anchorY = 0.5; } catch (e0) {} n.setPosition(x, y); var l = n.addComponent(cc.Label); l.string = text || ''; l.fontSize = size; l.lineHeight = Math.round(size * 1.4); try { l.horizontalAlign = align === 'left' ? cc.Label.HorizontalAlign.LEFT : cc.Label.HorizontalAlign.CENTER; } catch (e1) {} try { l.verticalAlign = cc.Label.VerticalAlign.CENTER; } catch (e2) {} try { n.color = new cc.Color(rgba[0], rgba[1], rgba[2], rgba[3]); } catch (e3) {} return l; } function mkButton(parent, text, x, y, w, h, fill, stroke, onTap, textColor) { var n = new cc.Node('Btn'); n.parent = parent; n.setContentSize(w, h); n.setPosition(x, y); var g = n.addComponent(cc.Graphics); g.fillColor = new cc.Color(fill[0], fill[1], fill[2], fill[3]); g.strokeColor = new cc.Color(stroke[0], stroke[1], stroke[2], stroke[3]); try { g.lineWidth = 2; } catch (e0) {} g.roundRect(-w / 2, -h / 2, w, h, 8); g.fill(); g.stroke(); mkLabel(n, text, 20, textColor || [0, 0, 0, 255], 0, 0, w - 8, 'center'); n.on(ev('TOUCH_END', 'touch-end'), function (e) { try { if (e && e.stopPropagation) e.stopPropagation(); } catch (e1) {} try { onTap(); } catch (e2) {} }, n); return n; } // ==================== DOM 提示条(100% 可见)==================== function showDomToast(msg, isOk) { try { if (typeof document === 'undefined' || !document.body) return; var old = document.getElementById('__capture_dom_toast__'); if (old && old.parentNode) old.parentNode.removeChild(old); var t = document.createElement('div'); t.id = '__capture_dom_toast__'; t.textContent = msg; t.style.cssText = 'position:fixed;left:50%;top:18%;transform:translateX(-50%);' + 'z-index:2147483647;padding:14px 22px;border-radius:10px;' + 'font-size:16px;font-family:sans-serif;font-weight:bold;color:#fff;' + 'max-width:80vw;word-break:break-all;text-align:center;line-height:1.5;' + 'box-shadow:0 6px 24px rgba(0,0,0,0.35);white-space:pre-wrap;' + 'background:' + (isOk ? 'rgba(46,170,90,0.95)' : 'rgba(220,60,60,0.95)') + ';'; document.body.appendChild(t); setTimeout(function () { try { t.style.transition = 'opacity 0.35s'; t.style.opacity = '0'; setTimeout(function () { try { if (t.parentNode) t.parentNode.removeChild(t); } catch (e) {} }, 400); } catch (e) {} }, 2600); } catch (e) {} } // ==================== DOM 手动复制浮层 ==================== function showManualCopyOverlay(text) { try { if (typeof document === 'undefined' || !document.body) { alert('内容已复制到剪贴板,如未生效请手动复制。'); return; } var old = document.getElementById('__capture_manual_overlay__'); if (old && old.parentNode) old.parentNode.removeChild(old); var overlay = document.createElement('div'); overlay.id = '__capture_manual_overlay__'; overlay.style.cssText = 'position:fixed;left:0;top:0;right:0;bottom:0;background:rgba(0,0,0,0.88);' + 'z-index:2147483647;display:flex;flex-direction:column;' + 'padding:14px;box-sizing:border-box;' + '-webkit-user-select:text;user-select:text;'; var header = document.createElement('div'); header.style.cssText = 'color:#fff;font-size:16px;text-align:center;margin-bottom:10px;line-height:1.5;flex-shrink:0;'; header.innerHTML = '
📋 复制抓包内容
' + '
长按下方文本框 → 全选 → 复制
' + '
共 ' + text.length.toLocaleString() + ' 字符 · ' + text.split('\n').length + ' 行
'; var ta = document.createElement('textarea'); ta.value = text; ta.style.cssText = 'flex:1;width:100%;box-sizing:border-box;padding:12px;font-size:13px;' + 'font-family:monospace;line-height:1.5;border:none;border-radius:8px;' + 'resize:none;background:#fff;color:#000;' + 'white-space:pre;overflow:auto;' + '-webkit-user-select:text;user-select:text;-webkit-touch-callout:default;'; ta.addEventListener('click', function () { try { ta.focus(); ta.setSelectionRange(0, ta.value.length); } catch (e) {} }); ta.addEventListener('touchstart', function () { try { ta.focus(); } catch (e) {} }); var btnRow = document.createElement('div'); btnRow.style.cssText = 'display:flex;gap:8px;margin-top:12px;flex-shrink:0;'; var baseCss = 'flex:1;padding:14px 8px;font-size:15px;color:#fff;border:none;' + 'border-radius:8px;font-weight:bold;cursor:pointer;-webkit-appearance:none;'; var selectBtn = document.createElement('button'); selectBtn.textContent = '全选'; selectBtn.style.cssText = baseCss + 'background:#4CAF50;'; selectBtn.onclick = function () { try { ta.focus(); ta.select(); ta.setSelectionRange(0, ta.value.length); showDomToast('已全选,请长按文本框选「复制」', true); } catch (e) {} }; var copyBtn = document.createElement('button'); copyBtn.textContent = '复制'; copyBtn.style.cssText = baseCss + 'background:#2196F3;'; copyBtn.onclick = function () { var ok = false; try { ta.focus(); ta.select(); ta.setSelectionRange(0, ta.value.length); ok = document.execCommand('copy'); } catch (e) {} if (ok) { copyBtn.textContent = '✓ 已复制'; copyBtn.style.background = '#1B5E20'; showDomToast('已复制到剪贴板', true); return; } // 尝试异步 API if (typeof navigator !== 'undefined' && navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(function () { copyBtn.textContent = '✓ 已复制'; copyBtn.style.background = '#1B5E20'; showDomToast('已复制到剪贴板', true); }).catch(function () { showDomToast('自动复制失败,请长按文本框手动复制', false); }); return; } showDomToast('请长按文本框手动复制', false); }; var closeBtn = document.createElement('button'); closeBtn.textContent = '关闭'; closeBtn.style.cssText = baseCss + 'background:#666;'; closeBtn.onclick = function () { try { if (overlay.parentNode) overlay.parentNode.removeChild(overlay); } catch (e) {} }; btnRow.appendChild(selectBtn); btnRow.appendChild(copyBtn); btnRow.appendChild(closeBtn); overlay.appendChild(header); overlay.appendChild(ta); overlay.appendChild(btnRow); document.body.appendChild(overlay); // 防止浮层里滚动穿透 overlay.addEventListener('touchmove', function (e) { try { e.stopPropagation(); } catch (er) {} }, { passive: false }); // 自动尝试一次复制 try { ta.focus(); ta.select(); ta.setSelectionRange(0, ta.value.length); if (document.execCommand('copy')) { copyBtn.textContent = '✓ 已复制'; copyBtn.style.background = '#1B5E20'; showDomToast('已复制到剪贴板', true); } } catch (e) {} } catch (e) { showDomToast('打开复制浮层失败: ' + (e && e.message || e), false); } } // ==================== 抓包核心 ==================== var _captureEnabled = true; var _logs = []; var MAX_LOG = 99999; var _scanTimer = null; function getConn() { var cands = [ window.ws, window.h5websocket && window.h5websocket.ws, window.h5websocket, window.gameWs, window.WebSocketClient, window._ws, window.gameSocket, ]; for (var i = 0; i < cands.length; i++) { var c = cands[i]; if (c && (c.sendAsync || c.send)) { if (c.readyState !== undefined && c.readyState !== 1) continue; return c; } } return null; } function nowStr() { var d = new Date(); function p(n) { return n < 10 ? '0' + n : '' + n; } function p3(n) { return n < 10 ? '00' + n : (n < 100 ? '0' + n : '' + n); } return d.getFullYear() + '-' + p(d.getMonth() + 1) + '-' + p(d.getDate()) + ' ' + p(d.getHours()) + ':' + p(d.getMinutes()) + ':' + p(d.getSeconds()) + '.' + p3(d.getMilliseconds()); } function normalizeMsg(msg) { if (msg === undefined || msg === null) return null; if (typeof msg === 'string') { try { return JSON.parse(msg); } catch (e) { return { _rawString: msg }; } } return msg; } // 多种字段名兜底提取 CMD function extractCmd(obj) { try { if (!obj) return 'unknown'; if (typeof obj !== 'object') return 'raw:' + String(obj).slice(0, 30); if (obj.cmd !== undefined && obj.cmd !== null) return String(obj.cmd); if (obj.command !== undefined && obj.command !== null) return String(obj.command); if (obj._cmd !== undefined && obj._cmd !== null) return String(obj._cmd); if (obj.name !== undefined && typeof obj.name === 'string') return obj.name; if (obj.body && typeof obj.body === 'object') { if (obj.body.cmd !== undefined && obj.body.cmd !== null) return String(obj.body.cmd); if (obj.body.command !== undefined) return String(obj.body.command); if (obj.body._cmd !== undefined) return String(obj.body._cmd); } if (obj.params && typeof obj.params === 'object') { if (obj.params.cmd !== undefined) return String(obj.params.cmd); if (obj.params._cmd !== undefined) return String(obj.params._cmd); } if (obj.data && typeof obj.data === 'object') { if (obj.data.cmd !== undefined) return String(obj.data.cmd); } if (obj.payload && typeof obj.payload === 'object') { if (obj.payload.cmd !== undefined) return String(obj.payload.cmd); } // 协议号型(type) if (obj.type !== undefined && typeof obj.type !== 'object') { return 'type:' + String(obj.type); } if (obj._rawString) { return 'raw:' + String(obj._rawString).slice(0, 30); } } catch (e) {} return 'unknown'; } function extractParams(obj) { try { if (!obj || typeof obj !== 'object') return ''; if (obj.params !== undefined) return obj.params; if (obj.data !== undefined) return obj.data; if (obj.body !== undefined) return obj.body; if (obj.payload !== undefined) return obj.payload; if (obj.extra !== undefined) return obj.extra; } catch (e) {} return ''; } function safeStr(v, max) { try { if (v === undefined || v === null) return ''; if (typeof v === 'string') return v.length > max ? v.slice(0, max) + '...' : v; var s = JSON.stringify(v); return s && s.length > max ? s.slice(0, max) + '...' : s; } catch (e) { return String(v); } } function pushLog(entry) { if (!entry) return; _logs.push(entry); if (_logs.length > MAX_LOG) _logs.shift(); try { updatePanelStats(); } catch (e) {} } function hookInstance(conn) { if (!conn || conn._autoCaptureHooked) return true; try { if (typeof conn.sendAsync === 'function' && !conn._autoCaptureHookedAsync) { var origAsync = conn.sendAsync; conn._autoCaptureHookedAsync = true; conn.sendAsync = function (msg) { try { if (_captureEnabled) { var obj = normalizeMsg(msg); var cmd = extractCmd(obj); var params = safeStr(extractParams(obj), 2000); pushLog({ time: nowStr(), cmd: cmd, params: params }); } } catch (e) {} return origAsync.apply(this, arguments); }; } if (typeof conn.send === 'function' && !conn._autoCaptureHookedSend) { var origSend = conn.send; conn._autoCaptureHookedSend = true; conn.send = function (msg) { try { if (_captureEnabled) { var obj = normalizeMsg(msg); var cmd = extractCmd(obj); var params = safeStr(extractParams(obj), 2000); pushLog({ time: nowStr(), cmd: cmd, params: params }); } } catch (e) {} return origSend.apply(this, arguments); }; } conn._autoCaptureHooked = true; try { updatePanelStatus('已连接协议,抓包中'); } catch (e) {} return true; } catch (e) { return false; } } // 定时扫描:每 1 秒检查一次,覆盖游戏重新 new ws 的情况 function tickScan() { try { var conn = getConn(); if (conn && !conn._autoCaptureHooked) { hookInstance(conn); } } catch (e) {} _scanTimer = setTimeout(tickScan, 1000); } // ==================== 内容生成 ==================== function buildFullText() { var lines = []; lines.push('==================== 自动抓包日志 ===================='); lines.push('导出时间: ' + nowStr()); lines.push('记录总数: ' + _logs.length); lines.push('==================== 开始 ===================='); lines.push(''); for (var i = 0; i < _logs.length; i++) { var e = _logs[i]; if (!e) continue; lines.push('---------------- 记录 #' + (i + 1) + ' ----------------'); lines.push('时间: ' + (e.time || '')); lines.push('CMD命令: ' + (e.cmd || '')); if (e.params && e.params !== '{}' && e.params !== '""') { lines.push('请求参数: ' + e.params); } lines.push(''); } lines.push('==================== 结束 ===================='); return lines.join('\n'); } function buildPreviewText() { if (!_logs.length) return '(暂无抓包记录)'; var lines = []; var start = Math.max(0, _logs.length - 8); for (var i = start; i < _logs.length; i++) { var e = _logs[i]; if (!e) continue; var t = (e.time || '').slice(11, 19); lines.push('[' + t + '] ' + (e.cmd || 'unknown')); if (e.params && e.params !== '{}' && e.params !== '""') { var p = e.params; if (p.length > 90) p = p.slice(0, 90) + '...'; lines.push(' ' + p); } } return lines.join('\n'); } // ==================== 剪贴板尝试(不依赖,只是额外)==================== function tryAutoCopy(text) { // 原生桥接 try { var bridge = window.AndroidBridge || window.Android || window.jsBridge || window.nativeBridge; if (bridge) { var names = ['copyText', 'setClipboard', 'setClipboardText', 'copy', 'copyToClipboard']; for (var bi = 0; bi < names.length; bi++) { if (typeof bridge[names[bi]] === 'function') { try { bridge[names[bi]](text); return 'bridge'; } catch (e) {} } } } } catch (e) {} // Cocos try { if (typeof cc !== 'undefined' && cc.sys && cc.sys.clipboard) { if (typeof cc.sys.clipboard.writeText === 'function') { try { cc.sys.clipboard.writeText(text); return 'cc.clipboard'; } catch (e) {} } } } catch (e) {} // execCommand try { if (typeof document !== 'undefined' && document.body) { var ta = document.createElement('textarea'); ta.value = text; ta.style.cssText = 'position:fixed;top:0;left:0;width:2px;height:2px;opacity:0;border:0;padding:0;'; document.body.appendChild(ta); ta.focus(); ta.select(); ta.setSelectionRange(0, ta.value.length); var ok = false; try { ok = document.execCommand('copy'); } catch (e) {} try { document.body.removeChild(ta); } catch (e) {} if (ok) return 'execCommand'; } } catch (e) {} return null; } // ==================== UI 面板 ==================== var _panelRefs = { statsLabel: null, statusLabel: null, listLabel: null }; function updatePanelStats() { try { if (_panelRefs.statsLabel && cc.isValid(_panelRefs.statsLabel)) { _panelRefs.statsLabel.string = '已抓记录: ' + _logs.length + ' 条'; } if (_panelRefs.listLabel && cc.isValid(_panelRefs.listLabel)) { _panelRefs.listLabel.string = buildPreviewText(); } } catch (e) {} } function updatePanelStatus(txt) { try { if (_panelRefs.statusLabel && cc.isValid(_panelRefs.statusLabel)) { _panelRefs.statusLabel.string = '状态: ' + txt; } } catch (e) {} } // ====== "正在开始抓包"弹窗 ====== function showStartupToast() { var scene = currentScene(); if (!cc.isValid(scene)) return; if (startToast && cc.isValid(startToast)) { try { startToast.destroy(); } catch (e) {} } var vs = getVS(); var W = Math.min(500, Math.floor(vs.width * 0.85)); var H = 200; startToast = new cc.Node('CaptureStartToast'); startToast.parent = scene; startToast.setContentSize(W, H); startToast.setAnchorPoint(0.5, 0.5); startToast.setPosition(vs.width / 2, vs.height / 2); startToast.zIndex = 2147483600; var bg = startToast.addComponent(cc.Graphics); bg.fillColor = new cc.Color(255, 255, 255, 255); bg.strokeColor = new cc.Color(255, 105, 180, 255); bg.lineWidth = 4; bg.roundRect(-W / 2, -H / 2, W, H, 20); bg.fill(); bg.stroke(); mkLabel(startToast, '📡 正在开始抓包', 26, [0, 0, 0, 255], 0, H / 2 - 42, W - 80, 'center'); mkLabel(startToast, '已自动连接协议,持续抓包中...', 17, [80, 80, 80, 255], 0, H / 2 - 80, W - 60, 'center'); mkLabel(startToast, '点击右上角 📡 悬浮球查看/复制内容', 15, [130, 130, 130, 255], 0, H / 2 - 110, W - 60, 'center'); mkButton(startToast, '×', W / 2 - 28, H / 2 - 28, 44, 44, [220, 60, 60, 255], [255, 120, 120, 255], function () { if (startToast && cc.isValid(startToast)) { try { startToast.destroy(); } catch (e) {} startToast = null; } }, [255, 255, 255, 255]); startToast.on(ev('TOUCH_START', 'touch-start'), function (e) { try { e.stopPropagation(); } catch (er) {} }, startToast); startToast.on(ev('TOUCH_MOVE', 'touch-move'), function (e) { try { e.stopPropagation(); } catch (er) {} }, startToast); startToast.on(ev('TOUCH_END', 'touch-end'), function (e) { try { e.stopPropagation(); } catch (er) {} }, startToast); setTimeout(function () { if (startToast && cc.isValid(startToast)) { try { startToast.destroy(); } catch (e) {} startToast = null; } }, 3500); } // ====== 主面板 ====== function buildCapturePanel() { if (mainPanel && cc.isValid(mainPanel)) return mainPanel; var scene = currentScene(); if (!cc.isValid(scene)) return null; var vs = getVS(); var W = Math.min(640, Math.floor(vs.width * 0.92)); var H = Math.min(800, Math.floor(vs.height * 0.9)); mainPanel = new cc.Node('CapturePanel'); mainPanel.parent = scene; mainPanel.setContentSize(W, H); mainPanel.setAnchorPoint(0.5, 0.5); mainPanel.setPosition(vs.width / 2, vs.height / 2); mainPanel.active = false; mainPanel.zIndex = 100000; mainPanel.on(ev('TOUCH_START', 'touch-start'), function (e) { try { e.stopPropagation(); } catch (er) {} }, mainPanel); mainPanel.on(ev('TOUCH_MOVE', 'touch-move'), function (e) { try { e.stopPropagation(); } catch (er) {} }, mainPanel); mainPanel.on(ev('TOUCH_END', 'touch-end'), function (e) { try { e.stopPropagation(); } catch (er) {} }, mainPanel); var bg = mainPanel.addComponent(cc.Graphics); bg.fillColor = new cc.Color(255, 255, 255, 255); bg.strokeColor = new cc.Color(255, 105, 180, 255); bg.lineWidth = 4; bg.roundRect(-W / 2 + 2, -H / 2 + 2, W - 4, H - 4, 24); bg.fill(); bg.stroke(); mkLabel(mainPanel, '📡 自动抓包系统', 26, [0, 0, 0, 255], 0, H / 2 - 36, W - 100, 'center'); mkButton(mainPanel, '×', W / 2 - 32, H / 2 - 30, 44, 44, [220, 60, 60, 255], [255, 120, 120, 255], function () { if (mainPanel) mainPanel.active = false; }, [255, 255, 255, 255]); _panelRefs.statusLabel = mkLabel(mainPanel, '状态: 正在连接协议...', 17, [60, 130, 220, 255], 0, H / 2 - 78, W - 60, 'center'); _panelRefs.statsLabel = mkLabel(mainPanel, '已抓记录: ' + _logs.length + ' 条', 17, [30, 160, 90, 255], 0, H / 2 - 106, W - 60, 'center'); // 第一行:开关 + 清空 var y1 = H / 2 - 152; var halfBtnW = (W - 80) / 2; mkButton(mainPanel, '开/关抓包', -halfBtnW / 2 - 8, y1, halfBtnW, 46, [90, 150, 220, 255], [255, 255, 255, 255], function () { _captureEnabled = !_captureEnabled; updatePanelStatus(_captureEnabled ? '抓包已开启' : '抓包已暂停'); showDomToast(_captureEnabled ? '抓包已开启' : '抓包已暂停', true); }, [255, 255, 255, 255]); mkButton(mainPanel, '清空记录', halfBtnW / 2 + 8, y1, halfBtnW, 46, [220, 130, 60, 255], [255, 255, 255, 255], function () { _logs = []; updatePanelStats(); if (_panelRefs.listLabel) _panelRefs.listLabel.string = buildPreviewText(); showDomToast('已清空抓包记录', true); }, [255, 255, 255, 255]); // 第二行:复制全部 + 手动复制 var y2 = y1 - 56; mkButton(mainPanel, '📋 复制全部', -halfBtnW / 2 - 8, y2, halfBtnW, 52, [60, 180, 100, 255], [255, 255, 255, 255], function () { if (_logs.length === 0) { showDomToast('当前没有抓包记录', false); return; } var text = buildFullText(); // 先尝试自动复制 var autoOk = tryAutoCopy(text); if (autoOk) showDomToast('已自动复制 ' + _logs.length + ' 条记录\n(同时打开浮层便于核对)', true); // 无论如何弹出浮层 showManualCopyOverlay(text); }, [255, 255, 255, 255]); mkButton(mainPanel, '✋ 手动复制', halfBtnW / 2 + 8, y2, halfBtnW, 52, [200, 120, 220, 255], [255, 255, 255, 255], function () { if (_logs.length === 0) { showDomToast('当前没有抓包记录', false); return; } var text = buildFullText(); showManualCopyOverlay(text); }, [255, 255, 255, 255]); // 内容预览(只显示 cmd + 请求) var listTop = H / 2 - 272; var listH = Math.max(180, H - 350); mkLabel(mainPanel, '最近抓包记录(CMD + 请求):', 17, [0, 0, 0, 255], -W / 2 + 40, listTop, 400, 'left'); var listBg = new cc.Node('ListBg'); listBg.parent = mainPanel; listBg.setContentSize(W - 60, listH); listBg.setPosition(0, listTop - 24 - listH / 2); var lbg = listBg.addComponent(cc.Graphics); lbg.fillColor = new cc.Color(245, 245, 245, 255); lbg.strokeColor = new cc.Color(200, 200, 200, 255); lbg.lineWidth = 1; lbg.roundRect(-(W - 60) / 2, -listH / 2, W - 60, listH, 10); lbg.fill(); lbg.stroke(); _panelRefs.listLabel = mkLabel(listBg, buildPreviewText(), 14, [0, 0, 0, 255], 0, 0, W - 90, 'left'); try { _panelRefs.listLabel.horizontalAlign = cc.Label.HorizontalAlign.LEFT; _panelRefs.listLabel.verticalAlign = cc.Label.VerticalAlign.TOP; _panelRefs.listLabel.node.setPosition(-(W - 90) / 2, listH / 2 - 12); _panelRefs.listLabel.node.anchorX = 0; _panelRefs.listLabel.node.anchorY = 1; _panelRefs.listLabel.lineHeight = 24; try { _panelRefs.listLabel.overflow = cc.Label.Overflow.CLAMP; } catch (e2) {} } catch (e) {} mkLabel(mainPanel, '复制失败会弹全屏浮层,长按文本框手动复制', 14, [120, 120, 120, 255], 0, -H / 2 + 30, W - 40, 'center'); return mainPanel; } // ==================== 悬浮球 ==================== function buildBall() { if (ball && cc.isValid(ball) && ball.parent) return ball; var scene = currentScene(); if (!cc.isValid(scene)) return null; var vs = getVS(); ball = new cc.Node('CaptureBall'); ball.parent = scene; ball.setContentSize(BALL_R * 2, BALL_R * 2); ball.setPosition(vs.width - BALL_R - 26, vs.height - BALL_R - 120); try { ball.zIndex = 2147483000; } catch (e0) {} var g = ball.addComponent(cc.Graphics); g.fillColor = new cc.Color(220, 60, 100, 255); g.circle(0, 0, BALL_R); g.fill(); g.strokeColor = new cc.Color(255, 255, 255, 255); try { g.lineWidth = 3; } catch (e1) {} g.circle(0, 0, BALL_R); g.stroke(); mkLabel(ball, '📡', 30, [255, 255, 255, 255], 0, 0, 60, 'center'); var inGesture = false, startLoc = null, moved = false; ball.on(ev('TOUCH_START', 'touch-start'), function (e) { inGesture = true; moved = false; try { startLoc = e.getLocation(); } catch (e2) { startLoc = null; } }, ball); ball.on(ev('TOUCH_MOVE', 'touch-move'), function (e) { if (!inGesture) return; var loc = null; try { loc = e.getLocation(); } catch (e3) {} if (!loc) return; if (startLoc && (Math.abs(loc.x - startLoc.x) > 10 || Math.abs(loc.y - startLoc.y) > 10)) moved = true; if (!moved) return; var vs2 = getVS(); var nx = Math.max(BALL_R, Math.min(vs2.width - BALL_R, loc.x)); var ny = Math.max(BALL_R, Math.min(vs2.height - BALL_R, loc.y)); ball.setPosition(nx, ny); }, ball); ball.on(ev('TOUCH_END', 'touch-end'), function () { if (!inGesture) return; inGesture = false; if (!moved) { var p = buildCapturePanel(); if (p) { p.active = !p.active; if (p.active) updatePanelStats(); } } }, ball); ball.on(ev('TOUCH_CANCEL', 'touch-cancel'), function () { inGesture = false; }, ball); return ball; } // ==================== 保活与启动 ==================== function ensureAlive() { try { var scene = currentScene(); if (!scene) return; if (!ball || !cc.isValid(ball) || !ball.parent) buildBall(); if (mainPanel && cc.isValid(mainPanel) && !mainPanel.parent) mainPanel.parent = scene; } catch (e) {} } function boot() { if (typeof cc === 'undefined' || !cc) { setTimeout(boot, 300); return; } var scene = currentScene(); if (!scene) { setTimeout(boot, 300); return; } // 立即尝试一次 + 启动定时扫描 hookInstance(getConn()); tickScan(); buildBall(); showStartupToast(); setInterval(ensureAlive, 2000); } // 外部接口 window.__CAPTURE__ = { enable: function () { _captureEnabled = true; }, disable: function () { _captureEnabled = false; }, copyAll: function () { var text = buildFullText(); if (!_logs.length) { showDomToast('没有抓包记录', false); return; } tryAutoCopy(text); showManualCopyOverlay(text); }, manualCopy: function () { if (!_logs.length) { showDomToast('没有抓包记录', false); return; } showManualCopyOverlay(buildFullText()); }, getText: function () { return buildFullText(); }, clear: function () { _logs = []; updatePanelStats(); }, getLogs: function () { return _logs.slice(); } }; if (typeof document !== 'undefined' && document.body) { boot(); } else if (typeof document !== 'undefined') { document.addEventListener('DOMContentLoaded', boot, { once: true }); } else { boot(); } try { console.log('[自动抓包系统 v4.0] 已注入'); } catch (e) {} })();