From 0c796dff90bc08ceabdce5611d58a4a4b6e4473d Mon Sep 17 00:00:00 2001 From: GRL Date: Thu, 19 Aug 2021 17:22:16 +0200 Subject: [PATCH 1/4] Player return a the same position when after editing his profile --- front/src/Phaser/Game/GameManager.ts | 10 ++++++++++ front/src/Phaser/Game/GameScene.ts | 24 ++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/front/src/Phaser/Game/GameManager.ts b/front/src/Phaser/Game/GameManager.ts index 12558d5d..265f4bd9 100644 --- a/front/src/Phaser/Game/GameManager.ts +++ b/front/src/Phaser/Game/GameManager.ts @@ -17,6 +17,7 @@ export class GameManager { private playerName: string | null; private characterLayers: string[] | null; private companion: string | null; + private positionBeforeSleep: { scene: string; x: number; y: number } | undefined; private startRoom!: Room; private scenePlugin!: Phaser.Scenes.ScenePlugin; currentGameSceneName: string | null = null; @@ -70,6 +71,10 @@ export class GameManager { return this.companion; } + getPositionBeforeSleep(): { scene: string; x: number; y: number } | undefined { + return this.positionBeforeSleep; + } + public loadMap(room: Room) { const roomID = room.key; @@ -108,6 +113,11 @@ export class GameManager { if (this.currentGameSceneName === null) throw "No current scene id set!"; const gameScene: GameScene = this.scenePlugin.get(this.currentGameSceneName) as GameScene; gameScene.cleanupClosingScene(); + this.positionBeforeSleep = { + scene: gameScene.roomUrl, + x: gameScene.CurrentPlayer.x, + y: gameScene.CurrentPlayer.y, + }; this.scenePlugin.stop(this.currentGameSceneName); this.scenePlugin.sleep(MenuSceneName); if (!this.scenePlugin.get(targetSceneName)) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 9a5d8f27..863fc4cd 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -92,9 +92,7 @@ import { PropertyUtils } from "../Map/PropertyUtils"; import Tileset = Phaser.Tilemaps.Tileset; import { userIsAdminStore } from "../../Stores/GameStore"; import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; -import { get } from "svelte/store"; import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager"; -import { helpCameraSettingsVisibleStore } from "../../Stores/HelpCameraSettingsStore"; export interface GameSceneInitInterface { initPosition: PointInterface | null; @@ -540,7 +538,15 @@ export class GameScene extends DirtyScene { } //notify game manager can to create currentUser in map - this.createCurrentPlayer(); + const positionBeforeSleep = gameManager.getPositionBeforeSleep(); + if (positionBeforeSleep && positionBeforeSleep.scene === this.room.key) { + this.createCurrentPlayer(positionBeforeSleep.x, positionBeforeSleep.y); + } else { + this.createCurrentPlayer( + this.startPositionCalculator.startPosition.x, + this.startPositionCalculator.startPosition.y + ); + } this.removeAllRemotePlayers(); //cleanup the list of remote players in case the scene was rebooted this.initCamera(); @@ -760,8 +766,10 @@ export class GameScene extends DirtyScene { this.connectionAnswerPromiseResolve(onConnect.room); // Analyze tags to find if we are admin. If yes, show console. - this.scene.wake(); - this.scene.stop(ReconnectingSceneName); + if (this.scene.isSleeping()) { + this.scene.wake(); + this.scene.stop(ReconnectingSceneName); + } //init user position and play trigger to check layers properties this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y); @@ -1483,14 +1491,14 @@ ${escapedMessage} } } - createCurrentPlayer() { + createCurrentPlayer(x: number, y: number) { //TODO create animation moving between exit and start const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.characterLayers); try { this.CurrentPlayer = new Player( this, - this.startPositionCalculator.startPosition.x, - this.startPositionCalculator.startPosition.y, + x, + y, this.playerName, texturesPromise, PlayerAnimationDirections.Down, From c2b3d23ec0a53166a381515f5952366d79876f82 Mon Sep 17 00:00:00 2001 From: GRL Date: Fri, 20 Aug 2021 09:49:37 +0200 Subject: [PATCH 2/4] Player return a the same position when after editing his profile (same as reconnection) --- front/src/Phaser/Game/GameManager.ts | 12 +------ front/src/Phaser/Game/GameScene.ts | 50 ++++++++++++++-------------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/front/src/Phaser/Game/GameManager.ts b/front/src/Phaser/Game/GameManager.ts index 265f4bd9..df527f9b 100644 --- a/front/src/Phaser/Game/GameManager.ts +++ b/front/src/Phaser/Game/GameManager.ts @@ -17,7 +17,6 @@ export class GameManager { private playerName: string | null; private characterLayers: string[] | null; private companion: string | null; - private positionBeforeSleep: { scene: string; x: number; y: number } | undefined; private startRoom!: Room; private scenePlugin!: Phaser.Scenes.ScenePlugin; currentGameSceneName: string | null = null; @@ -71,10 +70,6 @@ export class GameManager { return this.companion; } - getPositionBeforeSleep(): { scene: string; x: number; y: number } | undefined { - return this.positionBeforeSleep; - } - public loadMap(room: Room) { const roomID = room.key; @@ -113,12 +108,7 @@ export class GameManager { if (this.currentGameSceneName === null) throw "No current scene id set!"; const gameScene: GameScene = this.scenePlugin.get(this.currentGameSceneName) as GameScene; gameScene.cleanupClosingScene(); - this.positionBeforeSleep = { - scene: gameScene.roomUrl, - x: gameScene.CurrentPlayer.x, - y: gameScene.CurrentPlayer.y, - }; - this.scenePlugin.stop(this.currentGameSceneName); + gameScene.createSuccessorGameScene(false, false); this.scenePlugin.sleep(MenuSceneName); if (!this.scenePlugin.get(targetSceneName)) { this.scenePlugin.add(targetSceneName, sceneClass, false); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 863fc4cd..f6a75b65 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -538,15 +538,7 @@ export class GameScene extends DirtyScene { } //notify game manager can to create currentUser in map - const positionBeforeSleep = gameManager.getPositionBeforeSleep(); - if (positionBeforeSleep && positionBeforeSleep.scene === this.room.key) { - this.createCurrentPlayer(positionBeforeSleep.x, positionBeforeSleep.y); - } else { - this.createCurrentPlayer( - this.startPositionCalculator.startPosition.x, - this.startPositionCalculator.startPosition.y - ); - } + this.createCurrentPlayer(); this.removeAllRemotePlayers(); //cleanup the list of remote players in case the scene was rebooted this.initCamera(); @@ -692,19 +684,7 @@ export class GameScene extends DirtyScene { this.connection.onServerDisconnected(() => { console.log("Player disconnected from server. Reloading scene."); this.cleanupClosingScene(); - - const gameSceneKey = "somekey" + Math.round(Math.random() * 10000); - const game: Phaser.Scene = new GameScene(this.room, this.MapUrlFile, gameSceneKey); - this.scene.add(gameSceneKey, game, true, { - initPosition: { - x: this.CurrentPlayer.x, - y: this.CurrentPlayer.y, - }, - reconnecting: true, - }); - - this.scene.stop(this.scene.key); - this.scene.remove(this.scene.key); + this.createSuccessorGameScene(true, true); }); this.connection.onActionableEvent((message) => { @@ -1491,14 +1471,14 @@ ${escapedMessage} } } - createCurrentPlayer(x: number, y: number) { + createCurrentPlayer() { //TODO create animation moving between exit and start const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.characterLayers); try { this.CurrentPlayer = new Player( this, - x, - y, + this.startPositionCalculator.startPosition.x, + this.startPositionCalculator.startPosition.y, this.playerName, texturesPromise, PlayerAnimationDirections.Down, @@ -1936,4 +1916,24 @@ ${escapedMessage} waScaleManager.zoomModifier *= zoomFactor; biggestAvailableAreaStore.recompute(); } + + public createSuccessorGameScene(autostart: boolean, reconnecting: boolean) { + const gameSceneKey = "somekey" + Math.round(Math.random() * 10000); + const game = new GameScene(this.room, this.MapUrlFile, gameSceneKey); + this.scene.add(gameSceneKey, game, autostart, { + initPosition: { + x: this.CurrentPlayer.x, + y: this.CurrentPlayer.y, + }, + reconnecting: reconnecting, + }); + + //If new gameScene doesn't start automatically then we change the gameScene in gameManager so that it can start the new gameScene + if (!autostart) { + gameManager.gameSceneIsCreated(game); + } + + this.scene.stop(this.scene.key); + this.scene.remove(this.scene.key); + } } From ad95fa5e115b87b8c4e37e27666b95b0944fcaaa Mon Sep 17 00:00:00 2001 From: GRL Date: Mon, 16 Aug 2021 14:07:24 +0200 Subject: [PATCH 3/4] Execute scripts of the map after creating gameScene --- front/src/Api/IframeListener.ts | 96 +++++++++++++++++------------- front/src/Phaser/Game/GameScene.ts | 20 ++++--- 2 files changed, 65 insertions(+), 51 deletions(-) diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 4dde1b7d..eab33945 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -293,57 +293,67 @@ class IframeListener { this.iframes.delete(iframe); } - registerScript(scriptUrl: string): void { - console.log("Loading map related script at ", scriptUrl); + registerScript(scriptUrl: string): Promise { + return new Promise((resolve, reject) => { + console.log("Loading map related script at ", scriptUrl); - if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") { - // Using external iframe mode ( - const iframe = document.createElement("iframe"); - iframe.id = IframeListener.getIFrameId(scriptUrl); - iframe.style.display = "none"; - iframe.src = "/iframe.html?script=" + encodeURIComponent(scriptUrl); + if (!process.env.NODE_ENV || process.env.NODE_ENV === "development") { + // Using external iframe mode ( + const iframe = document.createElement("iframe"); + iframe.id = IframeListener.getIFrameId(scriptUrl); + iframe.style.display = "none"; + iframe.src = "/iframe.html?script=" + encodeURIComponent(scriptUrl); - // We are putting a sandbox on this script because it will run in the same domain as the main website. - iframe.sandbox.add("allow-scripts"); - iframe.sandbox.add("allow-top-navigation-by-user-activation"); + // We are putting a sandbox on this script because it will run in the same domain as the main website. + iframe.sandbox.add("allow-scripts"); + iframe.sandbox.add("allow-top-navigation-by-user-activation"); - document.body.prepend(iframe); + iframe.addEventListener("load", () => { + resolve(); + }); - this.scripts.set(scriptUrl, iframe); - this.registerIframe(iframe); - } else { - // production code - const iframe = document.createElement("iframe"); - iframe.id = IframeListener.getIFrameId(scriptUrl); - iframe.style.display = "none"; + document.body.prepend(iframe); - // We are putting a sandbox on this script because it will run in the same domain as the main website. - iframe.sandbox.add("allow-scripts"); - iframe.sandbox.add("allow-top-navigation-by-user-activation"); + this.scripts.set(scriptUrl, iframe); + this.registerIframe(iframe); + } else { + // production code + const iframe = document.createElement("iframe"); + iframe.id = IframeListener.getIFrameId(scriptUrl); + iframe.style.display = "none"; - //iframe.src = "data:text/html;charset=utf-8," + escape(html); - iframe.srcdoc = - "\n" + - "\n" + - '\n' + - "\n" + - '\n' + - '\n' + - "\n" + - "\n" + - "\n"; + // We are putting a sandbox on this script because it will run in the same domain as the main website. + iframe.sandbox.add("allow-scripts"); + iframe.sandbox.add("allow-top-navigation-by-user-activation"); - document.body.prepend(iframe); + //iframe.src = "data:text/html;charset=utf-8," + escape(html); + iframe.srcdoc = + "\n" + + "\n" + + '\n' + + "\n" + + '\n' + + '\n' + + "\n" + + "\n" + + "\n"; - this.scripts.set(scriptUrl, iframe); - this.registerIframe(iframe); - } + iframe.addEventListener("load", () => { + resolve(); + }); + + document.body.prepend(iframe); + + this.scripts.set(scriptUrl, iframe); + this.registerIframe(iframe); + } + }); } private getBaseUrl(src: string, source: MessageEventSource | null): string { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index f6a75b65..83a5ac6e 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -165,7 +165,7 @@ export class GameScene extends DirtyScene { value: RoomJoinedMessageInterface | PromiseLike ) => void; // A promise that will resolve when the "create" method is called (signaling loading is ended) - private createPromise: Promise; + public createPromise: Promise; private createPromiseResolve!: (value?: void | PromiseLike) => void; private iframeSubscriptionList!: Array; private peerStoreUnsubscribe!: () => void; @@ -403,12 +403,6 @@ export class GameScene extends DirtyScene { }); }); } - - // Now, let's load the script, if any - const scripts = this.getScriptUrls(this.mapFile); - for (const script of scripts) { - iframeListener.registerScript(script); - } } //hook initialisation @@ -567,6 +561,12 @@ export class GameScene extends DirtyScene { } this.createPromiseResolve(); + // Now, let's load the script, if any + const scripts = this.getScriptUrls(this.mapFile); + const scriptPromises = []; + for (const script of scripts) { + scriptPromises.push(iframeListener.registerScript(script)); + } this.userInputManager.spaceEvent(() => { this.outlinedItem?.activate(); @@ -584,6 +584,7 @@ export class GameScene extends DirtyScene { this.triggerOnMapLayerPropertyChange(); if (!this.room.isDisconnected()) { + this.scene.sleep(); this.connect(); } @@ -607,6 +608,10 @@ export class GameScene extends DirtyScene { this.chatVisibilityUnsubscribe = chatVisibilityStore.subscribe((v) => { this.openChatIcon.setVisible(!v); }); + + Promise.all([this.connectionAnswerPromise as Promise, ...scriptPromises]).then(() => { + this.scene.wake(); + }); } /** @@ -747,7 +752,6 @@ export class GameScene extends DirtyScene { // Analyze tags to find if we are admin. If yes, show console. if (this.scene.isSleeping()) { - this.scene.wake(); this.scene.stop(ReconnectingSceneName); } From 8c43c2e6e890af0afdd19bc97a30dba17eb2fbd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 16 Aug 2021 14:22:01 +0200 Subject: [PATCH 4/4] Rollback on createPromise switched to public --- front/src/Phaser/Game/GameScene.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 83a5ac6e..bd6890dc 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -165,7 +165,7 @@ export class GameScene extends DirtyScene { value: RoomJoinedMessageInterface | PromiseLike ) => void; // A promise that will resolve when the "create" method is called (signaling loading is ended) - public createPromise: Promise; + private createPromise: Promise; private createPromiseResolve!: (value?: void | PromiseLike) => void; private iframeSubscriptionList!: Array; private peerStoreUnsubscribe!: () => void;