diff --git a/src/server.cpp b/src/server.cpp index 0a5300f5f..1556de406 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1168,24 +1168,25 @@ void Server::yieldToOtherThreads(float dtime) g_profiler->avg("Server::yieldTo...() progress [#]", qs_initial - qs); } -PlayerSAO* Server::StageTwoClientInit(session_t peer_id) +PlayerSAO *Server::StageTwoClientInit(session_t peer_id) { std::string playername; - PlayerSAO *playersao = NULL; + std::unique_ptr sao; { ClientInterface::AutoLock clientlock(m_clients); RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone); if (client) { playername = client->getName(); - playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version); + sao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version); } } - RemotePlayer *player = m_env->getPlayer(playername.c_str(), true); + RemotePlayer *player = sao ? sao->getPlayer() : nullptr; // If failed, cancel - if (!playersao || !player) { - if (player && player->getPeerId() != PEER_ID_INEXISTENT) { + if (!player) { + RemotePlayer *joined = m_env->getPlayer(playername.c_str()); + if (joined && joined->getPeerId() != PEER_ID_INEXISTENT) { actionstream << "Server: Failed to emerge player \"" << playername << "\" (player allocated to another client)" << std::endl; DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED); @@ -1197,6 +1198,19 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id) return nullptr; } + // Add player to environment + m_env->addPlayer(player); + + /* Clean up old HUD elements from previous sessions */ + player->clearHud(); + + /* Add object to environment */ + PlayerSAO *playersao = sao.get(); + m_env->addActiveObject(std::move(sao)); + + if (playersao->isNewPlayer()) + m_script->on_newplayer(playersao); + /* Send complete position information */ @@ -3229,9 +3243,7 @@ void Server::reportPrivsModified(const std::string &name) PlayerSAO *sao = player->getPlayerSAO(); if(!sao) return; - sao->updatePrivileges( - getPlayerEffectivePrivs(name), - isSingleplayer()); + sao->updatePrivileges(getPlayerEffectivePrivs(name)); } } @@ -3965,7 +3977,8 @@ void Server::requestShutdown(const std::string &msg, bool reconnect, float delay m_shutdown_state.trigger(delay, msg, reconnect); } -PlayerSAO* Server::emergePlayer(const char *name, session_t peer_id, u16 proto_version) +std::unique_ptr Server::emergePlayer(const char *name, session_t peer_id, + u16 proto_version) { /* Try to get an existing player @@ -4008,20 +4021,13 @@ PlayerSAO* Server::emergePlayer(const char *name, session_t peer_id, u16 proto_v player = new RemotePlayer(name, idef()); } - bool newplayer = false; - // Load player - PlayerSAO *playersao = m_env->loadPlayer(player, &newplayer, peer_id, isSingleplayer()); + auto playersao = m_env->loadPlayer(player, peer_id); // Complete init with server parts playersao->finalize(player, getPlayerEffectivePrivs(player->getName())); player->protocol_version = proto_version; - /* Run scripts */ - if (newplayer) { - m_script->on_newplayer(playersao); - } - return playersao; } diff --git a/src/server.h b/src/server.h index a9ba35c63..560a3452d 100644 --- a/src/server.h +++ b/src/server.h @@ -194,7 +194,9 @@ public: void Receive(float min_time); void yieldToOtherThreads(float dtime); - PlayerSAO* StageTwoClientInit(session_t peer_id); + // Full player initialization after they processed all static media + // This is a helper function for TOSERVER_CLIENT_READY + PlayerSAO *StageTwoClientInit(session_t peer_id); /* * Command Handlers @@ -626,7 +628,8 @@ private: Call with env and con locked. */ - PlayerSAO *emergePlayer(const char *name, session_t peer_id, u16 proto_version); + std::unique_ptr emergePlayer(const char *name, session_t peer_id, + u16 proto_version); /* Variables diff --git a/src/server/player_sao.h b/src/server/player_sao.h index a792f0c11..0ce26f7cc 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -156,12 +156,14 @@ public: // Other - void updatePrivileges(const std::set &privs, bool is_singleplayer) + void updatePrivileges(const std::set &privs) { m_privs = privs; - m_is_singleplayer = is_singleplayer; } + inline void setNewPlayer() { m_is_new_player = true; } + inline bool isNewPlayer() { return m_is_new_player; } + bool getCollisionBox(aabb3f *toset) const override; bool getSelectionBox(aabb3f *toset) const override; bool collideWithObjects() const override { return true; } @@ -202,7 +204,8 @@ private: // Cached privileges for enforcement std::set m_privs; - bool m_is_singleplayer; + const bool m_is_singleplayer; + bool m_is_new_player = false; u16 m_breath = PLAYER_MAX_BREATH_DEFAULT; f32 m_pitch = 0.0f; diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 44645ca34..3c985e1b9 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -667,13 +667,13 @@ void ServerEnvironment::savePlayer(RemotePlayer *player) } } -PlayerSAO *ServerEnvironment::loadPlayer(RemotePlayer *player, bool *new_player, - session_t peer_id, bool is_singleplayer) +std::unique_ptr ServerEnvironment::loadPlayer(RemotePlayer *player, session_t peer_id) { - auto playersao = std::make_unique(this, player, peer_id, is_singleplayer); + auto playersao = std::make_unique(this, player, peer_id, m_server->isSingleplayer()); // Create player if it doesn't exist if (!m_player_database->loadPlayer(player, playersao.get())) { - *new_player = true; + playersao->setNewPlayer(); + // Set player position infostream << "Server: Finding spawn place for player \"" << player->getName() << "\"" << std::endl; @@ -692,20 +692,10 @@ PlayerSAO *ServerEnvironment::loadPlayer(RemotePlayer *player, bool *new_player, } } - // Add player to environment - addPlayer(player); - - /* Clean up old HUD elements from previous sessions */ - player->clearHud(); - - /* Add object to environment */ - PlayerSAO *ret = playersao.get(); - addActiveObject(std::move(playersao)); - // Update active blocks quickly for a bit so objects in those blocks appear on the client m_fast_active_block_divider = 10; - return ret; + return playersao; } void ServerEnvironment::saveMeta() diff --git a/src/serverenvironment.h b/src/serverenvironment.h index 42f777dde..89d33d9bf 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -240,8 +240,7 @@ public: // Save players void saveLoadedPlayers(bool force = false); void savePlayer(RemotePlayer *player); - PlayerSAO *loadPlayer(RemotePlayer *player, bool *new_player, session_t peer_id, - bool is_singleplayer); + std::unique_ptr loadPlayer(RemotePlayer *player, session_t peer_id); void addPlayer(RemotePlayer *player); void removePlayer(RemotePlayer *player); bool removePlayerFromDatabase(const std::string &name);