Skip to content

Commit

Permalink
fix(games): don't apply cooldown if the player takes back his spot (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
garrappachc authored Feb 16, 2023
1 parent ad9acc0 commit 8803789
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 6 deletions.
48 changes: 43 additions & 5 deletions e2e/player-does-not-join-and-gets-substituted.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ describe('Player does not join the gameserver and gets substituted (e2e)', () =>
let playersService: PlayersService;
let gameId: GameId;
let events: Events;
let playerSocket: Socket;
let leaverPlayerSocket: Socket;
let leaverBans: any[];
let replacementPlayerSocket: Socket;
let substituteRequests: any[];

beforeAll(async () => {
Expand All @@ -37,25 +39,44 @@ describe('Player does not join the gameserver and gets substituted (e2e)', () =>

const authService = app.get(AuthService);

const playerToken = await authService.generateJwtToken(
const leaverPlayerToken = await authService.generateJwtToken(
JwtTokenPurpose.websocket,
(
await playersService.findBySteamId(players[1])
).id,
);

playerSocket = io(
leaverPlayerSocket = io(
`http://localhost:${app.getHttpServer().address().port}`,
{
auth: { token: `Bearer ${playerToken}` },
auth: { token: `Bearer ${leaverPlayerToken}` },
},
);

const replacementPlayerToken = await authService.generateJwtToken(
JwtTokenPurpose.websocket,
(
await playersService.findBySteamId(players[12])
).id,
);

replacementPlayerSocket = io(
`http://localhost:${app.getHttpServer().address().port}`,
{
auth: { token: `Bearer ${replacementPlayerToken}` },
},
);

substituteRequests = [];
playerSocket.on(
leaverBans = [];
leaverPlayerSocket.on(
'substitute requests update',
(requests) => (substituteRequests = requests),
);
leaverPlayerSocket.on(
'profile update',
(profile) => (leaverBans = profile.bans ?? []),
);
});

beforeAll(async () => {
Expand Down Expand Up @@ -192,6 +213,7 @@ describe('Player does not join the gameserver and gets substituted (e2e)', () =>
});

it("should substitute a player that doesn't join the gameserver on time", async () => {
const leaver = await playersService.findBySteamId(players[1]);
expect(substituteRequests.length).toEqual(0);
await waitABit(70 * 1000);
expect(substituteRequests.length).toEqual(1);
Expand All @@ -201,5 +223,21 @@ describe('Player does not join the gameserver and gets substituted (e2e)', () =>
gameClass: Tf2ClassName.scout,
team: expect.any(String),
});
// the player should not be given a cooldown for now
expect(leaverBans.length).toBe(0);

await waitABit(1000);

// a replacement player takes the substitute spot
replacementPlayerSocket.emit('replace player', {
gameId: gameId.toString(),
replaceeId: leaver.id,
});

await waitABit(1000);

// the leaver should be given a cooldown
expect(leaverBans.length).toBe(1);
expect(leaverBans[0].reason).toEqual('Cooldown level 0');
});
});
27 changes: 26 additions & 1 deletion src/game-coordinator/services/player-behavior-handler.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Events } from '@/events/events';
import { GamesService } from '@/games/services/games.service';
import { PlayerSubstitutionService } from '@/games/services/player-substitution.service';
import { PlayerCooldownService } from '@/players/services/player-cooldown.service';
import { PlayersService } from '@/players/services/players.service';
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { isUndefined } from 'lodash';
import { filter, take, takeUntil } from 'rxjs';

@Injectable()
export class PlayerBehaviorHandlerService {
Expand All @@ -15,6 +17,7 @@ export class PlayerBehaviorHandlerService {
private readonly playerSubstitutionService: PlayerSubstitutionService,
private readonly playersService: PlayersService,
private readonly playerCooldownService: PlayerCooldownService,
private readonly events: Events,
) {}

@Cron(CronExpression.EVERY_10_SECONDS)
Expand Down Expand Up @@ -48,7 +51,29 @@ export class PlayerBehaviorHandlerService {
player._id,
bot._id,
);
await this.playerCooldownService.applyCooldown(player._id);

const gameEnds = this.events.gameChanges.pipe(
filter(({ newGame }) => newGame._id.equals(game._id)),
filter(
({ oldGame, newGame }) =>
oldGame.isInProgress() && !newGame.isInProgress(),
),
);

// Apply cooldown to the player if they get replaced by someone else.
// They still can take their own spot and not receive a ban.
this.events.playerReplaced
.pipe(
takeUntil(gameEnds),
filter(({ gameId }) => gameId.equals(game._id)),
filter(({ replaceeId }) => replaceeId.equals(player._id)),
take(1),
)
.subscribe(async ({ replaceeId, replacementId }) => {
if (!replaceeId.equals(replacementId)) {
await this.playerCooldownService.applyCooldown(player._id);
}
});
}
}
}
Expand Down

0 comments on commit 8803789

Please sign in to comment.