From d3ff50918fda0ae0047596c1047e9b2b973ed37e Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sat, 2 Apr 2022 15:14:21 -0700 Subject: [PATCH] add safety for erroneous AC commands from clients --- src/Client.hh | 6 ++++-- src/Lobby.cc | 2 +- src/ReceiveCommands.cc | 12 +++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Client.hh b/src/Client.hh index 5e93eb12..43c8de0d 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -58,10 +58,12 @@ struct Client { DCV1 = 0x0010, // Client is loading into a game LOADING = 0x0020, + // Client is loading a quest + LOADING_QUEST = 0x0040, // Client is in the information menu (login server only) - IN_INFORMATION_MENU = 0x0040, + IN_INFORMATION_MENU = 0x0080, // Client is at the welcome message (login server only) - AT_WELCOME_MESSAGE = 0x0080, + AT_WELCOME_MESSAGE = 0x0100, // Note: There isn't a good way to detect Episode 3 until the player data is // sent (via a 61 command), so the IS_EPISODE_3 flag is set in that handler diff --git a/src/Lobby.cc b/src/Lobby.cc index 040fe3c6..9c75281a 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -41,7 +41,7 @@ bool Lobby::any_client_loading() const { if (!this->clients[x].get()) { continue; } - if (this->clients[x]->flags & Client::Flag::LOADING) { + if (this->clients[x]->flags & (Client::Flag::LOADING | Client::Flag::LOADING_QUEST)) { return true; } } diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index a5deef01..11d96c91 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -894,7 +894,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, send_quest_file(l->clients[x], bin_basename, *bin_contents, false, false); send_quest_file(l->clients[x], dat_basename, *dat_contents, false, false); - l->clients[x]->flags |= Client::Flag::LOADING; + l->clients[x]->flags |= Client::Flag::LOADING_QUEST; } } else { @@ -1012,7 +1012,13 @@ void process_quest_ready(shared_ptr s, shared_ptr c, return; } - c->flags &= ~Client::Flag::LOADING; + // If this client is NOT loading, they should not send an AC. Sending an AC to + // a client that isn't waiting to start a quest will crash the client, so we + // have to be careful not to do so. + if (!(c->flags & Client::Flag::LOADING_QUEST)) { + return; + } + c->flags &= ~Client::Flag::LOADING_QUEST; // check if any client is still loading // TODO: we need to handle clients disconnecting while loading. probably @@ -1022,7 +1028,7 @@ void process_quest_ready(shared_ptr s, shared_ptr c, if (!l->clients[x]) { continue; } - if (l->clients[x]->flags & Client::Flag::LOADING) { + if (l->clients[x]->flags & Client::Flag::LOADING_QUEST) { break; } }