Skip to content

Commit c3a8b2d

Browse files
authored
Four team tournament (#1808)
* added four team tournament support * fix
1 parent bcbacc4 commit c3a8b2d

1 file changed

Lines changed: 164 additions & 148 deletions

File tree

src/routes/competition.ts

Lines changed: 164 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,7 @@ const parseFourTeamLabels = (raw_team_labels: string | null) => {
5858
const labels = parsed.map((label) =>
5959
typeof label === "string" ? label.trim() : "",
6060
);
61-
if (
62-
labels.length !== FOUR_TEAM_COUNT ||
63-
labels.some((label) => !label) ||
64-
new Set(labels).size !== FOUR_TEAM_COUNT
65-
) {
61+
if (labels.length !== FOUR_TEAM_COUNT || labels.some((label) => !label)) {
6662
return null;
6763
}
6864
return labels;
@@ -78,7 +74,12 @@ const getFourTeamCombinations = (team_ids: string[]) => {
7874
for (let j = i + 1; j < team_ids.length; j++) {
7975
for (let k = j + 1; k < team_ids.length; k++) {
8076
for (let l = k + 1; l < team_ids.length; l++) {
81-
combinations.push([team_ids[i], team_ids[j], team_ids[k], team_ids[l]]);
77+
combinations.push([
78+
team_ids[i],
79+
team_ids[j],
80+
team_ids[k],
81+
team_ids[l],
82+
]);
8283
}
8384
}
8485
}
@@ -90,8 +91,9 @@ const getAvailableFourTeamDetails = async (
9091
contest_id: string,
9192
map_team_labels: string[],
9293
): Promise<FourTeamAvailableContext | null> => {
94+
const unique_map_team_labels = Array.from(new Set(map_team_labels));
9395
const players_labels_entries = await Promise.all(
94-
map_team_labels.map(async (team_label) => {
96+
unique_map_team_labels.map(async (team_label) => {
9597
const player_labels: string[] = await ContHasFunc.get_players_label(
9698
contest_id,
9799
team_label,
@@ -114,7 +116,7 @@ const getAvailableFourTeamDetails = async (
114116
const available_team_details = (
115117
await Promise.all(
116118
team_list.map(async (team_id) => {
117-
const player_specs = map_team_labels.flatMap((team_label) => {
119+
const player_specs = unique_map_team_labels.flatMap((team_label) => {
118120
const player_labels =
119121
players_labels_by_team_label.get(team_label) ?? [];
120122
return player_labels.map((player_label, player_index) => ({
@@ -624,7 +626,10 @@ router.post("/start-all", authenticate(), async (req, res) => {
624626
return Promise.resolve(true);
625627
})
626628
.catch((err) => {
627-
console.error("Error while linking competition runtime code", err);
629+
console.error(
630+
"Error while linking competition runtime code",
631+
err,
632+
);
628633
console.log(`Copy ${code_file_name} failed: ${err}`);
629634
return Promise.resolve(false);
630635
});
@@ -801,47 +806,51 @@ router.post("/start-four-team", authenticate(), async (req, res) => {
801806
new Set(all_available_players.map((player) => player.code_id)),
802807
);
803808
const index_map = player_codes_unique.map((player_code) =>
804-
all_available_players.findIndex((player) => player.code_id === player_code),
809+
all_available_players.findIndex(
810+
(player) => player.code_id === player_code,
811+
),
805812
);
806813
console.debug("player_codes_unique: ", player_codes_unique);
807814
console.debug("index_map: ", index_map);
808815

809816
if (files_exist.some((file_exist) => !file_exist)) {
810817
const cos = await COS.initCOS();
811818
const config = await COS.getConfig();
812-
const download_promises = player_codes_unique.map((player_code, index) => {
813-
const player = all_available_players[index_map[index]];
814-
if (files_exist[index_map[index]]) {
815-
return Promise.resolve(true);
816-
}
817-
const code_file_name = getCodeFileName(player_code, player.language);
818-
console.debug("code_file_name: ", code_file_name);
819-
return fs
820-
.mkdir(
821-
`${base_directory}/${contest_name}/code/${player.team_id}/source`,
822-
{ recursive: true },
823-
)
824-
.then(() => {
825-
return COS.downloadObject(
826-
`${contest_name}/code/${player.team_id}/${code_file_name}`,
827-
`${base_directory}/${contest_name}/code/${player.team_id}/source/${code_file_name}`,
828-
cos,
829-
config,
830-
);
831-
})
832-
.then(() => {
833-
return fs.chmod(
834-
`${base_directory}/${contest_name}/code/${player.team_id}/source/${code_file_name}`,
835-
0o755,
836-
);
837-
})
838-
.then(() => Promise.resolve(true))
839-
.catch((err) => {
840-
console.error("Error while downloading team code file", err);
841-
console.log(`Download ${code_file_name} failed: ${err}`);
842-
return Promise.resolve(false);
843-
});
844-
});
819+
const download_promises = player_codes_unique.map(
820+
(player_code, index) => {
821+
const player = all_available_players[index_map[index]];
822+
if (files_exist[index_map[index]]) {
823+
return Promise.resolve(true);
824+
}
825+
const code_file_name = getCodeFileName(player_code, player.language);
826+
console.debug("code_file_name: ", code_file_name);
827+
return fs
828+
.mkdir(
829+
`${base_directory}/${contest_name}/code/${player.team_id}/source`,
830+
{ recursive: true },
831+
)
832+
.then(() => {
833+
return COS.downloadObject(
834+
`${contest_name}/code/${player.team_id}/${code_file_name}`,
835+
`${base_directory}/${contest_name}/code/${player.team_id}/source/${code_file_name}`,
836+
cos,
837+
config,
838+
);
839+
})
840+
.then(() => {
841+
return fs.chmod(
842+
`${base_directory}/${contest_name}/code/${player.team_id}/source/${code_file_name}`,
843+
0o755,
844+
);
845+
})
846+
.then(() => Promise.resolve(true))
847+
.catch((err) => {
848+
console.error("Error while downloading team code file", err);
849+
console.log(`Download ${code_file_name} failed: ${err}`);
850+
return Promise.resolve(false);
851+
});
852+
},
853+
);
845854
const download_results = await Promise.all(download_promises);
846855
console.debug("download_results: ", download_results);
847856
if (download_results.some((result) => !result)) {
@@ -890,116 +899,114 @@ router.post("/start-four-team", authenticate(), async (req, res) => {
890899
const players_by_team_id = new Map(
891900
available_team_details.map((team) => [team.team_id, team.players]),
892901
);
893-
const start_four_team_promises = team_combinations.map(
894-
async (team_ids) => {
895-
try {
896-
const room_player_groups = team_ids.map((team_id, index) => {
897-
const team_label = map_team_labels[index];
898-
return (players_by_team_id.get(team_id) ?? []).filter(
899-
(player) => player.team_label === team_label,
900-
);
901-
});
902-
if (
903-
room_player_groups.some((player_group) => player_group.length === 0)
904-
) {
905-
return false;
906-
}
907-
908-
const player_roles = room_player_groups.map((player_group) =>
909-
player_group.map((player) => player.role),
910-
);
911-
const player_codes = room_player_groups.map((player_group) =>
912-
player_group.map((player) => player.code_id),
902+
const start_four_team_promises = team_combinations.map(async (team_ids) => {
903+
try {
904+
const room_player_groups = team_ids.map((team_id, index) => {
905+
const team_label = map_team_labels[index];
906+
return (players_by_team_id.get(team_id) ?? []).filter(
907+
(player) => player.team_label === team_label,
913908
);
909+
});
910+
if (
911+
room_player_groups.some((player_group) => player_group.length === 0)
912+
) {
913+
return false;
914+
}
914915

915-
const room_id = await ContHasFunc.insert_room_competition(
916-
contest_id,
917-
"Waiting",
918-
map_id,
919-
round_id,
920-
);
921-
if (!room_id) {
922-
return false;
923-
}
924-
console.debug("room_id: ", room_id);
916+
const player_roles = room_player_groups.map((player_group) =>
917+
player_group.map((player) => player.role),
918+
);
919+
const player_codes = room_player_groups.map((player_group) =>
920+
player_group.map((player) => player.code_id),
921+
);
925922

926-
const affected_rows = await ContHasFunc.insert_room_teams(
927-
room_id,
928-
team_ids,
929-
map_team_labels,
930-
player_roles,
931-
player_codes,
932-
);
933-
if (affected_rows !== FOUR_TEAM_COUNT) {
934-
return false;
935-
}
923+
const room_id = await ContHasFunc.insert_room_competition(
924+
contest_id,
925+
"Waiting",
926+
map_id,
927+
round_id,
928+
);
929+
if (!room_id) {
930+
return false;
931+
}
932+
console.debug("room_id: ", room_id);
936933

937-
await fs.mkdir(
938-
`${base_directory}/${contest_name}/competition/${room_id}/source`,
939-
{ recursive: true },
940-
);
934+
const affected_rows = await ContHasFunc.insert_room_teams(
935+
room_id,
936+
team_ids,
937+
map_team_labels,
938+
player_roles,
939+
player_codes,
940+
);
941+
if (affected_rows !== FOUR_TEAM_COUNT) {
942+
return false;
943+
}
941944

942-
const room_players = room_player_groups.flat();
943-
const copy_promises = room_players.map((player) => {
944-
const code_file_name = getCodeFileName(
945-
player.code_id,
946-
player.language,
947-
);
948-
const competition_file_name = getRuntimeCodeFileName(
949-
contest_name,
950-
player.team_label,
951-
player.player_label,
952-
player.player_index,
953-
player.language,
954-
);
955-
return fs
956-
.mkdir(
957-
`${base_directory}/${contest_name}/competition/${room_id}/source/${player.team_id}`,
958-
{ recursive: true },
959-
)
960-
.then(() => {
961-
return fs.symlink(
962-
`${base_directory}/${contest_name}/code/${player.team_id}/source/${code_file_name}`,
963-
`${base_directory}/${contest_name}/competition/${room_id}/source/${player.team_id}/${competition_file_name}`,
964-
);
965-
})
966-
.then(() => Promise.resolve(true))
967-
.catch((err) => {
968-
console.error(
969-
"Error while linking four-team competition runtime code",
970-
err,
971-
);
972-
console.log(`Copy ${code_file_name} failed: ${err}`);
973-
return Promise.resolve(false);
974-
});
975-
});
976-
const copy_result = await Promise.all(copy_promises);
977-
console.debug("copy_result: ", copy_result);
978-
if (copy_result.some((result) => !result)) {
979-
return false;
980-
}
945+
await fs.mkdir(
946+
`${base_directory}/${contest_name}/competition/${room_id}/source`,
947+
{ recursive: true },
948+
);
981949

982-
docker_queue.push({
983-
contest_id: contest_id,
984-
round_id: round_id,
985-
room_id: room_id,
986-
map_id: map_id,
987-
team_label_binds: team_ids.map((team_id, index) => ({
988-
team_id,
989-
label: map_team_labels[index],
990-
})),
991-
competition: 1,
992-
exposed: exposed,
993-
envoy: envoy,
994-
});
995-
return true;
996-
} catch (err) {
997-
console.error("Error while starting four-team competition room", err);
998-
console.log(`Start four-team competition failed: ${err}`);
950+
const room_players = room_player_groups.flat();
951+
const copy_promises = room_players.map((player) => {
952+
const code_file_name = getCodeFileName(
953+
player.code_id,
954+
player.language,
955+
);
956+
const competition_file_name = getRuntimeCodeFileName(
957+
contest_name,
958+
player.team_label,
959+
player.player_label,
960+
player.player_index,
961+
player.language,
962+
);
963+
return fs
964+
.mkdir(
965+
`${base_directory}/${contest_name}/competition/${room_id}/source/${player.team_id}`,
966+
{ recursive: true },
967+
)
968+
.then(() => {
969+
return fs.symlink(
970+
`${base_directory}/${contest_name}/code/${player.team_id}/source/${code_file_name}`,
971+
`${base_directory}/${contest_name}/competition/${room_id}/source/${player.team_id}/${competition_file_name}`,
972+
);
973+
})
974+
.then(() => Promise.resolve(true))
975+
.catch((err) => {
976+
console.error(
977+
"Error while linking four-team competition runtime code",
978+
err,
979+
);
980+
console.log(`Copy ${code_file_name} failed: ${err}`);
981+
return Promise.resolve(false);
982+
});
983+
});
984+
const copy_result = await Promise.all(copy_promises);
985+
console.debug("copy_result: ", copy_result);
986+
if (copy_result.some((result) => !result)) {
999987
return false;
1000988
}
1001-
},
1002-
);
989+
990+
docker_queue.push({
991+
contest_id: contest_id,
992+
round_id: round_id,
993+
room_id: room_id,
994+
map_id: map_id,
995+
team_label_binds: team_ids.map((team_id, index) => ({
996+
team_id,
997+
label: map_team_labels[index],
998+
})),
999+
competition: 1,
1000+
exposed: exposed,
1001+
envoy: envoy,
1002+
});
1003+
return true;
1004+
} catch (err) {
1005+
console.error("Error while starting four-team competition room", err);
1006+
console.log(`Start four-team competition failed: ${err}`);
1007+
return false;
1008+
}
1009+
});
10031010

10041011
const start_results = await Promise.all(start_four_team_promises);
10051012
console.debug("start_results: ", start_results);
@@ -1735,7 +1742,10 @@ router.post("/finish-one", async (req, res) => {
17351742
return Promise.resolve(true);
17361743
})
17371744
.catch((err) => {
1738-
console.error("Error while uploading competition output file", err);
1745+
console.error(
1746+
"Error while uploading competition output file",
1747+
err,
1748+
);
17391749
console.log(`Upload ${filename} failed: ${err}`);
17401750
return Promise.resolve(false);
17411751
});
@@ -1766,7 +1776,10 @@ router.post("/finish-one", async (req, res) => {
17661776
return true;
17671777
})
17681778
.catch((err) => {
1769-
console.error("Error while uploading competition extra file", err);
1779+
console.error(
1780+
"Error while uploading competition extra file",
1781+
err,
1782+
);
17701783
console.log(`Upload ${extraFileName} failed: ${err}`);
17711784
return false;
17721785
});
@@ -1780,7 +1793,10 @@ router.post("/finish-one", async (req, res) => {
17801793
console.log("Extra files uploaded!");
17811794
}
17821795
} catch (err) {
1783-
console.error("Error while uploading competition finish artifacts", err);
1796+
console.error(
1797+
"Error while uploading competition finish artifacts",
1798+
err,
1799+
);
17841800
return res
17851801
.status(500)
17861802
.send("500 Internal Server Error: Delete files failed. " + err);

0 commit comments

Comments
 (0)