diff --git a/Source/Framework/Database/Databases/LoginDatabase.cs b/Source/Framework/Database/Databases/LoginDatabase.cs index eb698ea4f..d98b0361b 100644 --- a/Source/Framework/Database/Databases/LoginDatabase.cs +++ b/Source/Framework/Database/Databases/LoginDatabase.cs @@ -151,13 +151,15 @@ namespace Framework.Database PrepareStatement(LoginStatements.REP_ACCOUNT_TOYS, "REPLACE INTO battlenet_account_toys (accountId, itemId, isFavourite, hasFanfare) VALUES (?, ?, ?, ?)"); // Battle Pets - PrepareStatement(LoginStatements.SEL_BATTLE_PETS, "SELECT guid, species, breed, level, exp, health, quality, flags, name FROM battle_pets WHERE battlenetAccountId = ?"); + PrepareStatement(LoginStatements.SEL_BATTLE_PETS, "SELECT bp.guid, bp.species, bp.breed, 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.INS_BATTLE_PETS, "INSERT INTO battle_pets (guid, battlenetAccountId, species, breed, level, exp, health, quality, flags, name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); 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.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.DEL_BATTLE_PET_SLOTS, "DELETE FROM battle_pet_slots WHERE battlenetAccountId = ?"); + PrepareStatement(LoginStatements.INS_BATTLE_PET_DECLINED_NAME, "INSERT INTO battle_pet_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)"); + PrepareStatement(LoginStatements.DEL_BATTLE_PET_DECLINED_NAME, "DELETE FROM battle_pet_declinedname WHERE guid = ?"); PrepareStatement(LoginStatements.SEL_ACCOUNT_HEIRLOOMS, "SELECT itemId, flags FROM battlenet_account_heirlooms WHERE accountId = ?"); PrepareStatement(LoginStatements.REP_ACCOUNT_HEIRLOOMS, "REPLACE INTO battlenet_account_heirlooms (accountId, itemId, flags) VALUES (?, ?, ?)"); @@ -302,6 +304,8 @@ namespace Framework.Database SEL_BATTLE_PET_SLOTS, INS_BATTLE_PET_SLOTS, DEL_BATTLE_PET_SLOTS, + INS_BATTLE_PET_DECLINED_NAME, + DEL_BATTLE_PET_DECLINED_NAME, SEL_ACCOUNT_HEIRLOOMS, REP_ACCOUNT_HEIRLOOMS, diff --git a/Source/Game/BattlePets/BattlePetManager.cs b/Source/Game/BattlePets/BattlePetManager.cs index 26bbb4e32..0c9e9b314 100644 --- a/Source/Game/BattlePets/BattlePetManager.cs +++ b/Source/Game/BattlePets/BattlePetManager.cs @@ -179,6 +179,14 @@ namespace Game.BattlePets pet.PacketInfo.Flags = petsResult.Read(7); pet.PacketInfo.Name = petsResult.Read(8); pet.PacketInfo.CreatureID = speciesEntry.CreatureID; + + if (!petsResult.IsNull(9)) + { + pet.DeclinedName = new(); + for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i) + pet.DeclinedName.name[i] = petsResult.Read(9 + i); + } + pet.SaveInfo = BattlePetSaveInfo.Unchanged; pet.CalculateStats(); _pets[pet.PacketInfo.Guid.GetCounter()] = pet; @@ -223,6 +231,19 @@ namespace Game.BattlePets stmt.AddValue(8, pair.Value.PacketInfo.Flags); stmt.AddValue(9, pair.Value.PacketInfo.Name); trans.Append(stmt); + + if (pair.Value.DeclinedName != null) + { + stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_BATTLE_PET_DECLINED_NAME); + stmt.AddValue(0, pair.Key); + + for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; i++) + stmt.AddValue(i + 1, pair.Value.DeclinedName.name[i]); + + trans.Append(stmt); + } + + pair.Value.SaveInfo = BattlePetSaveInfo.Unchanged; break; case BattlePetSaveInfo.Changed: @@ -236,9 +257,29 @@ namespace Game.BattlePets stmt.AddValue(6, _owner.GetBattlenetAccountId()); stmt.AddValue(7, pair.Key); trans.Append(stmt); + + stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_BATTLE_PET_DECLINED_NAME); + stmt.AddValue(0, pair.Key); + trans.Append(stmt); + + if (pair.Value.DeclinedName != null) + { + stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_BATTLE_PET_DECLINED_NAME); + stmt.AddValue(0, pair.Key); + + for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; i++) + stmt.AddValue(i + 1, pair.Value.DeclinedName.name[i]); + + trans.Append(stmt); + } + pair.Value.SaveInfo = BattlePetSaveInfo.Unchanged; break; case BattlePetSaveInfo.Removed: + stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_BATTLE_PET_DECLINED_NAME); + stmt.AddValue(0, pair.Key); + trans.Append(stmt); + stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_BATTLE_PETS); stmt.AddValue(0, _owner.GetBattlenetAccountId()); stmt.AddValue(1, pair.Key); @@ -340,6 +381,22 @@ namespace Game.BattlePets pet.SaveInfo = BattlePetSaveInfo.Changed; } + public void ModifyName(ObjectGuid guid, string name, DeclinedName declinedName) + { + BattlePet pet = GetPet(guid); + if (pet == null) + return; + + pet.PacketInfo.Name = name; + + pet.DeclinedName = new DeclinedName(); + if (declinedName != null) + pet.DeclinedName = declinedName; + + if (pet.SaveInfo != BattlePetSaveInfo.New) + pet.SaveInfo = BattlePetSaveInfo.Changed; + } + bool IsPetInSlot(ObjectGuid guid) { foreach (BattlePetSlot slot in _slots) @@ -582,6 +639,7 @@ namespace Game.BattlePets } public BattlePetStruct PacketInfo; + public DeclinedName DeclinedName; public BattlePetSaveInfo SaveInfo; } } diff --git a/Source/Game/Handlers/BattlePetHandler.cs b/Source/Game/Handlers/BattlePetHandler.cs index fa25cc600..ee27e3052 100644 --- a/Source/Game/Handlers/BattlePetHandler.cs +++ b/Source/Game/Handlers/BattlePetHandler.cs @@ -45,14 +45,7 @@ namespace Game [WorldPacketHandler(ClientOpcodes.BattlePetModifyName)] void HandleBattlePetModifyName(BattlePetModifyName battlePetModifyName) { - BattlePetMgr.BattlePet pet = GetBattlePetMgr().GetPet(battlePetModifyName.PetGuid); - if (pet != null) - { - pet.PacketInfo.Name = battlePetModifyName.Name; - - if (pet.SaveInfo != BattlePetSaveInfo.New) - pet.SaveInfo = BattlePetSaveInfo.Changed; - } + GetBattlePetMgr().ModifyName(battlePetModifyName.PetGuid, battlePetModifyName.Name, battlePetModifyName.DeclinedName.Value); } [WorldPacketHandler(ClientOpcodes.BattlePetDeletePet)] diff --git a/Source/Game/Networking/Packets/BattlePetPackets.cs b/Source/Game/Networking/Packets/BattlePetPackets.cs index 1d661baaf..530736348 100644 --- a/Source/Game/Networking/Packets/BattlePetPackets.cs +++ b/Source/Game/Networking/Packets/BattlePetPackets.cs @@ -125,7 +125,7 @@ namespace Game.Networking.Packets if (_worldPacket.HasBit()) { - Declined = new DeclinedName(); + DeclinedName.Set(new DeclinedName()); byte[] declinedNameLengths = new byte[SharedConst.MaxDeclinedNameCases]; @@ -133,7 +133,7 @@ namespace Game.Networking.Packets declinedNameLengths[i] = _worldPacket.ReadBits(7); for (byte i = 0; i < SharedConst.MaxDeclinedNameCases; ++i) - Declined.name[i] = _worldPacket.ReadString(declinedNameLengths[i]); + DeclinedName.Value.name[i] = _worldPacket.ReadString(declinedNameLengths[i]); } Name = _worldPacket.ReadString(nameLength); @@ -141,7 +141,7 @@ namespace Game.Networking.Packets public ObjectGuid PetGuid; public string Name; - public DeclinedName Declined; + public Optional DeclinedName; } class BattlePetDeletePet : ClientPacket diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql index 5c3f6b593..27a1bac8a 100644 --- a/sql/base/auth_database.sql +++ b/sql/base/auth_database.sql @@ -199,6 +199,35 @@ LOCK TABLES `autobroadcast` WRITE; /*!40000 ALTER TABLE `autobroadcast` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `battle_pet_declinedname` +-- + +DROP TABLE IF EXISTS `battle_pet_declinedname`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `battle_pet_declinedname` ( + `guid` bigint NOT NULL, + `genitive` varchar(12) NOT NULL DEFAULT '', + `dative` varchar(12) NOT NULL DEFAULT '', + `accusative` varchar(12) NOT NULL DEFAULT '', + `instrumental` varchar(12) NOT NULL DEFAULT '', + `prepositional` varchar(12) NOT NULL DEFAULT '', + PRIMARY KEY (`guid`), + CONSTRAINT `fk_battle_pet__battle_pet_declinedname` FOREIGN KEY (`guid`) REFERENCES `battle_pets` (`guid`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `battle_pet_declinedname` +-- + +LOCK TABLES `battle_pet_declinedname` WRITE; +/*!40000 ALTER TABLE `battle_pet_declinedname` DISABLE KEYS */; +/*!40000 ALTER TABLE `battle_pet_declinedname` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + -- -- Table structure for table `battle_pet_slots` -- @@ -236,6 +265,7 @@ CREATE TABLE `battle_pets` ( `battlenetAccountId` int(10) NOT NULL, `species` int(10) NOT NULL, `breed` smallint(5) NOT NULL, + `displayId` int(11) NOT NULL DEFAULT '0', `level` smallint(5) NOT NULL DEFAULT '1', `exp` smallint(5) NOT NULL DEFAULT '0', `health` int(10) NOT NULL DEFAULT '1', @@ -2428,7 +2458,9 @@ INSERT INTO `updates` VALUES ('2021_09_10_00_auth.sql','DE94812ABC7B395C6C3405FB6718A8AF2C9F8FEC','ARCHIVED','2021-09-10 12:18:54',0), ('2021_10_07_00_auth.sql','45F2D92E28382F0CBE1F9B3A97693C0CC69E50BC','ARCHIVED','2021-10-07 10:32:05',0), ('2021_10_13_00_auth.sql','220E63385CACCBCEC36C57717DE369F2FCABCAAF','ARCHIVED','2021-10-13 21:15:05',0), -('2021_10_15_00_auth.sql','C8AA212AB2BB2DB5B3C2C9622A3874475AEFBD7B','ARCHIVED','2021-10-15 10:11:47',0); +('2021_10_15_00_auth.sql','C8AA212AB2BB2DB5B3C2C9622A3874475AEFBD7B','ARCHIVED','2021-10-15 10:11:47',0), +('2021_10_15_01_auth.sql','72A0437F0ADEC59FF9D6839DF845C473F693CA5B','RELEASED','2021-10-16 00:15:25',0), +('2021_10_16_00_auth.sql','FDC45C7BEFBAFC9BCE6C77377B026A59AE52EE21','RELEASED','2021-10-16 11:24:39',0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/auth/master/2021_10_15_01_auth.sql b/sql/updates/auth/master/2021_10_15_01_auth.sql new file mode 100644 index 000000000..53dafc768 --- /dev/null +++ b/sql/updates/auth/master/2021_10_15_01_auth.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS `battle_pet_declinedname`; +CREATE TABLE `battle_pet_declinedname` ( + `guid` bigint(20) NOT NULL, + `genitive` varchar(12) NOT NULL DEFAULT '', + `dative` varchar(12) NOT NULL DEFAULT '', + `accusative` varchar(12) NOT NULL DEFAULT '', + `instrumental` varchar(12) NOT NULL DEFAULT '', + `prepositional` varchar(12) NOT NULL DEFAULT '', + PRIMARY KEY (`guid`), + CONSTRAINT fk_battle_pet__battle_pet_declinedname FOREIGN KEY (`guid`) REFERENCES `battle_pets` (`guid`) ON DELETE RESTRICT ON UPDATE RESTRICT +) ENGINE=InnoDB DEFAULT CHARSET=utf8;