Skip to content

Commit

Permalink
generate tiebreaker sets for rr/swiss copy
Browse files Browse the repository at this point in the history
fixes #37
  • Loading branch information
jmlee337 committed Jul 23, 2024
1 parent d237a7b commit c7bb0ba
Show file tree
Hide file tree
Showing 11 changed files with 329 additions and 34 deletions.
34 changes: 25 additions & 9 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,24 @@ export type InvalidReplay = {
invalidReason: string;
};

export type Participant = {
displayName: string;
prefix: string;
pronouns: string;
};

export enum State {
PENDING = 1,
STARTED = 2,
COMPLETED = 3,
CALLED = 6,
}

export type Participant = {
displayName: string;
prefix: string;
pronouns: string;
};

export type Entrant = {
id: number;
participants: Participant[];
};

export type Set = {
id: number;
state: State;
Expand All @@ -73,6 +78,15 @@ export type Sets = {

export type PhaseGroup = {
id: number;
/**
* 1: SINGLE_ELIMINATION
* 2: DOUBLE_ELIMINATION
* 3: ROUND_ROBIN
* 4: SWISS
* https://developer.start.gg/reference/brackettype.doc
*/
bracketType: number;
entrants: Entrant[];
name: string;
sets: Sets;
};
Expand Down Expand Up @@ -103,9 +117,11 @@ export type AdminedTournament = {
};

export type ChallongeTournament = {
entrants: Entrant[];
name: string;
slug: string;
sets: Sets;
tournamentType: string;
};

export type StartggGameSelection = {
Expand Down Expand Up @@ -187,7 +203,7 @@ export type Context = {
name: string;
};
set: {
id: number;
id?: number;
fullRoundText: string;
round: number;
twitchStream: string | null;
Expand All @@ -199,10 +215,10 @@ export type Context = {
slug: string;
};
set: {
id: number;
id?: number;
fullRoundText: string;
round: number;
ordinal: number;
ordinal: number | null;
};
};
startMs: number;
Expand Down
30 changes: 24 additions & 6 deletions src/main/challonge.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AdminedTournament,
ChallongeMatchItem,
Entrant,
Set,
Sets,
State,
Expand Down Expand Up @@ -59,15 +60,18 @@ export async function getChallongeTournaments(
}));
}

export async function getChallongeTournamentName(
export async function getChallongeTournament(
slug: string,
key: string,
): Promise<string> {
): Promise<{ name: string; tournamentType: string }> {
const json = await get(
`https://api.challonge.com/v2.1/tournaments/${slug}.json`,
key,
);
return json.data.attributes.name;
return {
name: json.data.attributes.name,
tournamentType: json.data.attributes.tournament_type,
};
}

const participantIdToName = new Map<number, string>();
Expand Down Expand Up @@ -121,10 +125,11 @@ const toSet = (match: any): Set => {
export async function getChallongeSets(
slug: string,
key: string,
): Promise<Sets> {
): Promise<{ entrants: Entrant[]; sets: Sets }> {
let participantsPage = 0;
let participantsCount = 0;
let participantsSeen = 0;
const entrants: Entrant[] = [];
do {
participantsPage += 1;
// eslint-disable-next-line no-await-in-loop
Expand All @@ -136,6 +141,16 @@ export async function getChallongeSets(
data
.filter((participant: any) => participant.type === 'participant')
.forEach((participant: any) => {
entrants.push({
id: participant.id,
participants: [
{
displayName: participant.attributes.name,
prefix: '',
pronouns: '',
},
],
});
participantIdToName.set(
parseInt(participant.id, 10),
participant.attributes.name,
Expand Down Expand Up @@ -177,8 +192,11 @@ export async function getChallongeSets(
matchesSeen += data.length;
} while (matchesSeen < matchesCount);
return {
pendingSets: pendingSets.sort((a, b) => a.ordinal! - b.ordinal!),
completedSets: completedSets.sort((a, b) => b.ordinal! - a.ordinal!),
entrants,
sets: {
pendingSets: pendingSets.sort((a, b) => a.ordinal! - b.ordinal!),
completedSets: completedSets.sort((a, b) => b.ordinal! - a.ordinal!),
},
};
}

Expand Down
22 changes: 18 additions & 4 deletions src/main/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ChallongeMatchItem,
Context,
CopySettings,
Entrant,
Mode,
Output,
Replay,
Expand All @@ -31,11 +32,12 @@ import {
reportSet,
updateSet,
getTournaments,
getPhaseGroupEntrants,
} from './startgg';
import { enforceReplays, getReplaysInDir, writeReplays } from './replay';
import {
getChallongeSets,
getChallongeTournamentName,
getChallongeTournament,
getChallongeTournaments,
reportChallongeSet,
startChallongeSet,
Expand Down Expand Up @@ -262,6 +264,18 @@ export default function setupIPCs(mainWindow: BrowserWindow): void {
},
);

ipcMain.removeHandler('getPhaseGroupEntrants');
ipcMain.handle(
'getPhaseGroupEntrants',
async (event: IpcMainInvokeEvent, id: number): Promise<Entrant[]> => {
if (!sggApiKey) {
throw new Error('Please set start.gg API key');
}

return getPhaseGroupEntrants(sggApiKey, id);
},
);

ipcMain.removeHandler('getStartggKey');
ipcMain.handle('getStartggKey', () => sggApiKey);

Expand Down Expand Up @@ -289,15 +303,15 @@ export default function setupIPCs(mainWindow: BrowserWindow): void {
},
);

ipcMain.removeHandler('getChallongeTournamentName');
ipcMain.removeHandler('getChallongeTournament');
ipcMain.handle(
'getChallongeTournamentName',
'getChallongeTournament',
(event: IpcMainInvokeEvent, slug: string) => {
if (!challongeApiKey) {
throw new Error('Please set Challonge API key.');
}

return getChallongeTournamentName(slug, challongeApiKey);
return getChallongeTournament(slug, challongeApiKey);
},
);

Expand Down
13 changes: 10 additions & 3 deletions src/main/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Context,
CopySettings,
EnforceResult,
Entrant,
Event,
InvalidReplay,
Mode,
Expand Down Expand Up @@ -67,6 +68,8 @@ const electronHandler = {
ipcRenderer.invoke('reportSet', set),
updateSet: (set: StartggSet): Promise<Set> =>
ipcRenderer.invoke('updateSet', set),
getPhaseGroupEntrants: (id: number): Promise<Entrant[]> =>
ipcRenderer.invoke('getPhaseGroupEntrants', id),
getMode: (): Promise<Mode> => ipcRenderer.invoke('getMode'),
setMode: (mode: Mode): Promise<void> => ipcRenderer.invoke('setMode', mode),
getStartggKey: (): Promise<string> => ipcRenderer.invoke('getStartggKey'),
Expand All @@ -75,9 +78,13 @@ const electronHandler = {
getChallongeKey: (): Promise<string> => ipcRenderer.invoke('getChallongeKey'),
setChallongeKey: (challongeKey: string): Promise<void> =>
ipcRenderer.invoke('setChallongeKey', challongeKey),
getChallongeTournamentName: (slug: string): Promise<string> =>
ipcRenderer.invoke('getChallongeTournamentName', slug),
getChallongeSets: (slug: string): Promise<Sets> =>
getChallongeTournament: (
slug: string,
): Promise<{ name: string; tournamentType: string }> =>
ipcRenderer.invoke('getChallongeTournament', slug),
getChallongeSets: (
slug: string,
): Promise<{ entrants: Entrant[]; sets: Sets }> =>
ipcRenderer.invoke('getChallongeSets', slug),
startChallongeSet: (slug: string, id: number): Promise<Set> =>
ipcRenderer.invoke('startChallongeSet', slug, id),
Expand Down
62 changes: 62 additions & 0 deletions src/main/startgg.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
AdminedTournament,
Entrant,
Event,
Participant,
Phase,
Expand Down Expand Up @@ -137,10 +138,13 @@ export async function getPhase(id: number): Promise<PhaseGroup[]> {
`https://api.smash.gg/phase/${id}?expand[]=groups`,
);
const json = await response.json();
const { bracketType } = json.entities.phase;
return json.entities.groups
.map(
(group: any): PhaseGroup => ({
id: group.id,
bracketType,
entrants: [],
name: group.displayIdentifier,
sets: {
pendingSets: [],
Expand Down Expand Up @@ -428,3 +432,61 @@ export async function updateSet(key: string, set: StartggSet): Promise<Set> {
reportedSetIds.set(set.setId, true);
return apiSetToSet(data.updateBracketSet);
}

const PHASE_GROUP_ENTRANTS_QUERY = `
query PhaseGroupQuery($id: ID!, $page: Int) {
phaseGroup(id: $id) {
standings(query: {page: $page, perPage: 128}) {
pageInfo {
totalPages
}
nodes {
entrant {
id
participants {
gamerTag
prefix
player {
user {
genderPronoun
}
}
}
}
}
}
}
}
`;

// 2549545 test-tournament-sorry
// 2139098 the-off-season-2-2 1-000-melee-doubles
export async function getPhaseGroupEntrants(
key: string,
id: number,
): Promise<Entrant[]> {
let page = 1;
let nextData;
const entrants: Entrant[] = [];
do {
// eslint-disable-next-line no-await-in-loop
nextData = await fetchGql(key, PHASE_GROUP_ENTRANTS_QUERY, {
id,
page,
});
const newEntrants: Entrant[] = nextData.phaseGroup.standings.nodes.map(
(standing: any) => ({
id: standing.entrant.id,
participants: standing.entrant.participants.map((participant: any) => ({
displayName: participant.gamerTag,
prefix: participant.prefix,
pronouns: participant.player.user?.genderPronoun ?? '',
})),
}),
);
entrants.push(...newEntrants);

page += 1;
} while (page <= nextData.phaseGroup.standings.pageInfo.totalPages);
return entrants;
}
Loading

0 comments on commit c7bb0ba

Please sign in to comment.