diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 2334111e..4a1c9240 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -14,7 +14,7 @@ import si from "systeminformation"; import {Gauge} from "prom-client"; import {TokenInterface} from "../Controller/AuthenticateController"; import {isJoinRoomMessageInterface} from "../Model/Websocket/JoinRoomMessage"; -import {isPointInterface, PointInterface} from "../Model/Websocket/PointInterface"; +import {PointInterface} from "../Model/Websocket/PointInterface"; import {isWebRtcSignalMessageInterface} from "../Model/Websocket/WebRtcSignalMessage"; import {UserInGroupInterface} from "../Model/Websocket/UserInGroupInterface"; import {isItemEventMessageInterface} from "../Model/Websocket/ItemEventMessage"; @@ -27,7 +27,7 @@ import { SetPlayerDetailsMessage, SubMessage, UserMovedMessage, - BatchMessage + BatchMessage, GroupUpdateMessage, PointMessage } from "../../../messages/generated/messages_pb"; import {UserMovesMessage} from "../../../messages/generated/messages_pb"; import Direction = PositionMessage.Direction; @@ -90,7 +90,7 @@ export class IoSocketController { // Authentication with token. it will be decoded and stored in the socket. // Completely commented for now, as we do not use the "/login" route at all. this.Io.use((socket: Socket, next) => { - console.log(socket.handshake.query.token); + //console.log(socket.handshake.query.token); if (!socket.handshake.query || !socket.handshake.query.token) { console.error('An authentication error happened, a user tried to connect without a token.'); return next(new Error('Authentication error')); @@ -176,8 +176,8 @@ export class IoSocketController { const srvSockets = this.Io.sockets.sockets; this.nbClientsGauge.inc(); console.log(new Date().toISOString() + ' A user joined (', Object.keys(srvSockets).length, ' connected users)'); - si.currentLoad().then(data => console.log(' Current load: ', data.avgload)); - si.currentLoad().then(data => console.log(' CPU: ', data.currentload, '%')); + //si.currentLoad().then(data => console.log(' Current load: ', data.avgload)); + //si.currentLoad().then(data => console.log(' CPU: ', data.currentload, '%')); // End log server load /*join-rom event permit to join one room. @@ -189,7 +189,7 @@ export class IoSocketController { y: user y position on map */ socket.on(SocketIoEvent.JOIN_ROOM, (message: unknown, answerFn): void => { - console.log(SocketIoEvent.JOIN_ROOM, message); + //console.log(SocketIoEvent.JOIN_ROOM, message); try { if (!isJoinRoomMessageInterface(message)) { socket.emit(SocketIoEvent.MESSAGE_ERROR, {message: 'Invalid JOIN_ROOM message.'}); @@ -374,8 +374,8 @@ export class IoSocketController { const srvSockets = this.Io.sockets.sockets; this.nbClientsGauge.dec(); console.log('A user left (', Object.keys(srvSockets).length, ' connected users)'); - si.currentLoad().then(data => console.log('Current load: ', data.avgload)); - si.currentLoad().then(data => console.log('CPU: ', data.currentload, '%')); + //si.currentLoad().then(data => console.log('Current load: ', data.avgload)); + //si.currentLoad().then(data => console.log('CPU: ', data.currentload, '%')); // End log server load }); @@ -408,7 +408,7 @@ export class IoSocketController { }); socket.on(SocketIoEvent.SET_SILENT, (silent: unknown) => { - console.log(SocketIoEvent.SET_SILENT, silent); + //console.log(SocketIoEvent.SET_SILENT, silent); if (typeof silent !== "boolean") { socket.emit(SocketIoEvent.MESSAGE_ERROR, {message: 'Invalid SET_SILENT message.'}); console.warn('Invalid SET_SILENT message received: ', silent); @@ -543,10 +543,7 @@ export class IoSocketController { clientListener.emit(SocketIoEvent.JOIN_ROOM, messageUserJoined); } else if (thing instanceof Group) { - clientListener.emit(SocketIoEvent.GROUP_CREATE_UPDATE, { - position: thing.getPosition(), - groupId: thing.getId() - } as GroupUpdateInterface); + this.emitCreateUpdateGroupEvent(clientListener, thing); } else { console.error('Unexpected type for Movable.'); } @@ -565,10 +562,7 @@ export class IoSocketController { clientListener.emitInBatch(SocketIoEvent.USER_MOVED, subMessage); //console.log("Sending USER_MOVED event"); } else if (thing instanceof Group) { - clientListener.emit(SocketIoEvent.GROUP_CREATE_UPDATE, { - position: thing.getPosition(), - groupId: thing.getId() - } as GroupUpdateInterface); + this.emitCreateUpdateGroupEvent(clientListener, thing); } else { console.error('Unexpected type for Movable.'); } @@ -600,6 +594,18 @@ export class IoSocketController { return world; } + private emitCreateUpdateGroupEvent(socket: Socket, group: Group): void { + const position = group.getPosition(); + const pointMessage = new PointMessage(); + pointMessage.setX(Math.floor(position.x)); + pointMessage.setY(Math.floor(position.y)); + const groupUpdateMessage = new GroupUpdateMessage(); + groupUpdateMessage.setGroupid(group.getId()); + groupUpdateMessage.setPosition(pointMessage); + + socket.emit(SocketIoEvent.GROUP_CREATE_UPDATE, groupUpdateMessage.serializeBinary().buffer); + } + /** * * @param socket diff --git a/back/src/Model/Group.ts b/back/src/Model/Group.ts index 43990ef4..4364455d 100644 --- a/back/src/Model/Group.ts +++ b/back/src/Model/Group.ts @@ -13,6 +13,8 @@ export class Group implements Movable { private users: Set; private connectCallback: ConnectCallback; private disconnectCallback: DisconnectCallback; + private x!: number; + private y!: number; constructor(users: User[], connectCallback: ConnectCallback, disconnectCallback: DisconnectCallback) { @@ -25,6 +27,8 @@ export class Group implements Movable { users.forEach((user: User) => { this.join(user); }); + + this.updatePosition(); } getUsers(): User[] { @@ -39,6 +43,16 @@ export class Group implements Movable { * Returns the barycenter of all users (i.e. the center of the group) */ getPosition(): PositionInterface { + return { + x: this.x, + y: this.y + }; + } + + /** + * Computes the barycenter of all users (i.e. the center of the group) + */ + updatePosition(): void { let x = 0; let y = 0; // Let's compute the barycenter of all users. @@ -48,10 +62,11 @@ export class Group implements Movable { }); x /= this.users.size; y /= this.users.size; - return { - x, - y - }; + if (this.users.size === 0) { + throw new Error("EMPTY GROUP FOUND!!!"); + } + this.x = x; + this.y = y; } isFull(): boolean { diff --git a/back/src/Model/World.ts b/back/src/Model/World.ts index dc3dcd07..452c6c17 100644 --- a/back/src/Model/World.ts +++ b/back/src/Model/World.ts @@ -90,6 +90,7 @@ export class World { this.positionNotifier.updatePosition(user, userPosition, user.position); const oldGroupPosition = user.group?.getPosition(); + user.group?.updatePosition(); user.position = userPosition; @@ -126,7 +127,7 @@ export class World { } // At the very end, if the user is part of a group, let's call the callback to update group position - if (typeof user.group !== 'undefined') { + if (user.group !== undefined) { this.positionNotifier.updatePosition(user.group, user.group.getPosition(), oldGroupPosition ? oldGroupPosition : user.group.getPosition()); } } @@ -158,7 +159,7 @@ export class World { */ private leaveGroup(user: User): void { const group = user.group; - if (typeof group === 'undefined') { + if (group === undefined) { throw new Error("The user is part of no group"); } group.leave(user); diff --git a/front/src/Connection.ts b/front/src/Connection.ts index fa04feb8..02752c10 100644 --- a/front/src/Connection.ts +++ b/front/src/Connection.ts @@ -2,7 +2,7 @@ import Axios from "axios"; import {API_URL} from "./Enum/EnvironmentVariable"; import {MessageUI} from "./Logger/MessageUI"; import { - BatchMessage, + BatchMessage, GroupUpdateMessage, PositionMessage, SetPlayerDetailsMessage, UserMovedMessage, UserMovesMessage, @@ -78,7 +78,7 @@ export interface PositionInterface { export interface GroupCreatedUpdatedMessageInterface { position: PositionInterface, - groupId: string + groupId: number } export interface WebRtcStartMessageInterface { @@ -301,10 +301,31 @@ export class Connection implements Connection { } public onGroupUpdatedOrCreated(callback: (groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface) => void): void { - this.socket.on(EventMessage.GROUP_CREATE_UPDATE, callback); + // TODO: READ THIS FROM BINARY FORMAT + // TODO: READ THIS FROM BINARY FORMAT + // TODO: READ THIS FROM BINARY FORMAT + // TODO: CHANGE THIS EVENT TO BE PART OF THE BATCHES + // TODO: CHANGE THIS EVENT TO BE PART OF THE BATCHES + // TODO: CHANGE THIS EVENT TO BE PART OF THE BATCHES + // TODO: CHANGE THIS EVENT TO BE PART OF THE BATCHES + // TODO: CHANGE THIS EVENT TO BE PART OF THE BATCHES + this.socket.on(EventMessage.GROUP_CREATE_UPDATE, (buffer: ArrayBuffer) => { + const message = GroupUpdateMessage.deserializeBinary(new Uint8Array(buffer)); + const position = message.getPosition(); + if (position === undefined) { + throw new Error('Missing position in GROUP_CREATE_UPDATE'); + } + + const groupCreateUpdateMessage: GroupCreatedUpdatedMessageInterface = { + groupId: message.getGroupid(), + position: position.toObject() + } + + callback(groupCreateUpdateMessage); + }); } - public onGroupDeleted(callback: (groupId: string) => void): void { + public onGroupDeleted(callback: (groupId: number) => void): void { this.socket.on(EventMessage.GROUP_DELETE, callback) } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index c7a7fd3e..8abddfd3 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -80,7 +80,7 @@ interface GroupCreatedUpdatedEventInterface { interface DeleteGroupEventInterface { type: 'DeleteGroupEvent' - groupId: string + groupId: number } export class GameScene extends Phaser.Scene implements CenterListener { @@ -93,7 +93,7 @@ export class GameScene extends Phaser.Scene implements CenterListener { Layers!: Array; Objects!: Array; mapFile!: ITiledMap; - groups: Map; + groups: Map; startX!: number; startY!: number; circleTexture!: CanvasTexture; @@ -149,7 +149,7 @@ export class GameScene extends Phaser.Scene implements CenterListener { this.GameManager = gameManager; this.Terrains = []; - this.groups = new Map(); + this.groups = new Map(); this.instance = instance; this.MapKey = MapKey; @@ -237,7 +237,7 @@ export class GameScene extends Phaser.Scene implements CenterListener { this.shareGroupPosition(groupPositionMessage); }) - connection.onGroupDeleted((groupId: string) => { + connection.onGroupDeleted((groupId: number) => { try { this.deleteGroup(groupId); } catch (e) { @@ -1108,14 +1108,14 @@ export class GameScene extends Phaser.Scene implements CenterListener { } } - deleteGroup(groupId: string): void { + deleteGroup(groupId: number): void { this.pendingEvents.enqueue({ type: "DeleteGroupEvent", groupId }); } - doDeleteGroup(groupId: string): void { + doDeleteGroup(groupId: number): void { const group = this.groups.get(groupId); if(!group){ return;