/* ============================================================================
* 自动抓包系统 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) {}
})();