mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 15:48:23 -05:00
Fix server restarting mid-set changing map list
This commit is contained in:
@@ -44,7 +44,7 @@ const ROUND_MAPS = {
|
||||
} satisfies RoundMaps;
|
||||
|
||||
/** The maps every round of a factory-started bracket is played on. */
|
||||
type RoundMaps = Omit<Engine.RoundMapsInput, "roundId">;
|
||||
export type RoundMaps = Omit<Engine.RoundMapsInput, "roundId">;
|
||||
|
||||
/** The wrapping calendar event is not the caller's to choose, so it is not an argument. */
|
||||
type InsertArgs = Omit<
|
||||
|
||||
@@ -123,6 +123,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
match.mapPickingStyle !== "TO"
|
||||
? await TournamentTeamRepository.findRecentlyPlayedMapsByIds({
|
||||
teamIds: [opponentOne.id, opponentTwo.id],
|
||||
excludeMatchId: id,
|
||||
}).catch((error) => {
|
||||
logger.error("Failed to fetch recently played maps", error);
|
||||
return [];
|
||||
|
||||
@@ -117,6 +117,7 @@ export async function resolveMatchMapList({
|
||||
match.mapPickingStyle !== "TO"
|
||||
? await TournamentTeamRepository.findRecentlyPlayedMapsByIds({
|
||||
teamIds: teams,
|
||||
excludeMatchId: match.id,
|
||||
}).catch((error) => {
|
||||
logger.error("Failed to fetch recently played maps", error);
|
||||
return [];
|
||||
|
||||
@@ -143,6 +143,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
match.mapPickingStyle !== "TO"
|
||||
? await TournamentTeamRepository.findRecentlyPlayedMapsByIds({
|
||||
teamIds: [match.opponentOne.id, match.opponentTwo.id],
|
||||
excludeMatchId: matchId,
|
||||
}).catch((error) => {
|
||||
logger.error("Failed to fetch recently played maps", error);
|
||||
return [];
|
||||
|
||||
@@ -3,9 +3,40 @@ import * as TournamentFactory from "~/db/seed/factories/TournamentFactory";
|
||||
import * as TournamentTeamFactory from "~/db/seed/factories/TournamentTeamFactory";
|
||||
import * as UserFactory from "~/db/seed/factories/UserFactory";
|
||||
import { db } from "~/db/sql";
|
||||
import type { TournamentSettings } from "~/db/tables-json";
|
||||
import { withUserId } from "~/utils/Test";
|
||||
import * as TournamentTeamRepository from "./TournamentTeamRepository.server";
|
||||
|
||||
const TEAM_COUNT = 4;
|
||||
|
||||
/** Pools of two teams each, followed by a final between the two pool winners. */
|
||||
const POOLS_TO_FINAL: TournamentSettings["bracketProgression"] = [
|
||||
{
|
||||
name: "Pools",
|
||||
type: "round_robin",
|
||||
requiresCheckIn: false,
|
||||
settings: { teamsPerGroup: 2 },
|
||||
},
|
||||
{
|
||||
name: "Final",
|
||||
type: "single_elimination",
|
||||
requiresCheckIn: false,
|
||||
settings: { thirdPlaceMatch: false },
|
||||
sources: [{ bracketIdx: 0, placements: [1] }],
|
||||
},
|
||||
];
|
||||
|
||||
const POOL_MAPS: TournamentFactory.RoundMaps = {
|
||||
count: 1,
|
||||
type: "BEST_OF",
|
||||
list: [{ mode: "SZ", stageId: 1 }],
|
||||
};
|
||||
const FINAL_MAPS: TournamentFactory.RoundMaps = {
|
||||
count: 1,
|
||||
type: "BEST_OF",
|
||||
list: [{ mode: "TC", stageId: 2 }],
|
||||
};
|
||||
|
||||
let organizer: { id: number };
|
||||
let owner: { id: number };
|
||||
let member: { id: number };
|
||||
@@ -285,4 +316,39 @@ describe("TournamentTeamRepository", () => {
|
||||
).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findRecentlyPlayedMapsByIds", () => {
|
||||
test("leaves out the games of the match the maps are resolved for", async () => {
|
||||
// the map list of an in-progress set is regenerated whenever its cache entry
|
||||
// is lost, so counting the set's own games as recently played would change
|
||||
// the maps the teams have left to play under them
|
||||
const players = await UserFactory.createMany(TEAM_COUNT);
|
||||
const tournament = await TournamentFactory.createPlayed(
|
||||
{
|
||||
authorId: organizer.id,
|
||||
bracketProgression: POOLS_TO_FINAL,
|
||||
minMembersPerTeam: 1,
|
||||
},
|
||||
{
|
||||
teamRosters: players.map((player) => [player.id]),
|
||||
playedOut: 0,
|
||||
maps: POOL_MAPS,
|
||||
},
|
||||
);
|
||||
const [final] = await TournamentFactory.playOut(tournament.id, 1, {
|
||||
maps: FINAL_MAPS,
|
||||
});
|
||||
|
||||
const recentMaps =
|
||||
await TournamentTeamRepository.findRecentlyPlayedMapsByIds({
|
||||
teamIds: [final.winnerTeamId, final.loserTeamId],
|
||||
excludeMatchId: final.id,
|
||||
});
|
||||
|
||||
expect(recentMaps).toEqual([
|
||||
{ mode: "SZ", stageId: 1 },
|
||||
{ mode: "SZ", stageId: 1 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -999,7 +999,11 @@ async function replaceCounterpickMaps(
|
||||
.execute();
|
||||
}
|
||||
|
||||
async function findTeamRecentMaps(teamId: number, limit: number) {
|
||||
async function findTeamRecentMaps(
|
||||
teamId: number,
|
||||
excludeMatchId: number,
|
||||
limit: number,
|
||||
) {
|
||||
return db
|
||||
.selectFrom("TournamentMatchGameResult")
|
||||
.innerJoin(
|
||||
@@ -1012,6 +1016,7 @@ async function findTeamRecentMaps(teamId: number, limit: number) {
|
||||
"TournamentMatchGameResult.stageId",
|
||||
])
|
||||
.where("TournamentMatchGameResultParticipant.tournamentTeamId", "=", teamId)
|
||||
.where("TournamentMatchGameResult.matchId", "!=", excludeMatchId)
|
||||
.orderBy("TournamentMatchGameResult.createdAt", "desc")
|
||||
.limit(limit)
|
||||
.execute();
|
||||
@@ -1058,10 +1063,15 @@ export async function findMapPoolsByTeamIds(tournamentTeamIds: number[]) {
|
||||
|
||||
export async function findRecentlyPlayedMapsByIds({
|
||||
teamIds,
|
||||
excludeMatchId,
|
||||
limit = 5,
|
||||
}: {
|
||||
/** Team IDs to retrieve recent maps for */
|
||||
teamIds: [number, number];
|
||||
/** Match whose own games are left out, being the match the maps are resolved for.
|
||||
* Without it a set's map list changes under the teams mid-set, as the games they
|
||||
* already played would count as recently played when it is regenerated. */
|
||||
excludeMatchId: number;
|
||||
/** Limit of recent maps to retrieve per team
|
||||
*
|
||||
* @default 5
|
||||
@@ -1069,8 +1079,8 @@ export async function findRecentlyPlayedMapsByIds({
|
||||
limit?: number;
|
||||
}): Promise<Array<{ mode: ModeShort; stageId: StageId }>> {
|
||||
const [teamOneMaps, teamTwoMaps] = await Promise.all([
|
||||
findTeamRecentMaps(teamIds[0], limit),
|
||||
findTeamRecentMaps(teamIds[1], limit),
|
||||
findTeamRecentMaps(teamIds[0], excludeMatchId, limit),
|
||||
findTeamRecentMaps(teamIds[1], excludeMatchId, limit),
|
||||
]);
|
||||
|
||||
return flatZip(teamOneMaps, teamTwoMaps);
|
||||
|
||||
Reference in New Issue
Block a user