Files
TankIC/tools/hornet_tank_test.js
T
TermiNexus 90c377ad79 feat(3dtank): 本地镜像与 hornet 工具链迁到新版 bundle main.6469b966.js
旧 main.b7114b43.js 已被新构建替换(10,011,039 字节 / 1335 模块),本地镜像整体重切到新版并清掉旧产物;hornet 工具链按 tools/map_symbols.js 生成的新旧符号映射改名后重新打包(3dtank_bundle.js 与 unpacked/hornet_bundle.js 同步)。tools/symbol_map.json(8.9MB 映射产物)与切割解包目录不进库,可用 map_symbols.js / split.js 重新生成。
2026-09-17 19:59:40 +08:00

349 lines
12 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.
// ===== 坦克移动控制(j14b_1 控制值修改版) =====
// 功能:通过修改 Dyt.j14b_1(履带控制状态 Uyt)触发 KC 回调 → ryp(Ds) → kyt 发送网络包
// 原理:
// 1. Dyt 构造函数中 KC 回调(z14a_1)注册到 gameScene 每帧更新
// 2. KC 回调检测 j14b_1.equals(i14b_1) === false 时:
// a) 复制 j14b_1 → i14b_1(l14a)
// b) 触发 ryp(Ds)(_yt 事件全局单例)
// 3. kyt 监听 _yt 事件 → 调用 w14b_1.b14c(time, j14b_1) 发送网络包
// 4. 这是游戏自然移动路径,网络包格式/时机完全正常,不触发服务器检测
// 控制:W/S 前进/后退,A/D 左转/右转,松开停止
// 在浏览器控制台运行(需先运行 hook_gamemode.js + hornet_lib.js)
// 注册到 __hornetTools__.TankControl
// 注意:本文件不加入 bundle,独立加载
(function() {
var running = false;
var keys = {};
var updateInterval = null;
var verifyInterval = null;
var dyt = null;
var playerTank = null;
var maxSpeed = 100;
var maxTurn = 30;
var lastS140 = 0;
var lastT140 = 0;
var kcVerified = false;
function _start() {
console.log('===== 坦克移动控制启动(v14m_1 控制值修改版) =====');
if (!window.__gameMode__) {
console.error('请先运行 hook_gamemode.js');
return;
}
if (window.__hornetTankTest__ && window.__hornetTankTest__.GetRunning && window.__hornetTankTest__.GetRunning()) {
window.__hornetTankTest__.Stop();
}
var gm = window.__gameMode__;
var lib = window.__hornetLib__;
if (!lib) {
console.error('[测试] 请先运行 hornet_lib.js');
return;
}
var FindComponentByField = lib.FindComponentByField;
var GetTankPosition = lib.GetTankPosition;
// ===== 获取玩家坦克 =====
function GetPlayerTank() {
var t = gm.y100_1;
if (t) return t;
t = gm.x100_1;
if (t) return t;
try {
var tl = gm.q100_1.r11l();
if (tl.e1() > 0) return tl.g1(0);
} catch(e) {}
return null;
}
playerTank = GetPlayerTank();
if (!playerTank) {
console.error('[测试] 未找到玩家坦克');
return;
}
// ===== 获取 Dyt 组件(履带底盘,有 j14b_1 字段) =====
dyt = FindComponentByField(playerTank, 'v14m_1');
if (!dyt) {
console.error('[测试] 未找到 Dyt 组件(v14m_1 字段)');
console.error('[测试] 玩家坦克可能不是履带坦克,或移动组件未初始化');
return;
}
// ===== 诊断信息 =====
console.log('[诊断] Dyt 组件状态:');
console.log(' n14m_1 (在战斗中):', dyt.n14m_1);
try {
console.log(' v14m_1:', dyt.v14m_1.toString());
console.log(' i14b_1:', dyt.i14b_1.toString());
} catch(e) {
console.log(' v14m_1/i14b_1 toString 失败:', e.message);
}
// 检查 KC(z14a_1)的方法
if (dyt.l14m_1) {
console.log(' l14m_1.aye:', typeof dyt.l14m_1.aye);
console.log(' l14m_1.kak:', typeof dyt.l14m_1.kak);
console.log(' l14m_1 constructor:', dyt.l14m_1.constructor && dyt.l14m_1.constructor.name);
} else {
console.warn(' l14m_1 为 null,KC 回调可能未注册');
}
// ===== 获取 maxSpeed 和 maxTurn =====
// 尝试从 f14b_1(speedCharacteristics/dgt 组件)获取
try {
var sc = dyt.r14m_1;
if (sc) {
if (typeof sc.na9 === 'function') {
maxSpeed = sc.na9();
console.log(' 从 r14m_1.na9() 获取 maxSpeed:', maxSpeed);
} else if (sc.f14c_1 !== undefined) {
maxSpeed = sc.f14c_1;
console.log(' 从 r14m_1.f14c_1 获取 maxSpeed:', maxSpeed);
}
if (sc.j14c_1 !== undefined) {
maxTurn = sc.j14c_1;
console.log(' 从 r14m_1.j14c_1 获取 maxTurn:', maxTurn);
}
}
} catch(e) {
console.warn('[测试] 获取速度参数失败:', e.message);
}
// 尝试从其他组件获取(a149_1 字段存储 na9() 的值)
if (maxSpeed === 100) {
try {
playerTank.pyt_1.s2a_1.forEach(function(valueList) {
if (maxSpeed !== 100) return;
try {
var comp = valueList && typeof valueList.g1 === 'function' ? valueList.g1(0) : valueList;
if (comp && comp.m14k_1 !== undefined && typeof comp.m14k_1 === 'number' && comp.m14k_1 > 0) {
maxSpeed = comp.m14k_1;
console.log(' 从组件 m14k_1 获取 maxSpeed:', maxSpeed);
}
} catch(e) {}
});
} catch(e) {}
}
console.log(' 最终 maxSpeed:', maxSpeed);
console.log(' 最终 maxTurn:', maxTurn);
if (!dyt.n14m_1) {
console.warn('[测试] 玩家不在战斗中(n14m_1=false),KC 回调会直接返回不触发 iyz(Ds)');
console.warn('[测试] 请确保在战斗中再启动移动控制');
}
// ===== 键盘事件 =====
keys = {};
function onKeyDown(e) {
var k = e.key.toLowerCase();
if (k === 'w' || k === 'a' || k === 's' || k === 'd') {
keys[k] = true;
e.preventDefault();
e.stopPropagation();
}
}
function onKeyUp(e) {
var k = e.key.toLowerCase();
if (k === 'w' || k === 'a' || k === 's' || k === 'd') {
keys[k] = false;
e.preventDefault();
e.stopPropagation();
}
}
document.addEventListener('keydown', onKeyDown, true);
document.addEventListener('keyup', onKeyUp, true);
// ===== 主循环:设置 j14b_1 控制值 =====
running = true;
lastS140 = dyt.v14m_1.m14b_1;
lastT140 = dyt.v14m_1.n14b_1;
updateInterval = setInterval(function() {
if (!running || !dyt) return;
var forward = (keys['w'] ? 1 : 0) + (keys['s'] ? -1 : 0);
var turn = (keys['a'] ? 1 : 0) + (keys['d'] ? -1 : 0);
var newS140 = forward * maxSpeed;
var newT140 = turn * maxTurn;
// 只在值变化时设置(KC 回调检测 j14b_1 ≠ i14b_1 才触发 ryp(Ds))
if (newS140 !== lastS140 || newT140 !== lastT140) {
try {
dyt.v14m_1.m14b_1 = newS140;
dyt.v14m_1.n14b_1 = newT140;
// u140_1 (reverseBackTurn) 不修改
lastS140 = newS140;
lastT140 = newT140;
console.log('[移动] m14b_1=' + newS140 + ' n14b_1=' + newT140 +
' (v14m_1 ≠ i14b_1 → KC 回调将触发 iyz(Ds) → kyt 发送网络包)');
} catch(e) {
console.error('[测试] 设置 v14m_1 失败:', e.message);
}
}
}, 50);
// ===== KC 回调验证:修改 j14b_1 后检查 i14b_1 是否更新 =====
// KC 回调会复制 j14b_1 → i14b_1(i14b_1.l14a(j14b_1))
// 如果 i14b_1 更新了,说明 KC 回调每帧调用,方案有效
kcVerified = false;
var verifyCount = 0;
verifyInterval = setInterval(function() {
if (kcVerified || !running || !dyt) return;
verifyCount++;
if (verifyCount > 60) { // 3秒后停止验证
clearInterval(verifyInterval);
verifyInterval = null;
if (!kcVerified) {
console.warn('[验证] 3秒内未检测到 KC 回调工作(i14b_1 未跟随 v14m_1 更新)');
console.warn('[验证] 可能原因:1) KC 回调不每帧调用 2) n14m_1=false 3) l14m_1 未注册');
console.warn('[验证] 请尝试在游戏中移动(点击地面寻路),观察 i14b_1 是否变化');
}
return;
}
// 如果 j14b_1 ≠ i14b_1,说明 KC 回调还没复制(可能 KC 不每帧调用)
// 如果 j14b_1 == i14b_1,说明 KC 回调已复制(KC 工作正常)
try {
if (dyt.v14m_1.m14b_1 === dyt.i14b_1.m14b_1 &&
dyt.v14m_1.n14b_1 === dyt.i14b_1.n14b_1) {
if (lastS140 !== 0 || lastT140 !== 0) {
// j14b_1 有非零值且 i14b_1 已同步
kcVerified = true;
clearInterval(verifyInterval);
verifyInterval = null;
console.log('[验证] KC 回调工作正常!i14b_1 已跟随 v14m_1 更新');
console.log('[验证] iyz(Ds) 应已触发,kyt 应已发送网络包');
}
}
} catch(e) {}
}, 50);
// ===== 位置监控(每秒打印一次) =====
var posLogCount = 0;
var posLogInterval = setInterval(function() {
if (!running) {
clearInterval(posLogInterval);
return;
}
posLogCount++;
if (posLogCount % 20 === 0) { // 每10秒打印一次
try {
var p = GetTankPosition(playerTank);
if (p) {
console.log('[位置] (' + p.x.toFixed(1) + ', ' + p.y.toFixed(1) + ', ' + p.z.toFixed(1) + ')');
}
} catch(e) {}
}
}, 500);
console.log('[测试] 移动控制已启动');
console.log('[测试] W/S 前进/后退,A/D 左转/右转');
console.log('[测试] 停止请调用 TankControl.Stop()');
// 保存引用以便 Stop 清理
_stopCallbacks = {
onKeyDown: onKeyDown,
onKeyUp: onKeyUp,
posLogInterval: posLogInterval
};
}
var _stopCallbacks = null;
function Stop() {
running = false;
if (updateInterval) {
clearInterval(updateInterval);
updateInterval = null;
}
if (verifyInterval) {
clearInterval(verifyInterval);
verifyInterval = null;
}
if (_stopCallbacks) {
if (_stopCallbacks.posLogInterval) clearInterval(_stopCallbacks.posLogInterval);
document.removeEventListener('keydown', _stopCallbacks.onKeyDown, true);
document.removeEventListener('keyup', _stopCallbacks.onKeyUp, true);
_stopCallbacks = null;
}
// 停止移动:设置 j14b_1 为 0
if (dyt && dyt.v14m_1) {
try {
dyt.v14m_1.m14b_1 = 0;
dyt.v14m_1.n14b_1 = 0;
console.log('[测试] v14m_1 已归零,坦克停止移动');
} catch(e) {
console.error('[测试] 归零 v14m_1 失败:', e.message);
}
}
keys = {};
lastS140 = 0;
lastT140 = 0;
kcVerified = false;
console.log('[测试] 移动控制已停止');
}
function Status() {
if (!running) return '未运行';
var info = '运行中';
try {
if (playerTank) {
var p = window.__hornetLib__.GetTankPosition(playerTank);
if (p) info += ' 位置(' + p.x.toFixed(0) + ',' + p.y.toFixed(0) + ',' + p.z.toFixed(0) + ')';
}
} catch(e) {}
if (kcVerified) info += ' [KC回调已验证]';
else info += ' [KC回调未验证]';
return info;
}
function GetRunning() {
return running;
}
// ===== 手动设置移动值(不通过键盘) =====
function SetMove(forward, turn) {
if (!dyt || !dyt.v14m_1) {
console.error('[测试] Dyt 组件未初始化,请先 Start');
return;
}
var newS140 = Math.round(forward * maxSpeed);
var newT140 = Math.round(turn * maxTurn);
try {
dyt.v14m_1.m14b_1 = newS140;
dyt.v14m_1.n14b_1 = newT140;
lastS140 = newS140;
lastT140 = newT140;
console.log('[手动移动] m14b_1=' + newS140 + ' n14b_1=' + newT140);
} catch(e) {
console.error('[测试] 手动设置失败:', e.message);
}
}
// ===== 设置速度参数 =====
function SetParams(speed, turn) {
if (speed !== undefined && speed > 0) maxSpeed = Math.round(speed);
if (turn !== undefined && turn > 0) maxTurn = Math.round(turn);
console.log('[参数] maxSpeed=' + maxSpeed + ' maxTurn=' + maxTurn);
}
window.__hornetTankTest__ = {
Start: _start,
Stop: Stop,
Status: Status,
GetRunning: GetRunning,
SetMove: SetMove,
SetParams: SetParams
};
if (window.__hornetTools__) {
window.__hornetTools__.TankControl = window.__hornetTankTest__;
}
_start();
})();