Merge pull request #116 from thecodingmachine/remove_userid

Completely getting rid of "userid"
This commit is contained in:
David Négrier 2020-05-15 21:34:12 +02:00 committed by GitHub
commit 2411a3f85a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 130 additions and 84 deletions

View File

@ -4,7 +4,7 @@ import {BAD_REQUEST, OK} from "http-status-codes";
import {SECRET_KEY, URL_ROOM_STARTED} from "../Enum/EnvironmentVariable"; //TODO fix import by "_Enum/..."
import { uuid } from 'uuidv4';
export class AuthenticateController{
export class AuthenticateController {
App : Application;
constructor(App : Application) {
@ -14,7 +14,8 @@ export class AuthenticateController{
//permit to login on application. Return token to connect on Websocket IO.
login(){
this.App.post("/login", (req: Request, res: Response) => {
// For now, let's completely forget the /login route.
/*this.App.post("/login", (req: Request, res: Response) => {
let param = req.body;
if(!param.email){
return res.status(BAD_REQUEST).send({
@ -29,6 +30,6 @@ export class AuthenticateController{
mapUrlStart: URL_ROOM_STARTED,
userId: userId,
});
});
});*/
}
}
}

View File

@ -14,6 +14,7 @@ import {UserInterface} from "_Model/UserInterface";
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",
@ -33,7 +34,8 @@ export class IoSocketController {
this.Io = socketIO(server);
// Authentication with token. it will be decoded and stored in the socket.
this.Io.use((socket: Socket, next) => {
// Completely commented for now, as we do not use the "/login" route at all.
/*this.Io.use((socket: Socket, next) => {
if (!socket.handshake.query || !socket.handshake.query.token) {
return next(new Error('Authentication error'));
}
@ -47,7 +49,7 @@ export class IoSocketController {
(socket as ExSocketInterface).token = tokenDecoded;
next();
});
});
});*/
this.ioConnection();
this.shareUsersPosition();
@ -74,6 +76,7 @@ export class IoSocketController {
let userId = lastUser.id;
let client: ExSocketInterface|null = this.searchClientById(userId);
if (client === null) {
console.warn('Could not find client ', userId, ' in group')
return;
}
let roomId = client.roomId;
@ -180,7 +183,6 @@ export class IoSocketController {
socket.leave(Client.webRtcRoomId);
//delete all socket information
delete Client.userId;
delete Client.webRtcRoomId;
delete Client.roomId;
delete Client.token;
@ -190,6 +192,9 @@ export class IoSocketController {
console.error(e);
}
});
// Let's send the user id to the user
socket.emit(SockerIoEvent.ATTRIBUTE_USER_ID, socket.id);
});
}
@ -201,11 +206,12 @@ export class IoSocketController {
let clients: Array<any> = Object.values(this.Io.sockets.sockets);
for (let i = 0; i < clients.length; i++) {
let client: ExSocketInterface = clients[i];
if (client.userId !== userId) {
continue
if (client.id !== userId) {
continue;
}
return client;
}
console.log("Could not find user with id ", userId);
return null;
}
@ -216,7 +222,7 @@ export class IoSocketController {
let clients: Array<any> = Object.values(this.Io.sockets.sockets);
for (let i = 0; i < clients.length; i++) {
let client: ExSocketInterface = clients[i];
if (client.userId !== userId) {
if (client.id !== userId) {
continue
}
return client;
@ -230,7 +236,7 @@ export class IoSocketController {
*/
sendDisconnectedEvent(Client: ExSocketInterface) {
Client.broadcast.emit(SockerIoEvent.WEBRTC_DISCONNECT, JSON.stringify({
userId: Client.userId
userId: Client.id
}));
//disconnect webrtc room
@ -248,14 +254,16 @@ export class IoSocketController {
leaveRoom(Client : ExSocketInterface){
//lease previous room and world
if(Client.roomId){
//user leave previous room
Client.leave(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);
//this.Worlds.set(Client.roomId, world);
}
//user leave previous room
Client.leave(Client.roomId);
delete Client.roomId;
}
}
/**
@ -293,7 +301,7 @@ export class IoSocketController {
});
});
//join world
world.join(messageUserPosition);
world.join(Client, messageUserPosition);
this.Worlds.set(messageUserPosition.roomId, world);
}
@ -322,11 +330,11 @@ export class IoSocketController {
clients.forEach((client: ExSocketInterface, index: number) => {
let clientsId = clients.reduce((tabs: Array<any>, clientId: ExSocketInterface, indexClientId: number) => {
if (!clientId.userId || clientId.userId === client.userId) {
if (!clientId.id || clientId.id === client.id) {
return tabs;
}
tabs.push({
userId: clientId.userId,
userId: clientId.id,
name: clientId.name,
initiator: index <= indexClientId
});
@ -341,7 +349,7 @@ export class IoSocketController {
saveUserInformation(socket: ExSocketInterface, message: MessageUserPosition) {
socket.position = message.position;
socket.roomId = message.roomId;
socket.userId = message.userId;
//socket.userId = message.userId;
socket.name = message.name;
socket.character = message.character;
}
@ -354,9 +362,9 @@ export class IoSocketController {
}
rooms.refreshUserPosition(rooms, this.Io);
// update position in the worl
// update position in the world
let data = {
userId: Client.userId,
userId: Client.id,
roomId: Client.roomId,
position: Client.position,
name: Client.name,
@ -367,7 +375,7 @@ export class IoSocketController {
if (!world) {
return;
}
world.updatePosition(messageUserPosition);
world.updatePosition(Client, messageUserPosition);
this.Worlds.set(messageUserPosition.roomId, world);
}

View File

@ -1,11 +1,12 @@
import {Socket} from "socket.io";
import {PointInterface} from "./PointInterface";
import {Identificable} from "./Identificable";
export interface ExSocketInterface extends Socket {
export interface ExSocketInterface extends Socket, Identificable {
token: any;
roomId: string;
webRtcRoomId: string;
userId: string;
//userId: string;
name: string;
character: string;
position: PointInterface;

View File

@ -22,7 +22,7 @@ let RefreshUserPositionFunction = function(rooms : ExtRooms, Io: socketIO.Server
continue;
}
let data = {
userId: socket.userId,
userId: socket.id,
roomId: socket.roomId,
position: socket.position,
name: socket.name,

View File

@ -0,0 +1,3 @@
export interface Identificable {
id: string;
}

View File

@ -16,6 +16,7 @@ export class Message {
}
toJson() {
return {
userId: this.userId,
roomId: this.roomId,

View File

@ -5,6 +5,7 @@ import {Distance} from "./Distance";
import {UserInterface} from "./UserInterface";
import {ExSocketInterface} from "_Model/Websocket/ExSocketInterface";
import {PositionInterface} from "_Model/PositionInterface";
import {Identificable} from "_Model/Websocket/Identificable";
export type ConnectCallback = (user: string, group: Group) => void;
export type DisconnectCallback = (user: string, group: Group) => void;
@ -14,17 +15,17 @@ export type GroupUpdatedCallback = (group: Group) => void;
export type GroupDeletedCallback = (uuid: string, lastUser: UserInterface) => void;
export class World {
private minDistance: number;
private groupRadius: number;
private readonly minDistance: number;
private readonly groupRadius: number;
// Users, sorted by ID
private users: Map<string, UserInterface>;
private groups: Group[];
private readonly users: Map<string, UserInterface>;
private readonly groups: Group[];
private connectCallback: ConnectCallback;
private disconnectCallback: DisconnectCallback;
private groupUpdatedCallback: GroupUpdatedCallback;
private groupDeletedCallback: GroupDeletedCallback;
private readonly connectCallback: ConnectCallback;
private readonly disconnectCallback: DisconnectCallback;
private readonly groupUpdatedCallback: GroupUpdatedCallback;
private readonly groupDeletedCallback: GroupDeletedCallback;
constructor(connectCallback: ConnectCallback,
disconnectCallback: DisconnectCallback,
@ -47,25 +48,29 @@ export class World {
return this.groups;
}
public join(userPosition: MessageUserPosition): void {
this.users.set(userPosition.userId, {
id: userPosition.userId,
public join(socket : Identificable, userPosition: MessageUserPosition): void {
this.users.set(socket.id, {
id: socket.id,
position: userPosition.position
});
// Let's call update position to trigger the join / leave room
this.updatePosition(userPosition);
this.updatePosition(socket, userPosition);
}
public leave(user : ExSocketInterface){
public leave(user : Identificable){
let userObj = this.users.get(user.id);
if (userObj !== undefined && typeof userObj.group !== 'undefined') {
this.leaveGroup(user);
if (userObj === undefined) {
// FIXME: this seems always wrong. I guess user.id is different from userPosition.userId
console.warn('User ', user.id, 'does not belong to world! It should!');
}
this.users.delete(user.userId);
if (userObj !== undefined && typeof userObj.group !== 'undefined') {
this.leaveGroup(userObj);
}
this.users.delete(user.id);
}
public updatePosition(userPosition: MessageUserPosition): void {
let user = this.users.get(userPosition.userId);
public updatePosition(socket : Identificable, userPosition: MessageUserPosition): void {
let user = this.users.get(socket.id);
if(typeof user === 'undefined') {
return;
}
@ -118,7 +123,6 @@ export class World {
throw new Error("The user is part of no group");
}
group.leave(user);
if (group.isEmpty()) {
this.groupDeletedCallback(group.getId(), user);
group.destroy();

View File

@ -17,36 +17,36 @@ describe("World", () => {
let world = new World(connect, disconnect, 160, 160, () => {}, () => {});
world.join(new MessageUserPosition({
userId: "foo",
world.join({ id: "foo" }, new MessageUserPosition({
userId: "foofoo",
roomId: 1,
position: new Point(100, 100)
}));
world.join(new MessageUserPosition({
userId: "bar",
world.join({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(500, 100)
}));
world.updatePosition(new MessageUserPosition({
userId: "bar",
world.updatePosition({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(261, 100)
}));
expect(connectCalledNumber).toBe(0);
world.updatePosition(new MessageUserPosition({
userId: "bar",
world.updatePosition({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(101, 100)
}));
expect(connectCalledNumber).toBe(2);
world.updatePosition(new MessageUserPosition({
userId: "bar",
world.updatePosition({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(102, 100)
}));
@ -64,14 +64,14 @@ describe("World", () => {
let world = new World(connect, disconnect, 160, 160, () => {}, () => {});
world.join(new MessageUserPosition({
userId: "foo",
world.join({ id: "foo" }, new MessageUserPosition({
userId: "foofoo",
roomId: 1,
position: new Point(100, 100)
}));
world.join(new MessageUserPosition({
userId: "bar",
world.join({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(200, 100)
}));
@ -80,16 +80,16 @@ describe("World", () => {
connectCalled = false;
// baz joins at the outer limit of the group
world.join(new MessageUserPosition({
userId: "baz",
world.join({ id: "baz" }, new MessageUserPosition({
userId: "bazbaz",
roomId: 1,
position: new Point(311, 100)
}));
expect(connectCalled).toBe(false);
world.updatePosition(new MessageUserPosition({
userId: "baz",
world.updatePosition({ id: "baz" }, new MessageUserPosition({
userId: "bazbaz",
roomId: 1,
position: new Point(309, 100)
}));
@ -109,14 +109,14 @@ describe("World", () => {
let world = new World(connect, disconnect, 160, 160, () => {}, () => {});
world.join(new MessageUserPosition({
userId: "foo",
world.join({ id: "foo" }, new MessageUserPosition({
userId: "foofoo",
roomId: 1,
position: new Point(100, 100)
}));
world.join(new MessageUserPosition({
userId: "bar",
world.join({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(259, 100)
}));
@ -124,16 +124,16 @@ describe("World", () => {
expect(connectCalled).toBe(true);
expect(disconnectCallNumber).toBe(0);
world.updatePosition(new MessageUserPosition({
userId: "bar",
world.updatePosition({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(100+160+160+1, 100)
}));
expect(disconnectCallNumber).toBe(2);
world.updatePosition(new MessageUserPosition({
userId: "bar",
world.updatePosition({ id: "bar" }, new MessageUserPosition({
userId: "barbar",
roomId: 1,
position: new Point(262, 100)
}));

View File

@ -18,7 +18,8 @@ enum EventMessage{
GROUP_DELETE = "group-delete",
CONNECT_ERROR = "connect_error",
RECONNECT = "reconnect"
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.
}
class Message {
@ -184,25 +185,37 @@ export class Connexion implements ConnexionInterface {
* @param characterSelected
*/
createConnexion(characterSelected: string): Promise<ConnexionInterface> {
return Axios.post(`${API_URL}/login`, {email: this.email})
/*return Axios.post(`${API_URL}/login`, {email: this.email})
.then((res) => {
this.token = res.data.token;
this.userId = res.data.userId;
this.userId = res.data.userId;*/
this.socket = SocketIo(`${API_URL}`, {
query: {
/*query: {
token: this.token
}
}*/
});
this.connectSocketServer();
return res.data;
// TODO: maybe trigger promise only when connexion is established?
let promise = new Promise<ConnexionInterface>((resolve, reject) => {
/*console.log('PROMISE CREATED')
this.socket.on('connection', () => {
console.log('CONNECTED');
resolve(this);
});*/
resolve(this);
});
return promise;
/* return res.data;
})
.catch((err) => {
console.error(err);
throw err;
});
});*/
}
/**
@ -229,6 +242,7 @@ export class Connexion implements ConnexionInterface {
}
//listen event
this.attributeUserId();
this.positionOfAllUser();
this.disconnectServer();
this.errorMessage();
@ -286,6 +300,15 @@ export class Connexion implements ConnexionInterface {
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;
});
}
/**
* The data sent is an array with information for each user :
* [

View File

@ -67,7 +67,7 @@ export class GameManager {
*/
createCurrentPlayer(): void {
//Get started room send by the backend
this.currentGameScene.createCurrentPlayer(this.ConnexionInstance.userId);
this.currentGameScene.createCurrentPlayer();
this.status = StatusGameManagerEnum.CURRENT_USER_CREATED;
}
@ -119,6 +119,10 @@ export class GameManager {
return this.playerName;
}
getPlayerId(): string {
return this.ConnexionInstance.userId;
}
getCharacterSelected(): string {
return this.characterUserSelected;
}

View File

@ -15,7 +15,7 @@ export enum Textures {
export interface GameSceneInterface extends Phaser.Scene {
Map: Phaser.Tilemaps.Tilemap;
createCurrentPlayer(UserId : string) : void;
createCurrentPlayer() : void;
shareUserPosition(UsersPosition : Array<MessageUserPositionInterface>): void;
shareGroupPosition(groupPositionMessage: GroupCreatedUpdatedMessageInterface): void;
updateOrCreateMapPlayer(UsersPosition : Array<MessageUserPositionInterface>): void;
@ -266,11 +266,11 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface, Creat
})
}
createCurrentPlayer(UserId : string){
createCurrentPlayer(){
//initialise player
//TODO create animation moving between exit and strat
this.CurrentPlayer = new Player(
UserId,
null, // The current player is not has no id (because the id can change if connexion is lost and we should check that id using the GameManager.
this,
this.startX,
this.startY,
@ -347,9 +347,11 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface, Creat
return;
}
let currentPlayerId = this.GameManager.getPlayerId();
//add or create new user
UsersPosition.forEach((userPosition : MessageUserPositionInterface) => {
if(userPosition.userId === this.CurrentPlayer.userId){
if(userPosition.userId === currentPlayerId){
return;
}
let player = this.findPlayerInMap(userPosition.userId);

View File

@ -90,7 +90,7 @@ export class LogincScene extends Phaser.Scene implements GameSceneInterface {
});
/*create user*/
this.createCurrentPlayer("test");
this.createCurrentPlayer();
cypressAsserter.initFinished();
}
@ -144,7 +144,7 @@ export class LogincScene extends Phaser.Scene implements GameSceneInterface {
throw new Error("Method not implemented.");
}
createCurrentPlayer(UserId: string): void {
createCurrentPlayer(): void {
for (let i = 0; i <PLAYER_RESOURCES.length; i++) {
let playerResource = PLAYER_RESOURCES[i];
let player = this.physics.add.sprite(playerResource.x, playerResource.y, playerResource.name, playerResource.name);

View File

@ -7,7 +7,6 @@ import {PlayableCaracter} from "../Entity/PlayableCaracter";
export const hasMovedEventName = "hasMoved";
export interface CurrentGamerInterface extends PlayableCaracter{
userId : string;
initAnimation() : void;
moveUser(delta: number) : void;
say(text : string) : void;