Files
TankIC/tools/hook_gamemode.js
T
TermiNexus 1cc1afdb08 fix(hook): GameMode hook 目标改为新版导出键(jc/ic),修复所有工具静默失效
- 根因:新版导出键语义漂移 —— \$.ac 变成两字段数据类 \、\ \$.zb 变成 ydt,不再是「取 gmt 实例 / ght 类」

- 新版对应关系:\ \$.jc = dct(scene) 取 ght 实例;\ \$.ic = wct 即 ght 类;\ \$.kc = gct(scene) 取 GameMode 实体

- hook 目标改为 \ \$.jc,并继续 hook wct.prototype 全方法作为兜底

- 重新生成 hornet_bundle.js 并同步 unpacked
2026-10-17 15:57:40 +08:00

205 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ===== GameMode Hook 脚本 v2(快速获取版)=====
// 改进:
// 1. 每次 yht 调用都更新引用(解决新战斗中旧引用失效问题)
// 2. ght.prototype 方法每次调用都更新
// 3. 定时器主动验证引用有效性,失效则重置
// 4. trySetGameMode 验证坦克列表,避免捕获未初始化实例
//
// 原理(新版 main.7cfa4058):
// module_87072.$_$.jc = dct 函数(接收 scene,返回 ght 实例) ← 旧版是 $_$.ac,新版键位漂移
// module_87072.$_$.ic = wct 类(ght / GameMode 组件类) ← 旧版是 $_$.zb
// module_87072.$_$.kc = gct 函数(接收 scene,返回 GameMode 实体)← 旧版是 $_$.bc
// dct(scene).m10b_1 = 坦克列表管理器
// 坦克列表 = dct(scene).m10b_1.j11y()
(function() {
console.log('===== GameMode Hook v2 开始 =====');
// 1. 检查 webpack 内部对象
if (!window.__wp_require__) {
console.error('[错误] window.__wp_require__ 不存在');
return;
}
// 2. 获取 module_87072 的导出
var mod = window.__wp_require__(87072);
if (!mod || !mod.$_$) {
console.error('[错误] module_87072 未加载或无 $_$ 导出');
return;
}
var ghtClass = mod.$_$.ic; // 新版:wct(旧版 $_$.zb)
var yhtFunc = mod.$_$.jc; // 新版:dct(旧版 $_$.ac)
console.log('[1] ght 类:', ghtClass ? ghtClass.name : '未找到');
console.log('[1] yht 函数:', typeof yhtFunc === 'function' ? '已找到' : '未找到');
if (!ghtClass) {
console.error('[错误] ght 类未导出');
return;
}
// ===== 辅助:设置 gameMode(无条件设置,坦克列表单独处理)=====
function trySetGameMode(gm, source) {
if (!gm) return false;
var updated = window.__gameMode__ !== gm;
window.__gameMode__ = gm;
// 尝试获取坦克列表(失败也不影响 gameMode 设置)
var tankCount = -1;
try {
var list = gm.m10b_1.j11y();
tankCount = list.e1();
window.__tankList__ = list;
} catch(e) {
// xzq_1 或 z11b 暂时不可用,不影响 gameMode 设置
}
if (updated) {
console.log('%c[Hook] ght 已更新 (via ' + source + ') 坦克数:' + tankCount, 'color:#0f0;font-weight:bold');
}
return true;
}
// ===== 3. Hook yht 函数 — 每次调用都更新 =====
if (typeof yhtFunc === 'function' && !window.__yht_hooked__) {
window.__yht_hooked__ = true;
var origYht = yhtFunc;
mod.$_$.jc = function(t) {
var result = origYht.call(this, t);
if (result) trySetGameMode(result, 'yht');
return result;
};
console.log('[2] yht Hook 已安装(每次调用都更新)');
} else if (window.__yht_hooked__) {
console.log('[2] yht Hook 已存在');
}
// ===== 4. Hook ght.prototype 方法 — 每次调用都更新 =====
if (!window.__ght_proto_hooked__) {
window.__ght_proto_hooked__ = true;
var proto = ghtClass.prototype;
var methodCount = 0;
Object.getOwnPropertyNames(proto).forEach(function(name) {
if (name === 'constructor') return;
var orig = Object.getOwnPropertyDescriptor(proto, name);
if (!orig || typeof orig.value !== 'function') return;
var origFn = orig.value;
methodCount++;
proto[name] = function() {
trySetGameMode(this, 'ght.' + name);
return origFn.apply(this, arguments);
};
});
console.log('[3] ght.prototype 方法 Hook 已安装(' + methodCount + ' 个方法)');
} else {
console.log('[3] ght.prototype Hook 已存在');
}
// ===== 5. 定时器主动验证引用有效性 =====
if (!window.__ght_validator__) {
window.__ght_validator__ = true;
var validateCount = 0;
setInterval(function() {
validateCount++;
if (window.__gameMode__) {
// 验证当前引用是否有效
try {
var list = window.__gameMode__.m10b_1.j11y();
window.__tankList__ = list;
} catch(e) {
// 引用失效(新战斗/退出战斗),重置等待重新捕获
console.log('%c[验证] ght 引用失效,重置等待重新捕获', 'color:#f80;font-weight:bold');
window.__gameMode__ = null;
window.__tankList__ = null;
}
} else {
// 未捕获,前5次每秒提示
if (validateCount <= 5) {
console.log('[验证] 等待 ght 捕获... (' + validateCount + ')');
}
}
}, 500);
console.log('[4] 定时验证器已启动(每500ms)');
} else {
console.log('[4] 定时验证器已存在');
}
// ===== 6. 状态显示 =====
if (window.__gameMode__) {
console.log('[5] 已有 ght 实例:', window.__gameMode__);
if (window.__tankList__) {
try {
console.log(' 当前坦克数量:', window.__tankList__.e1());
} catch(e) {}
}
} else {
console.log('[5] 等待 ght 实例捕获...');
console.log(' 提示: hook 已安装,战斗中触发事件会自动捕获');
}
// ===== 7. 辅助函数 =====
window.__listTanks__ = function() {
if (!window.__gameMode__) {
console.log('ght 实例未捕获,请等待');
return;
}
var list = window.__gameMode__.m10b_1.j11y();
var count = list.e1();
console.log('=== 坦克列表 (' + count + " 个) ===");
for (var i = 0; i < count; i++) {
var tank = list.g1(i);
console.log('[' + i + ']', tank);
}
return list;
};
window.__probeTank__ = function(idx) {
if (!window.__gameMode__) {
console.log('ght 实例未捕获');
return;
}
var list = window.__gameMode__.m10b_1.j11y();
var tank = list.g1(idx || 0);
console.log('坦克[' + (idx || 0) + ']:', tank);
console.log('字段:', Object.keys(tank));
Object.keys(tank).forEach(function(k) {
var v = tank[k];
var type = typeof v;
if (type === 'number' || type === 'string' || type === 'boolean') {
console.log(' ' + k + ' = ' + v + ' (' + type + ')');
} else if (v === null) {
console.log(' ' + k + ' = null');
} else if (type === 'object') {
console.log(' ' + k + ' = [object] (' + (v.constructor ? v.constructor.name : typeof v) + ')');
} else if (type === 'function') {
console.log(' ' + k + ' = [function]');
}
});
return tank;
};
// 主动刷新/检查 ght 实例
window.__refreshGameMode__ = function() {
if (window.__gameMode__) {
try {
var list = window.__gameMode__.m10b_1.j11y();
console.log('%c[刷新] ght 引用有效,坦克数:' + list.e1(), 'color:#0f0;font-weight:bold');
return window.__gameMode__;
} catch(e) {
console.log('%c[刷新] 旧引用失效,已重置', 'color:#f80;font-weight:bold');
window.__gameMode__ = null;
window.__tankList__ = null;
}
}
console.log('[刷新] 等待 hook 捕获...(战斗中触发事件即可)');
return null;
};
console.log('\n===== Hook v2 安装完成 =====');
console.log('辅助函数:');
console.log(' __listTanks() - 列出所有坦克');
console.log(' __probeTank(idx) - 探查指定坦克的字段');
console.log(' __refreshGameMode__() - 刷新/检查 ght 实例');
console.log(' window.__gameMode__ - ght 实例(自动更新)');
console.log(' window.__tankList__ - 坦克列表(自动更新)');
})();