use Ep3 NTE command formats

This commit is contained in:
Martin Michelsen
2024-02-08 01:02:23 -08:00
parent 729d9af4b0
commit dcea0e4520
3 changed files with 59 additions and 26 deletions
+34 -19
View File
@@ -6701,26 +6701,41 @@ struct G_SetPlayerSubstatus_Ep3_6xB5x3C {
// This is sent before the counter sequence in a tournament game, to reserve the
// player and COM slots and set the map number.
struct G_SetTournamentPlayerDecks_Ep3_6xB4x3D_Entry {
/* 00 */ uint8_t type = 0; // 0 = no player, 1 = human, 2 = COM
/* 01 */ pstring<TextEncoding::MARKED, 0x10> player_name;
/* 11 */ pstring<TextEncoding::MARKED, 0x10> deck_name; // Only used for COM players
/* 21 */ parray<uint8_t, 5> unknown_a1;
/* 26 */ parray<le_uint16_t, 0x1F> card_ids; // Can be blank for human players
/* 64 */ uint8_t client_id = 0; // Unused for COMs
/* 65 */ uint8_t unknown_a4 = 0;
/* 66 */ le_uint16_t unknown_a2 = 0;
/* 68 */ le_uint16_t unknown_a3 = 0;
/* 6A */
} __packed__;
struct G_SetTournamentPlayerDecks_Ep3NTE_6xB4x3D {
/* 0000 */ G_CardBattleCommandHeader header = {0xB4, sizeof(G_SetTournamentPlayerDecks_Ep3NTE_6xB4x3D) / 4, 0, 0x3D, 0, 0, 0};
/* 0008 */ Episode3::Rules rules;
/* 0014 */ parray<G_SetTournamentPlayerDecks_Ep3_6xB4x3D_Entry, 4> entries;
/* 01BC */ le_uint32_t map_number = 0;
/* 01C0 */ uint8_t player_slot = 0; // Which deck slot is editable by the client
/* 01C1 */ uint8_t unknown_a3 = 0;
/* 01C2 */ uint8_t unknown_a4 = 0;
/* 01C3 */ uint8_t unknown_a5 = 0;
/* 01C4 */
} __packed__;
struct G_SetTournamentPlayerDecks_Ep3_6xB4x3D {
G_CardBattleCommandHeader header = {0xB4, sizeof(G_SetTournamentPlayerDecks_Ep3_6xB4x3D) / 4, 0, 0x3D, 0, 0, 0};
Episode3::Rules rules;
struct Entry {
uint8_t type = 0; // 0 = no player, 1 = human, 2 = COM
pstring<TextEncoding::MARKED, 0x10> player_name;
pstring<TextEncoding::MARKED, 0x10> deck_name; // Only used for COM players
parray<uint8_t, 5> unknown_a1;
parray<le_uint16_t, 0x1F> card_ids; // Can be blank for human players
uint8_t client_id = 0; // Unused for COMs
uint8_t unknown_a4 = 0;
le_uint16_t unknown_a2 = 0;
le_uint16_t unknown_a3 = 0;
} __packed__;
parray<Entry, 4> entries;
le_uint32_t map_number = 0;
uint8_t player_slot = 0; // Which deck slot is editable by the client
uint8_t unknown_a3 = 0;
uint8_t unknown_a4 = 0;
uint8_t unknown_a5 = 0;
/* 0000 */ G_CardBattleCommandHeader header = {0xB4, sizeof(G_SetTournamentPlayerDecks_Ep3_6xB4x3D) / 4, 0, 0x3D, 0, 0, 0};
/* 0008 */ Episode3::Rules rules;
/* 001C */ parray<G_SetTournamentPlayerDecks_Ep3_6xB4x3D_Entry, 4> entries;
/* 01C4 */ le_uint32_t map_number = 0;
/* 01C8 */ uint8_t player_slot = 0; // Which deck slot is editable by the client
/* 01C9 */ uint8_t unknown_a3 = 0;
/* 01CA */ uint8_t unknown_a4 = 0;
/* 01CB */ uint8_t unknown_a5 = 0;
/* 01CC */
} __packed__;
// 6xB5x3E: Make card auction bid
+14 -5
View File
@@ -994,11 +994,20 @@ static HandlerResult S_6x(shared_ptr<ProxyServer::LinkedSession> ses, uint16_t,
if (ses->config.check_flag(Client::Flag::PROXY_EP3_INFINITE_TIME_ENABLED) && (header.subcommand == 0xB4)) {
if (header.subsubcommand == 0x3D) {
auto& cmd = check_size_t<G_SetTournamentPlayerDecks_Ep3_6xB4x3D>(data);
if (cmd.rules.overall_time_limit || cmd.rules.phase_time_limit) {
cmd.rules.overall_time_limit = 0;
cmd.rules.phase_time_limit = 0;
modified = true;
if (ses->version() == Version::GC_EP3_NTE) {
auto& cmd = check_size_t<G_SetTournamentPlayerDecks_Ep3NTE_6xB4x3D>(data);
if (cmd.rules.overall_time_limit || cmd.rules.phase_time_limit) {
cmd.rules.overall_time_limit = 0;
cmd.rules.phase_time_limit = 0;
modified = true;
}
} else {
auto& cmd = check_size_t<G_SetTournamentPlayerDecks_Ep3_6xB4x3D>(data);
if (cmd.rules.overall_time_limit || cmd.rules.phase_time_limit) {
cmd.rules.overall_time_limit = 0;
cmd.rules.phase_time_limit = 0;
modified = true;
}
}
} else if (header.subsubcommand == 0x05) {
if (ses->version() == Version::GC_EP3_NTE) {
+11 -2
View File
@@ -3063,7 +3063,8 @@ void send_ep3_game_details(shared_ptr<Client> c, shared_ptr<Lobby> l) {
}
}
void send_ep3_set_tournament_player_decks(shared_ptr<Client> c) {
template <typename CmdT>
void send_ep3_set_tournament_player_decks_t(shared_ptr<Client> c) {
auto s = c->require_server_state();
auto l = c->require_lobby();
@@ -3073,7 +3074,7 @@ void send_ep3_set_tournament_player_decks(shared_ptr<Client> c) {
throw runtime_error("tournament is deleted");
}
G_SetTournamentPlayerDecks_Ep3_6xB4x3D cmd;
CmdT cmd;
cmd.rules = tourn->get_rules();
cmd.map_number = tourn->get_map()->map_number;
cmd.player_slot = 0xFF;
@@ -3186,6 +3187,14 @@ void send_ep3_tournament_match_result(shared_ptr<Lobby> l, uint32_t meseta_rewar
}
}
void send_ep3_set_tournament_player_decks(shared_ptr<Client> c) {
if (c->version() == Version::GC_EP3_NTE) {
send_ep3_set_tournament_player_decks_t<G_SetTournamentPlayerDecks_Ep3NTE_6xB4x3D>(c);
} else {
send_ep3_set_tournament_player_decks_t<G_SetTournamentPlayerDecks_Ep3_6xB4x3D>(c);
}
}
void send_ep3_update_game_metadata(shared_ptr<Lobby> l) {
size_t total_spectators = 0;
for (auto watcher_l : l->watcher_lobbies) {