Files
TankIC/3dtank.com/play/static/js/main.9f4e7a89.js
T
TermiNexus bb3d76117a feat(mirror): 右下角版本徽标(包版本 + 从模块源码读出的 HORNET-TAG)
加载器记录 __hornetPackVersion__ 并渲染固定徽标;TAG 用正则从 __modules__[87072] 源码读取,避免手写常量与真实包不一致。
2026-10-12 10:21:03 +08:00

160 lines
10 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.
console.log('Launcher loaded');
var __script_base_url__=(typeof document!=="undefined"&&document.currentScript&&document.currentScript.src)?document.currentScript.src.replace(/[^\/]+$/,""):"./";!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.Launcher=n():t.Launcher=n()}(globalThis,async()=>{
// ===== 切割版模块加载器 =====
window.__modules__ = {};
const __base_url__ = window.__script_base_url__ || './';
// 6.0 单包(unpacked.pack.json):一次请求拿到 resources.json + 全部代码模块,
// 避免 126 个小文件碎请求;没有包时自动回退逐文件加载(见 6.2)
const __pack_files__ = await (async () => {
try {
const __pack_resp__ = await fetch(__base_url__ + 'unpacked.pack.json', { cache: 'no-cache' });
if (!__pack_resp__.ok) {
console.warn('[Hornet] 单包不可用(HTTP ' + __pack_resp__.status + '),回退逐文件加载');
return null;
}
const __pack__ = await __pack_resp__.json();
window.__hornetPackVersion__ = __pack__.version || '';
console.log('[Hornet] 单包已载入: ' + (__pack__.count || 0) + ' 个文件 版本=' + __pack__.version);
return __pack__.files || null;
} catch (__pack_err__) {
console.warn('[Hornet] 单包不可用,回退逐文件加载: ' + (__pack_err__ && __pack_err__.message));
return null;
}
})();
// 6.1 加载资源模块 (resources.json;优先从单包里取)
let __resource_data__ = null;
if (__pack_files__ && typeof __pack_files__['resources.json'] === 'string') {
__resource_data__ = JSON.parse(__pack_files__['resources.json']);
} else {
const __resource_resp__ = await fetch(__base_url__ + 'unpacked/resources.json');
if (!__resource_resp__.ok) throw new Error('resources.json load failed: HTTP ' + __resource_resp__.status);
__resource_data__ = await __resource_resp__.json();
}
const __resource_map__ = __resource_data__.resourceMap;
for (const __id__ in __resource_map__) {
if (!Object.prototype.hasOwnProperty.call(__resource_map__, __id__)) continue;
const __path__ = __resource_map__[__id__];
const __id_num__ = Number(__id__);
window.__modules__[__id_num__] = (function(__p__) {
return (t, n, i) => {
"use strict";
t.exports = i.p + __p__;
};
})(__path__);
}
// 6.2 加载代码模块:单包命中直接 eval(无网络请求);缺的/没包时回退逐文件 fetch
const __code_ids__ = [806,905,1510,1901,3535,3569,7426,7552,7793,9345,9539,9963,10032,10283,10849,12218,13431,13532,13754,14766,15152,15330,15831,16100,17259,17323,18334,19074,19487,21300,21973,24635,24923,25377,26482,27736,28485,29518,29545,29554,30285,31509,31584,31620,31908,32088,36659,36734,37036,37504,38335,40293,41164,42920,43319,44740,44794,45555,45686,47243,48576,50824,51233,51400,51887,52943,54199,55088,55520,55920,56077,57128,57328,58309,59131,59411,60273,60824,61378,61430,61860,63383,64280,64477,65201,66610,67222,69682,70130,70298,71105,71426,72834,73932,74897,75453,76074,77249,77672,78231,78931,79763,80397,80693,81886,82347,84441,85183,85196,85667,85745,87072,88693,89613,89679,89803,90225,90875,92980,94090,94965,96480,97556,97675,99295,99527];
const __mod_name__ = (__id__) => 'module_' + (typeof __id__ === 'number' ? String(__id__).padStart(5, '0') : __id__) + '.js';
const __missing__ = [];
for (const __id__ of __code_ids__) {
const __name__ = __mod_name__(__id__);
const __src__ = __pack_files__ ? __pack_files__[__name__] : null;
if (typeof __src__ === 'string') (0, eval)(__src__);
else __missing__.push(__id__);
}
if (__missing__.length) {
if (__pack_files__) console.warn('[Hornet] 单包缺少 ' + __missing__.length + ' 个模块,回退逐文件加载');
await Promise.all(__missing__.map(async (__id__) => {
const __url__ = __base_url__ + 'unpacked/' + __mod_name__(__id__);
const __resp__ = await fetch(__url__);
if (!__resp__.ok) throw new Error('Module ' + __id__ + ' load failed: HTTP ' + __resp__.status + ' @ ' + __url__);
(0, eval)(await __resp__.text());
}));
}
var __webpack_modules__ = window.__modules__;
// ===== 版本徽标(右下角):包版本 + 从模块源码读出的 HORNET-TAG =====
// 目的:一眼确认「当前页面吃的是哪一版」,消灭"改了没生效 / 版本没换"这类排查干扰。
// TAG 是从 window.__modules__[87072] 的源码里正则读出来的(不是手写常量),所以它不会说谎。
try {
const __TagSrc__ = String((window.__modules__ && window.__modules__[87072]) || '');
const __TagM__ = __TagSrc__.match(/HORNET-TAG:\s*([^\r\n*]+)/);
const __BadgeText__ =
'Hornet 包 ' + (window.__hornetPackVersion__ || '?') + '\n' + (__TagM__ ? __TagM__[1].trim() : '(未找到 HORNET-TAG)');
const __AddBadge__ = () => {
try {
if (document.getElementById('__hornet_badge__')) return;
const El = document.createElement('div');
El.id = '__hornet_badge__';
El.style.cssText =
'position:fixed;right:6px;bottom:6px;z-index:2147483647;padding:4px 8px;border-radius:4px;' +
'background:rgba(0,0,0,.66);color:#7fe7a1;font:12px/1.45 Consolas,Menlo,monospace;pointer-events:none;white-space:pre';
El.textContent = __BadgeText__;
(document.body || document.documentElement).appendChild(El);
} catch (e) {}
};
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', __AddBadge__);
else __AddBadge__();
} catch (e) {}
// ===== 原 webpack runtime (一字未改) =====
;var __webpack_module_cache__={};function __webpack_require__(t){var n=__webpack_module_cache__[t];if(void 0!==n)return n.exports;var i=__webpack_module_cache__[t]={id:t,loaded:!1,exports:{}};return __webpack_modules__[t].call(i.exports,i,i.exports,__webpack_require__),i.loaded=!0,i.exports}__webpack_require__.n=t=>{var n=t&&t.__esModule?()=>t.default:()=>t;return __webpack_require__.d(n,{a:n}),n},__webpack_require__.d=(t,n)=>{for(var i in n)__webpack_require__.o(n,i)&&!__webpack_require__.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:n[i]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),__webpack_require__.hmd=t=>((t=Object.create(t)).children||(t.children=[]),Object.defineProperty(t,"exports",{enumerable:!0,set:()=>{throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+t.id)}}),t),__webpack_require__.o=(t,n)=>Object.prototype.hasOwnProperty.call(t,n),__webpack_require__.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},__webpack_require__.p="/play/",__webpack_require__(76074),__webpack_require__(13431),__webpack_require__(26482);var __webpack_exports__=__webpack_require__(78231);
// ===== 暴露 webpack require(hornet 工具链 hook_gamemode/hornet_lib 依赖)=====
window.__wp_require__ = __webpack_require__;
// ===== 出错时不自动刷新页面 =====
// 游戏在致命错误/断线后会调用 location.reload(),err toast 一闪就被刷掉、看不到原因。
// 这里拦截自动刷新并保留页面:
// ① 直接接管 location.reload(Chrome 上 Location 成员可能不可写,写入失败则走 ②)
// ② 兜底装 beforeunload 守卫(浏览器会问"确定离开?",取消即可留在页面看 toast)
// 需要刷新时按 F5:会先放行一次守卫,再用原始 reload 真正刷新。
var __hornetRealReload__ = window.location.reload.bind(window.location);
var __reloadHijacked__ = false;
try {
window.location.reload = function () {
console.warn('[Hornet] 已拦截自动刷新(保留页面,便于查看 err toast)。调用栈:\n' + new Error().stack);
};
__reloadHijacked__ = (window.location.reload !== __hornetRealReload__);
} catch (__reloadErr__) { __reloadHijacked__ = false; }
window.addEventListener('beforeunload', function (e) {
if (window.__hornetAllowUnload__) { window.__hornetAllowUnload__ = false; return; } // F5 放行一次
if (__reloadHijacked__) return; // 已由 ① 接管
e.preventDefault();
e.returnValue = '';
});
console.log('[Hornet] 自动刷新拦截: ' + (__reloadHijacked__ ? 'location.reload 已接管' : 'beforeunload 守卫'));
// ===== F5 刷新页面(游戏会吞掉 F5,这里在捕获阶段兜底)=====
window.addEventListener('keydown', function (e) {
if (e.key === 'F5') {
e.preventDefault();
e.stopImmediatePropagation();
window.__hornetAllowUnload__ = true;
__hornetRealReload__();
}
}, true);
// ===== 加载 hornet_bundle(默认加载;纯净页面用 #nohornet)=====
// 开关必须用 hash,不能用查询串:游戏在 module_13431 里把 location.search 的**所有**查询参数
// 注册成 config 参数,于是 ?hornet=1 会让 Hash Request 多出一个资源名 "hornet",真实服务器直接关闭连接(1005)。
if (/[?&]hornet=1(&|$)/.test(location.search)) {
console.warn('[Hornet] 请勿使用 ?hornet=1:查询参数会被游戏当成 config 参数,导致上游握手失败(1005)');
}
if (!/#nohornet/.test(location.hash) && !window.__hornetTools__) {
try {
const __hornet_url__ = __base_url__ + 'unpacked/hornet_bundle.js';
const __hornet_resp__ = await fetch(__hornet_url__);
if (__hornet_resp__.ok) {
const __hornet_code__ = await __hornet_resp__.text();
(0, eval)(__hornet_code__);
console.log('[Hornet] bundle 已加载');
} else {
console.warn('[Hornet] bundle 加载失败: HTTP ' + __hornet_resp__.status);
}
} catch (__hornet_err__) {
console.error('[Hornet] bundle 加载异常:', __hornet_err__);
}
}
// ===== Service Worker:已从模板移除(排查断联用,避免单包缓存接管干扰)=====
// 需要恢复时见 git 历史(tools/split.js 模板);hornet_sw.js 本体与 serve.js 的 /hornet_sw.js 路由保留未删。
return __webpack_exports__;
})//# sourceMappingURL=main.9f4e7a89.js.map