reworked
This commit is contained in:
@ -124,14 +124,14 @@ export class AuthController extends BaseController {
|
||||
return false;
|
||||
}
|
||||
|
||||
const tokenFromDb = await new ApiTokenMongoManager().getById(token._id.toString());
|
||||
const tokenFromDb: Token = await new ApiTokenMongoManager().getById(token._id.toString()) as Token;
|
||||
|
||||
if (!tokenFromDb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { roles } = tokenFromDb;
|
||||
const validRoles = rolesToCheck.filter((r: string) => roles.includes(r));
|
||||
const validRoles = rolesToCheck.filter((r: string) => roles?.includes(r) || false);
|
||||
return validRoles.length === rolesToCheck.length;
|
||||
}
|
||||
|
||||
|
@ -16,22 +16,42 @@ export class GameController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
public joinMatch(req: Request, res: Response) {
|
||||
public async joinMatch(req: Request, res: Response) {
|
||||
try {
|
||||
const { user, body } = req;
|
||||
const { sessionId } = body;
|
||||
this.sessionService.joinSession(user, sessionId);
|
||||
const { user, params } = req;
|
||||
const { sessionId } = params;
|
||||
await this.sessionService.joinSession(user, sessionId);
|
||||
res.status(200).json({ status: 'ok' });
|
||||
} catch (error) {
|
||||
this.handleError(res, error);
|
||||
}
|
||||
}
|
||||
|
||||
public listMatches(req: Request, res: Response) {
|
||||
public async listMatches(req: Request, res: Response) {
|
||||
try {
|
||||
this.sessionService.listSessions().then((sessions) => {
|
||||
res.status(200).json(sessions);
|
||||
});
|
||||
const sessions = await this.sessionService.listJoinableSessions()
|
||||
res.status(200).json(sessions);
|
||||
} catch (error) {
|
||||
this.handleError(res, error);
|
||||
}
|
||||
}
|
||||
|
||||
public async getMatch(req: Request, res: Response) {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
const session = this.sessionService.getSession(sessionId)
|
||||
res.status(200).json(session);
|
||||
} catch (error) {
|
||||
this.handleError(res, error);
|
||||
}
|
||||
}
|
||||
|
||||
public async deleteMatch(req: Request, res: Response) {
|
||||
try {
|
||||
const { sessionId } = req.params;
|
||||
await this.sessionService.deleteSession(sessionId);
|
||||
this.logger.info(`Session ${sessionId} deleted`);
|
||||
res.status(200).json({ status: 'ok' });
|
||||
} catch (error) {
|
||||
this.handleError(res, error);
|
||||
}
|
||||
|
@ -39,6 +39,10 @@ export interface User extends EntityMongo {
|
||||
namespace?: Namespace;
|
||||
}
|
||||
|
||||
export interface DbMatchSessionUpdate extends EntityMongo {
|
||||
state?: string;
|
||||
}
|
||||
|
||||
export interface DbMatchSession extends EntityMongo {
|
||||
id: string;
|
||||
name: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ObjectId } from "mongodb";
|
||||
import { mongoExecute } from "./mongoDBPool";
|
||||
import { Entity } from "../../interfaces";
|
||||
import { Entity, EntityMongo } from "../../interfaces";
|
||||
import { LoggingService } from "../../../../common/LoggingService";
|
||||
import toObjectId from "./mongoUtils";
|
||||
|
||||
@ -9,7 +9,8 @@ export abstract class BaseMongoManager {
|
||||
protected abstract collection?: string;
|
||||
logger = new LoggingService().logger;
|
||||
|
||||
create(data: Entity): Promise<ObjectId | undefined>{
|
||||
async create(data: Entity): Promise<ObjectId | undefined> {
|
||||
this.stampEntity(data);
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
const result = await collection?.insertOne(data as any);
|
||||
@ -19,25 +20,27 @@ export abstract class BaseMongoManager {
|
||||
);
|
||||
}
|
||||
|
||||
delete(id: string) {
|
||||
async delete(id: string): Promise<number> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
await collection?.deleteOne({ _id: this.toObjectId(id) });
|
||||
const result = await collection?.deleteOne({ _id: this.toObjectId(id) });
|
||||
return result?.deletedCount || 0;
|
||||
},
|
||||
{ colName: this.collection }
|
||||
);
|
||||
}
|
||||
|
||||
deleteByFilter(filter: any) {
|
||||
async deleteByFilter(filter: any): Promise<number> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
await collection?.deleteOne(filter);
|
||||
const result = await collection?.deleteOne(filter);
|
||||
return result?.deletedCount || 0;
|
||||
},
|
||||
{ colName: this.collection }
|
||||
);
|
||||
}
|
||||
|
||||
getById(id: string) {
|
||||
async getById(id: string): Promise<EntityMongo | null> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
return await collection?.findOne({ _id: this.toObjectId(id) });
|
||||
@ -46,7 +49,7 @@ export abstract class BaseMongoManager {
|
||||
);
|
||||
}
|
||||
|
||||
getByFilter(filter: any) {
|
||||
async getByFilter(filter: any): Promise<EntityMongo | null> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
return await collection?.findOne(filter);
|
||||
@ -55,51 +58,71 @@ export abstract class BaseMongoManager {
|
||||
);
|
||||
}
|
||||
|
||||
list() {
|
||||
async list(sortCriteria?: any, pagination?: {pageSize: number, page: number}): Promise<EntityMongo[]> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
return await collection?.find().toArray();
|
||||
const cursor = collection?.find();
|
||||
if (sortCriteria) {
|
||||
cursor?.sort(sortCriteria);
|
||||
}
|
||||
if (pagination) {
|
||||
cursor?.skip(pagination.pageSize * (pagination.page - 1)).limit(pagination.pageSize);
|
||||
}
|
||||
return await cursor?.toArray();
|
||||
},
|
||||
{ colName: this.collection }
|
||||
);
|
||||
}
|
||||
|
||||
listByFilter(filter: any) {
|
||||
async listByFilter(filter: any, sortCriteria?: any, pagination?: {pageSize: number, page: number}): Promise<EntityMongo[]> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
return await collection?.find(filter).toArray();
|
||||
const cursor = collection?.find(filter);
|
||||
if (sortCriteria) {
|
||||
cursor?.sort(sortCriteria);
|
||||
}
|
||||
if (pagination) {
|
||||
cursor?.skip(pagination.pageSize * (pagination.page - 1)).limit(pagination.pageSize);
|
||||
}
|
||||
return await cursor?.toArray();
|
||||
},
|
||||
{ colName: this.collection }
|
||||
);
|
||||
}
|
||||
|
||||
update(object: Entity) {
|
||||
async update(object: EntityMongo): Promise<number> {
|
||||
const data: any = { ...object };
|
||||
const id = data._id;
|
||||
delete data._id;
|
||||
this.stampEntity(data, false);
|
||||
delete data._id;
|
||||
return mongoExecute(async ({ collection }) => {
|
||||
return await collection?.updateOne(
|
||||
const result = await collection?.updateOne(
|
||||
{ _id: this.toObjectId(id) },
|
||||
{ $set: data }
|
||||
);
|
||||
return result?.modifiedCount || 0;
|
||||
},
|
||||
{ colName: this.collection });
|
||||
}
|
||||
|
||||
updateMany(filter: any, data: Entity) {
|
||||
async updateMany(filter: any, data: Entity): Promise<number>{
|
||||
|
||||
this.stampEntity(data, false);
|
||||
return mongoExecute(async ({ collection }) => {
|
||||
return await collection?.updateMany(filter, { $set: data as any });
|
||||
const result = await collection?.updateMany(filter, { $set: data as any });
|
||||
return result?.modifiedCount || 0;
|
||||
},
|
||||
{ colName: this.collection });
|
||||
}
|
||||
|
||||
replaceOne(filter: any, object: Entity) {
|
||||
async replaceOne(filter: any, object: Entity): Promise<number> {
|
||||
return mongoExecute(async ({collection}) => {
|
||||
return await collection?.replaceOne(filter, object);
|
||||
const result = await collection?.replaceOne(filter, object);
|
||||
return result?.modifiedCount || 0;
|
||||
}, {colName: this.collection});
|
||||
}
|
||||
|
||||
aggregation(pipeline: any) {
|
||||
async aggregation(pipeline: any): Promise<EntityMongo[]> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
return await collection?.aggregate(pipeline).toArray();
|
||||
@ -108,7 +131,7 @@ export abstract class BaseMongoManager {
|
||||
);
|
||||
}
|
||||
|
||||
aggregationOne(pipeline: any) {
|
||||
async aggregationOne(pipeline: any): Promise<EntityMongo | null> {
|
||||
return mongoExecute(
|
||||
async ({ collection }) => {
|
||||
return await collection?.aggregate(pipeline).next();
|
||||
@ -120,4 +143,11 @@ export abstract class BaseMongoManager {
|
||||
protected toObjectId = (oid: string) => {
|
||||
return toObjectId(oid);
|
||||
};
|
||||
|
||||
protected stampEntity(entity: Entity, isCreate: boolean = true) {
|
||||
if (isCreate) {
|
||||
entity.createdAt = Date.now();
|
||||
}
|
||||
entity.modifiedAt = Date.now();
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ export class SessionManager extends ManagerBase {
|
||||
SessionManager.sessions.set(session.id, session);
|
||||
}
|
||||
|
||||
deleteSession(session: MatchSession) {
|
||||
SessionManager.sessions.delete(session.id);
|
||||
deleteSession(sessionId: string) {
|
||||
SessionManager.sessions.delete(sessionId);
|
||||
}
|
||||
|
||||
getSession(id: string) {
|
||||
|
@ -10,8 +10,10 @@ export default function(): Router {
|
||||
const { authenticate } = AuthController
|
||||
|
||||
router.post('/match', authenticate({ roles: ['user']}), (req: Request, res: Response) => gameController.createMatch(req, res));
|
||||
router.patch('/match/join', authenticate({ roles: ['user']}), (req: Request, res: Response) => gameController.joinMatch(req, res));
|
||||
router.get('/match/list', authenticate({ roles: ['user']}), (req: Request, res: Response) => gameController.listMatches(req, res));
|
||||
router.get('/match', authenticate({ roles: ['user']}), (req: Request, res: Response) => gameController.listMatches(req, res));
|
||||
router.get('/match/:sessionId', authenticate({ roles: ['user']}), (req: Request, res: Response) => gameController.getMatch(req, res));
|
||||
router.put('/match/:sessionId', authenticate({ roles: ['user']}), (req: Request, res: Response) => gameController.joinMatch(req, res));
|
||||
router.delete('/match/:sessionId', authenticate({ roles: ['user']}), (req: Request, res: Response) => gameController.deleteMatch(req, res));
|
||||
|
||||
return router;
|
||||
}
|
||||
|
110
src/server/services/InteractionService.ts
Normal file
110
src/server/services/InteractionService.ts
Normal file
@ -0,0 +1,110 @@
|
||||
import PubSub from "pubsub-js";
|
||||
import { EventActions } from "../../game/constants";
|
||||
import { MatchSession } from "../../game/MatchSession";
|
||||
import { SessionManager } from "../managers/SessionManager";
|
||||
import { PlayerNotificationService } from "./PlayerNotificationService";
|
||||
import { ServiceBase } from "./ServiceBase";
|
||||
import { PlayerMove } from "../../game/entities/PlayerMove";
|
||||
|
||||
export class InteractionService extends ServiceBase{
|
||||
private sessionManager: SessionManager = new SessionManager();
|
||||
private notifyService = new PlayerNotificationService();
|
||||
|
||||
async handleClientEventWithAck(data: any): Promise<any> {
|
||||
const { event, data: eventData } = data;
|
||||
this.logger.trace(`Handling event: ${event} with ack`);
|
||||
switch(event) {
|
||||
case EventActions.START_SESSION:
|
||||
return this.onStartSession(eventData);
|
||||
default:
|
||||
// PubSub.publish(event, eventData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handleClientEvent(data: any): any {
|
||||
const { event, data: eventData } = data;
|
||||
this.logger.trace(`Handling event: ${event}`);
|
||||
switch(event) {
|
||||
case 'client:player-move':
|
||||
this.onClientMoveResponse(eventData);
|
||||
break;
|
||||
case 'client:set-client-ready':
|
||||
this.onClientReady(eventData);
|
||||
break;
|
||||
case EventActions.PLAYER_READY:
|
||||
this.onPlayerReady(eventData);
|
||||
break;
|
||||
default:
|
||||
PubSub.publish(event, eventData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private onStartSession(data: any): any {
|
||||
const sessionId: string = data.sessionId;
|
||||
const session: MatchSession | undefined = this.sessionManager.getSession(sessionId);
|
||||
|
||||
if (session === undefined) {
|
||||
return ({
|
||||
status: 'error',
|
||||
message: 'Session not found'
|
||||
});
|
||||
} else if (session.matchInProgress) {
|
||||
return {
|
||||
status: 'error',
|
||||
message: 'Game already in progress'
|
||||
};
|
||||
} else {
|
||||
const missingHumans = session.maxPlayers - session.numPlayers;
|
||||
for (let i = 0; i < missingHumans; i++) {
|
||||
session.addPlayerToSession(session.createPlayerAI(i));
|
||||
}
|
||||
this.notifyService.sendEventToPlayers('server:match-starting', session.players);
|
||||
session.start();
|
||||
return {
|
||||
status: 'ok'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public playerMove(data: any) {
|
||||
this.onClientMoveResponse(data);
|
||||
}
|
||||
|
||||
private onClientMoveResponse(data: any): any {
|
||||
const { sessionId, move }: { sessionId: string, move: PlayerMove } = data;
|
||||
const session: MatchSession | undefined = this.sessionManager.getSession(sessionId);
|
||||
if (session !== undefined) {
|
||||
session.playerMove(move);
|
||||
return {
|
||||
status: 'ok'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private onPlayerReady(data: any): any {
|
||||
const { userId, sessionId } = data;
|
||||
const session: MatchSession | undefined = this.sessionManager.getSession(sessionId);
|
||||
if (session !== undefined) {
|
||||
session.setPlayerReady(userId)
|
||||
this.notifyService.notifyMatchState(session);
|
||||
this.notifyService.notifyPlayersState(session.players);
|
||||
}
|
||||
}
|
||||
|
||||
private onClientReady(data: any): any {
|
||||
const { sessionId, userId } = data;
|
||||
const session: MatchSession | undefined = this.sessionManager.getSession(sessionId);
|
||||
session?.setClientReady(userId);
|
||||
return {
|
||||
status: 'ok'
|
||||
}
|
||||
}
|
||||
|
||||
public updateSocketId(sessionId: string, userId: string, socketId: string): any {
|
||||
return this.sessionManager.updateSocketId(sessionId, userId, socketId);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,35 +1,42 @@
|
||||
import { DominoesGame } from "../../game/DominoesGame";
|
||||
import { MatchSession } from "../../game/MatchSession";
|
||||
import { NetworkClientNotifier } from "../../game/NetworkClientNotifier";
|
||||
import { GameState } from "../../game/dto/GameState";
|
||||
import { NetworkPlayer } from "../../game/entities/player/NetworkPlayer";
|
||||
import { PlayerInterface } from "../../game/entities/player/PlayerInterface";
|
||||
import { ServiceBase } from "./ServiceBase";
|
||||
|
||||
export class PlayerNotificationService {
|
||||
export class PlayerNotificationService extends ServiceBase {
|
||||
clientNotifier: NetworkClientNotifier = new NetworkClientNotifier();
|
||||
|
||||
async notifyGameState(game: DominoesGame) {
|
||||
notifyGameState(game: DominoesGame) {
|
||||
const gameState: GameState = game.getGameState();
|
||||
const { players } = game;
|
||||
let promises: Promise<void>[] = players.map(player => player.sendEventWithAck('update-game-state', gameState));
|
||||
return await Promise.all(promises);
|
||||
players.map(player => player.sendEvent('update-game-state', gameState));
|
||||
}
|
||||
|
||||
async notifyPlayersState(players: PlayerInterface[]) {
|
||||
let promises: Promise<void>[] = players.map(player => player.sendEventWithAck('update-player-state', player.getState()));
|
||||
return await Promise.all(promises);
|
||||
notifyPlayersState(players: PlayerInterface[]) {
|
||||
players.map(player => player.sendEvent('update-player-state', player.getState()));
|
||||
}
|
||||
|
||||
|
||||
async notifyMatchState(session: MatchSession) {
|
||||
notifyMatchState(session: MatchSession) {
|
||||
const { players } = session;
|
||||
let promises: Promise<void>[] = players.map(player => player.sendEventWithAck('update-match-session-state', session.getState()));
|
||||
return await Promise.all(promises);
|
||||
players.map(player => player.sendEvent('update-match-session-state', session.getState()));
|
||||
}
|
||||
|
||||
async sendEventToPlayers(event: string, players: PlayerInterface[], data: any = {}) {
|
||||
let promises: Promise<void>[] = players.map(player => player.sendEvent(event, data));
|
||||
return await Promise.all(promises);
|
||||
async sendEventToPlayers(event: string, players: PlayerInterface[], data: Function | any = {}) {
|
||||
players.forEach((player) => {
|
||||
let dataTosend = data;
|
||||
if (typeof data === 'function') {
|
||||
dataTosend = data(player);
|
||||
}
|
||||
this.clientNotifier.sendEvent(player as NetworkPlayer, event, dataTosend);
|
||||
});
|
||||
}
|
||||
|
||||
async sendEvent(event: string, player: PlayerInterface, data: any = {}) {
|
||||
player.sendEvent(event, data)
|
||||
sendEvent(event: string, player: PlayerInterface, data: any = {}) {
|
||||
this.logger.debug(`Sending event '${event}' to player ${player.id}`);
|
||||
this.clientNotifier.sendEvent(player as NetworkPlayer, event, data);
|
||||
}
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
import { SessionCreationError } from "../../common/errors/SessionCreationError";
|
||||
import { SessionNotFoundError } from "../../common/errors/SessionNotFoundError";
|
||||
import { wait, whileNotUndefined } from "../../common/utilities";
|
||||
import { whileNotUndefined } from "../../common/utilities";
|
||||
import { NetworkPlayer } from "../../game/entities/player/NetworkPlayer";
|
||||
import { MatchSession } from "../../game/MatchSession";
|
||||
import { PlayerNotificationService } from "./PlayerNotificationService";
|
||||
import { matchSessionAdapter } from "../db/DbAdapter";
|
||||
import { DbMatchSession } from "../db/interfaces";
|
||||
import { DbMatchSession, DbMatchSessionUpdate } from "../db/interfaces";
|
||||
import { MatchSessionMongoManager } from "../db/mongo/MatchSessionMongoManager";
|
||||
import { SessionManager } from "../managers/SessionManager";
|
||||
import { ServiceBase } from "./ServiceBase";
|
||||
import { SocketIoService } from "./SocketIoService";
|
||||
import toObjectId from "../db/mongo/common/mongoUtils";
|
||||
|
||||
export class SessionService extends ServiceBase{
|
||||
private dbManager: MatchSessionMongoManager = new MatchSessionMongoManager();
|
||||
@ -37,68 +38,48 @@ export class SessionService extends ServiceBase{
|
||||
this.sessionManager.setSession(session);
|
||||
this.notifyService.notifyMatchState(session);
|
||||
this.notifyService.notifyPlayersState(session.players);
|
||||
this.logger.debug(`Session ${session.id} created`);
|
||||
return session.id;
|
||||
}
|
||||
|
||||
public async joinSession(user: any, sessionId: string): Promise<void> {
|
||||
public async joinSession(user: any, sessionId: string): Promise<string> {
|
||||
const session: MatchSession | undefined = this.sessionManager.getSession(sessionId);
|
||||
if (session === undefined) {
|
||||
throw new SessionNotFoundError();
|
||||
} let socketClient;
|
||||
}
|
||||
let socketClient;
|
||||
try {
|
||||
socketClient = await whileNotUndefined(() => SocketIoService.getClient(user._id));
|
||||
} catch (error) {
|
||||
throw new SessionCreationError();
|
||||
}
|
||||
const player = new NetworkPlayer(user._id, user.name, socketClient.socketId);
|
||||
session.addPlayer(player);
|
||||
socketClient.sessionId = session.id;
|
||||
const player = new NetworkPlayer(user._id, user.username, socketClient.socketId);
|
||||
this.dbManager.replaceOne({id: session.id}, matchSessionAdapter(session));
|
||||
session.addPlayerToSession(player);
|
||||
socketClient.sessionId = session.id;
|
||||
this.notifyService.notifyMatchState(session);
|
||||
this.notifyService.notifyPlayersState(session.players);
|
||||
return sessionId
|
||||
}
|
||||
|
||||
public listSessions(): Promise<DbMatchSession[]> {
|
||||
return this.dbManager.listByFilter({});
|
||||
public async listJoinableSessions(): Promise<DbMatchSession[]> {
|
||||
return await this.dbManager.listByFilter(
|
||||
{ state: 'created' },
|
||||
{ createdAt: -1 },
|
||||
{ page: 1, pageSize: 5 }) as DbMatchSession[];
|
||||
}
|
||||
|
||||
public updateSocketId(sessionId: string, userId: string, socketId: string): any {
|
||||
this.sessionManager.updateSocketId(sessionId, userId, socketId);
|
||||
public async getSession(sessionId: string): Promise<DbMatchSession | undefined> {
|
||||
return await this.dbManager.getById(sessionId) as DbMatchSession | undefined;
|
||||
}
|
||||
|
||||
setPlayerReady(data: any): any {
|
||||
const { userId, sessionId } = data;
|
||||
const session: MatchSession | undefined = this.sessionManager.getSession(sessionId);
|
||||
if (session !== undefined) {
|
||||
session.setPlayerReady(userId)
|
||||
this.notifyService.notifyMatchState(session);
|
||||
this.notifyService.notifyPlayersState(session.players);
|
||||
}
|
||||
}
|
||||
|
||||
startSession(data: any): any {
|
||||
const sessionId: string = data.sessionId;
|
||||
const seed: string | undefined = data.seed;
|
||||
const session: MatchSession | undefined = this.sessionManager.getSession(sessionId);
|
||||
|
||||
if (session === undefined) {
|
||||
return ({
|
||||
status: 'error',
|
||||
message: 'Session not found'
|
||||
});
|
||||
} else if (session.matchInProgress) {
|
||||
return {
|
||||
status: 'error',
|
||||
message: 'Game already in progress'
|
||||
};
|
||||
} else {
|
||||
const missingHumans = session.maxPlayers - session.numPlayers;
|
||||
for (let i = 0; i < missingHumans; i++) {
|
||||
session.addPlayer(session.createPlayerAI(i));
|
||||
}
|
||||
session.start();
|
||||
return {
|
||||
status: 'ok'
|
||||
};
|
||||
}
|
||||
public async deleteSession(sessionId: string): Promise<any> {
|
||||
this.sessionManager.deleteSession(sessionId);
|
||||
const session = {
|
||||
_id: toObjectId(sessionId),
|
||||
state: 'deleted'
|
||||
} as DbMatchSessionUpdate;
|
||||
return this.dbManager.update(session);
|
||||
}
|
||||
|
||||
// public updateSession(session: MatchSession): any {
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Server as HttpServer } from "http";
|
||||
import { ServiceBase } from "./ServiceBase";
|
||||
import { Server } from "socket.io";
|
||||
import { SessionManager } from "../managers/SessionManager";
|
||||
import { SecurityManager } from "../managers/SecurityManager";
|
||||
import { User } from "../db/interfaces";
|
||||
import { Socket } from "socket.io";
|
||||
import { SessionService } from "./SessionService";
|
||||
import { InteractionService } from "./InteractionService";
|
||||
import { ClientEvents } from "../../game/constants";
|
||||
|
||||
export class SocketIoService extends ServiceBase{
|
||||
io: Server
|
||||
private static clients: Map<string, any> = new Map();
|
||||
private sessionService: SessionService = new SessionService();
|
||||
private interactionService: InteractionService = new InteractionService();
|
||||
|
||||
static getClient(id: string) {
|
||||
return this.clients.get(id);
|
||||
@ -65,7 +65,7 @@ export class SocketIoService extends ServiceBase{
|
||||
socket.join('room-general')
|
||||
} else {
|
||||
const client = SocketIoService.clients.get(userId);
|
||||
this.sessionService.updateSocketId(client.sessionId, userId, socketId);
|
||||
this.interactionService.updateSocketId(client.sessionId, userId, socketId);
|
||||
client.socketId = socketId;
|
||||
this.logger.debug(`User '${user.username}' already connected. Updating socketId to ${socketId}`);
|
||||
client.alive = true;
|
||||
@ -82,25 +82,14 @@ export class SocketIoService extends ServiceBase{
|
||||
SocketIoService.clients.delete(id);
|
||||
}
|
||||
});
|
||||
|
||||
// socket.on('createSession', (data, callback) => {
|
||||
// const response = sessionController.createSession(data, socket.id);
|
||||
// callback(response);
|
||||
// });
|
||||
|
||||
socket.on('startSession', (data, callback) => {
|
||||
const response = this.sessionService.startSession(data);
|
||||
callback(response);
|
||||
socket.on(ClientEvents.CLIENT_EVENT, (data) => {
|
||||
this.interactionService.handleClientEvent(data);
|
||||
});
|
||||
|
||||
// socket.on('joinSession', (data, callback) => {
|
||||
// const response = sessionController.joinSession(data, socket.id);
|
||||
// callback(response);
|
||||
// });
|
||||
|
||||
socket.on('playerReady', (data, callback) => {
|
||||
const response = this.sessionService.setPlayerReady(data);
|
||||
callback(response);
|
||||
socket.on(ClientEvents.CLIENT_EVENT_WITH_ACK, (data, callback) => {
|
||||
const result = this.interactionService.handleClientEventWithAck(data);
|
||||
callback(result);
|
||||
});
|
||||
|
||||
socket.on('pong', () => {
|
||||
@ -110,11 +99,42 @@ export class SocketIoService extends ServiceBase{
|
||||
SocketIoService.clients.set(id, {...client, alive: true });
|
||||
}
|
||||
})
|
||||
socket.onAny((event, ...args) => {
|
||||
if (['pong'].includes(event)) return;
|
||||
let logStr = `Event received: ${event}`
|
||||
|
||||
if (event.startsWith('client:') && args.length > 0) {
|
||||
logStr = `${logStr} (${args[0].event})`;
|
||||
}
|
||||
this.logger.debug(logStr);
|
||||
});
|
||||
|
||||
this.pingClients()
|
||||
});
|
||||
|
||||
|
||||
// // socket.on('createSession', (data, callback) => {
|
||||
// // const response = sessionController.createSession(data, socket.id);
|
||||
// // callback(response);
|
||||
// // });
|
||||
|
||||
// socket.on('startSession', (data, callback) => {
|
||||
// const response = this.sessionService.startSession(data);
|
||||
// callback(response);
|
||||
// });
|
||||
|
||||
// socket.on('client:tile-animation-ended', (data) => {
|
||||
// this.sessionService.onClientEndTileAnimation(data);
|
||||
// });
|
||||
|
||||
// socket.on('joinSession', (data, callback) => {
|
||||
// const response = sessionController.joinSession(data, socket.id);
|
||||
// callback(response);
|
||||
// });
|
||||
|
||||
// socket.on('playerReady', (data, callback) => {
|
||||
// const response = this.sessionService.setPlayerReady(data);
|
||||
// callback(response);
|
||||
// });
|
||||
});
|
||||
}
|
||||
|
||||
private pingClients() {
|
||||
|
Reference in New Issue
Block a user