aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/auth_database.sql26
-rw-r--r--sql/updates/auth/6.x/2016_10_01_00_auth.sql10
-rw-r--r--sql/updates/world/6.x/2016_10_00_00_world.sql59
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp4
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h3
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.cpp154
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.h20
-rw-r--r--src/server/game/Entities/Player/Player.cpp11
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp5
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp22
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h22
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp4
-rw-r--r--src/server/game/Server/WorldSession.cpp6
-rw-r--r--src/server/game/Server/WorldSession.h3
-rw-r--r--src/server/game/World/World.cpp3
15 files changed, 343 insertions, 9 deletions
diff --git a/sql/base/auth_database.sql b/sql/base/auth_database.sql
index 94b1871632c..2b168cb2a16 100644
--- a/sql/base/auth_database.sql
+++ b/sql/base/auth_database.sql
@@ -302,6 +302,30 @@ LOCK TABLES `battlenet_account_heirlooms` WRITE;
UNLOCK TABLES;
--
+-- Table structure for table `battlenet_account_mounts`
+--
+
+DROP TABLE IF EXISTS `battlenet_account_mounts`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `battlenet_account_mounts` (
+ `battlenetAccountId` int(10) unsigned NOT NULL,
+ `mountSpellId` int(10) unsigned NOT NULL,
+ `flags` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`battlenetAccountId`,`mountSpellId`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `battlenet_account_mounts`
+--
+
+LOCK TABLES `battlenet_account_mounts` WRITE;
+/*!40000 ALTER TABLE `battlenet_account_mounts` DISABLE KEYS */;
+/*!40000 ALTER TABLE `battlenet_account_mounts` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
-- Table structure for table `battlenet_account_toys`
--
@@ -733,7 +757,7 @@ CREATE TABLE `updates` (
LOCK TABLES `updates` WRITE;
/*!40000 ALTER TABLE `updates` DISABLE KEYS */;
-INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','ARCHIVED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','ARCHIVED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_16_00_auth.sql','366AFFD1088762866091A81CE1EC64138B8B35F1','ARCHIVED','2015-11-08 00:46:02',62),('2015_10_17_00_auth.sql','AC0D45E905033F42093852D2C4476663BDACCB3D','ARCHIVED','2015-10-17 12:39:12',0),('2015_11_01_00_auth_2015_08_21_00.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-11-01 14:50:26',0),('2015_11_08_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',0),('2015_11_21_00_auth.sql','575A1D697CC6C7C517F7CCB950988267C99CE7FA','ARCHIVED','2015-11-21 21:25:38',0),('2015_12_07_00_auth.sql','24A07AC1F38E5D26A3599FC06D29E267418F69F3','ARCHIVED','2015-12-07 20:55:48',0),('2016_01_13_00_auth.sql','114527BCCB0DE286CBE6FDA3029DD0523D1037FA','ARCHIVED','2016-01-13 21:39:13',0),('2016_03_22_01_auth_2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-03-22 22:55:13',0),('2016_03_28_00_auth.sql','BA14D23D81FA24565F04A359090DE86C5E195209','ARCHIVED','2016-03-28 16:49:32',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-04-11 02:24:14',30),('2016_04_17_00_auth.sql','83399B64D1221B56F73A0FFB51889F11A70521BC','RELEASED','2016-04-17 00:22:05',0),('2016_05_07_00_auth.sql','7E36DCC4F06FCDCDA7155AF3C5EDF8D3A720565F','RELEASED','2016-05-07 01:00:21',0),('2016_05_19_00_auth.sql','FB52E6BF35682CE6FA667B552B551F4FBD72AC30','RELEASED','2016-05-19 22:18:06',0),('2016_07_19_00_auth.sql','D5498F28A1E21F4AD0E0D7C2B96FCF7292C14C4D','RELEASED','2016-07-19 14:00:28',0),('2016_07_19_01_auth.sql','EBFE5D7D7E7CFA0CDA76AC49A1E8D4FA461A12BE','RELEASED','2016-07-19 16:06:39',0),('2016_07_23_00_auth.sql','1048F6A922ACD9BFC2E4518A71AF7037F79A85C4','RELEASED','2016-07-23 14:39:21',0),('2016_07_23_01_auth.sql','5897C7D8B8DE15895286FBCD1535FC75E1B70F62','RELEASED','2016-07-23 17:35:11',0),('2016_07_30_00_auth.sql','0FD4147840F7F02E2F1828A904B269F5B66097E0','RELEASED','2016-07-30 15:07:02',0),('2016_08_07_00_auth.sql','D9DD23851822E32E1312FFABEE2DB721C8651443','RELEASED','2016-08-07 15:33:42',0),('2016_08_11_00_auth.sql','0C79A86A4DFC53746BECF3D8A145482F94AE5FC9','RELEASED','2016-08-11 17:02:20',0),('2016_08_13_00_auth.sql','ED2286C4FF3D80D0F4DEE3D3121BCC15544470BE','RELEASED','2016-08-13 01:11:49',0),('2016_08_26_00_auth.sql','3C566371B6026EFEEA19CD215EC9F02C6DA9EAB3','RELEASED','2016-08-26 14:09:52',19),('2016_08_27_00_auth.sql','65ABEF7ACBCEA974C744ED42F95FBBD29226917B','RELEASED','2016-08-27 07:02:45',0),('2016_08_30_00_auth.sql','E16C19A938FE6370921658D2B713EE28A633FD56','RELEASED','2016-08-30 00:00:00',0),('2016_09_02_00_auth.sql','08932DAC4BDE74D3C39A43DDE404522F23EDD035','RELEASED','2016-09-02 00:00:00',0),('2016_09_03_00_auth_2016_05_11_00_auth.sql','401EFD3586772BDED66B4A944C20A1AC18A22D3A','RELEASED','2016-09-03 11:29:38',0),('2016_09_03_01_auth.sql','08B5ABCB74BBF25A30D37AF639F0EA1B10640673','RELEASED','2016-09-03 13:24:32',0),('2016_09_03_02_auth_2016_06_06_00_auth.sql','A0A8D73A952D0618833416513D53F73A70E7EA25','RELEASED','2016-09-03 15:56:50',0),('2016_09_03_03_auth.sql','9BF1C03EE39B6DC7E817BA46BE7D12A41AFBFDF7','RELEASED','2016-09-03 15:56:50',0),('2016_09_15_00_auth.sql','CD65F822AF1B5B7776E39804D0362F3E34AA6445','RELEASED','2016-09-15 16:30:36',0),('2016_09_21_00_auth.sql','57219A16B88080240EED94CDD41FC2764B8A32C5','RELEASED','2016-09-21 17:08:43',0),('2016_09_25_00_auth.sql','E811EFD8CE92ABEC5B8C02A09E643035939CF96D','RELEASED','2016-09-25 15:56:58',0);
+INSERT INTO `updates` VALUES ('2014_10_04_00_auth.sql','C3BC70A6EC381474B7308F442346F1E721176BC6','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_19_00_auth.sql','7472B490A4F86C9D3DA609CDD3197499CB80C87C','ARCHIVED','2015-03-21 16:55:52',0),('2014_10_26_00_auth.sql','75CC67ADE2A3B2E54FD57D6B0DCAA8FE50F4EE35','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_03_00_auth.sql','5948C9F286CF0FEA8E241785C0259FF36B73BDC5','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_04_00_auth.sql','3AFC68B2375C2A417DDEA94583C53AFF83DE50DF','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_09_00_auth.sql','B8DD1A7047C0FDDB80344B239343EC33BF1A0D97','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth.sql','8FBA737A1D3FF4631A1E662A5B500A8BD304EC63','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_00_auth_from_335.sql','0E3CB119442D09DD88E967015319BBC8DAFBBFE0','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_10_01_auth.sql','327E77A1DA3546D5275AB249915DD57EDD6FDD3D','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_23_00_auth.sql','0BBEB3EB3AED0FEF277A062819B6B2C00084A742','ARCHIVED','2015-03-21 16:55:52',0),('2014_11_25_00_auth.sql','4F45CDB26BDBB3EE83F1988E3D7818C5926ADC02','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_05_00_auth.sql','6A7BBCEF43111C73A2D2C3CCB6911BE50DE7DD94','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_10_00_auth.sql','821703A96D80F9080074852B5A46E2909C9562EA','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_19_00_auth.sql','44D8E12FFF327AD07878FBDF8D9C16B6B7DCB122','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_20_00_auth.sql','4DAA02AE285C02AE6C82EA2C8B97AC71990F1085','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_25_00_auth.sql','61411930F482BC73FC7FD2C370C811E944F5FF92','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_27_00_auth.sql','CE2E5D2CD82E79C25294539ADED27A1429105B43','ARCHIVED','2015-03-21 16:55:52',0),('2014_12_28_00_auth.sql','0A913217610E76AFF119C27259737BBC523090E6','ARCHIVED','2015-03-21 16:55:52',0),('2015_02_22_00_auth.sql','21CCCF8B01252E16CA3D6C9E3E8DAA4C9B28ED6E','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_01_00_auth.sql','911881E273207FF6182D1FDAC8C85FFAE8F1C852','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_10_00_auth.sql','2CC8502C11412EFEB5C11BE166761A8754A59009','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_00_auth.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_01_auth.sql','5CCEDF20C8189FB1E8DF064A9F0DDC342841FBF0','ARCHIVED','2015-03-21 16:55:52',0),('2015_03_20_02_auth.sql','85E4ACD9AA099C0C4AC034575F2BB07D348EAC72','ARCHIVED','2015-03-21 16:56:46',0),('2015_03_15_00_auth.sql','1D8E107FBEFE5E7F47E09F45240DFF499B77CDED','ARCHIVED','2015-05-02 13:57:57',0),('2015_03_26_00_auth.sql','34AC8543E6A9C6C832DE58EAB33618EEEF70B9F9','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_04_00_auth.sql','57146B35E54A2EC7869C945034AB078358020311','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_06_00_auth.sql','2A8049DC2923420A002D42FB6F02C2FFCC5CDD22','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_08_00_auth.sql','4D7D8EEF285C982BB676836602266501BEC26764','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_10_00_auth.sql','4AE68FD97A95CEE5143EA20FD33F5D557367AC1F','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_00_auth.sql','80A71C8921CFEBB547D264558B6DE27201685B84','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_11_01_auth.sql','3E88183E1A85D11BFD74CF9A32A725C44AE02EEC','ARCHIVED','2015-05-02 13:57:57',0),('2015_04_21_00_auth.sql','1B3B48DBA06368B985C548D166C515C9DD598CB9','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_00_auth.sql','96AB595E0D2A088750E3F48B0AF0A8A14F3CFE1E','ARCHIVED','2015-05-02 13:57:57',0),('2015_05_02_01_auth.sql','FB11FB834E488B0FD3AFDABCC1A3113092E7C2E5','ARCHIVED','2015-05-02 13:57:57',0),('2015_07_02_00_auth.sql','E5EE3842AB9B01851E49B360FBAF6FFEEAB2A8DA','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_06_00_auth.sql','6D1ADBA496DC6E6D7B3BF887DA8D4D17D3FBACE0','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_00_auth.sql','CB54020AFD1E31742FD8BF9CE16879625E289788','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_08_01_auth.sql','74D281CB82E0DA36D628BDC7AC797AE5498DB461','ARCHIVED','2015-07-10 19:30:56',0),('2015_07_16_00_auth.sql','A057E95B5553B6A57A1642FE3FEC8E2E62EDE3C6','ARCHIVED','2015-10-10 08:30:48',0),('2015_07_29_00_auth.sql','0000FECBC413E96C7C45F303D162E263EFBA7116','ARCHIVED','2015-10-10 08:30:48',0),('2015_08_26_00_auth.sql','3071C02A2EB7DCBF4CEE10279FEFAB7C29A43A3A','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_00_auth.sql','F765D82B37873FA67447347D5B83C99C159FB452','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_05_01_auth.sql','97A72DBCBF14D27A1863834A22296905FF276086','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_09_00_auth.sql','495A0CF1B1C49205D4A5D3C25A4E1EB95616D6B4','ARCHIVED','2015-10-10 08:30:48',0),('2015_09_15_00_auth.sql','D1FEFDA4C98F30384DF4B64D5A53187303EB5786','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_09_00_auth.sql','B6D643D444C6AE711503F73B96B6252A852913D6','ARCHIVED','2015-10-10 08:30:48',0),('2015_10_16_00_auth.sql','366AFFD1088762866091A81CE1EC64138B8B35F1','ARCHIVED','2015-11-08 00:46:02',62),('2015_10_17_00_auth.sql','AC0D45E905033F42093852D2C4476663BDACCB3D','ARCHIVED','2015-10-17 12:39:12',0),('2015_11_01_00_auth_2015_08_21_00.sql','C31A9E1D28E11B60BE8F8198637DD51F6D75123F','ARCHIVED','2015-11-01 14:50:26',0),('2015_11_08_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','ARCHIVED','2015-11-08 00:51:45',0),('2015_11_21_00_auth.sql','575A1D697CC6C7C517F7CCB950988267C99CE7FA','ARCHIVED','2015-11-21 21:25:38',0),('2015_12_07_00_auth.sql','24A07AC1F38E5D26A3599FC06D29E267418F69F3','ARCHIVED','2015-12-07 20:55:48',0),('2016_01_13_00_auth.sql','114527BCCB0DE286CBE6FDA3029DD0523D1037FA','ARCHIVED','2016-01-13 21:39:13',0),('2016_03_22_01_auth_2016_01_13_00_auth.sql','24615CC69B3CD7BB4699874647C35BA86E8A93FD','ARCHIVED','2016-03-22 22:55:13',0),('2016_03_28_00_auth.sql','BA14D23D81FA24565F04A359090DE86C5E195209','ARCHIVED','2016-03-28 16:49:32',0),('2016_04_11_00_auth.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-04-11 02:24:14',30),('2016_04_17_00_auth.sql','83399B64D1221B56F73A0FFB51889F11A70521BC','RELEASED','2016-04-17 00:22:05',0),('2016_05_07_00_auth.sql','7E36DCC4F06FCDCDA7155AF3C5EDF8D3A720565F','RELEASED','2016-05-07 01:00:21',0),('2016_05_19_00_auth.sql','FB52E6BF35682CE6FA667B552B551F4FBD72AC30','RELEASED','2016-05-19 22:18:06',0),('2016_07_19_00_auth.sql','D5498F28A1E21F4AD0E0D7C2B96FCF7292C14C4D','RELEASED','2016-07-19 14:00:28',0),('2016_07_19_01_auth.sql','EBFE5D7D7E7CFA0CDA76AC49A1E8D4FA461A12BE','RELEASED','2016-07-19 16:06:39',0),('2016_07_23_00_auth.sql','1048F6A922ACD9BFC2E4518A71AF7037F79A85C4','RELEASED','2016-07-23 14:39:21',0),('2016_07_23_01_auth.sql','5897C7D8B8DE15895286FBCD1535FC75E1B70F62','RELEASED','2016-07-23 17:35:11',0),('2016_07_30_00_auth.sql','0FD4147840F7F02E2F1828A904B269F5B66097E0','RELEASED','2016-07-30 15:07:02',0),('2016_08_07_00_auth.sql','D9DD23851822E32E1312FFABEE2DB721C8651443','RELEASED','2016-08-07 15:33:42',0),('2016_08_11_00_auth.sql','0C79A86A4DFC53746BECF3D8A145482F94AE5FC9','RELEASED','2016-08-11 17:02:20',0),('2016_08_13_00_auth.sql','ED2286C4FF3D80D0F4DEE3D3121BCC15544470BE','RELEASED','2016-08-13 01:11:49',0),('2016_08_26_00_auth.sql','3C566371B6026EFEEA19CD215EC9F02C6DA9EAB3','RELEASED','2016-08-26 14:09:52',19),('2016_08_27_00_auth.sql','65ABEF7ACBCEA974C744ED42F95FBBD29226917B','RELEASED','2016-08-27 07:02:45',0),('2016_08_30_00_auth.sql','E16C19A938FE6370921658D2B713EE28A633FD56','RELEASED','2016-08-30 00:00:00',0),('2016_09_02_00_auth.sql','08932DAC4BDE74D3C39A43DDE404522F23EDD035','RELEASED','2016-09-02 00:00:00',0),('2016_09_03_00_auth_2016_05_11_00_auth.sql','401EFD3586772BDED66B4A944C20A1AC18A22D3A','RELEASED','2016-09-03 11:29:38',0),('2016_09_03_01_auth.sql','08B5ABCB74BBF25A30D37AF639F0EA1B10640673','RELEASED','2016-09-03 13:24:32',0),('2016_09_03_02_auth_2016_06_06_00_auth.sql','A0A8D73A952D0618833416513D53F73A70E7EA25','RELEASED','2016-09-03 15:56:50',0),('2016_09_03_03_auth.sql','9BF1C03EE39B6DC7E817BA46BE7D12A41AFBFDF7','RELEASED','2016-09-03 15:56:50',0),('2016_09_15_00_auth.sql','CD65F822AF1B5B7776E39804D0362F3E34AA6445','RELEASED','2016-09-15 16:30:36',0),('2016_09_21_00_auth.sql','57219A16B88080240EED94CDD41FC2764B8A32C5','RELEASED','2016-09-21 17:08:43',0),('2016_09_25_00_auth.sql','E811EFD8CE92ABEC5B8C02A09E643035939CF96D','RELEASED','2016-09-25 15:56:58',0),('2016_10_01_00_auth.sql','7C444FF1B03BA3C83472BDA409854754D052D6FB','RELEASED','2016-10-01 13:32:43',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/auth/6.x/2016_10_01_00_auth.sql b/sql/updates/auth/6.x/2016_10_01_00_auth.sql
new file mode 100644
index 00000000000..de3ddcc1d2c
--- /dev/null
+++ b/sql/updates/auth/6.x/2016_10_01_00_auth.sql
@@ -0,0 +1,10 @@
+--
+-- Table structure for table `battlenet_account_mounts`
+--
+DROP TABLE IF EXISTS `battlenet_account_mounts`;
+CREATE TABLE `battlenet_account_mounts` (
+ `battlenetAccountId` int(10) unsigned NOT NULL,
+ `mountSpellId` int(10) unsigned NOT NULL,
+ `flags` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (`battlenetAccountId`,`mountSpellId`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/sql/updates/world/6.x/2016_10_00_00_world.sql b/sql/updates/world/6.x/2016_10_00_00_world.sql
new file mode 100644
index 00000000000..2a51293f498
--- /dev/null
+++ b/sql/updates/world/6.x/2016_10_00_00_world.sql
@@ -0,0 +1,59 @@
+DROP TABLE IF EXISTS `mount_definitions`;
+CREATE TABLE `mount_definitions`(
+ `spellId` int(10) unsigned NOT NULL,
+ `otherFactionSpellId` int(10) unsigned NOT NULL,
+ PRIMARY KEY (`spellId`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+DELETE FROM `mount_definitions`;
+INSERT INTO `mount_definitions` (`spellId`,`otherFactionSpellId`) VALUES
+(17229,64658),
+(23509,23510),
+(23510,23509),
+(55531,60424),
+(59785,59788),
+(59788,59785),
+(59797,59799),
+(59799,59797),
+(60114,60116),
+(60116,60114),
+(60118,60119),
+(60119,60118),
+(60424,55531),
+(61229,61230),
+(61230,61229),
+(61425,61447),
+(61447,61425),
+(61465,61467),
+(61467,61465),
+(61469,61470),
+(61470,61469),
+(61996,61997),
+(61997,61996),
+(64658,17229),
+(66087,66088),
+(66088,66087),
+(66090,66091),
+(66091,66090),
+(90621,93644),
+(92231,92232),
+(92232,92231),
+(93644,90621),
+(107516,107517),
+(107517,107516),
+(118737,130985),
+(130985,118737),
+(135416,135418),
+(135418,135416),
+(136163,136164),
+(136164,136163),
+(140249,140250),
+(140250,140249),
+(142266,142478),
+(142478,142266),
+(171625,171842),
+(171626,171839),
+(171839,171626),
+(171842,171625),
+(179244,179245),
+(179245,179244);
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index d1491aef171..083bdb383f1 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -163,6 +163,10 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_ACCOUNT_HEIRLOOMS, "SELECT itemId, flags FROM battlenet_account_heirlooms WHERE accountId = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_REP_ACCOUNT_HEIRLOOMS, "REPLACE INTO battlenet_account_heirlooms (accountId, itemId, flags) VALUES (?, ?, ?)", CONNECTION_ASYNC);
+ // Account wide mounts
+ PrepareStatement(LOGIN_SEL_ACCOUNT_MOUNTS, "SELECT mountSpellId, flags FROM battlenet_account_mounts WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_REP_ACCOUNT_MOUNTS, "REPLACE INTO battlenet_account_mounts (battlenetAccountId, mountSpellId, flags) VALUES (?, ?, ?)", CONNECTION_ASYNC);
+
// Transmog collection
PrepareStatement(LOGIN_SEL_BNET_ITEM_APPEARANCES, "SELECT blobIndex, appearanceMask FROM battlenet_item_appearances WHERE battlenetAccountId = ? ORDER BY blobIndex DESC", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_BNET_ITEM_APPEARANCES, "INSERT INTO battlenet_item_appearances (battlenetAccountId, blobIndex, appearanceMask) VALUES (?, ?, ?) "
diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index ecb2cb6786f..bddb119544e 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
@@ -152,6 +152,9 @@ enum LoginDatabaseStatements
LOGIN_SEL_ACCOUNT_HEIRLOOMS,
LOGIN_REP_ACCOUNT_HEIRLOOMS,
+ LOGIN_SEL_ACCOUNT_MOUNTS,
+ LOGIN_REP_ACCOUNT_MOUNTS,
+
LOGIN_SEL_BNET_ITEM_APPEARANCES,
LOGIN_INS_BNET_ITEM_APPEARANCES,
LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES,
diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp
index 297c67e3acf..b8b438ab64f 100644
--- a/src/server/game/Entities/Player/CollectionMgr.cpp
+++ b/src/server/game/Entities/Player/CollectionMgr.cpp
@@ -16,10 +16,53 @@
*/
#include "CollectionMgr.h"
+#include "MiscPackets.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "TransmogrificationPackets.h"
+namespace
+{
+ MountDefinitionMap FactionSpecificMounts;
+}
+
+void CollectionMgr::LoadMountDefinitions()
+{
+ uint32 oldMSTime = getMSTime();
+
+ QueryResult result = WorldDatabase.Query("SELECT spellId, otherFactionSpellId FROM mount_definitions");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 mount definitions. DB table `mount_definitions` is empty.");
+ return;
+ }
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 spellId = fields[0].GetUInt32();
+ uint32 otherFactionSpellId = fields[1].GetUInt32();
+
+ if (!sDB2Manager.GetMount(spellId))
+ {
+ TC_LOG_ERROR("sql.sql", "Mount spell %u defined in `mount_definitions` does not exist in Mount.db2, skipped", spellId);
+ continue;
+ }
+
+ if (otherFactionSpellId && !sDB2Manager.GetMount(otherFactionSpellId))
+ {
+ TC_LOG_ERROR("sql.sql", "otherFactionSpellId %u defined in `mount_definitions` for spell %u does not exist in Mount.db2, skipped", otherFactionSpellId, spellId);
+ continue;
+ }
+
+ FactionSpecificMounts[spellId] = otherFactionSpellId;
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " mount definitions in %u ms", FactionSpecificMounts.size(), GetMSTimeDiffToNow(oldMSTime));
+}
+
CollectionMgr::CollectionMgr(WorldSession* owner) : _owner(owner), _appearances()
{
}
@@ -195,7 +238,7 @@ void CollectionMgr::UpgradeHeirloom(uint32 itemId, uint32 castItem)
// Get heirloom offset to update only one part of dynamic field
std::vector<uint32> const& fields = player->GetDynamicValues(PLAYER_DYNAMIC_FIELD_HEIRLOOMS);
- uint8 offset = std::find(fields.begin(), fields.end(), itemId) - fields.begin();
+ uint8 offset = uint8(std::find(fields.begin(), fields.end(), itemId) - fields.begin());
player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, offset, flags);
itr->second.flags = flags;
@@ -235,7 +278,7 @@ void CollectionMgr::CheckHeirloomUpgrades(Item* item)
if (newItemId)
{
std::vector<uint32> const& fields = player->GetDynamicValues(PLAYER_DYNAMIC_FIELD_HEIRLOOMS);
- uint8 offset = std::find(fields.begin(), fields.end(), itr->first) - fields.begin();
+ uint8 offset = uint8(std::find(fields.begin(), fields.end(), itr->first) - fields.begin());
player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOMS, offset, newItemId);
player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, offset, 0);
@@ -274,6 +317,107 @@ bool CollectionMgr::CanApplyHeirloomXpBonus(uint32 itemId, uint32 level)
return level <= 60;
}
+void CollectionMgr::LoadMounts()
+{
+ for (auto const& m : _mounts)
+ AddMount(m.first, m.second, false, false);
+}
+
+void CollectionMgr::LoadAccountMounts(PreparedQueryResult result)
+{
+ if (!result)
+ return;
+
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 mountSpellId = fields[0].GetUInt32();
+ MountStatusFlags flags = MountStatusFlags(fields[1].GetUInt8());
+
+ if (!sDB2Manager.GetMount(mountSpellId))
+ continue;
+
+ _mounts[mountSpellId] = flags;
+ } while (result->NextRow());
+}
+
+void CollectionMgr::SaveAccountMounts(SQLTransaction& trans)
+{
+ for (auto const& mount : _mounts)
+ {
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_ACCOUNT_MOUNTS);
+ stmt->setUInt32(0, _owner->GetBattlenetAccountId());
+ stmt->setUInt32(1, mount.first);
+ stmt->setUInt8(2, mount.second);
+ trans->Append(stmt);
+ }
+}
+
+bool CollectionMgr::AddMount(uint32 spellId, MountStatusFlags flags, bool factionMount /*= false*/, bool learned /*= false*/)
+{
+ Player* player = _owner->GetPlayer();
+ if (!player)
+ return false;
+
+ MountEntry const* mount = sDB2Manager.GetMount(spellId);
+ if (!mount)
+ return false;
+
+ MountDefinitionMap::const_iterator itr = FactionSpecificMounts.find(spellId);
+ if (itr != FactionSpecificMounts.end() && !factionMount)
+ AddMount(itr->second, flags, true, learned);
+
+ _mounts.insert(MountContainer::value_type(spellId, flags));
+
+ // Mount condition only applies to using it, should still learn it.
+ if (mount->PlayerConditionId)
+ {
+ PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(mount->PlayerConditionId);
+ if (!ConditionMgr::IsPlayerMeetingCondition(player, playerCondition))
+ return false;
+ }
+
+ if (!learned)
+ {
+ if (!factionMount)
+ SendSingleMountUpdate(std::make_pair(spellId, flags));
+ if (!player->HasSpell(spellId))
+ player->LearnSpell(spellId, true);
+ }
+
+ return true;
+}
+
+void CollectionMgr::MountSetFavorite(uint32 spellId, bool favorite)
+{
+ auto itr = _mounts.find(spellId);
+ if (itr == _mounts.end())
+ return;
+
+ if (favorite)
+ itr->second = MountStatusFlags(itr->second | MOUNT_IS_FAVORITE);
+ else
+ itr->second = MountStatusFlags(itr->second & ~MOUNT_IS_FAVORITE);
+
+ SendSingleMountUpdate(*itr);
+}
+
+void CollectionMgr::SendSingleMountUpdate(std::pair<uint32, MountStatusFlags> mount)
+{
+ Player* player = _owner->GetPlayer();
+ if (!player)
+ return;
+
+ // Temporary container, just need to store only selected mount
+ MountContainer tempMounts;
+ tempMounts.insert(mount);
+
+ WorldPackets::Misc::AccountMountUpdate mountUpdate;
+ mountUpdate.IsFullUpdate = false;
+ mountUpdate.Mounts = &tempMounts;
+ player->SendDirectMessage(mountUpdate.Write());
+}
+
struct DynamicBitsetBlockOutputIterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
{
explicit DynamicBitsetBlockOutputIterator(std::function<void(uint32)>&& action) : _action(std::forward<std::function<void(uint32)>>(action)) { }
@@ -351,7 +495,7 @@ void CollectionMgr::SaveAccountItemAppearances(SQLTransaction& trans)
if (blockValue) // this table is only appended/bits are set (never cleared) so don't save empty blocks
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ITEM_APPEARANCES);
- stmt->setUInt32(0, GetOwner()->GetBattlenetAccountId());
+ stmt->setUInt32(0, _owner->GetBattlenetAccountId());
stmt->setUInt16(1, blockIndex);
stmt->setUInt32(2, blockValue);
trans->Append(stmt);
@@ -515,7 +659,7 @@ void CollectionMgr::AddItemAppearance(ItemModifiedAppearanceEntry const* itemMod
{
if (_appearances.size() <= itemModifiedAppearance->ID)
{
- uint32 numBlocks = _appearances.num_blocks();
+ std::size_t numBlocks = _appearances.num_blocks();
_appearances.resize(itemModifiedAppearance->ID + 1);
numBlocks = _appearances.num_blocks() - numBlocks;
while (numBlocks--)
@@ -619,7 +763,7 @@ void CollectionMgr::SendFavoriteAppearances() const
transmogCollectionUpdate.FavoriteAppearances.reserve(_favoriteAppearances.size());
for (auto itr = _favoriteAppearances.begin(); itr != _favoriteAppearances.end(); ++itr)
if (itr->second != FavoriteAppearanceState::Removed)
- transmogCollectionUpdate.FavoriteAppearances.push_back(itr->first);
+ transmogCollectionUpdate.FavoriteAppearances.push_back(itr->first);
_owner->SendPacket(transmogCollectionUpdate.Write());
}
diff --git a/src/server/game/Entities/Player/CollectionMgr.h b/src/server/game/Entities/Player/CollectionMgr.h
index 7090995689d..f78a88950ba 100644
--- a/src/server/game/Entities/Player/CollectionMgr.h
+++ b/src/server/game/Entities/Player/CollectionMgr.h
@@ -48,12 +48,22 @@ struct HeirloomData
typedef std::map<uint32, bool> ToyBoxContainer;
typedef std::map<uint32, HeirloomData> HeirloomContainer;
+enum MountStatusFlags : uint8
+{
+ MOUNT_STATUS_NONE = 0x00,
+ MOUNT_NEEDS_FANFARE = 0x01,
+ MOUNT_IS_FAVORITE = 0x02
+};
+
+typedef std::map<uint32, MountStatusFlags> MountContainer;
+typedef std::unordered_map<uint32, uint32> MountDefinitionMap;
+
class TC_GAME_API CollectionMgr
{
public:
explicit CollectionMgr(WorldSession* owner);
- WorldSession* GetOwner() const { return _owner; }
+ static void LoadMountDefinitions();
// Account-wide toys
void LoadToys();
@@ -83,6 +93,13 @@ public:
HeirloomContainer const& GetAccountHeirlooms() const { return _heirlooms; }
// Account-wide mounts
+ void LoadMounts();
+ void LoadAccountMounts(PreparedQueryResult result);
+ void SaveAccountMounts(SQLTransaction& trans);
+ bool AddMount(uint32 spellId, MountStatusFlags flags, bool factionMount = false, bool learned = false);
+ void MountSetFavorite(uint32 spellId, bool favorite);
+ void SendSingleMountUpdate(std::pair<uint32, MountStatusFlags> mount);
+ MountContainer const& GetAccountMounts() const { return _mounts; }
// Appearances
void LoadItemAppearances();
@@ -114,6 +131,7 @@ private:
ToyBoxContainer _toys;
HeirloomContainer _heirlooms;
+ MountContainer _mounts;
boost::dynamic_bitset<uint32> _appearances;
std::unordered_map<uint32, std::unordered_set<ObjectGuid>> _temporaryAppearances;
std::unordered_map<uint32, FavoriteAppearanceState> _favoriteAppearances;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index f4c2188c18a..81566daa587 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3149,6 +3149,10 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
UpdateCriteria(CRITERIA_TYPE_LEARN_SPELL, spellId);
}
+ // needs to be when spell is already learned, to prevent infinite recursion crashes
+ if (sDB2Manager.GetMount(spellId))
+ GetSession()->GetCollectionMgr()->AddMount(spellId, MOUNT_STATUS_NONE, false, IsInWorld() ? false : true);
+
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
return active && !disabled && !superceded_old;
}
@@ -17551,6 +17555,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
_LoadSpells(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS));
GetSession()->GetCollectionMgr()->LoadToys();
GetSession()->GetCollectionMgr()->LoadHeirlooms();
+ GetSession()->GetCollectionMgr()->LoadMounts();
GetSession()->GetCollectionMgr()->LoadItemAppearances();
LearnSpecializationSpells();
@@ -19604,6 +19609,7 @@ void Player::SaveToDB(bool create /*=false*/)
GetSession()->GetCollectionMgr()->SaveAccountToys(trans);
GetSession()->GetBattlePetMgr()->SaveToDB(trans);
GetSession()->GetCollectionMgr()->SaveAccountHeirlooms(trans);
+ GetSession()->GetCollectionMgr()->SaveAccountMounts(trans);
GetSession()->GetCollectionMgr()->SaveAccountItemAppearances(trans);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_LAST_PLAYER_CHARACTERS);
@@ -23041,6 +23047,11 @@ void Player::SendInitialPacketsBeforeAddToMap()
SendDirectMessage(worldServerInfo.Write());
// SMSG_ACCOUNT_MOUNT_UPDATE
+ WorldPackets::Misc::AccountMountUpdate mountUpdate;
+ mountUpdate.IsFullUpdate = true;
+ mountUpdate.Mounts = &GetSession()->GetCollectionMgr()->GetAccountMounts();
+ SendDirectMessage(mountUpdate.Write());
+
// SMSG_ACCOUNT_TOYS_UPDATE
WorldPackets::Toy::AccountToysUpdate toysUpdate;
toysUpdate.IsFullUpdate = true;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index b5a190c9a63..9b04213509b 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1154,3 +1154,8 @@ void WorldSession::HandleMountSpecialAnimOpcode(WorldPackets::Misc::MountSpecial
specialMountAnim.UnitGUID = _player->GetGUID();
GetPlayer()->SendMessageToSet(specialMountAnim.Write(), false);
}
+
+void WorldSession::HandleMountSetFavorite(WorldPackets::Misc::MountSetFavorite& mountSetFavorite)
+{
+ _collectionMgr->MountSetFavorite(mountSetFavorite.MountSpellID, mountSetFavorite.IsFavorite);
+}
diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp
index a773741b690..6cde22d5130 100644
--- a/src/server/game/Server/Packets/MiscPackets.cpp
+++ b/src/server/game/Server/Packets/MiscPackets.cpp
@@ -642,3 +642,25 @@ WorldPacket const* WorldPackets::Misc::DisplayGameError::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Misc::AccountMountUpdate::Write()
+{
+ _worldPacket.WriteBit(IsFullUpdate);
+ _worldPacket << uint32(Mounts->size());
+
+ for (auto const& spell : *Mounts)
+ {
+ _worldPacket << int32(spell.first);
+ _worldPacket.WriteBits(spell.second, 2);
+ }
+
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Misc::MountSetFavorite::Read()
+{
+ _worldPacket >> MountSpellID;
+ IsFavorite = _worldPacket.ReadBit();
+}
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index bf8c0549314..e4aa5ebd026 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -838,6 +838,28 @@ namespace WorldPackets
Optional<int32> Arg;
Optional<int32> Arg2;
};
+
+ class AccountMountUpdate final : public ServerPacket
+ {
+ public:
+ AccountMountUpdate() : ServerPacket(SMSG_ACCOUNT_MOUNT_UPDATE) { }
+
+ WorldPacket const* Write() override;
+
+ bool IsFullUpdate = false;
+ MountContainer const* Mounts = nullptr;
+ };
+
+ class MountSetFavorite final : public ClientPacket
+ {
+ public:
+ MountSetFavorite(WorldPacket&& packet) : ClientPacket(CMSG_MOUNT_SET_FAVORITE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 MountSpellID = 0;
+ bool IsFavorite = false;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index d6647db388c..f9e8e740bbc 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -498,7 +498,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_MINIMAP_PING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode);
DEFINE_HANDLER(CMSG_MISSILE_TRAJECTORY_COLLISION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMissileTrajectoryCollision);
DEFINE_HANDLER(CMSG_MOUNT_CLEAR_FANFARE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSetFavorite);
DEFINE_HANDLER(CMSG_MOUNT_SPECIAL_ANIM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode);
DEFINE_HANDLER(CMSG_MOVE_APPLY_MOVEMENT_FORCE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_MOVE_CHANGE_TRANSPORT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes);
@@ -835,7 +835,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_CRITERIA_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HEIRLOOM_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 2b3a1c20ef0..dec0b2a8793 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -1079,6 +1079,7 @@ public:
BATTLE_PET_SLOTS,
GLOBAL_ACCOUNT_HEIRLOOMS,
GLOBAL_REALM_CHARACTER_COUNTS,
+ MOUNTS,
ITEM_APPEARANCES,
ITEM_FAVORITE_APPEARANCES,
@@ -1107,6 +1108,10 @@ public:
stmt->setUInt32(0, battlenetAccountId);
ok = SetPreparedQuery(GLOBAL_ACCOUNT_HEIRLOOMS, stmt) && ok;
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MOUNTS);
+ stmt->setUInt32(0, battlenetAccountId);
+ ok = SetPreparedQuery(MOUNTS, stmt) && ok;
+
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID);
stmt->setUInt32(0, accountId);
ok = SetPreparedQuery(GLOBAL_REALM_CHARACTER_COUNTS, stmt) && ok;
@@ -1152,6 +1157,7 @@ void WorldSession::InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQue
LoadTutorialsData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS));
_collectionMgr->LoadAccountToys(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_TOYS));
_collectionMgr->LoadAccountHeirlooms(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_HEIRLOOMS));
+ _collectionMgr->LoadAccountMounts(holder->GetPreparedResult(AccountInfoQueryHolder::MOUNTS));
_collectionMgr->LoadAccountItemAppearances(holder->GetPreparedResult(AccountInfoQueryHolder::ITEM_APPEARANCES), holder->GetPreparedResult(AccountInfoQueryHolder::ITEM_FAVORITE_APPEARANCES));
if (!m_inQueue)
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 324e79d7f59..b244b5fd96c 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -432,6 +432,7 @@ namespace WorldPackets
class WorldTeleport;
class MountSpecial;
class SetTaxiBenchmarkMode;
+ class MountSetFavorite;
}
namespace Movement
@@ -1681,6 +1682,8 @@ class TC_GAME_API WorldSession
void HandleToySetFavorite(WorldPackets::Toy::ToySetFavorite& packet);
void HandleUseToy(WorldPackets::Toy::UseToy& packet);
+ void HandleMountSetFavorite(WorldPackets::Misc::MountSetFavorite& mountSetFavorite);
+
// Scenes
void HandleSceneTriggerEvent(WorldPackets::Scenes::SceneTriggerEvent& sceneTriggerEvent);
void HandleScenePlaybackComplete(WorldPackets::Scenes::ScenePlaybackComplete& scenePlaybackComplete);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 50ffc1d7a24..9461a3fac60 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1938,6 +1938,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading faction change title pairs...");
sObjectMgr->LoadFactionChangeTitles();
+ TC_LOG_INFO("server.loading", "Loading mount definitions...");
+ CollectionMgr::LoadMountDefinitions();
+
TC_LOG_INFO("server.loading", "Loading GM bugs...");
sSupportMgr->LoadBugTickets();