Merge branch 'develop' of github.com:thecodingmachine/workadventure into develop

This commit is contained in:
Lurkars 2021-08-17 20:24:25 +02:00
commit f3cfe7ec82
22 changed files with 204 additions and 142 deletions

View File

@ -102,7 +102,7 @@
{/if} {/if}
{#if $consoleGlobalMessageManagerVisibleStore} {#if $consoleGlobalMessageManagerVisibleStore}
<div> <div>
<ConsoleGlobalMessageManager game={game}></ConsoleGlobalMessageManager> <ConsoleGlobalMessageManager></ConsoleGlobalMessageManager>
</div> </div>
{/if} {/if}
{#if $helpCameraSettingsVisibleStore} {#if $helpCameraSettingsVisibleStore}

View File

@ -3,10 +3,8 @@
import InputTextGlobalMessage from "./InputTextGlobalMessage.svelte"; import InputTextGlobalMessage from "./InputTextGlobalMessage.svelte";
import UploadAudioGlobalMessage from "./UploadAudioGlobalMessage.svelte"; import UploadAudioGlobalMessage from "./UploadAudioGlobalMessage.svelte";
import { gameManager } from "../../Phaser/Game/GameManager"; import { gameManager } from "../../Phaser/Game/GameManager";
import type { Game } from "../../Phaser/Game/Game";
import { consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore"; import { consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore";
export let game: Game;
let inputSendTextActive = true; let inputSendTextActive = true;
let uploadMusicActive = false; let uploadMusicActive = false;
let handleSendText: { sendTextMessage(broadcast: boolean): void }; let handleSendText: { sendTextMessage(broadcast: boolean): void };
@ -57,10 +55,10 @@
</div> </div>
<div class="content-console-global-message"> <div class="content-console-global-message">
{#if inputSendTextActive} {#if inputSendTextActive}
<InputTextGlobalMessage game={game} gameManager={gameManager} bind:handleSending={handleSendText}/> <InputTextGlobalMessage gameManager={gameManager} bind:handleSending={handleSendText}/>
{/if} {/if}
{#if uploadMusicActive} {#if uploadMusicActive}
<UploadAudioGlobalMessage game={game} gameManager={gameManager} bind:handleSending={handleSendAudio}/> <UploadAudioGlobalMessage gameManager={gameManager} bind:handleSending={handleSendAudio}/>
{/if} {/if}
</div> </div>
<div class="footer-console-global-message"> <div class="footer-console-global-message">

View File

@ -1,7 +1,6 @@
<script lang="ts"> <script lang="ts">
import { consoleGlobalMessageManagerFocusStore, consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore"; import { consoleGlobalMessageManagerFocusStore, consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore";
import {onDestroy, onMount} from "svelte"; import {onDestroy, onMount} from "svelte";
import type { Game } from "../../Phaser/Game/Game";
import type { GameManager } from "../../Phaser/Game/GameManager"; import type { GameManager } from "../../Phaser/Game/GameManager";
import { AdminMessageEventTypes } from "../../Connexion/AdminMessagesService"; import { AdminMessageEventTypes } from "../../Connexion/AdminMessagesService";
import type { Quill } from "quill"; import type { Quill } from "quill";
@ -31,10 +30,9 @@
// remove formatting button // remove formatting button
]; ];
export let game: Game;
export let gameManager: GameManager; export let gameManager: GameManager;
const gameScene = gameManager.getCurrentGameScene(game.findAnyScene()); const gameScene = gameManager.getCurrentGameScene();
let quill: Quill; let quill: Quill;
let INPUT_CONSOLE_MESSAGE: HTMLDivElement; let INPUT_CONSOLE_MESSAGE: HTMLDivElement;

View File

@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import { HtmlUtils } from "../../WebRtc/HtmlUtils"; import { HtmlUtils } from "../../WebRtc/HtmlUtils";
import type { Game } from "../../Phaser/Game/Game";
import type { GameManager } from "../../Phaser/Game/GameManager"; import type { GameManager } from "../../Phaser/Game/GameManager";
import { consoleGlobalMessageManagerFocusStore, consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore"; import { consoleGlobalMessageManagerFocusStore, consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore";
import { AdminMessageEventTypes } from "../../Connexion/AdminMessagesService"; import { AdminMessageEventTypes } from "../../Connexion/AdminMessagesService";
@ -11,10 +10,9 @@
files: Array<File>; files: Array<File>;
} }
export let game: Game;
export let gameManager: GameManager; export let gameManager: GameManager;
let gameScene = gameManager.getCurrentGameScene(game.findAnyScene()); let gameScene = gameManager.getCurrentGameScene();
let fileInput: HTMLInputElement; let fileInput: HTMLInputElement;
let fileName: string; let fileName: string;
let fileSize: string; let fileSize: string;

View File

@ -29,11 +29,24 @@ class ConnectionManager {
}); });
} }
public loadOpenIDScreen() { /**
localUserStore.setAuthToken(null); * @return Promise<void>
*/
public loadOpenIDScreen(): Promise<void> {
const state = localUserStore.generateState(); const state = localUserStore.generateState();
const nonce = localUserStore.generateNonce(); const nonce = localUserStore.generateNonce();
window.location.assign(`http://${PUSHER_URL}/login-screen?state=${state}&nonce=${nonce}`); localUserStore.setAuthToken(null);
//TODO refactor this and don't realise previous call
return Axios.get(`http://${PUSHER_URL}/login-screen?state=${state}&nonce=${nonce}`)
.then(() => {
window.location.assign(`http://${PUSHER_URL}/login-screen?state=${state}&nonce=${nonce}`);
})
.catch((err) => {
console.error(err, "We don't have URL to regenerate authentication user");
//TODO show modal login
window.location.reload();
});
} }
public logout() { public logout() {

View File

@ -1,6 +1,7 @@
import Axios from "axios"; import Axios from "axios";
import { PUSHER_URL } from "../Enum/EnvironmentVariable"; import { PUSHER_URL } from "../Enum/EnvironmentVariable";
import type { CharacterTexture } from "./LocalUser"; import type { CharacterTexture } from "./LocalUser";
import { localUserStore } from "./LocalUserStore";
export class MapDetail { export class MapDetail {
constructor(public readonly mapUrl: string, public readonly textures: CharacterTexture[] | undefined) {} constructor(public readonly mapUrl: string, public readonly textures: CharacterTexture[] | undefined) {}
@ -87,6 +88,7 @@ export class Room {
const result = await Axios.get(`${PUSHER_URL}/map`, { const result = await Axios.get(`${PUSHER_URL}/map`, {
params: { params: {
playUri: this.roomUrl.toString(), playUri: this.roomUrl.toString(),
authToken: localUserStore.getAuthToken(),
}, },
}); });

View File

@ -18,6 +18,7 @@ export class GameManager {
private characterLayers: string[] | null; private characterLayers: string[] | null;
private companion: string | null; private companion: string | null;
private startRoom!: Room; private startRoom!: Room;
private scenePlugin!: Phaser.Scenes.ScenePlugin;
currentGameSceneName: string | null = null; currentGameSceneName: string | null = null;
constructor() { constructor() {
@ -27,8 +28,9 @@ export class GameManager {
} }
public async init(scenePlugin: Phaser.Scenes.ScenePlugin): Promise<string> { public async init(scenePlugin: Phaser.Scenes.ScenePlugin): Promise<string> {
this.scenePlugin = scenePlugin;
this.startRoom = await connectionManager.initGameConnexion(); this.startRoom = await connectionManager.initGameConnexion();
this.loadMap(this.startRoom, scenePlugin); this.loadMap(this.startRoom);
if (!this.playerName) { if (!this.playerName) {
return LoginSceneName; return LoginSceneName;
@ -68,20 +70,20 @@ export class GameManager {
return this.companion; return this.companion;
} }
public loadMap(room: Room, scenePlugin: Phaser.Scenes.ScenePlugin) { public loadMap(room: Room) {
const roomID = room.key; const roomID = room.key;
const gameIndex = scenePlugin.getIndex(roomID); const gameIndex = this.scenePlugin.getIndex(roomID);
if (gameIndex === -1) { if (gameIndex === -1) {
const game: Phaser.Scene = new GameScene(room, room.mapUrl); const game: Phaser.Scene = new GameScene(room, room.mapUrl);
scenePlugin.add(roomID, game, false); this.scenePlugin.add(roomID, game, false);
} }
} }
public goToStartingMap(scenePlugin: Phaser.Scenes.ScenePlugin): void { public goToStartingMap(): void {
console.log("starting " + (this.currentGameSceneName || this.startRoom.key)); console.log("starting " + (this.currentGameSceneName || this.startRoom.key));
scenePlugin.start(this.currentGameSceneName || this.startRoom.key); this.scenePlugin.start(this.currentGameSceneName || this.startRoom.key);
scenePlugin.launch(MenuSceneName); this.scenePlugin.launch(MenuSceneName);
if ( if (
!localUserStore.getHelpCameraSettingsShown() && !localUserStore.getHelpCameraSettingsShown() &&
@ -102,33 +104,33 @@ export class GameManager {
* Temporary leave a gameScene to go back to the loginScene for example. * Temporary leave a gameScene to go back to the loginScene for example.
* This will close the socket connections and stop the gameScene, but won't remove it. * This will close the socket connections and stop the gameScene, but won't remove it.
*/ */
leaveGame(scene: Phaser.Scene, targetSceneName: string, sceneClass: Phaser.Scene): void { leaveGame(targetSceneName: string, sceneClass: Phaser.Scene): void {
if (this.currentGameSceneName === null) throw "No current scene id set!"; if (this.currentGameSceneName === null) throw "No current scene id set!";
const gameScene: GameScene = scene.scene.get(this.currentGameSceneName) as GameScene; const gameScene: GameScene = this.scenePlugin.get(this.currentGameSceneName) as GameScene;
gameScene.cleanupClosingScene(); gameScene.cleanupClosingScene();
scene.scene.stop(this.currentGameSceneName); this.scenePlugin.stop(this.currentGameSceneName);
scene.scene.sleep(MenuSceneName); this.scenePlugin.sleep(MenuSceneName);
if (!scene.scene.get(targetSceneName)) { if (!this.scenePlugin.get(targetSceneName)) {
scene.scene.add(targetSceneName, sceneClass, false); this.scenePlugin.add(targetSceneName, sceneClass, false);
} }
scene.scene.run(targetSceneName); this.scenePlugin.run(targetSceneName);
} }
/** /**
* follow up to leaveGame() * follow up to leaveGame()
*/ */
tryResumingGame(scene: Phaser.Scene, fallbackSceneName: string) { tryResumingGame(fallbackSceneName: string) {
if (this.currentGameSceneName) { if (this.currentGameSceneName) {
scene.scene.start(this.currentGameSceneName); this.scenePlugin.start(this.currentGameSceneName);
scene.scene.wake(MenuSceneName); this.scenePlugin.wake(MenuSceneName);
} else { } else {
scene.scene.run(fallbackSceneName); this.scenePlugin.run(fallbackSceneName);
} }
} }
public getCurrentGameScene(scene: Phaser.Scene): GameScene { public getCurrentGameScene(): GameScene {
if (this.currentGameSceneName === null) throw "No current scene id set!"; if (this.currentGameSceneName === null) throw "No current scene id set!";
return scene.scene.get(this.currentGameSceneName) as GameScene; return this.scenePlugin.get(this.currentGameSceneName) as GameScene;
} }
} }

View File

@ -94,6 +94,7 @@ import { userIsAdminStore } from "../../Stores/GameStore";
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
import { get } from "svelte/store"; import { get } from "svelte/store";
import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager"; import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager";
import { helpCameraSettingsVisibleStore } from "../../Stores/HelpCameraSettingsStore";
export interface GameSceneInitInterface { export interface GameSceneInitInterface {
initPosition: PointInterface | null; initPosition: PointInterface | null;
@ -814,13 +815,24 @@ export class GameScene extends DirtyScene {
private triggerOnMapLayerPropertyChange() { private triggerOnMapLayerPropertyChange() {
this.gameMap.onPropertyChange("exitSceneUrl", (newValue, oldValue) => { this.gameMap.onPropertyChange("exitSceneUrl", (newValue, oldValue) => {
if (newValue) if (newValue) {
this.onMapExit( this.onMapExit(
Room.getRoomPathFromExitSceneUrl(newValue as string, window.location.toString(), this.MapUrlFile) Room.getRoomPathFromExitSceneUrl(newValue as string, window.location.toString(), this.MapUrlFile)
); );
} else {
setTimeout(() => {
layoutManagerActionStore.removeAction("roomAccessDenied");
}, 2000);
}
}); });
this.gameMap.onPropertyChange("exitUrl", (newValue, oldValue) => { this.gameMap.onPropertyChange("exitUrl", (newValue, oldValue) => {
if (newValue) this.onMapExit(Room.getRoomPathFromExitUrl(newValue as string, window.location.toString())); if (newValue) {
this.onMapExit(Room.getRoomPathFromExitUrl(newValue as string, window.location.toString()));
} else {
setTimeout(() => {
layoutManagerActionStore.removeAction("roomAccessDenied");
}, 2000);
}
}); });
this.gameMap.onPropertyChange("openWebsite", (newValue, oldValue, allProps) => { this.gameMap.onPropertyChange("openWebsite", (newValue, oldValue, allProps) => {
if (newValue === undefined) { if (newValue === undefined) {
@ -915,9 +927,10 @@ export class GameScene extends DirtyScene {
}); });
this.gameMap.onPropertyChange("zone", (newValue, oldValue) => { this.gameMap.onPropertyChange("zone", (newValue, oldValue) => {
if (newValue === undefined || newValue === false || newValue === "") { if (oldValue) {
iframeListener.sendLeaveEvent(oldValue as string); iframeListener.sendLeaveEvent(oldValue as string);
} else { }
if (newValue) {
iframeListener.sendEnterEvent(newValue as string); iframeListener.sendEnterEvent(newValue as string);
} }
}); });
@ -1290,6 +1303,18 @@ ${escapedMessage}
targetRoom = await Room.createRoom(roomUrl); targetRoom = await Room.createRoom(roomUrl);
} catch (e /*: unknown*/) { } catch (e /*: unknown*/) {
console.error('Error while fetching new room "' + roomUrl.toString() + '"', e); console.error('Error while fetching new room "' + roomUrl.toString() + '"', e);
//show information room access denied
layoutManagerActionStore.addAction({
uuid: "roomAccessDenied",
type: "warning",
message: "Room access denied. You don't have right to access on this room.",
callback: () => {
layoutManagerActionStore.removeAction("roomAccessDenied");
},
userInputManager: this.userInputManager,
});
this.mapTransitioning = false; this.mapTransitioning = false;
return; return;
} }
@ -1344,7 +1369,6 @@ ${escapedMessage}
iframeListener.unregisterAnswerer("getState"); iframeListener.unregisterAnswerer("getState");
iframeListener.unregisterAnswerer("loadTileset"); iframeListener.unregisterAnswerer("loadTileset");
iframeListener.unregisterAnswerer("getMapData"); iframeListener.unregisterAnswerer("getMapData");
iframeListener.unregisterAnswerer("getState");
iframeListener.unregisterAnswerer("triggerActionMessage"); iframeListener.unregisterAnswerer("triggerActionMessage");
iframeListener.unregisterAnswerer("removeActionMessage"); iframeListener.unregisterAnswerer("removeActionMessage");
this.sharedVariablesManager?.close(); this.sharedVariablesManager?.close();
@ -1419,7 +1443,7 @@ ${escapedMessage}
private async loadNextGame(exitRoomPath: URL): Promise<void> { private async loadNextGame(exitRoomPath: URL): Promise<void> {
try { try {
const room = await Room.createRoom(exitRoomPath); const room = await Room.createRoom(exitRoomPath);
return gameManager.loadMap(room, this.scene); return gameManager.loadMap(room);
} catch (e /*: unknown*/) { } catch (e /*: unknown*/) {
console.warn('Error while pre-loading exit room "' + exitRoomPath.toString() + '"', e); console.warn('Error while pre-loading exit room "' + exitRoomPath.toString() + '"', e);
} }
@ -1480,7 +1504,7 @@ ${escapedMessage}
}); });
} catch (err) { } catch (err) {
if (err instanceof TextureError) { if (err instanceof TextureError) {
gameManager.leaveGame(this, SelectCharacterSceneName, new SelectCharacterScene()); gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
} }
throw err; throw err;
} }

View File

@ -282,7 +282,7 @@ export class CustomizeScene extends AbstractCharacterScene {
this.scene.sleep(CustomizeSceneName); this.scene.sleep(CustomizeSceneName);
waScaleManager.restoreZoom(); waScaleManager.restoreZoom();
this.events.removeListener("wake"); this.events.removeListener("wake");
gameManager.tryResumingGame(this, EnableCameraSceneName); gameManager.tryResumingGame(EnableCameraSceneName);
customCharacterSceneVisibleStore.set(false); customCharacterSceneVisibleStore.set(false);
} }

View File

@ -1,50 +1,43 @@
import {gameManager} from "../Game/GameManager"; import { gameManager } from "../Game/GameManager";
import {TextField} from "../Components/TextField"; import { TextField } from "../Components/TextField";
import Image = Phaser.GameObjects.Image; import Image = Phaser.GameObjects.Image;
import {mediaManager} from "../../WebRtc/MediaManager"; import { mediaManager } from "../../WebRtc/MediaManager";
import {SoundMeter} from "../Components/SoundMeter"; import { SoundMeter } from "../Components/SoundMeter";
import {HtmlUtils} from "../../WebRtc/HtmlUtils"; import { HtmlUtils } from "../../WebRtc/HtmlUtils";
import {touchScreenManager} from "../../Touch/TouchScreenManager"; import { touchScreenManager } from "../../Touch/TouchScreenManager";
import {PinchManager} from "../UserInput/PinchManager"; import { PinchManager } from "../UserInput/PinchManager";
import Zone = Phaser.GameObjects.Zone; import Zone = Phaser.GameObjects.Zone;
import { MenuScene } from "../Menu/MenuScene"; import { MenuScene } from "../Menu/MenuScene";
import {ResizableScene} from "./ResizableScene"; import { ResizableScene } from "./ResizableScene";
import { import { enableCameraSceneVisibilityStore } from "../../Stores/MediaStore";
enableCameraSceneVisibilityStore,
} from "../../Stores/MediaStore";
export const EnableCameraSceneName = "EnableCameraScene"; export const EnableCameraSceneName = "EnableCameraScene";
export class EnableCameraScene extends ResizableScene { export class EnableCameraScene extends ResizableScene {
constructor() { constructor() {
super({ super({
key: EnableCameraSceneName key: EnableCameraSceneName,
}); });
} }
preload() { preload() {}
}
create() { create() {
this.input.keyboard.on("keyup-ENTER", () => {
this.input.keyboard.on('keyup-ENTER', () => {
this.login(); this.login();
}); });
enableCameraSceneVisibilityStore.showEnableCameraScene(); enableCameraSceneVisibilityStore.showEnableCameraScene();
} }
public onResize(): void { public onResize(): void {}
}
update(time: number, delta: number): void { update(time: number, delta: number): void {}
}
public login(): void { public login(): void {
enableCameraSceneVisibilityStore.hideEnableCameraScene(); enableCameraSceneVisibilityStore.hideEnableCameraScene();
this.scene.sleep(EnableCameraSceneName); this.scene.sleep(EnableCameraSceneName);
gameManager.goToStartingMap(this.scene); gameManager.goToStartingMap();
} }
} }

View File

@ -1,6 +1,6 @@
import { gameManager } from "../Game/GameManager"; import { gameManager } from "../Game/GameManager";
import { Scene } from "phaser"; import { Scene } from "phaser";
import { ErrorScene } from "../Reconnecting/ErrorScene"; import { ErrorScene, ErrorSceneName } from "../Reconnecting/ErrorScene";
import { WAError } from "../Reconnecting/WAError"; import { WAError } from "../Reconnecting/WAError";
import { waScaleManager } from "../Services/WaScaleManager"; import { waScaleManager } from "../Services/WaScaleManager";
@ -36,6 +36,17 @@ export class EntryScene extends Scene {
), ),
this.scene this.scene
); );
} else if (err.response && err.response.status == 403) {
ErrorScene.showError(
new WAError(
"Connection rejected",
"You cannot join the World. Try again later" +
(err.response.data ? ". \n\r \n\r" + `${err.response.data}` : "") +
".",
"If you want more information, you may contact administrator or contact us at: hello@workadventu.re"
),
this.scene
);
} else { } else {
ErrorScene.showError(err, this.scene); ErrorScene.showError(err, this.scene);
} }

View File

@ -1,23 +1,21 @@
import {gameManager} from "../Game/GameManager"; import { gameManager } from "../Game/GameManager";
import {SelectCharacterSceneName} from "./SelectCharacterScene"; import { SelectCharacterSceneName } from "./SelectCharacterScene";
import {ResizableScene} from "./ResizableScene"; import { ResizableScene } from "./ResizableScene";
import {loginSceneVisibleStore} from "../../Stores/LoginSceneStore"; import { loginSceneVisibleStore } from "../../Stores/LoginSceneStore";
export const LoginSceneName = "LoginScene"; export const LoginSceneName = "LoginScene";
export class LoginScene extends ResizableScene { export class LoginScene extends ResizableScene {
private name: string = "";
private name: string = '';
constructor() { constructor() {
super({ super({
key: LoginSceneName key: LoginSceneName,
}); });
this.name = gameManager.getPlayerName() || ''; this.name = gameManager.getPlayerName() || "";
} }
preload() { preload() {}
}
create() { create() {
loginSceneVisibleStore.set(true); loginSceneVisibleStore.set(true);
@ -27,15 +25,13 @@ export class LoginScene extends ResizableScene {
name = name.trim(); name = name.trim();
gameManager.setPlayerName(name); gameManager.setPlayerName(name);
this.scene.stop(LoginSceneName) this.scene.stop(LoginSceneName);
gameManager.tryResumingGame(this, SelectCharacterSceneName); gameManager.tryResumingGame(SelectCharacterSceneName);
this.scene.remove(LoginSceneName); this.scene.remove(LoginSceneName);
loginSceneVisibleStore.set(false); loginSceneVisibleStore.set(false);
} }
update(time: number, delta: number): void { update(time: number, delta: number): void {}
}
public onResize(): void { public onResize(): void {}
}
} }

View File

@ -101,7 +101,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
this.scene.stop(SelectCharacterSceneName); this.scene.stop(SelectCharacterSceneName);
waScaleManager.restoreZoom(); waScaleManager.restoreZoom();
gameManager.setCharacterLayers([this.selectedPlayer.texture.key]); gameManager.setCharacterLayers([this.selectedPlayer.texture.key]);
gameManager.tryResumingGame(this, EnableCameraSceneName); gameManager.tryResumingGame(EnableCameraSceneName);
this.players = []; this.players = [];
selectCharacterSceneVisibleStore.set(false); selectCharacterSceneVisibleStore.set(false);
this.events.removeListener("wake"); this.events.removeListener("wake");

View File

@ -1,18 +1,18 @@
import Image = Phaser.GameObjects.Image; import Image = Phaser.GameObjects.Image;
import Rectangle = Phaser.GameObjects.Rectangle; import Rectangle = Phaser.GameObjects.Rectangle;
import { addLoader } from "../Components/Loader"; import { addLoader } from "../Components/Loader";
import { gameManager} from "../Game/GameManager"; import { gameManager } from "../Game/GameManager";
import { ResizableScene } from "./ResizableScene"; import { ResizableScene } from "./ResizableScene";
import { EnableCameraSceneName } from "./EnableCameraScene"; import { EnableCameraSceneName } from "./EnableCameraScene";
import { localUserStore } from "../../Connexion/LocalUserStore"; import { localUserStore } from "../../Connexion/LocalUserStore";
import type { CompanionResourceDescriptionInterface } from "../Companion/CompanionTextures"; import type { CompanionResourceDescriptionInterface } from "../Companion/CompanionTextures";
import { getAllCompanionResources } from "../Companion/CompanionTexturesLoadingManager"; import { getAllCompanionResources } from "../Companion/CompanionTexturesLoadingManager";
import {touchScreenManager} from "../../Touch/TouchScreenManager"; import { touchScreenManager } from "../../Touch/TouchScreenManager";
import {PinchManager} from "../UserInput/PinchManager"; import { PinchManager } from "../UserInput/PinchManager";
import { MenuScene } from "../Menu/MenuScene"; import { MenuScene } from "../Menu/MenuScene";
import {selectCompanionSceneVisibleStore} from "../../Stores/SelectCompanionStore"; import { selectCompanionSceneVisibleStore } from "../../Stores/SelectCompanionStore";
import {waScaleManager} from "../Services/WaScaleManager"; import { waScaleManager } from "../Services/WaScaleManager";
import {isMobile} from "../../Enum/EnvironmentVariable"; import { isMobile } from "../../Enum/EnvironmentVariable";
export const SelectCompanionSceneName = "SelectCompanionScene"; export const SelectCompanionSceneName = "SelectCompanionScene";
@ -28,12 +28,12 @@ export class SelectCompanionScene extends ResizableScene {
constructor() { constructor() {
super({ super({
key: SelectCompanionSceneName key: SelectCompanionSceneName,
}); });
} }
preload() { preload() {
getAllCompanionResources(this.load).forEach(model => { getAllCompanionResources(this.load).forEach((model) => {
this.companionModels.push(model); this.companionModels.push(model);
}); });
@ -42,7 +42,6 @@ export class SelectCompanionScene extends ResizableScene {
} }
create() { create() {
selectCompanionSceneVisibleStore.set(true); selectCompanionSceneVisibleStore.set(true);
waScaleManager.saveZoom(); waScaleManager.saveZoom();
@ -53,14 +52,16 @@ export class SelectCompanionScene extends ResizableScene {
} }
// input events // input events
this.input.keyboard.on('keyup-ENTER', this.selectCompanion.bind(this)); this.input.keyboard.on("keyup-ENTER", this.selectCompanion.bind(this));
this.input.keyboard.on('keydown-RIGHT', this.moveToRight.bind(this)); this.input.keyboard.on("keydown-RIGHT", this.moveToRight.bind(this));
this.input.keyboard.on('keydown-LEFT', this.moveToLeft.bind(this)); this.input.keyboard.on("keydown-LEFT", this.moveToLeft.bind(this));
if(localUserStore.getCompanion()){ if (localUserStore.getCompanion()) {
const companionIndex = this.companionModels.findIndex((companion) => companion.name === localUserStore.getCompanion()); const companionIndex = this.companionModels.findIndex(
if(companionIndex > -1 || companionIndex < this.companions.length){ (companion) => companion.name === localUserStore.getCompanion()
);
if (companionIndex > -1 || companionIndex < this.companions.length) {
this.currentCompanion = companionIndex; this.currentCompanion = companionIndex;
this.selectedCompanion = this.companions[companionIndex]; this.selectedCompanion = this.companions[companionIndex];
} }
@ -89,26 +90,26 @@ export class SelectCompanionScene extends ResizableScene {
this.closeScene(); this.closeScene();
} }
public closeScene(){ public closeScene() {
// next scene // next scene
this.scene.stop(SelectCompanionSceneName); this.scene.stop(SelectCompanionSceneName);
waScaleManager.restoreZoom(); waScaleManager.restoreZoom();
gameManager.tryResumingGame(this, EnableCameraSceneName); gameManager.tryResumingGame(EnableCameraSceneName);
this.scene.remove(SelectCompanionSceneName); this.scene.remove(SelectCompanionSceneName);
selectCompanionSceneVisibleStore.set(false); selectCompanionSceneVisibleStore.set(false);
} }
private createCurrentCompanion(): void { private createCurrentCompanion(): void {
for (let i = 0; i < this.companionModels.length; i++) { for (let i = 0; i < this.companionModels.length; i++) {
const companionResource = this.companionModels[i] const companionResource = this.companionModels[i];
const [middleX, middleY] = this.getCompanionPosition(); const [middleX, middleY] = this.getCompanionPosition();
const companion = this.physics.add.sprite(middleX, middleY, companionResource.name, 0); const companion = this.physics.add.sprite(middleX, middleY, companionResource.name, 0);
this.setUpCompanion(companion, i); this.setUpCompanion(companion, i);
this.anims.create({ this.anims.create({
key: companionResource.name, key: companionResource.name,
frames: this.anims.generateFrameNumbers(companionResource.name, {start: 0, end: 2,}), frames: this.anims.generateFrameNumbers(companionResource.name, { start: 0, end: 2 }),
frameRate: 10, frameRate: 10,
repeat: -1 repeat: -1,
}); });
companion.setInteractive().on("pointerdown", () => { companion.setInteractive().on("pointerdown", () => {
@ -140,87 +141,84 @@ export class SelectCompanionScene extends ResizableScene {
this.selectedCompanion = companion; this.selectedCompanion = companion;
} }
private moveCompanion(){ private moveCompanion() {
for(let i = 0; i < this.companions.length; i++){ for (let i = 0; i < this.companions.length; i++) {
const companion = this.companions[i]; const companion = this.companions[i];
this.setUpCompanion(companion, i); this.setUpCompanion(companion, i);
} }
this.updateSelectedCompanion(); this.updateSelectedCompanion();
} }
public moveToRight(){ public moveToRight() {
if(this.currentCompanion === (this.companions.length - 1)){ if (this.currentCompanion === this.companions.length - 1) {
return; return;
} }
this.currentCompanion += 1; this.currentCompanion += 1;
this.moveCompanion(); this.moveCompanion();
} }
public moveToLeft(){ public moveToLeft() {
if(this.currentCompanion === 0){ if (this.currentCompanion === 0) {
return; return;
} }
this.currentCompanion -= 1; this.currentCompanion -= 1;
this.moveCompanion(); this.moveCompanion();
} }
private defineSetupCompanion(num: number){ private defineSetupCompanion(num: number) {
const deltaX = 30; const deltaX = 30;
const deltaY = 2; const deltaY = 2;
let [companionX, companionY] = this.getCompanionPosition(); let [companionX, companionY] = this.getCompanionPosition();
let companionVisible = true; let companionVisible = true;
let companionScale = 1.5; let companionScale = 1.5;
let companionOpactity = 1; let companionOpactity = 1;
if( this.currentCompanion !== num ){ if (this.currentCompanion !== num) {
companionVisible = false; companionVisible = false;
} }
if( num === (this.currentCompanion + 1) ){ if (num === this.currentCompanion + 1) {
companionY -= deltaY; companionY -= deltaY;
companionX += deltaX; companionX += deltaX;
companionScale = 0.8; companionScale = 0.8;
companionOpactity = 0.6; companionOpactity = 0.6;
companionVisible = true; companionVisible = true;
} }
if( num === (this.currentCompanion + 2) ){ if (num === this.currentCompanion + 2) {
companionY -= deltaY; companionY -= deltaY;
companionX += (deltaX * 2); companionX += deltaX * 2;
companionScale = 0.8; companionScale = 0.8;
companionOpactity = 0.6; companionOpactity = 0.6;
companionVisible = true; companionVisible = true;
} }
if( num === (this.currentCompanion - 1) ){ if (num === this.currentCompanion - 1) {
companionY -= deltaY; companionY -= deltaY;
companionX -= deltaX; companionX -= deltaX;
companionScale = 0.8; companionScale = 0.8;
companionOpactity = 0.6; companionOpactity = 0.6;
companionVisible = true; companionVisible = true;
} }
if( num === (this.currentCompanion - 2) ){ if (num === this.currentCompanion - 2) {
companionY -= deltaY; companionY -= deltaY;
companionX -= (deltaX * 2); companionX -= deltaX * 2;
companionScale = 0.8; companionScale = 0.8;
companionOpactity = 0.6; companionOpactity = 0.6;
companionVisible = true; companionVisible = true;
} }
return {companionX, companionY, companionScale, companionOpactity, companionVisible} return { companionX, companionY, companionScale, companionOpactity, companionVisible };
} }
/** /**
* Returns pixel position by on column and row number * Returns pixel position by on column and row number
*/ */
private getCompanionPosition(): [number, number] { private getCompanionPosition(): [number, number] {
return [ return [this.game.renderer.width / 2, this.game.renderer.height / 3];
this.game.renderer.width / 2,
this.game.renderer.height / 3
];
} }
private setUpCompanion(companion: Phaser.Physics.Arcade.Sprite, numero: number){ private setUpCompanion(companion: Phaser.Physics.Arcade.Sprite, numero: number) {
const { companionX, companionY, companionScale, companionOpactity, companionVisible } =
const {companionX, companionY, companionScale, companionOpactity, companionVisible} = this.defineSetupCompanion(numero); this.defineSetupCompanion(numero);
companion.setBounce(0.2); companion.setBounce(0.2);
companion.setCollideWorldBounds(true); companion.setCollideWorldBounds(true);
companion.setVisible( companionVisible ); companion.setVisible(companionVisible);
companion.setScale(companionScale, companionScale); companion.setScale(companionScale, companionScale);
companion.setAlpha(companionOpactity); companion.setAlpha(companionOpactity);
companion.setX(companionX); companion.setX(companionX);

View File

@ -171,7 +171,7 @@ export class MenuScene extends Phaser.Scene {
this.closeAll(); this.closeAll();
this.sideMenuOpened = true; this.sideMenuOpened = true;
this.menuButton.getChildByID("openMenuButton").innerHTML = "X"; this.menuButton.getChildByID("openMenuButton").innerHTML = "X";
const connection = gameManager.getCurrentGameScene(this).connection; const connection = gameManager.getCurrentGameScene().connection;
if (connection && connection.isAdmin()) { if (connection && connection.isAdmin()) {
const adminSection = this.menuElement.getChildByID("adminConsoleSection") as HTMLElement; const adminSection = this.menuElement.getChildByID("adminConsoleSection") as HTMLElement;
adminSection.hidden = false; adminSection.hidden = false;
@ -322,18 +322,18 @@ export class MenuScene extends Phaser.Scene {
switch ((event?.target as HTMLInputElement).id) { switch ((event?.target as HTMLInputElement).id) {
case "changeNameButton": case "changeNameButton":
this.closeSideMenu(); this.closeSideMenu();
gameManager.leaveGame(this, LoginSceneName, new LoginScene()); gameManager.leaveGame(LoginSceneName, new LoginScene());
break; break;
case "sparkButton": case "sparkButton":
this.gotToCreateMapPage(); this.gotToCreateMapPage();
break; break;
case "changeSkinButton": case "changeSkinButton":
this.closeSideMenu(); this.closeSideMenu();
gameManager.leaveGame(this, SelectCharacterSceneName, new SelectCharacterScene()); gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
break; break;
case "changeCompanionButton": case "changeCompanionButton":
this.closeSideMenu(); this.closeSideMenu();
gameManager.leaveGame(this, SelectCompanionSceneName, new SelectCompanionScene()); gameManager.leaveGame(SelectCompanionSceneName, new SelectCompanionScene());
break; break;
case "closeButton": case "closeButton":
this.closeSideMenu(); this.closeSideMenu();

View File

@ -62,7 +62,7 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
this.opened = true; this.opened = true;
gameManager.getCurrentGameScene(this.scene).userInputManager.disableControls(); gameManager.getCurrentGameScene().userInputManager.disableControls();
this.scene.tweens.add({ this.scene.tweens.add({
targets: this, targets: this,
@ -73,7 +73,7 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
} }
public close(): void { public close(): void {
gameManager.getCurrentGameScene(this.scene).userInputManager.restoreControls(); gameManager.getCurrentGameScene().userInputManager.restoreControls();
this.opened = false; this.opened = false;
const mainEl = this.getChildByID("gameReport") as HTMLElement; const mainEl = this.getChildByID("gameReport") as HTMLElement;
this.scene.tweens.add({ this.scene.tweens.add({
@ -112,9 +112,7 @@ export class ReportMenu extends Phaser.GameObjects.DOMElement {
gamePError.style.display = "block"; gamePError.style.display = "block";
return; return;
} }
gameManager gameManager.getCurrentGameScene().connection?.emitReportPlayerMessage(this.userUuid, gameTextArea.value);
.getCurrentGameScene(this.scene)
.connection?.emitReportPlayerMessage(this.userUuid, gameTextArea.value);
this.close(); this.close();
} }
} }

View File

@ -90,7 +90,11 @@ export class ErrorScene extends Phaser.Scene {
// Axios HTTP error // Axios HTTP error
// client received an error response (5xx, 4xx) // client received an error response (5xx, 4xx)
scene.start(ErrorSceneName, { scene.start(ErrorSceneName, {
title: "HTTP " + error.response.status + " - " + error.response.statusText, title:
"HTTP " +
error.response.status +
" - " +
(error.response.data ? error.response.data : error.response.statusText),
subTitle: "An error occurred while accessing URL:", subTitle: "An error occurred while accessing URL:",
message: error.response.config.url, message: error.response.config.url,
}); });

View File

@ -29,7 +29,12 @@ export class BaseController {
if (e.response) { if (e.response) {
res.writeStatus(e.response.status + " " + e.response.statusText); res.writeStatus(e.response.status + " " + e.response.statusText);
this.addCorsHeaders(res); this.addCorsHeaders(res);
res.end("An error occurred: " + e.response.status + " " + e.response.statusText); res.end(
"An error occurred: " +
e.response.status +
" " +
(e.response.data && e.response.data.message ? e.response.data.message : e.response.statusText)
);
} else { } else {
res.writeStatus("500 Internal Server Error"); res.writeStatus("500 Internal Server Error");
this.addCorsHeaders(res); this.addCorsHeaders(res);

View File

@ -174,7 +174,7 @@ export class IoSocketController {
} }
const tokenData = const tokenData =
token && typeof token === "string" ? jwtTokenManager.decodeJWTToken(token) : null; token && typeof token === "string" ? jwtTokenManager.verifyJWTToken(token) : null;
const userIdentifier = tokenData ? tokenData.identifier : ""; const userIdentifier = tokenData ? tokenData.identifier : "";
let memberTags: string[] = []; let memberTags: string[] = [];

View File

@ -5,6 +5,9 @@ import { adminApi } from "../Services/AdminApi";
import { ADMIN_API_URL } from "../Enum/EnvironmentVariable"; import { ADMIN_API_URL } from "../Enum/EnvironmentVariable";
import { GameRoomPolicyTypes } from "../Model/PusherRoom"; import { GameRoomPolicyTypes } from "../Model/PusherRoom";
import { MapDetailsData } from "../Services/AdminApi/MapDetailsData"; import { MapDetailsData } from "../Services/AdminApi/MapDetailsData";
import { socketManager } from "../Services/SocketManager";
import { AuthTokenData, jwtTokenManager } from "../Services/JWTTokenManager";
import { v4 } from "uuid";
export class MapController extends BaseController { export class MapController extends BaseController {
constructor(private App: TemplatedApp) { constructor(private App: TemplatedApp) {
@ -67,7 +70,20 @@ export class MapController extends BaseController {
(async () => { (async () => {
try { try {
const mapDetails = await adminApi.fetchMapDetails(query.playUri as string); let userId: string | undefined = undefined;
if (query.authToken != undefined) {
let authTokenData: AuthTokenData;
try {
authTokenData = jwtTokenManager.verifyJWTToken(query.authToken as string);
userId = authTokenData.identifier;
} catch (e) {
// Decode token, in this case we don't need to create new token.
authTokenData = jwtTokenManager.verifyJWTToken(query.authToken as string, true);
userId = authTokenData.identifier;
console.info("JWT expire, but decoded", userId);
}
}
const mapDetails = await adminApi.fetchMapDetails(query.playUri as string, userId);
res.writeStatus("200 OK"); res.writeStatus("200 OK");
this.addCorsHeaders(res); this.addCorsHeaders(res);

View File

@ -31,13 +31,19 @@ export interface FetchMemberDataByUuidResponse {
} }
class AdminApi { class AdminApi {
async fetchMapDetails(playUri: string): Promise<MapDetailsData | RoomRedirect> { /**
* @var playUri: is url of the room
* @var userId: can to be undefined or email or uuid
* @return MapDetailsData|RoomRedirect
*/
async fetchMapDetails(playUri: string, userId?: string): Promise<MapDetailsData | RoomRedirect> {
if (!ADMIN_API_URL) { if (!ADMIN_API_URL) {
return Promise.reject(new Error("No admin backoffice set!")); return Promise.reject(new Error("No admin backoffice set!"));
} }
const params: { playUri: string } = { const params: { playUri: string; userId?: string } = {
playUri, playUri,
userId,
}; };
const res = await Axios.get(ADMIN_API_URL + "/api/map", { const res = await Axios.get(ADMIN_API_URL + "/api/map", {

View File

@ -15,9 +15,9 @@ class JWTTokenManager {
return Jwt.sign({ identifier }, SECRET_KEY, { expiresIn: "200d" }); return Jwt.sign({ identifier }, SECRET_KEY, { expiresIn: "200d" });
} }
public decodeJWTToken(token: string): AuthTokenData { public verifyJWTToken(token: string, ignoreExpiration: boolean = false): AuthTokenData {
try { try {
return Jwt.verify(token, SECRET_KEY, { ignoreExpiration: false }) as AuthTokenData; return Jwt.verify(token, SECRET_KEY, { ignoreExpiration }) as AuthTokenData;
} catch (e) { } catch (e) {
throw { reason: tokenInvalidException, message: e.message }; throw { reason: tokenInvalidException, message: e.message };
} }