diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ClientHandle.cpp | 12 | ||||
-rw-r--r-- | src/ClientHandle.h | 2 | ||||
-rw-r--r-- | src/Entities/Boat.cpp | 2 | ||||
-rw-r--r-- | src/Entities/Entity.h | 2 | ||||
-rw-r--r-- | src/Entities/ItemFrame.cpp | 2 | ||||
-rw-r--r-- | src/Entities/Minecart.cpp | 5 | ||||
-rw-r--r-- | src/Entities/Pawn.cpp | 9 | ||||
-rw-r--r-- | src/Entities/Player.cpp | 47 | ||||
-rw-r--r-- | src/Entities/Player.h | 15 | ||||
-rw-r--r-- | src/Mobs/Monster.cpp | 54 | ||||
-rw-r--r-- | src/Mobs/Monster.h | 23 | ||||
-rw-r--r-- | src/Mobs/Sheep.cpp | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol.h | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol125.cpp | 23 | ||||
-rw-r--r-- | src/Protocol/Protocol125.h | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol132.cpp | 9 | ||||
-rw-r--r-- | src/Protocol/Protocol17x.cpp | 36 | ||||
-rw-r--r-- | src/Protocol/Protocol17x.h | 2 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.cpp | 4 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.h | 2 | ||||
-rw-r--r-- | src/World.cpp | 14 | ||||
-rw-r--r-- | src/World.h | 2 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.cpp | 2 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.cpp | 13 |
24 files changed, 239 insertions, 47 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/Boat.cpp b/src/Entities/Boat.cpp index 8ff8866a1..328a70846 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -62,6 +62,8 @@ bool cBoat::DoTakeDamage(TakeDamageInfo & TDI) void cBoat::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + if (m_Attachee != NULL) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index b9c280b6b..774cdb062 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -447,7 +447,7 @@ public: // tolua_end /// Called when the specified player right-clicks this entity - virtual void OnRightClicked(cPlayer &) {} + virtual void OnRightClicked(cPlayer & a_Player) {} /// Returns the list of drops for this pawn when it is killed. May check a_Killer for special handling (sword of looting etc.). Called from KilledBy(). virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index 0bc10ec60..3ccb95998 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -22,6 +22,8 @@ cItemFrame::cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_ void cItemFrame::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + if (!m_Item.IsEmpty()) { // Item not empty, rotate, clipping values to zero to three inclusive diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 1501eea84..5fabbb542 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -1072,6 +1072,8 @@ cRideableMinecart::cRideableMinecart(double a_X, double a_Y, double a_Z, const c void cRideableMinecart::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + if (m_Attachee != NULL) { if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID()) @@ -1124,8 +1126,7 @@ void cMinecartWithChest::SetSlot(size_t a_Idx, const cItem & a_Item) void cMinecartWithChest::OnRightClicked(cPlayer & a_Player) { - // Show the chest UI window to the player - // TODO + // TODO: Show the chest UI window to the player } diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index fe6c24a7a..fc8ca3d47 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -9,9 +9,9 @@ -cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height): - super(a_EntityType, 0, 0, 0, a_Width, a_Height), - m_EntityEffects(tEffectMap()) +cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height) : + super(a_EntityType, 0, 0, 0, a_Width, a_Height) + , m_EntityEffects(tEffectMap()) { } @@ -111,3 +111,6 @@ void cPawn::ClearEntityEffects() RemoveEntityEffect(EffectType); } } + + + 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..49380c776 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); + /** Returns true if the player has a custom name. */ + 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.cpp b/src/Mobs/Monster.cpp index f7ee0b0c0..b0b836dff 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -75,6 +75,8 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_IdleInterval(0) , m_DestroyTimer(0) , m_MobType(a_MobType) + , m_CustomName("") + , m_CustomNameAlwaysVisible(false) , m_SoundHurt(a_SoundHurt) , m_SoundDeath(a_SoundDeath) , m_AttackRate(3) @@ -551,6 +553,25 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI) +void cMonster::OnRightClicked(cPlayer & a_Player) +{ + super::OnRightClicked(a_Player); + + const cItem & EquippedItem = a_Player.GetEquippedItem(); + if ((EquippedItem.m_ItemType == E_ITEM_NAME_TAG) && !EquippedItem.m_CustomName.empty()) + { + SetCustomName(EquippedItem.m_CustomName); + if (!a_Player.IsGameModeCreative()) + { + a_Player.GetInventory().RemoveOneEquippedItem(); + } + } +} + + + + + // Checks to see if EventSeePlayer should be fired // monster sez: Do I see the player void cMonster::CheckEventSeePlayer(void) @@ -679,6 +700,39 @@ void cMonster::InStateEscaping(float a_Dt) +void cMonster::SetCustomName(const AString & a_CustomName) +{ + m_CustomName = a_CustomName; + + // The maximal length is 64 + if (a_CustomName.length() > 64) + { + m_CustomName = a_CustomName.substr(0, 64); + } + + if (m_World != NULL) + { + m_World->BroadcastEntityMetadata(*this); + } +} + + + + + +void cMonster::SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible) +{ + m_CustomNameAlwaysVisible = a_CustomNameAlwaysVisible; + if (m_World != NULL) + { + m_World->BroadcastEntityMetadata(*this); + } +} + + + + + void cMonster::GetMonsterConfig(const AString & a_Name) { cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, a_Name); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index cdbd26c09..1d66d50e5 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -92,6 +92,8 @@ public: virtual void KilledBy(TakeDamageInfo & a_TDI) override; + virtual void OnRightClicked(cPlayer & a_Player) override; + virtual void MoveToPosition(const Vector3d & a_Position); // tolua_export virtual bool ReachedDestination(void); @@ -144,7 +146,24 @@ public: virtual bool IsSitting (void) const { return false; } // tolua_begin - + + /** Returns true if the monster has a custom name. */ + bool HasCustomName(void) const { return !m_CustomName.empty(); } + + /** Gets the custom name of the monster. If no custom name is set, the function returns an empty string. */ + const AString & GetCustomName(void) const { return m_CustomName; } + + /** 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. */ + bool IsCustomNameAlwaysVisible(void) const { return m_CustomNameAlwaysVisible; } + + /** Sets the custom name visiblity of this monster. + If it's false, you only see the name when you sight the mob. If it's true, you always see the custom name. */ + void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible); + /// Translates MobType enum to a string, empty string if unknown static AString MobTypeToString(eType a_MobType); @@ -228,6 +247,8 @@ protected: float m_DestroyTimer; eType m_MobType; + AString m_CustomName; + bool m_CustomNameAlwaysVisible; AString m_SoundHurt; AString m_SoundDeath; diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 9fb47201d..ee3236bba 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -47,6 +47,8 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSheep::OnRightClicked(cPlayer & a_Player) { + super::OnRightClicked(a_Player); + const cItem & EquippedItem = a_Player.GetEquippedItem(); if ((EquippedItem.m_ItemType == E_ITEM_SHEARS) && !IsSheared() && !IsBaby()) { 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 1091b877f..2ac1d0d0f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1,3 +1,4 @@ + // Protocol17x.cpp /* @@ -864,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); } @@ -945,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()); @@ -3021,6 +3029,15 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) break; } } // switch (a_Mob.GetType()) + + // Custom name: + if (a_Mob.HasCustomName()) + { + WriteByte(0x8a); + WriteString(a_Mob.GetCustomName()); + WriteByte(0x0b); + WriteByte(a_Mob.IsCustomNameAlwaysVisible() ? 1 : 0); + } } @@ -3065,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 8b395230a..2cd2a935b 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); diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 68e541eba..1962d42ff 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -504,6 +504,8 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddFloat("", a_Monster->GetDropChanceBoots()); m_Writer.EndList(); m_Writer.AddByte("CanPickUpLoot", (char)a_Monster->CanPickUpLoot()); + m_Writer.AddString("CustomName", a_Monster->GetCustomName()); + m_Writer.AddByte("CustomNameVisible", (char)a_Monster->IsCustomNameAlwaysVisible()); switch (a_Monster->GetMobType()) { case cMonster::mtBat: diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index e79cc291d..5c155aeef 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2640,6 +2640,19 @@ bool cWSSAnvil::LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_Monster.SetCanPickUpLoot(CanPickUpLoot); } + int CustomNameTag = a_NBT.FindChildByName(a_TagIdx, "CustomName"); + if ((CustomNameTag > 0) && (a_NBT.GetType(CustomNameTag) == TAG_String)) + { + a_Monster.SetCustomName(a_NBT.GetString(CustomNameTag)); + } + + int CustomNameVisibleTag = a_NBT.FindChildByName(a_TagIdx, "CustomNameVisible"); + if ((CustomNameVisibleTag > 0) && (a_NBT.GetType(CustomNameVisibleTag) == TAG_Byte)) + { + bool CustomNameVisible = (a_NBT.GetByte(CustomNameVisibleTag) == 1); + a_Monster.SetCustomNameAlwaysVisible(CustomNameVisible); + } + return true; } |