Skip to content
This repository has been archived by the owner on Jan 18, 2024. It is now read-only.

Commit

Permalink
Core/Pets: re-implement pet renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
Ovahlord committed Oct 16, 2023
1 parent 9e5902b commit cfbb9f6
Show file tree
Hide file tree
Showing 15 changed files with 175 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -611,10 +611,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CALENDAR_INVITE, "DELETE FROM calendar_invites WHERE id = ?", CONNECTION_ASYNC);

// Pet
//PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE Guid = ?", CONNECTION_ASYNC);
//PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE PetNumber = ?", CONNECTION_ASYNC);
//PrepareStatement(CHAR_INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (PetNumber, Guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE Guid = ? AND PetNumber = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (PetNumber, Guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE PetNumber = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_PET_DECLINED_NAMES, "SELECT PetNumber, genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE PetNumber IN (SELECT PetNumber FROM character_pet WHERE Guid = ?)", CONNECTION_ASYNC);

PrepareStatement(CHAR_SEL_PET_AURAS, "SELECT guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges, critChance, applyResilience FROM pet_aura WHERE guid IN (SELECT PetNumber FROM character_pet WHERE Guid = ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PET_AURAS, "DELETE FROM pet_aura WHERE guid = ?", CONNECTION_BOTH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,9 @@ enum CharacterDatabaseStatements : uint32
CHAR_DEL_PET_SPELL_COOLDOWNS,
CHAR_INS_PET_SPELL_COOLDOWN,

CHAR_SEL_PET_DECLINED_NAME,
CHAR_INS_CHAR_PET_DECLINEDNAME,
CHAR_DEL_CHAR_PET_DECLINEDNAME,
CHAR_SEL_PET_DECLINED_NAMES,

CHAR_INS_CHAR_PET,
CHAR_DEL_CHAR_PET,
Expand Down
14 changes: 14 additions & 0 deletions src/server/game/Entities/Creature/TemporarySummon/NewPet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ bool NewPet::HandlePreSummonActions(Unit const* summoner, uint8 creatureLevel, u
{
SetName(playerPetData->Name);
ApplySavedAuras(playerPetData);
if (playerPetData->DeclinedNames.has_value())
_declinedNames = std::make_unique<DeclinedName>(*playerPetData->DeclinedNames);
}

SetReactState(playerPetData->ReactState);
Expand Down Expand Up @@ -306,6 +308,13 @@ void NewPet::UpdatePlayerPetData(PlayerPetData* petData)
petData->Name = GetName();
petData->ActionBar = GenerateActionBarDataString();
petData->Talents = GenenerateTalentsDataString();
if (_declinedNames)
petData->DeclinedNames = *_declinedNames.get();
else
petData->DeclinedNames.reset();

if (IsHunterPet())
petData->HasBeenRenamed = !HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, UNIT_CAN_BE_RENAMED);

if (IsClassPet())
{
Expand Down Expand Up @@ -378,6 +387,11 @@ void NewPet::SendTalentsInfoUpdateToSummoner()
summoner->ToPlayer()->SendDirectMessage(packet.Write());
}

void NewPet::SetDeclinedNames(DeclinedName&& declinedNames)
{
_declinedNames = std::make_unique<DeclinedName>(std::move(declinedNames));
}

// ------------- private methods

void NewPet::SendSpellLearnedToSummoner(uint32 spellId)
Expand Down
5 changes: 5 additions & 0 deletions src/server/game/Entities/Creature/TemporarySummon/NewPet.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ class TC_GAME_API NewPet final : public NewGuardian
void LoadTalents(std::string const& dataString);
// Sends a pet talent info update packet to the summoner
void SendTalentsInfoUpdateToSummoner();
// Stores the declined names which have been retrieved in the CMSG_PET_RENAME packet to store them in database later
void SetDeclinedNames(DeclinedName&& declinedNames);
// Returns a pointer to the stored declined names of the pet if there are any. Otherwise nullptr will be returned
DeclinedName const* GetDeclinedNames() const { return _declinedNames.get(); }

private:
void SendSpellLearnedToSummoner(uint32 spellId);
Expand All @@ -106,6 +110,7 @@ class TC_GAME_API NewPet final : public NewGuardian
PetSpellMap _spells;
Optional<PlayerPetDataKey> _playerPetDataKey;
PetTalentMap _talents;
std::unique_ptr<DeclinedName> _declinedNames;
};

#endif // NewPet_h__
53 changes: 50 additions & 3 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16922,9 +16922,10 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
m_deathState = DEAD;

_LoadPets(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PETS));
_LoadPetCooldowns(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_COOLDOWNS));
_LoadPetAuras(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_AURAS));
_LoadPets(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_PETS));
_LoadPetCooldowns(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_PET_COOLDOWNS));
_LoadPetAuras(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_PET_AURAS));
_LoadPetDeclinedNames(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_PET_DECLINED_NAMES));

// after spell load, learn rewarded spell if need also
_LoadQuestStatus(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS));
Expand Down Expand Up @@ -17846,6 +17847,32 @@ void Player::_LoadPetAuras(PreparedQueryResult result)
} while (result->NextRow());
}

void Player::_LoadPetDeclinedNames(PreparedQueryResult result)
{
// "SELECT PetNumber, genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE PetNumber IN (SELECT PetNumber FROM character_pet WHERE Guid = ?)"
if (!result)
return;

do
{
Field* fields = result->Fetch();

uint32 petNumber = fields[0].GetUInt32();
PlayerPetData* petData = GetPlayerPetDataByPetNumber(petNumber);
if (!petData)
continue;

uint8 i = 1;
DeclinedName& declinedNames = petData->DeclinedNames.emplace();
for (std::string& declinedName : declinedNames.name)
{
declinedName = fields[i].GetString();
++i;
}

} while (result->NextRow());
}

void Player::SendPetSpellsMessage(NewPet* pet, bool remove /*= false*/)
{
CharmInfo* charmInfo = pet->GetCharmInfo();
Expand Down Expand Up @@ -20103,6 +20130,22 @@ void Player::_SavePets(CharacterDatabaseTransaction& trans)
stmt->setBool(16, itr.ApplyResilience);
trans->Append(stmt);
}

// Declined names
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME);
stmt->setUInt32(0, petData->PetNumber);
trans->Append(stmt);

if (petData->DeclinedNames.has_value())
{
uint8 i = 0;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_PET_DECLINEDNAME);
stmt->setUInt32(i++, petData->PetNumber);
stmt->setUInt32(i++, GetGUID().GetCounter());

for (std::string const& declinedName : petData->DeclinedNames->name)
stmt->setString(i++, declinedName);
}
}

for (uint32 deletedPetNumber : _deletedPlayerPetDataSet)
Expand All @@ -20118,6 +20161,10 @@ void Player::_SavePets(CharacterDatabaseTransaction& trans)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_AURAS);
stmt->setUInt32(0, deletedPetNumber);
trans->Append(stmt);

stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME);
stmt->setUInt32(0, deletedPetNumber);
trans->Append(stmt);
}

_deletedPlayerPetDataSet.clear();
Expand Down
10 changes: 6 additions & 4 deletions src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -800,10 +800,11 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_CURRENCY = 34,
PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES = 35,
PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 36,
PLAYER_LOGIN_QUERY_LOAD_ALL_PETS = 37,
PLAYER_LOGIN_QUERY_LOAD_ALL_PET_COOLDOWNS = 38,
PLAYER_LOGIN_QUERY_LOAD_ALL_PET_AURAS = 39,
PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS = 40,
PLAYER_LOGIN_QUERY_LOAD_PETS = 37,
PLAYER_LOGIN_QUERY_LOAD_PET_COOLDOWNS = 38,
PLAYER_LOGIN_QUERY_LOAD_PET_AURAS = 39,
PLAYER_LOGIN_QUERY_LOAD_PET_DECLINED_NAMES = 40,
PLAYER_LOGIN_QUERY_LOAD_LFG_REWARD_STATUS = 41,
MAX_PLAYER_LOGIN_QUERY
};

Expand Down Expand Up @@ -2467,6 +2468,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _LoadPets(PreparedQueryResult result);
void _LoadPetCooldowns(PreparedQueryResult result);
void _LoadPetAuras(PreparedQueryResult result);
void _LoadPetDeclinedNames(PreparedQueryResult result);

/*********************************************************/
/*** SAVE SYSTEM ***/
Expand Down
1 change: 1 addition & 0 deletions src/server/game/Entities/Player/PlayerPetData.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct PlayerPetData
std::string Talents;
std::vector<SpellHistory::CooldownEntry> Cooldowns;
std::vector<PlayerPetDataAura> Auras;
Optional<DeclinedName> DeclinedNames;
PlayerPetDataStatus Status = PlayerPetDataStatus::New;
};

Expand Down
2 changes: 1 addition & 1 deletion src/server/game/Entities/Unit/UnitDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ enum HitInfo

struct DeclinedName
{
std::string name[MAX_DECLINED_NAME_CASES];
std::array<std::string, MAX_DECLINED_NAME_CASES> name;
};

enum ActiveStates : uint8
Expand Down
10 changes: 7 additions & 3 deletions src/server/game/Handlers/CharacterHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,19 @@ bool LoginQueryHolder::Initialize()

stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET);
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ALL_PETS, stmt);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_PETS, stmt);

stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_COOLDOWNS);
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_COOLDOWNS, stmt);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_PET_COOLDOWNS, stmt);

stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURAS);
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ALL_PET_AURAS, stmt);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_PET_AURAS, stmt);

stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_DECLINED_NAMES);
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_PET_DECLINED_NAMES, stmt);

stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_REWARDSTATUS_LFG);
stmt->setUInt32(0, lowGuid);
Expand Down
108 changes: 24 additions & 84 deletions src/server/game/Handlers/PetHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,17 +255,11 @@ void WorldSession::SendPetNameQuery(ObjectGuid petGuid, uint32 petNumber)

packet.Timestamp = pet->GetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP);
packet.Name = pet->GetName();

/*
if (pet->IsPet() && ((Pet*)pet)->GetDeclinedNames())
if (DeclinedName const* declinedNames = pet->GetDeclinedNames())
{
data << uint8(1);
for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
data << ((Pet*)pet)->GetDeclinedNames()->name[i];
packet.HasDeclined = true;
packet.DeclinedNames = *declinedNames;
}
else
data << uint8(0);
*/

_player->SendDirectMessage(packet.Write());
}
Expand Down Expand Up @@ -345,95 +339,46 @@ void WorldSession::HandlePetSetAction(WorldPackets::Pet::PetSetAction& packet)
}
}

void WorldSession::HandlePetRename(WorldPacket& recvData)
void WorldSession::HandlePetRename(WorldPackets::Pet::PetRename& packet)
{
TC_LOG_DEBUG("network.opcode", "WORLD: Received CMSG_PET_RENAME");

ObjectGuid petguid;
uint8 isdeclined;

std::string name;
DeclinedName declinedname;

recvData >> petguid;
recvData >> name;
recvData >> isdeclined;

return;
if (packet.RenameData.PetGUID.IsEmpty())
return;

/*
Pet* pet = ObjectAccessor::GetPet(*_player, petguid);
// check it!
if (!pet || !pet->IsPet() || !((Pet*)pet)->IsHunterPet() ||
!pet->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, UNIT_CAN_BE_RENAMED) ||
pet->GetOwnerOrCreatorGUID() != _player->GetGUID() || !pet->GetCharmInfo())
NewPet* pet = _player->GetActivelyControlledSummon();
if (!pet || !pet->IsHunterPet() || pet->GetGUID() != packet.RenameData.PetGUID || !pet->HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, UNIT_CAN_BE_RENAMED))
return;

PetNameInvalidReason res = ObjectMgr::CheckPetName(name, GetSessionDbcLocale());
PetNameInvalidReason res = ObjectMgr::CheckPetName(packet.RenameData.NewName, GetSessionDbcLocale());
if (res != PET_NAME_SUCCESS)
{
SendPetNameInvalid(res, name, nullptr);
SendPetNameInvalid(res, packet.RenameData);
return;
}

if (sObjectMgr->IsReservedName(name))
if (sObjectMgr->IsReservedName(packet.RenameData.NewName))
{
SendPetNameInvalid(PET_NAME_RESERVED, name, nullptr);
SendPetNameInvalid(PET_NAME_RESERVED, packet.RenameData);
return;
}

pet->SetName(name);
if (pet->GetOwner()->GetGroup())
pet->GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);
pet->SetName(packet.RenameData.NewName);
pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PET_FLAGS, UNIT_CAN_BE_RENAMED);

if (isdeclined)
if (packet.RenameData.HasDeclinedNames)
{
for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
{
recvData >> declinedname.name[i];
}
std::wstring wname;
if (!Utf8toWStr(name, wname))
if (!Utf8toWStr(packet.RenameData.NewName, wname))
return;

if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
if (!ObjectMgr::CheckDeclinedNames(wname, packet.RenameData.DeclinedNames))
{
SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname);
SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, packet.RenameData);
return;
}
}

/*
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
if (isdeclined)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME);
stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber());
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_PET_DECLINEDNAME);
stmt->setUInt32(0, _player->GetGUID().GetCounter());
for (uint8 i = 0; i < 5; i++)
stmt->setString(i + 1, declinedname.name[i]);
trans->Append(stmt);
}
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_NAME);
stmt->setString(0, name);
stmt->setUInt32(1, _player->GetGUID().GetCounter());
stmt->setUInt32(2, pet->GetCharmInfo()->GetPetNumber());
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime())); // cast can't be helped
*/
pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, static_cast<uint32>(GameTime::GetGameTime()));
pet->SetDeclinedNames(std::move(packet.RenameData.DeclinedNames));
}

void WorldSession::HandlePetAbandon(WorldPackets::Pet::PetAbandon& packet)
Expand Down Expand Up @@ -537,17 +482,12 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
}
}

void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName)
void WorldSession::SendPetNameInvalid(uint32 error, WorldPackets::Pet::PetRenameData const& renameData)
{
WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1);
data << uint32(error);
data << name;
data << uint8(declinedName ? 1 : 0);
if (declinedName)
for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
data << declinedName->name[i];

SendPacket(&data);
WorldPackets::Pet::PetNameInvalid packet;
packet.Result = error;
packet.RenameData = renameData;
SendPacket(packet.Write());
}

void WorldSession::HandlePetLearnTalent(WorldPacket& recvData)
Expand Down
Loading

0 comments on commit cfbb9f6

Please sign in to comment.