send tournament bracket updates when any match is complete
This commit is contained in:
+11
-7
@@ -2103,15 +2103,18 @@ struct C_SetBlockedSenders_BB_C6 : C_SetBlockedSenders_C6<28> { } __packed__;
|
||||
|
||||
struct S_ConfirmTournamentEntry_GC_Ep3_CC {
|
||||
ptext<char, 0x40> tournament_name;
|
||||
parray<le_uint16_t, 4> unknown_a2;
|
||||
le_uint16_t num_teams = 0;
|
||||
le_uint16_t unknown_a1 = 0;
|
||||
le_uint16_t unknown_a2 = 0;
|
||||
le_uint16_t unknown_a3 = 0;
|
||||
ptext<char, 0x20> server_name;
|
||||
ptext<char, 0x20> start_time; // e.g. "15:09:30" or "13:03 PST"
|
||||
struct Entry {
|
||||
le_uint16_t unknown_a1 = 0;
|
||||
le_uint16_t present = 0; // 1 if team present, 0 otherwise
|
||||
ptext<char, 0x20> team_name;
|
||||
struct TeamEntry {
|
||||
le_uint16_t win_count = 0;
|
||||
le_uint16_t is_active = 0;
|
||||
ptext<char, 0x20> name;
|
||||
} __packed__;
|
||||
parray<Entry, 0x20> entries;
|
||||
parray<TeamEntry, 0x20> team_entries;
|
||||
} __packed__;
|
||||
|
||||
// CD: Invalid command
|
||||
@@ -2365,7 +2368,8 @@ struct S_TournamentList_GC_Ep3_E0 {
|
||||
ptext<char, 0x20> name;
|
||||
le_uint16_t num_teams = 0;
|
||||
le_uint16_t max_teams = 0;
|
||||
parray<le_uint16_t, 2> unknown_a3;
|
||||
le_uint16_t unknown_a3 = 0;
|
||||
le_uint16_t unknown_a4 = 0;
|
||||
} __packed__;
|
||||
parray<Entry, 0x20> entries;
|
||||
} __packed__;
|
||||
|
||||
@@ -515,6 +515,10 @@ shared_ptr<Tournament::Team> Tournament::team_for_serial_number(
|
||||
throw logic_error("serial number registered in tournament but not in any team");
|
||||
}
|
||||
|
||||
const set<uint32_t>& Tournament::get_all_player_serial_numbers() const {
|
||||
return this->all_player_serial_numbers;
|
||||
}
|
||||
|
||||
void Tournament::start() {
|
||||
if (this->current_state != State::REGISTRATION) {
|
||||
throw runtime_error("tournament has already started");
|
||||
|
||||
@@ -107,6 +107,7 @@ public:
|
||||
std::shared_ptr<Match> next_match_for_team(std::shared_ptr<Team> team) const;
|
||||
std::shared_ptr<Match> get_final_match() const;
|
||||
std::shared_ptr<Team> team_for_serial_number(uint32_t serial_number) const;
|
||||
const std::set<uint32_t>& get_all_player_serial_numbers() const;
|
||||
|
||||
void start();
|
||||
|
||||
|
||||
+46
-21
@@ -215,8 +215,15 @@ void on_connect(std::shared_ptr<ServerState> s, std::shared_ptr<Client> c) {
|
||||
|
||||
void on_login_complete(shared_ptr<ServerState> s, shared_ptr<Client> c) {
|
||||
if (c->flags & Client::Flag::IS_EPISODE_3) {
|
||||
c->ep3_tournament_team = s->ep3_tournament_index->team_for_serial_number(
|
||||
auto team = s->ep3_tournament_index->team_for_serial_number(
|
||||
c->license->serial_number);
|
||||
if (team) {
|
||||
auto tourn = team->tournament.lock();
|
||||
if (tourn) {
|
||||
c->ep3_tournament_team = team;
|
||||
send_ep3_confirm_tournament_entry(s, c, tourn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On the BB data server, this function is called only on the last connection
|
||||
@@ -1042,6 +1049,42 @@ static void on_ep3_counter_state(shared_ptr<ServerState> s, shared_ptr<Client> c
|
||||
}
|
||||
}
|
||||
|
||||
static void on_tournament_bracket_updated(
|
||||
shared_ptr<ServerState> s, shared_ptr<const Episode3::Tournament> tourn) {
|
||||
const auto& serial_numbers = tourn->get_all_player_serial_numbers();
|
||||
|
||||
for (const auto& l : s->all_lobbies()) {
|
||||
for (const auto& c : l->clients) {
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
if (!c->license || !serial_numbers.count(c->license->serial_number)) {
|
||||
continue;
|
||||
}
|
||||
if (c->ep3_tournament_team.expired()) {
|
||||
continue;
|
||||
}
|
||||
send_ep3_confirm_tournament_entry(s, c, tourn);
|
||||
}
|
||||
}
|
||||
|
||||
if (tourn && (tourn->get_state() == Episode3::Tournament::State::COMPLETE)) {
|
||||
s->ep3_tournament_index->delete_tournament(tourn->get_number());
|
||||
}
|
||||
|
||||
if (tourn->get_state() == Episode3::Tournament::State::COMPLETE) {
|
||||
auto team = tourn->get_winner_team();
|
||||
if (team->player_serial_numbers.empty()) {
|
||||
send_ep3_text_message_printf(s, "$C7A CPU team won\nthe tournament\n$C6%s", tourn->get_name().c_str());
|
||||
} else {
|
||||
send_ep3_text_message_printf(s, "$C6%s$C7\nwon the tournament\n$C6%s", team->name.c_str(), tourn->get_name().c_str());
|
||||
}
|
||||
s->ep3_tournament_index->delete_tournament(tourn->get_number());
|
||||
}
|
||||
|
||||
s->ep3_tournament_index->save();
|
||||
}
|
||||
|
||||
static void on_ep3_server_data_request(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
uint16_t, uint32_t, const string& data) { // CA
|
||||
auto l = s->find_lobby(c->lobby_id);
|
||||
@@ -1117,26 +1160,10 @@ static void on_ep3_server_data_request(shared_ptr<ServerState> s, shared_ptr<Cli
|
||||
}
|
||||
send_ep3_tournament_match_result(l, l->tournament_match);
|
||||
|
||||
tourn->print_bracket(stderr);
|
||||
if (tourn && (tourn->get_state() == Episode3::Tournament::State::COMPLETE)) {
|
||||
s->ep3_tournament_index->delete_tournament(tourn->get_number());
|
||||
}
|
||||
s->ep3_tournament_index->save();
|
||||
on_tournament_bracket_updated(s, tourn);
|
||||
}
|
||||
}
|
||||
|
||||
static void on_tournament_complete(
|
||||
shared_ptr<ServerState> s, shared_ptr<const Episode3::Tournament> tourn) {
|
||||
auto team = tourn->get_winner_team();
|
||||
if (team->player_serial_numbers.empty()) {
|
||||
send_ep3_text_message_printf(s, "$C7A CPU team won\nthe tournament\n$C6%s", tourn->get_name().c_str());
|
||||
} else {
|
||||
send_ep3_text_message_printf(s, "$C6%s$C7\nwon the tournament\n$C6%s", team->name.c_str(), tourn->get_name().c_str());
|
||||
}
|
||||
s->ep3_tournament_index->delete_tournament(tourn->get_number());
|
||||
s->ep3_tournament_index->save();
|
||||
}
|
||||
|
||||
static void on_ep3_tournament_control(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
uint16_t, uint32_t flag, const string&) { // E2
|
||||
switch (flag) {
|
||||
@@ -1164,9 +1191,7 @@ static void on_ep3_tournament_control(shared_ptr<ServerState> s, shared_ptr<Clie
|
||||
if (tourn) {
|
||||
if (tourn->get_state() != Episode3::Tournament::State::COMPLETE) {
|
||||
team->unregister_player(c->license->serial_number);
|
||||
if (tourn->get_state() == Episode3::Tournament::State::COMPLETE) {
|
||||
on_tournament_complete(s, tourn);
|
||||
}
|
||||
on_tournament_bracket_updated(s, tourn);
|
||||
}
|
||||
c->ep3_tournament_team.reset();
|
||||
}
|
||||
|
||||
+5
-3
@@ -1953,8 +1953,9 @@ void send_ep3_confirm_tournament_entry(
|
||||
cmd.start_time = "Unknown";
|
||||
auto& teams = tourn->all_teams();
|
||||
for (size_t z = 0; z < min<size_t>(teams.size(), 0x20); z++) {
|
||||
cmd.entries[z].present = 1;
|
||||
cmd.entries[z].team_name = teams[z]->name;
|
||||
cmd.team_entries[z].win_count = teams[z]->num_rounds_cleared;
|
||||
cmd.team_entries[z].is_active = teams[z]->is_active;
|
||||
cmd.team_entries[z].name = teams[z]->name;
|
||||
}
|
||||
}
|
||||
send_command_t(c, 0xCC, tourn ? 0x01 : 0x00, cmd);
|
||||
@@ -1992,7 +1993,8 @@ void send_ep3_tournament_list(
|
||||
}
|
||||
}
|
||||
entry.max_teams = teams.size();
|
||||
entry.unknown_a3.clear(0xFFFF);
|
||||
entry.unknown_a3 = 0xFFFF;
|
||||
entry.unknown_a4 = 0xFFFF;
|
||||
z++;
|
||||
}
|
||||
send_command_t(c, 0xE0, z, cmd);
|
||||
|
||||
Reference in New Issue
Block a user