// ===== 坦克移动控制(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(); })();