diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 707df4a6..75ee3064 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -12,8 +12,7 @@ import { WebRtcSignalToServerMessage, PlayGlobalMessage, ReportPlayerMessage, - QueryJitsiJwtMessage, - SendJitsiJwtMessage, + QueryJitsiJwtMessage } from "../Messages/generated/messages_pb"; import {UserMovesMessage} from "../Messages/generated/messages_pb"; import {TemplatedApp} from "uWebSockets.js" @@ -72,7 +71,20 @@ export class IoSocketController { clientEventsEmitter.registerToClientLeave(ws.clientLeaveCallback); }, message: (ws, arrayBuffer, isBinary): void => { - console.log('m', ws); //todo: add admin actions such as ban here + try { + //TODO refactor message type and data + let message: {event: string, message: {type: string, message: unknown, userUuid: string}} = + JSON.parse(new TextDecoder("utf-8").decode(new Uint8Array(arrayBuffer))); + + if(message.event === 'user-message') { + if (message.message.type === 'ban') { + let messageToEmit = (message.message as {message: string, type: string, userUuid: string}); + socketManager.emitSendUserMessage(messageToEmit); + } + } + }catch (err) { + console.error(err); + } }, close: (ws, code, message) => { //todo make sure this code unregister the right listeners diff --git a/back/src/Services/SocketManager.ts b/back/src/Services/SocketManager.ts index 44579123..a6204941 100644 --- a/back/src/Services/SocketManager.ts +++ b/back/src/Services/SocketManager.ts @@ -19,7 +19,11 @@ import { UserMovesMessage, ViewportMessage, WebRtcDisconnectMessage, WebRtcSignalToClientMessage, - WebRtcSignalToServerMessage, WebRtcStartMessage, QueryJitsiJwtMessage, SendJitsiJwtMessage + WebRtcSignalToServerMessage, + WebRtcStartMessage, + QueryJitsiJwtMessage, + SendJitsiJwtMessage, + SendUserMessage } from "../Messages/generated/messages_pb"; import {PointInterface} from "../Model/Websocket/PointInterface"; import {User} from "../Model/User"; @@ -668,6 +672,24 @@ class SocketManager { client.send(serverToClientMessage.serializeBinary().buffer, true); } + + public emitSendUserMessage(messageToSend: {userUuid: string, message: string, type: string}): void { + let socket = this.searchClientByUuid(messageToSend.userUuid); + if(!socket){ + throw 'socket was not found'; + } + + const sendUserMessage = new SendUserMessage(); + sendUserMessage.setMessage(messageToSend.message); + sendUserMessage.setType(messageToSend.type); + + const serverToClientMessage = new ServerToClientMessage(); + serverToClientMessage.setSendusermessage(sendUserMessage); + + if (!socket.disconnecting) { + socket.send(serverToClientMessage.serializeBinary().buffer, true); + } + } } export const socketManager = new SocketManager(); diff --git a/front/dist/index.html b/front/dist/index.html index 5984af7b..8e957965 100644 --- a/front/dist/index.html +++ b/front/dist/index.html @@ -125,6 +125,9 @@ + diff --git a/front/dist/resources/objects/report-message.mp3 b/front/dist/resources/objects/report-message.mp3 new file mode 100644 index 00000000..0135bfaf Binary files /dev/null and b/front/dist/resources/objects/report-message.mp3 differ diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index fa91d1e7..23a4bba6 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -654,4 +654,6 @@ div.modal-report-user{ width: 100%; text-align: left; padding: 30px; + max-width: calc(800px - 60px); /* size of modal - padding*/ } + diff --git a/front/src/Administration/TypeMessage.ts b/front/src/Administration/TypeMessage.ts new file mode 100644 index 00000000..41b30133 --- /dev/null +++ b/front/src/Administration/TypeMessage.ts @@ -0,0 +1,62 @@ +import {TypeMessageInterface} from "./UserMessageManager"; +import {HtmlUtils} from "../WebRtc/HtmlUtils"; + +export class Ban implements TypeMessageInterface { + private nbSecond = 0; + private maxNbSecond = 10; + private titleMessage = 'IMPORTANT !'; + + showMessage(message: string): void { + let div : HTMLDivElement = document.createElement('div'); + div.classList.add('modal-report-user'); + div.id = 'report-message-user'; + div.style.backgroundColor = '#000000e0'; + + let img : HTMLImageElement = document.createElement('img'); + img.src = 'resources/logos/report.svg'; + div.appendChild(img); + + let title : HTMLParagraphElement = document.createElement('p'); + title.id = 'title-report-user'; + title.innerText = `${this.titleMessage} (${this.maxNbSecond})`; + div.appendChild(title); + + let p : HTMLParagraphElement = document.createElement('p'); + p.id = 'body-report-user' + p.innerText = message; + div.appendChild(p); + + const mainSectionDiv = HtmlUtils.getElementByIdOrFail('main-container'); + mainSectionDiv.appendChild(div); + + const reportMessageAudio = HtmlUtils.getElementByIdOrFail('audio-webrtc-in'); + reportMessageAudio.play(); + + this.nbSecond = this.maxNbSecond; + setTimeout((c) => { + this.forMessage(title); + }, 1000); + } + + forMessage(title: HTMLParagraphElement){ + this.nbSecond -= 1; + title.innerText = `${this.titleMessage} (${this.nbSecond})`; + if(this.nbSecond > 0){ + setTimeout(() => { + this.forMessage(title); + }, 1000); + }else{ + title.innerText = this.titleMessage; + + let imgCancel : HTMLImageElement = document.createElement('img'); + imgCancel.id = 'cancel-report-user'; + imgCancel.src = 'resources/logos/close.svg'; + + const div = HtmlUtils.getElementByIdOrFail('report-message-user'); + div.appendChild(imgCancel); + imgCancel.addEventListener('click', () => { + div.remove(); + }); + } + } +} \ No newline at end of file diff --git a/front/src/Administration/UserMessageManager.ts b/front/src/Administration/UserMessageManager.ts new file mode 100644 index 00000000..87395c14 --- /dev/null +++ b/front/src/Administration/UserMessageManager.ts @@ -0,0 +1,36 @@ +import {RoomConnection} from "../Connexion/RoomConnection"; +import * as TypeMessages from "./TypeMessage"; + +export interface TypeMessageInterface{ + showMessage(message: string) : void; +}; + +export class UserMessageManager { + + typeMessages : Map = new Map(); + + constructor(private Connection: RoomConnection) { + let valueTypeMessageTab = Object.values(TypeMessages); + Object.keys(TypeMessages).forEach((value: string, index: number) => { + let typeMessageInstance : TypeMessageInterface = (new valueTypeMessageTab[index]() as TypeMessageInterface); + this.typeMessages.set(value.toLowerCase(), typeMessageInstance); + }); + this.initialise(); + } + + initialise(){ + //receive signal to show message + this.Connection.receiveUserMessage((type: string, message: string) => { + this.showMessage(type, message); + }); + } + + showMessage(type: string, message: string){ + let classTypeMessage = this.typeMessages.get(type.toLowerCase()); + if(!classTypeMessage){ + console.error('Message unknown'); + return; + } + classTypeMessage.showMessage(message); + } +}; \ No newline at end of file diff --git a/front/src/Connexion/ConnexionModels.ts b/front/src/Connexion/ConnexionModels.ts index 375e1ded..fd2149c5 100644 --- a/front/src/Connexion/ConnexionModels.ts +++ b/front/src/Connexion/ConnexionModels.ts @@ -27,6 +27,7 @@ export enum EventMessage{ STOP_GLOBAL_MESSAGE = "stop-global-message", TELEPORT = "teleport", + USER_MESSAGE = "user-message", START_JITSI_ROOM = "start-jitsi-room", } diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts index 2d2d2cf8..9d04cedd 100644 --- a/front/src/Connexion/RoomConnection.ts +++ b/front/src/Connexion/RoomConnection.ts @@ -22,7 +22,7 @@ import { WebRtcSignalToServerMessage, WebRtcStartMessage, ReportPlayerMessage, - TeleportMessageMessage, QueryJitsiJwtMessage, SendJitsiJwtMessage + TeleportMessageMessage, QueryJitsiJwtMessage, SendJitsiJwtMessage, SendUserMessage } from "../Messages/generated/messages_pb" import {UserSimplePeerInterface} from "../WebRtc/SimplePeer"; @@ -35,8 +35,6 @@ import { RoomJoinedMessageInterface, ViewportInterface, WebRtcDisconnectMessageInterface, WebRtcSignalReceivedMessageInterface, - WebRtcSignalSentMessageInterface, - WebRtcStartMessageInterface } from "./ConnexionModels"; export class RoomConnection implements RoomConnection { @@ -152,6 +150,8 @@ export class RoomConnection implements RoomConnection { this.dispatch(EventMessage.TELEPORT, message.getTeleportmessagemessage()); } else if (message.hasSendjitsijwtmessage()) { this.dispatch(EventMessage.START_JITSI_ROOM, message.getSendjitsijwtmessage()); + } else if (message.hasSendusermessage()) { + this.dispatch(EventMessage.USER_MESSAGE, message.getSendusermessage()); } else { throw new Error('Unknown message received'); } @@ -479,8 +479,13 @@ export class RoomConnection implements RoomConnection { }); } + public receiveUserMessage(callback: (type: string, message: string) => void) { + return this.onMessage(EventMessage.USER_MESSAGE, (message: SendUserMessage) => { + callback(message.getType(), message.getMessage()); + }); + } + public emitGlobalMessage(message: PlayGlobalMessageInterface){ - console.log('emitGlobalMessage', message); const playGlobalMessage = new PlayGlobalMessage(); playGlobalMessage.setId(message.id); playGlobalMessage.setType(message.type); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 2eb34ca0..f82a6ce2 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -51,6 +51,7 @@ import {ProtobufClientUtils} from "../../Network/ProtobufClientUtils"; import {connectionManager} from "../../Connexion/ConnectionManager"; import {RoomConnection} from "../../Connexion/RoomConnection"; import {GlobalMessageManager} from "../../Administration/GlobalMessageManager"; +import {UserMessageManager} from "../../Administration/UserMessageManager"; import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager"; import {ResizableScene} from "../Login/ResizableScene"; import {Room} from "../../Connexion/Room"; @@ -114,6 +115,7 @@ export class GameScene extends ResizableScene implements CenterListener { private connection!: RoomConnection; private simplePeer!: SimplePeer; private GlobalMessageManager!: GlobalMessageManager; + private UserMessageManager!: UserMessageManager; private ConsoleGlobalMessageManager!: ConsoleGlobalMessageManager; private connectionAnswerPromise: Promise; private connectionAnswerPromiseResolve!: (value?: RoomJoinedMessageInterface | PromiseLike) => void; @@ -600,6 +602,7 @@ export class GameScene extends ResizableScene implements CenterListener { // When connection is performed, let's connect SimplePeer this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic); this.GlobalMessageManager = new GlobalMessageManager(this.connection); + this.UserMessageManager = new UserMessageManager(this.connection); const self = this; this.simplePeer.registerPeerConnectionListener({ diff --git a/messages/messages.proto b/messages/messages.proto index 450def24..45872f22 100644 --- a/messages/messages.proto +++ b/messages/messages.proto @@ -178,6 +178,11 @@ message SendJitsiJwtMessage { string jwt = 2; } +message SendUserMessage{ + string type = 1; + string message = 2; +} + message ServerToClientMessage { oneof message { BatchMessage batchMessage = 1; @@ -191,5 +196,6 @@ message ServerToClientMessage { StopGlobalMessage stopGlobalMessage = 9; TeleportMessageMessage teleportMessageMessage = 10; SendJitsiJwtMessage sendJitsiJwtMessage = 11; + SendUserMessage sendUserMessage = 12; } }