From 193489f3a7101be202b70ec73fd43874caf62d32 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Mon, 18 Jul 2016 21:14:24 +0200 Subject: [PATCH] Core/Players: Split playerBytes fields in characters table (cherry picked from commit 2a6f65f) (i think i don't have broken nothing, loged with fresh created chars and old chars and all looks to be ok) --- sql/base/characters_database.sql | 11 +- .../characters/2016_07_17_00_characters.sql | 20 ++ .../Implementation/CharacterDatabase.cpp | 15 +- .../Implementation/CharacterDatabase.h | 2 +- src/server/game/Entities/Player/Player.cpp | 197 +++++++++--------- src/server/game/Handlers/CharacterHandler.cpp | 4 +- 6 files changed, 140 insertions(+), 109 deletions(-) create mode 100644 sql/updates/characters/2016_07_17_00_characters.sql diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 94cf041028b..8fd61075224 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1364,8 +1364,13 @@ CREATE TABLE `characters` ( `level` tinyint(3) unsigned NOT NULL DEFAULT '0', `xp` int(10) unsigned NOT NULL DEFAULT '0', `money` bigint(20) unsigned NOT NULL DEFAULT '0', - `playerBytes` int(10) unsigned NOT NULL DEFAULT '0', - `playerBytes2` int(10) unsigned NOT NULL DEFAULT '0', + `skin` tinyint(3) unsigned NOT NULL DEFAULT '0', + `face` tinyint(3) unsigned NOT NULL DEFAULT '0', + `hairStyle` tinyint(3) unsigned NOT NULL DEFAULT '0', + `hairColor` tinyint(3) unsigned NOT NULL DEFAULT '0', + `facialStyle` tinyint(3) unsigned NOT NULL DEFAULT '0', + `bankSlots` tinyint(3) unsigned NOT NULL DEFAULT '0', + `restState` tinyint(3) unsigned NOT NULL DEFAULT '0', `playerFlags` int(10) unsigned NOT NULL DEFAULT '0', `position_x` float NOT NULL DEFAULT '0', `position_y` float NOT NULL DEFAULT '0', @@ -2787,7 +2792,7 @@ CREATE TABLE `updates` ( LOCK TABLES `updates` WRITE; /*!40000 ALTER TABLE `updates` DISABLE KEYS */; -INSERT INTO `updates` VALUES ('2014_10_28_00_characters.sql','DCC0367E2784919FBE6ED44D60057179','ARCHIVED','2014-10-28 21:00:00',0),('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_01_characters.sql','894F08B70449A5481FFAF394EE5571D7FC4D8A3A','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_02_characters.sql','97D7BE0CAADC79F3F11B9FD296B8C6CD40FE593B','ARCHIVED','2015-03-21 21:44:51',0),('2015_06_26_00_characters_335.sql','f8230a59a9e878a6f54f421d6621f1595bd93861','ARCHIVED','2015-03-21 21:44:51',0),('2016_01_11_00_characters_from_335.sql','AAECE4BA6FDCF0C34A57FADD11DB68DAFD8AE9CD','ARCHIVED','2016-01-10 21:57:56',0),('2016_01_11_01_characters_from_335.sql','F8682A431D50E54BDC4AC0E7DBED21AE8AAB6AD4','ARCHIVED','2015-09-29 22:23:32',0),('2016_01_11_02_characters_from_335.sql','4555A7F35C107E54C13D74D20F141039ED42943E','ARCHIVED','2015-10-29 20:32:37',0),('2016_01_14_from_335_2015_10_06_00_characters.sql','16842FDD7E8547F2260D3312F53EFF8761EFAB35','ARCHIVED','2015-10-11 19:47:41',0),('2016_01_14_from_335_2015_10_07_00_characters.sql','E15AB463CEBE321001D7BFDEA4B662FF618728FD','ARCHIVED','2015-10-11 19:47:41',0),('2016_01_14_from_335_2015_10_12_00_characters.sql','D6F9927BDED72AD0A81D6EC2C6500CBC34A39FA2','ARCHIVED','2015-10-13 01:06:25',0),('2016_01_14_from_335_2015_10_28_00_characters.sql','622A9CA8FCE690429EBE23BA071A37C7A007BF8B','ARCHIVED','2015-10-28 21:49:52',0),('2016_01_14_from_335_2015_11_03_00_characters.sql','CC045717B8FDD9733351E52A5302560CD08AAD57','ARCHIVED','2015-11-03 22:56:17',0),('2016_02_21_from_335_2016_02_10_00_characters.sql','F1B4DA202819CABC7319A4470A2D224A34609E97','RELEASED','2016-02-10 00:00:00',0),('2016_03_12_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-03-12 00:00:00',0); +INSERT INTO `updates` VALUES ('2014_10_28_00_characters.sql','DCC0367E2784919FBE6ED44D60057179','ARCHIVED','2014-10-28 21:00:00',0),('2015_03_20_00_characters.sql','B761760804EA73BD297F296C5C1919687DF7191C','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_01_characters.sql','894F08B70449A5481FFAF394EE5571D7FC4D8A3A','ARCHIVED','2015-03-21 21:44:15',0),('2015_03_20_02_characters.sql','97D7BE0CAADC79F3F11B9FD296B8C6CD40FE593B','ARCHIVED','2015-03-21 21:44:51',0),('2015_06_26_00_characters_335.sql','f8230a59a9e878a6f54f421d6621f1595bd93861','ARCHIVED','2015-03-21 21:44:51',0),('2016_01_11_00_characters_from_335.sql','AAECE4BA6FDCF0C34A57FADD11DB68DAFD8AE9CD','ARCHIVED','2016-01-10 21:57:56',0),('2016_01_11_01_characters_from_335.sql','F8682A431D50E54BDC4AC0E7DBED21AE8AAB6AD4','ARCHIVED','2015-09-29 22:23:32',0),('2016_01_11_02_characters_from_335.sql','4555A7F35C107E54C13D74D20F141039ED42943E','ARCHIVED','2015-10-29 20:32:37',0),('2016_01_14_from_335_2015_10_06_00_characters.sql','16842FDD7E8547F2260D3312F53EFF8761EFAB35','ARCHIVED','2015-10-11 19:47:41',0),('2016_01_14_from_335_2015_10_07_00_characters.sql','E15AB463CEBE321001D7BFDEA4B662FF618728FD','ARCHIVED','2015-10-11 19:47:41',0),('2016_01_14_from_335_2015_10_12_00_characters.sql','D6F9927BDED72AD0A81D6EC2C6500CBC34A39FA2','ARCHIVED','2015-10-13 01:06:25',0),('2016_01_14_from_335_2015_10_28_00_characters.sql','622A9CA8FCE690429EBE23BA071A37C7A007BF8B','ARCHIVED','2015-10-28 21:49:52',0),('2016_01_14_from_335_2015_11_03_00_characters.sql','CC045717B8FDD9733351E52A5302560CD08AAD57','ARCHIVED','2015-11-03 22:56:17',0),('2016_02_21_from_335_2016_02_10_00_characters.sql','F1B4DA202819CABC7319A4470A2D224A34609E97','RELEASED','2016-02-10 00:00:00',0),('2016_03_12_00_characters.sql','0ACDD35EC9745231BCFA701B78056DEF94D0CC53','RELEASED','2016-03-12 00:00:00',0), ('2016_07_17_00_characters.sql', '41BF94C59FE13A61067E6721092F6187E184F37B', 'RELEASED', '2016-07-18 21:05:05', 0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/2016_07_17_00_characters.sql b/sql/updates/characters/2016_07_17_00_characters.sql new file mode 100644 index 00000000000..5c162df5ee4 --- /dev/null +++ b/sql/updates/characters/2016_07_17_00_characters.sql @@ -0,0 +1,20 @@ +-- +ALTER TABLE `characters` + ADD `skin` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `money`, + ADD `face` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `skin`, + ADD `hairStyle` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `face`, + ADD `hairColor` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `hairStyle`, + ADD `facialStyle` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `hairColor`, + ADD `bankSlots` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `facialStyle`, + ADD `restState` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `bankSlots`; + +UPDATE `characters` SET + `skin`=`playerBytes`&0xFF, + `face`=(`playerBytes`>>8)&0xFF, + `hairStyle`=(`playerBytes`>>16)&0xFF, + `hairColor`=(`playerBytes`>>24)&0xFF, + `facialStyle`=`playerBytes2`&0xFF, + `bankSlots`=(`playerBytes2`>>16)&0xFF, + `restState`=(`playerBytes2`>>24)&0xFF; + +ALTER TABLE `characters` DROP `playerBytes`, DROP `playerBytes2`; diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 470b73179a1..67acee0f088 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -42,11 +42,11 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_MAIL_LIST_INFO, "SELECT id, sender, (SELECT name FROM characters WHERE guid = sender) AS sendername, receiver, (SELECT name FROM characters WHERE guid = receiver) AS receivername, " "subject, deliver_time, expire_time, money, has_items FROM mail WHERE receiver = ? ", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_MAIL_LIST_ITEMS, "SELECT itemEntry,count FROM item_instance WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, " + PrepareStatement(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.skin, c.face, c.hairStyle, c.hairColor, c.facialStyle, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, " "gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, c.slot " "FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid " "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, " + PrepareStatement(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.skin, c.face, c.hairStyle, c.hairColor, c.facialStyle, c.level, c.zone, c.map, " "c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, " "cb.guid, c.slot, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? " "LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid " @@ -64,7 +64,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_BATTLEGROUND_RANDOM, "DELETE FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " + PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, " "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " "resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " @@ -369,7 +369,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_LFG_DATA, "DELETE FROM lfg_data WHERE guid = ?", CONNECTION_ASYNC); // Player saving - PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " + PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, " "map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, " "taximask, cinematic, " "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, talentTree, " @@ -377,8 +377,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() "death_expire_time, taxi_path, totalKills, " "todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, " "power4, power5, latency, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?," + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,skin=?,face=?,hairStyle=?,hairColor=?,facialStyle=?,bankSlots=?,restState=?,playerFlags=?," "map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,talentTree=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," "totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?," @@ -426,7 +426,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_CHAR_INSTANCE, "UPDATE character_instance SET instance = ?, permanent = ?, extendState = ? WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_CHAR_INSTANCE, "INSERT INTO character_instance (guid, instance, permanent, extendState) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GENDER_PLAYERBYTES, "UPDATE characters SET gender = ?, playerBytes = ?, playerBytes2 = ? WHERE guid = ?", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_GENDER_AND_APPEARANCE, "UPDATE characters SET gender = ?, skin = ?, face = ?, hairStyle = ?, hairColor = ?, facialStyle = ? WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_CHARACTER_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags | ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags & ~ ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); @@ -459,7 +459,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, "SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid = ? AND type = ? LIMIT 1", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PLAYERBYTES2, "SELECT playerBytes2 FROM characters WHERE guid = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_SEL_CHAR_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_SYNCH); PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 2eba8d065a8..5fd48824284 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -351,7 +351,7 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, CHAR_UPD_CHAR_INSTANCE, CHAR_INS_CHAR_INSTANCE, - CHAR_UPD_GENDER_PLAYERBYTES, + CHAR_UPD_GENDER_AND_APPEARANCE, CHAR_DEL_CHARACTER_SKILL, CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS, CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS, diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7efd9aba585..b7ae32f94b9 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1606,12 +1606,14 @@ void Player::setDeathState(DeathState s) bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer) { - // 0 1 2 3 4 5 6 7 - // "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, " - // 8 9 10 11 12 13 14 - // "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, " - // 15 16 17 18 19 20 21 22 - // "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data, character_banned.guid, characters.slot, character_declinedname.genitive" + // 0 1 2 3 4 5 6 7 + // SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.skin, characters.face, characters.hairStyle, + // 8 9 10 11 12 13 14 15 + // characters.hairColor, characters.facialStyle, characters.level, characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, + // 16 17 18 19 20 21 22 + // guild_member.guildid, characters.playerFlags, characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data, + // 23 24 25 + // character_banned.guid, characters.slot, character_declinedname.genitive Field* fields = result->Fetch(); @@ -1620,25 +1622,25 @@ bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, B uint8 plrRace = fields[2].GetUInt8(); uint8 plrClass = fields[3].GetUInt8(); uint8 gender = fields[4].GetUInt8(); - uint8 skin = uint8(fields[5].GetUInt32() & 0xFF); - uint8 face = uint8((fields[5].GetUInt32() >> 8) & 0xFF); - uint8 hairStyle = uint8((fields[5].GetUInt32() >> 16) & 0xFF); - uint8 hairColor = uint8((fields[5].GetUInt32() >> 24) & 0xFF); - uint8 facialHair = uint8(fields[6].GetUInt32() & 0xFF); - uint8 level = fields[7].GetUInt8(); - uint32 zone = fields[8].GetUInt16(); - uint32 mapId = uint32(fields[9].GetUInt16()); - float x = fields[10].GetFloat(); - float y = fields[11].GetFloat(); - float z = fields[12].GetFloat(); - uint32 guildId = fields[13].GetUInt32(); + uint8 skin = fields[5].GetUInt8(); + uint8 face = fields[6].GetUInt8(); + uint8 hairStyle = fields[7].GetUInt8(); + uint8 hairColor = fields[8].GetUInt8(); + uint8 facialHair = fields[9].GetUInt8(); + uint8 level = fields[10].GetUInt8(); + uint32 zone = fields[11].GetUInt16(); + uint32 mapId = uint32(fields[12].GetUInt16()); + float x = fields[13].GetFloat(); + float y = fields[14].GetFloat(); + float z = fields[15].GetFloat(); + uint32 guildId = fields[16].GetUInt32(); ObjectGuid guildGuid; if (guildId) guildGuid = ObjectGuid(HighGuid::Guild, guildId); - uint32 playerFlags = fields[14].GetUInt32(); - uint32 atLoginFlags = fields[15].GetUInt16(); - Tokenizer equipment(fields[19].GetString(), ' '); - uint8 slot = fields[21].GetUInt8(); + uint32 playerFlags = fields[17].GetUInt32(); + uint32 atLoginFlags = fields[18].GetUInt16(); + Tokenizer equipment(fields[22].GetString(), ' '); + uint8 slot = fields[24].GetUInt8(); if (!ValidateAppearance(uint8(plrRace), uint8(plrClass), gender, hairStyle, hairColor, face, facialHair, skin)) { @@ -1670,7 +1672,7 @@ bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, B if (atLoginFlags & AT_LOGIN_RENAME) charFlags |= CHARACTER_FLAG_RENAME; - if (fields[20].GetUInt32()) + if (fields[23].GetUInt32()) charFlags |= CHARACTER_FLAG_LOCKED_BY_BILLING; if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) && !fields[22].GetString().empty()) @@ -1690,12 +1692,12 @@ bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, B // show pet at selection character in character list only for non-ghost character if (result && !(playerFlags & PLAYER_FLAGS_GHOST) && (plrClass == CLASS_WARLOCK || plrClass == CLASS_HUNTER || plrClass == CLASS_DEATH_KNIGHT)) { - uint32 entry = fields[16].GetUInt32(); + uint32 entry = fields[19].GetUInt32(); CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry); if (creatureInfo) { - petDisplayId = fields[17].GetUInt32(); - petLevel = fields[18].GetUInt16(); + petDisplayId = fields[20].GetUInt32(); + petLevel = fields[21].GetUInt16(); petFamily = creatureInfo->family; } } @@ -1740,7 +1742,7 @@ bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, B for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot) { // values stored in 2 uint16 - uint32 enchantId = 0x0000FFFF & (enchants >> enchantSlot*16); + uint32 enchantId = 0x0000FFFF & (enchants >> enchantSlot * 16); if (!enchantId) continue; @@ -16934,17 +16936,17 @@ bool Player::IsLoading() const bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) { - //// 0 1 2 3 4 5 6 7 8 9 10 11 - //QueryResult* result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " + //// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + //QueryResult* result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, bankSlots, restState, playerFlags, " // 12 13 14 15 16 17 18 19 20 21 22 23 24 //"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - // 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 + // 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 //"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " - // 40 41 42 43 44 45 + // 45 46 47 48 49 50 //"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " - // 46 47 48 49 50 51 52 53 54 55 56 + // 51 52 53 54 55 56 57 58 59 60 61 //"health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, " - // 57 58 59 + // 62 63 64 //"knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid); PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM); if (!result) @@ -16979,8 +16981,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) // check name limitations if (ObjectMgr::CheckPlayerName(m_name, GetSession()->GetSessionDbcLocale()) != CHAR_NAME_SUCCESS || - (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && - sObjectMgr->IsReservedName(m_name))) + (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(m_name))) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(AT_LOGIN_RENAME)); @@ -17017,8 +17018,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8()); SetUInt32Value(PLAYER_XP, fields[7].GetUInt32()); - _LoadIntoDataField(fields[55].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); - _LoadIntoDataField(fields[57].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2); + _LoadIntoDataField(fields[60].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); + _LoadIntoDataField(fields[62].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2); SetObjectScale(1.0f); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); @@ -17031,17 +17032,23 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) money = MAX_MONEY_AMOUNT; SetMoney(money); - SetUInt32Value(PLAYER_BYTES, fields[9].GetUInt32()); - SetUInt32Value(PLAYER_BYTES_2, fields[10].GetUInt32()); + SetByteValue(PLAYER_BYTES, 0, fields[9].GetUInt8()); + SetByteValue(PLAYER_BYTES, 1, fields[10].GetUInt8()); + SetByteValue(PLAYER_BYTES, 2, fields[11].GetUInt8()); + SetByteValue(PLAYER_BYTES, 3, fields[12].GetUInt8()); + SetByteValue(PLAYER_BYTES_2, 0, fields[13].GetUInt8()); + SetByteValue(PLAYER_BYTES_2, 2, fields[14].GetUInt8()); + SetByteValue(PLAYER_BYTES_2, 3, fields[15].GetUInt8()); SetByteValue(PLAYER_BYTES_3, 0, fields[5].GetUInt8()); - SetByteValue(PLAYER_BYTES_3, 1, fields[45].GetUInt8()); + SetByteValue(PLAYER_BYTES_3, 1, fields[50].GetUInt8()); if (!ValidateAppearance( fields[3].GetUInt8(), // race fields[4].GetUInt8(), // class - gender, GetByteValue(PLAYER_BYTES, 2), // hair type + gender, + GetByteValue(PLAYER_BYTES, 2), // hair type GetByteValue(PLAYER_BYTES, 3), //hair color - uint8(fields[9].GetUInt32() >> 8), // face + GetByteValue(PLAYER_BYTES, 1), // face GetByteValue(PLAYER_BYTES_2, 0), // facial hair GetByteValue(PLAYER_BYTES, 0))) // skin color { @@ -17049,11 +17056,11 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) return false; } - SetUInt32Value(PLAYER_FLAGS, fields[11].GetUInt32()); - SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[44].GetUInt32()); + SetUInt32Value(PLAYER_FLAGS, fields[16].GetUInt32()); + SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[49].GetUInt32()); // set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise) - SetByteValue(PLAYER_FIELD_BYTES, 2, fields[58].GetUInt8()); + SetByteValue(PLAYER_FIELD_BYTES, 2, fields[63].GetUInt8()); InitDisplayIds(); @@ -17081,23 +17088,23 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) InitPrimaryProfessions(); // to max set before any spell loaded // init saved position, and fix it later if problematic - ObjectGuid::LowType transLowGUID = fields[31].GetUInt32(); + ObjectGuid::LowType transLowGUID = fields[36].GetUInt32(); - Relocate(fields[12].GetFloat(), fields[13].GetFloat(), fields[14].GetFloat(), fields[16].GetFloat()); + Relocate(fields[17].GetFloat(), fields[18].GetFloat(), fields[19].GetFloat(), fields[21].GetFloat()); - uint32 mapId = fields[15].GetUInt16(); - uint32 instanceId = fields[52].GetUInt32(); + uint32 mapId = fields[20].GetUInt16(); + uint32 instanceId = fields[57].GetUInt32(); - uint32 dungeonDiff = fields[39].GetUInt8() & 0x0F; + uint32 dungeonDiff = fields[44].GetUInt8() & 0x0F; if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY) dungeonDiff = DUNGEON_DIFFICULTY_NORMAL; - uint32 raidDiff = (fields[39].GetUInt8() >> 4) & 0x0F; + uint32 raidDiff = (fields[44].GetUInt8() >> 4) & 0x0F; if (raidDiff >= MAX_RAID_DIFFICULTY) raidDiff = RAID_DIFFICULTY_10MAN_NORMAL; SetDungeonDifficulty(Difficulty(dungeonDiff)); // may be changed in _LoadGroup SetRaidDifficulty(Difficulty(raidDiff)); // may be changed in _LoadGroup - std::string taxi_nodes = fields[38].GetString(); + std::string taxi_nodes = fields[43].GetString(); #define RelocateToHomebind(){ mapId = m_homebindMapId; instanceId = 0; Relocate(m_homebindX, m_homebindY, m_homebindZ); } @@ -17197,7 +17204,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) if (transport) { - float x = fields[27].GetFloat(), y = fields[28].GetFloat(), z = fields[29].GetFloat(), o = fields[30].GetFloat(); + float x = fields[32].GetFloat(), y = fields[33].GetFloat(), z = fields[34].GetFloat(), o = fields[35].GetFloat(); m_movementInfo.transport.pos.Relocate(x, y, z, o); transport->CalculatePassengerPosition(x, y, z, &o); @@ -17383,12 +17390,12 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) // randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE] // this must help in case next save after mass player load after server startup - m_nextSave = urand(m_nextSave/2, m_nextSave*3/2); + m_nextSave = urand(m_nextSave / 2, m_nextSave * 3 / 2); SaveRecallPosition(); time_t now = time(nullptr); - time_t logoutTime = time_t(fields[22].GetUInt32()); + time_t logoutTime = time_t(fields[27].GetUInt32()); // since last logout (in seconds) uint32 time_diff = uint32(now - logoutTime); //uint64 is excessive for a time_diff in seconds.. uint32 allows for 136~ year difference. @@ -17401,18 +17408,18 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) SetDrunkValue(newDrunkValue); - m_cinematic = fields[18].GetUInt8(); - m_Played_time[PLAYED_TIME_TOTAL]= fields[19].GetUInt32(); - m_Played_time[PLAYED_TIME_LEVEL]= fields[20].GetUInt32(); + m_cinematic = fields[23].GetUInt8(); + m_Played_time[PLAYED_TIME_TOTAL]= fields[24].GetUInt32(); + m_Played_time[PLAYED_TIME_LEVEL]= fields[25].GetUInt32(); - SetTalentResetCost(fields[24].GetUInt32()); - SetTalentResetTime(time_t(fields[25].GetUInt32())); + SetTalentResetCost(fields[29].GetUInt32()); + SetTalentResetTime(time_t(fields[30].GetUInt32())); - m_taxi.LoadTaxiMask(fields[17].GetString()); // must be before InitTaxiNodesForLevel + m_taxi.LoadTaxiMask(fields[22].GetString()); // must be before InitTaxiNodesForLevel - uint32 extraflags = fields[32].GetUInt16(); + uint32 extraflags = fields[37].GetUInt16(); - m_stableSlots = fields[33].GetUInt8(); + m_stableSlots = fields[38].GetUInt8(); if (m_stableSlots > MAX_PET_STABLES) { TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) can't have more stable slots than %u, but has %u in DB", @@ -17420,7 +17427,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) m_stableSlots = MAX_PET_STABLES; } - m_atLoginFlags = fields[34].GetUInt16(); + m_atLoginFlags = fields[39].GetUInt16(); if (HasAtLoginFlag(AT_LOGIN_RENAME)) { @@ -17433,7 +17440,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) m_lastHonorUpdateTime = logoutTime; UpdateHonorFields(); - m_deathExpireTime = time_t(fields[37].GetUInt32()); + m_deathExpireTime = time_t(fields[42].GetUInt32()); if (m_deathExpireTime > now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP) m_deathExpireTime = now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP - 1; @@ -17470,7 +17477,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) InitRunes(); // rest bonus can only be calculated after InitStatsForLevel() - m_rest_bonus = fields[21].GetFloat(); + m_rest_bonus = fields[26].GetFloat(); if (time_diff > 0) { @@ -17478,11 +17485,11 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) float bubble0 = 0.031f; //speed collect rest bonus in offline, in logout, in tavern, city (section/in hour) float bubble1 = 0.125f; - float bubble = fields[23].GetUInt8() > 0 + float bubble = fields[28].GetUInt8() > 0 ? bubble1*sWorld->getRate(RATE_REST_OFFLINE_IN_TAVERN_OR_CITY) : bubble0*sWorld->getRate(RATE_REST_OFFLINE_IN_WILDERNESS); - SetRestBonus(GetRestBonus()+ time_diff*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP)/72000)*bubble); + SetRestBonus(GetRestBonus() + time_diff*((float)GetUInt32Value(PLAYER_NEXT_LEVEL_XP) / 72000)*bubble); } // load skills after InitStatsForLevel because it triggering aura apply also @@ -17494,8 +17501,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) //mails are loaded only when needed ;-) - when player in game click on mailbox. //_LoadMail(); - SetSpecsCount(fields[53].GetUInt8()); - SetActiveSpec(fields[54].GetUInt8()); + SetSpecsCount(fields[58].GetUInt8()); + SetActiveSpec(fields[59].GetUInt8()); // sanity check if (GetSpecsCount() > MAX_TALENT_SPECS || GetActiveSpec() > MAX_TALENT_SPEC || GetSpecsCount() < MIN_TALENT_SPECS) @@ -17560,7 +17567,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) // check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded - uint32 curTitle = fields[43].GetUInt32(); + uint32 curTitle = fields[48].GetUInt32(); if (curTitle && !HasTitle(curTitle)) curTitle = 0; @@ -17583,14 +17590,14 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) UpdateAllStats(); // restore remembered power/health values (but not more max values) - uint32 savedHealth = fields[46].GetUInt32(); + uint32 savedHealth = fields[51].GetUInt32(); SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth); uint32 loadedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) { if (GetPowerIndex(i) != MAX_POWERS) { - uint32 savedPower = fields[47+loadedPowers].GetUInt32(); + uint32 savedPower = fields[52 + loadedPowers].GetUInt32(); uint32 maxPower = GetUInt32Value(UNIT_FIELD_MAXPOWER1 + loadedPowers); SetPower(Powers(i), (savedPower > maxPower) ? maxPower : savedPower); if (++loadedPowers >= MAX_POWERS_PER_CLASS) @@ -17666,7 +17673,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) } // RaF stuff. - m_grantableLevels = fields[59].GetUInt8(); + m_grantableLevels = fields[64].GetUInt8(); if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0)) SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND); @@ -19224,8 +19231,13 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, getLevel()); stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP)); stmt->setUInt64(index++, GetMoney()); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES)); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 0)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 1)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 2)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 3)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 0)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 2)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 3)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS)); stmt->setUInt16(index++, (uint16)GetMapId()); stmt->setUInt32(index++, (uint32)GetInstanceId()); @@ -19338,8 +19350,13 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, getLevel()); stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP)); stmt->setUInt64(index++, GetMoney()); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES)); - stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 0)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 1)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 2)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES, 3)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 0)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 2)); + stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, 3)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS)); if (!IsBeingTeleported()) @@ -20313,25 +20330,15 @@ void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 va void Player::Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransaction& trans) { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PLAYERBYTES2); - stmt->setUInt32(0, customizeInfo->Guid.GetCounter()); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (!result) - return; - - Field* fields = result->Fetch(); - - uint32 playerBytes2 = fields[0].GetUInt32(); - playerBytes2 &= ~0xFF; - playerBytes2 |= customizeInfo->FacialHair; - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_PLAYERBYTES); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GENDER_AND_APPEARANCE); stmt->setUInt8(0, customizeInfo->Gender); - stmt->setUInt32(1, customizeInfo->Skin | (customizeInfo->Face << 8) | (customizeInfo->HairStyle << 16) | (customizeInfo->HairColor << 24)); - stmt->setUInt32(2, playerBytes2); - stmt->setUInt32(3, customizeInfo->Guid.GetCounter()); + stmt->setUInt8(1, customizeInfo->Skin); + stmt->setUInt8(2, customizeInfo->Face); + stmt->setUInt8(3, customizeInfo->HairStyle); + stmt->setUInt8(4, customizeInfo->HairColor); + stmt->setUInt8(5, customizeInfo->FacialHair); + stmt->setUInt32(6, customizeInfo->Guid.GetCounter()); CharacterDatabase.ExecuteOrAppend(trans, stmt); } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 3d8e0661c83..e6135a30a39 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -251,11 +251,11 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result) Player::BuildEnumData(result, &dataBuffer, &bitBuffer); // Do not allow banned characters to log in - if (!(*result)[20].GetUInt32()) + if (!(*result)[23].GetUInt32()) _legitCharacters.insert(guid); if (!sWorld->HasCharacterInfo(guid)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet. - sWorld->AddCharacterInfo(guid, GetAccountId(), (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[7].GetUInt8()); + sWorld->AddCharacterInfo(guid, GetAccountId(), (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[10].GetUInt8()); } while (result->NextRow()); } else