From 75e723209626cbeb810fe81a921b079c68537e02 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sat, 25 Apr 2026 12:06:43 -0700 Subject: [PATCH] handle BB not sending C6 after 08E8 --- src/Client.cc | 6 +++--- src/CommandFormats.hh | 6 +++--- src/ProxyCommands.cc | 2 +- src/ReceiveCommands.cc | 42 +++++++++++++++++++++++++++++++----------- src/SaveFileFormats.cc | 12 ++++++------ src/SaveFileFormats.hh | 2 +- src/ServerState.cc | 2 +- 7 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/Client.cc b/src/Client.cc index 633b043e..3c0e9745 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -1008,9 +1008,9 @@ void Client::load_all_files() { auto stack_limits = s->item_stack_limits(this->version()); this->blocked_senders.clear(); - for (size_t z = 0; z < this->guild_card_data->blocked.size(); z++) { - if (this->guild_card_data->blocked[z].present) { - this->blocked_senders.emplace(this->guild_card_data->blocked[z].guild_card_number); + for (size_t z = 0; z < this->guild_card_data->blocked_senders.size(); z++) { + if (this->guild_card_data->blocked_senders[z].present) { + this->blocked_senders.emplace(this->guild_card_data->blocked_senders[z].guild_card_number); } } diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index c710b855..e394edf0 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -1235,12 +1235,12 @@ struct S_JoinGame_BB_64 : S_JoinGameT_DC_PC { // Similarly to 64, the client will ignore 64 and 65 commands while loading, and will buffer all other commands except // 1D until loading is done. -struct LobbyFlags_DCNTE { +struct LobbyFlagsDCNTE { uint8_t client_id = 0; uint8_t leader_id = 0; uint8_t disable_udp = 1; uint8_t unused = 0; -} __packed_ws__(LobbyFlags_DCNTE, 4); +} __packed_ws__(LobbyFlagsDCNTE, 4); struct LobbyFlags { uint8_t client_id = 0; @@ -1274,7 +1274,7 @@ struct S_JoinLobbyT { return offsetof(S_JoinLobbyT, entries) + used_entries * sizeof(Entry); } } __attribute__((packed)); -using S_JoinLobby_DCNTE_65_67_68 = S_JoinLobbyT; +using S_JoinLobby_DCNTE_65_67_68 = S_JoinLobbyT; using S_JoinLobby_PC_65_67_68 = S_JoinLobbyT; using S_JoinLobby_DC_GC_65_67_68_Ep3_EB = S_JoinLobbyT; using S_JoinLobby_BB_65_67_68 = S_JoinLobbyT; diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index e739f9bb..70ed72a8 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -1645,7 +1645,7 @@ static asio::awaitable S_65_67_68_EB(shared_ptr c, Channe c->log.warning_f("Proxied player appears multiple times in lobby"); } - if constexpr (sizeof(cmd.lobby_flags) > sizeof(LobbyFlags_DCNTE)) { + if constexpr (sizeof(cmd.lobby_flags) > sizeof(LobbyFlagsDCNTE)) { c->proxy_session->lobby_event = cmd.lobby_flags.event; if (c->override_lobby_event != 0xFF) { cmd.lobby_flags.event = c->override_lobby_event; diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 1d0a8fd5..3441313f 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -3769,7 +3769,7 @@ static asio::awaitable on_E3_BB(shared_ptr c, Channel::Message& ms static asio::awaitable on_E8_BB(shared_ptr c, Channel::Message& msg) { constexpr size_t max_count = sizeof(PSOBBGuildCardFile::entries) / sizeof(PSOBBGuildCardFile::Entry); - constexpr size_t max_blocked = sizeof(PSOBBGuildCardFile::blocked) / sizeof(GuildCardBB); + constexpr size_t max_blocked_senders = sizeof(PSOBBGuildCardFile::blocked_senders) / sizeof(GuildCardBB); auto gcf = c->guild_card_file(); bool should_save = false; switch (msg.command) { @@ -3833,11 +3833,12 @@ static asio::awaitable on_E8_BB(shared_ptr c, Channel::Message& ms } case 0x07E8: { // Add blocked user auto& new_gc = check_size_t(msg.data); - for (size_t z = 0; z < max_blocked; z++) { - auto& gcf_blocked = gcf->blocked[z]; - if (!gcf_blocked.present) { - gcf_blocked = new_gc; + for (size_t z = 0; z < max_blocked_senders; z++) { + auto& gcf_blocked_senders = gcf->blocked_senders[z]; + if (!gcf_blocked_senders.present) { + gcf_blocked_senders = new_gc; c->log.info_f("Added blocked guild card {} at position {}", new_gc.guild_card_number, z); + c->blocked_senders.emplace(new_gc.guild_card_number); should_save = true; break; } @@ -3846,14 +3847,15 @@ static asio::awaitable on_E8_BB(shared_ptr c, Channel::Message& ms } case 0x08E8: { // Delete blocked user auto& cmd = check_size_t(msg.data); - for (size_t z = 0; z < max_blocked; z++) { - auto& gcf_blocked = gcf->blocked[z]; - if (gcf_blocked.guild_card_number == cmd.guild_card_number) { + for (size_t z = 0; z < max_blocked_senders; z++) { + auto& gcf_blocked_senders = gcf->blocked_senders[z]; + if (gcf_blocked_senders.guild_card_number == cmd.guild_card_number) { c->log.info_f("Deleted blocked guild card {} at position {}", cmd.guild_card_number, z); - for (z = 0; z < max_blocked - 1; z++) { - gcf_blocked = gcf->blocked[z + 1]; + for (z = 0; z < max_blocked_senders - 1; z++) { + gcf_blocked_senders = gcf->blocked_senders[z + 1]; } - gcf->blocked[max_blocked - 1].clear(); + gcf->blocked_senders[max_blocked_senders - 1].clear(); + c->blocked_senders.erase(cmd.guild_card_number); should_save = true; break; } @@ -4192,16 +4194,34 @@ static asio::awaitable on_89(shared_ptr c, Channel::Message& msg) static asio::awaitable on_40(shared_ptr c, Channel::Message& msg) { const auto& cmd = check_size_t(msg.data); + if (!c->login) { + throw std::logic_error("Login required for 40 command"); + } + if (cmd.searcher_guild_card_number != c->login->account->account_id) { + throw std::runtime_error(std::format( + "Client sent incorrect source Guild Card number ({:08X}) in card search", + cmd.searcher_guild_card_number.load())); + } try { auto s = c->require_server_state(); auto result = s->find_client(nullptr, cmd.target_guild_card_number); if (!result->blocked_senders.count(c->login->account->account_id)) { auto result_lobby = result->lobby.lock(); if (result_lobby) { + c->log.info_f("Guild Card search ({} for {}) found {}", + cmd.searcher_guild_card_number.load(), cmd.target_guild_card_number.load(), result->channel->name); send_card_search_result(c, result, result_lobby); + } else { + c->log.info_f("Guild Card search ({} for {}) found {} but player is not in any lobby", + cmd.searcher_guild_card_number.load(), cmd.target_guild_card_number.load(), result->channel->name); } + } else { + c->log.info_f("Guild Card search ({} for {}) found {} but searcher is blocked", + cmd.searcher_guild_card_number.load(), cmd.target_guild_card_number.load(), result->channel->name); } } catch (const out_of_range&) { + c->log.info_f("Guild Card search ({} for {}) did not find any player", + cmd.searcher_guild_card_number.load(), cmd.target_guild_card_number.load()); } co_return; } diff --git a/src/SaveFileFormats.cc b/src/SaveFileFormats.cc index 4f4aea4c..a8ea88d8 100644 --- a/src/SaveFileFormats.cc +++ b/src/SaveFileFormats.cc @@ -324,17 +324,17 @@ void PSOBBGuildCardFile::delete_duplicates() { { unordered_set seen; size_t read_index = 0, write_index = 0; - for (read_index = 0; read_index < this->blocked.size(); read_index++) { - const auto& read_blocked = this->blocked[read_index]; - if (seen.emplace(read_blocked.guild_card_number).second) { + for (read_index = 0; read_index < this->blocked_senders.size(); read_index++) { + const auto& read_blocked_senders = this->blocked_senders[read_index]; + if (seen.emplace(read_blocked_senders.guild_card_number).second) { if (write_index != read_index) { - this->blocked[write_index] = read_blocked; + this->blocked_senders[write_index] = read_blocked_senders; } write_index++; } } - for (; write_index < this->blocked.size(); write_index++) { - this->blocked[write_index].clear(); + for (; write_index < this->blocked_senders.size(); write_index++) { + this->blocked_senders[write_index].clear(); } } diff --git a/src/SaveFileFormats.hh b/src/SaveFileFormats.hh index 6a5b2443..34354f10 100644 --- a/src/SaveFileFormats.hh +++ b/src/SaveFileFormats.hh @@ -994,7 +994,7 @@ struct PSOBBGuildCardFile { } __packed_ws__(Entry, 0x1BC); /* 0000 */ PSOBBMinimalSystemFile system_file; - /* 0114 */ parray blocked; + /* 0114 */ parray blocked_senders; /* 1DF4 */ parray unknown_a2; /* 1F74 */ parray entries; /* D590 */ diff --git a/src/ServerState.cc b/src/ServerState.cc index bd6923ef..a6897cfe 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -260,7 +260,7 @@ shared_ptr ServerState::find_client(const string* identifier, uint64_t a for (auto& other_l : this->all_lobbies()) { if (l == other_l) { - continue; // don't bother looking again + continue; // Don't bother looking again } try { return other_l->find_client(identifier, account_id);