diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 1d5bbe06..5f1bc47f 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -33,7 +33,8 @@ enum SockerIoEvent { MESSAGE_ERROR = "message-error", GROUP_CREATE_UPDATE = "group-create-update", GROUP_DELETE = "group-delete", - SET_PLAYER_DETAILS = "set-player-details" + SET_PLAYER_DETAILS = "set-player-details", + SET_SILENT = "set_silent", // Set or unset the silent mode for this user. } export class IoSocketController { @@ -274,6 +275,29 @@ export class IoSocketController { Client.characterLayers = playerDetails.characterLayers; answerFn(Client.userId); }); + + socket.on(SockerIoEvent.SET_SILENT, (silent: unknown) => { + if (typeof silent !== "boolean") { + socket.emit(SockerIoEvent.MESSAGE_ERROR, {message: 'Invalid SET_SILENT message.'}); + console.warn('Invalid SET_SILENT message received: ', silent); + return; + } + + try { + const Client = (socket as ExSocketInterface); + + // update position in the world + const world = this.Worlds.get(Client.roomId); + if (!world) { + console.error("Could not find world with id '", Client.roomId, "'"); + return; + } + world.setSilent(Client, silent); + } catch (e) { + console.error('An error occurred on "SET_SILENT"'); + console.error(e); + } + }); }); } diff --git a/back/src/Model/UserInterface.ts b/back/src/Model/UserInterface.ts index 743f8b4d..89994a31 100644 --- a/back/src/Model/UserInterface.ts +++ b/back/src/Model/UserInterface.ts @@ -4,5 +4,6 @@ import { PointInterface } from "./Websocket/PointInterface"; export interface UserInterface { id: string, group?: Group, - position: PointInterface -} \ No newline at end of file + position: PointInterface, + silent: boolean +} diff --git a/back/src/Model/World.ts b/back/src/Model/World.ts index 6d4fc205..8855702e 100644 --- a/back/src/Model/World.ts +++ b/back/src/Model/World.ts @@ -55,7 +55,8 @@ export class World { public join(socket : Identificable, userPosition: PointInterface): void { this.users.set(socket.userId, { id: socket.userId, - position: userPosition + position: userPosition, + silent: false // FIXME: silent should be set at the correct value when joining a room. }); // Let's call update position to trigger the join / leave room this.updatePosition(socket, userPosition); @@ -84,6 +85,10 @@ export class World { user.position = userPosition; + if (user.silent) { + return; + } + if (typeof user.group === 'undefined') { // If the user is not part of a group: // should he join a group? @@ -118,6 +123,26 @@ export class World { } } + setSilent(socket: Identificable, silent: boolean) { + const user = this.users.get(socket.userId); + if(typeof user === 'undefined') { + console.warn('In setSilent, could not find user with ID "'+socket.userId+'" in world.'); + return; + } + if (user.silent === silent) { + return; + } + + user.silent = silent; + if (silent && user.group !== undefined) { + this.leaveGroup(user); + } + if (!silent) { + // If we are back to life, let's trigger a position update to see if we can join some group. + this.updatePosition(socket, user.position); + } + } + /** * Makes a user leave a group and closes and destroy the group if the group contains only one remaining person. * @@ -145,6 +170,7 @@ export class World { * Looks for the closest user that is: * - close enough (distance <= minDistance) * - not in a group + * - not silent * OR * - close enough to a group (distance <= groupRadius) */ @@ -160,6 +186,9 @@ export class World { if(currentUser === user) { return; } + if (currentUser.silent) { + return; + } const distance = World.computeDistance(user, currentUser); // compute distance between peers. diff --git a/front/src/Connection.ts b/front/src/Connection.ts index 783b5d41..4a184c52 100644 --- a/front/src/Connection.ts +++ b/front/src/Connection.ts @@ -24,6 +24,7 @@ enum EventMessage{ SET_PLAYER_DETAILS = "set-player-details", // Send the name and character to the server (on connect), receive back the id. CONNECT_ERROR = "connect_error", + SET_SILENT = "set_silent", // Set or unset the silent mode for this user. } export interface PointInterface { @@ -167,6 +168,10 @@ export class Connection implements Connection { this.socket.emit(EventMessage.USER_POSITION, point); } + public setSilent(silent: boolean): void { + this.socket.emit(EventMessage.SET_SILENT, silent); + } + public onUserJoins(callback: (message: MessageUserJoined) => void): void { this.socket.on(EventMessage.JOIN_ROOM, callback); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 485b7dce..c30bdf61 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -423,9 +423,10 @@ export class GameScene extends Phaser.Scene implements CenterListener { CoWebsiteManager.loadCoWebsite(newValue as string); } }); - let jitsiApi: any; + let jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue) => { if (newValue === undefined) { + this.connection.setSilent(false); jitsiApi?.dispose(); CoWebsiteManager.closeCoWebsite(); } else { @@ -444,9 +445,10 @@ export class GameScene extends Phaser.Scene implements CenterListener { MOBILE_APP_PROMO: false } }; - jitsiApi = new (window as any).JitsiMeetExternalAPI(domain, options); + jitsiApi = new (window as any).JitsiMeetExternalAPI(domain, options); // eslint-disable-line @typescript-eslint/no-explicit-any jitsiApi.executeCommand('displayName', gameManager.getPlayerName()); - })) + })); + this.connection.setSilent(true); } }); }