Skip to content

Commit 8360519

Browse files
committed
Lobby support
1 parent bc20dd8 commit 8360519

10 files changed

+162
-32
lines changed

src/core.controller.ts

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { StartFakeMatchEvent } from 'gateway/events/start-fake-match.event';
1717
import { ServerStatusEvent } from 'gateway/events/gs/server-status.event';
1818
import { MatchFailedEvent } from 'gateway/events/match-failed.event';
1919
import { PlayerAbandonedEvent } from 'gateway/events/bans/player-abandoned.event';
20+
import { LobbyReadyEvent } from 'gateway/events/lobby-ready.event';
2021

2122

2223
@Controller()
@@ -29,11 +30,16 @@ export class CoreController {
2930
buff.__proto__ = constructor.prototype;
3031
if (!isDev) this.ebus.publish(buff);
3132
}
33+
3234
@EventPattern(RoomReadyEvent.name)
3335
async RoomReadyEvent(data: RoomReadyEvent) {
3436
this.event(RoomReadyEvent, data);
3537
}
3638

39+
@EventPattern(LobbyReadyEvent.name)
40+
async LobbyReadyEvent(data: LobbyReadyEvent) {
41+
this.event(LobbyReadyEvent, data);
42+
}
3743

3844
@EventPattern(TournamentGameReadyEvent.name)
3945
async TournamentGameReadyEvent(data: TournamentGameReadyEvent) {
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { MatchInfo } from 'gateway/events/room-ready.event';
1+
import { GamePreparedEvent } from 'gameserver/event/game-prepared.event';
22

33
export class FindGameServerCommand {
44
constructor(
5-
public readonly matchInfo: MatchInfo,
5+
public readonly info: GamePreparedEvent,
66
public readonly tries: number
77
) {}
88
}

src/gameserver/command/FindGameServer/find-game-server.handler.ts

+20-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { MatchmakingMode } from 'gateway/shared-types/matchmaking-mode';
3131
import { Dota_GameMode } from 'gateway/shared-types/dota-game-mode';
3232
import { MatchmakingModeMappingEntity } from 'gameserver/model/matchmaking-mode-mapping.entity';
3333
import { Dota_Map } from 'gateway/shared-types/dota-map';
34+
import { GamePreparedEvent } from 'gameserver/event/game-prepared.event';
3435

3536
@CommandHandler(FindGameServerCommand)
3637
export class FindGameServerHandler
@@ -96,7 +97,9 @@ export class FindGameServerHandler
9697
return mapping.dotaGameMode;
9798
}
9899

99-
private async extendMatchInfo(matchInfo: MatchInfo): Promise<GSMatchInfo> {
100+
private async extendMatchInfo(
101+
matchInfo: GamePreparedEvent,
102+
): Promise<GSMatchInfo> {
100103
const players: FullMatchPlayer[] = [];
101104

102105
// TODO: i dont like it and want to move username resolving into operator
@@ -119,22 +122,22 @@ export class FindGameServerHandler
119122
matchInfo.roomId,
120123
players,
121124
matchInfo.version,
122-
matchInfo.averageMMR,
125+
0,
123126
);
124127
}
125128

126129
private async findServer(command: FindGameServerCommand) {
127130
const freeServerPool = await this.gsSessionRepository.getAllFree(
128-
command.matchInfo.version,
131+
command.info.version,
129132
);
130133

131-
const gsInfo = await this.extendMatchInfo(command.matchInfo);
134+
const gsInfo = await this.extendMatchInfo(command.info);
132135

133136
console.log("FindServer called, pool", freeServerPool);
134137

135138
const m = new MatchEntity();
136139
m.server = MatchEntity.NOT_DECIDED_SERVER;
137-
m.mode = command.matchInfo.mode;
140+
m.mode = command.info.mode;
138141
m.started = false;
139142
m.finished = false;
140143
m.matchInfoJson = {
@@ -190,7 +193,18 @@ export class FindGameServerHandler
190193
await this.matchEntityRepository.save(m);
191194
} else {
192195
// cancel match : no servers free :sadkek:
193-
this.ebus.publish(new MatchCancelledEvent(m.id, command.matchInfo));
196+
this.ebus.publish(
197+
new MatchCancelledEvent(
198+
m.id,
199+
new MatchInfo(
200+
command.info.mode,
201+
command.info.roomId,
202+
command.info.players,
203+
0,
204+
command.info.version,
205+
),
206+
),
207+
);
194208
return;
195209
}
196210
// ok here we launch server
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { MatchmakingMode } from 'gateway/shared-types/matchmaking-mode';
2+
import { Dota2Version } from 'gateway/shared-types/dota2version';
3+
import { MatchPlayer } from 'gateway/events/room-ready.event';
4+
5+
export class PrepareGameCommand {
6+
constructor(
7+
public readonly lobbyType: MatchmakingMode,
8+
public readonly roomId: string,
9+
public readonly players: MatchPlayer[],
10+
public readonly version: Dota2Version,
11+
) {}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { CommandHandler, EventBus, ICommandHandler, QueryBus } from '@nestjs/cqrs';
2+
import { Logger } from '@nestjs/common';
3+
import { PrepareGameCommand } from 'gameserver/command/PrepareGame/prepare-game.command';
4+
import { GamePreparedEvent } from 'gameserver/event/game-prepared.event';
5+
import { MatchmakingMode } from 'gateway/shared-types/matchmaking-mode';
6+
import { Dota_Map } from 'gateway/shared-types/dota-map';
7+
import { Dota_GameMode } from 'gateway/shared-types/dota-game-mode';
8+
import { MatchmakingModeMappingEntity } from 'gameserver/model/matchmaking-mode-mapping.entity';
9+
import { InjectRepository } from '@nestjs/typeorm';
10+
import { Repository } from 'typeorm';
11+
import { Dota2Version } from 'gateway/shared-types/dota2version';
12+
13+
@CommandHandler(PrepareGameCommand)
14+
export class PrepareGameHandler implements ICommandHandler<PrepareGameCommand> {
15+
private readonly logger = new Logger(PrepareGameHandler.name);
16+
17+
constructor(
18+
private readonly ebus: EventBus,
19+
private readonly qbus: QueryBus,
20+
@InjectRepository(MatchmakingModeMappingEntity)
21+
private readonly matchmakingModeMappingEntityRepository: Repository<MatchmakingModeMappingEntity>,
22+
) {}
23+
24+
async execute(command: PrepareGameCommand) {
25+
const mapping = await this.getMappingForLobbyType(command.lobbyType);
26+
27+
this.ebus.publish(
28+
new GamePreparedEvent(
29+
command.lobbyType,
30+
mapping?.dotaGameMode || Dota_GameMode.ALLPICK,
31+
mapping?.dotaMap || Dota_Map.DOTA,
32+
Dota2Version.Dota_684,
33+
command.roomId,
34+
command.players,
35+
),
36+
);
37+
}
38+
39+
private async getMappingForLobbyType(
40+
lobby: MatchmakingMode,
41+
): Promise<MatchmakingModeMappingEntity | undefined> {
42+
return await this.matchmakingModeMappingEntityRepository.findOne({
43+
where: {
44+
lobbyType: lobby,
45+
},
46+
});
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { EventBus, EventsHandler, IEventHandler } from '@nestjs/cqrs';
2+
import { LobbyReadyEvent } from 'gateway/events/lobby-ready.event';
3+
import { GamePreparedEvent } from 'gameserver/event/game-prepared.event';
4+
5+
@EventsHandler(LobbyReadyEvent)
6+
export class LobbyReadyHandler implements IEventHandler<LobbyReadyEvent> {
7+
constructor(private readonly ebus: EventBus) {}
8+
9+
async handle(event: LobbyReadyEvent) {
10+
this.ebus.publish(
11+
new GamePreparedEvent(
12+
event.mode,
13+
event.gameMode,
14+
event.map,
15+
event.version,
16+
event.roomId,
17+
event.players,
18+
),
19+
);
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { MatchmakingMode } from 'gateway/shared-types/matchmaking-mode';
2+
import { Dota2Version } from 'gateway/shared-types/dota2version';
3+
import { Dota_GameMode } from 'gateway/shared-types/dota-game-mode';
4+
import { Dota_Map } from 'gateway/shared-types/dota-map';
5+
import { MatchPlayer } from 'gateway/events/room-ready.event';
6+
7+
export class GamePreparedEvent {
8+
constructor(
9+
public readonly mode: MatchmakingMode,
10+
public readonly gameMode: Dota_GameMode,
11+
public readonly map: Dota_Map,
12+
public readonly version: Dota2Version,
13+
public readonly roomId: string,
14+
public readonly players: MatchPlayer[],
15+
) {}
16+
}

src/gameserver/index.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ import { ProcessAchievementsHandler } from 'gameserver/command/ProcessAchievemen
3030
import { AchievementService } from 'gameserver/achievement.service';
3131
import { MatchFailedHandler } from 'gameserver/event-handler/match-failed.handler';
3232
import { PlayerAbandonedHandler } from 'gameserver/event-handler/player-abandoned.handler';
33+
import { PrepareGameHandler } from 'gameserver/command/PrepareGame/prepare-game.handler';
34+
import { LobbyReadyHandler } from 'gameserver/event-handler/lobby-ready.handler';
3335

3436
const CommandHandlers = [
3537
FindGameServerHandler,
3638
ProcessRankedMatchHandler,
3739
MakeSureExistsHandler,
38-
ProcessAchievementsHandler
40+
ProcessAchievementsHandler,
41+
PrepareGameHandler
3942
];
4043
const EventHandlers = [
4144
StartFakeMatchHandler,
@@ -52,6 +55,7 @@ const EventHandlers = [
5255

5356
GameResultsHandler,
5457
PlayerBanHammeredHandler,
58+
LobbyReadyHandler,
5559

5660
ServerStatusHandler,
5761
PlayerNotLoadedHandler,

src/gameserver/saga/gameserver.saga.ts

+31-22
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,41 @@ import { Injectable } from '@nestjs/common';
22
import { ICommand, ofType, Saga } from '@nestjs/cqrs';
33
import { Observable } from 'rxjs';
44
import { filter, map } from 'rxjs/operators';
5-
import { FindGameServerCommand } from 'gameserver/command/FindGameServer/find-game-server.command';
6-
import { MatchInfo, RoomReadyEvent } from 'gateway/events/room-ready.event';
5+
import { RoomReadyEvent } from 'gateway/events/room-ready.event';
76
import { MatchmakingMode } from 'gateway/shared-types/matchmaking-mode';
87
import { ProcessRankedMatchCommand } from 'gameserver/command/ProcessRankedMatch/process-ranked-match.command';
98
import { PlayerId } from 'gateway/shared-types/player-id';
109
import * as uuidr from 'uuid';
1110
import { ProcessAchievementsCommand } from 'gameserver/command/ProcessAchievements/process-achievements.command';
1211
import { MatchRecordedEvent } from 'gameserver/event/match-recorded.event';
12+
import { PrepareGameCommand } from 'gameserver/command/PrepareGame/prepare-game.command';
13+
import { GamePreparedEvent } from 'gameserver/event/game-prepared.event';
14+
import { FindGameServerCommand } from 'gameserver/command/FindGameServer/find-game-server.command';
1315

1416
export const uuid = (): string => uuidr.v4();
1517

16-
1718
@Injectable()
1819
export class GameserverSaga {
1920
@Saga()
20-
listenReactions = (events$: Observable<any>): Observable<ICommand> => {
21+
prepareRoomGame = (events$: Observable<any>): Observable<ICommand> => {
2122
return events$.pipe(
2223
ofType(RoomReadyEvent),
2324
map(
24-
e =>
25-
new FindGameServerCommand(
26-
new MatchInfo(
27-
e.mode,
28-
e.roomId,
29-
e.players,
30-
0,
31-
e.version,
32-
),
33-
0,
34-
),
25+
(e: RoomReadyEvent) =>
26+
new PrepareGameCommand(e.mode, e.roomId, e.players, e.version),
3527
),
3628
);
3729
};
3830

31+
@Saga()
32+
findServer = (events$: Observable<any>): Observable<ICommand> => {
33+
return events$.pipe(
34+
ofType(GamePreparedEvent),
35+
map((e: GamePreparedEvent) => new FindGameServerCommand(e, 0)),
36+
);
37+
};
38+
39+
// GamePreparedEvent
3940

4041
// @Saga()
4142
// tournamentGameReady = (events$: Observable<any>): Observable<ICommand> => {
@@ -76,17 +77,25 @@ export class GameserverSaga {
7677
processRanked = (events$: Observable<any>): Observable<ICommand> => {
7778
return events$.pipe(
7879
ofType(MatchRecordedEvent),
79-
filter((t: MatchRecordedEvent) => t.type === MatchmakingMode.RANKED || t.type === MatchmakingMode.UNRANKED),
80+
filter(
81+
(t: MatchRecordedEvent) =>
82+
t.type === MatchmakingMode.RANKED ||
83+
t.type === MatchmakingMode.UNRANKED,
84+
),
8085
map((e: MatchRecordedEvent) => {
81-
8286
const losers = e.players
83-
.filter(p => p.team !== e.winner)
84-
.map(t => new PlayerId(t.steam_id));
87+
.filter((p) => p.team !== e.winner)
88+
.map((t) => new PlayerId(t.steam_id));
8589
const winners = e.players
86-
.filter(p => p.team === e.winner)
87-
.map(t => new PlayerId(t.steam_id));
90+
.filter((p) => p.team === e.winner)
91+
.map((t) => new PlayerId(t.steam_id));
8892

89-
return new ProcessRankedMatchCommand(e.matchId, winners, losers, e.type);
93+
return new ProcessRankedMatchCommand(
94+
e.matchId,
95+
winners,
96+
losers,
97+
e.type,
98+
);
9099
}),
91100
);
92101
};

src/gateway

0 commit comments

Comments
 (0)