mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-06-03 09:04:40 -04:00
Update to latest version of storage which fixes issue where an HTML 404 page was being returned for missing asset data. Update VM to handle null assets properly.
This commit is contained in:
parent
2481f28191
commit
11f938f8a9
8 changed files with 48 additions and 27 deletions
32
package-lock.json
generated
32
package-lock.json
generated
|
@ -15763,6 +15763,32 @@
|
||||||
"scratch-storage": "^1.0.0",
|
"scratch-storage": "^1.0.0",
|
||||||
"scratch-svg-renderer": "0.2.0-prerelease.20210727023023",
|
"scratch-svg-renderer": "0.2.0-prerelease.20210727023023",
|
||||||
"twgl.js": "4.4.0"
|
"twgl.js": "4.4.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"scratch-storage": {
|
||||||
|
"version": "1.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-1.3.6.tgz",
|
||||||
|
"integrity": "sha512-L/7z7SB7cGANsgjyiE+qZNaPEqFHK1yPbNomizkgN3WHGcKRogLvmheR57kOxHNpQzodUTbG+pVVH6fR2ZY1Sg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"arraybuffer-loader": "^1.0.3",
|
||||||
|
"base64-js": "1.3.0",
|
||||||
|
"fastestsmallesttextencoderdecoder": "^1.0.7",
|
||||||
|
"js-md5": "0.7.3",
|
||||||
|
"minilog": "3.1.0",
|
||||||
|
"worker-loader": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"worker-loader": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"loader-utils": "^1.0.0",
|
||||||
|
"schema-utils": "^0.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scratch-render-fonts": {
|
"scratch-render-fonts": {
|
||||||
|
@ -15785,9 +15811,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scratch-storage": {
|
"scratch-storage": {
|
||||||
"version": "1.3.6",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-1.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-2.0.0.tgz",
|
||||||
"integrity": "sha512-L/7z7SB7cGANsgjyiE+qZNaPEqFHK1yPbNomizkgN3WHGcKRogLvmheR57kOxHNpQzodUTbG+pVVH6fR2ZY1Sg==",
|
"integrity": "sha512-eLqI5bBWTS1d43BY3zSzJYerBfdwa2l5myLD+IASkGN8eBJtW+/CDsKQC0FtI6xV9Afb7req9eeikHlPYczIuw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"arraybuffer-loader": "^1.0.3",
|
"arraybuffer-loader": "^1.0.3",
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
"scratch-l10n": "3.14.20220510031559",
|
"scratch-l10n": "3.14.20220510031559",
|
||||||
"scratch-render": "0.1.0-prerelease.20211028200436",
|
"scratch-render": "0.1.0-prerelease.20211028200436",
|
||||||
"scratch-render-fonts": "1.0.0-prerelease.20210401210003",
|
"scratch-render-fonts": "1.0.0-prerelease.20210401210003",
|
||||||
"scratch-storage": "1.3.6",
|
"scratch-storage": "2.0.0",
|
||||||
"scratch-svg-renderer": "0.2.0-prerelease.20210727023023",
|
"scratch-svg-renderer": "0.2.0-prerelease.20210727023023",
|
||||||
"script-loader": "0.7.2",
|
"script-loader": "0.7.2",
|
||||||
"stats.js": "0.17.0",
|
"stats.js": "0.17.0",
|
||||||
|
|
|
@ -302,7 +302,7 @@ const loadCostumeFromAsset = function (costume, runtime, optVersion) {
|
||||||
costume.assetId = costume.asset.assetId;
|
costume.assetId = costume.asset.assetId;
|
||||||
const renderer = runtime.renderer;
|
const renderer = runtime.renderer;
|
||||||
if (!renderer) {
|
if (!renderer) {
|
||||||
log.error('No rendering module present; cannot load costume: ', costume.name);
|
log.warn('No rendering module present; cannot load costume: ', costume.name);
|
||||||
return Promise.resolve(costume);
|
return Promise.resolve(costume);
|
||||||
}
|
}
|
||||||
const AssetType = runtime.storage.AssetType;
|
const AssetType = runtime.storage.AssetType;
|
||||||
|
@ -352,12 +352,12 @@ const loadCostume = function (md5ext, costume, runtime, optVersion) {
|
||||||
|
|
||||||
// Need to load the costume from storage. The server should have a reference to this md5.
|
// Need to load the costume from storage. The server should have a reference to this md5.
|
||||||
if (!runtime.storage) {
|
if (!runtime.storage) {
|
||||||
log.error('No storage module present; cannot load costume asset: ', md5ext);
|
log.warn('No storage module present; cannot load costume asset: ', md5ext);
|
||||||
return Promise.resolve(costume);
|
return Promise.resolve(costume);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!runtime.storage.defaultAssetId) {
|
if (!runtime.storage.defaultAssetId) {
|
||||||
log.error(`No default assets found`);
|
log.warn(`No default assets found`);
|
||||||
return Promise.resolve(costume);
|
return Promise.resolve(costume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ const log = require('../util/log');
|
||||||
const loadSoundFromAsset = function (sound, soundAsset, runtime, soundBank) {
|
const loadSoundFromAsset = function (sound, soundAsset, runtime, soundBank) {
|
||||||
sound.assetId = soundAsset.assetId;
|
sound.assetId = soundAsset.assetId;
|
||||||
if (!runtime.audioEngine) {
|
if (!runtime.audioEngine) {
|
||||||
log.error('No audio engine present; cannot load sound asset: ', sound.md5);
|
log.warn('No audio engine present; cannot load sound asset: ', sound.md5);
|
||||||
return Promise.resolve(sound);
|
return Promise.resolve(sound);
|
||||||
}
|
}
|
||||||
return runtime.audioEngine.decodeSoundPlayer(Object.assign(
|
return runtime.audioEngine.decodeSoundPlayer(Object.assign(
|
||||||
|
@ -49,7 +49,7 @@ const loadSoundFromAsset = function (sound, soundAsset, runtime, soundBank) {
|
||||||
*/
|
*/
|
||||||
const loadSound = function (sound, runtime, soundBank) {
|
const loadSound = function (sound, runtime, soundBank) {
|
||||||
if (!runtime.storage) {
|
if (!runtime.storage) {
|
||||||
log.error('No storage module present; cannot load sound asset: ', sound.md5);
|
log.warn('No storage module present; cannot load sound asset: ', sound.md5);
|
||||||
return Promise.resolve(sound);
|
return Promise.resolve(sound);
|
||||||
}
|
}
|
||||||
const idParts = StringUtil.splitFirst(sound.md5, '.');
|
const idParts = StringUtil.splitFirst(sound.md5, '.');
|
||||||
|
@ -60,6 +60,12 @@ const loadSound = function (sound, runtime, soundBank) {
|
||||||
(sound.asset && Promise.resolve(sound.asset)) ||
|
(sound.asset && Promise.resolve(sound.asset)) ||
|
||||||
runtime.storage.load(runtime.storage.AssetType.Sound, md5, ext)
|
runtime.storage.load(runtime.storage.AssetType.Sound, md5, ext)
|
||||||
).then(soundAsset => {
|
).then(soundAsset => {
|
||||||
|
if (!soundAsset) {
|
||||||
|
log.warn('Failed to find sound data: ', sound);
|
||||||
|
// TODO add missing sound error handling that adds the "gray question sound"
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
sound.asset = soundAsset;
|
sound.asset = soundAsset;
|
||||||
return loadSoundFromAsset(sound, soundAsset, runtime, soundBank);
|
return loadSoundFromAsset(sound, soundAsset, runtime, soundBank);
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ const deserializeSound = function (sound, runtime, zip, assetFileName) {
|
||||||
const fileName = assetFileName ? assetFileName : sound.md5;
|
const fileName = assetFileName ? assetFileName : sound.md5;
|
||||||
const storage = runtime.storage;
|
const storage = runtime.storage;
|
||||||
if (!storage) {
|
if (!storage) {
|
||||||
log.error('No storage module present; cannot load sound asset: ', fileName);
|
log.warn('No storage module present; cannot load sound asset: ', fileName);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ const deserializeCostume = function (costume, runtime, zip, assetFileName, textL
|
||||||
`${assetId}.${costume.dataFormat}`;
|
`${assetId}.${costume.dataFormat}`;
|
||||||
|
|
||||||
if (!storage) {
|
if (!storage) {
|
||||||
log.error('No storage module present; cannot load costume asset: ', fileName);
|
log.warn('No storage module present; cannot load costume asset: ', fileName);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -366,7 +366,9 @@ class VirtualMachine extends EventEmitter {
|
||||||
const vm = this;
|
const vm = this;
|
||||||
const promise = storage.load(storage.AssetType.Project, id);
|
const promise = storage.load(storage.AssetType.Project, id);
|
||||||
promise.then(projectAsset => {
|
promise.then(projectAsset => {
|
||||||
vm.loadProject(projectAsset.data);
|
if (projectAsset) {
|
||||||
|
return vm.loadProject(projectAsset.data);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,13 +23,6 @@ let vm;
|
||||||
|
|
||||||
tap.beforeEach(() => {
|
tap.beforeEach(() => {
|
||||||
const storage = makeTestStorage();
|
const storage = makeTestStorage();
|
||||||
|
|
||||||
// This line removes the webhelper from the list of available helpers.
|
|
||||||
// W/o the following line, this fails because storage doesn't handle the case
|
|
||||||
// where none of the tools have isGetSupported: true
|
|
||||||
// TODO: Remove this line when the related storage bug is resolved so that
|
|
||||||
// storage gracefully handles non-browser situations where assets are missing.
|
|
||||||
storage._helpers = [storage._helpers[0]];
|
|
||||||
|
|
||||||
vm = new VirtualMachine();
|
vm = new VirtualMachine();
|
||||||
vm.attachStorage(storage);
|
vm.attachStorage(storage);
|
||||||
|
@ -88,8 +81,8 @@ test('load and then save sb3 project with missing costume file', t => {
|
||||||
|
|
||||||
test('serializeCostume does not save data for missing costume', t => {
|
test('serializeCostume does not save data for missing costume', t => {
|
||||||
const costumeDescs = serializeCostumes(vm.runtime);
|
const costumeDescs = serializeCostumes(vm.runtime);
|
||||||
|
|
||||||
t.equal(costumeDescs.length, 1); // Should only have one costume, the backdrop
|
t.equal(costumeDescs.length, 1); // Should only have one costume, the backdrop
|
||||||
|
|
||||||
t.not(costumeDescs[0].fileName, `${missingCostumeAssetId}.svg`);
|
t.not(costumeDescs[0].fileName, `${missingCostumeAssetId}.svg`);
|
||||||
|
|
||||||
t.end();
|
t.end();
|
||||||
|
|
|
@ -27,13 +27,6 @@ let vm;
|
||||||
|
|
||||||
tap.beforeEach(() => {
|
tap.beforeEach(() => {
|
||||||
const storage = makeTestStorage();
|
const storage = makeTestStorage();
|
||||||
|
|
||||||
// This line removes the webhelper from the list of available helpers.
|
|
||||||
// W/o the following line, this fails because storage doesn't handle the case
|
|
||||||
// where none of the tools have isGetSupported: true
|
|
||||||
// TODO: Remove this line when the related storage bug is resolved so that
|
|
||||||
// storage gracefully handles non-browser situations where assets are missing.
|
|
||||||
storage._helpers = [storage._helpers[0]];
|
|
||||||
|
|
||||||
vm = new VirtualMachine();
|
vm = new VirtualMachine();
|
||||||
vm.attachStorage(storage);
|
vm.attachStorage(storage);
|
||||||
|
@ -86,6 +79,7 @@ test('load and then save sprite3 with missing vector costume file', t => {
|
||||||
|
|
||||||
test('serializeCostume does not save data for missing costume', t => {
|
test('serializeCostume does not save data for missing costume', t => {
|
||||||
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
|
const costumeDescs = serializeCostumes(vm.runtime, vm.runtime.targets[2].id);
|
||||||
|
|
||||||
t.equal(costumeDescs.length, 0);
|
t.equal(costumeDescs.length, 0);
|
||||||
|
|
||||||
t.end();
|
t.end();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue