MatchMaster/packages/cloud-rise-package/runtime.js
2026-09-24 16:50:43 +08:00

90 lines
4.9 KiB
JavaScript

'use strict';
// Check one shared version; Creator caches each requested file by its versioned URL.
const config = require('./cloud-rise-package-config');
const names = ['matching', 'stage1', 'stage2', 'stage3', 'art'];
const cacheKey = 'cloud_rise_bundle_version_v2';
const downloader = cc.assetManager.downloader, original = downloader._downloaders.bundle;
let versionTask = null, selectedVersion = '';
const isVersion = value => typeof value === 'string' && value.length <= 32 && /^\d+\.\d+\.\d+$/.test(value);
const warn = (message, error) => console.warn('[cloud-rise-package] ' + message, error && (error.message || error.errMsg) || '');
function readCacheState() {
try { return JSON.parse(cc.sys.localStorage.getItem(cacheKey)) || {}; } catch (_) { return {}; }
}
function remember(version) {
try { cc.sys.localStorage.setItem(cacheKey, JSON.stringify({ version, baseUrl: config.baseUrl })); }
catch (error) { warn('Cannot persist selected version', error); }
}
function selectVersion() {
if (versionTask) return versionTask;
if (!/^https:\/\/[^\s?#]+\/$/.test(config.baseUrl)) {
return Promise.reject(new Error('Invalid Cloud Rise resource address'));
}
const previous = readCacheState();
const fallback = previous.baseUrl === config.baseUrl && isVersion(previous.version) ? previous.version : '';
versionTask = new Promise((resolve, reject) => {
let finished = false, request;
const finish = (error, version) => {
if (finished) return;
finished = true; clearTimeout(timer);
if (error && !fallback) { reject(error); return; }
if (error) warn('Version check failed; using cached version ' + fallback, error);
// Same version reuses the same cache keys; a changed version cannot hit old entries.
selectedVersion = version || fallback;
resolve(selectedVersion);
};
const timer = setTimeout(() => {
finish(new Error('Version check timed out'));
if (request && request.abort) request.abort();
}, 5000);
try {
request = wx.request({
url: config.baseUrl + 'version.json?_t=' + Date.now(), timeout: 5000,
header: { 'Cache-Control': 'no-cache' },
success: response => {
try {
if (response.statusCode !== 200) throw new Error('Version HTTP ' + response.statusCode);
const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
if (!data || !isVersion(data.version)) throw new Error('Invalid Cloud Rise version');
finish(null, data.version);
} catch (error) { finish(error); }
},
fail: error => finish(error)
});
} catch (error) { finish(error); }
}).catch(error => { versionTask = null; throw error; });
return versionTask;
}
window.__prepareCloudRiseVersion = selectVersion;
function resourceUrl(url) {
const owned = names.some(name => url.startsWith(config.baseUrl + name + '/'));
if (!selectedVersion || !owned) return url;
return url + (url.includes('?') ? '&' : '?') + 'v=' + selectedVersion;
}
// Include packed import JSON as well as images/native files, without changing other games' URLs.
Object.keys(downloader._downloaders).filter(type => type !== 'bundle').forEach(type => {
const handler = downloader._downloaders[type];
downloader.register(type, (url, options, done) => {
const versioned = resourceUrl(url);
handler(versioned, versioned === url ? options : Object.assign({}, options, { cacheEnabled: true }), done);
});
});
downloader.register('bundle', function (nameOrUrl, options, onComplete) {
// Only redirect the five named bundles. Explicit URLs and other gameplay keep the engine loader.
if (!names.includes(nameOrUrl)) return original(nameOrUrl, options, onComplete);
selectVersion().then(version => {
const base = config.baseUrl + nameOrUrl + '/', url = base + 'config.json';
__cocos_require__('src/scripts/' + nameOrUrl + '/index.js');
const cache = cc.assetManager.cacheManager;
cache.makeBundleFolder(nameOrUrl);
downloader._downloaders['.json'](url, Object.assign({}, options, { __cacheBundleRoot__: nameOrUrl, cacheEnabled: true }), (error, data) => {
if (!error && (!data || data.name !== nameOrUrl || data.isZip || data.cloudRiseVersion !== version)) {
error = new Error('Cloud Rise bundle version mismatch: ' + nameOrUrl);
const key = resourceUrl(url);
delete cache.cacheQueue[key]; cache.tempFiles.remove(key); cache.removeCache(key);
}
if (!error) { data.base = base; remember(version); }
onComplete(error, data);
});
}).catch(error => onComplete(error));
});