From 1bb4d7941267ee55cdf7f35fa6a0055521115960 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 2 Sep 2014 19:12:35 +0200 Subject: [PATCH] Added SetCustomName() to players. --- src/ClientHandle.cpp | 12 +++----- src/ClientHandle.h | 2 +- src/Entities/Player.cpp | 47 ++++++++++++++++++++++++++++- src/Entities/Player.h | 15 +++++++++ src/Mobs/Monster.h | 3 +- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 23 +++++++------- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol132.cpp | 9 +++++- src/Protocol/Protocol17x.cpp | 26 ++++++++++++---- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 +-- src/Protocol/ProtocolRecognizer.h | 2 +- src/World.cpp | 14 ++++++--- src/World.h | 2 +- 15 files changed, 124 insertions(+), 41 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index f9c6a664c..e97c126a1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -124,13 +124,11 @@ cClientHandle::~cClientHandle() if (m_Player != NULL) { cWorld * World = m_Player->GetWorld(); - if (!m_Username.empty() && (World != NULL)) - { - // Send the Offline PlayerList packet: - World->BroadcastPlayerListItem(*m_Player, false, this); - } if (World != NULL) { + // Send the Offline PlayerList packet: + World->BroadcastPlayerListItem(m_Player->GetTabListName(), false, 0, this); + World->RemovePlayer(m_Player, true); // Must be called before cPlayer::Destroy() as otherwise cChunk tries to delete the player, and then we do it again m_Player->Destroy(); } @@ -2371,9 +2369,9 @@ void cClientHandle::SendPlayerAbilities() -void cClientHandle::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cClientHandle::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { - m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); + m_Protocol->SendPlayerListItem(a_PlayerName, a_IsOnline, a_Ping); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 7ae70a07f..529ee4555 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -156,7 +156,7 @@ public: void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount); void SendPlayerAbilities (void); - void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline); + void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) void SendPlayerMoveLook (void); void SendPlayerPosition (void); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 756410989..a2934d036 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -81,7 +81,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : m_Team(NULL), m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL), m_bIsTeleporting(false), - m_UUID((a_Client != NULL) ? a_Client->GetUUID() : "") + m_UUID((a_Client != NULL) ? a_Client->GetUUID() : ""), + m_CustomName("") { m_InventoryWindow = new cInventoryWindow(*this); m_CurrentWindow = m_InventoryWindow; @@ -813,6 +814,28 @@ void cPlayer::SetCanFly(bool a_CanFly) +void cPlayer::SetCustomName(const AString & a_CustomName) +{ + if (m_CustomName == a_CustomName) + { + return; + } + m_World->BroadcastPlayerListItem(GetTabListName(), false, 0); // Remove old tab-list entry + + m_CustomName = a_CustomName; + if (m_CustomName.length() > 16) + { + m_CustomName = m_CustomName.substr(0, 16); + } + + m_World->BroadcastSpawnEntity(*this, m_ClientHandle); + m_World->BroadcastPlayerListItem(GetTabListName(), true, GetClientHandle()->GetPing()); +} + + + + + void cPlayer::SetFlying(bool a_IsFlying) { if (a_IsFlying == m_IsFlying) @@ -1443,6 +1466,28 @@ AString cPlayer::GetColor(void) const +AString cPlayer::GetTabListName(void) const +{ + const AString & Color = GetColor(); + + if (HasCustomName()) + { + return m_CustomName; + } + else if ((GetName().length() <= 14) && !Color.empty()) + { + return Printf("%s%s", Color.c_str(), GetName().c_str()); + } + else + { + return GetName(); + } +} + + + + + void cPlayer::TossEquippedItem(char a_Amount) { cItems Drops; diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 9821cc6d9..da64bd64f 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -251,6 +251,9 @@ public: The returned value either is empty, or includes the cChatColor::Delimiter. */ AString GetColor(void) const; + /** Returns the name that is used in the tablist. */ + AString GetTabListName(void) const; + /** tosses the item in the selected hotbar slot */ void TossEquippedItem(char a_Amount = 1); @@ -398,6 +401,16 @@ public: /** If true the player can fly even when he's not in creative. */ void SetCanFly(bool a_CanFly); + /** Is a custom name for this player set? */ + bool HasCustomName(void) const { return !m_CustomName.empty(); } + + /** Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string. */ + const AString & GetCustomName(void) const { return m_CustomName; } + + /** Sets the custom name of this player. If you want to disable the custom name, simply set an empty string. + The custom name will be used in the tab-list, in the player nametag and in the tab-completion. */ + void SetCustomName(const AString & a_CustomName); + /** Gets the last position that the player slept in This is initialised to the world spawn point if the player has not slept in a bed as of yet */ @@ -562,6 +575,8 @@ protected: If no ClientHandle is given, the UUID is initialized to empty. */ AString m_UUID; + AString m_CustomName; + /** 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; diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index f14a4f100..a777978f6 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -153,7 +153,8 @@ public: /** Gets the custom name of the monster. If no custom name is set, the function returns a empty string. */ const AString & GetCustomName(void) const { return m_CustomName; } - /** Sets the custom name of the monster. You see the name over the monster. */ + /** Sets the custom name of the monster. You see the name over the monster. + If you want to disable the custom name, simply set an empty string. */ void SetCustomName(const AString & a_CustomName); /** Is the custom name of this monster always visible? If not, you only see the name when you sight the mob. */ diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 8e1842ec1..9b64faf79 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -93,7 +93,7 @@ public: virtual void SendPlayerAbilities (void) = 0; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0; virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) = 0; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) = 0; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) = 0; virtual void SendPlayerMaxSpeed (void) = 0; ///< Informs the client of the maximum player speed (1.6.1+) virtual void SendPlayerMoveLook (void) = 0; virtual void SendPlayerPosition (void) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index a66c64309..0b5e3de91 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -719,21 +719,13 @@ void cProtocol125::SendPaintingSpawn(const cPainting & a_Painting) -void cProtocol125::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocol125::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { cCSLock Lock(m_CSPacket); - AString PlayerName(a_Player.GetColor()); - PlayerName.append(a_Player.GetName()); - if (PlayerName.length() > 14) - { - PlayerName.erase(14); - } - PlayerName += cChatColor::White; - WriteByte ((unsigned char)PACKET_PLAYER_LIST_ITEM); - WriteString(PlayerName); + WriteString(a_PlayerName); WriteBool (a_IsOnline); - WriteShort (a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0); + WriteShort (a_Ping); Flush(); } @@ -792,7 +784,14 @@ void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player) cCSLock Lock(m_CSPacket); WriteByte (PACKET_PLAYER_SPAWN); WriteInt (a_Player.GetUniqueID()); - WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + WriteString(a_Player.GetCustomName()); + } + else + { + WriteString(a_Player.GetName()); + } WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 1063777a2..9ab0adfcd 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -65,7 +65,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 5c58ab0ba..af3bc68ee 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -260,7 +260,14 @@ void cProtocol132::SendPlayerSpawn(const cPlayer & a_Player) cCSLock Lock(m_CSPacket); WriteByte (PACKET_PLAYER_SPAWN); WriteInt (a_Player.GetUniqueID()); - WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + WriteString(a_Player.GetCustomName()); + } + else + { + WriteString(a_Player.GetName()); + } WriteInt ((int)(a_Player.GetPosX() * 32)); WriteInt ((int)(a_Player.GetPosY() * 32)); WriteInt ((int)(a_Player.GetPosZ() * 32)); diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index ed9812377..2ac1d0d0f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -865,14 +865,14 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr -void cProtocol172::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocol172::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, 0x38); // Playerlist Item packet - Pkt.WriteString(a_Player.GetName()); + Pkt.WriteString(a_PlayerName); Pkt.WriteBool(a_IsOnline); - Pkt.WriteShort(a_IsOnline ? a_Player.GetClientHandle()->GetPing() : 0); + Pkt.WriteShort(a_Ping); } @@ -946,9 +946,16 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player) // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet - Pkt.WriteVarInt(a_Player.GetUniqueID()); + Pkt.WriteVarInt((UInt32) a_Player.GetUniqueID()); Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); - Pkt.WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + Pkt.WriteString(a_Player.GetCustomName()); + } + else + { + Pkt.WriteString(a_Player.GetName()); + } Pkt.WriteFPInt(a_Player.GetPosX()); Pkt.WriteFPInt(a_Player.GetPosY()); Pkt.WriteFPInt(a_Player.GetPosZ()); @@ -3075,7 +3082,14 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt(a_Player.GetUniqueID()); Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID())); - Pkt.WriteString(a_Player.GetName()); + if (a_Player.HasCustomName()) + { + Pkt.WriteString(a_Player.GetCustomName()); + } + else + { + Pkt.WriteString(a_Player.GetName()); + } const Json::Value & Properties = a_Player.GetClientHandle()->GetProperties(); Pkt.WriteVarInt(Properties.size()); diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index ccfa19eb6..eb64f6ad5 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -97,7 +97,7 @@ public: virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index c831da251..d9cfc140a 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -487,10 +487,10 @@ void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_A -void cProtocolRecognizer::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) +void cProtocolRecognizer::SendPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping) { ASSERT(m_Protocol != NULL); - m_Protocol->SendPlayerListItem(a_Player, a_IsOnline); + m_Protocol->SendPlayerListItem(a_PlayerName, a_IsOnline, a_Ping); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index a05aeda70..95fcae1d3 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -100,7 +100,7 @@ public: virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override; virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; - virtual void SendPlayerListItem (const cPlayer & a_Player, bool a_IsOnline) override; + virtual void SendPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0) override; virtual void SendPlayerMaxSpeed (void) override; virtual void SendPlayerMoveLook (void) override; virtual void SendPlayerPosition (void) override; diff --git a/src/World.cpp b/src/World.cpp index 99e09c658..469606012 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2147,7 +2147,7 @@ void cWorld::BroadcastParticleEffect(const AString & a_ParticleName, float a_Src -void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude) +void cWorld::BroadcastPlayerListItem(const AString & a_PlayerName, bool a_IsOnline, short a_Ping, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -2157,7 +2157,7 @@ void cWorld::BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, { continue; } - ch->SendPlayerListItem(a_Player, a_IsOnline); + ch->SendPlayerListItem(a_PlayerName, a_IsOnline, a_Ping); } } @@ -2669,7 +2669,7 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer) cClientHandle * ch = (*itr)->GetClientHandle(); if ((ch != NULL) && !ch->IsDestroyed()) { - a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr), true); + a_DestPlayer->GetClientHandle()->SendPlayerListItem((*itr)->GetTabListName(), true, (*itr)->GetClientHandle()->GetPing()); } } } @@ -3209,13 +3209,17 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr) { AString PlayerName ((*itr)->GetName()); + if ((*itr)->HasCustomName()) + { + PlayerName = (*itr)->GetCustomName(); + } + AString::size_type Found = PlayerName.find(LastWord); // Try to find last word in playername - if (Found == AString::npos) { continue; // No match } - + UsernamesByWeight.push_back(std::make_pair(Found, PlayerName)); // Match! Store it with the position of the match as a weight } Lock.Unlock(); diff --git a/src/World.h b/src/World.h index 578c9682b..5f4466603 100644 --- a/src/World.h +++ b/src/World.h @@ -237,7 +237,7 @@ public: void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); + void BroadcastPlayerListItem (const AString & a_PlayerName, bool a_IsOnline, short a_Ping = 0, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode);