mirror of
https://github.com/minetest/minetest.git
synced 2025-01-09 23:07:31 +01:00
Reorder client initialization (#15554)
Previously, ServerEnv created a player instance before they're fully initialized. This commit moves all initialization steps and callbacks into TOSERVER_CLIENT_READY ^ which includes StageTwoClientInit for player loading or creation
This commit is contained in:
parent
c49ff76955
commit
d1dd044455
@ -1168,24 +1168,25 @@ void Server::yieldToOtherThreads(float dtime)
|
|||||||
g_profiler->avg("Server::yieldTo...() progress [#]", qs_initial - qs);
|
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;
|
std::string playername;
|
||||||
PlayerSAO *playersao = NULL;
|
std::unique_ptr<PlayerSAO> sao;
|
||||||
{
|
{
|
||||||
ClientInterface::AutoLock clientlock(m_clients);
|
ClientInterface::AutoLock clientlock(m_clients);
|
||||||
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
|
RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
|
||||||
if (client) {
|
if (client) {
|
||||||
playername = client->getName();
|
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 failed, cancel
|
||||||
if (!playersao || !player) {
|
if (!player) {
|
||||||
if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
|
RemotePlayer *joined = m_env->getPlayer(playername.c_str());
|
||||||
|
if (joined && joined->getPeerId() != PEER_ID_INEXISTENT) {
|
||||||
actionstream << "Server: Failed to emerge player \"" << playername
|
actionstream << "Server: Failed to emerge player \"" << playername
|
||||||
<< "\" (player allocated to another client)" << std::endl;
|
<< "\" (player allocated to another client)" << std::endl;
|
||||||
DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED);
|
DenyAccess(peer_id, SERVER_ACCESSDENIED_ALREADY_CONNECTED);
|
||||||
@ -1197,6 +1198,19 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
|
|||||||
return nullptr;
|
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
|
Send complete position information
|
||||||
*/
|
*/
|
||||||
@ -3229,9 +3243,7 @@ void Server::reportPrivsModified(const std::string &name)
|
|||||||
PlayerSAO *sao = player->getPlayerSAO();
|
PlayerSAO *sao = player->getPlayerSAO();
|
||||||
if(!sao)
|
if(!sao)
|
||||||
return;
|
return;
|
||||||
sao->updatePrivileges(
|
sao->updatePrivileges(getPlayerEffectivePrivs(name));
|
||||||
getPlayerEffectivePrivs(name),
|
|
||||||
isSingleplayer());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3965,7 +3977,8 @@ void Server::requestShutdown(const std::string &msg, bool reconnect, float delay
|
|||||||
m_shutdown_state.trigger(delay, msg, reconnect);
|
m_shutdown_state.trigger(delay, msg, reconnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerSAO* Server::emergePlayer(const char *name, session_t peer_id, u16 proto_version)
|
std::unique_ptr<PlayerSAO> Server::emergePlayer(const char *name, session_t peer_id,
|
||||||
|
u16 proto_version)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Try to get an existing player
|
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());
|
player = new RemotePlayer(name, idef());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool newplayer = false;
|
|
||||||
|
|
||||||
// Load player
|
// 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
|
// Complete init with server parts
|
||||||
playersao->finalize(player, getPlayerEffectivePrivs(player->getName()));
|
playersao->finalize(player, getPlayerEffectivePrivs(player->getName()));
|
||||||
player->protocol_version = proto_version;
|
player->protocol_version = proto_version;
|
||||||
|
|
||||||
/* Run scripts */
|
|
||||||
if (newplayer) {
|
|
||||||
m_script->on_newplayer(playersao);
|
|
||||||
}
|
|
||||||
|
|
||||||
return playersao;
|
return playersao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,9 @@ public:
|
|||||||
void Receive(float min_time);
|
void Receive(float min_time);
|
||||||
void yieldToOtherThreads(float dtime);
|
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
|
* Command Handlers
|
||||||
@ -626,7 +628,8 @@ private:
|
|||||||
|
|
||||||
Call with env and con locked.
|
Call with env and con locked.
|
||||||
*/
|
*/
|
||||||
PlayerSAO *emergePlayer(const char *name, session_t peer_id, u16 proto_version);
|
std::unique_ptr<PlayerSAO> emergePlayer(const char *name, session_t peer_id,
|
||||||
|
u16 proto_version);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Variables
|
Variables
|
||||||
|
@ -156,12 +156,14 @@ public:
|
|||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
||||||
void updatePrivileges(const std::set<std::string> &privs, bool is_singleplayer)
|
void updatePrivileges(const std::set<std::string> &privs)
|
||||||
{
|
{
|
||||||
m_privs = 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 getCollisionBox(aabb3f *toset) const override;
|
||||||
bool getSelectionBox(aabb3f *toset) const override;
|
bool getSelectionBox(aabb3f *toset) const override;
|
||||||
bool collideWithObjects() const override { return true; }
|
bool collideWithObjects() const override { return true; }
|
||||||
@ -202,7 +204,8 @@ private:
|
|||||||
|
|
||||||
// Cached privileges for enforcement
|
// Cached privileges for enforcement
|
||||||
std::set<std::string> m_privs;
|
std::set<std::string> m_privs;
|
||||||
bool m_is_singleplayer;
|
const bool m_is_singleplayer;
|
||||||
|
bool m_is_new_player = false;
|
||||||
|
|
||||||
u16 m_breath = PLAYER_MAX_BREATH_DEFAULT;
|
u16 m_breath = PLAYER_MAX_BREATH_DEFAULT;
|
||||||
f32 m_pitch = 0.0f;
|
f32 m_pitch = 0.0f;
|
||||||
|
@ -667,13 +667,13 @@ void ServerEnvironment::savePlayer(RemotePlayer *player)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerSAO *ServerEnvironment::loadPlayer(RemotePlayer *player, bool *new_player,
|
std::unique_ptr<PlayerSAO> ServerEnvironment::loadPlayer(RemotePlayer *player, session_t peer_id)
|
||||||
session_t peer_id, bool is_singleplayer)
|
|
||||||
{
|
{
|
||||||
auto playersao = std::make_unique<PlayerSAO>(this, player, peer_id, is_singleplayer);
|
auto playersao = std::make_unique<PlayerSAO>(this, player, peer_id, m_server->isSingleplayer());
|
||||||
// Create player if it doesn't exist
|
// Create player if it doesn't exist
|
||||||
if (!m_player_database->loadPlayer(player, playersao.get())) {
|
if (!m_player_database->loadPlayer(player, playersao.get())) {
|
||||||
*new_player = true;
|
playersao->setNewPlayer();
|
||||||
|
|
||||||
// Set player position
|
// Set player position
|
||||||
infostream << "Server: Finding spawn place for player \""
|
infostream << "Server: Finding spawn place for player \""
|
||||||
<< player->getName() << "\"" << std::endl;
|
<< 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
|
// Update active blocks quickly for a bit so objects in those blocks appear on the client
|
||||||
m_fast_active_block_divider = 10;
|
m_fast_active_block_divider = 10;
|
||||||
|
|
||||||
return ret;
|
return playersao;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerEnvironment::saveMeta()
|
void ServerEnvironment::saveMeta()
|
||||||
|
@ -240,8 +240,7 @@ public:
|
|||||||
// Save players
|
// Save players
|
||||||
void saveLoadedPlayers(bool force = false);
|
void saveLoadedPlayers(bool force = false);
|
||||||
void savePlayer(RemotePlayer *player);
|
void savePlayer(RemotePlayer *player);
|
||||||
PlayerSAO *loadPlayer(RemotePlayer *player, bool *new_player, session_t peer_id,
|
std::unique_ptr<PlayerSAO> loadPlayer(RemotePlayer *player, session_t peer_id);
|
||||||
bool is_singleplayer);
|
|
||||||
void addPlayer(RemotePlayer *player);
|
void addPlayer(RemotePlayer *player);
|
||||||
void removePlayer(RemotePlayer *player);
|
void removePlayer(RemotePlayer *player);
|
||||||
bool removePlayerFromDatabase(const std::string &name);
|
bool removePlayerFromDatabase(const std::string &name);
|
||||||
|
Loading…
Reference in New Issue
Block a user