From 559e15ebb6f08c28437e0109c6151960510c971d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Tue, 30 Mar 2021 16:08:49 +0200 Subject: [PATCH] Adding an "alone" mode In "alone" mode (or single-player mode), WorkAdventure does not connect to the server at all. In order to enter the "alone" mode, you need to add "?alone=true" to the URL. "alone" mode can be useful for tutorials (First Time User Experience) where you want to explain how WorkAdventure works without being disturbed by other users. --- front/src/Connexion/ConnectionManager.ts | 8 ++--- front/src/Connexion/Room.ts | 32 +++++++++++++------ front/src/Phaser/Game/GameScene.ts | 39 +++++++++++++++--------- front/src/Url/UrlManager.ts | 3 +- 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts index b2f1247c..ed920aa0 100644 --- a/front/src/Connexion/ConnectionManager.ts +++ b/front/src/Connexion/ConnectionManager.ts @@ -14,11 +14,11 @@ class ConnectionManager { private connexionType?: GameConnexionTypes private reconnectingTimeout: NodeJS.Timeout|null = null; private _unloading:boolean = false; - + get unloading () { return this._unloading; } - + constructor() { window.addEventListener('beforeunload', () => { this._unloading = true; @@ -42,7 +42,7 @@ class ConnectionManager { const worldSlug = data.worldSlug; const roomSlug = data.roomSlug; - const room = new Room('/@/'+organizationSlug+'/'+worldSlug+'/'+roomSlug + window.location.hash); + const room = new Room('/@/'+organizationSlug+'/'+worldSlug+'/'+roomSlug + window.location.search + window.location.hash); urlManager.pushRoomIdToUrl(room); return Promise.resolve(room); } else if (connexionType === GameConnexionTypes.organization || connexionType === GameConnexionTypes.anonymous || connexionType === GameConnexionTypes.empty) { @@ -64,7 +64,7 @@ class ConnectionManager { if (connexionType === GameConnexionTypes.empty) { roomId = START_ROOM_URL; } else { - roomId = window.location.pathname + window.location.hash; + roomId = window.location.pathname + window.location.search + window.location.hash; } return Promise.resolve(new Room(roomId)); } diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index 72c3b42e..782d5edf 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -6,24 +6,25 @@ export class Room { public readonly isPublic: boolean; private mapUrl: string|undefined; private instance: string|undefined; + private _search: URLSearchParams; constructor(id: string) { - if (id.startsWith('/')) { - id = id.substr(1); + const url = new URL(id, 'https://example.com'); + + this.id = url.pathname; + + if (this.id.startsWith('/')) { + this.id = this.id.substr(1); } - this.id = id; - if (id.startsWith('_/')) { + if (this.id.startsWith('_/')) { this.isPublic = true; - } else if (id.startsWith('@/')) { + } else if (this.id.startsWith('@/')) { this.isPublic = false; } else { throw new Error('Invalid room ID'); } - const indexOfHash = this.id.indexOf('#'); - if (indexOfHash !== -1) { - this.id = this.id.substr(0, indexOfHash); - } + this._search = new URLSearchParams(url.search); } public static getIdFromIdentifier(identifier: string, baseUrl: string, currentInstance: string): {roomId: string, hash: string} { @@ -117,4 +118,17 @@ export class Room { } return results; } + + public isDisconnected(): boolean + { + const alone = this._search.get('alone'); + if (alone && alone !== '0' && alone.toLowerCase() !== 'false') { + return true; + } + return false; + } + + public get search(): URLSearchParams { + return this._search; + } } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 6faaf4fa..d80c9fbf 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -306,7 +306,7 @@ export class GameScene extends ResizableScene implements CenterListener { gameManager.gameSceneIsCreated(this); urlManager.pushRoomIdToUrl(this.room); this.startLayerName = urlManager.getStartLayerNameFromUrl(); - + this.messageSubscription = worldFullMessageStream.stream.subscribe((message) => this.showWorldFullError()) const playerName = gameManager.getPlayerName(); @@ -373,19 +373,21 @@ export class GameScene extends ResizableScene implements CenterListener { this.initCirclesCanvas(); // Let's pause the scene if the connection is not established yet - if (this.isReconnecting) { - setTimeout(() => { - this.scene.sleep(); - this.scene.launch(ReconnectingSceneName); - }, 0); - } else if (this.connection === undefined) { - // Let's wait 1 second before printing the "connecting" screen to avoid blinking - setTimeout(() => { - if (this.connection === undefined) { + if (!this.room.isDisconnected()) { + if (this.isReconnecting) { + setTimeout(() => { this.scene.sleep(); this.scene.launch(ReconnectingSceneName); - } - }, 1000); + }, 0); + } else if (this.connection === undefined) { + // Let's wait 1 second before printing the "connecting" screen to avoid blinking + setTimeout(() => { + if (this.connection === undefined) { + this.scene.sleep(); + this.scene.launch(ReconnectingSceneName); + } + }, 1000); + } } this.createPromiseResolve(); @@ -411,6 +413,16 @@ export class GameScene extends ResizableScene implements CenterListener { layoutManager.setListener(this); this.triggerOnMapLayerPropertyChange(); + + if (!this.room.isDisconnected()) { + this.connect(); + } + } + + /** + * Initializes the connection to Pusher. + */ + private connect(): void { const camera = this.cameras.main; connectionManager.connectToRoomSocket( @@ -548,7 +560,6 @@ export class GameScene extends ResizableScene implements CenterListener { }); } - //todo: into dedicated classes private initCirclesCanvas(): void { // Let's generate the circle for the group delimiter @@ -582,7 +593,7 @@ export class GameScene extends ResizableScene implements CenterListener { contextRed.stroke(); this.circleRedTexture.refresh(); } - + private safeParseJSONstring(jsonString: string|undefined, propertyName: string) { try { diff --git a/front/src/Url/UrlManager.ts b/front/src/Url/UrlManager.ts index 31862899..9e10b4ee 100644 --- a/front/src/Url/UrlManager.ts +++ b/front/src/Url/UrlManager.ts @@ -35,7 +35,8 @@ class UrlManager { public pushRoomIdToUrl(room:Room): void { if (window.location.pathname === room.id) return; const hash = window.location.hash; - history.pushState({}, 'WorkAdventure', room.id+hash); + const search = room.search.toString(); + history.pushState({}, 'WorkAdventure', room.id+(search?'?'+search:'')+hash); } public getStartLayerNameFromUrl(): string|null {