implement lobby assignment at login
This commit is contained in:
+1
-1
@@ -156,7 +156,7 @@ public:
|
|||||||
std::weak_ptr<Lobby> lobby;
|
std::weak_ptr<Lobby> lobby;
|
||||||
uint8_t lobby_client_id = 0;
|
uint8_t lobby_client_id = 0;
|
||||||
uint8_t lobby_arrow_color = 0;
|
uint8_t lobby_arrow_color = 0;
|
||||||
int64_t preferred_lobby_id = -1; // <0 = no preference
|
int64_t preferred_lobby_id = -1; // <0 = none chosen
|
||||||
|
|
||||||
asio::steady_timer save_game_data_timer;
|
asio::steady_timer save_game_data_timer;
|
||||||
asio::steady_timer send_ping_timer;
|
asio::steady_timer send_ping_timer;
|
||||||
|
|||||||
@@ -835,3 +835,35 @@ bool Lobby::compare_shared(const shared_ptr<const Lobby>& a, const shared_ptr<co
|
|||||||
|
|
||||||
return a->name < b->name;
|
return a->name < b->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
const char* phosg::name_for_enum<Lobby::JoinError>(Lobby::JoinError value) {
|
||||||
|
switch (value) {
|
||||||
|
case Lobby::JoinError::ALLOWED:
|
||||||
|
return "ALLOWED";
|
||||||
|
case Lobby::JoinError::FULL:
|
||||||
|
return "FULL";
|
||||||
|
case Lobby::JoinError::VERSION_CONFLICT:
|
||||||
|
return "VERSION_CONFLICT";
|
||||||
|
case Lobby::JoinError::QUEST_SELECTION_IN_PROGRESS:
|
||||||
|
return "QUEST_SELECTION_IN_PROGRESS";
|
||||||
|
case Lobby::JoinError::QUEST_IN_PROGRESS:
|
||||||
|
return "QUEST_IN_PROGRESS";
|
||||||
|
case Lobby::JoinError::BATTLE_IN_PROGRESS:
|
||||||
|
return "BATTLE_IN_PROGRESS";
|
||||||
|
case Lobby::JoinError::LOADING:
|
||||||
|
return "LOADING";
|
||||||
|
case Lobby::JoinError::SOLO:
|
||||||
|
return "SOLO";
|
||||||
|
case Lobby::JoinError::INCORRECT_PASSWORD:
|
||||||
|
return "INCORRECT_PASSWORD";
|
||||||
|
case Lobby::JoinError::LEVEL_TOO_LOW:
|
||||||
|
return "LEVEL_TOO_LOW";
|
||||||
|
case Lobby::JoinError::LEVEL_TOO_HIGH:
|
||||||
|
return "LEVEL_TOO_HIGH";
|
||||||
|
case Lobby::JoinError::NO_ACCESS_TO_QUEST:
|
||||||
|
return "NO_ACCESS_TO_QUEST";
|
||||||
|
default:
|
||||||
|
throw runtime_error("invalid drop mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+1
-3
@@ -279,6 +279,4 @@ struct Lobby : public std::enable_shared_from_this<Lobby> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
ServerDropMode phosg::enum_for_name<ServerDropMode>(const char* name);
|
const char* phosg::name_for_enum<Lobby::JoinError>(Lobby::JoinError value);
|
||||||
template <>
|
|
||||||
const char* phosg::name_for_enum<ServerDropMode>(ServerDropMode value);
|
|
||||||
|
|||||||
@@ -314,7 +314,13 @@ asio::awaitable<void> start_login_server_procedure(shared_ptr<Client> c) {
|
|||||||
s->ep3_tournament_index->link_client(c);
|
s->ep3_tournament_index->link_client(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->welcome_message.empty() ||
|
if (c->preferred_lobby_id >= 0) {
|
||||||
|
s->add_client_to_available_lobby(c, true);
|
||||||
|
if (c->require_lobby()->is_game()) {
|
||||||
|
c->set_flag(Client::Flag::LOADING);
|
||||||
|
c->log.info_f("LOADING flag set");
|
||||||
|
}
|
||||||
|
} else if (s->welcome_message.empty() ||
|
||||||
c->check_flag(Client::Flag::NO_D6) ||
|
c->check_flag(Client::Flag::NO_D6) ||
|
||||||
!c->check_flag(Client::Flag::AT_WELCOME_MESSAGE)) {
|
!c->check_flag(Client::Flag::AT_WELCOME_MESSAGE)) {
|
||||||
c->clear_flag(Client::Flag::AT_WELCOME_MESSAGE);
|
c->clear_flag(Client::Flag::AT_WELCOME_MESSAGE);
|
||||||
@@ -2527,7 +2533,7 @@ static asio::awaitable<void> on_10_main_menu(shared_ptr<Client> c, uint32_t item
|
|||||||
co_await send_get_player_info(c);
|
co_await send_get_player_info(c);
|
||||||
}
|
}
|
||||||
if (!c->lobby.lock()) {
|
if (!c->lobby.lock()) {
|
||||||
s->add_client_to_available_lobby(c);
|
s->add_client_to_available_lobby(c, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3093,7 +3099,7 @@ static asio::awaitable<void> on_84(shared_ptr<Client> c, Channel::Message& msg)
|
|||||||
// If the client isn't in any lobby, then they just left a game. Add them to the lobby they requested, but fall
|
// If the client isn't in any lobby, then they just left a game. Add them to the lobby they requested, but fall
|
||||||
// back to another lobby if it's full.
|
// back to another lobby if it's full.
|
||||||
c->preferred_lobby_id = cmd.item_id;
|
c->preferred_lobby_id = cmd.item_id;
|
||||||
s->add_client_to_available_lobby(c);
|
s->add_client_to_available_lobby(c, false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If the client already is in a lobby, then they're using the lobby teleporter; add them to the lobby they
|
// If the client already is in a lobby, then they're using the lobby teleporter; add them to the lobby they
|
||||||
|
|||||||
+33
-18
@@ -83,30 +83,45 @@ ServerState::ServerState(const string& config_filename, bool is_replay)
|
|||||||
bb_system_cache(new FileContentsCache(3600000000ULL)),
|
bb_system_cache(new FileContentsCache(3600000000ULL)),
|
||||||
gba_files_cache(new FileContentsCache(3600000000ULL)) {}
|
gba_files_cache(new FileContentsCache(3600000000ULL)) {}
|
||||||
|
|
||||||
void ServerState::add_client_to_available_lobby(shared_ptr<Client> c) {
|
void ServerState::add_client_to_available_lobby(shared_ptr<Client> c, bool allow_games) {
|
||||||
shared_ptr<Lobby> added_to_lobby;
|
shared_ptr<Lobby> added_to_lobby;
|
||||||
|
|
||||||
if (c->preferred_lobby_id >= 0) {
|
auto try_join_lobby = [&](uint32_t lobby_id) -> std::shared_ptr<Lobby> {
|
||||||
try {
|
auto l = this->find_lobby(lobby_id);
|
||||||
auto l = this->find_lobby(c->preferred_lobby_id);
|
if (!l) {
|
||||||
if (l && !l->is_game() && l->check_flag(Lobby::Flag::PUBLIC) && l->version_is_allowed(c->version())) {
|
c->log.info_f("Cannot join lobby {:08X}: lobby does not exist", lobby_id);
|
||||||
l->add_client(c);
|
return nullptr;
|
||||||
added_to_lobby = l;
|
|
||||||
}
|
|
||||||
} catch (const out_of_range&) {
|
|
||||||
}
|
}
|
||||||
|
if (!allow_games && l->is_game()) {
|
||||||
|
c->log.info_f("Cannot join lobby {:08X}: lobby is a game", lobby_id);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
static const std::string password = "";
|
||||||
|
auto join_error = l->join_error_for_client(c, &password);
|
||||||
|
if (join_error == Lobby::JoinError::ALLOWED) {
|
||||||
|
try {
|
||||||
|
l->add_client(c);
|
||||||
|
c->log.info_f("Joined lobby {:08X}", lobby_id);
|
||||||
|
return l;
|
||||||
|
} catch (const out_of_range& e) {
|
||||||
|
c->log.info_f("Cannot join lobby {:08X}: {}", lobby_id, e.what());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c->log.info_f("Cannot join lobby {:08X}: {}", lobby_id, phosg::name_for_enum(join_error));
|
||||||
|
return nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (c->preferred_lobby_id >= 0) {
|
||||||
|
added_to_lobby = try_join_lobby(c->preferred_lobby_id);
|
||||||
|
c->preferred_lobby_id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!added_to_lobby.get()) {
|
if (!added_to_lobby) {
|
||||||
for (const auto& lobby_id : this->public_lobby_search_order(c)) {
|
for (const auto& lobby_id : this->public_lobby_search_order(c)) {
|
||||||
try {
|
added_to_lobby = try_join_lobby(lobby_id);
|
||||||
auto l = this->find_lobby(lobby_id);
|
if (added_to_lobby) {
|
||||||
if (l && !l->is_game() && l->check_flag(Lobby::Flag::PUBLIC) && l->version_is_allowed(c->version())) {
|
break;
|
||||||
l->add_client(c);
|
|
||||||
added_to_lobby = l;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (const out_of_range&) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -316,7 +316,7 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
|
|||||||
ServerState& operator=(const ServerState&) = delete;
|
ServerState& operator=(const ServerState&) = delete;
|
||||||
ServerState& operator=(ServerState&&) = delete;
|
ServerState& operator=(ServerState&&) = delete;
|
||||||
|
|
||||||
void add_client_to_available_lobby(std::shared_ptr<Client> c);
|
void add_client_to_available_lobby(std::shared_ptr<Client> c, bool allow_games);
|
||||||
void remove_client_from_lobby(std::shared_ptr<Client> c);
|
void remove_client_from_lobby(std::shared_ptr<Client> c);
|
||||||
bool change_client_lobby(
|
bool change_client_lobby(
|
||||||
std::shared_ptr<Client> c,
|
std::shared_ptr<Client> c,
|
||||||
|
|||||||
Reference in New Issue
Block a user