// ===== 3DTank Hornet Pre-hook ===== // 功能:在游戏脚本执行前 hook Function.prototype.call, // 捕获 webpack 的 __webpack_require__,然后加载 hornet_bundle.js // 用途:当无法修改 main.xxx.js 时,用此脚本从外部获取 webpack 内部对象 // // 加载方式(三选一): // 1. Tampermonkey userscript:@run-at document-start,@match *://3dtank.com/play/* // 2. 修改 HTML:在游戏 // 3. 浏览器扩展:content_script 在 document_start 注入 // // 原理: // webpack runtime 调用: // __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__) // 第四参数 = __webpack_require__ // hook 检测到后捕获,立即恢复原 .call 避免性能影响 (function() { if (window.__hornetPrehook__) return; window.__hornetPrehook__ = true; var origCall = Function.prototype.call; var captured = false; // 超时保护:10秒后放弃 var timeout = setTimeout(function() { if (!captured) { Function.prototype.call = origCall; console.error('[Hornet Prehook] 10秒内未捕获 __webpack_require__,可能游戏结构已变化'); } }, 10000); Function.prototype.call = function(thisArg) { if (!captured && arguments.length >= 4) { var req = arguments[3]; // 检测 __webpack_require__: // 1. 是函数 // 2. .p === '/play/'(webpack publicPath) // 3. 有 .n/.d/.o 辅助函数 if (typeof req === 'function' && req.p === '/play/' && typeof req.n === 'function' && typeof req.d === 'function' && typeof req.o === 'function') { window.__wp_require__ = req; captured = true; clearTimeout(timeout); Function.prototype.call = origCall; // 立即恢复,避免性能影响 console.log('[Hornet Prehook] __webpack_require__ 已捕获'); console.log('[Hornet Prehook] window.__wp_require__ 就绪'); // 加载 hornet_bundle.js(默认关闭:加 #hornet 才加载) // 务必用 hash:查询串会被游戏当成 config 参数,导致 Hash Request 多出名字、上游关闭连接 if (!window.__hornetTools__ && /#hornet/.test(location.hash)) { var s = document.createElement('script'); s.src = '/play/static/js/unpacked/hornet_bundle.js'; s.onload = function() { console.log('[Hornet Prehook] hornet_bundle.js 已加载'); }; s.onerror = function() { console.error('[Hornet Prehook] hornet_bundle.js 加载失败,请检查路径'); }; (document.head || document.documentElement).appendChild(s); } } } return origCall.apply(this, arguments); }; console.log('[Hornet Prehook] 已注入,等待 webpack 模块初始化...'); })();