new badges

This commit is contained in:
yohlo
2026-03-01 17:04:06 -06:00
parent 9a64f316b9
commit 5d6136a445

View File

@@ -160,6 +160,97 @@ export function createBadgesService(pb: PocketBase) {
return bigWins.length > 0 ? 1 : 0; return bigWins.length > 0 ? 1 : 0;
} }
if (criteria.unique_partners !== undefined) {
const matches = await pb.collection("matches").getFullList({
filter: `(home.players.id ?~ "${playerId}" || away.players.id ?~ "${playerId}") && status = "ended"`,
expand: 'home,away,home.players,away.players',
});
const partners = new Set<string>();
for (const match of matches) {
const isHome = match.expand?.home?.expand?.players?.some((p: any) => p.id === playerId) ||
match.expand?.home?.players?.includes(playerId);
const isAway = match.expand?.away?.expand?.players?.some((p: any) => p.id === playerId) ||
match.expand?.away?.players?.includes(playerId);
let teamPlayers: any[] = [];
if (isHome) {
teamPlayers = match.expand?.home?.expand?.players || match.expand?.home?.players || [];
} else if (isAway) {
teamPlayers = match.expand?.away?.expand?.players || match.expand?.away?.players || [];
}
for (const player of teamPlayers) {
const partnerId = typeof player === 'string' ? player : player.id;
if (partnerId !== playerId) {
partners.add(partnerId);
}
}
}
return partners.size;
}
if (criteria.beat_mainline_partner !== undefined) {
const mainlineMatches = await pb.collection("matches").getFullList({
filter: `(home.players.id ?~ "${playerId}" || away.players.id ?~ "${playerId}") && status = "ended" && (tournament.regional = false || tournament.regional = null)`,
expand: 'home,away,home.players,away.players',
});
const mainlinePartners = new Set<string>();
for (const match of mainlineMatches) {
const isHome = match.expand?.home?.expand?.players?.some((p: any) => p.id === playerId) ||
match.expand?.home?.players?.includes(playerId);
const isAway = match.expand?.away?.expand?.players?.some((p: any) => p.id === playerId) ||
match.expand?.away?.players?.includes(playerId);
let teamPlayers: any[] = [];
if (isHome) {
teamPlayers = match.expand?.home?.expand?.players || match.expand?.home?.players || [];
} else if (isAway) {
teamPlayers = match.expand?.away?.expand?.players || match.expand?.away?.players || [];
}
for (const player of teamPlayers) {
const partnerId = typeof player === 'string' ? player : player.id;
if (partnerId !== playerId) {
mainlinePartners.add(partnerId);
}
}
}
const regionalMatches = await pb.collection("matches").getFullList({
filter: `(home.players.id ?~ "${playerId}" || away.players.id ?~ "${playerId}") && status = "ended" && tournament.regional = true`,
expand: 'home,away,home.players,away.players',
});
for (const match of regionalMatches) {
const isHome = match.expand?.home?.expand?.players?.some((p: any) => p.id === playerId) ||
match.expand?.home?.players?.includes(playerId);
const isAway = match.expand?.away?.expand?.players?.some((p: any) => p.id === playerId) ||
match.expand?.away?.players?.includes(playerId);
const didWin = (isHome && match.home_cups > match.away_cups) ||
(isAway && match.away_cups > match.home_cups);
if (!didWin) continue;
const opponentPlayers: any[] = isHome
? (match.expand?.away?.expand?.players || match.expand?.away?.players || [])
: (match.expand?.home?.expand?.players || match.expand?.home?.players || []);
for (const opponent of opponentPlayers) {
const opponentId = typeof opponent === 'string' ? opponent : opponent.id;
if (mainlinePartners.has(opponentId)) {
return 1;
}
}
}
return 0;
}
return 0; return 0;
}, },
@@ -314,18 +405,34 @@ export function createBadgesService(pb: PocketBase) {
} }
if (criteria.tournament_record !== undefined) { if (criteria.tournament_record !== undefined) {
const includeRegional = criteria.tournament_record === "0-3";
const tournamentFilter = includeRegional
? ''
: 'regional = false || regional = null';
const tournaments = await pb.collection("tournaments").getFullList({ const tournaments = await pb.collection("tournaments").getFullList({
filter: 'regional = false || regional = null', filter: tournamentFilter,
sort: 'start_time', sort: 'start_time',
}); });
let timesWent02 = 0; const allMatches = includeRegional
? await pb.collection("matches").getFullList({
filter: `(home.players.id ?~ "${playerId}" || away.players.id ?~ "${playerId}") && status = "ended"`,
expand: 'tournament,home,away,home.players,away.players',
})
: matches;
for (const tournamentId of tournamentIds) { const relevantTournamentIds = includeRegional
? new Set(allMatches.map(m => m.tournament))
: tournamentIds;
let timesMetRecord = 0;
for (const tournamentId of relevantTournamentIds) {
const tournament = tournaments.find(t => t.id === tournamentId); const tournament = tournaments.find(t => t.id === tournamentId);
if (!tournament) continue; if (!tournament) continue;
const tournamentMatches = matches.filter(m => m.tournament === tournamentId); const tournamentMatches = allMatches.filter(m => m.tournament === tournamentId);
let wins = 0; let wins = 0;
let losses = 0; let losses = 0;
@@ -353,16 +460,16 @@ export function createBadgesService(pb: PocketBase) {
if (currentIndex > 0) { if (currentIndex > 0) {
const previousTournament = tournaments[currentIndex - 1]; const previousTournament = tournaments[currentIndex - 1];
if (previousTournament.winner_id === playerId) { if (previousTournament.winner_id === playerId) {
timesWent02++; timesMetRecord++;
} }
} }
} else { } else {
timesWent02++; timesMetRecord++;
} }
} }
} }
return timesWent02 > 0 ? 1 : 0; return timesMetRecord > 0 ? 1 : 0;
} }
if (criteria.consecutive_wins !== undefined) { if (criteria.consecutive_wins !== undefined) {
@@ -380,26 +487,34 @@ export function createBadgesService(pb: PocketBase) {
expand: 'home,away,home.players,away.players', expand: 'home,away,home.players,away.players',
}); });
if (tournamentMatches.length === 0) {
continue;
}
const winnersMatches = tournamentMatches.filter(m => !m.is_losers_bracket); const winnersMatches = tournamentMatches.filter(m => !m.is_losers_bracket);
if (winnersMatches.length === 0) {
continue;
}
const finalsMatch = winnersMatches.reduce((highest: any, current: any) => const finalsMatch = winnersMatches.reduce((highest: any, current: any) =>
(!highest || current.lid > highest.lid) ? current : highest, null); (!highest || current.lid > highest.lid) ? current : highest, null);
if (finalsMatch && finalsMatch.status === 'ended') { if (!finalsMatch || finalsMatch.status !== 'ended') {
const finalsWinnerId = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.home : finalsMatch.away; continue;
}
const winningTeam = finalsMatch.expand?.[finalsWinnerId === finalsMatch.home ? 'home' : 'away']; const finalsWinnerId = (finalsMatch.home_cups > finalsMatch.away_cups) ? finalsMatch.home : finalsMatch.away;
const winningPlayers = winningTeam?.expand?.players || winningTeam?.players || [];
const playerWon = winningPlayers.some((p: any) => const winningTeam = finalsMatch.expand?.[finalsWinnerId === finalsMatch.home ? 'home' : 'away'];
(typeof p === 'string' ? p : p.id) === playerId const winningPlayers = winningTeam?.expand?.players || winningTeam?.players || [];
);
if (playerWon) { const playerWon = winningPlayers.some((p: any) =>
consecutiveWins++; (typeof p === 'string' ? p : p.id) === playerId
maxConsecutiveWins = Math.max(maxConsecutiveWins, consecutiveWins); );
} else {
consecutiveWins = 0; if (playerWon) {
} consecutiveWins++;
maxConsecutiveWins = Math.max(maxConsecutiveWins, consecutiveWins);
} else { } else {
consecutiveWins = 0; consecutiveWins = 0;
} }
@@ -408,6 +523,64 @@ export function createBadgesService(pb: PocketBase) {
return maxConsecutiveWins >= criteria.consecutive_wins ? 1 : 0; return maxConsecutiveWins >= criteria.consecutive_wins ? 1 : 0;
} }
if (criteria.undefeated_group_stage !== undefined) {
const regionalTournaments = await pb.collection("tournaments").getFullList({
filter: 'regional = true',
sort: 'start_time',
});
for (const tournament of regionalTournaments) {
const groups = await pb.collection("groups").getFullList({
filter: `tournament = "${tournament.id}"`,
expand: 'teams,teams.players',
});
for (const group of groups) {
const teams = group.expand?.teams || [];
let playerTeamId: string | null = null;
for (const team of teams) {
const teamPlayers = team.expand?.players || team.players || [];
const isPlayerInTeam = teamPlayers.some((p: any) =>
(typeof p === 'string' ? p : p.id) === playerId
);
if (isPlayerInTeam) {
playerTeamId = team.id;
break;
}
}
if (!playerTeamId) continue;
const groupMatches = await pb.collection("matches").getFullList({
filter: `tournament = "${tournament.id}" && group = "${group.id}" && status = "ended" && (home = "${playerTeamId}" || away = "${playerTeamId}")`,
expand: 'home,away',
});
if (groupMatches.length === 0) continue;
let isUndefeated = true;
for (const match of groupMatches) {
const isHome = match.home === playerTeamId;
const didWin = isHome
? match.home_cups > match.away_cups
: match.away_cups > match.home_cups;
if (!didWin) {
isUndefeated = false;
break;
}
}
if (isUndefeated) {
return 1;
}
}
}
return 0;
}
return 0; return 0;
}, },
@@ -425,10 +598,13 @@ export function createBadgesService(pb: PocketBase) {
if (criteria.overtime_matches !== undefined) return criteria.overtime_matches; if (criteria.overtime_matches !== undefined) return criteria.overtime_matches;
if (criteria.overtime_wins !== undefined) return criteria.overtime_wins; if (criteria.overtime_wins !== undefined) return criteria.overtime_wins;
if (criteria.consecutive_wins !== undefined) return criteria.consecutive_wins; if (criteria.consecutive_wins !== undefined) return criteria.consecutive_wins;
if (criteria.unique_partners !== undefined) return criteria.unique_partners;
if (criteria.won_tournament !== undefined) return 1; if (criteria.won_tournament !== undefined) return 1;
if (criteria.placement !== undefined) return 1; if (criteria.placement !== undefined) return 1;
if (criteria.margin_of_victory !== undefined) return 1; if (criteria.margin_of_victory !== undefined) return 1;
if (criteria.tournament_record !== undefined) return 1; if (criteria.tournament_record !== undefined) return 1;
if (criteria.beat_mainline_partner !== undefined) return 1;
if (criteria.undefeated_group_stage !== undefined) return 1;
return 1; return 1;
}, },