diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 6349b352..2c798797 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -1,7 +1,7 @@ import socketIO = require('socket.io'); import {Socket} from "socket.io"; import * as http from "http"; -import {MessageUserPosition} from "../Model/Websocket/MessageUserPosition"; //TODO fix import by "_Model/.." +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} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..." @@ -10,11 +10,11 @@ import {ExtRoomsInterface} from "../Model/Websocket/ExtRoomsInterface"; import {World} from "../Model/World"; import {Group} from "_Model/Group"; import {UserInterface} from "_Model/UserInterface"; +import {SetPlayerDetailsMessage} from "_Model/Websocket/SetPlayerDetailsMessage"; enum SockerIoEvent { CONNECTION = "connection", DISCONNECT = "disconnect", - ATTRIBUTE_USER_ID = "attribute-user-id", // Sent from server to client just after the connexion is established to give the client its unique id. JOIN_ROOM = "join-room", USER_POSITION = "user-position", WEBRTC_SIGNAL = "webrtc-signal", @@ -24,6 +24,7 @@ enum SockerIoEvent { MESSAGE_ERROR = "message-error", GROUP_CREATE_UPDATE = "group-create-update", GROUP_DELETE = "group-delete", + SET_PLAYER_DETAILS = "set-player-details" } export class IoSocketController { @@ -93,16 +94,16 @@ export class IoSocketController { x: user x position on map y: user y position on map */ - socket.on(SockerIoEvent.JOIN_ROOM, (message: string) => { + socket.on(SockerIoEvent.JOIN_ROOM, (roomId: any): void => { try { - let messageUserPosition = this.hydrateMessageReceive(message); - if (messageUserPosition instanceof Error) { - return socket.emit(SockerIoEvent.MESSAGE_ERROR, JSON.stringify({message: messageUserPosition.message})) + if (typeof(roomId) !== 'string') { + socket.emit(SockerIoEvent.MESSAGE_ERROR, {message: 'Expected roomId as a string.'}); + return; } let Client = (socket as ExSocketInterface); - if (Client.roomId === messageUserPosition.roomId) { + if (Client.roomId === roomId) { return; } @@ -110,32 +111,32 @@ export class IoSocketController { this.leaveRoom(Client); //join new previous room - this.joinRoom(Client, messageUserPosition); - - // sending to all clients in room except sender - this.saveUserInformation(Client, messageUserPosition); + this.joinRoom(Client, roomId); //add function to refresh position user in real time. this.refreshUserPosition(Client); - socket.to(messageUserPosition.roomId).emit(SockerIoEvent.JOIN_ROOM, messageUserPosition.toString()); + let messageUserPosition = new MessageUserPosition(Client.id, Client.name, Client.character,new Point(0, 0, 'none')); + + socket.to(roomId).emit(SockerIoEvent.JOIN_ROOM, messageUserPosition); } catch (e) { console.error('An error occurred on "join_room" event'); console.error(e); } }); - socket.on(SockerIoEvent.USER_POSITION, (message: string) => { + socket.on(SockerIoEvent.USER_POSITION, (message: any): void => { try { - let messageUserPosition = this.hydrateMessageReceive(message); - if (messageUserPosition instanceof Error) { - return socket.emit(SockerIoEvent.MESSAGE_ERROR, JSON.stringify({message: messageUserPosition.message})); + let position = this.hydratePositionReceive(message); + if (position instanceof Error) { + socket.emit(SockerIoEvent.MESSAGE_ERROR, {message: position.message}); + return; } let Client = (socket as ExSocketInterface); // sending to all clients in room except sender - this.saveUserInformation(Client, messageUserPosition); + Client.position = position; //refresh position of all user in all rooms in real time this.refreshUserPosition(Client); @@ -145,19 +146,17 @@ export class IoSocketController { } }); - socket.on(SockerIoEvent.WEBRTC_SIGNAL, (message: string) => { - let data: any = JSON.parse(message); + socket.on(SockerIoEvent.WEBRTC_SIGNAL, (data: any) => { //send only at user let client = this.searchClientById(data.receiverId); if (!client) { - console.error("client doesn't exist for ", data.receiverId); + console.error("While exchanging a WebRTC signal: client doesn't exist for ", data.receiverId); return; } - return client.emit(SockerIoEvent.WEBRTC_SIGNAL, message); + return client.emit(SockerIoEvent.WEBRTC_SIGNAL, data); }); - socket.on(SockerIoEvent.WEBRTC_OFFER, (message: string) => { - let data: any = JSON.parse(message); + socket.on(SockerIoEvent.WEBRTC_OFFER, (data: any) => { //send only at user let client = this.searchClientById(data.receiverId); @@ -165,7 +164,7 @@ export class IoSocketController { console.error("client doesn't exist for ", data.receiverId); return; } - client.emit(SockerIoEvent.WEBRTC_OFFER, message); + client.emit(SockerIoEvent.WEBRTC_OFFER, data); }); socket.on(SockerIoEvent.DISCONNECT, () => { @@ -194,7 +193,12 @@ export class IoSocketController { }); // Let's send the user id to the user - socket.emit(SockerIoEvent.ATTRIBUTE_USER_ID, socket.id); + socket.on(SockerIoEvent.SET_PLAYER_DETAILS, (playerDetails: SetPlayerDetailsMessage, answerFn) => { + let Client = (socket as ExSocketInterface); + Client.name = playerDetails.name; + Client.character = playerDetails.character; + answerFn(socket.id); + }); }); } @@ -212,6 +216,7 @@ export class IoSocketController { return client; } console.log("Could not find user with id ", userId); + //throw new Error("Could not find user with id " + userId); return null; } @@ -235,9 +240,9 @@ export class IoSocketController { * @param Client: ExSocketInterface */ sendDisconnectedEvent(Client: ExSocketInterface) { - Client.broadcast.emit(SockerIoEvent.WEBRTC_DISCONNECT, JSON.stringify({ + Client.broadcast.emit(SockerIoEvent.WEBRTC_DISCONNECT, { userId: Client.id - })); + }); //disconnect webrtc room if(!Client.webRtcRoomId){ @@ -247,17 +252,12 @@ export class IoSocketController { delete Client.webRtcRoomId; } - /** - * - * @param Client - */ leaveRoom(Client : ExSocketInterface){ //lease previous room and world if(Client.roomId){ //user leave previous world let world : World|undefined = this.Worlds.get(Client.roomId); if(world){ - console.log('Entering world.leave') world.leave(Client); //this.Worlds.set(Client.roomId, world); } @@ -266,17 +266,15 @@ export class IoSocketController { delete Client.roomId; } } - /** - * - * @param Client - * @param messageUserPosition - */ - joinRoom(Client : ExSocketInterface, messageUserPosition: MessageUserPosition){ + + joinRoom(Client : ExSocketInterface, roomId: string){ //join user in room - Client.join(messageUserPosition.roomId); + Client.join(roomId); + Client.roomId = roomId; + Client.position = new Point(-1000, -1000); //check and create new world for a room - if(!this.Worlds.get(messageUserPosition.roomId)){ + if(!this.Worlds.get(roomId)){ let world = new World((user1: string, group: Group) => { this.connectedUser(user1, group); }, (user1: string, group: Group) => { @@ -286,11 +284,10 @@ export class IoSocketController { }, (groupUuid: string, lastUser: UserInterface) => { this.sendDeleteGroupEvent(groupUuid, lastUser); }); - this.Worlds.set(messageUserPosition.roomId, world); + this.Worlds.set(roomId, world); } - let world : World|undefined = this.Worlds.get(messageUserPosition.roomId); - + let world : World|undefined = this.Worlds.get(roomId); if(world) { // Dispatch groups position to newly connected user @@ -301,11 +298,9 @@ export class IoSocketController { }); }); //join world - world.join(Client, messageUserPosition); - this.Worlds.set(messageUserPosition.roomId, world); + world.join(Client, Client.position); + this.Worlds.set(roomId, world); } - - } /** @@ -341,19 +336,10 @@ export class IoSocketController { return tabs; }, []); - client.emit(SockerIoEvent.WEBRTC_START, JSON.stringify({clients: clientsId, roomId: roomId})); + client.emit(SockerIoEvent.WEBRTC_START, {clients: clientsId, roomId: roomId}); }); } - //permit to save user position in socket - saveUserInformation(socket: ExSocketInterface, message: MessageUserPosition) { - socket.position = message.position; - socket.roomId = message.roomId; - //socket.userId = message.userId; - socket.name = message.name; - socket.character = message.character; - } - refreshUserPosition(Client : ExSocketInterface) { //refresh position of all user in all rooms in real time let rooms = (this.Io.sockets.adapter.rooms as ExtRoomsInterface); @@ -363,26 +349,22 @@ export class IoSocketController { rooms.refreshUserPosition(rooms, this.Io); // update position in the world - let data = { - userId: Client.id, - roomId: Client.roomId, - position: Client.position, - name: Client.name, - character: Client.character, - }; - let messageUserPosition = new MessageUserPosition(data); - let world = this.Worlds.get(messageUserPosition.roomId); + let messageUserPosition = new MessageUserPosition(Client.id, Client.name, Client.character, Client.position); + let world = this.Worlds.get(Client.roomId); if (!world) { return; } - world.updatePosition(Client, messageUserPosition); - this.Worlds.set(messageUserPosition.roomId, world); + world.updatePosition(Client, messageUserPosition.position); + this.Worlds.set(Client.roomId, world); } //Hydrate and manage error - hydrateMessageReceive(message: string): MessageUserPosition | Error { + hydratePositionReceive(message: any): Point | Error { try { - return new MessageUserPosition(JSON.parse(message)); + if (!message.x || !message.y || !message.direction) { + return new Error("invalid point message sent"); + } + return new Point(message.x, message.y, message.direction); } catch (err) { //TODO log error return new Error(err); @@ -421,7 +403,7 @@ export class IoSocketController { } arrayMap.forEach((value: any) => { let roomId = value[0]; - this.Io.in(roomId).emit(SockerIoEvent.USER_POSITION, JSON.stringify(value)); + this.Io.in(roomId).emit(SockerIoEvent.USER_POSITION, value); }); this.seTimeOutInProgress = setTimeout(() => { this.shareUsersPosition(); diff --git a/back/src/Model/Websocket/ExtRooms.ts b/back/src/Model/Websocket/ExtRooms.ts index 43395a28..b5493fdb 100644 --- a/back/src/Model/Websocket/ExtRooms.ts +++ b/back/src/Model/Websocket/ExtRooms.ts @@ -23,19 +23,18 @@ let RefreshUserPositionFunction = function(rooms : ExtRooms, Io: socketIO.Server } let data = { userId: socket.id, - roomId: socket.roomId, position: socket.position, name: socket.name, character: socket.character, }; let dataArray = []; - if (mapPositionUserByRoom.get(data.roomId)) { - dataArray = mapPositionUserByRoom.get(data.roomId); + if (mapPositionUserByRoom.get(socket.roomId)) { + dataArray = mapPositionUserByRoom.get(socket.roomId); dataArray.push(data); } else { dataArray = [data]; } - mapPositionUserByRoom.set(data.roomId, dataArray); + mapPositionUserByRoom.set(socket.roomId, dataArray); } rooms.userPositionMapByRoom = Array.from(mapPositionUserByRoom); }; diff --git a/back/src/Model/Websocket/Message.ts b/back/src/Model/Websocket/Message.ts deleted file mode 100644 index f4bdead8..00000000 --- a/back/src/Model/Websocket/Message.ts +++ /dev/null @@ -1,27 +0,0 @@ -export class Message { - userId: string; - roomId: string; - name: string; - character: string; - - constructor(data: any) { - if (!data.userId || !data.roomId) { - console.error("Got invalid message", data); - throw Error("userId or roomId cannot be null"); - } - this.userId = data.userId; - this.roomId = data.roomId; - this.name = data.name; - this.character = data.character; - } - - toJson() { - - return { - userId: this.userId, - roomId: this.roomId, - name: this.name, - character: this.character - } - } -} diff --git a/back/src/Model/Websocket/MessageUserPosition.ts b/back/src/Model/Websocket/MessageUserPosition.ts index 1b534620..613e47e6 100644 --- a/back/src/Model/Websocket/MessageUserPosition.ts +++ b/back/src/Model/Websocket/MessageUserPosition.ts @@ -1,44 +1,11 @@ -import {Message} from "./Message"; import {PointInterface} from "./PointInterface"; export class Point implements PointInterface{ - x: number; - y: number; - direction: string; - - constructor(x : number, y : number, direction : string = "none") { - if(x === null || y === null){ - throw Error("position x and y cannot be null"); - } - this.x = x; - this.y = y; - this.direction = direction; - } - - toJson(){ - return { - x : this.x, - y: this.y, - direction: this.direction - } + constructor(public x : number, public y : number, public direction : string = "none") { } } -export class MessageUserPosition extends Message{ - position: PointInterface; - - constructor(message: any) { - super(message); - this.position = new Point(message.position.x, message.position.y, message.position.direction); - } - - toString() { - return JSON.stringify( - Object.assign( - super.toJson(), - { - position: this.position.toJson() - }) - ); +export class MessageUserPosition { + constructor(public userId: string, public name: string, public character: string, public position: PointInterface) { } } diff --git a/back/src/Model/Websocket/PointInterface.ts b/back/src/Model/Websocket/PointInterface.ts index 7b464a5d..9243acbe 100644 --- a/back/src/Model/Websocket/PointInterface.ts +++ b/back/src/Model/Websocket/PointInterface.ts @@ -2,5 +2,4 @@ export interface PointInterface { x: number; y: number; direction: string; - toJson() : object; -} \ No newline at end of file +} diff --git a/back/src/Model/Websocket/SetPlayerDetailsMessage.ts b/back/src/Model/Websocket/SetPlayerDetailsMessage.ts new file mode 100644 index 00000000..2f3cc707 --- /dev/null +++ b/back/src/Model/Websocket/SetPlayerDetailsMessage.ts @@ -0,0 +1,4 @@ +export interface SetPlayerDetailsMessage { + name: string, + character: string +} diff --git a/back/src/Model/World.ts b/back/src/Model/World.ts index 19e8c194..39233271 100644 --- a/back/src/Model/World.ts +++ b/back/src/Model/World.ts @@ -48,10 +48,10 @@ export class World { return this.groups; } - public join(socket : Identificable, userPosition: MessageUserPosition): void { + public join(socket : Identificable, userPosition: PointInterface): void { this.users.set(socket.id, { id: socket.id, - position: userPosition.position + position: userPosition }); // Let's call update position to trigger the join / leave room this.updatePosition(socket, userPosition); @@ -69,14 +69,14 @@ export class World { this.users.delete(user.id); } - public updatePosition(socket : Identificable, userPosition: MessageUserPosition): void { + public updatePosition(socket : Identificable, userPosition: PointInterface): void { let user = this.users.get(socket.id); if(typeof user === 'undefined') { return; } - user.position.x = userPosition.position.x; - user.position.y = userPosition.position.y; + user.position.x = userPosition.x; + user.position.y = userPosition.y; if (typeof user.group === 'undefined') { // If the user is not part of a group: diff --git a/back/tests/MessageTest.ts b/back/tests/MessageTest.ts deleted file mode 100644 index d908e12e..00000000 --- a/back/tests/MessageTest.ts +++ /dev/null @@ -1,40 +0,0 @@ -import "jasmine"; -import {Message} from "../src/Model/Websocket/Message"; - -describe("Message Model", () => { - it("should find userId and roomId", () => { - let message = {userId: "test1", roomId: "test2", name: "foo", character: "user"}; - let messageObject = new Message(message); - expect(messageObject.userId).toBe("test1"); - expect(messageObject.roomId).toBe("test2"); - expect(messageObject.name).toBe("foo"); - expect(messageObject.character).toBe("user"); - }) - - it("should expose a toJson method", () => { - let message = {userId: "test1", roomId: "test2", name: "foo", character: "user"}; - let messageObject = new Message(message); - expect(messageObject.toJson()).toEqual({userId: "test1", roomId: "test2", name: "foo", character: "user"}); - }); - - it("should find throw error when no userId", () => { - let message = {roomId: "test2"}; - expect(() => { - let messageObject = new Message(message); - }).toThrow(new Error("userId or roomId cannot be null")); - }); - - it("should find throw error when no roomId", () => { - let message = {userId: "test1"}; - expect(() => { - let messageObject = new Message(message); - }).toThrow(new Error("userId or roomId cannot be null")); - }); - - it("should find throw error when no roomId", () => { - let message = {name: "foo"}; - expect(() => { - let messageObject = new Message(message); - }).toThrow(new Error("userId or roomId cannot be null")); - }); -}) diff --git a/back/tests/WorldTest.ts b/back/tests/WorldTest.ts index 148e7383..aed9b838 100644 --- a/back/tests/WorldTest.ts +++ b/back/tests/WorldTest.ts @@ -1,98 +1,60 @@ import "jasmine"; -import {Message} from "../src/Model/Websocket/Message"; import {World, ConnectCallback, DisconnectCallback } from "../src/Model/World"; -import {MessageUserPosition, Point} from "../src/Model/Websocket/MessageUserPosition"; +import {Point} from "../src/Model/Websocket/MessageUserPosition"; import { Group } from "../src/Model/Group"; -import {Distance} from "../src/Model//Distance"; describe("World", () => { it("should connect user1 and user2", () => { let connectCalledNumber: number = 0; - let connect = (user: string, group: Group): void => { + let connect: ConnectCallback = (user: string, group: Group): void => { connectCalledNumber++; } - let disconnect = (user: string, group: Group): void => { + let disconnect: DisconnectCallback = (user: string, group: Group): void => { } let world = new World(connect, disconnect, 160, 160, () => {}, () => {}); - world.join({ id: "foo" }, new MessageUserPosition({ - userId: "foofoo", - roomId: 1, - position: new Point(100, 100) - })); + world.join({ id: "foo" }, new Point(100, 100)); - world.join({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(500, 100) - })); + world.join({ id: "bar" }, new Point(500, 100)); - world.updatePosition({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(261, 100) - })); + world.updatePosition({ id: "bar" }, new Point(261, 100)); expect(connectCalledNumber).toBe(0); - world.updatePosition({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(101, 100) - })); + world.updatePosition({ id: "bar" }, new Point(101, 100)); expect(connectCalledNumber).toBe(2); - world.updatePosition({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(102, 100) - })); + world.updatePosition({ id: "bar" }, new Point(102, 100)); expect(connectCalledNumber).toBe(2); }); it("should connect 3 users", () => { let connectCalled: boolean = false; - let connect = (user: string, group: Group): void => { + let connect: ConnectCallback = (user: string, group: Group): void => { connectCalled = true; } - let disconnect = (user: string, group: Group): void => { + let disconnect: DisconnectCallback = (user: string, group: Group): void => { } let world = new World(connect, disconnect, 160, 160, () => {}, () => {}); - world.join({ id: "foo" }, new MessageUserPosition({ - userId: "foofoo", - roomId: 1, - position: new Point(100, 100) - })); + world.join({ id: "foo" }, new Point(100, 100)); - world.join({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(200, 100) - })); + world.join({ id: "bar" }, new Point(200, 100)); expect(connectCalled).toBe(true); connectCalled = false; // baz joins at the outer limit of the group - world.join({ id: "baz" }, new MessageUserPosition({ - userId: "bazbaz", - roomId: 1, - position: new Point(311, 100) - })); + world.join({ id: "baz" }, new Point(311, 100)); expect(connectCalled).toBe(false); - world.updatePosition({ id: "baz" }, new MessageUserPosition({ - userId: "bazbaz", - roomId: 1, - position: new Point(309, 100) - })); + world.updatePosition({ id: "baz" }, new Point(309, 100)); expect(connectCalled).toBe(true); }); @@ -100,43 +62,27 @@ describe("World", () => { it("should disconnect user1 and user2", () => { let connectCalled: boolean = false; let disconnectCallNumber: number = 0; - let connect = (user: string, group: Group): void => { + let connect: ConnectCallback = (user: string, group: Group): void => { connectCalled = true; } - let disconnect = (user: string, group: Group): void => { + let disconnect: DisconnectCallback = (user: string, group: Group): void => { disconnectCallNumber++; } let world = new World(connect, disconnect, 160, 160, () => {}, () => {}); - world.join({ id: "foo" }, new MessageUserPosition({ - userId: "foofoo", - roomId: 1, - position: new Point(100, 100) - })); + world.join({ id: "foo" }, new Point(100, 100)); - world.join({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(259, 100) - })); + world.join({ id: "bar" }, new Point(259, 100)); expect(connectCalled).toBe(true); expect(disconnectCallNumber).toBe(0); - world.updatePosition({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(100+160+160+1, 100) - })); + world.updatePosition({ id: "bar" }, new Point(100+160+160+1, 100)); expect(disconnectCallNumber).toBe(2); - world.updatePosition({ id: "bar" }, new MessageUserPosition({ - userId: "barbar", - roomId: 1, - position: new Point(262, 100) - })); + world.updatePosition({ id: "bar" }, new Point(262, 100)); expect(disconnectCallNumber).toBe(2); }); diff --git a/back/tsconfig.json b/back/tsconfig.json index 7686fb67..51858b84 100644 --- a/back/tsconfig.json +++ b/back/tsconfig.json @@ -36,8 +36,8 @@ /* Additional Checks */ // "noUnusedLocals": true, /* Report errors on unused locals. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/front/src/Connexion.ts b/front/src/Connexion.ts index f29bef2e..f3e4f4ce 100644 --- a/front/src/Connexion.ts +++ b/front/src/Connexion.ts @@ -1,10 +1,12 @@ import {GameManager} from "./Phaser/Game/GameManager"; - -const SocketIo = require('socket.io-client'); import Axios from "axios"; import {API_URL} from "./Enum/EnvironmentVariable"; -import {getMapKeyByUrl} from "./Phaser/Login/LogincScene"; import {MessageUI} from "./Logger/MessageUI"; +import {SetPlayerDetailsMessage} from "./Messages/SetPlayerDetailsMessage"; + +const SocketIo = require('socket.io-client'); +import Socket = SocketIOClient.Socket; + enum EventMessage{ WEBRTC_SIGNAL = "webrtc-signal", @@ -19,37 +21,25 @@ enum EventMessage{ CONNECT_ERROR = "connect_error", RECONNECT = "reconnect", - ATTRIBUTE_USER_ID = "attribute-user-id" // Sent from server to client just after the connexion is established to give the client its unique id. + SET_PLAYER_DETAILS = "set-player-details" // Send the name and character to the server (on connect), receive back the id. } class Message { userId: string; - roomId: string; name: string; character: string; - constructor(userId : string, roomId : string, name: string, character: string) { + constructor(userId : string, name: string, character: string) { this.userId = userId; - this.roomId = roomId; this.name = name; this.character = character; } - - toJson() { - return { - userId: this.userId, - roomId: this.roomId, - name: this.name, - character: this.character - } - } } export interface PointInterface { x: number; y: number; direction : string; - toJson() : object; } class Point implements PointInterface{ @@ -65,19 +55,10 @@ class Point implements PointInterface{ this.y = y; this.direction = direction; } - - toJson(){ - return { - x : this.x, - y: this.y, - direction: this.direction - } - } } export interface MessageUserPositionInterface { userId: string; - roomId: string; name: string; character: string; position: PointInterface; @@ -86,20 +67,10 @@ export interface MessageUserPositionInterface { class MessageUserPosition extends Message implements MessageUserPositionInterface{ position: PointInterface; - constructor(userId : string, roomId : string, point : Point, name: string, character: string) { - super(userId, roomId, name, character); + constructor(userId : string, point : Point, name: string, character: string) { + super(userId, name, character); this.position = point; } - - toString() { - return JSON.stringify( - Object.assign( - super.toJson(), - { - position: this.position.toJson() - }) - ); - } } export interface ListMessageUserPositionInterface { @@ -117,7 +88,6 @@ class ListMessageUserPosition { data.forEach((userPosition: any) => { this.listUsersPosition.push(new MessageUserPosition( userPosition.userId, - userPosition.roomId, new Point( userPosition.position.x, userPosition.position.y, @@ -143,10 +113,10 @@ export interface GroupCreatedUpdatedMessageInterface { export interface ConnexionInterface { socket: any; token: string; - email: string; + name: string; userId: string; - createConnexion(characterSelected: string): Promise; + createConnexion(name: string, characterSelected: string): Promise; loadMaps(): Promise; @@ -167,24 +137,24 @@ export interface ConnexionInterface { } export class Connexion implements ConnexionInterface { - socket: any; + socket: Socket; token: string; - email: string; + name: string; // TODO: drop "name" storage here + character: string; userId: string; GameManager: GameManager; - lastPositionShared: MessageUserPosition = null; + lastPositionShared: PointInterface = null; + lastRoom: string|null = null; - constructor(email : string, GameManager: GameManager) { - this.email = email; + constructor(GameManager: GameManager) { this.GameManager = GameManager; } - /** - * @param characterSelected - */ - createConnexion(characterSelected: string): Promise { + createConnexion(name: string, characterSelected: string): Promise { + this.name = name; + this.character = characterSelected; /*return Axios.post(`${API_URL}/login`, {email: this.email}) .then((res) => { this.token = res.data.token; @@ -196,19 +166,7 @@ export class Connexion implements ConnexionInterface { }*/ }); - this.connectSocketServer(); - - // TODO: maybe trigger promise only when connexion is established? - let promise = new Promise((resolve, reject) => { - /*console.log('PROMISE CREATED') - this.socket.on('connection', () => { - console.log('CONNECTED'); - resolve(this); - });*/ - resolve(this); - }); - - return promise; + return this.connectSocketServer(); /* return res.data; }) @@ -222,32 +180,42 @@ export class Connexion implements ConnexionInterface { * * @param character */ - connectSocketServer(character : string = null){ - //if try to reconnect with last position - if(this.lastPositionShared) { - //join the room - this.joinARoom( - this.lastPositionShared.roomId, - this.lastPositionShared.character - ); - - //share your first position - this.sharePosition( - this.lastPositionShared ? this.lastPositionShared.position.x : 0, - this.lastPositionShared ? this.lastPositionShared.position.y : 0, - this.lastPositionShared.character, - this.lastPositionShared.roomId, - this.lastPositionShared.position.direction - ); - } - + connectSocketServer(): Promise{ //listen event - this.attributeUserId(); this.positionOfAllUser(); this.disconnectServer(); this.errorMessage(); this.groupUpdatedOrCreated(); this.groupDeleted(); + + return new Promise((resolve, reject) => { + this.socket.emit(EventMessage.SET_PLAYER_DETAILS, { + name: this.name, + character: this.character + } as SetPlayerDetailsMessage, (id: string) => { + this.userId = id; + }); + + //if try to reconnect with last position + if(this.lastRoom) { + //join the room + this.joinARoom( + this.lastRoom + ); + } + + if(this.lastPositionShared) { + + //share your first position + this.sharePosition( + this.lastPositionShared ? this.lastPositionShared.x : 0, + this.lastPositionShared ? this.lastPositionShared.y : 0, + this.lastPositionShared.direction + ); + } + + resolve(this); + }); } //TODO add middleware with access token to secure api @@ -266,15 +234,9 @@ export class Connexion implements ConnexionInterface { * @param roomId * @param character */ - joinARoom(roomId: string, character: string): void { - let messageUserPosition = new MessageUserPosition( - this.userId, - roomId, - new Point(0, 0), - this.email, - character - ); - this.socket.emit(EventMessage.JOIN_ROOM, messageUserPosition.toString()); + joinARoom(roomId: string): void { + this.socket.emit(EventMessage.JOIN_ROOM, roomId); + this.lastRoom = roomId; } /** @@ -285,28 +247,13 @@ export class Connexion implements ConnexionInterface { * @param roomId * @param direction */ - sharePosition(x : number, y : number, character : string, roomId : string, direction : string = "none") : void{ + sharePosition(x : number, y : number, direction : string = "none") : void{ if(!this.socket){ return; } - let messageUserPosition = new MessageUserPosition( - this.userId, - roomId, - new Point(x, y, direction), - this.email, - character - ); - this.lastPositionShared = messageUserPosition; - this.socket.emit(EventMessage.USER_POSITION, messageUserPosition.toString()); - } - - attributeUserId(): void { - // This event is received as soon as the connexion is established. - // It allows informing the browser of its own user id. - this.socket.on(EventMessage.ATTRIBUTE_USER_ID, (userId: string) => { - console.log('Received my user id: ', userId); - this.userId = userId; - }); + let point = new Point(x, y, direction); + this.lastPositionShared = point; + this.socket.emit(EventMessage.USER_POSITION, point); } /** @@ -326,7 +273,7 @@ export class Connexion implements ConnexionInterface { **/ positionOfAllUser(): void { this.socket.on(EventMessage.USER_POSITION, (message: string) => { - let dataList = JSON.parse(message); + let dataList = message; let UserPositions : Array = Object.values(dataList); let listMessageUserPosition = new ListMessageUserPosition(UserPositions[0], UserPositions[1]); this.GameManager.shareUserPosition(listMessageUserPosition); @@ -347,12 +294,12 @@ export class Connexion implements ConnexionInterface { } sendWebrtcSignal(signal: any, roomId: string, userId? : string, receiverId? : string) { - return this.socket.emit(EventMessage.WEBRTC_SIGNAL, JSON.stringify({ + return this.socket.emit(EventMessage.WEBRTC_SIGNAL, { userId: userId ? userId : this.userId, receiverId: receiverId ? receiverId : this.userId, roomId: roomId, signal: signal - })); + }); } receiveWebrtcStart(callback: Function) { diff --git a/front/src/Messages/SetPlayerDetailsMessage.ts b/front/src/Messages/SetPlayerDetailsMessage.ts new file mode 100644 index 00000000..2f3cc707 --- /dev/null +++ b/front/src/Messages/SetPlayerDetailsMessage.ts @@ -0,0 +1,4 @@ +export interface SetPlayerDetailsMessage { + name: string, + character: string +} diff --git a/front/src/Phaser/Game/GameManager.ts b/front/src/Phaser/Game/GameManager.ts index b886de9e..a84653cd 100644 --- a/front/src/Phaser/Game/GameManager.ts +++ b/front/src/Phaser/Game/GameManager.ts @@ -17,7 +17,6 @@ export interface HasMovedEvent { direction: string; x: number; y: number; - character: string; } export interface MapObject { @@ -40,8 +39,8 @@ export class GameManager { connect(name: string, characterUserSelected : string) { this.playerName = name; this.characterUserSelected = characterUserSelected; - this.ConnexionInstance = new Connexion(name, this); - return this.ConnexionInstance.createConnexion(characterUserSelected).then((data : any) => { + this.ConnexionInstance = new Connexion(this); + return this.ConnexionInstance.createConnexion(name, characterUserSelected).then((data : any) => { this.SimplePeer = new SimplePeer(this.ConnexionInstance); return data; }).catch((err) => { @@ -71,8 +70,8 @@ export class GameManager { this.status = StatusGameManagerEnum.CURRENT_USER_CREATED; } - joinRoom(sceneKey : string, character: string){ - this.ConnexionInstance.joinARoom(sceneKey, character); + joinRoom(sceneKey : string){ + this.ConnexionInstance.joinARoom(sceneKey); } /** @@ -128,7 +127,7 @@ export class GameManager { } pushPlayerPosition(event: HasMovedEvent) { - this.ConnexionInstance.sharePosition(event.x, event.y, event.character, this.currentGameScene.scene.key, event.direction); + this.ConnexionInstance.sharePosition(event.x, event.y, event.direction); } loadMap(mapUrl: string, scene: ScenePlugin): string { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 1e4d1e6e..56c775ed 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -284,7 +284,7 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface, Creat this.createCollisionObject(); //join room - this.GameManager.joinRoom(this.scene.key, this.CurrentPlayer.PlayerTexture); + this.GameManager.joinRoom(this.scene.key); //listen event to share position of user this.CurrentPlayer.on(hasMovedEventName, this.pushPlayerPosition.bind(this)) diff --git a/front/src/Phaser/Player/Player.ts b/front/src/Phaser/Player/Player.ts index dd33bd3c..73aad77e 100644 --- a/front/src/Phaser/Player/Player.ts +++ b/front/src/Phaser/Player/Player.ts @@ -81,12 +81,12 @@ export class Player extends PlayableCaracter implements CurrentGamerInterface, G } if (x !== 0 || y !== 0) { this.move(x, y); - this.emit(hasMovedEventName, {direction, x: this.x, y: this.y, character: this.PlayerTexture}); + this.emit(hasMovedEventName, {direction, x: this.x, y: this.y}); } else { if (this.previousMove !== PlayerAnimationNames.None) { direction = PlayerAnimationNames.None; this.stop(); - this.emit(hasMovedEventName, {direction, x: this.x, y: this.y, character: this.PlayerTexture}); + this.emit(hasMovedEventName, {direction, x: this.x, y: this.y}); } } diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index 02f35329..595e83b2 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -32,7 +32,7 @@ export class SimplePeer implements SimplePeerInterface{ private initialise() { //receive signal by gemer - this.Connexion.receiveWebrtcSignal((message: string) => { + this.Connexion.receiveWebrtcSignal((message: any) => { this.receiveWebrtcSignal(message); }); @@ -40,7 +40,7 @@ export class SimplePeer implements SimplePeerInterface{ this.MediaManager.getCamera().then(() => { //receive message start - this.Connexion.receiveWebrtcStart((message: string) => { + this.Connexion.receiveWebrtcStart((message: any) => { this.receiveWebrtcStart(message); }); @@ -49,18 +49,12 @@ export class SimplePeer implements SimplePeerInterface{ }); //receive signal by gemer - this.Connexion.disconnectMessage((message: string) => { - let data = JSON.parse(message); + this.Connexion.disconnectMessage((data: any) => { this.closeConnexion(data.userId); }); } - /** - * - * @param message - */ - private receiveWebrtcStart(message: string) { - let data = JSON.parse(message); + private receiveWebrtcStart(data: any) { this.WebRtcRoomId = data.roomId; this.Users = data.clients; @@ -193,12 +187,7 @@ export class SimplePeer implements SimplePeerInterface{ } } - /** - * - * @param message - */ - private receiveWebrtcSignal(message: string) { - let data = JSON.parse(message); + private receiveWebrtcSignal(data: any) { try { //if offer type, create peer connexion if(data.signal.type === "offer"){