From c63fb6ed6fc59756fadbc571ee137eb5528fbec1 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 6 Oct 2020 23:56:27 +0200 Subject: [PATCH 01/15] Add image to report and to teleport player --- front/dist/resources/objects/report_flag.png | Bin 0 -> 447 bytes .../dist/resources/objects/teleportation.png | Bin 0 -> 555 bytes front/src/Phaser/Entity/Character.ts | 29 ++++++++++++++++++ front/src/Phaser/Entity/body_character.ts | 27 ++++++++++++++++ front/src/Phaser/Game/GameScene.ts | 19 ++---------- 5 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 front/dist/resources/objects/report_flag.png create mode 100644 front/dist/resources/objects/teleportation.png diff --git a/front/dist/resources/objects/report_flag.png b/front/dist/resources/objects/report_flag.png new file mode 100644 index 0000000000000000000000000000000000000000..57b99126dd322fc798db9765fa10dfdd2195eb9d GIT binary patch literal 447 zcmV;w0YLtVP)amQ`_F&}{9*Y0jS*xDGAQ$%bc^@RcU8sb$MET8c=wBoVZrmC^I5P- z^0EG4uo8QKQ}d6%EDTN8RZm`G*pkJB*BUGU z%O7@zm*06A_I!N3`1}7)FF?wOHb9=|1DMtpc*(%bq*x}wsCMYZ|64n;dg1L)ZidZ| zwHU5`5N9~_Qjy`yZ#EQpJF)vLIif}@_!z}Cu)5&ezki>efBSj+$~PV`|L6x<3^o7$ z|7K8Tu*k=1!1KRv&Mf`7&Y2jmksJ$y+yFDK;29sE{FY$(#;2pl?%qnY0c?z%{6_44 zQ#53Z;{_GDc_p<(#5Bas)AU)rdYKtnQR5H|Fe)=x=14GThN@Yp*s=1WhUt&je;ICF pxVH5f!?l$U|DRiop__q$0Ra6sqZ;yv3L^jj002ovPDHLkV1hgX*C7A^ literal 0 HcmV?d00001 diff --git a/front/dist/resources/objects/teleportation.png b/front/dist/resources/objects/teleportation.png new file mode 100644 index 0000000000000000000000000000000000000000..e13826f9ae2b2c095008601ef503ee1161ce4e49 GIT binary patch literal 555 zcmV+`0@VG9P)JF|xzXlxY<5lU$r8cgr3H$_G8wvQlU zuPXF`3iYb`4ql6R(S)iG5L!Gm7(B$(cC*>@$R^DuO`7~+mibPq$GTGnViUC+Z0 z1EMJ6aDRX2)6voE#IFw$e4$4TV;(dhVY-YdgQq0}9Q1GyO93t0Is13}E~bbn&v~5M zCi6x_H--~ivYhv+wJf?qaCXuCKByDpeV#7bv^+_r;PNL>{PYy1IhU`F!Ivw)nx1PV_FY_RmC!;Bvt}z|Z4isTv6GwttLm)4*J%3aX++XdW%b34`H68HV zhw5dPZmbdd0{2HhSm7 zht2v*e!WOOSMw=K0io($;Nj8=Cg#Rc-!R7yZ>SWoSzg=TaK7B!ZS-9zSSYV<10Svd tDy5Z2_e>8>o3Y-cUMW;*<#Epd{sUbnu8Sxqu5|za002ovPDHLkV1f$k^0xp0 literal 0 HcmV?d00001 diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 6edb0e36..74a4d99d 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -46,6 +46,8 @@ export abstract class Character extends Container { public PlayerValue: string; public sprites: Map; private lastDirection: string = PlayerAnimationNames.WalkDown; + private report: Sprite; + private teleportation: Sprite; constructor(scene: Phaser.Scene, x: number, @@ -62,6 +64,15 @@ export abstract class Character extends Container { for (const texture of textures) { const sprite = new Sprite(scene, 0, 0, texture, frame); + sprite.setInteractive({useHandCursor: true}); + sprite.on('pointerover', () => { + this.report.visible = true; + this.teleportation.visible = true; + }); + sprite.on('pointerup', () => { + this.report.visible = true; + this.teleportation.visible = true; + }); this.add(sprite); this.getPlayerAnimations(texture).forEach(d => { this.scene.anims.create({ @@ -76,6 +87,24 @@ export abstract class Character extends Container { this.sprites.set(texture, sprite); } + this.report = new Sprite(scene, 20, -10, 'report_flag', 3); + this.report.setInteractive(); + this.report.visible = false; + this.report.on('pointerup', () => { + this.report.visible = false; + this.teleportation.visible = false; + }); + this.add(this.report); + + this.teleportation = new Sprite(scene, -20, -10, 'teleportation', 3); + this.teleportation.setInteractive(); + this.teleportation.visible = false; + this.teleportation.on('pointerup', () => { + this.report.visible = false; + this.teleportation.visible = false; + }); + this.add(this.teleportation); + this.PlayerValue = name; this.playerName = new BitmapText(scene, x, y - 25, 'main_font', name, 8); this.playerName.setOrigin(0.5).setCenterAlign().setDepth(99999); diff --git a/front/src/Phaser/Entity/body_character.ts b/front/src/Phaser/Entity/body_character.ts index 3d9d5a5f..50f1eea6 100644 --- a/front/src/Phaser/Entity/body_character.ts +++ b/front/src/Phaser/Entity/body_character.ts @@ -1,4 +1,5 @@ import LoaderPlugin = Phaser.Loader.LoaderPlugin; +import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "./Character"; export interface BodyResourceDescriptionInterface { name: string, @@ -310,3 +311,29 @@ export const loadAllLayers = (load: LoaderPlugin) => { } } } + +export const OBJECTS: Array = [ + {name:'report_flag', img:'resources/objects/report_flag.png'}, + {name:'layout_modes', img:'resources/objects/layout_modes.png'}, + {name:'teleportation', img:'resources/objects/teleportation.png'}, +]; + +export const loadObject = (load: LoaderPlugin) => { + for (let j = 0; j < OBJECTS.length; j++) { + load.spritesheet( + OBJECTS[j].name, + OBJECTS[j].img, + {frameWidth: 32, frameHeight: 32} + ) + } +} + +export const loadPlayerCharacters = (load: LoaderPlugin) => { + PLAYER_RESOURCES.forEach((playerResource: PlayerResourceDescriptionInterface) => { + load.spritesheet( + playerResource.name, + playerResource.img, + {frameWidth: 32, frameHeight: 32} + ); + }); +} diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 608d920b..ed98d9b9 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -16,7 +16,6 @@ import { ITiledMapLayerProperty, ITiledMapObject, ITiledTileSet } from "../Map/ITiledMap"; -import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character"; import {AddPlayerInterface} from "./AddPlayerInterface"; import {PlayerAnimationNames} from "../Player/Animation"; import {PlayerMovement} from "./PlayerMovement"; @@ -25,7 +24,7 @@ import {RemotePlayer} from "../Entity/RemotePlayer"; import {Queue} from 'queue-typescript'; import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer"; import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene"; -import {loadAllLayers} from "../Entity/body_character"; +import {loadAllLayers, loadObject, loadPlayerCharacters} from "../Entity/body_character"; import {CenterListener, layoutManager, LayoutMode} from "../../WebRtc/LayoutManager"; import Texture = Phaser.Textures.Texture; import Sprite = Phaser.GameObjects.Sprite; @@ -189,21 +188,9 @@ export class GameScene extends Phaser.Scene implements CenterListener { } //add player png - PLAYER_RESOURCES.forEach((playerResource: PlayerResourceDescriptionInterface) => { - this.load.spritesheet( - playerResource.name, - playerResource.img, - {frameWidth: 32, frameHeight: 32} - ); - }); - - this.load.spritesheet( - 'layout_modes', - 'resources/objects/layout_modes.png', - {frameWidth: 32, frameHeight: 32} - ); - + loadPlayerCharacters(this.load); loadAllLayers(this.load); + loadObject(this.load); this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); From aeced0c648fdcbd85949035a9e3185b38d5092c3 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 12 Oct 2020 11:22:41 +0200 Subject: [PATCH 02/15] create message to report --- back/src/Controller/IoSocketController.ts | 29 +++++++++++++++++++---- front/src/Connexion/RoomConnection.ts | 15 ++++++++++-- front/src/Phaser/Entity/Character.ts | 24 +++---------------- front/src/Phaser/Entity/RemotePlayer.ts | 21 ++++++++++++++++ front/src/Phaser/Game/GameScene.ts | 9 +++++++ messages/messages.proto | 6 +++++ 6 files changed, 77 insertions(+), 27 deletions(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index e9f97ea6..b8d0d69a 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -42,7 +42,7 @@ import { SilentMessage, WebRtcSignalToClientMessage, WebRtcSignalToServerMessage, - WebRtcStartMessage, WebRtcDisconnectMessage, PlayGlobalMessage + WebRtcStartMessage, WebRtcDisconnectMessage, PlayGlobalMessage, ReportPlayerMessage } from "../Messages/generated/messages_pb"; import {UserMovesMessage} from "../Messages/generated/messages_pb"; import Direction = PositionMessage.Direction; @@ -50,6 +50,7 @@ import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils"; import {App, HttpRequest, TemplatedApp, WebSocket} from "uWebSockets.js" import {parse} from "query-string"; import {cpuTracker} from "../Services/CpuTracker"; +import axios from "axios"; function emitInBatch(socket: ExSocketInterface, payload: SubMessage): void { socket.batchedMessages.addPayload(payload); @@ -267,11 +268,13 @@ export class IoSocketController { } else if (message.hasItemeventmessage()) { this.handleItemEvent(client, message.getItemeventmessage() as ItemEventMessage); } else if (message.hasWebrtcsignaltoservermessage()) { - this.emitVideo(client, message.getWebrtcsignaltoservermessage() as WebRtcSignalToServerMessage) + this.emitVideo(client, message.getWebrtcsignaltoservermessage() as WebRtcSignalToServerMessage); } else if (message.hasWebrtcscreensharingsignaltoservermessage()) { - this.emitScreenSharing(client, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage) + this.emitScreenSharing(client, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage); } else if (message.hasPlayglobalmessage()) { - this.emitPlayGlobalMessage(client, message.getPlayglobalmessage() as PlayGlobalMessage) + this.emitPlayGlobalMessage(client, message.getPlayglobalmessage() as PlayGlobalMessage); + } else if (message.hasReportplayermessage()){ + this.handleReportMessage(client, message.getReportplayermessage() as ReportPlayerMessage); } /* Ok is false if backpressure was built up, wait for drain */ @@ -547,6 +550,24 @@ export class IoSocketController { } } + private handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) { + try { + let reportedSocket = this.sockets.get(reportPlayerMessage.getReporteduserid()); + if(!reportedSocket){ + throw 'reported socket user not found'; + } + //TODO report user on admin application + axios.post('/report', { + reportedUserId: reportPlayerMessage.getReporteduserid(), + reportedUserComment: reportPlayerMessage.getReportcomment(), + reporterUserId: client.userUuid, + }); + } catch (e) { + console.error('An error occurred on "handleReportMessage"'); + console.error(e); + } + } + emitVideo(socket: ExSocketInterface, data: WebRtcSignalToServerMessage): void { //send only at user const client = this.sockets.get(data.getReceiverid()); diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts index a27bd323..282d830e 100644 --- a/front/src/Connexion/RoomConnection.ts +++ b/front/src/Connexion/RoomConnection.ts @@ -21,7 +21,8 @@ import { WebRtcDisconnectMessage, WebRtcSignalToClientMessage, WebRtcSignalToServerMessage, - WebRtcStartMessage + WebRtcStartMessage, + ReportPlayerMessage } from "../Messages/generated/messages_pb" import {UserSimplePeerInterface} from "../WebRtc/SimplePeer"; @@ -401,7 +402,6 @@ export class RoomConnection implements RoomConnection { } callback(event); }); - } public getUserId(): number|null { @@ -478,4 +478,15 @@ export class RoomConnection implements RoomConnection { this.socket.send(clientToServerMessage.serializeBinary().buffer); } + + public emitReportPlayerMessage(reportedUserId: number, reportComment: string ): void { + const reportPlayerMessage = new ReportPlayerMessage(); + reportPlayerMessage.setReporteduserid(reportedUserId); + reportPlayerMessage.setReportcomment(reportComment); + + const clientToServerMessage = new ClientToServerMessage(); + clientToServerMessage.setReportplayermessage(reportPlayerMessage); + + this.socket.send(clientToServerMessage.serializeBinary().buffer); + } } diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 74a4d99d..4e899ec2 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -46,8 +46,7 @@ export abstract class Character extends Container { public PlayerValue: string; public sprites: Map; private lastDirection: string = PlayerAnimationNames.WalkDown; - private report: Sprite; - private teleportation: Sprite; + //private teleportation: Sprite; constructor(scene: Phaser.Scene, x: number, @@ -65,14 +64,6 @@ export abstract class Character extends Container { for (const texture of textures) { const sprite = new Sprite(scene, 0, 0, texture, frame); sprite.setInteractive({useHandCursor: true}); - sprite.on('pointerover', () => { - this.report.visible = true; - this.teleportation.visible = true; - }); - sprite.on('pointerup', () => { - this.report.visible = true; - this.teleportation.visible = true; - }); this.add(sprite); this.getPlayerAnimations(texture).forEach(d => { this.scene.anims.create({ @@ -87,23 +78,14 @@ export abstract class Character extends Container { this.sprites.set(texture, sprite); } - this.report = new Sprite(scene, 20, -10, 'report_flag', 3); - this.report.setInteractive(); - this.report.visible = false; - this.report.on('pointerup', () => { - this.report.visible = false; - this.teleportation.visible = false; - }); - this.add(this.report); - - this.teleportation = new Sprite(scene, -20, -10, 'teleportation', 3); + /*this.teleportation = new Sprite(scene, -20, -10, 'teleportation', 3); this.teleportation.setInteractive(); this.teleportation.visible = false; this.teleportation.on('pointerup', () => { this.report.visible = false; this.teleportation.visible = false; }); - this.add(this.teleportation); + this.add(this.teleportation);*/ this.PlayerValue = name; this.playerName = new BitmapText(scene, x, y - 25, 'main_font', name, 8); diff --git a/front/src/Phaser/Entity/RemotePlayer.ts b/front/src/Phaser/Entity/RemotePlayer.ts index ba0a74d2..f0d0baa5 100644 --- a/front/src/Phaser/Entity/RemotePlayer.ts +++ b/front/src/Phaser/Entity/RemotePlayer.ts @@ -1,12 +1,14 @@ import {GameScene} from "../Game/GameScene"; import {PointInterface} from "../../Connexion/ConnexionModels"; import {Character} from "../Entity/Character"; +import {Sprite} from "./Sprite"; /** * Class representing the sprite of a remote player (a player that plays on another computer) */ export class RemotePlayer extends Character { userId: number; + private report: Sprite; constructor( userId: number, @@ -23,6 +25,25 @@ export class RemotePlayer extends Character { //set data this.userId = userId; + this.report = new Sprite(Scene, 20, -10, 'report_flag', 3); + this.report.setInteractive(); + this.report.visible = false; + this.report.on('pointerup', () => { + //this.scene.events.emit('reportUser', {reportedUserId: userId, reportComment: comment}); + this.scene.events.emit('reportUser', {reportedUserId: this.userId, reportComment: 'test'}); + this.report.visible = false; + }); + this.add(this.report); + + this.sprites.forEach((sprite: Sprite) => { + sprite.on('pointerover', () => { + this.report.visible = true; + }); + sprite.on('pointerup', () => { + this.report.visible = true; + }); + }) + //the current player model should be push away by other players to prevent conflict //this.setImmovable(false); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 0dc89a7b..ca936e65 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -601,6 +601,9 @@ export class GameScene extends ResizableScene implements CenterListener { this.connection.setSilent(true); } }); + + //lisen event to report user + this.onReportUser(); } private switchLayoutMode(): void { @@ -1181,4 +1184,10 @@ export class GameScene extends ResizableScene implements CenterListener { public onCenterChange(): void { this.updateCameraOffset(); } + + public onReportUser(){ + this.events.on('reportUser', (message: {reportedUserId: number, reportComment: string}) => { + this.connection.emitReportPlayerMessage(message.reportedUserId, message.reportComment); + }); + } } diff --git a/messages/messages.proto b/messages/messages.proto index 87cf2231..2d9b970a 100644 --- a/messages/messages.proto +++ b/messages/messages.proto @@ -54,6 +54,11 @@ message WebRtcSignalToServerMessage { string signal = 2; } +message ReportPlayerMessage { + int32 reportedUserId = 1; + string reportComment = 2; +} + message ClientToServerMessage { oneof message { JoinRoomMessage joinRoomMessage = 1; @@ -66,6 +71,7 @@ message ClientToServerMessage { WebRtcSignalToServerMessage webRtcScreenSharingSignalToServerMessage = 8; PlayGlobalMessage playGlobalMessage = 9; StopGlobalMessage stopGlobalMessage = 10; + ReportPlayerMessage reportPlayerMessage = 11; } } From 3c2f134e4ed92bc3a3c50ac783407a47fbbe97ff Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 13 Oct 2020 09:37:38 +0200 Subject: [PATCH 03/15] Finish report in admin --- back/src/Controller/IoSocketController.ts | 29 +++++++++++++++++------ back/src/Enum/EnvironmentVariable.ts | 4 ++-- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index b8d0d69a..ddf123ce 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -2,7 +2,14 @@ import * as http from "http"; import {MessageUserPosition, Point} from "../Model/Websocket/MessageUserPosition"; //TODO fix import by "_Model/.." import {ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.." import Jwt, {JsonWebTokenError} from "jsonwebtoken"; -import {SECRET_KEY, MINIMUM_DISTANCE, GROUP_RADIUS, ALLOW_ARTILLERY} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..." +import { + SECRET_KEY, + MINIMUM_DISTANCE, + GROUP_RADIUS, + ALLOW_ARTILLERY, + ADMIN_API_URL, + ADMIN_API_TOKEN +} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..." import {World} from "../Model/World"; import {Group} from "../Model/Group"; import {User} from "../Model/User"; @@ -50,7 +57,7 @@ import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils"; import {App, HttpRequest, TemplatedApp, WebSocket} from "uWebSockets.js" import {parse} from "query-string"; import {cpuTracker} from "../Services/CpuTracker"; -import axios from "axios"; +import Axios from "axios"; function emitInBatch(socket: ExSocketInterface, payload: SubMessage): void { socket.batchedMessages.addPayload(payload); @@ -553,14 +560,22 @@ export class IoSocketController { private handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) { try { let reportedSocket = this.sockets.get(reportPlayerMessage.getReporteduserid()); - if(!reportedSocket){ + if (!reportedSocket) { throw 'reported socket user not found'; } //TODO report user on admin application - axios.post('/report', { - reportedUserId: reportPlayerMessage.getReporteduserid(), - reportedUserComment: reportPlayerMessage.getReportcomment(), - reporterUserId: client.userUuid, + console.log('ADMIN_API_URL', ADMIN_API_URL); + console.log('ADMIN_API_TOKEN', ADMIN_API_TOKEN); + Axios.post(`${ADMIN_API_URL}/aoi/report`, { + reportedUserUuid: client.userUuid, + reportedUserComment: reportPlayerMessage.getReportcomment(), + reporterUserUuid: client.userUuid, + }, + { + headers: {"Authorization": `${ADMIN_API_TOKEN}`} + }).catch((err) => { + console.error(err); + throw err; }); } catch (e) { console.error('An error occurred on "handleReportMessage"'); diff --git a/back/src/Enum/EnvironmentVariable.ts b/back/src/Enum/EnvironmentVariable.ts index b69ba00c..61ab4cc9 100644 --- a/back/src/Enum/EnvironmentVariable.ts +++ b/back/src/Enum/EnvironmentVariable.ts @@ -3,8 +3,8 @@ const URL_ROOM_STARTED = "/Floor0/floor0.json"; const MINIMUM_DISTANCE = process.env.MINIMUM_DISTANCE ? Number(process.env.MINIMUM_DISTANCE) : 64; const GROUP_RADIUS = process.env.GROUP_RADIUS ? Number(process.env.GROUP_RADIUS) : 48; const ALLOW_ARTILLERY = process.env.ALLOW_ARTILLERY ? process.env.ALLOW_ARTILLERY == 'true' : false; -const ADMIN_API_URL = process.env.ADMIN_API_URL || null; -const ADMIN_API_TOKEN = process.env.ADMIN_API_TOKEN || null; +const ADMIN_API_URL = process.env.ADMIN_API_URL || 'http://admin'; +const ADMIN_API_TOKEN = process.env.ADMIN_API_TOKEN || 'myapitoken'; const CPU_OVERHEAT_THRESHOLD = Number(process.env.CPU_OVERHEAT_THRESHOLD) || 80; export { From 65406f844eeb39704cebfddaabf9394b2dfce2b8 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 13 Oct 2020 11:39:07 +0200 Subject: [PATCH 04/15] Teleport notification - Create end point to permit the teleport notification. The map url will be /teleport/token_user - Create message teleport - Create receive feature in phaser to teleport TODO Teleport player on black room. --- back/src/App.ts | 3 ++ back/src/Controller/BaseController.ts | 10 +++++- back/src/Controller/IoSocketController.ts | 41 +++++++++++++---------- back/src/Controller/ReportController.ts | 38 +++++++++++++++++++++ front/src/Connexion/ConnexionModels.ts | 2 ++ front/src/Connexion/RoomConnection.ts | 11 +++++- front/src/Phaser/Game/GameScene.ts | 5 +++ messages/messages.proto | 5 +++ 8 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 back/src/Controller/ReportController.ts diff --git a/back/src/App.ts b/back/src/App.ts index 6430251a..2cd668d2 100644 --- a/back/src/App.ts +++ b/back/src/App.ts @@ -6,6 +6,7 @@ import {PrometheusController} from "./Controller/PrometheusController"; import {FileController} from "./Controller/FileController"; import {DebugController} from "./Controller/DebugController"; import {App as uwsApp} from "./Server/sifrr.server"; +import {ReportController} from "./Controller/ReportController"; class App { public app: uwsApp; @@ -15,6 +16,7 @@ class App { public mapController: MapController; public prometheusController: PrometheusController; private debugController: DebugController; + private reportController: ReportController; constructor() { this.app = new uwsApp(); @@ -24,6 +26,7 @@ class App { this.authenticateController = new AuthenticateController(this.app); this.fileController = new FileController(this.app); this.mapController = new MapController(this.app); + this.reportController = new ReportController(this.app, this.ioSocketController); this.prometheusController = new PrometheusController(this.app, this.ioSocketController); this.debugController = new DebugController(this.app, this.ioSocketController); } diff --git a/back/src/Controller/BaseController.ts b/back/src/Controller/BaseController.ts index 93c17ab4..2757519d 100644 --- a/back/src/Controller/BaseController.ts +++ b/back/src/Controller/BaseController.ts @@ -1,4 +1,5 @@ -import {HttpResponse} from "uWebSockets.js"; +import {HttpRequest, HttpResponse} from "uWebSockets.js"; +import {ADMIN_API_TOKEN} from "../Enum/EnvironmentVariable"; export class BaseController { @@ -7,4 +8,11 @@ export class BaseController { res.writeHeader('access-control-allow-methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.writeHeader('access-control-allow-origin', '*'); } + + protected checkAdminToken(req: HttpRequest): void { + //TODO + /*if(req.getHeader('Authorization') !== ADMIN_API_TOKEN){ + throw 'Error token api'; + }*/ + } } diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index ddf123ce..f277cb4b 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -49,7 +49,7 @@ import { SilentMessage, WebRtcSignalToClientMessage, WebRtcSignalToServerMessage, - WebRtcStartMessage, WebRtcDisconnectMessage, PlayGlobalMessage, ReportPlayerMessage + WebRtcStartMessage, WebRtcDisconnectMessage, PlayGlobalMessage, ReportPlayerMessage, TeleportMessageMessage } from "../Messages/generated/messages_pb"; import {UserMovesMessage} from "../Messages/generated/messages_pb"; import Direction = PositionMessage.Direction; @@ -108,22 +108,6 @@ export class IoSocketController { return true; } - /** - * - * @param token - */ -/* searchClientByToken(token: string): ExSocketInterface | null { - const clients: ExSocketInterface[] = Object.values(this.Io.sockets.sockets) as ExSocketInterface[]; - for (let i = 0; i < clients.length; i++) { - const client = clients[i]; - if (client.token !== token) { - continue - } - return client; - } - return null; - }*/ - private async authenticate(req: HttpRequest): Promise<{ token: string, userUuid: string }> { //console.log(socket.handshake.query.token); @@ -921,4 +905,27 @@ export class IoSocketController { public getWorlds(): Map { return this.Worlds; } + + /** + * + * @param token + */ + searchClientByUuid(uuid: string): ExSocketInterface | null { + for(let socket of this.sockets.values()){ + if(socket.userUuid === uuid){ + return socket; + } + } + return null; + } + + public teleport(userUuid: string) { + let user = this.searchClientByUuid(userUuid); + if(!user){ + throw 'User not found'; + } + const teleportMessageMessage = new TeleportMessageMessage(); + teleportMessageMessage.setMap(`/teleport/${user.userUuid}`); + user.send(teleportMessageMessage.serializeBinary().buffer, true); + } } diff --git a/back/src/Controller/ReportController.ts b/back/src/Controller/ReportController.ts new file mode 100644 index 00000000..d39e9816 --- /dev/null +++ b/back/src/Controller/ReportController.ts @@ -0,0 +1,38 @@ +import {BaseController} from "./BaseController"; +import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js"; +import {IoSocketController} from "./IoSocketController"; + +export class ReportController extends BaseController { + + constructor(private App: TemplatedApp, private ioSocketController: IoSocketController) { + super(); + this.teleport(); + } + + teleport(){ + this.App.options("/teleport", (res: HttpResponse, req: HttpRequest) => { + this.checkAdminToken(req); + this.addCorsHeaders(res); + res.end(); + }); + + this.App.post("/teleport", (res: HttpResponse, req: HttpRequest) => { + (async () => { + try { + this.checkAdminToken(req); + this.addCorsHeaders(res); + + res.onAborted(() => { + console.warn('Login request was aborted'); + }) + const param = await res.json(); + this.ioSocketController.teleport(param.userUuid); + res.writeStatus("200 OK").end(); + } catch (e) { + console.log("An error happened", e) + res.writeStatus(e.status || "500 Internal Server Error").end('An error happened'); + } + })(); + }); + } +} \ No newline at end of file diff --git a/front/src/Connexion/ConnexionModels.ts b/front/src/Connexion/ConnexionModels.ts index 4ec76198..30d14c79 100644 --- a/front/src/Connexion/ConnexionModels.ts +++ b/front/src/Connexion/ConnexionModels.ts @@ -24,6 +24,8 @@ export enum EventMessage{ PLAY_GLOBAL_MESSAGE = "play-global-message", STOP_GLOBAL_MESSAGE = "stop-global-message", + + TELEPORT = "teleport", } export interface PointInterface { diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts index 282d830e..5ce724aa 100644 --- a/front/src/Connexion/RoomConnection.ts +++ b/front/src/Connexion/RoomConnection.ts @@ -22,7 +22,8 @@ import { WebRtcSignalToClientMessage, WebRtcSignalToServerMessage, WebRtcStartMessage, - ReportPlayerMessage + ReportPlayerMessage, + TeleportMessageMessage } from "../Messages/generated/messages_pb" import {UserSimplePeerInterface} from "../WebRtc/SimplePeer"; @@ -129,6 +130,8 @@ export class RoomConnection implements RoomConnection { this.dispatch(EventMessage.PLAY_GLOBAL_MESSAGE, message.getPlayglobalmessage()); } else if (message.hasStopglobalmessage()) { this.dispatch(EventMessage.STOP_GLOBAL_MESSAGE, message.getStopglobalmessage()); + } else if (message.hasTeleportmessagemessage()) { + this.dispatch(EventMessage.TELEPORT, message.getTeleportmessagemessage()); } else { throw new Error('Unknown message received'); } @@ -466,6 +469,12 @@ export class RoomConnection implements RoomConnection { }); } + public receiveTeleportMessage(callback: (messageId: string) => void) { + return this.onMessage(EventMessage.TELEPORT, (message: TeleportMessageMessage) => { + callback(message.getMap()); + }); + } + public emitGlobalMessage(message: PlayGlobalMessageInterface){ console.log('emitGlobalMessage', message); const playGlobalMessage = new PlayGlobalMessage(); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index ca936e65..3cc9ef57 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -269,6 +269,11 @@ export class GameScene extends ResizableScene implements CenterListener { item.fire(message.event, message.state, message.parameters); })); + connection.receiveTeleportMessage((map: string) => { + //TODO + console.log('receiveTeleportMessage', map); + }) + // When connection is performed, let's connect SimplePeer this.simplePeer = new SimplePeer(this.connection); this.GlobalMessageManager = new GlobalMessageManager(this.connection); diff --git a/messages/messages.proto b/messages/messages.proto index 2d9b970a..bfd1958c 100644 --- a/messages/messages.proto +++ b/messages/messages.proto @@ -172,6 +172,10 @@ message WebRtcSignalToClientMessage { string signal = 2; } +message TeleportMessageMessage{ + string map = 1; +} + message ServerToClientMessage { oneof message { BatchMessage batchMessage = 1; @@ -184,5 +188,6 @@ message ServerToClientMessage { WebRtcDisconnectMessage webRtcDisconnectMessage = 8; PlayGlobalMessage playGlobalMessage = 9; StopGlobalMessage stopGlobalMessage = 10; + TeleportMessageMessage teleportMessageMessage = 11; } } From dbaf44e8146536662c4a3e587ce418d7d8931506 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 13 Oct 2020 19:56:42 +0200 Subject: [PATCH 05/15] Change report flag - Add icon on video - Permit to have a modal with comment --- back/src/Controller/IoSocketController.ts | 9 +-- front/dist/resources/logos/close.svg | 1 + front/dist/resources/logos/report.svg | 1 + front/dist/resources/objects/report_flag.png | Bin 447 -> 0 bytes front/dist/resources/style/style.css | 78 ++++++++++++++++++- front/src/Phaser/Entity/RemotePlayer.ts | 23 ------ front/src/WebRtc/MediaManager.ts | 68 ++++++++++++++-- front/src/WebRtc/SimplePeer.ts | 12 ++- front/src/index.ts | 9 ++- 9 files changed, 164 insertions(+), 37 deletions(-) create mode 100644 front/dist/resources/logos/close.svg create mode 100644 front/dist/resources/logos/report.svg delete mode 100644 front/dist/resources/objects/report_flag.png diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index f277cb4b..2ef8b422 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -543,13 +543,11 @@ export class IoSocketController { private handleReportMessage(client: ExSocketInterface, reportPlayerMessage: ReportPlayerMessage) { try { - let reportedSocket = this.sockets.get(reportPlayerMessage.getReporteduserid()); + const reportedSocket = this.sockets.get(reportPlayerMessage.getReporteduserid()); if (!reportedSocket) { throw 'reported socket user not found'; } //TODO report user on admin application - console.log('ADMIN_API_URL', ADMIN_API_URL); - console.log('ADMIN_API_TOKEN', ADMIN_API_TOKEN); Axios.post(`${ADMIN_API_URL}/aoi/report`, { reportedUserUuid: client.userUuid, reportedUserComment: reportPlayerMessage.getReportcomment(), @@ -558,7 +556,6 @@ export class IoSocketController { { headers: {"Authorization": `${ADMIN_API_TOKEN}`} }).catch((err) => { - console.error(err); throw err; }); } catch (e) { @@ -911,7 +908,7 @@ export class IoSocketController { * @param token */ searchClientByUuid(uuid: string): ExSocketInterface | null { - for(let socket of this.sockets.values()){ + for(const socket of this.sockets.values()){ if(socket.userUuid === uuid){ return socket; } @@ -920,7 +917,7 @@ export class IoSocketController { } public teleport(userUuid: string) { - let user = this.searchClientByUuid(userUuid); + const user = this.searchClientByUuid(userUuid); if(!user){ throw 'User not found'; } diff --git a/front/dist/resources/logos/close.svg b/front/dist/resources/logos/close.svg new file mode 100644 index 00000000..6acd8b49 --- /dev/null +++ b/front/dist/resources/logos/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/dist/resources/logos/report.svg b/front/dist/resources/logos/report.svg new file mode 100644 index 00000000..1cb3b068 --- /dev/null +++ b/front/dist/resources/logos/report.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/dist/resources/objects/report_flag.png b/front/dist/resources/objects/report_flag.png deleted file mode 100644 index 57b99126dd322fc798db9765fa10dfdd2195eb9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 447 zcmV;w0YLtVP)amQ`_F&}{9*Y0jS*xDGAQ$%bc^@RcU8sb$MET8c=wBoVZrmC^I5P- z^0EG4uo8QKQ}d6%EDTN8RZm`G*pkJB*BUGU z%O7@zm*06A_I!N3`1}7)FF?wOHb9=|1DMtpc*(%bq*x}wsCMYZ|64n;dg1L)ZidZ| zwHU5`5N9~_Qjy`yZ#EQpJF)vLIif}@_!z}Cu)5&ezki>efBSj+$~PV`|L6x<3^o7$ z|7K8Tu*k=1!1KRv&Mf`7&Y2jmksJ$y+yFDK;29sE{FY$(#;2pl?%qnY0c?z%{6_44 zQ#53Z;{_GDc_p<(#5Bas)AU)rdYKtnQR5H|Fe)=x=14GThN@Yp*s=1WhUt&je;ICF pxVH5f!?l$U|DRiop__q$0Ra6sqZ;yv3L^jj002ovPDHLkV1hgX*C7A^ diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index e22795a9..7e8d7521 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -56,6 +56,12 @@ body .message-info.warning{ padding: 10px; z-index: 2; } + +.video-container img.report{ + right: 5px; + left: auto; +} + .video-container video{ height: 100%; } @@ -567,4 +573,74 @@ body { .main-container .audio-playing p{ color: white; margin-left: 10px; -} \ No newline at end of file +} + +/*REPORT input*/ +div.modal-report-user{ + position: absolute; + width: 800px; + height: 600px; + left: calc(50% - 400px); + top: calc(50% - 100px); + background-color: #000000ad; +} + +.modal-report-user textarea{ + position: absolute; + width: 400px; + height: 200px; + z-index: 999; + left: calc(50% - 200px); + top: calc(50% - 100px); + background-color: #00000052; + color: white; +} + +.modal-report-user img{ + position: absolute; + height: 50px; + width: 50px; + z-index: 999; + left: calc(50% - 25px); + top: calc(50% - 250px); +} + +.modal-report-user img#cancel-report-user{ + position: absolute; + z-index: 999; + right: 0; + left: auto; + top: 0; + cursor: pointer; + width: 15px; + height: 15px; +} + +.modal-report-user button{ + position: absolute; + top: calc(50% + 200px); + left: calc(50% - 50px); + width: 100px; + border: 1px solid black; + background-color: #00000000; + color: #ffda01; + border-radius: 10px; + padding: 10px 30px; + transition: all .2s ease; +} +.modal-report-user button:hover{ + cursor: pointer; + background-color: #ffda01; + color: black; + border: 1px solid black; + transform: scale(1.1); +} + +.modal-report-user p{ + font-size: 30px; + color: white; + position: absolute; + top: 90px; + width: 100%; + text-align: center; +} diff --git a/front/src/Phaser/Entity/RemotePlayer.ts b/front/src/Phaser/Entity/RemotePlayer.ts index f0d0baa5..08f657d4 100644 --- a/front/src/Phaser/Entity/RemotePlayer.ts +++ b/front/src/Phaser/Entity/RemotePlayer.ts @@ -8,7 +8,6 @@ import {Sprite} from "./Sprite"; */ export class RemotePlayer extends Character { userId: number; - private report: Sprite; constructor( userId: number, @@ -24,28 +23,6 @@ export class RemotePlayer extends Character { //set data this.userId = userId; - - this.report = new Sprite(Scene, 20, -10, 'report_flag', 3); - this.report.setInteractive(); - this.report.visible = false; - this.report.on('pointerup', () => { - //this.scene.events.emit('reportUser', {reportedUserId: userId, reportComment: comment}); - this.scene.events.emit('reportUser', {reportedUserId: this.userId, reportComment: 'test'}); - this.report.visible = false; - }); - this.add(this.report); - - this.sprites.forEach((sprite: Sprite) => { - sprite.on('pointerover', () => { - this.report.visible = true; - }); - sprite.on('pointerup', () => { - this.report.visible = true; - }); - }) - - //the current player model should be push away by other players to prevent conflict - //this.setImmovable(false); } updatePosition(position: PointInterface): void { diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 6d8e5c3d..1dd58c11 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -10,6 +10,7 @@ const videoConstraint: boolean|MediaTrackConstraints = { export type UpdatedLocalStreamCallback = (media: MediaStream|null) => void; export type StartScreenSharingCallback = (media: MediaStream) => void; export type StopScreenSharingCallback = (media: MediaStream) => void; +export type ReportCallback = (message: string) => void; // TODO: Split MediaManager in 2 classes: MediaManagerUI (in charge of HTML) and MediaManager (singleton in charge of the camera only) // TODO: verify that microphone event listeners are not triggered plenty of time NOW (since MediaManager is created many times!!!!) @@ -36,7 +37,6 @@ export class MediaManager { private cinemaBtn: HTMLDivElement; private monitorBtn: HTMLDivElement; - constructor() { this.myCamVideo = this.getElementByIdOrFail('myCamVideo'); @@ -91,17 +91,14 @@ export class MediaManager { } public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void { - this.updatedLocalStreamCallBacks.add(callback); } public onStartScreenSharing(callback: StartScreenSharingCallback): void { - this.startScreenSharingCallBacks.add(callback); } public onStopScreenSharing(callback: StopScreenSharingCallback): void { - this.stopScreenSharingCallBacks.add(callback); } @@ -342,8 +339,10 @@ export class MediaManager { /** * * @param userId + * @param reportCallBack + * @param userName */ - addActiveVideo(userId: string, userName: string = ""){ + addActiveVideo(userId: string, reportCallBack: ReportCallback, userName: string = ""){ this.webrtcInAudio.play(); userName = userName.toUpperCase(); @@ -355,12 +354,19 @@ export class MediaManager { ${userName} + `; layoutManager.add(DivImportance.Normal, userId, html); + const reportBtn = this.getElementByIdOrFail(`report-${userId}`); + reportBtn.addEventListener('click', (e: MouseEvent) => { + e.preventDefault(); + this.showReportModal(userId, userName, reportCallBack); + }); + this.remoteVideo.set(userId, this.getElementByIdOrFail(userId)); } @@ -542,6 +548,58 @@ export class MediaManager { return elem as T; } + private showReportModal(userId: string, userName: string, reportCallBack: ReportCallback){ + //create report text area + const mainContainer = this.getElementByIdOrFail('main-container'); + + const divReport = document.createElement('div'); + divReport.classList.add('modal-report-user'); + + const inputHidden = document.createElement('input'); + inputHidden.id = 'input-report-user'; + inputHidden.type = 'hidden'; + inputHidden.value = userId; + divReport.appendChild(inputHidden); + + const titleMessage = document.createElement('p'); + titleMessage.innerText = 'Vous souhaitez report : ' + userName; + divReport.appendChild(titleMessage); + + const imgReportUser = document.createElement('img'); + imgReportUser.id = 'img-report-user'; + imgReportUser.src = 'resources/logos/report.svg'; + divReport.appendChild(imgReportUser); + + const textareaUser = document.createElement('textarea'); + textareaUser.id = 'textarea-report-user'; + textareaUser.placeholder = 'Laissez un commentaire pour confirmer le report de la personne'; + divReport.appendChild(textareaUser); + + const buttonReport = document.createElement('button'); + buttonReport.id = 'button-save-report-user'; + buttonReport.innerText = 'Report'; + buttonReport.addEventListener('click', () => { + if(!textareaUser.value){ + textareaUser.style.border = '1px solid red' + return; + } + reportCallBack(textareaUser.value); + divReport.remove(); + }); + divReport.appendChild(buttonReport); + + const buttonCancel = document.createElement('img'); + buttonCancel.id = 'cancel-report-user'; + buttonCancel.src = 'resources/logos/close.svg'; + buttonCancel.addEventListener('click', () => { + divReport.remove(); + }); + divReport.appendChild(buttonCancel); + + mainContainer.appendChild(divReport); + } + + } export const mediaManager = new MediaManager(); diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index 890a4313..20d10f04 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -47,6 +47,7 @@ export class SimplePeer { this.sendLocalVideoStreamCallback = this.sendLocalVideoStream.bind(this); this.sendLocalScreenSharingStreamCallback = this.sendLocalScreenSharingStream.bind(this); this.stopLocalScreenSharingStreamCallback = this.stopLocalScreenSharingStream.bind(this); + mediaManager.onUpdateLocalStream(this.sendLocalVideoStreamCallback); mediaManager.onStartScreenSharing(this.sendLocalScreenSharingStreamCallback); mediaManager.onStopScreenSharing(this.stopLocalScreenSharingStreamCallback); @@ -145,7 +146,9 @@ export class SimplePeer { } mediaManager.removeActiveVideo("" + user.userId); - mediaManager.addActiveVideo("" + user.userId, name); + mediaManager.addActiveVideo("" + user.userId, (comment: string) => { + this.reportUser(user.userId, comment); + }, name); const peer = new VideoPeer(user.userId, user.initiator ? user.initiator : false, this.Connection); // When a connection is established to a video stream, and if a screen sharing is taking place, @@ -363,6 +366,13 @@ export class SimplePeer { } } + /** + * Triggered locally when clicking on the report button + */ + public reportUser(userId: number, message: string) { + this.Connection.emitReportPlayerMessage(userId, message) + } + private sendLocalScreenSharingStreamToUser(userId: number): void { // If a connection already exists with user (because it is already sharing a screen with us... let's use this connection) if (this.PeerScreenSharingConnectionArray.has(userId)) { diff --git a/front/src/index.ts b/front/src/index.ts index 177c56c0..0e8c0180 100644 --- a/front/src/index.ts +++ b/front/src/index.ts @@ -31,7 +31,14 @@ const config: GameConfig = { width: width / RESOLUTION, height: height / RESOLUTION, parent: "game", - scene: [LoginScene, SelectCharacterScene, EnableCameraScene, ReconnectingScene, FourOFourScene, CustomizeScene], + scene: [ + LoginScene, + SelectCharacterScene, + EnableCameraScene, + ReconnectingScene, + FourOFourScene, + CustomizeScene + ], zoom: RESOLUTION, physics: { default: "arcade", From 3e74e178fb8ae7d784e05f118dcdb497358180fd Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 13 Oct 2020 21:22:39 +0200 Subject: [PATCH 06/15] Fix CI --- back/src/Controller/IoSocketController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 35ae2c92..9febeacb 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -1,5 +1,5 @@ import {ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.." -import {MINIMUM_DISTANCE, GROUP_RADIUS} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..." +import {MINIMUM_DISTANCE, GROUP_RADIUS, ADMIN_API_URL, ADMIN_API_TOKEN} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..." import {GameRoom} from "../Model/GameRoom"; import {Group} from "../Model/Group"; import {User} from "../Model/User"; From 436cde7033a50abfa42d8a3e71614a5afaf2ca92 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 13 Oct 2020 21:54:08 +0200 Subject: [PATCH 07/15] Fixe style media manager and text modale --- front/dist/resources/style/style.css | 23 ++++++++++++++++------- front/src/WebRtc/MediaManager.ts | 10 ++++++++-- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 7e8d7521..6ee8f090 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -581,7 +581,7 @@ div.modal-report-user{ width: 800px; height: 600px; left: calc(50% - 400px); - top: calc(50% - 100px); + top: 100px; background-color: #000000ad; } @@ -591,8 +591,8 @@ div.modal-report-user{ height: 200px; z-index: 999; left: calc(50% - 200px); - top: calc(50% - 100px); - background-color: #00000052; + top: 200px; + background-color: #000000; color: white; } @@ -602,7 +602,7 @@ div.modal-report-user{ width: 50px; z-index: 999; left: calc(50% - 25px); - top: calc(50% - 250px); + top: 10px; } .modal-report-user img#cancel-report-user{ @@ -618,7 +618,7 @@ div.modal-report-user{ .modal-report-user button{ position: absolute; - top: calc(50% + 200px); + top: 450px; left: calc(50% - 50px); width: 100px; border: 1px solid black; @@ -636,11 +636,20 @@ div.modal-report-user{ transform: scale(1.1); } -.modal-report-user p{ +.modal-report-user p#title-report-user{ font-size: 30px; color: white; position: absolute; + top: 30px; + width: 100%; + text-align: center; +} + +.modal-report-user p#body-report-user{ + font-size: 24px; + color: white; + position: absolute; top: 90px; width: 100%; - text-align: center; + text-align: left; } diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 1dd58c11..dfa6c694 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -562,9 +562,15 @@ export class MediaManager { divReport.appendChild(inputHidden); const titleMessage = document.createElement('p'); - titleMessage.innerText = 'Vous souhaitez report : ' + userName; + titleMessage.id = 'title-report-user'; + titleMessage.innerText = 'Open a report'; divReport.appendChild(titleMessage); + const bodyMessage = document.createElement('p'); + bodyMessage.id = 'body-report-user'; + bodyMessage.innerText = `You are about to open a report regarding an offensive conduct from user ${userName.toUpperCase()}. Please explain to us how you think ${userName.toUpperCase()} breached the code of conduct.`; + divReport.appendChild(bodyMessage); + const imgReportUser = document.createElement('img'); imgReportUser.id = 'img-report-user'; imgReportUser.src = 'resources/logos/report.svg'; @@ -572,7 +578,7 @@ export class MediaManager { const textareaUser = document.createElement('textarea'); textareaUser.id = 'textarea-report-user'; - textareaUser.placeholder = 'Laissez un commentaire pour confirmer le report de la personne'; + textareaUser.placeholder = 'Write ...'; divReport.appendChild(textareaUser); const buttonReport = document.createElement('button'); From f05f4a7f5b01babba1c322d86c51bb6c312e86d2 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 13 Oct 2020 22:19:32 +0200 Subject: [PATCH 08/15] Fix url --- back/src/Controller/IoSocketController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 9febeacb..84bdd6b8 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -514,7 +514,7 @@ export class IoSocketController { throw 'reported socket user not found'; } //TODO report user on admin application - Axios.post(`${ADMIN_API_URL}/aoi/report`, { + Axios.post(`${ADMIN_API_URL}/api/report`, { reportedUserUuid: client.userUuid, reportedUserComment: reportPlayerMessage.getReportcomment(), reporterUserUuid: client.userUuid, From 7b435edd713622a472c36bcf591129259e5ad004 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Thu, 15 Oct 2020 10:37:40 +0200 Subject: [PATCH 09/15] Finish report --- back/src/Controller/IoSocketController.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index e9398135..d39c9eb3 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -500,9 +500,9 @@ export class IoSocketController { } //TODO report user on admin application Axios.post(`${ADMIN_API_URL}/api/report`, { - reportedUserUuid: client.userUuid, + reportedUserUuid: reportedSocket.userUuid, reportedUserComment: reportPlayerMessage.getReportcomment(), - reporterUserUuid: client.userUuid, + reporterUserUuid: client.userUuid }, { headers: {"Authorization": `${ADMIN_API_TOKEN}`} From 8df56204e34c53e2c9b0025c9be8e4ec84e2482b Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Thu, 15 Oct 2020 11:51:24 +0200 Subject: [PATCH 10/15] Add teleport event --- back/src/Controller/IoSocketController.ts | 12 ++++++++---- back/src/Controller/ReportController.ts | 5 ++++- front/src/Administration/GlobalMessageManager.ts | 6 ++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index d39c9eb3..4dfe3576 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -891,12 +891,16 @@ export class IoSocketController { } public teleport(userUuid: string) { - const user = this.searchClientByUuid(userUuid); - if(!user){ + const userSocket = this.searchClientByUuid(userUuid); + if (!userSocket) { throw 'User not found'; } const teleportMessageMessage = new TeleportMessageMessage(); - teleportMessageMessage.setMap(`/teleport/${user.userUuid}`); - user.send(teleportMessageMessage.serializeBinary().buffer, true); + teleportMessageMessage.setMap(`wait/${userSocket.userUuid}`); + + const serverToClientMessage = new ServerToClientMessage(); + serverToClientMessage.setTeleportmessagemessage(teleportMessageMessage); + + userSocket.send(serverToClientMessage.serializeBinary().buffer, true); } } diff --git a/back/src/Controller/ReportController.ts b/back/src/Controller/ReportController.ts index d39e9816..5b5e342d 100644 --- a/back/src/Controller/ReportController.ts +++ b/back/src/Controller/ReportController.ts @@ -27,7 +27,10 @@ export class ReportController extends BaseController { }) const param = await res.json(); this.ioSocketController.teleport(param.userUuid); - res.writeStatus("200 OK").end(); + res.writeHeader('Content-Type', 'application/json'); + res.writeStatus("200 OK").end(JSON.stringify({ + mapUrl: `wait/${param.userUuid}` + })); } catch (e) { console.log("An error happened", e) res.writeStatus(e.status || "500 Internal Server Error").end('An error happened'); diff --git a/front/src/Administration/GlobalMessageManager.ts b/front/src/Administration/GlobalMessageManager.ts index 963db8cc..e3b2b503 100644 --- a/front/src/Administration/GlobalMessageManager.ts +++ b/front/src/Administration/GlobalMessageManager.ts @@ -20,6 +20,12 @@ export class GlobalMessageManager { this.Connection.receiveStopGlobalMessage((messageId: string) => { this.stopMessage(messageId); }); + + //receive signal to close message + this.Connection.receiveTeleportMessage((map: string) => { + console.log('map to teleport user', map); + //TODO teleport user on map + }); } private playMessage(message : PlayGlobalMessageInterface){ From 38d2cc9a8cdfeda04bc06eea85e39badf95f5ca8 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Thu, 15 Oct 2020 12:12:11 +0200 Subject: [PATCH 11/15] Remove teleport feature --- back/src/App.ts | 3 -- back/src/Controller/BaseController.ts | 7 ---- back/src/Controller/IoSocketController.ts | 17 +--------- back/src/Controller/ReportController.ts | 41 ----------------------- front/src/WebRtc/SimplePeer.ts | 2 ++ 5 files changed, 3 insertions(+), 67 deletions(-) delete mode 100644 back/src/Controller/ReportController.ts diff --git a/back/src/App.ts b/back/src/App.ts index 2cd668d2..6430251a 100644 --- a/back/src/App.ts +++ b/back/src/App.ts @@ -6,7 +6,6 @@ import {PrometheusController} from "./Controller/PrometheusController"; import {FileController} from "./Controller/FileController"; import {DebugController} from "./Controller/DebugController"; import {App as uwsApp} from "./Server/sifrr.server"; -import {ReportController} from "./Controller/ReportController"; class App { public app: uwsApp; @@ -16,7 +15,6 @@ class App { public mapController: MapController; public prometheusController: PrometheusController; private debugController: DebugController; - private reportController: ReportController; constructor() { this.app = new uwsApp(); @@ -26,7 +24,6 @@ class App { this.authenticateController = new AuthenticateController(this.app); this.fileController = new FileController(this.app); this.mapController = new MapController(this.app); - this.reportController = new ReportController(this.app, this.ioSocketController); this.prometheusController = new PrometheusController(this.app, this.ioSocketController); this.debugController = new DebugController(this.app, this.ioSocketController); } diff --git a/back/src/Controller/BaseController.ts b/back/src/Controller/BaseController.ts index 2757519d..0b744082 100644 --- a/back/src/Controller/BaseController.ts +++ b/back/src/Controller/BaseController.ts @@ -8,11 +8,4 @@ export class BaseController { res.writeHeader('access-control-allow-methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.writeHeader('access-control-allow-origin', '*'); } - - protected checkAdminToken(req: HttpRequest): void { - //TODO - /*if(req.getHeader('Authorization') !== ADMIN_API_TOKEN){ - throw 'Error token api'; - }*/ - } } diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 4dfe3576..244262d6 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -31,8 +31,7 @@ import { WebRtcStartMessage, WebRtcDisconnectMessage, PlayGlobalMessage, - ReportPlayerMessage, - TeleportMessageMessage + ReportPlayerMessage } from "../Messages/generated/messages_pb"; import {UserMovesMessage} from "../Messages/generated/messages_pb"; import Direction = PositionMessage.Direction; @@ -889,18 +888,4 @@ export class IoSocketController { } return null; } - - public teleport(userUuid: string) { - const userSocket = this.searchClientByUuid(userUuid); - if (!userSocket) { - throw 'User not found'; - } - const teleportMessageMessage = new TeleportMessageMessage(); - teleportMessageMessage.setMap(`wait/${userSocket.userUuid}`); - - const serverToClientMessage = new ServerToClientMessage(); - serverToClientMessage.setTeleportmessagemessage(teleportMessageMessage); - - userSocket.send(serverToClientMessage.serializeBinary().buffer, true); - } } diff --git a/back/src/Controller/ReportController.ts b/back/src/Controller/ReportController.ts deleted file mode 100644 index 5b5e342d..00000000 --- a/back/src/Controller/ReportController.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {BaseController} from "./BaseController"; -import {HttpRequest, HttpResponse, TemplatedApp} from "uWebSockets.js"; -import {IoSocketController} from "./IoSocketController"; - -export class ReportController extends BaseController { - - constructor(private App: TemplatedApp, private ioSocketController: IoSocketController) { - super(); - this.teleport(); - } - - teleport(){ - this.App.options("/teleport", (res: HttpResponse, req: HttpRequest) => { - this.checkAdminToken(req); - this.addCorsHeaders(res); - res.end(); - }); - - this.App.post("/teleport", (res: HttpResponse, req: HttpRequest) => { - (async () => { - try { - this.checkAdminToken(req); - this.addCorsHeaders(res); - - res.onAborted(() => { - console.warn('Login request was aborted'); - }) - const param = await res.json(); - this.ioSocketController.teleport(param.userUuid); - res.writeHeader('Content-Type', 'application/json'); - res.writeStatus("200 OK").end(JSON.stringify({ - mapUrl: `wait/${param.userUuid}` - })); - } catch (e) { - console.log("An error happened", e) - res.writeStatus(e.status || "500 Internal Server Error").end('An error happened'); - } - })(); - }); - } -} \ No newline at end of file diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index 20d10f04..e9f507a0 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -146,6 +146,8 @@ export class SimplePeer { } mediaManager.removeActiveVideo("" + user.userId); + + //TODO ad condition isPublic or annonyme mediaManager.addActiveVideo("" + user.userId, (comment: string) => { this.reportUser(user.userId, comment); }, name); From 62dfb68aafc802565a248f0d3a384e5cacbbe6cb Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Thu, 15 Oct 2020 12:24:16 +0200 Subject: [PATCH 12/15] Update style report modal --- front/dist/resources/style/style.css | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 6ee8f090..fa91d1e7 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -587,13 +587,13 @@ div.modal-report-user{ .modal-report-user textarea{ position: absolute; - width: 400px; height: 200px; z-index: 999; - left: calc(50% - 200px); top: 200px; background-color: #000000; color: white; + width: calc(100% - 60px); + margin: 30px; } .modal-report-user img{ @@ -614,6 +614,7 @@ div.modal-report-user{ cursor: pointer; width: 15px; height: 15px; + margin: 10px; } .modal-report-user button{ @@ -649,7 +650,8 @@ div.modal-report-user{ font-size: 24px; color: white; position: absolute; - top: 90px; + top: 70px; width: 100%; text-align: left; + padding: 30px; } From 0ea7240834c69596c8be4a862436399fe301180f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 15 Oct 2020 17:58:27 +0200 Subject: [PATCH 13/15] Adding condition to enable reporting only on private rooms --- front/src/Phaser/Game/GameScene.ts | 2 +- front/src/WebRtc/MediaManager.ts | 20 ++++++++++++-------- front/src/WebRtc/SimplePeer.ts | 14 ++++++-------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d993571f..d64d1757 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -592,7 +592,7 @@ export class GameScene extends ResizableScene implements CenterListener { })); // When connection is performed, let's connect SimplePeer - this.simplePeer = new SimplePeer(this.connection); + this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic); this.GlobalMessageManager = new GlobalMessageManager(this.connection); const self = this; diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index dfa6c694..eb65b555 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -342,7 +342,7 @@ export class MediaManager { * @param reportCallBack * @param userName */ - addActiveVideo(userId: string, reportCallBack: ReportCallback, userName: string = ""){ + addActiveVideo(userId: string, reportCallBack: ReportCallback|undefined, userName: string = ""){ this.webrtcInAudio.play(); userName = userName.toUpperCase(); @@ -354,18 +354,22 @@ export class MediaManager { ${userName} - - + ` + + ((reportCallBack!==undefined)?``:'') + + + ` `; layoutManager.add(DivImportance.Normal, userId, html); - const reportBtn = this.getElementByIdOrFail(`report-${userId}`); - reportBtn.addEventListener('click', (e: MouseEvent) => { - e.preventDefault(); - this.showReportModal(userId, userName, reportCallBack); - }); + if (reportCallBack) { + const reportBtn = this.getElementByIdOrFail(`report-${userId}`); + reportBtn.addEventListener('click', (e: MouseEvent) => { + e.preventDefault(); + this.showReportModal(userId, userName, reportCallBack); + }); + } this.remoteVideo.set(userId, this.getElementByIdOrFail(userId)); } diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index e9f507a0..5c77ab79 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -29,8 +29,6 @@ export interface PeerConnectionListener { * This class manages connections to all the peers in the same group as me. */ export class SimplePeer { - private Connection: RoomConnection; - private WebRtcRoomId: string; private Users: Array = new Array(); private PeerScreenSharingConnectionArray: Map = new Map(); @@ -40,9 +38,7 @@ export class SimplePeer { private readonly stopLocalScreenSharingStreamCallback: StopScreenSharingCallback; private readonly peerConnectionListeners: Array = new Array(); - constructor(Connection: RoomConnection, WebRtcRoomId: string = "test-webrtc") { - this.Connection = Connection; - this.WebRtcRoomId = WebRtcRoomId; + constructor(private Connection: RoomConnection, private enableReporting: boolean) { // We need to go through this weird bound function pointer in order to be able to "free" this reference later. this.sendLocalVideoStreamCallback = this.sendLocalVideoStream.bind(this); this.sendLocalScreenSharingStreamCallback = this.sendLocalScreenSharingStream.bind(this); @@ -148,9 +144,11 @@ export class SimplePeer { mediaManager.removeActiveVideo("" + user.userId); //TODO ad condition isPublic or annonyme - mediaManager.addActiveVideo("" + user.userId, (comment: string) => { - this.reportUser(user.userId, comment); - }, name); + const reportCallback = this.enableReporting ? (comment: string) => { + this.reportUser(user.userId, comment); + }: undefined; + + mediaManager.addActiveVideo("" + user.userId, reportCallback, name); const peer = new VideoPeer(user.userId, user.initiator ? user.initiator : false, this.Connection); // When a connection is established to a video stream, and if a screen sharing is taking place, From 267476c651a21013296c5b66216b79d88fa30725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 15 Oct 2020 17:59:32 +0200 Subject: [PATCH 14/15] Removing TODO --- back/src/Controller/AuthenticateController.ts | 2 +- front/src/WebRtc/SimplePeer.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/back/src/Controller/AuthenticateController.ts b/back/src/Controller/AuthenticateController.ts index 446e5d19..321386a2 100644 --- a/back/src/Controller/AuthenticateController.ts +++ b/back/src/Controller/AuthenticateController.ts @@ -36,7 +36,7 @@ export class AuthenticateController extends BaseController { //todo: what to do if the organizationMemberToken is already used? const organizationMemberToken:string|null = param.organizationMemberToken; - + try { if (typeof organizationMemberToken != 'string') throw new Error('No organization token'); const data = await adminApi.fetchMemberDataByToken(organizationMemberToken); diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index 5c77ab79..718837b7 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -143,7 +143,6 @@ export class SimplePeer { mediaManager.removeActiveVideo("" + user.userId); - //TODO ad condition isPublic or annonyme const reportCallback = this.enableReporting ? (comment: string) => { this.reportUser(user.userId, comment); }: undefined; From c59a335a1a0805aebc9cc95500f579acdfdcb109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Thu, 15 Oct 2020 18:00:34 +0200 Subject: [PATCH 15/15] Removing useless resource --- front/src/Phaser/Entity/body_character.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/front/src/Phaser/Entity/body_character.ts b/front/src/Phaser/Entity/body_character.ts index 50f1eea6..6fbeaadb 100644 --- a/front/src/Phaser/Entity/body_character.ts +++ b/front/src/Phaser/Entity/body_character.ts @@ -313,7 +313,6 @@ export const loadAllLayers = (load: LoaderPlugin) => { } export const OBJECTS: Array = [ - {name:'report_flag', img:'resources/objects/report_flag.png'}, {name:'layout_modes', img:'resources/objects/layout_modes.png'}, {name:'teleportation', img:'resources/objects/teleportation.png'}, ];