90 lines
4.9 KiB
JavaScript
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));
|
|
});
|