From 6bebcc841e2b8cee41e5151a95b83b1ae4a8b64d Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sat, 7 Oct 2023 21:09:55 -0700 Subject: [PATCH] implement overflow lobbies --- TODO.md | 1 - src/Lobby.hh | 1 + src/ReceiveSubcommands.cc | 4 ++++ src/SendCommands.cc | 12 +++++++++--- src/ServerState.cc | 9 +++++++-- 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/TODO.md b/TODO.md index fdb9176e..371a7a32 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,6 @@ - Test PSOX (blocked on Insignia private server support) - Implement server-side drops on non-BB game versions - Find a way to silence audio in RunDOL.s -- Implement private and overflow lobbies - Encapsulate BB server-side random state and make replays deterministic - Implement character and inventory replacement for battle and challenge modes - Implement choice search diff --git a/src/Lobby.hh b/src/Lobby.hh index 7815d87a..c3d12605 100644 --- a/src/Lobby.hh +++ b/src/Lobby.hh @@ -45,6 +45,7 @@ struct Lobby : public std::enable_shared_from_this { PUBLIC = 0x01000000, DEFAULT = 0x02000000, V2_AND_LATER = 0x04000000, // Lobby does not appear on v1 + IS_OVERFLOW = 0x08000000, }; std::weak_ptr server_state; diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 6bc2821e..41096771 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -447,6 +447,10 @@ static void on_set_player_visibility(shared_ptr c, uint8_t command, uint if (!l->is_game() && !(c->flags & Client::Flag::IS_DC_V1)) { send_arrow_update(l); } + if (!l->is_game() && (l->flags & Lobby::Flag::IS_OVERFLOW)) { + send_message_box(c, u"$C6All lobbies are full.\n\n$C7You are in a private lobby. You can use the\nteleporter to join other lobbies if there is space\navailable."); + send_lobby_message_box(c, u""); + } } } diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 2ca0f309..d2abbc12 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -1674,9 +1674,15 @@ void send_join_lobby_t(shared_ptr c, shared_ptr l, send_player_records_t(c, l, joining_client); } - uint8_t lobby_type = (c->options.override_lobby_number >= 0) - ? c->options.override_lobby_number - : l->block - 1; + uint8_t lobby_type; + if (c->options.override_lobby_number >= 0) { + lobby_type = c->options.override_lobby_number; + } else if (l->flags & Lobby::Flag::IS_OVERFLOW) { + lobby_type = (c->flags & Client::Flag::IS_EPISODE_3) ? 15 : 0; + } else { + lobby_type = l->block - 1; + } + // Allow non-canonical lobby types on GC. They may work on other versions too, // but I haven't verified which values don't crash on each version. if (c->version() == GameVersion::GC) { diff --git a/src/ServerState.cc b/src/ServerState.cc index b5ae7b30..8c99a2bd 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -147,8 +147,13 @@ void ServerState::add_client_to_available_lobby(shared_ptr c) { } if (!added_to_lobby) { - // TODO: Add the user to a dynamically-created private lobby instead - throw out_of_range("all lobbies full"); + added_to_lobby = this->create_lobby(); + added_to_lobby->flags |= Lobby::Flag::PUBLIC | Lobby::Flag::IS_OVERFLOW; + added_to_lobby->block = 100; + added_to_lobby->name = u"Overflow"; + added_to_lobby->max_clients = 12; + added_to_lobby->event = this->pre_lobby_event; + added_to_lobby->add_client(c); } // Send a join message to the joining player, and notifications to all others