From 0623ee0bf2ebb8cb1f4b4277aad3d1373d2050f9 Mon Sep 17 00:00:00 2001 From: kharhamel Date: Mon, 21 Jun 2021 11:44:18 +0200 Subject: [PATCH] HOTFIX: loading errors after the preload stage should not crash the game anymore --- .../Entity/PlayerTexturesLoadingManager.ts | 22 ++++++++++++++++--- front/src/Phaser/Game/GameScene.ts | 16 +++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts index 95f00a9e..eaba79aa 100644 --- a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts +++ b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts @@ -59,9 +59,11 @@ export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, textur } else { returnPromise = Promise.resolve(texturekeys); } + + //If the loading fail, we render the default model instead. return returnPromise.then((keys) => keys.map((key) => { return typeof key !== 'string' ? key.name : key; - })) + })).catch(() => lazyLoadPlayerCharacterTextures(loadPlugin, ["color_22", "eyes_23"])); } export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptionInterface): BodyResourceDescriptionInterface => { @@ -80,11 +82,25 @@ export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptio } export const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface, frameConfig: FrameConfig) => { - return new Promise((res) => { + return new Promise((res, rej) => { + console.log('count', loadPlugin.listenerCount('loaderror')); if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) { return res(playerResourceDescriptor); } loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, frameConfig); - loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor)); + const errorCallback = (file: {src: string}) => { + if (file.src !== playerResourceDescriptor.img) return; + console.error('failed loading player ressource: ', playerResourceDescriptor) + rej(playerResourceDescriptor); + loadPlugin.off('filecomplete-spritesheet-' + playerResourceDescriptor.name, successCallback); + loadPlugin.off('loaderror', errorCallback); + } + const successCallback = () => { + loadPlugin.off('loaderror', errorCallback); + res(playerResourceDescriptor); + } + + loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, successCallback); + loadPlugin.on('loaderror', errorCallback); }); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 72279c61..62d66c30 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -192,6 +192,7 @@ export class GameScene extends DirtyScene implements CenterListener { private pinchManager: PinchManager|undefined; private mapTransitioning: boolean = false; //used to prevent transitions happenning at the same time. private emoteManager!: EmoteManager; + private preloading: boolean = true; constructor(private room: Room, MapUrlFile: string, customKey?: string|undefined) { super({ @@ -259,11 +260,15 @@ export class GameScene extends DirtyScene implements CenterListener { return; } - this.scene.start(ErrorSceneName, { - title: 'Network error', - subTitle: 'An error occurred while loading resource:', - message: this.originalMapUrl ?? file.src - }); + //once preloading is over, we don't want loading errors to crash the game, so we need to disable this behavior after preloading. + console.error('Error when loading: ', file); + if (this.preloading) { + this.scene.start(ErrorSceneName, { + title: 'Network error', + subTitle: 'An error occurred while loading resource:', + message: this.originalMapUrl ?? file.src + }); + } }); this.load.on('filecomplete-tilemapJSON-'+this.MapUrlFile, (key: string, type: string, data: unknown) => { this.onMapLoad(data); @@ -388,6 +393,7 @@ export class GameScene extends DirtyScene implements CenterListener { //hook create scene create(): void { + this.preloading = false; this.trackDirtyAnims(); gameManager.gameSceneIsCreated(this);