fix item ID conflicts in lobbies

This commit is contained in:
Martin Michelsen
2023-12-28 11:29:09 -08:00
parent b6cfb5b2a2
commit 0bd3bb7b77
13 changed files with 155 additions and 149 deletions
+1 -1
View File
@@ -590,7 +590,7 @@ static void server_command_persist(shared_ptr<Client> c, const std::string&) {
auto l = c->require_lobby();
if (l->check_flag(Lobby::Flag::DEFAULT)) {
send_text_message(c, "$C6Default lobbies\ncannot be marked\ntemporary");
} else if (!l->check_flag(Lobby::Flag::GAME)) {
} else if (!l->is_game()) {
send_text_message(c, "$C6Private lobbies\ncannot be marked\npersistent");
} else if (l->check_flag(Lobby::Flag::QUEST_IN_PROGRESS) || l->check_flag(Lobby::Flag::JOINABLE_QUEST_IN_PROGRESS)) {
send_text_message(c, "$C6Games cannot be\npersistent if a\nquest has already\nbegun");
+14 -8
View File
@@ -135,9 +135,9 @@ uint32_t Lobby::FloorItemManager::reassign_all_item_ids(uint32_t next_item_id) {
return next_item_id;
}
Lobby::Lobby(shared_ptr<ServerState> s, uint32_t id)
Lobby::Lobby(shared_ptr<ServerState> s, uint32_t id, bool is_game)
: server_state(s),
log(string_printf("[Lobby:%" PRIX32 "] ", id), lobby_log.min_level),
log(string_printf("[%s:%" PRIX32 "] ", is_game ? "Game" : "Lobby", id), lobby_log.min_level),
lobby_id(id),
min_level(0),
max_level(0xFFFFFFFF),
@@ -162,15 +162,24 @@ Lobby::Lobby(shared_ptr<ServerState> s, uint32_t id)
event_new(s->base.get(), -1, EV_TIMEOUT | EV_PERSIST, &Lobby::dispatch_on_idle_timeout, this),
event_free) {
this->log.info("Created");
for (size_t x = 0; x < 12; x++) {
this->next_item_id_for_client[x] = 0x00010000 + 0x00200000 * x;
if (is_game) {
this->set_flag(Flag::GAME);
}
this->reset_next_item_ids();
}
Lobby::~Lobby() {
this->log.info("Deleted");
}
void Lobby::reset_next_item_ids() {
uint32_t base_item_id = this->is_game() ? 0x00010000 : 0x10010000;
for (size_t x = 0; x < 12; x++) {
this->next_item_id_for_client[x] = base_item_id + 0x00200000 * x;
}
this->next_game_item_id = 0xCC000000;
}
shared_ptr<ServerState> Lobby::require_server_state() const {
auto s = this->server_state.lock();
if (!s) {
@@ -468,10 +477,7 @@ void Lobby::add_client(shared_ptr<Client> c, ssize_t required_client_id) {
// If this is a lobby or no one was here before this, reassign all the floor
// item IDs and reset the next item IDs
if (!this->is_game() || (leader_index >= this->max_clients)) {
for (size_t x = 0; x < 12; x++) {
this->next_item_id_for_client[x] = 0x00010000 + 0x00200000 * x;
}
this->next_game_item_id = 0xCC000000;
this->reset_next_item_ids();
for (auto& m : this->floor_item_managers) {
this->next_game_item_id = m.reassign_all_item_ids(this->next_game_item_id);
}
+3 -1
View File
@@ -169,13 +169,15 @@ struct Lobby : public std::enable_shared_from_this<Lobby> {
uint64_t idle_timeout_usecs;
std::unique_ptr<struct event, void (*)(struct event*)> idle_timeout_event;
Lobby(std::shared_ptr<ServerState> s, uint32_t id);
Lobby(std::shared_ptr<ServerState> s, uint32_t id, bool is_game);
Lobby(const Lobby&) = delete;
Lobby(Lobby&&) = delete;
~Lobby();
Lobby& operator=(const Lobby&) = delete;
Lobby& operator=(Lobby&&) = delete;
void reset_next_item_ids();
[[nodiscard]] inline bool check_flag(Flag flag) const {
return !!(this->enabled_flags & static_cast<uint32_t>(flag));
}
+1 -3
View File
@@ -3955,10 +3955,8 @@ shared_ptr<Lobby> create_game_generic(
return nullptr;
}
shared_ptr<Lobby> game = s->create_lobby();
shared_ptr<Lobby> game = s->create_lobby(true);
game->name = name;
game->set_flag(Lobby::Flag::GAME);
game->base_version = c->version();
game->allowed_versions = 0;
switch (game->base_version) {
+4 -4
View File
@@ -93,7 +93,7 @@ void ServerState::init() {
bool allow_v1 = (x <= 9);
bool allow_non_ep3 = (x <= 14);
shared_ptr<Lobby> l = this->create_lobby();
shared_ptr<Lobby> l = this->create_lobby(false);
l->set_flag(Lobby::Flag::PUBLIC);
l->set_flag(Lobby::Flag::DEFAULT);
l->set_flag(Lobby::Flag::PERSISTENT);
@@ -190,7 +190,7 @@ void ServerState::add_client_to_available_lobby(shared_ptr<Client> c) {
}
if (!added_to_lobby) {
added_to_lobby = this->create_lobby();
added_to_lobby = this->create_lobby(false);
added_to_lobby->set_flag(Lobby::Flag::PUBLIC);
added_to_lobby->set_flag(Lobby::Flag::IS_OVERFLOW);
added_to_lobby->block = 100;
@@ -278,11 +278,11 @@ vector<shared_ptr<Lobby>> ServerState::all_lobbies() {
return ret;
}
shared_ptr<Lobby> ServerState::create_lobby() {
shared_ptr<Lobby> ServerState::create_lobby(bool is_game) {
while (this->id_to_lobby.count(this->next_lobby_id)) {
this->next_lobby_id++;
}
auto l = make_shared<Lobby>(this->shared_from_this(), this->next_lobby_id++);
auto l = make_shared<Lobby>(this->shared_from_this(), this->next_lobby_id++, is_game);
this->id_to_lobby.emplace(l->lobby_id, l);
l->idle_timeout_usecs = this->persistent_game_idle_timeout_usecs;
return l;
+1 -1
View File
@@ -245,7 +245,7 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
std::shared_ptr<Lobby> find_lobby(uint32_t lobby_id);
std::vector<std::shared_ptr<Lobby>> all_lobbies();
std::shared_ptr<Lobby> create_lobby();
std::shared_ptr<Lobby> create_lobby(bool is_game);
void remove_lobby(std::shared_ptr<Lobby> l);
void on_player_left_lobby(std::shared_ptr<Lobby> l, uint8_t leaving_client_id);