jp.ms.common.modules 1.0.54 → 1.0.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/exception/global-exception-filter.js +5 -7
  2. package/dist/exception/global-exception-filter.js.map +1 -1
  3. package/dist/modules/main/main-tables-list-screen.view.js +5 -2
  4. package/dist/modules/main/main-tables-list-screen.view.js.map +1 -1
  5. package/dist/modules/main/main.controller.d.ts +1 -1
  6. package/dist/modules/main/main.controller.js +1 -1
  7. package/dist/modules/main/main.controller.js.map +1 -1
  8. package/dist/modules/main/main.service.d.ts +1 -1
  9. package/dist/modules/main/main.service.js +10 -3
  10. package/dist/modules/main/main.service.js.map +1 -1
  11. package/dist/modules/many-tables-tournament/many-tables-tournament.controller.d.ts +2 -2
  12. package/dist/modules/many-tables-tournament/many-tables-tournament.controller.js +2 -3
  13. package/dist/modules/many-tables-tournament/many-tables-tournament.controller.js.map +1 -1
  14. package/dist/modules/many-tables-tournament/many-tables-tournament.module.js +4 -0
  15. package/dist/modules/many-tables-tournament/many-tables-tournament.module.js.map +1 -1
  16. package/dist/modules/many-tables-tournament/many-tables-tournament.service.d.ts +5 -4
  17. package/dist/modules/many-tables-tournament/many-tables-tournament.service.js +30 -21
  18. package/dist/modules/many-tables-tournament/many-tables-tournament.service.js.map +1 -1
  19. package/dist/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.interfaces.d.ts +2 -0
  20. package/dist/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.module.js +3 -0
  21. package/dist/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.module.js.map +1 -1
  22. package/dist/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.service.d.ts +7 -0
  23. package/dist/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.service.js +48 -3
  24. package/dist/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.service.js.map +1 -1
  25. package/dist/modules/one-table-tournament/one-table-tournament.controller.d.ts +1 -1
  26. package/dist/modules/one-table-tournament/one-table-tournament.controller.js +1 -1
  27. package/dist/modules/one-table-tournament/one-table-tournament.module.js +6 -1
  28. package/dist/modules/one-table-tournament/one-table-tournament.module.js.map +1 -1
  29. package/dist/modules/one-table-tournament/one-table-tournament.service.d.ts +4 -2
  30. package/dist/modules/one-table-tournament/one-table-tournament.service.js +20 -8
  31. package/dist/modules/one-table-tournament/one-table-tournament.service.js.map +1 -1
  32. package/dist/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.interfaces.d.ts +2 -0
  33. package/dist/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.module.d.ts +3 -2
  34. package/dist/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.module.js +15 -2
  35. package/dist/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.module.js.map +1 -1
  36. package/dist/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.service.d.ts +10 -2
  37. package/dist/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.service.js +53 -7
  38. package/dist/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.service.js.map +1 -1
  39. package/dist/modules/simple-rooms/simple-rooms.controller.d.ts +1 -1
  40. package/dist/modules/simple-rooms/simple-rooms.controller.js +2 -2
  41. package/dist/modules/simple-rooms/simple-rooms.controller.js.map +1 -1
  42. package/dist/modules/simple-rooms/simple-rooms.module.js +2 -1
  43. package/dist/modules/simple-rooms/simple-rooms.module.js.map +1 -1
  44. package/dist/modules/simple-rooms/simple-rooms.service.d.ts +4 -2
  45. package/dist/modules/simple-rooms/simple-rooms.service.js +20 -8
  46. package/dist/modules/simple-rooms/simple-rooms.service.js.map +1 -1
  47. package/dist/modules/simple-rooms-manager/simple-rooms-manager.service.js +2 -2
  48. package/dist/modules/simple-rooms-manager/simple-rooms-manager.service.js.map +1 -1
  49. package/dist/tsconfig.tsbuildinfo +1 -1
  50. package/package.json +3 -3
  51. package/src/exception/global-exception-filter.ts +4 -10
  52. package/src/modules/main/main-tables-list-screen.view.ts +9 -2
  53. package/src/modules/main/main.controller.ts +1 -1
  54. package/src/modules/main/main.service.ts +20 -3
  55. package/src/modules/many-tables-tournament/many-tables-tournament.controller.ts +2 -2
  56. package/src/modules/many-tables-tournament/many-tables-tournament.module.ts +7 -0
  57. package/src/modules/many-tables-tournament/many-tables-tournament.service.ts +54 -38
  58. package/src/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.interfaces.ts +2 -0
  59. package/src/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.module.ts +3 -0
  60. package/src/modules/many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.service.ts +81 -3
  61. package/src/modules/one-table-tournament/one-table-tournament.controller.ts +1 -1
  62. package/src/modules/one-table-tournament/one-table-tournament.module.ts +9 -1
  63. package/src/modules/one-table-tournament/one-table-tournament.service.ts +30 -8
  64. package/src/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.interfaces.ts +2 -0
  65. package/src/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.module.ts +24 -2
  66. package/src/modules/one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.service.ts +69 -1
  67. package/src/modules/simple-rooms/simple-rooms.controller.ts +6 -2
  68. package/src/modules/simple-rooms/simple-rooms.module.ts +5 -1
  69. package/src/modules/simple-rooms/simple-rooms.service.ts +32 -6
  70. package/src/modules/simple-rooms-manager/simple-rooms-manager.service.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jp.ms.common.modules",
3
- "version": "1.0.54",
3
+ "version": "1.0.56",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,8 +15,8 @@
15
15
  "dayjs": "1.11.18",
16
16
  "jp.common.models": "1.1.61",
17
17
  "jp.common.utils": "1.0.9",
18
- "jp.db.schemas": "2.2.17",
19
- "jp.ms.common.engine": "3.0.33",
18
+ "jp.db.schemas": "2.2.25",
19
+ "jp.ms.common.engine": "3.0.35",
20
20
  "mongoose": "9.1.5",
21
21
  "nestjs-i18n": "10.5.1",
22
22
  "node-schedule": "2.1.1",
@@ -23,16 +23,10 @@ export class GlobalExceptionFilter implements ExceptionFilter {
23
23
  const ctx = host.switchToHttp();
24
24
  const response = ctx.getResponse<Response>();
25
25
 
26
- switch (exception.constructor.name) {
27
- case HttpExceptionWithSnackbar.name: {
28
- return this.processHttpExceptionWithSnackbar(
29
- exception as HttpExceptionWithSnackbar,
30
- response,
31
- );
32
- }
33
- case HttpException.name: {
34
- return this.processHttpException(exception as HttpException, response);
35
- }
26
+ if (exception instanceof HttpExceptionWithSnackbar) {
27
+ return this.processHttpExceptionWithSnackbar(exception, response);
28
+ } else if (exception instanceof HttpException) {
29
+ return this.processHttpException(exception, response);
36
30
  }
37
31
 
38
32
  response.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
@@ -123,7 +123,11 @@ export class MainTablesListScreenView extends UniversalScreenView {
123
123
  this.getOneTableTournamentIcon(room),
124
124
  true,
125
125
  true,
126
- AppScreenRouter.getOneTableTournamentStatusPath(room.getId()),
126
+ room.getRoomMaster<TournamentMaster>().isInProgress()
127
+ ? AppScreenRouter.getOneTableTournamentTablePath(
128
+ room.getFirstMaster()?.getTable().getId() ?? '',
129
+ )
130
+ : AppScreenRouter.getOneTableTournamentStatusPath(room.getId()),
127
131
  ),
128
132
  );
129
133
  }
@@ -251,7 +255,10 @@ export class MainTablesListScreenView extends UniversalScreenView {
251
255
  }
252
256
 
253
257
  private getManyTablesTournamenButtons(tournament: ManyTablesTournamentRoom) {
254
- if (tournament.isParticipant(this.playerId)) {
258
+ if (
259
+ tournament.isParticipant(this.playerId) ||
260
+ tournament.getRoomMaster<TournamentMaster>().isInProgress()
261
+ ) {
255
262
  return new PrimaryButtonButtonsComponent(
256
263
  new TextButtonComponent(
257
264
  this.localeService.t(
@@ -43,7 +43,7 @@ export class MainController {
43
43
  }
44
44
 
45
45
  @Get('find_free_table')
46
- findFreeTable(@Headers() headers: IAppHeaders): FindFreeTableDto {
46
+ findFreeTable(@Headers() headers: IAppHeaders): Promise<FindFreeTableDto> {
47
47
  return this.mainService.findFreeTable(
48
48
  headers.client_auth_token,
49
49
  headers.client_language,
@@ -29,6 +29,7 @@ import { ManyTablesTournamentRoomsManagerService } from '../many-tables-tourname
29
29
  import { EventsBusMainTablesSubscribeService } from '../event-bus/events-bus.main-tables.subscribe.service';
30
30
  import {
31
31
  ErrorCodeEnum,
32
+ NotEnoughMoneyForPurchaseException,
32
33
  NotFoundFreeRoomForFastGameException,
33
34
  } from '../../exception';
34
35
 
@@ -140,11 +141,16 @@ export class MainService {
140
141
  return PlayerCheckStateDto.fromEntities(redirectUrl, player?.id ?? '');
141
142
  }
142
143
 
143
- findFreeTable(clientAuthToken: string, lang: string): FindFreeTableDto {
144
+ async findFreeTable(
145
+ clientAuthToken: string,
146
+ lang: string,
147
+ ): Promise<FindFreeTableDto> {
144
148
  const player = this.playersManager.getPlayerById(clientAuthToken);
145
- const tableId = this.simpleRoomsManager.getFreeFastGameRoom()?.getId();
149
+ const table = this.simpleRoomsManager.getFreeFastGameRoom();
150
+ const tableId = table?.getId();
151
+ const user = await this.usersRepository.findById(player?.id ?? '');
146
152
 
147
- if (!player || !tableId) {
153
+ if (!player || !table || !tableId || !user) {
148
154
  throw new NotFoundFreeRoomForFastGameException(
149
155
  new ErrorSnackbarComponent(
150
156
  ErrorCodeEnum.NOT_FOUND_FREE_ROOM_FOR_FAST_GAME,
@@ -153,6 +159,17 @@ export class MainService {
153
159
  );
154
160
  }
155
161
 
162
+ if (user.balance < table.room.getTicketPrice()) {
163
+ throw new NotEnoughMoneyForPurchaseException(
164
+ new ErrorSnackbarComponent(
165
+ ErrorCodeEnum.NOT_ENOUGH_MONEY_FOR_PURCHASE,
166
+ this.options.i18n.t('common.server.message.code.4004', {
167
+ lang,
168
+ }),
169
+ ),
170
+ );
171
+ }
172
+
156
173
  return FindFreeTableDto.fromEntities(
157
174
  AppScreenRouter.getSimpleRoomTablePath(tableId),
158
175
  player.id,
@@ -104,7 +104,7 @@ export class ManyTablesTournamentController {
104
104
  joinTournament(
105
105
  @Param('tournamentId') tournamentId: string,
106
106
  @Headers() headers: IAppHeaders,
107
- ): JoinTournamentDto {
107
+ ): Promise<JoinTournamentDto> {
108
108
  return this.tournamentService.joinTournament(
109
109
  tournamentId,
110
110
  headers.client_auth_token,
@@ -116,7 +116,7 @@ export class ManyTablesTournamentController {
116
116
  leaveTournament(
117
117
  @Param('tournamentId') tournamentId: string,
118
118
  @Headers() headers: IAppHeaders,
119
- ): void {
119
+ ): Promise<void> {
120
120
  return this.tournamentService.leaveTournament(
121
121
  tournamentId,
122
122
  headers.client_auth_token,
@@ -4,6 +4,9 @@ import {
4
4
  ManyTablesTournamentRoom,
5
5
  ManyTablesTournamentRoomSchema,
6
6
  ManyTablesTournamentRoomsRepository,
7
+ Purchase,
8
+ PurchaseRepository,
9
+ PurchaseSchema,
7
10
  User,
8
11
  UserSchema,
9
12
  UsersRepository,
@@ -31,12 +34,16 @@ import { ManyTablesTournamentModuleOptions } from './many-tables-tournament.inte
31
34
  },
32
35
  ]),
33
36
  MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
37
+ MongooseModule.forFeature([
38
+ { name: Purchase.name, schema: PurchaseSchema },
39
+ ]),
34
40
  ],
35
41
  controllers: [ManyTablesTournamentController],
36
42
  providers: [
37
43
  ManyTablesTournamentService,
38
44
  ManyTablesTournamentRoomsRepository,
39
45
  UsersRepository,
46
+ PurchaseRepository,
40
47
  ],
41
48
  })
42
49
  export class ManyTablesTournamentModule {
@@ -9,11 +9,8 @@ import {
9
9
  AppScreenRouter,
10
10
  ErrorSnackbarComponent,
11
11
  } from 'jp.common.models';
12
- import {
13
- ManyTablesTournamentMaster,
14
- TournamentMaster,
15
- } from 'jp.ms.common.engine';
16
- import { UsersRepository } from 'jp.db.schemas';
12
+ import { TournamentMaster } from 'jp.ms.common.engine';
13
+ import { PurchaseRepository, UsersRepository } from 'jp.db.schemas';
17
14
 
18
15
  import { BaseAppScreenDto } from '../../dto';
19
16
  import { ManyTablesTournamentRoomsManagerService } from '../many-tables-tournament-rooms-manager/many-tables-tournament-rooms-manager.service';
@@ -39,6 +36,7 @@ export class ManyTablesTournamentService {
39
36
  @Inject(MANY_TABLES_TOURNAMENT_OPTIONS)
40
37
  private readonly options: ManyTablesTournamentFactoryOptions,
41
38
  private readonly usersRepository: UsersRepository,
39
+ private readonly purchaseRepository: PurchaseRepository,
42
40
  ) {}
43
41
 
44
42
  getStatusScreen(
@@ -139,54 +137,58 @@ export class ManyTablesTournamentService {
139
137
  throw new InternalServerErrorException();
140
138
  }
141
139
 
142
- joinTournament(
140
+ async joinTournament(
143
141
  tournamentId: string,
144
142
  clientAuthToken: string,
145
- ): JoinTournamentDto {
143
+ ): Promise<JoinTournamentDto> {
146
144
  const player = this.playersManager.getPlayerById(clientAuthToken);
147
145
  const tournament =
148
146
  this.manyTablesRoomsManagerService.getRoomByTableId(tournamentId);
147
+ const ticket = await this.purchaseRepository.getManyTablesTournamentTicket(
148
+ tournamentId,
149
+ player?.id ?? '',
150
+ );
149
151
 
150
- if (player && tournament) {
151
- tournament.handleJoinTournament(player);
152
+ if (!player || !tournament) {
153
+ throw new InternalServerErrorException();
154
+ }
152
155
 
153
- if (tournament.getRoomMaster<TournamentMaster>().isInProgress()) {
154
- if (player.isPlayer() || player.isTableQueuer()) {
155
- return JoinTournamentDto.fromEntities(
156
- AppScreenRouter.getManyTablesTournamentTablePath(
157
- player.tableId ?? '',
158
- ),
159
- player.id,
160
- );
161
- } else if (tournament.isParticipant(player.id)) {
162
- tournament
163
- .getRoomMaster<ManyTablesTournamentMaster>()
164
- .onTournamentProcessAlonePlayer(tournament.getRoomMaster(), player);
165
-
166
- return JoinTournamentDto.fromEntities(
167
- AppScreenRouter.getManyTablesTournamentTablePath(
168
- player.tableId ?? '',
169
- ),
170
- player.id,
171
- );
172
- } else {
173
- return JoinTournamentDto.fromEntities(
174
- AppScreenRouter.getManyTablesTournamentTableListPath(tournamentId),
175
- player.id,
176
- );
177
- }
156
+ if (tournament.getRoomMaster<TournamentMaster>().isInProgress()) {
157
+ if (tournament.isParticipant(player.id) && ticket?.amount) {
158
+ player.stack = ticket.amount;
159
+ tournament.handleJoinTournament(player);
160
+
161
+ return JoinTournamentDto.fromEntities(
162
+ AppScreenRouter.getManyTablesTournamentTablePath(
163
+ player.tableId ?? '',
164
+ ),
165
+ player.id,
166
+ );
178
167
  } else {
179
168
  return JoinTournamentDto.fromEntities(
180
- AppScreenRouter.getManyTablesTournamentStatusPath(tournament.getId()),
169
+ AppScreenRouter.getManyTablesTournamentTableListPath(tournamentId),
181
170
  player.id,
182
171
  );
183
172
  }
184
- }
173
+ } else if (tournament.getRoomMaster<TournamentMaster>().isWaiting()) {
174
+ tournament.handleJoinTournament(player);
185
175
 
186
- throw new InternalServerErrorException();
176
+ return JoinTournamentDto.fromEntities(
177
+ AppScreenRouter.getManyTablesTournamentStatusPath(tournament.getId()),
178
+ player.id,
179
+ );
180
+ } else {
181
+ return JoinTournamentDto.fromEntities(
182
+ AppScreenRouter.getManyTablesTournamentStatusPath(tournament.getId()),
183
+ player.id,
184
+ );
185
+ }
187
186
  }
188
187
 
189
- leaveTournament(tournamentId: string, clientAuthToken: string): void {
188
+ async leaveTournament(
189
+ tournamentId: string,
190
+ clientAuthToken: string,
191
+ ): Promise<void> {
190
192
  const player = this.playersManager.getPlayerById(clientAuthToken);
191
193
  const tournament =
192
194
  this.manyTablesRoomsManagerService.getRoomByTableId(tournamentId);
@@ -195,6 +197,20 @@ export class ManyTablesTournamentService {
195
197
  throw new InternalServerErrorException();
196
198
  }
197
199
 
200
+ if (tournament.isParticipant(player.id) && player.isPlayer()) {
201
+ const ticket =
202
+ await this.purchaseRepository.getManyTablesTournamentTicket(
203
+ tournament.getId(),
204
+ player.id,
205
+ );
206
+
207
+ if (ticket) {
208
+ await this.purchaseRepository.cancelManyTablesTournamentTicket(
209
+ ticket.purchaseId,
210
+ );
211
+ }
212
+ }
213
+
198
214
  tournament.handleLeaveTournament(player);
199
215
  }
200
216
 
@@ -35,4 +35,6 @@ export interface ManyTablesTournamentRoomsFactoryOptions {
35
35
  dailyTournamentTime: string;
36
36
  minPlayersForMergeTables: number;
37
37
  levelUpBonus: number;
38
+ purgeRoomsEnabled: boolean;
39
+ purgeRoomsTime: string;
38
40
  }
@@ -91,6 +91,9 @@ export class ManyTablesTournamentRoomsManagerModule {
91
91
  if (this.options.dailyTournamentScheduleJobEnabled) {
92
92
  await this.managerService.runDailyTournamentJob();
93
93
  }
94
+ if (this.options.purgeRoomsEnabled) {
95
+ this.managerService.runPurgeRoomsJob();
96
+ }
94
97
  await this.managerService.hydrateTournamentsFromDB();
95
98
  }
96
99
  }
@@ -18,6 +18,7 @@ import {
18
18
  GameTournamentFinishedEvent,
19
19
  GameTournamentPlayerJoinedTheTournamentEvent,
20
20
  GameTournamentPlayerLeavedTheTournamentEvent,
21
+ GameTournamentPlayerLostTournamentEvent,
21
22
  GameTournamentStartedEvent,
22
23
  GameTournamentWaitedEvent,
23
24
  LocalService,
@@ -55,6 +56,7 @@ import { ManyTablesTournamentRoomsFactoryOptions } from './many-tables-tournamen
55
56
  export class ManyTablesTournamentRoomsManagerService extends TournamentRoomsManagerService {
56
57
  private readonly rooms: Map<string, ManyTablesTournamentRoom>;
57
58
  private createDailyTournamentJob: Job | null;
59
+ private purgeRoomsJob: Job;
58
60
 
59
61
  constructor(
60
62
  private readonly tournamentRepository: ManyTablesTournamentRoomsRepository,
@@ -84,6 +86,10 @@ export class ManyTablesTournamentRoomsManagerService extends TournamentRoomsMana
84
86
  return this.rooms.get(roomId);
85
87
  }
86
88
 
89
+ removeRoom(roomId: string) {
90
+ this.rooms.delete(roomId);
91
+ }
92
+
87
93
  getRoomByTableId(tableId: string): ManyTablesTournamentRoom | undefined {
88
94
  const { roomId } = GameMaster.parseTableId(tableId);
89
95
 
@@ -131,6 +137,31 @@ export class ManyTablesTournamentRoomsManagerService extends TournamentRoomsMana
131
137
  }
132
138
  }
133
139
 
140
+ runPurgeRoomsJob() {
141
+ const purgeRoomsTime = this.options.purgeRoomsTime;
142
+
143
+ if (purgeRoomsTime) {
144
+ this.logger.log(
145
+ `${ManyTablesTournamentRoomsManagerService.name}: runPurgeRoomsJob`,
146
+ );
147
+
148
+ this.purgeRoomsJob = schedule.scheduleJob(purgeRoomsTime, () =>
149
+ this.purgeRooms(),
150
+ );
151
+ }
152
+ }
153
+
154
+ purgeRooms() {
155
+ for (const room of this.getRooms()) {
156
+ if (!room.isActual()) {
157
+ this.removeRoom(room.getId());
158
+ this.logger.log(
159
+ `${ManyTablesTournamentRoomsManagerService.name}: removeRoom: ${room.getId()}`,
160
+ );
161
+ }
162
+ }
163
+ }
164
+
134
165
  async createTournament(createTournamentDto: ManyTablesTournamentCreateDto) {
135
166
  const newTournament =
136
167
  await this.tournamentRepository.createTournament(createTournamentDto);
@@ -237,6 +268,7 @@ export class ManyTablesTournamentRoomsManagerService extends TournamentRoomsMana
237
268
  tournamentWinners: tournamentDocument.winners,
238
269
  maxParticipants: tournamentDocument.maxParticipants,
239
270
  participants: tournamentDocument.participants,
271
+ finishDate: tournamentDocument.finishDate,
240
272
  };
241
273
  }
242
274
 
@@ -284,7 +316,19 @@ export class ManyTablesTournamentRoomsManagerService extends TournamentRoomsMana
284
316
  this.handleRoomStatusUpdated(event as GameTournamentFinishedEvent);
285
317
  break;
286
318
  }
287
- case GamePlayerKickedOutTheTableEvent.name:
319
+ case GamePlayerKickedOutTheTableEvent.name: {
320
+ void this.handleGamePlayerKickedOutTheTable(
321
+ event as GamePlayerKickedOutTheTableEvent,
322
+ );
323
+ this.handleRoomStatusUpdated(event as GamePlayerKickedOutTheTableEvent);
324
+ break;
325
+ }
326
+ case GameTournamentPlayerLostTournamentEvent.name: {
327
+ void this.handleGameTournamentPlayerLostTournamentEvent(
328
+ event as GameTournamentPlayerLostTournamentEvent,
329
+ );
330
+ break;
331
+ }
288
332
  case GameTournamentPlayerJoinedTheTournamentEvent.name:
289
333
  case GameTournamentPlayerLeavedTheTournamentEvent.name:
290
334
  case GameTournamentWaitedEvent.name: {
@@ -292,8 +336,7 @@ export class ManyTablesTournamentRoomsManagerService extends TournamentRoomsMana
292
336
  event as
293
337
  | GameTournamentPlayerJoinedTheTournamentEvent
294
338
  | GameTournamentPlayerLeavedTheTournamentEvent
295
- | GameTournamentCancelledEvent
296
- | GamePlayerKickedOutTheTableEvent,
339
+ | GameTournamentCancelledEvent,
297
340
  );
298
341
  break;
299
342
  }
@@ -327,6 +370,41 @@ export class ManyTablesTournamentRoomsManagerService extends TournamentRoomsMana
327
370
  );
328
371
  };
329
372
 
373
+ private handleGamePlayerKickedOutTheTable = async (
374
+ event: GamePlayerKickedOutTheTableEvent,
375
+ ) => {
376
+ await this.cancelTicket(event);
377
+ };
378
+
379
+ private handleGameTournamentPlayerLostTournamentEvent = async (
380
+ event: GameTournamentPlayerLostTournamentEvent,
381
+ ) => {
382
+ await this.cancelTicket(event);
383
+ };
384
+
385
+ private async cancelTicket(
386
+ event:
387
+ | GamePlayerKickedOutTheTableEvent
388
+ | GameTournamentPlayerLostTournamentEvent,
389
+ ) {
390
+ const tournament = this.getRoomById(event.roomId);
391
+ if (tournament?.isParticipant(event.playerId)) {
392
+ const ticket =
393
+ await this.purchaseRepository.getManyTablesTournamentTicket(
394
+ event.roomId,
395
+ event.playerId,
396
+ );
397
+
398
+ if (ticket) {
399
+ await this.purchaseRepository.cancelManyTablesTournamentTicket(
400
+ ticket.purchaseId,
401
+ );
402
+ }
403
+
404
+ tournament.handleLeaveTournament(event.player);
405
+ }
406
+ }
407
+
330
408
  private handleRoomStatusUpdated = (
331
409
  event:
332
410
  | GameTournamentPlayerJoinedTheTournamentEvent
@@ -86,7 +86,7 @@ export class OneTableTournamentController {
86
86
  joinTournament(
87
87
  @Param('tournamentId') tournamentId: string,
88
88
  @Headers() headers: IAppHeaders,
89
- ): IBaseAppScreen {
89
+ ): Promise<IBaseAppScreen> {
90
90
  return this.tournamentService.joinTournament(tournamentId, headers);
91
91
  }
92
92
 
@@ -4,6 +4,9 @@ import {
4
4
  OneTableTournamentRoom,
5
5
  OneTableTournamentRoomSchema,
6
6
  OneTableTournamentRoomsRepository,
7
+ User,
8
+ UserSchema,
9
+ UsersRepository,
7
10
  } from 'jp.db.schemas';
8
11
  import {
9
12
  GamePlayer,
@@ -27,9 +30,14 @@ import { OneTableTournamentModuleOptions } from './one-table-tournament.interfac
27
30
  schema: OneTableTournamentRoomSchema,
28
31
  },
29
32
  ]),
33
+ MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
30
34
  ],
31
35
  controllers: [OneTableTournamentController],
32
- providers: [OneTableTournamentService, OneTableTournamentRoomsRepository],
36
+ providers: [
37
+ OneTableTournamentService,
38
+ OneTableTournamentRoomsRepository,
39
+ UsersRepository,
40
+ ],
33
41
  })
34
42
  export class OneTableTournamentModule {
35
43
  constructor(
@@ -8,11 +8,17 @@ import {
8
8
  IBaseAppScreen,
9
9
  IBaseMoveData,
10
10
  IAppTableState,
11
+ ErrorSnackbarComponent,
11
12
  } from 'jp.common.models';
13
+ import { UsersRepository } from 'jp.db.schemas';
12
14
 
13
15
  import { BaseAppScreenDto } from '../../dto';
14
16
  import { OneTableTournamentRoomsManagerService } from '../one-table-tournament-rooms-manager/one-table-tournament-rooms-manager.service';
15
17
  import { PlayersManagerService } from '../players-manager/players-manager.service';
18
+ import {
19
+ NotEnoughMoneyForPurchaseException,
20
+ ErrorCodeEnum,
21
+ } from '../../exception';
16
22
 
17
23
  import { OneTableTournamentFactoryOptions } from './one-table-tournament.interfaces';
18
24
  import { ONE_TABLE_TOURNAMENT_OPTIONS } from './one-table-tournament.constants';
@@ -23,6 +29,7 @@ export class OneTableTournamentService {
23
29
  constructor(
24
30
  private readonly oneTableRoomsManagerService: OneTableTournamentRoomsManagerService,
25
31
  private readonly playersManager: PlayersManagerService,
32
+ private readonly usersRepository: UsersRepository,
26
33
  @Inject(ONE_TABLE_TOURNAMENT_OPTIONS)
27
34
  private readonly options: OneTableTournamentFactoryOptions,
28
35
  ) {}
@@ -112,22 +119,37 @@ export class OneTableTournamentService {
112
119
  throw new InternalServerErrorException();
113
120
  }
114
121
 
115
- joinTournament(tournamentId: string, headers: IAppHeaders): IBaseAppScreen {
122
+ async joinTournament(
123
+ tournamentId: string,
124
+ headers: IAppHeaders,
125
+ ): Promise<IBaseAppScreen> {
116
126
  const player = this.playersManager.getPlayerById(headers.client_auth_token);
117
127
  const tournament =
118
128
  this.oneTableRoomsManagerService.getRoomByTableId(tournamentId);
129
+ const user = await this.usersRepository.findById(player?.id ?? '');
119
130
 
120
- if (player && tournament) {
121
- tournament.handleJoinTournament(player);
131
+ if (!player || !tournament || !user) {
132
+ throw new InternalServerErrorException();
133
+ }
122
134
 
123
- return this.getStatusScreen(
124
- tournamentId,
125
- headers.client_language,
126
- headers.client_auth_token,
135
+ if (user.balance < tournament.getTicketPrice()) {
136
+ throw new NotEnoughMoneyForPurchaseException(
137
+ new ErrorSnackbarComponent(
138
+ ErrorCodeEnum.NOT_ENOUGH_MONEY_FOR_PURCHASE,
139
+ this.options.i18n.t('common.server.message.code.4004', {
140
+ lang: headers.client_language,
141
+ }),
142
+ ),
127
143
  );
128
144
  }
129
145
 
130
- throw new InternalServerErrorException();
146
+ tournament.handleJoinTournament(player);
147
+
148
+ return this.getStatusScreen(
149
+ tournamentId,
150
+ headers.client_language,
151
+ headers.client_auth_token,
152
+ );
131
153
  }
132
154
 
133
155
  leaveTournament(tournamentId: string, clientAuthToken: string): void {
@@ -29,4 +29,6 @@ export interface OneTableTournamentRoomsFactoryOptions {
29
29
  instantFinishMode: boolean;
30
30
  tournamentPrizeTable: IPrizeTableData;
31
31
  levelUpBonus: number;
32
+ purgeRoomsEnabled: boolean;
33
+ purgeRoomsTime: string;
32
34
  }
@@ -1,4 +1,10 @@
1
- import { DynamicModule, Global, Module, Provider } from '@nestjs/common';
1
+ import {
2
+ DynamicModule,
3
+ Global,
4
+ Inject,
5
+ Module,
6
+ Provider,
7
+ } from '@nestjs/common';
2
8
  import { MongooseModule } from '@nestjs/mongoose';
3
9
  import {
4
10
  OneTableTournamentRoom,
@@ -16,10 +22,16 @@ import {
16
22
  ActivityLog,
17
23
  ActivityLogRepository,
18
24
  ActivityLogSchema,
25
+ Purchase,
26
+ PurchaseRepository,
27
+ PurchaseSchema,
19
28
  } from 'jp.db.schemas';
20
29
 
21
30
  import { OneTableTournamentRoomsManagerService } from './one-table-tournament-rooms-manager.service';
22
- import { OneTableTournamentRoomsManagerOptions } from './one-table-tournament-rooms-manager.interfaces';
31
+ import {
32
+ OneTableTournamentRoomsFactoryOptions,
33
+ OneTableTournamentRoomsManagerOptions,
34
+ } from './one-table-tournament-rooms-manager.interfaces';
23
35
  import { ONE_TABLE_TOURNAMENT_ROOMS_MANAGER_OPTIONS } from './one-table-tournament-rooms-manager.constants';
24
36
 
25
37
  @Global()
@@ -39,6 +51,9 @@ import { ONE_TABLE_TOURNAMENT_ROOMS_MANAGER_OPTIONS } from './one-table-tourname
39
51
  MongooseModule.forFeature([
40
52
  { name: ActivityLog.name, schema: ActivityLogSchema },
41
53
  ]),
54
+ MongooseModule.forFeature([
55
+ { name: Purchase.name, schema: PurchaseSchema },
56
+ ]),
42
57
  ],
43
58
  providers: [
44
59
  OneTableTournamentRoomsRepository,
@@ -47,12 +62,15 @@ import { ONE_TABLE_TOURNAMENT_ROOMS_MANAGER_OPTIONS } from './one-table-tourname
47
62
  GameResultRepository,
48
63
  RatingRepository,
49
64
  ActivityLogRepository,
65
+ PurchaseRepository,
50
66
  ],
51
67
  exports: [OneTableTournamentRoomsManagerService],
52
68
  })
53
69
  export class OneTableTournamentRoomsManagerModule {
54
70
  constructor(
55
71
  private readonly managerService: OneTableTournamentRoomsManagerService,
72
+ @Inject(ONE_TABLE_TOURNAMENT_ROOMS_MANAGER_OPTIONS)
73
+ private readonly options: OneTableTournamentRoomsFactoryOptions,
56
74
  ) {}
57
75
 
58
76
  static forRootAsync(
@@ -74,5 +92,9 @@ export class OneTableTournamentRoomsManagerModule {
74
92
  async onModuleInit() {
75
93
  await this.managerService.createMasterTournament();
76
94
  await this.managerService.hydrateTournamentsFromDB();
95
+
96
+ if (this.options.purgeRoomsEnabled) {
97
+ this.managerService.runPurgeRoomsJob();
98
+ }
77
99
  }
78
100
  }