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 // This is sent before the counter sequence in a tournament game, to reserve the
// player and COM slots and set the map number. // 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 { struct G_SetTournamentPlayerDecks_Ep3_6xB4x3D {
G_CardBattleCommandHeader header = {0xB4, sizeof(G_SetTournamentPlayerDecks_Ep3_6xB4x3D) / 4, 0, 0x3D, 0, 0, 0}; /* 0000 */ G_CardBattleCommandHeader header = {0xB4, sizeof(G_SetTournamentPlayerDecks_Ep3_6xB4x3D) / 4, 0, 0x3D, 0, 0, 0};
Episode3::Rules rules; /* 0008 */ Episode3::Rules rules;
struct Entry { /* 001C */ parray<G_SetTournamentPlayerDecks_Ep3_6xB4x3D_Entry, 4> entries;
uint8_t type = 0; // 0 = no player, 1 = human, 2 = COM /* 01C4 */ le_uint32_t map_number = 0;
pstring<TextEncoding::MARKED, 0x10> player_name; /* 01C8 */ uint8_t player_slot = 0; // Which deck slot is editable by the client
pstring<TextEncoding::MARKED, 0x10> deck_name; // Only used for COM players /* 01C9 */ uint8_t unknown_a3 = 0;
parray<uint8_t, 5> unknown_a1; /* 01CA */ uint8_t unknown_a4 = 0;
parray<le_uint16_t, 0x1F> card_ids; // Can be blank for human players /* 01CB */ uint8_t unknown_a5 = 0;
uint8_t client_id = 0; // Unused for COMs /* 01CC */
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;
} __packed__; } __packed__;
// 6xB5x3E: Make card auction bid // 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 (ses->config.check_flag(Client::Flag::PROXY_EP3_INFINITE_TIME_ENABLED) && (header.subcommand == 0xB4)) {
if (header.subsubcommand == 0x3D) { if (header.subsubcommand == 0x3D) {
auto& cmd = check_size_t<G_SetTournamentPlayerDecks_Ep3_6xB4x3D>(data); if (ses->version() == Version::GC_EP3_NTE) {
if (cmd.rules.overall_time_limit || cmd.rules.phase_time_limit) { auto& cmd = check_size_t<G_SetTournamentPlayerDecks_Ep3NTE_6xB4x3D>(data);
cmd.rules.overall_time_limit = 0; if (cmd.rules.overall_time_limit || cmd.rules.phase_time_limit) {
cmd.rules.phase_time_limit = 0; cmd.rules.overall_time_limit = 0;
modified = true; 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) { } else if (header.subsubcommand == 0x05) {
if (ses->version() == Version::GC_EP3_NTE) { 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 s = c->require_server_state();
auto l = c->require_lobby(); 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"); throw runtime_error("tournament is deleted");
} }
G_SetTournamentPlayerDecks_Ep3_6xB4x3D cmd; CmdT cmd;
cmd.rules = tourn->get_rules(); cmd.rules = tourn->get_rules();
cmd.map_number = tourn->get_map()->map_number; cmd.map_number = tourn->get_map()->map_number;
cmd.player_slot = 0xFF; 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) { void send_ep3_update_game_metadata(shared_ptr<Lobby> l) {
size_t total_spectators = 0; size_t total_spectators = 0;
for (auto watcher_l : l->watcher_lobbies) { for (auto watcher_l : l->watcher_lobbies) {