handle BB not sending C6 after 08E8

This commit is contained in:
Martin Michelsen
2026-04-25 12:06:43 -07:00
parent 7a29b39771
commit 75e7232096
7 changed files with 46 additions and 26 deletions
+3 -3
View File
@@ -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);
}
}
+3 -3
View File
@@ -1235,12 +1235,12 @@ struct S_JoinGame_BB_64 : S_JoinGameT_DC_PC<PlayerLobbyDataBB> {
// 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<LobbyFlags_DCNTE, PlayerLobbyDataDCGC, PlayerDispDataDCPCV3>;
using S_JoinLobby_DCNTE_65_67_68 = S_JoinLobbyT<LobbyFlagsDCNTE, PlayerLobbyDataDCGC, PlayerDispDataDCPCV3>;
using S_JoinLobby_PC_65_67_68 = S_JoinLobbyT<LobbyFlags, PlayerLobbyDataPC, PlayerDispDataDCPCV3>;
using S_JoinLobby_DC_GC_65_67_68_Ep3_EB = S_JoinLobbyT<LobbyFlags, PlayerLobbyDataDCGC, PlayerDispDataDCPCV3>;
using S_JoinLobby_BB_65_67_68 = S_JoinLobbyT<LobbyFlags, PlayerLobbyDataBB, PlayerDispDataBB>;
+1 -1
View File
@@ -1645,7 +1645,7 @@ static asio::awaitable<HandlerResult> S_65_67_68_EB(shared_ptr<Client> 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;
+31 -11
View File
@@ -3769,7 +3769,7 @@ static asio::awaitable<void> on_E3_BB(shared_ptr<Client> c, Channel::Message& ms
static asio::awaitable<void> on_E8_BB(shared_ptr<Client> 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<void> on_E8_BB(shared_ptr<Client> c, Channel::Message& ms
}
case 0x07E8: { // Add blocked user
auto& new_gc = check_size_t<GuildCardBB>(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<void> on_E8_BB(shared_ptr<Client> c, Channel::Message& ms
}
case 0x08E8: { // Delete blocked user
auto& cmd = check_size_t<C_DeleteGuildCard_BB_05E8_08E8>(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<void> on_89(shared_ptr<Client> c, Channel::Message& msg)
static asio::awaitable<void> on_40(shared_ptr<Client> c, Channel::Message& msg) {
const auto& cmd = check_size_t<C_GuildCardSearch_40>(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;
}
+6 -6
View File
@@ -324,17 +324,17 @@ void PSOBBGuildCardFile::delete_duplicates() {
{
unordered_set<uint32_t> 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();
}
}
+1 -1
View File
@@ -994,7 +994,7 @@ struct PSOBBGuildCardFile {
} __packed_ws__(Entry, 0x1BC);
/* 0000 */ PSOBBMinimalSystemFile system_file;
/* 0114 */ parray<GuildCardBB, 0x1C> blocked;
/* 0114 */ parray<GuildCardBB, 0x1C> blocked_senders;
/* 1DF4 */ parray<uint8_t, 0x180> unknown_a2;
/* 1F74 */ parray<Entry, 0x69> entries;
/* D590 */
+1 -1
View File
@@ -260,7 +260,7 @@ shared_ptr<Client> 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);