From 054a89dd9e5d6819adede9d7ba781b69f98ff2f4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 6 Jan 2021 00:35:42 +0000 Subject: Clarify cClientHandle, cPlayer ownership semantics + A cPlayer, once created, has a strong pointer to the cClientHandle. The player ticks the clienthandle. If he finds the handle destroyed, he destroys himself in turn. Nothing else can kill the player. * The client handle has a pointer to the player. Once a player is created, the client handle never outlasts the player, nor does it manage the player's lifetime. The pointer is always safe to use after FinishAuthenticate, which is also the point where cProtocol is put into the Game state that allows player manipulation. + Entities are once again never lost by constructing a chunk when they try to move into one that doesn't exist. * Fixed a forgotten Super invocation in cPlayer::OnRemoveFromWorld. * Fix SaveToDisk usage in destructor by only saving things cPlayer owns, instead of accessing cWorld. --- src/Entities/Player.h | 55 ++++++++++++++++++--------------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) (limited to 'src/Entities/Player.h') diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 1e7a17e4f..ba3c345ed 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -48,12 +48,11 @@ public: CLASS_PROTODEF(cPlayer) - cPlayer(const cClientHandlePtr & a_Client, const AString & a_PlayerName); - - virtual bool Initialize(OwnedEntity a_Self, cWorld & a_World) override; + cPlayer(const cClientHandlePtr & a_Client); virtual ~cPlayer() override; + virtual void OnAddToWorld(cWorld & a_World) override; virtual void OnRemoveFromWorld(cWorld & a_World) override; virtual void SpawnOn(cClientHandle & a_Client) override; @@ -123,6 +122,9 @@ public: // tolua_end + /** Gets the set of IDs for recipes this player has discovered. */ + const std::set & GetKnownRecipes() const; + /** Starts charging the equipped bow */ void StartChargingBow(void); @@ -187,7 +189,7 @@ public: eGameMode GetGameMode(void) const { return m_GameMode; } /** Returns the current effective gamemode (inherited gamemode is resolved before returning) */ - eGameMode GetEffectiveGameMode(void) const { return (m_GameMode == gmNotSet) ? m_World->GetGameMode() : m_GameMode; } + eGameMode GetEffectiveGameMode(void) const; /** Sets the gamemode for the player. The gamemode may be gmNotSet, in that case the player inherits the world's gamemode. @@ -219,7 +221,7 @@ public: /** Returns true if the player can be targeted by Mobs */ bool CanMobsTarget(void) const; - AString GetIP(void) const { return m_IP; } // tolua_export + AString GetIP(void) const; // tolua_export /** Returns the associated team, nullptr if none */ cTeam * GetTeam(void) { return m_Team; } // tolua_export @@ -243,8 +245,6 @@ public: If the achievement has been already awarded to the player, this method will just increment the stat counter. */ void AwardAchievement(Statistic a_Ach); - void SetIP(const AString & a_IP); - /** Forces the player to move in the given direction. @deprecated Use SetSpeed instead. */ void ForceSetSpeed(const Vector3d & a_Speed); // tolua_export @@ -263,7 +263,6 @@ public: /** Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow */ void CloseWindowIfID(char a_WindowID, bool a_CanRefuse = true); - /** Returns the raw client handle associated with the player. */ cClientHandle * GetClientHandle(void) const { return m_ClientHandle.get(); } // tolua_end @@ -275,9 +274,6 @@ public: /** Permute the seed for enchanting related PRNGs, don't use this for other purposes. */ void PermuteEnchantmentSeed(); - /** Returns the SharedPtr to client handle associated with the player. */ - cClientHandlePtr GetClientHandlePtr(void) const { return m_ClientHandle; } - // tolua_begin void SendMessage (const AString & a_Message); @@ -294,8 +290,7 @@ public: void SendSystemMessage (const cCompositeChat & a_Message); void SendAboveActionBarMessage(const cCompositeChat & a_Message); - const AString & GetName(void) const { return m_PlayerName; } - void SetName(const AString & a_Name) { m_PlayerName = a_Name; } + const AString & GetName(void) const; // tolua_end @@ -434,7 +429,7 @@ public: */ bool LoadFromFile(const AString & a_FileName, cWorldPtr & a_World); - const AString & GetLoadedWorldName() { return m_LoadedWorldName; } + const AString & GetLoadedWorldName() const { return m_CurrentWorldName; } /** Opens the inventory of any tame horse the player is riding. If the player is not riding a horse or if the horse is untamed, does nothing. */ @@ -452,13 +447,6 @@ public: equipped item is enchanted. */ void UseItem(int a_SlotNumber, short a_Damage = 1); - void SendHealth(void); - - // Send current active hotbar slot - void SendHotbarActiveSlot(void); - - void SendExperience(void); - /** In UI windows, get the item that the player is dragging */ cItem & GetDraggingItem(void) {return m_DraggingItem; } // tolua_export @@ -598,10 +586,6 @@ public: virtual void AttachTo(cEntity * a_AttachTo) override; virtual void Detach(void) override; - /** Called by cClientHandle when the client is being destroyed. - The player removes its m_ClientHandle ownership so that the ClientHandle gets deleted. */ - void RemoveClientHandle(void); - /** Returns the progress mined per tick for the block a_Block as a fraction (1 would be completely mined) Depends on hardness values so check those are correct. @@ -647,9 +631,6 @@ protected: AString m_MsgPrefix, m_MsgSuffix; AString m_MsgNameColorCode; - AString m_PlayerName; - AString m_LoadedWorldName; - /** Xp Level stuff */ enum { @@ -687,11 +668,18 @@ protected: /** The player's last saved bed position */ Vector3i m_LastBedPos; - /** The world which the player respawns in upon death */ - cWorld * m_SpawnWorld; + /** The name of the world which the player respawns in upon death. + This is stored as a string to enable SaveToDisk to not touch cRoot, and thus can be safely called in the player's destructor. */ + std::string m_SpawnWorldName; + + /** The name of the world which the player currently resides in. + Stored in addition to m_World to allow SaveToDisk to be safely called in the player's destructor. */ + std::string m_CurrentWorldName; + + /** The save path of the default world. */ + std::string m_DefaultWorldPath; eGameMode m_GameMode; - AString m_IP; /** The item being dragged by the cursor while in a UI window */ cItem m_DraggingItem; @@ -738,9 +726,6 @@ protected: int m_CurrentXp; unsigned int m_EnchantmentSeed; - // flag saying we need to send a xp update to client - bool m_bDirtyExperience; - bool m_IsChargingBow; int m_BowCharge; @@ -781,8 +766,6 @@ protected: /** List of known items as Ids */ std::set m_KnownItems; - virtual void DoMoveToWorld(const cEntity::sWorldChangeInfo & a_WorldChangeInfo) override; - /** Sets the speed and sends it to the client, so that they are forced to move so. */ virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override; -- cgit v1.2.3