feat(Core/Commands): add .pet rename command (#25951)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andrew
2026-05-24 18:32:35 -03:00
committed by GitHub
parent 110cb0874d
commit 503735c540
5 changed files with 95 additions and 1 deletions
@@ -0,0 +1,8 @@
-- RBAC permission for .pet rename (sec 3+, Admin role 196).
DELETE FROM `rbac_permissions` WHERE `id` = 922;
INSERT INTO `rbac_permissions` (`id`, `name`) VALUES
(922, 'Command: pet rename');
DELETE FROM `rbac_linked_permissions` WHERE `linkedId` = 922;
INSERT INTO `rbac_linked_permissions` (`id`, `linkedId`) VALUES
(196, 922);
@@ -0,0 +1,5 @@
-- acore_string entries for .pet rename command.
DELETE FROM `acore_string` WHERE `entry` IN (35453, 35454);
INSERT INTO `acore_string` (`entry`, `content_default`, `locale_koKR`, `locale_frFR`, `locale_deDE`, `locale_zhCN`, `locale_zhTW`, `locale_esES`, `locale_esMX`, `locale_ruRU`) VALUES
(35453, 'Invalid pet name: {}.', '잘못된 펫 이름입니다: {}.', 'Nom de familier invalide : {}.', 'Ungültiger Begleitername: {}.', '无效的宠物名称: {}。', '無效的寵物名稱:{}。', 'Nombre de mascota no válido: {}.', 'Nombre de mascota no válido: {}.', 'Недопустимое имя питомца: {}.'),
(35454, 'Renamed pet {0} ({1} -> {2}) for player {3} ({4}).', '플레이어 {3} ({4})의 펫 {0}의 이름을 {1}에서 {2}(으)로 변경했습니다.', 'Familier {0} renommé ({1} -> {2}) pour le joueur {3} ({4}).', 'Begleiter {0} umbenannt ({1} -> {2}) für Spieler {3} ({4}).', '已将玩家 {3} ({4}) 的宠物 {0} 重命名 ({1} -> {2})。', '已將玩家 {3} ({4}) 的寵物 {0} 重新命名({1} -> {2})。', 'Mascota {0} renombrada ({1} -> {2}) para el jugador {3} ({4}).', 'Mascota {0} renombrada ({1} -> {2}) para el jugador {3} ({4}).', 'Питомец {0} переименован ({1} -> {2}) у игрока {3} ({4}).');
+1
View File
@@ -683,6 +683,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_RESPAWN_GAMEOBJECT_ENTRY = 919,
RBAC_PERM_COMMAND_DEBUG_INFO = 920,
RBAC_PERM_COMMAND_DEBUG_COSMETIC = 921,
RBAC_PERM_COMMAND_PET_RENAME = 922,
// custom permissions 1000+
RBAC_PERM_MAX
};
+5 -1
View File
@@ -1508,6 +1508,10 @@ enum AcoreStrings
LANG_RESPAWN_ENTRY_GAMEOBJECT_QUEUED = 35452,
// List respawns console support
LANG_LIST_RESPAWNS_NO_MAP = 35447
LANG_LIST_RESPAWNS_NO_MAP = 35447,
// Pet rename command
LANG_PET_RENAME_INVALID = 35453,
LANG_PET_RENAME_SUCCESS = 35454
};
#endif
+76
View File
@@ -19,6 +19,8 @@
#include "CommandScript.h"
#include "DatabaseEnv.h"
#include <algorithm>
#include "GameTime.h"
#include "Group.h"
#include "Language.h"
#include "Log.h"
#include "ObjectMgr.h"
@@ -43,6 +45,7 @@ public:
{ "delete", HandlePetDeleteCommand, rbac::RBAC_PERM_COMMAND_PET_DELETE, Console::Yes },
{ "learn", HandlePetLearnCommand, rbac::RBAC_PERM_COMMAND_PET_LEARN, Console::No },
{ "list", HandlePetListCommand, rbac::RBAC_PERM_COMMAND_PET_LIST, Console::Yes },
{ "rename", HandlePetRenameCommand, rbac::RBAC_PERM_COMMAND_PET_RENAME, Console::Yes },
{ "unlearn", HandlePetUnlearnCommand, rbac::RBAC_PERM_COMMAND_PET_UNLEARN, Console::No }
};
@@ -227,6 +230,79 @@ public:
return true;
}
static bool HandlePetRenameCommand(ChatHandler* handler, PlayerIdentifier owner, uint32 petNumber, std::string newName)
{
if (ObjectMgr::CheckPetName(newName) != PET_NAME_SUCCESS)
{
handler->SendErrorMessage(LANG_PET_RENAME_INVALID, newName);
return false;
}
ObjectGuid ownerGuid = owner.GetGUID();
QueryResult result = CharacterDatabase.Query("SELECT name FROM character_pet WHERE id = {} AND owner = {}", petNumber, ownerGuid.GetCounter());
if (!result)
{
handler->SendErrorMessage(LANG_PET_DELETE_NOT_FOUND, petNumber, owner.GetName(), ownerGuid.GetCounter());
return false;
}
std::string oldName = result->Fetch()[0].Get<std::string>();
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_NAME);
stmt->SetData(0, newName);
stmt->SetData(1, ownerGuid.GetCounter());
stmt->SetData(2, petNumber);
CharacterDatabase.Execute(stmt);
if (Player* online = owner.GetConnectedPlayer())
{
if (Pet* activePet = online->GetPet())
{
if (activePet->GetCharmInfo() && activePet->GetCharmInfo()->GetPetNumber() == petNumber)
{
activePet->SetName(newName);
// Bump the name timestamp so nearby clients re-query and drop their cached pet name.
activePet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime().count()));
activePet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);
if (online->GetGroup())
online->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);
}
}
if (PetStable* stable = online->GetPetStable())
{
if (stable->CurrentPet && stable->CurrentPet->PetNumber == petNumber)
{
stable->CurrentPet->Name = newName;
stable->CurrentPet->WasRenamed = true;
}
for (Optional<PetStable::PetInfo>& stabled : stable->StabledPets)
{
if (stabled && stabled->PetNumber == petNumber)
{
stabled->Name = newName;
stabled->WasRenamed = true;
}
}
for (PetStable::PetInfo& unslotted : stable->UnslottedPets)
{
if (unslotted.PetNumber == petNumber)
{
unslotted.Name = newName;
unslotted.WasRenamed = true;
}
}
}
}
handler->PSendSysMessage(LANG_PET_RENAME_SUCCESS, petNumber, oldName, newName, owner.GetName(), ownerGuid.GetCounter());
return true;
}
static bool HandlePetUnlearnCommand(ChatHandler* handler, SpellInfo const* spell)
{
if (!spell)