Core/BattlePets: Implemented battle pet name query packet

Port From (https://github.com/TrinityCore/TrinityCore/commit/8614690e27df8197586cc702760409293f3f6c3d)
This commit is contained in:
hondacrx
2021-11-23 15:07:17 -05:00
parent 5129b4a45f
commit 0a8541a39c
9 changed files with 150 additions and 39 deletions
+9 -16
View File
@@ -14,31 +14,24 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using System;
namespace Framework.Constants namespace Framework.Constants
{ {
[Flags]
public enum BattlePetError
{
CantHaveMorePetsOfThatType = 3, // You can't have any more pets of that type.
CantHaveMorePets = 4, // You can't have any more pets.
TooHighLevelToUncage = 7, // This pet is too high level for you to uncage.
}
public enum FlagsControlType public enum FlagsControlType
{ {
Apply = 1, Apply = 1,
Remove = 2 Remove = 2
} }
public enum BattlePetError
{
CantHaveMorePetsOfThatType = 3,
CantHaveMorePets = 4,
TooHighLevelToUncage = 7,
// TODO: find correct values if possible and needed (also wrong order)
DuplicateConvertedPet,
NeedToUnlock,
BadParam,
LockedPetAlreadyExists,
Ok,
Uncapturable,
CantInvalidCharacterGuid
}
// taken from BattlePetState.db2 - it seems to store some initial values for battle pets // taken from BattlePetState.db2 - it seems to store some initial values for battle pets
// there are only values used in BattlePetSpeciesState.db2 and BattlePetBreedState.db2 // there are only values used in BattlePetSpeciesState.db2 and BattlePetBreedState.db2
// TODO: expand this enum if needed // TODO: expand this enum if needed
@@ -151,10 +151,10 @@ namespace Framework.Database
PrepareStatement(LoginStatements.REP_ACCOUNT_TOYS, "REPLACE INTO battlenet_account_toys (accountId, itemId, isFavourite, hasFanfare) VALUES (?, ?, ?, ?)"); PrepareStatement(LoginStatements.REP_ACCOUNT_TOYS, "REPLACE INTO battlenet_account_toys (accountId, itemId, isFavourite, hasFanfare) VALUES (?, ?, ?, ?)");
// Battle Pets // Battle Pets
PrepareStatement(LoginStatements.SEL_BATTLE_PETS, "SELECT bp.guid, bp.species, bp.breed, bp.displayId, bp.level, bp.exp, bp.health, bp.quality, bp.flags, bp.name, dn.genitive, dn.dative, dn.accusative, dn.instrumental, dn.prepositional FROM battle_pets bp LEFT JOIN battle_pet_declinedname dn ON bp.guid = dn.guid WHERE bp.battlenetAccountId = ?"); PrepareStatement(LoginStatements.SEL_BATTLE_PETS, "SELECT bp.guid, bp.species, bp.breed, bp.displayId, bp.level, bp.exp, bp.health, bp.quality, bp.flags, bp.name, bp.nameTimestamp, dn.genitive, dn.dative, dn.accusative, dn.instrumental, dn.prepositional FROM battle_pets bp LEFT JOIN battle_pet_declinedname dn ON bp.guid = dn.guid WHERE bp.battlenetAccountId = ?");
PrepareStatement(LoginStatements.INS_BATTLE_PETS, "INSERT INTO battle_pets (guid, battlenetAccountId, species, breed, displayId, level, exp, health, quality, flags, name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); PrepareStatement(LoginStatements.INS_BATTLE_PETS, "INSERT INTO battle_pets (guid, battlenetAccountId, species, breed, displayId, level, exp, health, quality, flags, name, nameTimestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
PrepareStatement(LoginStatements.DEL_BATTLE_PETS, "DELETE FROM battle_pets WHERE battlenetAccountId = ? AND guid = ?"); PrepareStatement(LoginStatements.DEL_BATTLE_PETS, "DELETE FROM battle_pets WHERE battlenetAccountId = ? AND guid = ?");
PrepareStatement(LoginStatements.UPD_BATTLE_PETS, "UPDATE battle_pets SET level = ?, exp = ?, health = ?, quality = ?, flags = ?, name = ? WHERE battlenetAccountId = ? AND guid = ?"); PrepareStatement(LoginStatements.UPD_BATTLE_PETS, "UPDATE battle_pets SET level = ?, exp = ?, health = ?, quality = ?, flags = ?, name = ?, nameTimestamp = ? WHERE battlenetAccountId = ? AND guid = ?");
PrepareStatement(LoginStatements.SEL_BATTLE_PET_SLOTS, "SELECT id, battlePetGuid, locked FROM battle_pet_slots WHERE battlenetAccountId = ?"); PrepareStatement(LoginStatements.SEL_BATTLE_PET_SLOTS, "SELECT id, battlePetGuid, locked FROM battle_pet_slots WHERE battlenetAccountId = ?");
PrepareStatement(LoginStatements.INS_BATTLE_PET_SLOTS, "INSERT INTO battle_pet_slots (id, battlenetAccountId, battlePetGuid, locked) VALUES (?, ?, ?, ?)"); PrepareStatement(LoginStatements.INS_BATTLE_PET_SLOTS, "INSERT INTO battle_pet_slots (id, battlenetAccountId, battlePetGuid, locked) VALUES (?, ?, ?, ?)");
PrepareStatement(LoginStatements.DEL_BATTLE_PET_SLOTS, "DELETE FROM battle_pet_slots WHERE battlenetAccountId = ?"); PrepareStatement(LoginStatements.DEL_BATTLE_PET_SLOTS, "DELETE FROM battle_pet_slots WHERE battlenetAccountId = ?");
+27 -12
View File
@@ -195,13 +195,14 @@ namespace Game.BattlePets
pet.PacketInfo.Quality = petsResult.Read<byte>(7); pet.PacketInfo.Quality = petsResult.Read<byte>(7);
pet.PacketInfo.Flags = petsResult.Read<ushort>(8); pet.PacketInfo.Flags = petsResult.Read<ushort>(8);
pet.PacketInfo.Name = petsResult.Read<string>(9); pet.PacketInfo.Name = petsResult.Read<string>(9);
pet.NameTimestamp = petsResult.Read<long>(10);
pet.PacketInfo.CreatureID = speciesEntry.CreatureID; pet.PacketInfo.CreatureID = speciesEntry.CreatureID;
if (!petsResult.IsNull(10)) if (!petsResult.IsNull(11))
{ {
pet.DeclinedName = new(); pet.DeclinedName = new();
for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i) for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i)
pet.DeclinedName.name[i] = petsResult.Read<string>(10 + i); pet.DeclinedName.name[i] = petsResult.Read<string>(11 + i);
} }
pet.SaveInfo = BattlePetSaveInfo.Unchanged; pet.SaveInfo = BattlePetSaveInfo.Unchanged;
@@ -248,6 +249,7 @@ namespace Game.BattlePets
stmt.AddValue(8, pair.Value.PacketInfo.Quality); stmt.AddValue(8, pair.Value.PacketInfo.Quality);
stmt.AddValue(9, pair.Value.PacketInfo.Flags); stmt.AddValue(9, pair.Value.PacketInfo.Flags);
stmt.AddValue(10, pair.Value.PacketInfo.Name); stmt.AddValue(10, pair.Value.PacketInfo.Name);
stmt.AddValue(11, pair.Value.NameTimestamp);
trans.Append(stmt); trans.Append(stmt);
if (pair.Value.DeclinedName != null) if (pair.Value.DeclinedName != null)
@@ -272,8 +274,9 @@ namespace Game.BattlePets
stmt.AddValue(3, pair.Value.PacketInfo.Quality); stmt.AddValue(3, pair.Value.PacketInfo.Quality);
stmt.AddValue(4, pair.Value.PacketInfo.Flags); stmt.AddValue(4, pair.Value.PacketInfo.Flags);
stmt.AddValue(5, pair.Value.PacketInfo.Name); stmt.AddValue(5, pair.Value.PacketInfo.Name);
stmt.AddValue(6, _owner.GetBattlenetAccountId()); stmt.AddValue(6, pair.Value.NameTimestamp);
stmt.AddValue(7, pair.Key); stmt.AddValue(7, _owner.GetBattlenetAccountId());
stmt.AddValue(8, pair.Key);
trans.Append(stmt); trans.Append(stmt);
stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_BATTLE_PET_DECLINED_NAME); stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_BATTLE_PET_DECLINED_NAME);
@@ -349,6 +352,7 @@ namespace Game.BattlePets
pet.PacketInfo.Name = ""; pet.PacketInfo.Name = "";
pet.CalculateStats(); pet.CalculateStats();
pet.PacketInfo.Health = pet.PacketInfo.MaxHealth; pet.PacketInfo.Health = pet.PacketInfo.MaxHealth;
pet.NameTimestamp = 0;
pet.SaveInfo = BattlePetSaveInfo.New; pet.SaveInfo = BattlePetSaveInfo.New;
_pets[pet.PacketInfo.Guid.GetCounter()] = pet; _pets[pet.PacketInfo.Guid.GetCounter()] = pet;
@@ -395,6 +399,7 @@ namespace Game.BattlePets
return; return;
pet.PacketInfo.Name = name; pet.PacketInfo.Name = name;
pet.NameTimestamp = !pet.PacketInfo.Name.IsEmpty() ? GameTime.GetGameTime() : 0;
pet.DeclinedName = new DeclinedName(); pet.DeclinedName = new DeclinedName();
if (declinedName != null) if (declinedName != null)
@@ -402,6 +407,14 @@ namespace Game.BattlePets
if (pet.SaveInfo != BattlePetSaveInfo.New) if (pet.SaveInfo != BattlePetSaveInfo.New)
pet.SaveInfo = BattlePetSaveInfo.Changed; pet.SaveInfo = BattlePetSaveInfo.Changed;
// Update the timestamp if the battle pet is summoned
Player player = _owner.GetPlayer();
Creature summonedBattlePet = ObjectAccessor.GetCreatureOrPetOrVehicle(player, player.GetCritterGUID());
if (summonedBattlePet != null)
if (player.GetSummonedBattlePetGUID() == summonedBattlePet.GetBattlePetCompanionGUID())
if (summonedBattlePet.GetBattlePetCompanionGUID() == guid)
summonedBattlePet.SetBattlePetCompanionNameTimestamp((uint)pet.NameTimestamp);
} }
bool IsPetInSlot(ObjectGuid guid) bool IsPetInSlot(ObjectGuid guid)
@@ -533,20 +546,21 @@ namespace Game.BattlePets
return; return;
// TODO: set proper CreatureID for spell DEFAULT_SUMMON_BATTLE_PET_SPELL (default EffectMiscValueA is 40721 - Murkimus the Gladiator) // TODO: set proper CreatureID for spell DEFAULT_SUMMON_BATTLE_PET_SPELL (default EffectMiscValueA is 40721 - Murkimus the Gladiator)
_owner.GetPlayer().SetSummonedBattlePetGUID(guid); Player player = _owner.GetPlayer();
_owner.GetPlayer().SetCurrentBattlePetBreedQuality(pet.PacketInfo.Quality); player.SetSummonedBattlePetGUID(guid);
_owner.GetPlayer().CastSpell(_owner.GetPlayer(), speciesEntry.SummonSpellID != 0 ? speciesEntry.SummonSpellID : SharedConst.DefaultSummonBattlePetSpell); player.SetCurrentBattlePetBreedQuality(pet.PacketInfo.Quality);
player.CastSpell(_owner.GetPlayer(), speciesEntry.SummonSpellID != 0 ? speciesEntry.SummonSpellID : SharedConst.DefaultSummonBattlePetSpell);
} }
public void DismissPet() public void DismissPet()
{ {
Player ownerPlayer = _owner.GetPlayer(); Player player = _owner.GetPlayer();
Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(ownerPlayer, ownerPlayer.GetCritterGUID()); Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(player, player.GetCritterGUID());
if (pet && ownerPlayer.m_activePlayerData.SummonedBattlePetGUID == pet.GetBattlePetCompanionGUID()) if (pet && player.GetSummonedBattlePetGUID() == pet.GetBattlePetCompanionGUID())
{ {
pet.DespawnOrUnsummon(); pet.DespawnOrUnsummon();
ownerPlayer.SetSummonedBattlePetGUID(ObjectGuid.Empty); player.SetSummonedBattlePetGUID(ObjectGuid.Empty);
ownerPlayer.SetCurrentBattlePetBreedQuality((byte)BattlePetBreedQuality.Poor); player.SetCurrentBattlePetBreedQuality((byte)BattlePetBreedQuality.Poor);
} }
} }
@@ -669,6 +683,7 @@ namespace Game.BattlePets
} }
public BattlePetStruct PacketInfo; public BattlePetStruct PacketInfo;
public long NameTimestamp;
public DeclinedName DeclinedName; public DeclinedName DeclinedName;
public BattlePetSaveInfo SaveInfo; public BattlePetSaveInfo SaveInfo;
} }
+1
View File
@@ -7444,6 +7444,7 @@ namespace Game.Entities
} }
public void ClearSelfResSpell() { ClearDynamicUpdateFieldValues(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SelfResSpells)); } public void ClearSelfResSpell() { ClearDynamicUpdateFieldValues(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SelfResSpells)); }
public ObjectGuid GetSummonedBattlePetGUID() { return m_activePlayerData.SummonedBattlePetGUID; }
public void SetSummonedBattlePetGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SummonedBattlePetGUID), guid); } public void SetSummonedBattlePetGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.SummonedBattlePetGUID), guid); }
public void AddTrackCreatureFlag(uint flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TrackCreatureMask), flags); } public void AddTrackCreatureFlag(uint flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TrackCreatureMask), flags); }
+3 -2
View File
@@ -147,10 +147,11 @@ namespace Game.Entities
Player thisPlayer = ToPlayer(); Player thisPlayer = ToPlayer();
if (thisPlayer != null) if (thisPlayer != null)
{ {
var pet = thisPlayer.GetSession().GetBattlePetMgr().GetPet(thisPlayer.m_activePlayerData.SummonedBattlePetGUID); var pet = thisPlayer.GetSession().GetBattlePetMgr().GetPet(thisPlayer.GetSummonedBattlePetGUID());
if (pet != null) if (pet != null)
{ {
minion.SetBattlePetCompanionGUID(thisPlayer.m_activePlayerData.SummonedBattlePetGUID); minion.SetBattlePetCompanionGUID(thisPlayer.GetSummonedBattlePetGUID());
minion.SetBattlePetCompanionNameTimestamp((uint)pet.NameTimestamp);
minion.SetWildBattlePetLevel(pet.PacketInfo.Level); minion.SetWildBattlePetLevel(pet.PacketInfo.Level);
} }
} }
+4 -1
View File
@@ -1906,8 +1906,11 @@ namespace Game.Entities
return IsCharmed() ? GetCharmer() : GetOwner(); return IsCharmed() ? GetCharmer() : GetOwner();
} }
public void SetWildBattlePetLevel(uint wildBattlePetLevel) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.WildBattlePetLevel), wildBattlePetLevel); } public uint GetBattlePetCompanionNameTimestamp() { return m_unitData.BattlePetCompanionNameTimestamp; }
public void SetBattlePetCompanionNameTimestamp(uint timestamp) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.BattlePetCompanionNameTimestamp), timestamp); }
public uint GetWildBattlePetLevel() { return m_unitData.WildBattlePetLevel; } public uint GetWildBattlePetLevel() { return m_unitData.WildBattlePetLevel; }
public void SetWildBattlePetLevel(uint wildBattlePetLevel) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.WildBattlePetLevel), wildBattlePetLevel); }
public bool HasUnitFlag(UnitFlags flags) { return (m_unitData.Flags & (uint)flags) != 0; } public bool HasUnitFlag(UnitFlags flags) { return (m_unitData.Flags & (uint)flags) != 0; }
public void AddUnitFlag(UnitFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Flags), (uint)flags); } public void AddUnitFlag(UnitFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Flags), (uint)flags); }
+44 -2
View File
@@ -17,6 +17,7 @@
using Framework.Constants; using Framework.Constants;
using Game.BattlePets; using Game.BattlePets;
using Game.Entities;
using Game.Networking; using Game.Networking;
using Game.Networking.Packets; using Game.Networking.Packets;
@@ -54,7 +55,48 @@ namespace Game
[WorldPacketHandler(ClientOpcodes.BattlePetModifyName)] [WorldPacketHandler(ClientOpcodes.BattlePetModifyName)]
void HandleBattlePetModifyName(BattlePetModifyName battlePetModifyName) void HandleBattlePetModifyName(BattlePetModifyName battlePetModifyName)
{ {
GetBattlePetMgr().ModifyName(battlePetModifyName.PetGuid, battlePetModifyName.Name, battlePetModifyName.DeclinedName.Value); GetBattlePetMgr().ModifyName(battlePetModifyName.PetGuid, battlePetModifyName.Name, battlePetModifyName.DeclinedNames.Value);
}
[WorldPacketHandler(ClientOpcodes.QueryBattlePetName)]
void HandleQueryBattlePetName(QueryBattlePetName queryBattlePetName)
{
QueryBattlePetNameResponse response = new();
response.BattlePetID = queryBattlePetName.BattlePetID;
Creature summonedBattlePet = ObjectAccessor.GetCreatureOrPetOrVehicle(_player, queryBattlePetName.UnitGUID);
if (!summonedBattlePet || !summonedBattlePet.IsSummon())
{
SendPacket(response);
return;
}
response.CreatureID = summonedBattlePet.GetEntry();
response.Timestamp = summonedBattlePet.GetBattlePetCompanionNameTimestamp();
Unit petOwner = summonedBattlePet.ToTempSummon().GetSummoner();
if (!petOwner.IsPlayer())
{
SendPacket(response);
return;
}
BattlePetMgr.BattlePet battlePet = petOwner.ToPlayer().GetSession().GetBattlePetMgr().GetPet(queryBattlePetName.BattlePetID);
if (battlePet == null)
{
SendPacket(response);
return;
}
response.Allow = true;
response.Name = battlePet.PacketInfo.Name;
if (battlePet.DeclinedName != null)
{
response.HasDeclined = true;
response.DeclinedNames = battlePet.DeclinedName;
}
SendPacket(response);
} }
[WorldPacketHandler(ClientOpcodes.BattlePetDeletePet)] [WorldPacketHandler(ClientOpcodes.BattlePetDeletePet)]
@@ -97,7 +139,7 @@ namespace Game
[WorldPacketHandler(ClientOpcodes.BattlePetSummon, Processing = PacketProcessing.Inplace)] [WorldPacketHandler(ClientOpcodes.BattlePetSummon, Processing = PacketProcessing.Inplace)]
void HandleBattlePetSummon(BattlePetSummon battlePetSummon) void HandleBattlePetSummon(BattlePetSummon battlePetSummon)
{ {
if (_player.m_activePlayerData.SummonedBattlePetGUID != battlePetSummon.PetGuid) if (_player.GetSummonedBattlePetGUID() != battlePetSummon.PetGuid)
GetBattlePetMgr().SummonPet(battlePetSummon.PetGuid); GetBattlePetMgr().SummonPet(battlePetSummon.PetGuid);
else else
GetBattlePetMgr().DismissPet(); GetBattlePetMgr().DismissPet();
@@ -139,7 +139,7 @@ namespace Game.Networking.Packets
if (_worldPacket.HasBit()) if (_worldPacket.HasBit())
{ {
DeclinedName.Set(new DeclinedName()); DeclinedNames.Set(new DeclinedName());
byte[] declinedNameLengths = new byte[SharedConst.MaxDeclinedNameCases]; byte[] declinedNameLengths = new byte[SharedConst.MaxDeclinedNameCases];
@@ -147,7 +147,7 @@ namespace Game.Networking.Packets
declinedNameLengths[i] = _worldPacket.ReadBits<byte>(7); declinedNameLengths[i] = _worldPacket.ReadBits<byte>(7);
for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i) for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i)
DeclinedName.Value.name[i] = _worldPacket.ReadString(declinedNameLengths[i]); DeclinedNames.Value.name[i] = _worldPacket.ReadString(declinedNameLengths[i]);
} }
Name = _worldPacket.ReadString(nameLength); Name = _worldPacket.ReadString(nameLength);
@@ -155,7 +155,60 @@ namespace Game.Networking.Packets
public ObjectGuid PetGuid; public ObjectGuid PetGuid;
public string Name; public string Name;
public Optional<DeclinedName> DeclinedName; public Optional<DeclinedName> DeclinedNames;
}
class QueryBattlePetName : ClientPacket
{
public QueryBattlePetName(WorldPacket packet) : base(packet) { }
public override void Read()
{
BattlePetID = _worldPacket.ReadPackedGuid();
UnitGUID = _worldPacket.ReadPackedGuid();
}
public ObjectGuid BattlePetID;
public ObjectGuid UnitGUID;
}
class QueryBattlePetNameResponse : ServerPacket
{
public QueryBattlePetNameResponse() : base(ServerOpcodes.QueryBattlePetNameResponse, ConnectionType.Instance) { }
public override void Write()
{
_worldPacket.WritePackedGuid(BattlePetID);
_worldPacket.WriteUInt32(CreatureID);
_worldPacket.WriteInt64(Timestamp);
_worldPacket.WriteBit(Allow);
if (Allow)
{
_worldPacket.WriteBits(Name.GetByteCount(), 8);
_worldPacket.WriteBit(HasDeclined);
for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i)
_worldPacket.WriteBits(DeclinedNames.name[i].GetByteCount(), 7);
for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i)
_worldPacket.WriteString(DeclinedNames.name[i]);
_worldPacket.WriteString(Name);
}
_worldPacket.FlushBits();
}
public ObjectGuid BattlePetID;
public uint CreatureID;
public long Timestamp;
public bool Allow;
public bool HasDeclined;
public DeclinedName DeclinedNames;
public string Name;
} }
class BattlePetDeletePet : ClientPacket class BattlePetDeletePet : ClientPacket
@@ -0,0 +1,3 @@
ALTER TABLE `battle_pets` ADD `nameTimestamp` bigint(20) NOT NULL DEFAULT '0' AFTER `name`;
UPDATE `battle_pets` SET `nameTimestamp`=UNIX_TIMESTAMP() WHERE LENGTH(`name`) > 0;