From 039786b2f8571e6d0c814c2b3346809efddac9b2 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 1 Dec 2023 20:05:12 -0800 Subject: [PATCH] handle GC NTE character data struct --- src/CommandFormats.hh | 13 +++++++++++++ src/ReceiveCommands.cc | 33 ++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index f626368c..e2ff081b 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -1121,6 +1121,19 @@ struct C_CharacterData_PC_61_98 { /* 05A4 */ // uint16_t auto_reply[...EOF]; } __attribute__((packed)); +struct C_CharacterData_GCNTE_61_98 { + /* 0000 */ PlayerInventory inventory; + /* 034C */ PlayerDispDataDCPCV3 disp; + /* 041C */ PlayerRecordsEntry_DC records; + /* 04D8 */ ChoiceSearchConfig choice_search_config; + /* 04F0 */ parray blocked_senders; + /* 0468 */ le_uint32_t auto_reply_enabled = 0; + // The auto-reply message can be up to 0x200 bytes. If it's shorter than that, + // the client truncates the command after the first zero byte (rounded up to + // the next 4-byte boundary). + /* 046C */ // char auto_reply[...EOF]; +} __attribute__((packed)); + struct C_CharacterData_V3_61_98 { /* 0000 */ PlayerInventory inventory; /* 034C */ PlayerDispDataDCPCV3 disp; diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 74652312..8f2a7655 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -2830,7 +2830,30 @@ static void on_61_98(shared_ptr c, uint16_t command, uint32_t flag, stri } break; } - case Version::GC_NTE: + case Version::GC_NTE: { + const auto& cmd = check_size_t(data, 0xFFFF); + c->game_data.last_reported_disp_v1_v2 = make_unique(cmd.disp); + + auto s = c->require_server_state(); + player->inventory = cmd.inventory; + player->disp = cmd.disp.to_bb(player->inventory.language, player->inventory.language); + player->battle_records = cmd.records.battle; + player->challenge_records = cmd.records.challenge; + player->choice_search_config = cmd.choice_search_config; + for (size_t z = 0; z < cmd.blocked_senders.size(); z++) { + c->game_data.blocked_senders.at(z) = cmd.blocked_senders[z]; + } + if (cmd.auto_reply_enabled) { + string auto_reply = data.substr(sizeof(cmd), 0xAC); + strip_trailing_zeroes(auto_reply); + string encoded = tt_decode_marked(auto_reply, player->inventory.language, false); + player->auto_reply.encode(encoded, player->inventory.language); + } else { + player->auto_reply.clear(); + } + break; + } + case Version::GC_V3: case Version::GC_EP3_TRIAL_EDITION: case Version::GC_EP3: @@ -2858,10 +2881,6 @@ static void on_61_98(shared_ptr c, uint16_t command, uint32_t flag, stri cmd = &check_size_t(data, 0xFFFF); } - if (c->version() == Version::GC_NTE) { - c->game_data.last_reported_disp_v1_v2 = make_unique(cmd->disp); - } - auto s = c->require_server_state(); // We use the flag field in this command to differentiate between Ep3 @@ -2894,7 +2913,7 @@ static void on_61_98(shared_ptr c, uint16_t command, uint32_t flag, stri player->disp = cmd->disp.to_bb(player->inventory.language, player->inventory.language); player->battle_records = cmd->records.battle; player->challenge_records = cmd->records.challenge; - // TODO: Parse choice search config + player->choice_search_config = cmd->choice_search_config; player->info_board.encode(cmd->info_board.decode(player->inventory.language), player->inventory.language); for (size_t z = 0; z < cmd->blocked_senders.size(); z++) { c->game_data.blocked_senders.at(z) = cmd->blocked_senders[z]; @@ -2915,7 +2934,7 @@ static void on_61_98(shared_ptr c, uint16_t command, uint32_t flag, stri // them (we sent the player data to the client in the first place) player->battle_records = cmd.records.battle; player->challenge_records = cmd.records.challenge; - // TODO: Parse choice search config + player->choice_search_config = cmd.choice_search_config; player->info_board = cmd.info_board; for (size_t z = 0; z < cmd.blocked_senders.size(); z++) { c->game_data.blocked_senders.at(z) = cmd.blocked_senders[z];