@ttmg/cli 0.3.3 → 0.3.5-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -1
- package/dist/index.js +230 -109
- package/dist/index.js.map +1 -1
- package/dist/package.json +2 -2
- package/dist/public/assets/index-BRMID64m.js +1 -0
- package/dist/public/assets/{index-BBJshfB_.js → index-Ba0pzb2a.js} +1 -1
- package/dist/public/assets/index-Ba0pzb2a.js.br +0 -0
- package/dist/public/assets/{index-IjT-c81T.js → index-BgPufU68.js} +1 -1
- package/dist/public/assets/{index-DqhIu6n9.js → index-Bup0y3Y0.js} +1 -1
- package/dist/public/assets/{index-CgXh9-IR.js → index-BvQYQ3nw.js} +4 -4
- package/dist/public/assets/index-BvQYQ3nw.js.br +0 -0
- package/dist/public/assets/{index-liPKaTSM.js → index-CUbWSY4M.js} +1 -1
- package/dist/public/assets/{index-maYHtPXK.js → index-D7wHfGqp.js} +1 -1
- package/dist/public/assets/index-DH6jmQlu.js +1 -0
- package/dist/public/assets/{index-DZ4Lot5a.js → index-DNiiCmLA.js} +1 -1
- package/dist/public/assets/index-DNiiCmLA.js.br +0 -0
- package/dist/public/assets/{index-C250u6X0.css → index-D_5oU4mJ.css} +1 -1
- package/dist/public/assets/index-D_5oU4mJ.css.br +0 -0
- package/dist/public/assets/{index-Dwl4ZYBR.js → index-EpYlOZ81.js} +1 -1
- package/dist/public/assets/{index-Bxrlcdy9.js → index-HAU2X1j9.js} +1 -1
- package/dist/public/assets/index-HAU2X1j9.js.br +0 -0
- package/dist/public/assets/{index-D_UafQRj.js → index-xb5uiTXk.js} +1 -1
- package/dist/public/index.html +2 -2
- package/package.json +2 -2
- package/dist/public/assets/index-BBJshfB_.js.br +0 -0
- package/dist/public/assets/index-Bxrlcdy9.js.br +0 -0
- package/dist/public/assets/index-C250u6X0.css.br +0 -0
- package/dist/public/assets/index-CgXh9-IR.js.br +0 -0
- package/dist/public/assets/index-CnpdpEXV.js +0 -1
- package/dist/public/assets/index-DZ4Lot5a.js.br +0 -0
- package/dist/public/assets/index-DZSJz0Hu.js +0 -1
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -38,6 +38,7 @@ var FormData$1 = require('form-data');
|
|
|
38
38
|
var ttmgPack = require('ttmg-pack');
|
|
39
39
|
var expressStaticGzip = require('express-static-gzip');
|
|
40
40
|
var fileUpload = require('express-fileupload');
|
|
41
|
+
var async_hooks = require('async_hooks');
|
|
41
42
|
var fs$1 = require('node:fs');
|
|
42
43
|
var path$1 = require('node:path');
|
|
43
44
|
var zlib = require('zlib');
|
|
@@ -6532,7 +6533,7 @@ function getAxiosProxyConfig() {
|
|
|
6532
6533
|
}
|
|
6533
6534
|
return {};
|
|
6534
6535
|
}
|
|
6535
|
-
async function request({ url, method, data, headers, params, }) {
|
|
6536
|
+
async function request$1({ url, method, data, headers, params, }) {
|
|
6536
6537
|
const config = getTTMGRC();
|
|
6537
6538
|
const cookie = config?.cookie;
|
|
6538
6539
|
const proxyConfig = getAxiosProxyConfig();
|
|
@@ -6572,7 +6573,20 @@ async function request({ url, method, data, headers, params, }) {
|
|
|
6572
6573
|
};
|
|
6573
6574
|
}
|
|
6574
6575
|
}
|
|
6575
|
-
|
|
6576
|
+
/** wasm/archive 大文件下载超时(毫秒),防止无限卡住 */
|
|
6577
|
+
const DOWNLOAD_TIMEOUT_MS = 10 * 60 * 1000; // 10 分钟
|
|
6578
|
+
function formatBytes(n) {
|
|
6579
|
+
if (n >= 1024 * 1024)
|
|
6580
|
+
return `${(n / 1024 / 1024).toFixed(2)}MB`;
|
|
6581
|
+
if (n >= 1024)
|
|
6582
|
+
return `${(n / 1024).toFixed(2)}KB`;
|
|
6583
|
+
return `${n}B`;
|
|
6584
|
+
}
|
|
6585
|
+
async function download$1(url, filePath, headers) {
|
|
6586
|
+
const t0 = Date.now();
|
|
6587
|
+
const baseName = filePath.split(/[/\\]/).pop() ?? filePath;
|
|
6588
|
+
const urlShort = url.length > 120 ? url.slice(0, 100) + '...' + url.slice(-20) : url;
|
|
6589
|
+
console.log(`[download] start out=${baseName} url=${urlShort}`);
|
|
6576
6590
|
// 清理旧文件
|
|
6577
6591
|
if (fs.existsSync(filePath)) {
|
|
6578
6592
|
try {
|
|
@@ -6584,40 +6598,88 @@ async function download(url, filePath) {
|
|
|
6584
6598
|
try {
|
|
6585
6599
|
const res = await axios.get(url, {
|
|
6586
6600
|
responseType: 'stream',
|
|
6587
|
-
// 让非 2xx 进入 catch
|
|
6588
6601
|
validateStatus: s => s >= 200 && s < 300,
|
|
6602
|
+
headers: headers || {},
|
|
6603
|
+
timeout: DOWNLOAD_TIMEOUT_MS,
|
|
6589
6604
|
...proxyConfig,
|
|
6590
6605
|
});
|
|
6591
|
-
|
|
6592
|
-
|
|
6606
|
+
const contentLength = res.headers['content-length'];
|
|
6607
|
+
const expectedSize = contentLength ? parseInt(contentLength, 10) : null;
|
|
6608
|
+
console.log(`[download] response ok out=${baseName} content-length=${expectedSize != null ? formatBytes(expectedSize) : 'unknown'} elapsed=${Date.now() - t0}ms`);
|
|
6609
|
+
// 流写入 + 超时保护,防止 pipe 卡死
|
|
6610
|
+
const pipePromise = new Promise((resolve, reject) => {
|
|
6593
6611
|
const writer = fs.createWriteStream(filePath);
|
|
6612
|
+
let settled = false;
|
|
6613
|
+
let receivedBytes = 0;
|
|
6614
|
+
let lastLogBytes = 0;
|
|
6615
|
+
const LOG_INTERVAL = 1024 * 1024; // 每 1MB 打一次日志
|
|
6616
|
+
const settle = (fn) => {
|
|
6617
|
+
if (settled)
|
|
6618
|
+
return;
|
|
6619
|
+
settled = true;
|
|
6620
|
+
fn();
|
|
6621
|
+
};
|
|
6594
6622
|
const onError = (e) => {
|
|
6595
6623
|
cleanup();
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6624
|
+
console.error(`[download] stream error out=${baseName} received=${formatBytes(receivedBytes)} err=`, e);
|
|
6625
|
+
settle(() => {
|
|
6626
|
+
try {
|
|
6627
|
+
if (fs.existsSync(filePath))
|
|
6628
|
+
fs.unlinkSync(filePath);
|
|
6629
|
+
}
|
|
6630
|
+
catch { }
|
|
6631
|
+
reject(e);
|
|
6632
|
+
});
|
|
6602
6633
|
};
|
|
6603
6634
|
const onClose = () => {
|
|
6604
6635
|
cleanup();
|
|
6605
|
-
|
|
6636
|
+
const elapsed = Date.now() - t0;
|
|
6637
|
+
const speed = elapsed > 0 ? (receivedBytes / 1024 / elapsed).toFixed(1) : '?';
|
|
6638
|
+
console.log(`[download] pipe done out=${baseName} size=${formatBytes(receivedBytes)} elapsed=${elapsed}ms speed=${speed}KB/s`);
|
|
6639
|
+
settle(resolve);
|
|
6606
6640
|
};
|
|
6607
6641
|
const cleanup = () => {
|
|
6642
|
+
res.data.off('data', onData);
|
|
6608
6643
|
writer.off('error', onError);
|
|
6609
6644
|
writer.off('close', onClose);
|
|
6610
6645
|
res.data.off('error', onError);
|
|
6646
|
+
if (timeoutId)
|
|
6647
|
+
clearTimeout(timeoutId);
|
|
6611
6648
|
};
|
|
6649
|
+
const onData = (chunk) => {
|
|
6650
|
+
receivedBytes += Buffer.isBuffer(chunk) ? chunk.length : Buffer.byteLength(chunk);
|
|
6651
|
+
if (receivedBytes - lastLogBytes >= LOG_INTERVAL) {
|
|
6652
|
+
lastLogBytes = receivedBytes;
|
|
6653
|
+
const elapsed = Date.now() - t0;
|
|
6654
|
+
const speed = elapsed > 0 ? (receivedBytes / 1024 / elapsed).toFixed(1) : '?';
|
|
6655
|
+
console.log(`[download] progress out=${baseName} received=${formatBytes(receivedBytes)} elapsed=${elapsed}ms speed=${speed}KB/s`);
|
|
6656
|
+
}
|
|
6657
|
+
};
|
|
6658
|
+
const timeoutId = setTimeout(() => {
|
|
6659
|
+
cleanup();
|
|
6660
|
+
console.error(`[download] timeout out=${baseName} received=${formatBytes(receivedBytes)} expected=${expectedSize != null ? formatBytes(expectedSize) : 'unknown'}`);
|
|
6661
|
+
settle(() => {
|
|
6662
|
+
try {
|
|
6663
|
+
if (fs.existsSync(filePath))
|
|
6664
|
+
fs.unlinkSync(filePath);
|
|
6665
|
+
}
|
|
6666
|
+
catch { }
|
|
6667
|
+
res.data?.destroy();
|
|
6668
|
+
reject(new Error(`下载超时(${DOWNLOAD_TIMEOUT_MS / 60000} 分钟),请检查网络后重试`));
|
|
6669
|
+
});
|
|
6670
|
+
}, DOWNLOAD_TIMEOUT_MS);
|
|
6671
|
+
res.data.on('data', onData);
|
|
6612
6672
|
res.data.on('error', onError);
|
|
6613
6673
|
writer.on('error', onError);
|
|
6614
6674
|
writer.on('close', onClose);
|
|
6615
6675
|
res.data.pipe(writer);
|
|
6616
6676
|
});
|
|
6617
|
-
|
|
6677
|
+
await pipePromise;
|
|
6618
6678
|
return { ok: true };
|
|
6619
6679
|
}
|
|
6620
6680
|
catch (err) {
|
|
6681
|
+
const elapsed = Date.now() - t0;
|
|
6682
|
+
console.error(`[download] failed out=${baseName} elapsed=${elapsed}ms err=`, err);
|
|
6621
6683
|
// 403 等受控处理
|
|
6622
6684
|
if (isAxiosError(err) && err.response?.status === 403) {
|
|
6623
6685
|
// 不抛出,让上层自行决定
|
|
@@ -6633,7 +6695,7 @@ function isAxiosError(e) {
|
|
|
6633
6695
|
|
|
6634
6696
|
async function fetchGameInfo(clientKey) {
|
|
6635
6697
|
// 访问 V4 接口
|
|
6636
|
-
const response = await request({
|
|
6698
|
+
const response = await request$1({
|
|
6637
6699
|
url: `https://developers.tiktok.com/tiktok/v4/devportal/mini_game/devtool/info`,
|
|
6638
6700
|
method: 'GET',
|
|
6639
6701
|
params: {
|
|
@@ -6690,7 +6752,7 @@ async function uploadGameToPlatform({ data, name, clientKey, note = '--', appId,
|
|
|
6690
6752
|
formData.append('file', new Blob([data], { type: 'application/zip' }), sanitized);
|
|
6691
6753
|
formData.append('client_key', clientKey);
|
|
6692
6754
|
formData.append('note', note);
|
|
6693
|
-
const response = await request({
|
|
6755
|
+
const response = await request$1({
|
|
6694
6756
|
method: 'POST',
|
|
6695
6757
|
url: 'https://developers.tiktok.com/tiktok/v4/devportal/mini_game/devtool/upload',
|
|
6696
6758
|
data: formData,
|
|
@@ -8680,8 +8742,34 @@ async function listen(app, options) {
|
|
|
8680
8742
|
return { server, port, url, version };
|
|
8681
8743
|
}
|
|
8682
8744
|
|
|
8745
|
+
const asyncLocalStorage = new async_hooks.AsyncLocalStorage();
|
|
8746
|
+
/** 在请求作用域内运行,供 middleware 调用 */
|
|
8747
|
+
function runWithRequest(req, fn) {
|
|
8748
|
+
return asyncLocalStorage.run({ req }, fn);
|
|
8749
|
+
}
|
|
8750
|
+
/** Express 中间件:将 req 注入 AsyncLocalStorage,供 api.request/download 内部读取 ppeHeaders */
|
|
8751
|
+
function requestContextMiddleware(req, res, next) {
|
|
8752
|
+
runWithRequest(req, () => next());
|
|
8753
|
+
}
|
|
8754
|
+
/** 从当前请求中提取 x-use-ppe、x-tt-env,仅当浏览器有传时才返回 */
|
|
8755
|
+
function getPpeHeaders() {
|
|
8756
|
+
const store = asyncLocalStorage.getStore();
|
|
8757
|
+
if (!store?.req?.headers)
|
|
8758
|
+
return {};
|
|
8759
|
+
const h = store.req.headers;
|
|
8760
|
+
const result = {};
|
|
8761
|
+
const v1 = h['x-use-ppe'];
|
|
8762
|
+
const v2 = h['x-tt-env'];
|
|
8763
|
+
if (typeof v1 === 'string')
|
|
8764
|
+
result['x-use-ppe'] = v1;
|
|
8765
|
+
if (typeof v2 === 'string')
|
|
8766
|
+
result['x-tt-env'] = v2;
|
|
8767
|
+
return result;
|
|
8768
|
+
}
|
|
8769
|
+
|
|
8683
8770
|
function setupMiddlewares(app, options) {
|
|
8684
8771
|
const { publicPath, outputDir } = options;
|
|
8772
|
+
app.use(requestContextMiddleware);
|
|
8685
8773
|
app.use(fileUpload());
|
|
8686
8774
|
app.use(expressStaticGzip(publicPath, {
|
|
8687
8775
|
enableBrotli: true,
|
|
@@ -8883,6 +8971,8 @@ const UNITY_WASM_SPLIT_CONFIG_FIELD_SCHEME = {
|
|
|
8883
8971
|
IOS_CODE_FILE_MD5: `$IOS_CODE_FILE_MD5`,
|
|
8884
8972
|
ANDROID_CODE_FILE_MD5: `$ANDROID_CODE_FILE_MD5`,
|
|
8885
8973
|
ANDROID_SUB_CODE_FILE_MD5: `$SUB_CODE_FILE_MD5`,
|
|
8974
|
+
ARCHIVE_CODE_FILE_MD5: `$ARCHIVE_CODE_FILE_MD5`,
|
|
8975
|
+
enableArchiveMode: `"$ENABLEARCHIVEMODE"`,
|
|
8886
8976
|
WASMSPLITVERSION: `"$WASMSPLITVERSION"`,
|
|
8887
8977
|
ENABLEWASMSPLIT: `"$ENABLEWASMSPLIT"`,
|
|
8888
8978
|
IOS_SUB_JS_FILE_CONFIG: `"$IOS_SUB_JS_FILE_CONFIG"`,
|
|
@@ -8902,9 +8992,11 @@ const WASM_SPLIT_SUBPACKAGE_CONFIG = {
|
|
|
8902
8992
|
name: 'wasmcode1-android',
|
|
8903
8993
|
root: 'wasmcode1-android/',
|
|
8904
8994
|
},
|
|
8905
|
-
|
|
8906
|
-
|
|
8995
|
+
archive: {
|
|
8996
|
+
name: 'wasmcode-archive',
|
|
8997
|
+
root: 'wasmcode-archive/',
|
|
8907
8998
|
},
|
|
8999
|
+
/** iOS 与 archive 互斥:有 archive 时 iOS URL 为空,反之亦然 */
|
|
8908
9000
|
iosMain: {
|
|
8909
9001
|
name: 'wasmcode-ios',
|
|
8910
9002
|
root: 'wasmcode-ios/',
|
|
@@ -8915,6 +9007,7 @@ const WASM_SPLIT_SUBPACKAGE_CONFIG = {
|
|
|
8915
9007
|
},
|
|
8916
9008
|
};
|
|
8917
9009
|
const WASM_FILENAME_SUFFIX = '.webgl.wasm.code.unityweb.wasm';
|
|
9010
|
+
const WASM_ARCHIVE_FILENAME_SUFFIX = '.webgl.wasm.code.unityweb.bin';
|
|
8918
9011
|
const BR_SUFFIX = '.br';
|
|
8919
9012
|
// 输出 JSON 格式
|
|
8920
9013
|
const JSON_INDENT = 2;
|
|
@@ -8924,6 +9017,21 @@ const CONCURRENCY_LIMIT = 2;
|
|
|
8924
9017
|
const DOWNLOAD_RETRY = 3;
|
|
8925
9018
|
const WASM_SPLIT_CONFIG_FILE_NAME = 'webgl-wasm-split.js';
|
|
8926
9019
|
|
|
9020
|
+
/**
|
|
9021
|
+
* Unity 模块统一的 HTTP 请求封装
|
|
9022
|
+
* DEV_HEADERS 与 ppeHeaders(从当前请求 AsyncLocalStorage 读取)的合并逻辑集中在此处
|
|
9023
|
+
*/
|
|
9024
|
+
const request = (opts) => {
|
|
9025
|
+
const ppeHeaders = getPpeHeaders();
|
|
9026
|
+
const headers = { ...DEV_HEADERS, ...ppeHeaders, ...opts.headers };
|
|
9027
|
+
return request$1({ ...opts, headers });
|
|
9028
|
+
};
|
|
9029
|
+
const download = (url, filePath) => {
|
|
9030
|
+
const ppeHeaders = getPpeHeaders();
|
|
9031
|
+
const headers = ppeHeaders && Object.keys(ppeHeaders).length > 0 ? ppeHeaders : undefined;
|
|
9032
|
+
return download$1(url, filePath, headers);
|
|
9033
|
+
};
|
|
9034
|
+
|
|
8927
9035
|
// prepare.ts
|
|
8928
9036
|
// 若你的 request 是 axios:你可以添加 maxBodyLength/ maxContentLength 等参数
|
|
8929
9037
|
// 若是 got:可直接传 form 实例
|
|
@@ -8974,16 +9082,9 @@ async function startPrepare(params) {
|
|
|
8974
9082
|
return request({
|
|
8975
9083
|
url: `${BASE_URL}/api/stark_wasm/v4/post/prepare`,
|
|
8976
9084
|
method: 'POST',
|
|
8977
|
-
headers:
|
|
8978
|
-
|
|
8979
|
-
...formHeaders, // 包含正确的 multipart/form-data; boundary=...
|
|
8980
|
-
},
|
|
8981
|
-
params: {
|
|
8982
|
-
client_key: params.client_key,
|
|
8983
|
-
with_ios: true,
|
|
8984
|
-
},
|
|
9085
|
+
headers: formHeaders,
|
|
9086
|
+
params: { client_key: params.client_key, with_ios: true },
|
|
8985
9087
|
data: form,
|
|
8986
|
-
// 若 request 基于 axios,建议加上以下两项以支持大文件:
|
|
8987
9088
|
});
|
|
8988
9089
|
}
|
|
8989
9090
|
|
|
@@ -9069,7 +9170,6 @@ async function downloadPrepared(data) {
|
|
|
9069
9170
|
const res = await request({
|
|
9070
9171
|
url: `${BASE_URL}/api/stark_wasm/v4/post/download_prepared`,
|
|
9071
9172
|
method: 'POST',
|
|
9072
|
-
headers: DEV_HEADERS,
|
|
9073
9173
|
data,
|
|
9074
9174
|
});
|
|
9075
9175
|
wsServer.sendUnitySplitStatus({
|
|
@@ -9091,9 +9191,6 @@ async function downloadPrepared(data) {
|
|
|
9091
9191
|
url: downloadUrl,
|
|
9092
9192
|
});
|
|
9093
9193
|
await download(downloadUrl, tempWasmPath);
|
|
9094
|
-
/**
|
|
9095
|
-
* 下载完成后需要进行 br 并替换 codePath 对应的文件后再返回成功
|
|
9096
|
-
*/
|
|
9097
9194
|
fs$1.copyFileSync(tempWasmPath, willReplaceWasmPath);
|
|
9098
9195
|
wsServer.sendUnitySplitStatus({
|
|
9099
9196
|
status: 'download_prepared_wasm_done',
|
|
@@ -9170,11 +9267,7 @@ async function getCollectedFuncIds({ client_key, wasm_md5, }) {
|
|
|
9170
9267
|
return request({
|
|
9171
9268
|
url: `${BASE_URL}/api/stark_wasm/v4/get/collectedfuncids`,
|
|
9172
9269
|
method: 'GET',
|
|
9173
|
-
|
|
9174
|
-
params: {
|
|
9175
|
-
client_key,
|
|
9176
|
-
wasm_md5,
|
|
9177
|
-
},
|
|
9270
|
+
params: { client_key, wasm_md5 },
|
|
9178
9271
|
});
|
|
9179
9272
|
}
|
|
9180
9273
|
|
|
@@ -9182,11 +9275,7 @@ async function setCollect({ client_key, wasm_md5, }) {
|
|
|
9182
9275
|
return request({
|
|
9183
9276
|
url: `${BASE_URL}/api/stark_wasm/v4/post/set_collecting`,
|
|
9184
9277
|
method: 'POST',
|
|
9185
|
-
data: {
|
|
9186
|
-
client_key,
|
|
9187
|
-
wasm_md5,
|
|
9188
|
-
},
|
|
9189
|
-
headers: DEV_HEADERS,
|
|
9278
|
+
data: { client_key, wasm_md5 },
|
|
9190
9279
|
});
|
|
9191
9280
|
}
|
|
9192
9281
|
|
|
@@ -9194,26 +9283,15 @@ async function getCollecttingInfo({ client_key, wasm_md5, }) {
|
|
|
9194
9283
|
return request({
|
|
9195
9284
|
url: `${BASE_URL}/api/stark_wasm/v4/get/funccollect`,
|
|
9196
9285
|
method: 'GET',
|
|
9197
|
-
|
|
9198
|
-
params: {
|
|
9199
|
-
client_key,
|
|
9200
|
-
wasm_md5,
|
|
9201
|
-
},
|
|
9286
|
+
params: { client_key, wasm_md5 },
|
|
9202
9287
|
});
|
|
9203
9288
|
}
|
|
9204
9289
|
|
|
9205
|
-
// /api/stark_wasm/v4/post/split
|
|
9206
9290
|
async function startSplit({ client_key, wasm_md5, }) {
|
|
9207
9291
|
return request({
|
|
9208
9292
|
url: `${BASE_URL}/api/stark_wasm/v4/post/split`,
|
|
9209
9293
|
method: 'POST',
|
|
9210
|
-
|
|
9211
|
-
...DEV_HEADERS,
|
|
9212
|
-
},
|
|
9213
|
-
data: {
|
|
9214
|
-
client_key,
|
|
9215
|
-
wasm_md5,
|
|
9216
|
-
},
|
|
9294
|
+
data: { client_key, wasm_md5 },
|
|
9217
9295
|
});
|
|
9218
9296
|
}
|
|
9219
9297
|
|
|
@@ -9383,7 +9461,8 @@ function pLimit(concurrency) {
|
|
|
9383
9461
|
return generator;
|
|
9384
9462
|
}
|
|
9385
9463
|
|
|
9386
|
-
|
|
9464
|
+
/** iOS 与 archive 互斥,二者只会存在其一 */
|
|
9465
|
+
function updateSubpackageConfigSync(options) {
|
|
9387
9466
|
const gameJsonPath = path__namespace.join(process.cwd(), SUBPACKAGE_CONFIG_FILE_NAME);
|
|
9388
9467
|
const raw = fs__namespace.readFileSync(gameJsonPath, 'utf-8');
|
|
9389
9468
|
const gameJson = JSON.parse(raw);
|
|
@@ -9396,11 +9475,17 @@ function updateSubpackageConfigSync() {
|
|
|
9396
9475
|
const filtered = subpackages.filter(s => s.name !== WASM_SPLIT_SUBPACKAGE_CONFIG.origin.name);
|
|
9397
9476
|
/**
|
|
9398
9477
|
* 基于 SUBPACKAGE_CONFIG_FILE_NAME 更新 subpackages
|
|
9478
|
+
* iOS 与 archive 互斥:有 archive 加 archive,否则有 iOS 加 iosMain+iosSub
|
|
9399
9479
|
*/
|
|
9400
9480
|
filtered.push(WASM_SPLIT_SUBPACKAGE_CONFIG.androidMain);
|
|
9401
9481
|
filtered.push(WASM_SPLIT_SUBPACKAGE_CONFIG.androidSub);
|
|
9402
|
-
|
|
9403
|
-
|
|
9482
|
+
if (options?.hasArchive) {
|
|
9483
|
+
filtered.push(WASM_SPLIT_SUBPACKAGE_CONFIG.archive);
|
|
9484
|
+
}
|
|
9485
|
+
else if (options?.hasIos) {
|
|
9486
|
+
filtered.push(WASM_SPLIT_SUBPACKAGE_CONFIG.iosMain);
|
|
9487
|
+
filtered.push(WASM_SPLIT_SUBPACKAGE_CONFIG.iosSub);
|
|
9488
|
+
}
|
|
9404
9489
|
// 合并去重:存在则更新 root,不存在则新增
|
|
9405
9490
|
const map = new Map(filtered.map(s => [s.name, s]));
|
|
9406
9491
|
gameJson[fieldName] = Array.from(map.values());
|
|
@@ -9452,12 +9537,28 @@ async function downloadSplited(context) {
|
|
|
9452
9537
|
ensureDirSync(splitTempDir);
|
|
9453
9538
|
const mainAndroidDir = path.join(splitTempDir, WASM_SPLIT_SUBPACKAGE_CONFIG.androidMain.root);
|
|
9454
9539
|
const subAndroidDir = path.join(splitTempDir, WASM_SPLIT_SUBPACKAGE_CONFIG.androidSub.root);
|
|
9455
|
-
|
|
9456
|
-
const
|
|
9457
|
-
|
|
9540
|
+
/** iOS 与 archive 互斥:有 archive 时 iOS URL 为空,反之亦然 */
|
|
9541
|
+
const hasArchive = Boolean(context.archive_wasm_download_url);
|
|
9542
|
+
const hasIos = !hasArchive && Boolean(context.main_wasm_h5_download_url);
|
|
9543
|
+
const archiveDir = hasArchive
|
|
9544
|
+
? path.join(splitTempDir, WASM_SPLIT_SUBPACKAGE_CONFIG.archive.root)
|
|
9545
|
+
: null;
|
|
9546
|
+
const mainIosDir = hasIos
|
|
9547
|
+
? path.join(splitTempDir, WASM_SPLIT_SUBPACKAGE_CONFIG.iosMain.root)
|
|
9548
|
+
: null;
|
|
9549
|
+
const subIosDir = hasIos
|
|
9550
|
+
? path.join(splitTempDir, WASM_SPLIT_SUBPACKAGE_CONFIG.iosSub.root)
|
|
9551
|
+
: null;
|
|
9552
|
+
const dirsToEnsure = [
|
|
9553
|
+
mainAndroidDir,
|
|
9554
|
+
subAndroidDir,
|
|
9555
|
+
...(archiveDir ? [archiveDir] : []),
|
|
9556
|
+
...(mainIosDir ? [mainIosDir] : []),
|
|
9557
|
+
...(subIosDir ? [subIosDir] : []),
|
|
9558
|
+
];
|
|
9559
|
+
dirsToEnsure.forEach(ensureDirSync);
|
|
9458
9560
|
const mainAndroidWasmCodeTempPath = path.join(mainAndroidDir, `${context.main_wasm_md5}${WASM_FILENAME_SUFFIX}`);
|
|
9459
9561
|
const subAndroidWasmCodeTempPath = path.join(subAndroidDir, `${context.sub_wasm_md5}${WASM_FILENAME_SUFFIX}`);
|
|
9460
|
-
const mainIosWasmCodeTempPath = path.join(mainIosDir, `${context.main_wasm_h5_md5}${WASM_FILENAME_SUFFIX}`);
|
|
9461
9562
|
const limit = pLimit(CONCURRENCY_LIMIT);
|
|
9462
9563
|
try {
|
|
9463
9564
|
console.log('downloadWasmSplit', context);
|
|
@@ -9468,7 +9569,6 @@ async function downloadSplited(context) {
|
|
|
9468
9569
|
wsServer.sendUnitySplitStatus({
|
|
9469
9570
|
status: 'start_download_android_sub_wasm_code',
|
|
9470
9571
|
});
|
|
9471
|
-
wsServer.sendUnitySplitStatus({ status: 'start_download_ios_main_wasm' });
|
|
9472
9572
|
/**
|
|
9473
9573
|
* 需要做个保护,只有 有 URL 时才下载
|
|
9474
9574
|
*/
|
|
@@ -9490,28 +9590,41 @@ async function downloadSplited(context) {
|
|
|
9490
9590
|
url: context.sub_wasm_download_url,
|
|
9491
9591
|
out: subAndroidWasmCodeTempPath,
|
|
9492
9592
|
})),
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9593
|
+
...(hasArchive && archiveDir && context.wasm_archive_md5
|
|
9594
|
+
? [
|
|
9595
|
+
limit(() => downloadAndCompress({
|
|
9596
|
+
startDownloadStatus: 'start_download_archive_wasm',
|
|
9597
|
+
downloadDoneStatus: 'download_archive_wasm_done',
|
|
9598
|
+
url: context.archive_wasm_download_url,
|
|
9599
|
+
out: path.join(archiveDir, `${context.wasm_archive_md5}${WASM_ARCHIVE_FILENAME_SUFFIX}`),
|
|
9600
|
+
})),
|
|
9601
|
+
]
|
|
9602
|
+
: []),
|
|
9603
|
+
// iOS 子包(与 archive 互斥,仅当 hasIos 时下载)
|
|
9604
|
+
...(hasIos && mainIosDir && subIosDir
|
|
9605
|
+
? [
|
|
9606
|
+
limit(() => downloadAndCompress({
|
|
9607
|
+
startDownloadStatus: 'start_download_ios_main_wasm',
|
|
9608
|
+
downloadDoneStatus: 'download_ios_main_wasm_done',
|
|
9609
|
+
startCompressStatus: 'start_compress_ios_main_wasm',
|
|
9610
|
+
compressDoneStatus: 'compress_ios_main_wasm_done',
|
|
9611
|
+
url: context.main_wasm_h5_download_url,
|
|
9612
|
+
out: path.join(mainIosDir, `${context.main_wasm_h5_md5}${WASM_FILENAME_SUFFIX}`),
|
|
9613
|
+
})),
|
|
9614
|
+
limit(() => downloadAndCompress({
|
|
9615
|
+
startDownloadStatus: 'start_download_ios_range_json',
|
|
9616
|
+
downloadDoneStatus: 'download_ios_range_json_done',
|
|
9617
|
+
url: context.sub_js_range_download_url,
|
|
9618
|
+
out: path.join(subIosDir, 'func_bytes_range.json'),
|
|
9619
|
+
})),
|
|
9620
|
+
limit(() => downloadAndCompress({
|
|
9621
|
+
startDownloadStatus: 'start_download_ios_js_data_br',
|
|
9622
|
+
downloadDoneStatus: 'download_ios_js_data_br_done',
|
|
9623
|
+
url: context.sub_js_data_download_url,
|
|
9624
|
+
out: path.join(subIosDir, 'subjs.data'),
|
|
9625
|
+
})),
|
|
9626
|
+
]
|
|
9627
|
+
: []),
|
|
9515
9628
|
]);
|
|
9516
9629
|
// 复制 split/* 到项目根目录(递归、覆盖)——避免 EISDIR
|
|
9517
9630
|
console.log('copy splitTempDir to root start');
|
|
@@ -9529,25 +9642,35 @@ async function downloadSplited(context) {
|
|
|
9529
9642
|
console.log('copy splitTempDir to root end');
|
|
9530
9643
|
// 更新分包配置(幂等)
|
|
9531
9644
|
console.log('updateSubpackageConfigSync start');
|
|
9532
|
-
updateSubpackageConfigSync(
|
|
9645
|
+
updateSubpackageConfigSync({
|
|
9646
|
+
hasArchive,
|
|
9647
|
+
hasIos,
|
|
9648
|
+
});
|
|
9533
9649
|
console.log('updateSubpackageConfigSync end');
|
|
9534
9650
|
// 更新 wasm split 配置(保持原始状态文案)
|
|
9535
9651
|
console.log('updateWasmSplitConfig start');
|
|
9536
9652
|
wsServer.sendUnitySplitStatus({ status: 'start_update_wasm_split_config' });
|
|
9537
|
-
|
|
9653
|
+
const wasmSplitConfigFields = {
|
|
9538
9654
|
ENABLEWASMCOLLECT: true,
|
|
9539
9655
|
ORIGINALWASMMD5: `${context.original_wasm_md5}`,
|
|
9540
9656
|
WASMTABLESIZE: context.table_size,
|
|
9541
9657
|
GLOBALVARLIST: JSON.stringify(context.global_var_list ?? []),
|
|
9542
|
-
SUBJSURL: `${context.sub_js_download_url}`,
|
|
9543
|
-
IOS_CODE_FILE_MD5: `${context.main_wasm_h5_md5}`,
|
|
9544
9658
|
ANDROID_CODE_FILE_MD5: `${context.main_wasm_md5}`,
|
|
9545
9659
|
ANDROID_SUB_CODE_FILE_MD5: `${context.sub_wasm_md5}`,
|
|
9546
9660
|
WASMSPLITVERSION: `${context.version}`,
|
|
9547
|
-
USINGWASMH5: Boolean(context.main_wasm_h5_md5),
|
|
9548
9661
|
ENABLEWASMSPLIT: true,
|
|
9549
|
-
|
|
9550
|
-
|
|
9662
|
+
};
|
|
9663
|
+
// iOS 与 archive 互斥:走 iOS 时写入 iOS 相关字段,走 archive 时写入 archive 相关字段
|
|
9664
|
+
if (hasIos) {
|
|
9665
|
+
wasmSplitConfigFields.IOS_CODE_FILE_MD5 = `${context.main_wasm_h5_md5}`;
|
|
9666
|
+
wasmSplitConfigFields.USINGWASMH5 = true;
|
|
9667
|
+
wasmSplitConfigFields.SUBJSURL = `${context.sub_js_download_url ?? ''}`;
|
|
9668
|
+
}
|
|
9669
|
+
if (hasArchive && context.wasm_archive_md5) {
|
|
9670
|
+
wasmSplitConfigFields.ARCHIVE_CODE_FILE_MD5 = `${context.wasm_archive_md5}`;
|
|
9671
|
+
wasmSplitConfigFields.enableArchiveMode = true;
|
|
9672
|
+
}
|
|
9673
|
+
updateWasmSplitConfig(wasmSplitConfigFields);
|
|
9551
9674
|
wsServer.sendUnitySplitStatus({ status: 'update_wasm_split_config_done' });
|
|
9552
9675
|
console.log('updateWasmSplitConfig end');
|
|
9553
9676
|
return {
|
|
@@ -9590,7 +9713,6 @@ async function getSplitResult({ client_key, wasm_md5, wasm_path, }) {
|
|
|
9590
9713
|
return request({
|
|
9591
9714
|
url: `${BASE_URL}/api/stark_wasm/v4/post/download`,
|
|
9592
9715
|
method: 'POST',
|
|
9593
|
-
headers: { ...DEV_HEADERS },
|
|
9594
9716
|
data: { client_key, wasm_md5, wasm_path },
|
|
9595
9717
|
});
|
|
9596
9718
|
}
|
|
@@ -9636,13 +9758,7 @@ async function resetWasmSplit(data) {
|
|
|
9636
9758
|
const res = await request({
|
|
9637
9759
|
url: `${BASE_URL}/api/stark_wasm/v4/post/reset`,
|
|
9638
9760
|
method: 'POST',
|
|
9639
|
-
|
|
9640
|
-
...DEV_HEADERS,
|
|
9641
|
-
},
|
|
9642
|
-
data: {
|
|
9643
|
-
client_key: data.clientkey,
|
|
9644
|
-
wasm_md5: data.wasmMd5,
|
|
9645
|
-
},
|
|
9761
|
+
data: { client_key: data.clientkey, wasm_md5: data.wasmMd5 },
|
|
9646
9762
|
});
|
|
9647
9763
|
/**
|
|
9648
9764
|
* 把— __TTMG_TEMP__/wasmcode/ 目录下的所有文件恢复到原本的位置,进行重置
|
|
@@ -9694,9 +9810,17 @@ async function resetWasmSplit(data) {
|
|
|
9694
9810
|
if (fs.existsSync(androidSubpackageSubDir)) {
|
|
9695
9811
|
fs.rmSync(androidSubpackageSubDir, { recursive: true });
|
|
9696
9812
|
}
|
|
9697
|
-
const
|
|
9698
|
-
if (fs.existsSync(
|
|
9699
|
-
fs.rmSync(
|
|
9813
|
+
const archiveSubpackageDir = path.join(process.cwd(), WASM_SPLIT_SUBPACKAGE_CONFIG.archive.root);
|
|
9814
|
+
if (fs.existsSync(archiveSubpackageDir)) {
|
|
9815
|
+
fs.rmSync(archiveSubpackageDir, { recursive: true });
|
|
9816
|
+
}
|
|
9817
|
+
const iosMainDir = path.join(process.cwd(), WASM_SPLIT_SUBPACKAGE_CONFIG.iosMain.root);
|
|
9818
|
+
if (fs.existsSync(iosMainDir)) {
|
|
9819
|
+
fs.rmSync(iosMainDir, { recursive: true });
|
|
9820
|
+
}
|
|
9821
|
+
const iosSubDir = path.join(process.cwd(), WASM_SPLIT_SUBPACKAGE_CONFIG.iosSub.root);
|
|
9822
|
+
if (fs.existsSync(iosSubDir)) {
|
|
9823
|
+
fs.rmSync(iosSubDir, { recursive: true });
|
|
9700
9824
|
}
|
|
9701
9825
|
return res;
|
|
9702
9826
|
}
|
|
@@ -9737,7 +9861,6 @@ const getTaskStatus = (params) => {
|
|
|
9737
9861
|
return request({
|
|
9738
9862
|
url: `${BASE_URL}/api/stark_wasm/v4/get/status`,
|
|
9739
9863
|
method: 'GET',
|
|
9740
|
-
headers: DEV_HEADERS,
|
|
9741
9864
|
params,
|
|
9742
9865
|
});
|
|
9743
9866
|
};
|
|
@@ -9746,7 +9869,6 @@ const getTaskInfo = async (params) => {
|
|
|
9746
9869
|
return request({
|
|
9747
9870
|
url: `${BASE_URL}/api/stark_wasm/v4/get/taskinfo`,
|
|
9748
9871
|
method: 'GET',
|
|
9749
|
-
headers: DEV_HEADERS,
|
|
9750
9872
|
params,
|
|
9751
9873
|
});
|
|
9752
9874
|
};
|
|
@@ -9963,13 +10085,12 @@ const gameWasmSplitDownloadResultRoute = {
|
|
|
9963
10085
|
}
|
|
9964
10086
|
else {
|
|
9965
10087
|
const splitResult = (response.data?.result || {});
|
|
10088
|
+
// iOS 与 archive 互斥:有 archive 时校验 archive 字段,否则校验 iOS 字段
|
|
10089
|
+
const hasArchive = typeof splitResult.archive_wasm_download_url === 'string' && String(splitResult.archive_wasm_download_url).trim() !== '';
|
|
9966
10090
|
const requiredDownloadFields = [
|
|
9967
10091
|
'main_wasm_download_url',
|
|
9968
|
-
'
|
|
9969
|
-
|
|
9970
|
-
// 'sub_js_download_url',
|
|
9971
|
-
// 'sub_js_data_download_url',
|
|
9972
|
-
// 'sub_js_range_download_url',
|
|
10092
|
+
'sub_wasm_download_url',
|
|
10093
|
+
...(hasArchive ? ['archive_wasm_download_url'] : ['main_wasm_h5_download_url']),
|
|
9973
10094
|
];
|
|
9974
10095
|
const missingFields = requiredDownloadFields.filter(field => {
|
|
9975
10096
|
const value = splitResult[field];
|
|
@@ -10643,7 +10764,7 @@ async function upload({ clientKey, note = '--', dir, }) {
|
|
|
10643
10764
|
}
|
|
10644
10765
|
}
|
|
10645
10766
|
|
|
10646
|
-
var version = "0.3.
|
|
10767
|
+
var version = "0.3.5-beta.1";
|
|
10647
10768
|
var pkg = {
|
|
10648
10769
|
version: version};
|
|
10649
10770
|
|