diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index aefd52f0..b2c9ea7e 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -165,10 +165,10 @@ export class IoSocketController { const room = await socketManager.getOrCreateRoom(roomId); //TODO http return status - /*if (room.isFull()) { - res.writeStatus("503").end('Too many users'); - return; + /*if (room.isFull) { + throw new Error('Room is full'); }*/ + try { const userData = await adminApi.fetchMemberDataByUuid(userUuid); //console.log('USERDATA', userData) @@ -239,14 +239,13 @@ export class IoSocketController { (async () => { // Let's join the room const client = this.initClient(ws); //todo: into the upgrade instead? - socketManager.handleJoinRoom(client); - resetPing(client); - //if room is full, emit redirect room message - const room = await socketManager.getOrCreateRoom(client.roomId); - if (room.isFull) { - socketManager.emitCloseMessage(client.userUuid, 302); - return; + const room = socketManager.getRoomById(client.roomId); + if (room && room.isFull) { + socketManager.emitCloseMessage(client, 302); + }else { + socketManager.handleJoinRoom(client); + resetPing(client); } //get data information and shwo messages @@ -263,13 +262,20 @@ export class IoSocketController { message: messageToSend.message }) }); - }catch(err) { + } catch (err) { console.error('fetchMemberDataByUuid => err', err); - }; + } })(); }, message: (ws, arrayBuffer, isBinary): void => { + const client = ws as ExSocketInterface; + + const room = socketManager.getRoomById(client.roomId); + if (room && room.isFull) { + return; + } + const message = ClientToServerMessage.deserializeBinary(new Uint8Array(arrayBuffer)); if (message.hasViewportmessage()) { @@ -293,7 +299,6 @@ export class IoSocketController { } else if (message.hasQueryjitsijwtmessage()){ socketManager.handleQueryJitsiJwtMessage(client, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage); } - /* Ok is false if backpressure was built up, wait for drain */ //let ok = ws.send(message, isBinary); }, diff --git a/back/src/Services/SocketManager.ts b/back/src/Services/SocketManager.ts index d1ffab59..1ec9ab20 100644 --- a/back/src/Services/SocketManager.ts +++ b/back/src/Services/SocketManager.ts @@ -408,6 +408,10 @@ export class SocketManager { return Promise.resolve(world) } + getRoomById(roomId: string) { + return this.Worlds.get(roomId); + } + private joinRoom(client : ExSocketInterface, position: PointInterface): GameRoom { const roomId = client.roomId; @@ -695,12 +699,7 @@ export class SocketManager { return socket; } - public emitCloseMessage(userUuid: string, status: number): ExSocketInterface { - const socket = this.searchClientByUuid(userUuid); - if(!socket){ - throw 'socket was not found'; - } - + public emitCloseMessage(socket: ExSocketInterface, status: number): ExSocketInterface { const closeMessage = new CloseMessage(); closeMessage.setStatus(status); diff --git a/front/src/Connexion/ConnectionManager.ts b/front/src/Connexion/ConnectionManager.ts index 997d06f0..7f3c1c41 100644 --- a/front/src/Connexion/ConnectionManager.ts +++ b/front/src/Connexion/ConnectionManager.ts @@ -97,8 +97,7 @@ class ConnectionManager { return new Promise((resolve, reject) => { const connection = new RoomConnection(this.localUser.jwtToken, roomId, name, characterLayers, position, viewport); connection.onConnectError((error: object) => { - console.log(error); - if (false) { //todo: how to check error type? + if (error) { //todo: how to check error type? reject(connexionErrorTypes.tooManyUsers); } else { reject(connexionErrorTypes.serverError); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index c11d18a4..7c9d5fd5 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -56,6 +56,7 @@ import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMes import {ResizableScene} from "../Login/ResizableScene"; import {Room} from "../../Connexion/Room"; import {MessageUI} from "../../Logger/MessageUI"; +import {WaitScene} from "../Reconnecting/WaitScene"; export enum Textures { @@ -620,7 +621,32 @@ export class GameScene extends ResizableScene implements CenterListener { connection.onCloseMessage((status: number) => { console.log(`close message status : ${status}`); + //TODO show wait room + this.connection.closeConnection(); + this.simplePeer.unregister(); + connection.closeConnection(); + + const waitGameSceneKey = 'somekey' + Math.round(Math.random() * 10000); + //show wait scene + setTimeout(() => { + const game: Phaser.Scene = new WaitScene(waitGameSceneKey, status); + this.scene.add(waitGameSceneKey, game, true, { + initPosition: { + x: this.CurrentPlayer.x, + y: this.CurrentPlayer.y + } + }); + this.scene.stop(this.scene.key); + this.scene.start(waitGameSceneKey); + }, 500); + + //trying to reload map + setTimeout(() => { + this.scene.stop(waitGameSceneKey); + this.scene.remove(waitGameSceneKey); + this.scene.start(this.scene.key); + }, 30000); }); // When connection is performed, let's connect SimplePeer @@ -1168,6 +1194,7 @@ export class GameScene extends ResizableScene implements CenterListener { const positionX = 48; const positionY = 48; + console.log('doShareGroupPosition', groupSize); let texture = 'circleSprite-red'; if(groupSize < 4){ texture = 'circleSprite-white'; diff --git a/front/src/Phaser/Reconnecting/WaitScene.ts b/front/src/Phaser/Reconnecting/WaitScene.ts new file mode 100644 index 00000000..0d4df895 --- /dev/null +++ b/front/src/Phaser/Reconnecting/WaitScene.ts @@ -0,0 +1,70 @@ +import {TextField} from "../Components/TextField"; +import Image = Phaser.GameObjects.Image; + +enum ReconnectingTextures { + icon = "icon", + mainFont = "main_font" +} + +export class WaitScene extends Phaser.Scene { + private reconnectingField!: TextField; + private logo!: Image; + private text: string = ''; + + constructor(key: string, private readonly status: number) { + super({ + key: key + }); + this.initialiseText(); + } + + initialiseText() { + this.text = `${this.status}` + '\n' + '\n'; + switch (this.status) { + case 302: + this.text += 'Aie ! Work Adventure est victime de son succes, ' + + '\n' + + '\n' + + 'le nombre maximum de joueurs a ete atteint !' + + '\n' + + '\n' + + `Reconnexion dans 30 secondes ...`; + break; + } + } + + preload() { + this.load.image(ReconnectingTextures.icon, "resources/logos/tcm_full.png"); + // Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap + this.load.bitmapFont(ReconnectingTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); + this.load.spritesheet( + 'cat', + 'resources/characters/pipoya/Cat 01-1.png', + {frameWidth: 32, frameHeight: 32} + ); + } + + create() { + this.logo = new Image(this, this.game.renderer.width - 30, this.game.renderer.height - 20, ReconnectingTextures.icon); + this.add.existing(this.logo); + + this.reconnectingField = new TextField( + this, + this.game.renderer.width / 2, + this.game.renderer.height / 2, + this.text); + + const cat = this.physics.add.sprite( + this.game.renderer.width / 2, + this.game.renderer.height / 2 - 70, + 'cat'); + + this.anims.create({ + key: 'right', + frames: this.anims.generateFrameNumbers('cat', {start: 6, end: 8}), + frameRate: 10, + repeat: -1 + }); + cat.play('right'); + } +}