diff --git a/src/Consts/game-state.consts.ts b/src/Consts/game-state.consts.ts new file mode 100644 index 0000000..02384c0 --- /dev/null +++ b/src/Consts/game-state.consts.ts @@ -0,0 +1,5 @@ +export class GameStateConsts { + static Main = 'main'; + static EndgamePoints = 'endgamepoints'; + static Finish = 'finish'; +} \ No newline at end of file diff --git a/src/Consts/types.d.ts b/src/Consts/types.d.ts new file mode 100644 index 0000000..76ba488 --- /dev/null +++ b/src/Consts/types.d.ts @@ -0,0 +1,65 @@ +import {GameQueueTypes} from "../schemas/game-queue.schema"; + +export interface IStateInfo { + state:string; + value:string; +} + +export interface IValidAnswerReceivedSocketEvent { + telegramId: number; + validAnswer: string; + note: string; +} + +export interface IUserInfoMinimal { + telegramId: number; +} + +export interface IUserBasicInfo extends IUserInfoMinimal { + name: string; +} + +export interface IVersusBeginSocketEvent { + player1: number; + player2: number; + player1name: string; + player2name: string; +} + +export interface IVersusEndSocketEvent { + winner: number; +} + +export interface IScoreChangedSocketEvent extends IUserInfoMinimal { + newScore: number; +} + +export interface IUserCardChangedEvent extends IUserInfoMinimal { + cards: string[]; +} + +export interface IEmptyNotification {} + +export interface ISocketNotificationEvent { + text: string; + timeout: number; +} + +export interface IUserPropertyChangedEvent { + user: number; + property: string; + value: string; +} + +export interface ICardPlayedSocketEvent extends IUserInfoMinimal{ + card: string; + name: string; + timeout: number; +} +export interface IGameQueueSocketEvent { + _id: any; + completed: boolean; + target: number; + type: GameQueueTypes; + text: string; +} \ No newline at end of file diff --git a/src/featureflag/featureflag.service.ts b/src/featureflag/featureflag.service.ts index a968439..f3360b0 100644 --- a/src/featureflag/featureflag.service.ts +++ b/src/featureflag/featureflag.service.ts @@ -1,6 +1,6 @@ import {Injectable, Logger} from '@nestjs/common'; import {SharedService} from "../shared/shared.service"; -import {SocketEvents} from "../shared/events.consts"; +import {ClientNotificationType} from "../socket/socket.gateway"; export interface IFeatureFlagStatus { name: string; @@ -32,11 +32,12 @@ export class FeatureflagService { async setFeatureFlag(id: string, status: boolean) : Promise { this.logger.verbose(`Setting feature flag status for ${id} to ${status} `); const result = await this.sharedService.setConfig(`featureflag/${id}`, status.toString()); - this.sharedService.sendSocketNotificationToAllClients(SocketEvents.FEATURE_FLAG_CHANGED, {}); - return { + const ffStatus: IFeatureFlagStatus = { name: id, state: result.value !== 'false', } + this.sharedService.notifyAllClients(ClientNotificationType.FeatureFlagChanged, ffStatus); + return ffStatus; } } diff --git a/src/game/comand-handlers/proceed-game-queue-command.handler.ts b/src/game/comand-handlers/proceed-game-queue-command.handler.ts index 1732821..28dcd2c 100644 --- a/src/game/comand-handlers/proceed-game-queue-command.handler.ts +++ b/src/game/comand-handlers/proceed-game-queue-command.handler.ts @@ -1,13 +1,14 @@ -import { CommandBus, CommandHandler, EventBus, ICommandHandler } from '@nestjs/cqrs'; -import { ProceedGameQueueCommand } from '../commands/proceed-game-queue.command'; -import { GameService } from '../game.service'; -import { NextQuestionCommand } from '../commands/next-question.command'; -import { SharedService } from '../../shared/shared.service'; -import { SocketEvents } from '../../shared/events.consts'; -import { Logger } from '@nestjs/common'; -import { GameQueueTypes } from '../../schemas/game-queue.schema'; -import { QuizAnswerStateChangedEvent } from '../events/quiz-answer-state-changed.event'; -import { QuizAnswerStateEnum } from '../entities/quiz-answer-state.enum'; +import {CommandBus, CommandHandler, EventBus, ICommandHandler} from '@nestjs/cqrs'; +import {ProceedGameQueueCommand} from '../commands/proceed-game-queue.command'; +import {GameService} from '../game.service'; +import {NextQuestionCommand} from '../commands/next-question.command'; +import {SharedService} from '../../shared/shared.service'; +import {Logger} from '@nestjs/common'; +import {GameQueueTypes} from '../../schemas/game-queue.schema'; +import {QuizAnswerStateChangedEvent} from '../events/quiz-answer-state-changed.event'; +import {QuizAnswerStateEnum} from '../entities/quiz-answer-state.enum'; +import {IGameQueueSocketEvent} from "../../Consts/types"; +import {ClientNotificationType} from "../../socket/socket.gateway"; @CommandHandler(ProceedGameQueueCommand) export class GameProceedGameQueueCommandHandler @@ -25,16 +26,13 @@ export class GameProceedGameQueueCommandHandler if (!item) { return this.cmdBus.execute(new NextQuestionCommand()); } - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.GameQueueItem, - { - _id: item.id, - completed: item.completed, - target: item.target, - type: item.type, - text: item.text - }, - ); + this.sharedService.notifyAllClients(ClientNotificationType.GameQueueItem, { + _id: item.id, + completed: item.completed, + target: item.target, + type: item.type, + text: item.text + }); switch (item.type) { case GameQueueTypes.giveOutAPrize: this.eventBus.publish( diff --git a/src/game/game.service.ts b/src/game/game.service.ts index 5c85159..ae416d3 100644 --- a/src/game/game.service.ts +++ b/src/game/game.service.ts @@ -1,19 +1,15 @@ import {Injectable, InternalServerErrorException, Logger, OnApplicationBootstrap} from '@nestjs/common'; import {CommandBus, EventBus, QueryBus} from '@nestjs/cqrs'; -import { CardSelectionTimeExceedCommand } from './commands/card-selection-time-exceed.command'; -import { InjectModel } from '@nestjs/mongoose'; -import { - GameQueue, - GameQueueDocument, - GameQueueTypes, -} from '../schemas/game-queue.schema'; +import {CardSelectionTimeExceedCommand} from './commands/card-selection-time-exceed.command'; +import {InjectModel} from '@nestjs/mongoose'; +import {GameQueue, GameQueueDocument, GameQueueTypes,} from '../schemas/game-queue.schema'; import {Model, Promise} from 'mongoose'; -import { ProceedGameQueueCommand } from './commands/proceed-game-queue.command'; -import { SharedService } from '../shared/shared.service'; -import { SocketEvents } from '../shared/events.consts'; +import {ProceedGameQueueCommand} from './commands/proceed-game-queue.command'; +import {SharedService} from '../shared/shared.service'; import {ConfigService} from "@nestjs/config"; import {gameCards} from "./entities/cards.entities"; -import {GuestsService} from "../guests/guests.service"; +import {IEmptyNotification} from "../Consts/types"; +import {ClientNotificationType} from "../socket/socket.gateway"; @Injectable() export class GameService implements OnApplicationBootstrap{ @@ -27,7 +23,6 @@ export class GameService implements OnApplicationBootstrap{ private sharedService: SharedService, private commandBus: CommandBus, private queryBus: QueryBus, - private guestService: GuestsService, ) { } @@ -72,29 +67,20 @@ export class GameService implements OnApplicationBootstrap{ } qItem.completed = true; await qItem.save(); - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.QUEUE_COMPLETED, - {}, - ); + this.sharedService.notifyAllClients(ClientNotificationType.QueueCompleted, {}); await this.cmdBus.execute(new ProceedGameQueueCommand()); return qItem; } async pauseGame() { await this.sharedService.setConfig('game_state', 'paused'); - await this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.GAME_PAUSED, - {}, - ); + this.sharedService.notifyAllClients(ClientNotificationType.GamePaused, {}); return Promise.resolve({ result: true }); } async resumeGame() { await this.sharedService.setConfig('game_state', 'running'); - await this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.GAME_RESUMED, - {}, - ); + this.sharedService.notifyAllClients(ClientNotificationType.GameResumed,{}); return Promise.resolve({ result: true }); } diff --git a/src/game/versus/versus.service.ts b/src/game/versus/versus.service.ts index 715e9ef..cf8ede2 100644 --- a/src/game/versus/versus.service.ts +++ b/src/game/versus/versus.service.ts @@ -1,18 +1,18 @@ import {Injectable, Logger} from '@nestjs/common'; -import {SocketEvents} from "../../shared/events.consts"; import {GuestsService} from "../../guests/guests.service"; import {SharedService} from "../../shared/shared.service"; import {InjectModel} from "@nestjs/mongoose"; import {Versus, VersusDocument} from "../../schemas/versus.schema"; -import {Model, Query} from "mongoose"; +import {Model} from "mongoose"; import {VersusDto} from "./versus.types"; import {CommandBus, QueryBus} from "@nestjs/cqrs"; import {IncreasePlayerScoreCommand} from "../../guests/command/increase-player-score.command"; import {IncreasePlayerWinningRateCommand} from "../commands/increase-player-winning-rate.command"; -import {GetGuestQuery} from "../../guests/queries/getguest.query"; import {GetGuestPropertyQuery} from "../../guests/command/get-guest-property.handler"; import {GuestPropertyNamesConsts} from "../../Consts/guest-property-names.consts"; import {SetGuestPropertyCommand} from "../../guests/command/set-guest-property.command"; +import {IVersusBeginSocketEvent, IVersusEndSocketEvent} from "../../Consts/types"; +import {ClientNotificationType} from "../../socket/socket.gateway"; @Injectable() export class VersusService { @@ -51,10 +51,12 @@ export class VersusService { player2name: p2data.name, } })); - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.BEGIN_VERSUS, - { player1, player2, player1name: p1data.name, player2name: p2data.name } - ) + this.sharedService.notifyAllClients(ClientNotificationType.BeginVersus, { + player1, + player2, + player1name: p1data.name, + player2name: p2data.name + }); } async importVersus(data: VersusDto[]) { @@ -111,11 +113,10 @@ export class VersusService { this.logger.verbose(`Set win count for ${winner} to ${wonCount}`); tasks.push(await this.cmdBus.execute(new SetGuestPropertyCommand(winner, GuestPropertyNamesConsts.VersusWonCount, wonCount.toString))); await Promise.all(tasks); - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.END_VERSUS, - { winner: winner } - ) - + this.sharedService.notifyAllClients(ClientNotificationType.EndVersus, { + winner: winner + } + ); return item; } diff --git a/src/messaging/guests.controller.ts b/src/messaging/guests.controller.ts index 38cb32f..bd4794f 100644 --- a/src/messaging/guests.controller.ts +++ b/src/messaging/guests.controller.ts @@ -1,15 +1,15 @@ import {Controller, Logger} from "@nestjs/common"; -import {Ctx, EventPattern, MessagePattern, Payload, RmqContext} from "@nestjs/microservices"; +import {Ctx, MessagePattern, Payload, RmqContext} from "@nestjs/microservices"; import {GetGuestInfoModel} from "./models/get-guest-info.model"; import {GuestsService} from "../guests/guests.service"; import {RegisterUserModel} from "./models/register-user.model"; import {SharedService} from "../shared/shared.service"; -import {SocketEvents} from "../shared/events.consts"; import {CommandsConsts} from "../Consts/commands.consts"; import {EventBus} from "@nestjs/cqrs"; import {PlayerCardSelectedEvent} from "../game/events/player-card-selected.event"; import {getCard} from "../helpers/card-parser"; import {QuizService} from "../quiz/quiz.service"; +import {ClientNotificationType} from "../socket/socket.gateway"; @Controller() export class GuestsMessageController { @@ -49,7 +49,7 @@ export class GuestsMessageController { @MessagePattern({ cmd: CommandsConsts.PhotoUpdated }) async photoUpdated(@Payload() data: { id: number}) { this.logger.verbose(`Photo updated event, send notification`); - this.sharedService.sendSocketNotificationToAllClients(SocketEvents.PHOTOS_UPDATED_EVENT, data); + this.sharedService.notifyAllClients<{id: number}>(ClientNotificationType.PhotosUpdated, data) } @MessagePattern({ cmd: CommandsConsts.CardPlayed }) diff --git a/src/mocks/shared-service.mock.ts b/src/mocks/shared-service.mock.ts index ab35373..1d54e71 100644 --- a/src/mocks/shared-service.mock.ts +++ b/src/mocks/shared-service.mock.ts @@ -1,5 +1,5 @@ export const SharedServiceMock = { setConfig: jest.fn(), getConfig: jest.fn(), - sendSocketNotificationToAllClients: jest.fn(), + notifyAllClients: jest.fn(), } \ No newline at end of file diff --git a/src/quiz/quiz.controller.ts b/src/quiz/quiz.controller.ts index 5c251be..c5b1d53 100644 --- a/src/quiz/quiz.controller.ts +++ b/src/quiz/quiz.controller.ts @@ -51,7 +51,7 @@ export class QuizController { return this.quizService.dealPrize(); } - @Get('endgame-extrapoints') + @Post('calculate-endgame-extrapoints') async endgameExtrapoints() { return await this.quizService.calculateEndgamePoints(); diff --git a/src/quiz/quiz.service.ts b/src/quiz/quiz.service.ts index 2c29058..f9e6a8d 100644 --- a/src/quiz/quiz.service.ts +++ b/src/quiz/quiz.service.ts @@ -19,6 +19,7 @@ import {IncreasePlayerScoreCommand} from "../guests/command/increase-player-scor import {FeatureflagService} from "../featureflag/featureflag.service"; import {FeatureFlagsConsts} from "../Consts/FeatureFlags.consts"; import {QuizEndGameResults} from "./quiz.types"; +import {ClientNotificationType} from "../socket/socket.gateway"; @Injectable({ scope: Scope.TRANSIENT }) export class QuizService { @@ -48,10 +49,7 @@ export class QuizService { await item.save(); this.logger.verbose(`Question updated`); await this.guestService.postQuestion(questionDto, target); - this.sharedService.sendSocketNotificationToAllClients( - 'question_changed', - questionDto, - ); + this.sharedService.notifyAllClients(ClientNotificationType.QuestionChanged, questionDto); return item.save(); } @@ -171,7 +169,7 @@ export class QuizService { //const { maxRewards, maxInvalidAnswers } = Promise.all([maxRewardsPromise, maxInvalidAnswersPromise]); const [maxRewards, maxInvalidAnswers, maxPenaltiesReceived] = await Promise.all([maxRewardsPromise, maxInvalidAnswersPromise, maxPenaltiesPromise]); - return { + const result = { maxInvalidAnswers: { id: maxInvalidAnswers[0].id, count: maxInvalidAnswers[0].invalidAnswers, @@ -188,6 +186,8 @@ export class QuizService { name: maxPenaltiesReceived[0].name, } } + await this.sharedService.setConfig('endgame-points', JSON.stringify(result)); + return result; } private async getNextQuestion() { diff --git a/src/scheduler/scheduler.service.spec.ts b/src/scheduler/scheduler.service.spec.ts index 5329357..135f68c 100644 --- a/src/scheduler/scheduler.service.spec.ts +++ b/src/scheduler/scheduler.service.spec.ts @@ -49,7 +49,7 @@ describe('SchedulerService', () => { it('should finish game if prizes count is 0', async () => { const getRemainingPrizeCountFn = jest.spyOn(giftService, 'getRemainingPrizeCount').mockImplementation(() => Promise.resolve(0)); - const notificationFn = jest.spyOn(sharedService,'sendSocketNotificationToAllClients').mockImplementation(); + const notificationFn = jest.spyOn(sharedService,'notifyAllClients').mockImplementation(); const setStateFn = jest.spyOn(stateService,'setState').mockImplementation((name,newstate) => Promise.resolve({ state: name, value: newstate})); await service.gameStatus(); expect(getRemainingPrizeCountFn).toHaveBeenCalled(); @@ -59,7 +59,7 @@ describe('SchedulerService', () => { it('should not finish game if prizes count above 0', async () => { const getRemainingPrizeCountFn = jest.spyOn(giftService, 'getRemainingPrizeCount').mockImplementation(() => Promise.resolve(5)); - const notificationFn = jest.spyOn(sharedService,'sendSocketNotificationToAllClients').mockImplementation() + const notificationFn = jest.spyOn(sharedService,'notifyAllClients').mockImplementation() await service.gameStatus(); expect(notificationFn).not.toHaveBeenCalled(); }); diff --git a/src/scheduler/scheduler.service.ts b/src/scheduler/scheduler.service.ts index 175a4a5..c6316a1 100644 --- a/src/scheduler/scheduler.service.ts +++ b/src/scheduler/scheduler.service.ts @@ -7,9 +7,9 @@ import {SharedService} from '../shared/shared.service'; import {FeatureflagService} from "../featureflag/featureflag.service"; import {FeatureFlagsConsts} from "../Consts/FeatureFlags.consts"; import {CommandBus} from "@nestjs/cqrs"; -import {EndgameDict} from "../voice/dicts/endgame.dict"; -import {CreateNewQueueItemCommand} from "../game/commands/create-new-queue-item.command"; -import {GameQueueTypes} from "../schemas/game-queue.schema"; +import {GameStateConsts} from "../Consts/game-state.consts"; +import {IStateInfo} from "../Consts/types"; +import {ClientNotificationType} from "../socket/socket.gateway"; @Injectable() export class SchedulerService { @@ -37,24 +37,11 @@ export class SchedulerService { if(await this.featureFlagService.getFeatureFlag(FeatureFlagsConsts.EnableEndgamePoints)) { this.logger.verbose(`Feature flag ${FeatureFlagsConsts.EnableEndgamePoints} is enabled`); const endgamePoints = await this.quizService.calculateEndgamePoints(); - await Promise.all([ - this.commandBus.execute( - new CreateNewQueueItemCommand(endgamePoints.maxInvalidAnswers.id, - GameQueueTypes.extra_points, - EndgameDict.maxAmountOfInvalidQuestions)), - new CreateNewQueueItemCommand(endgamePoints.maxPenalties.id, - GameQueueTypes.extra_points, - EndgameDict.maxPenalties), - new CreateNewQueueItemCommand(endgamePoints.maxRewards.id, - GameQueueTypes.extra_points, - EndgameDict.maxAmountOfRewards) - ]); + const state = await this.stateService.setState(GameStateConsts.Main, GameStateConsts.EndgamePoints); + this.sharedService.notifyAllClients(ClientNotificationType.StateChanged, state); } else { const state = await this.stateService.setState('main', 'finish'); - this.sharedService.sendSocketNotificationToAllClients( - 'state_changed', - state, - ); + this.sharedService.notifyAllClients(ClientNotificationType.StateChanged, state); this.logger.warn(`Gifts is ended, finishing game`); } } diff --git a/src/shared/events.consts.ts b/src/shared/events.consts.ts deleted file mode 100644 index 37781fe..0000000 --- a/src/shared/events.consts.ts +++ /dev/null @@ -1,18 +0,0 @@ -export enum SocketEvents { - PHOTOS_UPDATED_EVENT = 'photos_updated', - VALID_ANSWER_RECEIVED = 'answer_received', - WRONG_ANSWER_RECEIVED = 'wrong_answer_received', - USER_ADDED = 'user_added', - USER_PROPERTY_CHANGED = 'user_property_changed', - CARDS_CHANGED_EVENT = 'cards_changed', - CARD_PLAYED = 'card_played', - SCORE_CHANGED = 'score_changed', - GameQueueItem = 'game_queue', - QUEUE_COMPLETED = 'queue_completed', - GAME_PAUSED = 'game_paused', - GAME_RESUMED = 'game_resumed', - NOTIFICATION = 'notification', - FEATURE_FLAG_CHANGED = 'feature_flag_changed', - BEGIN_VERSUS = 'begin_versus', - END_VERSUS = 'end_versus', -} diff --git a/src/shared/shared.service.ts b/src/shared/shared.service.ts index 99fd64d..8c044c8 100644 --- a/src/shared/shared.service.ts +++ b/src/shared/shared.service.ts @@ -1,4 +1,4 @@ -import { SocketGateway } from '../socket/socket.gateway'; +import {ClientNotificationType, SocketGateway} from '../socket/socket.gateway'; import { Injectable, Logger } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Config, ConfigDocument } from '../schemas/config.schema'; @@ -55,14 +55,19 @@ export class SharedService { } /** - * Notifies all connected socket about changes - * @deprecated Use specific handlers in this class - * @param event - * @param payload + * Notifies all connected clients via the socket gateway with the given event and payload. + * + * @template T - The type of the payload. + * + * @param event - The event name to be sent to the clients. + * @param payload - The data to be sent along with the event. + * + * @returns {void} - This function does not return any value. */ - sendSocketNotificationToAllClients(event: string, payload?: any) { + notifyAllClients(event: ClientNotificationType, payload: T): void { this.logger.verbose(`Sending notification to client: ${event}, ${JSON.stringify(payload)}`); this.socketGateway.notifyAllClients(event, payload); } + } diff --git a/src/socket/socket-handlers/commands-handlers/notify-card-played-command.handler.ts b/src/socket/socket-handlers/commands-handlers/notify-card-played-command.handler.ts index 2650579..1eb26ad 100644 --- a/src/socket/socket-handlers/commands-handlers/notify-card-played-command.handler.ts +++ b/src/socket/socket-handlers/commands-handlers/notify-card-played-command.handler.ts @@ -1,8 +1,9 @@ -import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; -import { NotifyCardOnScreenCommand } from '../../../game/commands/notify-card-on-screen-command'; -import { SharedService } from '../../../shared/shared.service'; -import { SocketEvents } from '../../../shared/events.consts'; -import { Logger } from '@nestjs/common'; +import {CommandHandler, ICommandHandler} from '@nestjs/cqrs'; +import {NotifyCardOnScreenCommand} from '../../../game/commands/notify-card-on-screen-command'; +import {SharedService} from '../../../shared/shared.service'; +import {Logger} from '@nestjs/common'; +import {ICardPlayedSocketEvent} from "../../../Consts/types"; +import {ClientNotificationType} from "../../socket.gateway"; @CommandHandler(NotifyCardOnScreenCommand) export class NotifyCardPlayedCommandHandler @@ -12,8 +13,7 @@ export class NotifyCardPlayedCommandHandler } async execute(command: NotifyCardOnScreenCommand): Promise { this.logger.log(`Notify about card`); - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.CARD_PLAYED, { + this.sharedService.notifyAllClients(ClientNotificationType.CardPlayed, { telegramId: command.telegramId, card: command.card.description, name: command.card.name, diff --git a/src/socket/socket-handlers/commands-handlers/send-toast-command-handler.ts b/src/socket/socket-handlers/commands-handlers/send-toast-command-handler.ts index e0b3bc3..38668fd 100644 --- a/src/socket/socket-handlers/commands-handlers/send-toast-command-handler.ts +++ b/src/socket/socket-handlers/commands-handlers/send-toast-command-handler.ts @@ -1,8 +1,9 @@ -import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; -import { SendToastCommand } from '../../../game/commands/send-toast.command'; -import { SharedService } from '../../../shared/shared.service'; -import { SocketEvents } from '../../../shared/events.consts'; +import {CommandHandler, ICommandHandler} from '@nestjs/cqrs'; +import {SendToastCommand} from '../../../game/commands/send-toast.command'; +import {SharedService} from '../../../shared/shared.service'; import {Logger} from "@nestjs/common"; +import {ISocketNotificationEvent} from "../../../Consts/types"; +import {ClientNotificationType} from "../../socket.gateway"; @CommandHandler(SendToastCommand) export class SendToastCommandHandler implements ICommandHandler { @@ -11,12 +12,9 @@ export class SendToastCommandHandler implements ICommandHandler(ClientNotificationType.Notification, { + text: command.text, + timeout: command.timeout, + }); } } diff --git a/src/socket/socket-handlers/event-handlers/cards-set-changed-event.handler.ts b/src/socket/socket-handlers/event-handlers/cards-set-changed-event.handler.ts index 84d8df3..d164717 100644 --- a/src/socket/socket-handlers/event-handlers/cards-set-changed-event.handler.ts +++ b/src/socket/socket-handlers/event-handlers/cards-set-changed-event.handler.ts @@ -1,17 +1,16 @@ -import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; -import { CardsSetChangedEvent } from '../../../game/events/cards-events/cards-set-changed.event'; -import { SharedService } from '../../../shared/shared.service'; -import { SocketEvents } from '../../../shared/events.consts'; +import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; +import {CardsSetChangedEvent} from '../../../game/events/cards-events/cards-set-changed.event'; +import {SharedService} from '../../../shared/shared.service'; +import {IUserInfoMinimal} from "../../../Consts/types"; +import {ClientNotificationType} from "../../socket.gateway"; @EventsHandler(CardsSetChangedEvent) export class CardsSetChangedEventHandler implements IEventHandler { constructor(private sharedService: SharedService) {} - handle(event: CardsSetChangedEvent): any { - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.CARDS_CHANGED_EVENT, - { telegramId: event.telegramId }, - ); + handle(event: CardsSetChangedEvent): void { + this.sharedService + .notifyAllClients(ClientNotificationType.CardsChanged, { telegramId: event.telegramId}) } } diff --git a/src/socket/socket-handlers/event-handlers/cards-updated.event.handler.ts b/src/socket/socket-handlers/event-handlers/cards-updated.event.handler.ts index f4ebbc5..44a2550 100644 --- a/src/socket/socket-handlers/event-handlers/cards-updated.event.handler.ts +++ b/src/socket/socket-handlers/event-handlers/cards-updated.event.handler.ts @@ -1,18 +1,17 @@ -import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; -import { CardsDealedEvent } from '../../../game/events/cards-dealed.event'; -import { SharedService } from '../../../shared/shared.service'; -import { SocketEvents } from '../../../shared/events.consts'; +import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; +import {CardsDealedEvent} from '../../../game/events/cards-dealed.event'; +import {SharedService} from '../../../shared/shared.service'; +import {IUserCardChangedEvent} from "../../../Consts/types"; +import {ClientNotificationType} from "../../socket.gateway"; @EventsHandler(CardsDealedEvent) export class CardsUpdatedEventHandler implements IEventHandler { constructor(private sharedService: SharedService) { } - handle(event: CardsDealedEvent): any { - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.CARDS_CHANGED_EVENT, - { - telegramId: event.telegramId, - cards: event.cards, + handle(event: CardsDealedEvent): void { + this.sharedService.notifyAllClients(ClientNotificationType.CardsChanged, { + telegramId: event.telegramId, + cards: event.cards, }); } } diff --git a/src/socket/socket-handlers/event-handlers/score-changed-event.handler.ts b/src/socket/socket-handlers/event-handlers/score-changed-event.handler.ts index 0238771..4987d41 100644 --- a/src/socket/socket-handlers/event-handlers/score-changed-event.handler.ts +++ b/src/socket/socket-handlers/event-handlers/score-changed-event.handler.ts @@ -1,7 +1,8 @@ -import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; -import { ScoreChangedEvent } from '../../../game/events/score-changed.event'; -import { SharedService } from '../../../shared/shared.service'; -import { SocketEvents } from '../../../shared/events.consts'; +import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; +import {ScoreChangedEvent} from '../../../game/events/score-changed.event'; +import {SharedService} from '../../../shared/shared.service'; +import {IScoreChangedSocketEvent} from "../../../Consts/types"; +import {ClientNotificationType} from "../../socket.gateway"; @EventsHandler(ScoreChangedEvent) export class SocketScoreChangedEventHandler @@ -9,12 +10,9 @@ export class SocketScoreChangedEventHandler constructor(private sharedService: SharedService) { } async handle(event: ScoreChangedEvent) { - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.SCORE_CHANGED, - { - telegramId: event.telegramId, - newScore: event.newScore, - }, - ); + this.sharedService.notifyAllClients(ClientNotificationType.ScoreChanged, { + telegramId: event.telegramId, + newScore: event.newScore, + }); } } diff --git a/src/socket/socket-handlers/event-handlers/user-property-changed-event.handler.ts b/src/socket/socket-handlers/event-handlers/user-property-changed-event.handler.ts index ff2937b..e384714 100644 --- a/src/socket/socket-handlers/event-handlers/user-property-changed-event.handler.ts +++ b/src/socket/socket-handlers/event-handlers/user-property-changed-event.handler.ts @@ -1,17 +1,19 @@ import {EventsHandler, IEventHandler} from "@nestjs/cqrs"; import {UserPropertyChangedEvent} from "../../../guests/event-handlers/user-property-changed.event"; import {SharedService} from "../../../shared/shared.service"; -import {SocketEvents} from "../../../shared/events.consts"; +import {IUserPropertyChangedEvent} from "../../../Consts/types"; +import {ClientNotificationType} from "../../socket.gateway"; @EventsHandler(UserPropertyChangedEvent) export class UserPropertyChangedEventHandler implements IEventHandler { constructor(private sharedService: SharedService) { } - handle(event: UserPropertyChangedEvent): any { - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.USER_PROPERTY_CHANGED, - { user: event.user, property: event.property, value: event.propertyValue } - ); + handle(event: UserPropertyChangedEvent): void { + this.sharedService.notifyAllClients(ClientNotificationType.UserPropertyChanged, { + user: event.user, + property: event.property, + value: event.propertyValue + }); } } \ No newline at end of file diff --git a/src/socket/socket-handlers/event-handlers/user-registered.event.handler.ts b/src/socket/socket-handlers/event-handlers/user-registered.event.handler.ts index 9fc0eb8..ce88775 100644 --- a/src/socket/socket-handlers/event-handlers/user-registered.event.handler.ts +++ b/src/socket/socket-handlers/event-handlers/user-registered.event.handler.ts @@ -1,17 +1,17 @@ -import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; -import { UserRegisteredEvent } from '../../../game/events/user-registered.event'; -import { SharedService } from '../../../shared/shared.service'; -import { SocketEvents } from '../../../shared/events.consts'; +import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; +import {UserRegisteredEvent} from '../../../game/events/user-registered.event'; +import {SharedService} from '../../../shared/shared.service'; +import {IUserBasicInfo} from "../../../Consts/types"; +import {ClientNotificationType} from "../../socket.gateway"; + @EventsHandler(UserRegisteredEvent) export class UserRegisteredEventHandler implements IEventHandler { constructor(private sharedService: SharedService) { } - handle(event: UserRegisteredEvent): any { - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.USER_ADDED, - { - telegramId: event.telegramId, - name: event.name, + handle(event: UserRegisteredEvent): void { + this.sharedService.notifyAllClients(ClientNotificationType.UserAdded, { + telegramId: event.telegramId, + name: event.name, }); } } diff --git a/src/socket/socket-handlers/event-handlers/valid-answer-received-event.handler.ts b/src/socket/socket-handlers/event-handlers/valid-answer-received-event.handler.ts index 1977df3..9a5dadc 100644 --- a/src/socket/socket-handlers/event-handlers/valid-answer-received-event.handler.ts +++ b/src/socket/socket-handlers/event-handlers/valid-answer-received-event.handler.ts @@ -1,7 +1,8 @@ -import { EventsHandler, IEventHandler } from '@nestjs/cqrs'; -import { ValidAnswerReceivedEvent } from '../../../game/events/valid-answer.recieved'; -import { SharedService } from '../../../shared/shared.service'; -import { SocketEvents } from '../../../shared/events.consts'; +import {EventsHandler, IEventHandler} from '@nestjs/cqrs'; +import {ValidAnswerReceivedEvent} from '../../../game/events/valid-answer.recieved'; +import {SharedService} from '../../../shared/shared.service'; +import {ClientNotificationType} from "../../socket.gateway"; +import {IValidAnswerReceivedSocketEvent} from "../../../Consts/types"; @EventsHandler(ValidAnswerReceivedEvent) export class SocketValidAnswerReceivedEventHandler @@ -11,9 +12,12 @@ export class SocketValidAnswerReceivedEventHandler } handle(event: ValidAnswerReceivedEvent): any { - this.sharedService.sendSocketNotificationToAllClients( - SocketEvents.VALID_ANSWER_RECEIVED, - { telegramId: event.tId, validAnswer: event.validAnswer, note: event.extraDetails }, - ); + const notification : IValidAnswerReceivedSocketEvent = { + telegramId: event.tId, + validAnswer: event.validAnswer, + note: event.extraDetails + }; + this.sharedService + .notifyAllClients(ClientNotificationType.ValidAnswerReceived, notification); } } diff --git a/src/socket/socket.gateway.ts b/src/socket/socket.gateway.ts index d0562b2..0c3dc48 100644 --- a/src/socket/socket.gateway.ts +++ b/src/socket/socket.gateway.ts @@ -10,6 +10,28 @@ import { Server, Socket } from 'socket.io'; import { Injectable, Logger } from "@nestjs/common"; import { from, map, Observable } from 'rxjs'; + +export const enum ClientNotificationType { + StateChanged = 'state_changed', + PhotosUpdated = 'photos_updated', + ValidAnswerReceived = 'answer_received', + WrongAnswerReceived = 'wrong_answer_received', + UserAdded = 'user_added', + UserPropertyChanged = 'user_property_changed', + CardsChanged = 'cards_changed', + CardPlayed = 'card_played', + ScoreChanged = 'score_changed', + GameQueueItem = 'game_queue', + QueueCompleted = 'queue_completed', + GamePaused = 'game_paused', + GameResumed = 'game_resumed', + Notification = 'notification', + FeatureFlagChanged = 'feature_flag_changed', + BeginVersus = 'begin_versus', + EndVersus = 'end_versus', + QuestionChanged = 'question_changed' +} + @WebSocketGateway({ cors: true, transports: ['websocket']}) @Injectable() export class SocketGateway implements OnGatewayConnection, OnGatewayDisconnect{ @@ -47,7 +69,7 @@ export class SocketGateway implements OnGatewayConnection, OnGatewayDisconnect{ } - notifyAllClients(event: string, payload: any) { + notifyAllClients(event: ClientNotificationType, payload: any) { this.server.emit("events", { event, data: payload}); // this.logger.warn(`send notification to all clients ${event}`); // this.clients.forEach((c) => { diff --git a/src/state/state.controller.ts b/src/state/state.controller.ts index b06fa96..1ad04e7 100644 --- a/src/state/state.controller.ts +++ b/src/state/state.controller.ts @@ -1,11 +1,13 @@ import {Body, Controller, Get, Inject, Logger, Param, Post} from '@nestjs/common'; -import { StateService } from './state.service'; -import { SharedService } from '../shared/shared.service'; -import { EventBus } from '@nestjs/cqrs'; -import { GameStartedEvent } from '../game/events/game-started.event'; +import {StateService} from './state.service'; +import {SharedService} from '../shared/shared.service'; +import {EventBus} from '@nestjs/cqrs'; +import {GameStartedEvent} from '../game/events/game-started.event'; import {ClientProxy} from "@nestjs/microservices"; import {CommandsConsts} from "../Consts/commands.consts"; import {MqtMessageModel} from "../messaging/models/mqt-message.model"; +import {ClientNotificationType} from "../socket/socket.gateway"; +import {IStateInfo} from "../Consts/types"; interface SetStateDTO { state: string; @@ -50,7 +52,7 @@ export class StateController { this.logger.verbose('reset commands'); this.telegramService.emit({ cmd: CommandsConsts.ResetCommands }, {}); } - this.sharedService.sendSocketNotificationToAllClients('state_changed', res); + this.sharedService.notifyAllClients(ClientNotificationType.StateChanged, res); return res; } } diff --git a/src/state/state.service.ts b/src/state/state.service.ts index feaaaac..783e24d 100644 --- a/src/state/state.service.ts +++ b/src/state/state.service.ts @@ -4,6 +4,7 @@ import { State, StateDocument } from '../schemas/state.schema'; import { Model } from 'mongoose'; import { EventBus } from '@nestjs/cqrs'; import { PrepareGameEvent } from '../game/events/prepare-game.event'; +import {IStateInfo} from "../Consts/types"; interface StateDTO { name: string; @@ -30,7 +31,7 @@ export class StateService { return state; } - async setState(name: string, newValue: string) { + async setState(name: string, newValue: string): Promise { if (newValue === 'onboarding') { this.eventBus.publish(new PrepareGameEvent()); } @@ -40,6 +41,6 @@ export class StateService { return { state: stateEntity.state, value: stateEntity.value, - } + } as IStateInfo } }