diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 9110702e..57e204f4 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -27,7 +27,13 @@ import { SetPlayerDetailsMessage, SubMessage, UserMovedMessage, - BatchMessage, GroupUpdateMessage, PointMessage, GroupDeleteMessage, UserJoinedMessage, UserLeftMessage + BatchMessage, + GroupUpdateMessage, + PointMessage, + GroupDeleteMessage, + UserJoinedMessage, + UserLeftMessage, + ItemEventMessage } from "../Messages/generated/messages_pb"; import {UserMovesMessage} from "../Messages/generated/messages_pb"; import Direction = PositionMessage.Direction; @@ -433,22 +439,42 @@ export class IoSocketController { } }); - socket.on(SocketIoEvent.ITEM_EVENT, (itemEvent: unknown) => { - if (!isItemEventMessageInterface(itemEvent)) { + socket.on(SocketIoEvent.ITEM_EVENT, (message: unknown) => { + if (!(message instanceof Buffer)) { + socket.emit(SocketIoEvent.MESSAGE_ERROR, {message: 'Invalid ITEM_EVENT message. Expecting binary buffer.'}); + console.warn('Invalid ITEM_EVENT message received (expecting binary buffer): ', message); + return; + } + const itemEventMessage = ItemEventMessage.deserializeBinary(new Uint8Array(message)); + + const itemEvent = ProtobufUtils.toItemEvent(itemEventMessage); + + /*if (!isItemEventMessageInterface(itemEvent)) { socket.emit(SocketIoEvent.MESSAGE_ERROR, {message: 'Invalid ITEM_EVENT message.'}); console.warn('Invalid ITEM_EVENT message received: ', itemEvent); return; - } + }*/ try { const Client = (socket as ExSocketInterface); - socket.to(Client.roomId).emit(SocketIoEvent.ITEM_EVENT, itemEvent); + //socket.to(Client.roomId).emit(SocketIoEvent.ITEM_EVENT, itemEvent); const world = this.Worlds.get(Client.roomId); if (!world) { console.error("Could not find world with id '", Client.roomId, "'"); return; } + + const subMessage = new SubMessage(); + subMessage.setItemeventmessage(itemEventMessage); + + // Let's send the event without using the SocketIO room. + for (let user of world.getUsers().values()) { + const client = this.searchClientByIdOrFail(user.id); + //client.emit(SocketIoEvent.ITEM_EVENT, itemEvent); + emitInBatch(client, SocketIoEvent.ITEM_EVENT, subMessage); + } + world.setItemState(itemEvent.itemId, itemEvent.state); } catch (e) { console.error('An error occurred on "item_event"'); diff --git a/back/src/Model/Websocket/ProtobufUtils.ts b/back/src/Model/Websocket/ProtobufUtils.ts index 4e5aec02..aa6810a4 100644 --- a/back/src/Model/Websocket/ProtobufUtils.ts +++ b/back/src/Model/Websocket/ProtobufUtils.ts @@ -1,7 +1,8 @@ import {PointInterface} from "./PointInterface"; -import {PositionMessage} from "../../Messages/generated/messages_pb"; +import {ItemEventMessage, PositionMessage} from "../../Messages/generated/messages_pb"; import {ExSocketInterface} from "_Model/Websocket/ExSocketInterface"; import Direction = PositionMessage.Direction; +import {ItemEventMessageInterface} from "_Model/Websocket/ItemEventMessage"; export class ProtobufUtils { @@ -32,4 +33,23 @@ export class ProtobufUtils { return position; } + + public static toItemEvent(itemEventMessage: ItemEventMessage): ItemEventMessageInterface { + return { + itemId: itemEventMessage.getItemid(), + event: itemEventMessage.getEvent(), + parameters: JSON.parse(itemEventMessage.getParametersjson()), + state: JSON.parse(itemEventMessage.getStatejson()), + } + } + + public static toItemEventProtobuf(itemEvent: ItemEventMessageInterface): ItemEventMessage { + const itemEventMessage = new ItemEventMessage(); + itemEventMessage.setItemid(itemEvent.itemId); + itemEventMessage.setEvent(itemEvent.event); + itemEventMessage.setParametersjson(JSON.stringify(itemEvent.parameters)); + itemEventMessage.setStatejson(JSON.stringify(itemEvent.state)); + + return itemEventMessage; + } } diff --git a/front/src/Connection.ts b/front/src/Connection.ts index faf080f0..8201b5af 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, GroupDeleteMessage, GroupUpdateMessage, + BatchMessage, GroupDeleteMessage, GroupUpdateMessage, ItemEventMessage, PositionMessage, SetPlayerDetailsMessage, UserJoinedMessage, UserLeftMessage, UserMovedMessage, UserMovesMessage, @@ -173,6 +173,9 @@ export class Connection implements Connection { } else if (message.hasUserleftmessage()) { event = EventMessage.USER_LEFT; payload = message.getUserleftmessage(); + } else if (message.hasItemeventmessage()) { + event = EventMessage.ITEM_EVENT; + payload = message.getItemeventmessage(); } else { throw new Error('Unexpected batch message type'); } @@ -400,16 +403,24 @@ export class Connection implements Connection { this.socket.on(EventMessage.WEBRTC_DISCONNECT, callback); } - emitActionableEvent(itemId: number, event: string, state: unknown, parameters: unknown) { - return this.socket.emit(EventMessage.ITEM_EVENT, { - itemId, - event, - state, - parameters - }); + emitActionableEvent(itemId: number, event: string, state: unknown, parameters: unknown): void { + const itemEventMessage = new ItemEventMessage(); + itemEventMessage.setItemid(itemId); + itemEventMessage.setEvent(event); + itemEventMessage.setStatejson(JSON.stringify(state)); + itemEventMessage.setParametersjson(JSON.stringify(parameters)); + + this.socket.emit(EventMessage.ITEM_EVENT, itemEventMessage.serializeBinary().buffer); } onActionableEvent(callback: (message: ItemEventMessageInterface) => void): void { - this.socket.on(EventMessage.ITEM_EVENT, callback); + this.onBatchMessage(EventMessage.ITEM_EVENT, (message: ItemEventMessage) => { + callback({ + itemId: message.getItemid(), + event: message.getEvent(), + parameters: JSON.parse(message.getParametersjson()), + state: JSON.parse(message.getStatejson()) + }); + }); } } diff --git a/messages/messages.proto b/messages/messages.proto index 01782e57..57b1f2ea 100644 --- a/messages/messages.proto +++ b/messages/messages.proto @@ -39,6 +39,14 @@ message UserMovesMessage { ViewportMessage viewport = 2; } +/************ BI-DIRECTIONAL MESSAGES **************/ + +message ItemEventMessage { + int32 itemId = 1; + string event = 2; + string stateJson = 3; + string parametersJson = 4; +} /*********** SERVER TO CLIENT MESSAGES *************/ @@ -54,6 +62,7 @@ message SubMessage { GroupDeleteMessage groupDeleteMessage = 3; UserJoinedMessage userJoinedMessage = 4; UserLeftMessage userLeftMessage = 5; + ItemEventMessage itemEventMessage = 6; } }