From 9c4d0aa32ffcd02ca336a96a46da3bf38dec75fc Mon Sep 17 00:00:00 2001 From: Mickael Chimansky Date: Tue, 9 Feb 2021 14:17:48 +0100 Subject: [PATCH 1/8] Jitsi config properties --- front/src/Phaser/Game/GameScene.ts | 8 +++++- front/src/WebRtc/JitsiFactory.ts | 43 +++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 5ed2db87..4c07be26 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -669,11 +669,17 @@ export class GameScene extends ResizableScene implements CenterListener { this.connection.emitQueryJitsiJwtMessage(this.instance.replace('/', '-') + "-" + newValue, adminTag); } else { + const jitsiConfig = allProps.get("jitsiConfig") as string|undefined; + jitsiFactory.setJitsiConfig(jitsiConfig || undefined); + + const jitsiInterfaceConfig = allProps.get("jitsiInterfaceConfig") as string|undefined; + jitsiFactory.setJitsiInterfaceConfig(jitsiInterfaceConfig || undefined); + this.startJitsi(newValue as string); } layoutManager.removeActionButton('jitsiRoom', this.userInputManager); } - + const jitsiTriggerValue = allProps.get(TRIGGER_JITSI_PROPERTIES); if(jitsiTriggerValue && jitsiTriggerValue === ON_ACTION_TRIGGER_BUTTON) { layoutManager.addActionButton('jitsiRoom', 'Click on SPACE to enter in jitsi meet room', () => { diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index 736b5244..0763271a 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -3,6 +3,12 @@ import {mediaManager} from "./MediaManager"; import {coWebsiteManager} from "./CoWebsiteManager"; declare const window:any; // eslint-disable-line @typescript-eslint/no-explicit-any +const config = { + startWithAudioMuted: !mediaManager.constraintsMedia.audio, + startWithVideoMuted: mediaManager.constraintsMedia.video === false, + prejoinPageEnabled: false +} + const interfaceConfig = { SHOW_CHROME_EXTENSION_BANNER: false, MOBILE_APP_PROMO: false, @@ -26,6 +32,8 @@ const interfaceConfig = { }; class JitsiFactory { + public jitsiConfig: object = config; + public jitsiInterfaceConfig: object = interfaceConfig; private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any private audioCallback = this.onAudioChange.bind(this); private videoCallback = this.onVideoChange.bind(this); @@ -39,12 +47,8 @@ class JitsiFactory { width: "100%", height: "100%", parentNode: cowebsiteDiv, - configOverwrite: { - startWithAudioMuted: !mediaManager.constraintsMedia.audio, - startWithVideoMuted: mediaManager.constraintsMedia.video === false, - prejoinPageEnabled: false - }, - interfaceConfigOverwrite: interfaceConfig, + configOverwrite: this.jitsiConfig, + interfaceConfigOverwrite: this.jitsiInterfaceConfig }; if (!options.jwt) { delete options.jwt; @@ -88,6 +92,33 @@ class JitsiFactory { } } + public setJitsiConfig(jitsiConfig: string|undefined): void { + if(jitsiConfig) { + try { + const parsedConfig = JSON.parse(jitsiConfig); + this.jitsiConfig = {...config, ...parsedConfig}; + } catch (e) { + console.warn('jitsiConfig', e); + this.jitsiConfig = config; + } + } else { + this.jitsiConfig = config; + } + } + + public setJitsiInterfaceConfig(jitsiInterfaceConfig: string|undefined): void { + if(jitsiInterfaceConfig) { + try { + const parsedInterfaceConfig = JSON.parse(jitsiInterfaceConfig); + this.jitsiInterfaceConfig = {...interfaceConfig, ...parsedInterfaceConfig}; + } catch (e) { + console.warn('jitsiInterfaceConfig', e); + this.jitsiInterfaceConfig = interfaceConfig; + } + } else { + this.jitsiInterfaceConfig = interfaceConfig; + } + } } export const jitsiFactory = new JitsiFactory(); \ No newline at end of file From 5cb9624b0bf23a2c33721f35f349a6db7ff9cc3d Mon Sep 17 00:00:00 2001 From: Mickael Chimansky Date: Tue, 9 Feb 2021 20:31:49 +0100 Subject: [PATCH 2/8] fixup! Jitsi config properties --- front/src/Phaser/Game/GameScene.ts | 24 +++++++++++------- front/src/WebRtc/JitsiFactory.ts | 40 ++++-------------------------- 2 files changed, 20 insertions(+), 44 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 4c07be26..000fffaf 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -631,6 +631,15 @@ export class GameScene extends ResizableScene implements CenterListener { } } + private safeParseJSONstring(jsonString: string|undefined) { + try { + return jsonString ? JSON.parse(jsonString) : {}; + } catch(e) { + console.warn(jsonString, e); + return {} + } + } + private triggerOnMapLayerPropertyChange(){ this.gameMap.onPropertyChange('exitSceneUrl', (newValue, oldValue) => { if (newValue) this.onMapExit(newValue as string); @@ -669,13 +678,10 @@ export class GameScene extends ResizableScene implements CenterListener { this.connection.emitQueryJitsiJwtMessage(this.instance.replace('/', '-') + "-" + newValue, adminTag); } else { - const jitsiConfig = allProps.get("jitsiConfig") as string|undefined; - jitsiFactory.setJitsiConfig(jitsiConfig || undefined); - - const jitsiInterfaceConfig = allProps.get("jitsiInterfaceConfig") as string|undefined; - jitsiFactory.setJitsiInterfaceConfig(jitsiInterfaceConfig || undefined); - - this.startJitsi(newValue as string); + const jitsiConfig = this.safeParseJSONstring(allProps.get("jitsiConfig") as string|undefined); + const jitsiInterfaceConfig = this.safeParseJSONstring(allProps.get("jitsiInterfaceConfig") as string|undefined); + + this.startJitsi(newValue as string, undefined, jitsiConfig, jitsiInterfaceConfig); } layoutManager.removeActionButton('jitsiRoom', this.userInputManager); } @@ -1234,8 +1240,8 @@ export class GameScene extends ResizableScene implements CenterListener { this.updateCameraOffset(); } - public startJitsi(roomName: string, jwt?: string): void { - jitsiFactory.start(roomName, this.playerName, jwt); + public startJitsi(roomName: string, jwt?: string, config: object = {}, interfaceConfig: object = {}): void { + jitsiFactory.start(roomName, this.playerName, jwt, config, interfaceConfig); this.connection.setSilent(true); mediaManager.hideGameOverlay(); diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index 0763271a..4d4d9f64 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -3,13 +3,13 @@ import {mediaManager} from "./MediaManager"; import {coWebsiteManager} from "./CoWebsiteManager"; declare const window:any; // eslint-disable-line @typescript-eslint/no-explicit-any -const config = { +const defaultConfig = { startWithAudioMuted: !mediaManager.constraintsMedia.audio, startWithVideoMuted: mediaManager.constraintsMedia.video === false, prejoinPageEnabled: false } -const interfaceConfig = { +const defaultInterfaceConfig = { SHOW_CHROME_EXTENSION_BANNER: false, MOBILE_APP_PROMO: false, @@ -32,13 +32,11 @@ const interfaceConfig = { }; class JitsiFactory { - public jitsiConfig: object = config; - public jitsiInterfaceConfig: object = interfaceConfig; private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any private audioCallback = this.onAudioChange.bind(this); private videoCallback = this.onVideoChange.bind(this); - public start(roomName: string, playerName:string, jwt?: string): void { + public start(roomName: string, playerName:string, jwt?: string, config?: object, interfaceConfig?: object): void { coWebsiteManager.insertCoWebsite((cowebsiteDiv => { const domain = JITSI_URL; const options: any = { // eslint-disable-line @typescript-eslint/no-explicit-any @@ -47,8 +45,8 @@ class JitsiFactory { width: "100%", height: "100%", parentNode: cowebsiteDiv, - configOverwrite: this.jitsiConfig, - interfaceConfigOverwrite: this.jitsiInterfaceConfig + configOverwrite: {...defaultConfig, ...config}, + interfaceConfigOverwrite: {...defaultInterfaceConfig, ...interfaceConfig} }; if (!options.jwt) { delete options.jwt; @@ -91,34 +89,6 @@ class JitsiFactory { mediaManager.enableCamera(); } } - - public setJitsiConfig(jitsiConfig: string|undefined): void { - if(jitsiConfig) { - try { - const parsedConfig = JSON.parse(jitsiConfig); - this.jitsiConfig = {...config, ...parsedConfig}; - } catch (e) { - console.warn('jitsiConfig', e); - this.jitsiConfig = config; - } - } else { - this.jitsiConfig = config; - } - } - - public setJitsiInterfaceConfig(jitsiInterfaceConfig: string|undefined): void { - if(jitsiInterfaceConfig) { - try { - const parsedInterfaceConfig = JSON.parse(jitsiInterfaceConfig); - this.jitsiInterfaceConfig = {...interfaceConfig, ...parsedInterfaceConfig}; - } catch (e) { - console.warn('jitsiInterfaceConfig', e); - this.jitsiInterfaceConfig = interfaceConfig; - } - } else { - this.jitsiInterfaceConfig = interfaceConfig; - } - } } export const jitsiFactory = new JitsiFactory(); \ No newline at end of file From a5bdf68246d532ecad3bc446ae5c40e4c3f08ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 10 Feb 2021 11:08:57 +0100 Subject: [PATCH 3/8] Moving property reading inside startJitsi (startJitsi is called at 2 different places) --- front/src/Phaser/Game/GameMap.ts | 4 ++++ front/src/Phaser/Game/GameScene.ts | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/front/src/Phaser/Game/GameMap.ts b/front/src/Phaser/Game/GameMap.ts index 9f3157a0..12da0514 100644 --- a/front/src/Phaser/Game/GameMap.ts +++ b/front/src/Phaser/Game/GameMap.ts @@ -49,6 +49,10 @@ export class GameMap { this.lastProperties = newProps; } + public getCurrentProperties(): Map { + return this.lastProperties; + } + private getProperties(key: number): Map { const properties = new Map(); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 000fffaf..29e6a0e3 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -631,11 +631,11 @@ export class GameScene extends ResizableScene implements CenterListener { } } - private safeParseJSONstring(jsonString: string|undefined) { + private safeParseJSONstring(jsonString: string|undefined, propertyName: string) { try { return jsonString ? JSON.parse(jsonString) : {}; } catch(e) { - console.warn(jsonString, e); + console.warn('Invalid JSON found in property "' + propertyName + '" of the map:' + jsonString, e); return {} } } @@ -678,14 +678,11 @@ export class GameScene extends ResizableScene implements CenterListener { this.connection.emitQueryJitsiJwtMessage(this.instance.replace('/', '-') + "-" + newValue, adminTag); } else { - const jitsiConfig = this.safeParseJSONstring(allProps.get("jitsiConfig") as string|undefined); - const jitsiInterfaceConfig = this.safeParseJSONstring(allProps.get("jitsiInterfaceConfig") as string|undefined); - - this.startJitsi(newValue as string, undefined, jitsiConfig, jitsiInterfaceConfig); + this.startJitsi(newValue as string, undefined); } layoutManager.removeActionButton('jitsiRoom', this.userInputManager); } - + const jitsiTriggerValue = allProps.get(TRIGGER_JITSI_PROPERTIES); if(jitsiTriggerValue && jitsiTriggerValue === ON_ACTION_TRIGGER_BUTTON) { layoutManager.addActionButton('jitsiRoom', 'Click on SPACE to enter in jitsi meet room', () => { @@ -1240,8 +1237,12 @@ export class GameScene extends ResizableScene implements CenterListener { this.updateCameraOffset(); } - public startJitsi(roomName: string, jwt?: string, config: object = {}, interfaceConfig: object = {}): void { - jitsiFactory.start(roomName, this.playerName, jwt, config, interfaceConfig); + public startJitsi(roomName: string, jwt?: string): void { + const allProps = this.gameMap.getCurrentProperties(); + const jitsiConfig = this.safeParseJSONstring(allProps.get("jitsiConfig") as string|undefined, 'jitsiConfig'); + const jitsiInterfaceConfig = this.safeParseJSONstring(allProps.get("jitsiInterfaceConfig") as string|undefined, 'jitsiInterfaceConfig'); + + jitsiFactory.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig); this.connection.setSilent(true); mediaManager.hideGameOverlay(); From f8b5ca04e52f578c82d08d815f08a45e749a329a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 10 Feb 2021 11:09:22 +0100 Subject: [PATCH 4/8] Adding a test map for Jitsi meet special properties --- maps/tests/Attribution-tilesets.txt | 25 ++++++++ maps/tests/jitsi_config.json | 92 ++++++++++++++++++++++++++++ maps/tests/tileset1.png | Bin 0 -> 29402 bytes 3 files changed, 117 insertions(+) create mode 100644 maps/tests/Attribution-tilesets.txt create mode 100644 maps/tests/jitsi_config.json create mode 100644 maps/tests/tileset1.png diff --git a/maps/tests/Attribution-tilesets.txt b/maps/tests/Attribution-tilesets.txt new file mode 100644 index 00000000..a0e4224a --- /dev/null +++ b/maps/tests/Attribution-tilesets.txt @@ -0,0 +1,25 @@ +License +------- + +CC-BY-SA 3.0: + - http://creativecommons.org/licenses/by-sa/3.0/ + - See the file: cc-by-sa-3.0.txt +GNU GPL 3.0: + - http://www.gnu.org/licenses/gpl-3.0.html + - See the file: gpl-3.0.txt + +Assets from: workadventure@thecodingmachine.com + +BASE assets: +------------ + + - le-coq.png + - logotcm.png + - pin.png + - tileset1-repositioning.png + - tileset1.png + - tileset2.2.png + - tileset2.png + - tileset3.2.png + - tileset3.png + - walls2.png \ No newline at end of file diff --git a/maps/tests/jitsi_config.json b/maps/tests/jitsi_config.json new file mode 100644 index 00000000..7937d1e3 --- /dev/null +++ b/maps/tests/jitsi_config.json @@ -0,0 +1,92 @@ +{ "compressionlevel":-1, + "height":10, + "infinite":false, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":10, + "id":1, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":4, + "name":"jitsi", + "opacity":1, + "properties":[ + { + "name":"jitsiConfig", + "type":"string", + "value":"{ \"startWithAudioMuted\": true }" + }, + { + "name":"jitsiInterfaceConfig", + "type":"string", + "value":"{ \"DEFAULT_BACKGROUND\": \"#77ee77\" }" + }, + { + "name":"jitsiRoom", + "type":"string", + "value":"myRoom" + }], + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":3, + "name":"floorLayer", + "objects":[], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":5, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.3.3", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.2, + "width":10 +} \ No newline at end of file diff --git a/maps/tests/tileset1.png b/maps/tests/tileset1.png new file mode 100644 index 0000000000000000000000000000000000000000..6e7dafb47dfbf1d7b225b7094ef7bfde8699f93c GIT binary patch literal 29402 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 literal 0 HcmV?d00001 From e7ddeedb3e1d6dad13d29278443850da8cac381b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 10 Feb 2021 11:13:47 +0100 Subject: [PATCH 5/8] Disabling Join/Leave notifications by default --- front/src/WebRtc/JitsiFactory.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index 4d4d9f64..d9b0e9ea 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -3,7 +3,7 @@ import {mediaManager} from "./MediaManager"; import {coWebsiteManager} from "./CoWebsiteManager"; declare const window:any; // eslint-disable-line @typescript-eslint/no-explicit-any -const defaultConfig = { +const defaultConfig = { startWithAudioMuted: !mediaManager.constraintsMedia.audio, startWithVideoMuted: mediaManager.constraintsMedia.video === false, prejoinPageEnabled: false @@ -14,6 +14,7 @@ const defaultInterfaceConfig = { MOBILE_APP_PROMO: false, HIDE_INVITE_MORE_HEADER: true, + DISABLE_JOIN_LEAVE_NOTIFICATIONS: true, // Note: hiding brand does not seem to work, we probably need to put this on the server side. SHOW_BRAND_WATERMARK: false, @@ -35,7 +36,7 @@ class JitsiFactory { private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any private audioCallback = this.onAudioChange.bind(this); private videoCallback = this.onVideoChange.bind(this); - + public start(roomName: string, playerName:string, jwt?: string, config?: object, interfaceConfig?: object): void { coWebsiteManager.insertCoWebsite((cowebsiteDiv => { const domain = JITSI_URL; @@ -51,7 +52,7 @@ class JitsiFactory { if (!options.jwt) { delete options.jwt; } - + return new Promise((resolve, reject) => { options.onload = () => resolve(); //we want for the iframe to be loaded before triggering animations. setTimeout(() => resolve(), 2000); //failsafe in case the iframe is deleted before loading or too long to load @@ -91,4 +92,4 @@ class JitsiFactory { } } -export const jitsiFactory = new JitsiFactory(); \ No newline at end of file +export const jitsiFactory = new JitsiFactory(); From 8389fad877351e8bfae7a69f9171e2851de65e6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 10 Feb 2021 11:20:05 +0100 Subject: [PATCH 6/8] Disabling video background by default on Jitsi (because it consumes a lot of CPU) --- front/src/WebRtc/JitsiFactory.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index d9b0e9ea..fb7dfa80 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -15,6 +15,7 @@ const defaultInterfaceConfig = { HIDE_INVITE_MORE_HEADER: true, DISABLE_JOIN_LEAVE_NOTIFICATIONS: true, + DISABLE_VIDEO_BACKGROUND: true, // Note: hiding brand does not seem to work, we probably need to put this on the server side. SHOW_BRAND_WATERMARK: false, From f6e93da48a364871327e8d45b58aa402cbb7cfeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Tue, 9 Feb 2021 12:41:35 +0100 Subject: [PATCH 7/8] Fixing loading logo being displayed when nothing was loaded --- front/src/Phaser/Components/Loader.ts | 4 ++++ front/src/Phaser/Game/GameScene.ts | 4 ++-- front/src/Phaser/Login/SelectCharacterScene.ts | 4 +++- maps/Floor0/floor0.json | 2 +- maps/Floor1/floor1.json | 8 ++++---- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/front/src/Phaser/Components/Loader.ts b/front/src/Phaser/Components/Loader.ts index 0eda58dc..1ee18b32 100644 --- a/front/src/Phaser/Components/Loader.ts +++ b/front/src/Phaser/Components/Loader.ts @@ -6,6 +6,10 @@ const LogoResource: string = 'resources/logos/logo.png'; const LogoFrame: ImageFrameConfig = {frameWidth: 307, frameHeight: 59}; export const addLoader = (scene: Phaser.Scene): void => { + // If there is nothing to load, do not display the loader. + if (scene.load.list.entries.length === 0) { + return; + } let loadingText: Phaser.GameObjects.Text|null = null; const loadingBarWidth: number = Math.floor(scene.game.renderer.width / 3); const loadingBarHeight: number = 16; diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 29e6a0e3..1b4cf567 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -183,8 +183,6 @@ export class GameScene extends ResizableScene implements CenterListener { //hook preload scene preload(): void { - addLoader(this); - const localUser = localUserStore.getLocalUser(); const textures = localUser?.textures; if (textures) { @@ -215,6 +213,8 @@ export class GameScene extends ResizableScene implements CenterListener { this.load.spritesheet('layout_modes', 'resources/objects/layout_modes.png', {frameWidth: 32, frameHeight: 32}); this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); + + addLoader(this); } // FIXME: we need to put a "unknown" instead of a "any" and validate the structure of the JSON we are receiving. diff --git a/front/src/Phaser/Login/SelectCharacterScene.ts b/front/src/Phaser/Login/SelectCharacterScene.ts index 905c9ae4..e47cf38a 100644 --- a/front/src/Phaser/Login/SelectCharacterScene.ts +++ b/front/src/Phaser/Login/SelectCharacterScene.ts @@ -59,6 +59,8 @@ export class SelectCharacterScene extends AbstractCharacterScene { this.playerModels = loadAllDefaultModels(this.load); this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png'); this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.png'); + + addLoader(this); } create() { @@ -123,7 +125,7 @@ export class SelectCharacterScene extends AbstractCharacterScene { /*create user*/ this.createCurrentPlayer(); - + const playerNumber = localUserStore.getPlayerCharacterIndex(); if (playerNumber && playerNumber !== -1) { this.selectedRectangleXPos = playerNumber % this.nbCharactersPerRow; diff --git a/maps/Floor0/floor0.json b/maps/Floor0/floor0.json index 3bbd67cd..6a88f78d 100644 --- a/maps/Floor0/floor0.json +++ b/maps/Floor0/floor0.json @@ -278,7 +278,7 @@ { "name":"exitUrl", "type":"string", - "value":"\/@\/tcm\/workadventure\/floor1" + "value":"..\/Floor1\/floor1.json" }], "type":"tilelayer", "visible":true, diff --git a/maps/Floor1/floor1.json b/maps/Floor1/floor1.json index 6deb3bf5..1894ed42 100644 --- a/maps/Floor1/floor1.json +++ b/maps/Floor1/floor1.json @@ -83,9 +83,9 @@ "opacity":1, "properties":[ { - "name":"exitSceneUrl", + "name":"exitUrl", "type":"string", - "value":"\/@\/tcm\/workadventure\/floor0#down-the-stairs" + "value":"..\/Floor0\/floor0.json" }], "type":"tilelayer", "visible":true, @@ -264,7 +264,7 @@ "nextobjectid":1, "orientation":"orthogonal", "renderorder":"right-down", - "tiledversion":"1.4.2", + "tiledversion":"1.3.3", "tileheight":32, "tilesets":[ { @@ -1959,6 +1959,6 @@ }], "tilewidth":32, "type":"map", - "version":1.4, + "version":1.2, "width":46 } \ No newline at end of file From 91fddd68939cfeb0f38d60b91acc9ddc8e4df8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 10 Feb 2021 11:40:59 +0100 Subject: [PATCH 8/8] Slugifies the Jitsi room name This will avoid Jitsi breaking on unexpected characters and displaying a HTTP 404 error. --- front/src/Phaser/Game/GameScene.ts | 5 +++-- front/src/WebRtc/JitsiFactory.ts | 19 +++++++++++++++++++ maps/tests/jitsi_config.json | 9 ++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 1b4cf567..7138330a 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -673,12 +673,13 @@ export class GameScene extends ResizableScene implements CenterListener { this.stopJitsi(); }else{ const openJitsiRoomFunction = () => { + const roomName = jitsiFactory.getRoomName(newValue.toString(), this.instance); if (JITSI_PRIVATE_MODE) { const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined; - this.connection.emitQueryJitsiJwtMessage(this.instance.replace('/', '-') + "-" + newValue, adminTag); + this.connection.emitQueryJitsiJwtMessage(roomName, adminTag); } else { - this.startJitsi(newValue as string, undefined); + this.startJitsi(roomName, undefined); } layoutManager.removeActionButton('jitsiRoom', this.userInputManager); } diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index fb7dfa80..7d470754 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -33,11 +33,30 @@ const defaultInterfaceConfig = { ], }; +const slugify = (...args: (string | number)[]): string => { + const value = args.join(' ') + + return value + .normalize('NFD') // split an accented letter in the base letter and the accent + .replace(/[\u0300-\u036f]/g, '') // remove all previously split accents + .toLowerCase() + .trim() + .replace(/[^a-z0-9 ]/g, '') // remove all chars not letters, numbers and spaces (to be replaced) + .replace(/\s+/g, '-') // separator +} + class JitsiFactory { private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any private audioCallback = this.onAudioChange.bind(this); private videoCallback = this.onVideoChange.bind(this); + /** + * Slugifies the room name and prepends the room name with the instance + */ + public getRoomName(roomName: string, instance: string): string { + return slugify(instance.replace('/', '-') + "-" + roomName); + } + public start(roomName: string, playerName:string, jwt?: string, config?: object, interfaceConfig?: object): void { coWebsiteManager.insertCoWebsite((cowebsiteDiv => { const domain = JITSI_URL; diff --git a/maps/tests/jitsi_config.json b/maps/tests/jitsi_config.json index 7937d1e3..1a831d97 100644 --- a/maps/tests/jitsi_config.json +++ b/maps/tests/jitsi_config.json @@ -1,4 +1,11 @@ { "compressionlevel":-1, + "editorsettings": + { + "export": + { + "target":"." + } + }, "height":10, "infinite":false, "layers":[ @@ -46,7 +53,7 @@ { "name":"jitsiRoom", "type":"string", - "value":"myRoom" + "value":"myRoom avec espace \u00e9\u00e0$&'\"_ \ud83d\ude00" }], "type":"tilelayer", "visible":true,