diff options
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Battlefield/BattlefieldHandler.cpp | 22 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 85 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.h | 105 | ||||
| -rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Handlers/GroupHandler.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 194 | ||||
| -rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 4 | ||||
| -rwxr-xr-x | src/server/game/Server/WorldSession.h | 4 |
9 files changed, 376 insertions, 50 deletions
diff --git a/src/server/game/Battlefield/BattlefieldHandler.cpp b/src/server/game/Battlefield/BattlefieldHandler.cpp index f16237b6e31..66285fe1b04 100644 --- a/src/server/game/Battlefield/BattlefieldHandler.cpp +++ b/src/server/game/Battlefield/BattlefieldHandler.cpp @@ -112,7 +112,7 @@ void WorldSession::SendBfQueueInviteResponse(uint64 guid, uint32 ZoneId, bool Ca ObjectGuid guidBytes = guid; WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, 16); - + data.WriteBit(guidBytes[1]); data.WriteBit(guidBytes[6]); data.WriteBit(guidBytes[5]); @@ -121,32 +121,32 @@ void WorldSession::SendBfQueueInviteResponse(uint64 guid, uint32 ZoneId, bool Ca data.WriteBit(guidBytes[0]); data.WriteBit(!hasSecondGuid); data.WriteBit(guidBytes[4]); - - // if (hasSecondGuid) 7 3 0 4 2 6 1 5 - + + // if (hasSecondGuid) 7 3 0 4 2 6 1 5 + data.WriteBit(guidBytes[3]); data.WriteBit(guidBytes[2]); - + // if (hasSecondGuid) 2 5 3 0 4 6 1 7 data.FlushBits(); data << uint8(CanQueue); // Accepted - + data.WriteByteSeq(guidBytes[1]); data.WriteByteSeq(guidBytes[3]); data.WriteByteSeq(guidBytes[6]); data.WriteByteSeq(guidBytes[7]); data.WriteByteSeq(guidBytes[0]); - + data << uint8(warmup); - + data.WriteByteSeq(guidBytes[2]); data.WriteByteSeq(guidBytes[4]); data.WriteByteSeq(guidBytes[5]); - + data << uint32(ZoneId); - + SendPacket(&data); } @@ -157,7 +157,7 @@ void WorldSession::SendBfEntered(uint64 guid) ObjectGuid guidBytes = guid; WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERED, 11); - + data.WriteBit(0); // unk data.WriteBit(isAFK); // Clear AFK data.WriteBit(guidBytes[1]); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bef557e0b8f..8ac3ba358dd 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -849,7 +849,8 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep _activeCheats = CHEAT_NONE; - memset(_voidStorageItems, 0, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*)); + memset(_voidStorageItems, NULL, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*)); + memset(_CUFProfiles, NULL, MAX_CUF_PROFILES * sizeof(CUFProfile*)); } Player::~Player() @@ -884,6 +885,9 @@ Player::~Player() for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) delete _voidStorageItems[i]; + for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) + delete _CUFProfiles[i]; + sWorld->DecreasePlayerCount(); } @@ -17325,9 +17329,46 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) _LoadEquipmentSets(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS)); + _LoadCUFProfiles(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES)); + return true; } +void Player::_LoadCUFProfiles(PreparedQueryResult result) +{ + if (!result) + return; + + do + { + // SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154 FROM character_cuf_profiles WHERE guid = ? + Field* fields = result->Fetch(); + + uint8 id = fields[0].GetUInt8(); + std::string name = fields[1].GetString(); + uint16 frameHeight = fields[2].GetUInt16(); + uint16 frameWidth = fields[3].GetUInt16(); + uint8 sortBy = fields[4].GetUInt8(); + uint8 healthText = fields[5].GetUInt8(); + uint32 boolOptions = fields[6].GetUInt32(); + uint8 unk146 = fields[7].GetUInt8(); + uint8 unk147 = fields[8].GetUInt8(); + uint8 unk148 = fields[9].GetUInt8(); + uint16 unk150 = fields[10].GetUInt16(); + uint16 unk152 = fields[11].GetUInt16(); + uint16 unk154 = fields[12].GetUInt16(); + + if (id > MAX_CUF_PROFILES) + { + sLog->outError(LOG_FILTER_PLAYER, "Player::_LoadCUFProfiles - Player (GUID: %u, name: %s) has an CUF profile with invalid id (id: %u), max is %i.", GetGUIDLow(), GetName(), id, MAX_CUF_PROFILES); + continue; + } + + _CUFProfiles[id] = new CUFProfile(name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154); + } + while (result->NextRow()); +} + bool Player::isAllowedToLoot(const Creature* creature) { if (!creature->isDead() || !creature->IsDamageEnoughForLootingAndReward()) @@ -18941,6 +18982,7 @@ void Player::SaveToDB(bool create /*=false*/) _SaveGlyphs(trans); _SaveInstanceTimeRestrictions(trans); _SaveCurrency(trans); + _SaveCUFProfiles(trans); // check if stats should only be saved on logout // save stats can be out of transaction @@ -19226,6 +19268,45 @@ void Player::_SaveVoidStorage(SQLTransaction& trans) } } + +void Player::_SaveCUFProfiles(SQLTransaction& trans) +{ + PreparedStatement* stmt = NULL; + uint32 lowGuid = GetGUIDLow(); + + for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) + { + if (!_CUFProfiles[i]) // unused profile + { + // DELETE FROM character_cuf_profiles WHERE guid = ? and id = ? + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_CUF_PROFILES); + stmt->setUInt32(0, lowGuid); + stmt->setUInt8(1, i); + } + else + { + // REPLACE INTO character_cuf_profiles (guid, id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_CUF_PROFILES); + stmt->setUInt32(0, lowGuid); + stmt->setUInt8(1, i); + stmt->setString(2, _CUFProfiles[i]->ProfileName); + stmt->setUInt16(3, _CUFProfiles[i]->FrameHeight); + stmt->setUInt16(4, _CUFProfiles[i]->FrameWidth); + stmt->setUInt8(5, _CUFProfiles[i]->SortBy); + stmt->setUInt8(6, _CUFProfiles[i]->HealthText); + stmt->setUInt32(7, _CUFProfiles[i]->BoolOptions.to_ulong()); // 24 of 31 fields used, fits in an int + stmt->setUInt8(8, _CUFProfiles[i]->Unk146); + stmt->setUInt8(9, _CUFProfiles[i]->Unk147); + stmt->setUInt8(10, _CUFProfiles[i]->Unk148); + stmt->setUInt16(11, _CUFProfiles[i]->Unk150); + stmt->setUInt16(12, _CUFProfiles[i]->Unk152); + stmt->setUInt16(13, _CUFProfiles[i]->Unk154); + } + + trans->Append(stmt); + } +} + void Player::_SaveMail(SQLTransaction& trans) { if (!m_mailsLoaded) @@ -22358,6 +22439,8 @@ void Player::SendInitialPacketsAfterAddToMap() ResetTimeSync(); SendTimeSync(); + Player::GetSession()->SendLoadCUFProfiles(); + CastSpell(this, 836, true); // LOGINEFFECT // set some aura effects that send packet to player client after add player to map diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index bfa70e611e6..89c56165390 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -19,6 +19,7 @@ #ifndef _PLAYER_H #define _PLAYER_H +#include <bitset> #include "AchievementMgr.h" #include "Battleground.h" #include "Bag.h" @@ -147,6 +148,94 @@ typedef UNORDERED_MAP<uint32, PlayerCurrency> PlayerCurrenciesMap; typedef std::list<uint64> WhisperListContainer; +/// Maximum number of CompactUnitFrames profiles +#define MAX_CUF_PROFILES 5 + +/// Bit index used in the many bool options of CompactUnitFrames +enum CUFBoolOptions +{ + CUF_KEEP_GROUPS_TOGETHER, + CUF_DISPLAY_PETS, + CUF_DISPLAY_MAIN_TANK_AND_ASSIST, + CUF_DISPLAY_HEAL_PREDICTION, + CUF_DISPLAY_AGGRO_HIGHLIGHT, + CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS, + CUF_DISPLAY_POWER_BAR, + CUF_DISPLAY_BORDER, + CUF_USE_CLASS_COLORS, + CUF_DISPLAY_NON_BOSS_DEBUFFS, + CUF_DISPLAY_HORIZONTAL_GROUPS, + CUF_LOCKED, + CUF_SHOWN, + CUF_AUTO_ACTIVATE_2_PLAYERS, + CUF_AUTO_ACTIVATE_3_PLAYERS, + CUF_AUTO_ACTIVATE_5_PLAYERS, + CUF_AUTO_ACTIVATE_10_PLAYERS, + CUF_AUTO_ACTIVATE_15_PLAYERS, + CUF_AUTO_ACTIVATE_25_PLAYERS, + CUF_AUTO_ACTIVATE_40_PLAYERS, + CUF_AUTO_ACTIVATE_SPEC_1, + CUF_AUTO_ACTIVATE_SPEC_2, + CUF_AUTO_ACTIVATE_PVP, + CUF_AUTO_ACTIVATE_PVE, + CUF_UNK_145, + CUF_UNK_156, + CUF_UNK_157, + + CUF_BOOL_OPTIONS_COUNT, +}; + +/// Represents a CompactUnitFrame profile +struct CUFProfile +{ + CUFProfile() : ProfileName(), BoolOptions() // might want to change default value for options + { + FrameHeight = 0; + FrameWidth = 0; + SortBy = 0; + HealthText = 0; + Unk146 = 0; + Unk147 = 0; + Unk148 = 0; + Unk150 = 0; + Unk152 = 0; + Unk154 = 0; + } + + CUFProfile(const std::string& name, uint16 frameHeight, uint16 frameWidth, uint8 sortBy, uint8 healthText, uint32 boolOptions, + uint8 unk146, uint8 unk147, uint8 unk148, uint16 unk150, uint16 unk152, uint16 unk154) + : ProfileName(name), BoolOptions((int)boolOptions) + { + FrameHeight = frameHeight; + FrameWidth = frameWidth; + SortBy = sortBy; + HealthText = healthText; + Unk146 = unk146; + Unk147 = unk147; + Unk148 = unk148; + Unk150 = Unk150; + Unk152 = unk152; + Unk154 = unk154; + } + + std::string ProfileName; + uint16 FrameHeight; + uint16 FrameWidth; + uint8 SortBy; + uint8 HealthText; + + uint8 Unk146; + uint8 Unk147; + uint8 Unk148; + uint16 Unk150; + uint16 Unk152; + uint16 Unk154; + + std::bitset<CUF_BOOL_OPTIONS_COUNT> BoolOptions; + + // More fields can be added to BoolOptions without changing DB schema (up to 31, currently 24) +}; + struct SpellCooldown { time_t end; @@ -793,6 +882,7 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOADSEASONALQUESTSTATUS = 31, PLAYER_LOGIN_QUERY_LOADVOIDSTORAGE = 32, PLAYER_LOGIN_QUERY_LOADCURRENCY = 33, + PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES = 34, MAX_PLAYER_LOGIN_QUERY, }; @@ -1577,6 +1667,17 @@ class Player : public Unit, public GridObject<Player> void AddTimedQuest(uint32 quest_id) { m_timedquests.insert(quest_id); } void RemoveTimedQuest(uint32 quest_id) { m_timedquests.erase(quest_id); } + void SaveCUFProfile(uint8 id, CUFProfile* profile) { delete _CUFProfiles[id]; _CUFProfiles[id] = profile; } ///> Replaces a CUF profile at position 0-4 + CUFProfile* GetCUFProfile(uint8 id) const { return _CUFProfiles[id]; } ///> Retrieves a CUF profile at position 0-4 + uint8 GetCUFProfilesCount() const + { + uint8 count = 0; + for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) + if (_CUFProfiles[i]) + ++count; + return count; + } + /*********************************************************/ /*** LOAD SYSTEM ***/ /*********************************************************/ @@ -2712,6 +2813,7 @@ class Player : public Unit, public GridObject<Player> void _LoadTalents(PreparedQueryResult result); void _LoadInstanceTimeRestrictions(PreparedQueryResult result); void _LoadCurrency(PreparedQueryResult result); + void _LoadCUFProfiles(PreparedQueryResult result); /*********************************************************/ /*** SAVE SYSTEM ***/ @@ -2735,6 +2837,7 @@ class Player : public Unit, public GridObject<Player> void _SaveStats(SQLTransaction& trans); void _SaveInstanceTimeRestrictions(SQLTransaction& trans); void _SaveCurrency(SQLTransaction& trans); + void _SaveCUFProfiles(SQLTransaction& trans); /*********************************************************/ /*** ENVIRONMENTAL SYSTEM ***/ @@ -2898,6 +3001,8 @@ class Player : public Unit, public GridObject<Player> uint8 m_grantableLevels; + CUFProfile* _CUFProfiles[MAX_CUF_PROFILES]; + private: // internal common parts for CanStore/StoreItem functions InventoryResult CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemTemplate const* pProto, uint32& count, bool swap, Item* pSrcItem) const; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 7e1195463a2..6609ef55494 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -166,6 +166,10 @@ bool LoginQueryHolder::Initialize() stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUF_PROFILES); + stmt->setUInt32(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_BGDATA); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADBGDATA, stmt); diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 1d6cbf61c68..3549e56fb88 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -513,7 +513,7 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_SET_ROLES"); - + uint32 newRole; ObjectGuid guid1; // Assigner GUID ObjectGuid guid2; // Target GUID @@ -539,7 +539,7 @@ void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) recvData.ReadByteSeq(guid2[5]); recvData.ReadByteSeq(guid2[2]); recvData.ReadByteSeq(guid2[7]); - + WorldPacket data(SMSG_GROUP_SET_ROLE, 24); data.WriteBit(guid1[1]); @@ -558,7 +558,7 @@ void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) data.WriteBit(guid1[6]); data.WriteBit(guid2[1]); data.WriteBit(guid1[0]); - + data.WriteByteSeq(guid1[7]); data.WriteByteSeq(guid2[3]); data.WriteByteSeq(guid1[6]); diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 5b5f83719e3..e127a5ba658 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -775,7 +775,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid) } int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0; - + if (int32 priceMod = _player->GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES)) price -= CalculatePctN(price, priceMod); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c6e0515a8ed..6499ead3685 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1940,35 +1940,165 @@ void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) HandleMovementOpcodes(recvPacket); } } - void WorldSession::HandleViolenceLevel(WorldPacket& recvPacket) - { - uint8 violenceLevel; - recvPacket >> violenceLevel; - - // do something? - } - - void WorldSession::HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket) - { - ObjectGuid guid; - guid[6] = recvPacket.ReadBit(); - guid[7] = recvPacket.ReadBit(); - guid[4] = recvPacket.ReadBit(); - guid[0] = recvPacket.ReadBit(); - guid[1] = recvPacket.ReadBit(); - guid[5] = recvPacket.ReadBit(); - guid[3] = recvPacket.ReadBit(); - guid[2] = recvPacket.ReadBit(); - - recvPacket.ReadByteSeq(guid[6]); - recvPacket.ReadByteSeq(guid[7]); - recvPacket.ReadByteSeq(guid[2]); - recvPacket.ReadByteSeq(guid[3]); - recvPacket.ReadByteSeq(guid[1]); - recvPacket.ReadByteSeq(guid[4]); - recvPacket.ReadByteSeq(guid[0]); - recvPacket.ReadByteSeq(guid[5]); - - WorldObject* obj = ObjectAccessor::GetWorldObject(*GetPlayer(), guid); - sLog->outError(LOG_FILTER_NETWORKIO, "Object update failed for object "UI64FMTD" (%s) for player %s (%u)", uint64(guid), obj ? obj->GetName() : "object-not-found", GetPlayerName().c_str(), GetGuidLow()); - } + +void WorldSession::HandleViolenceLevel(WorldPacket& recvPacket) +{ + uint8 violenceLevel; + recvPacket >> violenceLevel; + + // do something? +} + +void WorldSession::HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket) +{ + ObjectGuid guid; + guid[6] = recvPacket.ReadBit(); + guid[7] = recvPacket.ReadBit(); + guid[4] = recvPacket.ReadBit(); + guid[0] = recvPacket.ReadBit(); + guid[1] = recvPacket.ReadBit(); + guid[5] = recvPacket.ReadBit(); + guid[3] = recvPacket.ReadBit(); + guid[2] = recvPacket.ReadBit(); + + recvPacket.ReadByteSeq(guid[6]); + recvPacket.ReadByteSeq(guid[7]); + recvPacket.ReadByteSeq(guid[2]); + recvPacket.ReadByteSeq(guid[3]); + recvPacket.ReadByteSeq(guid[1]); + recvPacket.ReadByteSeq(guid[4]); + recvPacket.ReadByteSeq(guid[0]); + recvPacket.ReadByteSeq(guid[5]); + + WorldObject* obj = ObjectAccessor::GetWorldObject(*GetPlayer(), guid); + sLog->outError(LOG_FILTER_NETWORKIO, "Object update failed for object "UI64FMTD" (%s) for player %s (%u)", uint64(guid), obj ? obj->GetName() : "object-not-found", GetPlayerName().c_str(), GetGuidLow()); +} + +void WorldSession::HandleSaveCUFProfiles(WorldPacket& recvPacket) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SAVE_CUF_PROFILES"); + + uint8 count = (uint8)recvPacket.ReadBits(20); + + if (count > MAX_CUF_PROFILES) + { + sLog->outError(LOG_FILTER_PLAYER, "HandleSaveCUFProfiles - %s tried to save more than %i CUF profiles. Hacking attempt?", GetPlayerName(), MAX_CUF_PROFILES); + recvPacket.rfinish(); + return; + } + + CUFProfile* profiles[MAX_CUF_PROFILES]; + uint8 strlens[MAX_CUF_PROFILES]; + + for (uint8 i = 0; i < count; ++i) + { + profiles[i] = new CUFProfile; + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_2 , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_10_PLAYERS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_UNK_157 , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_HEAL_PREDICTION , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_1 , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVP , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_POWER_BAR , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_15_PLAYERS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_40_PLAYERS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_PETS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_5_PLAYERS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS, recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_2_PLAYERS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_UNK_156 , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_NON_BOSS_DEBUFFS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_MAIN_TANK_AND_ASSIST , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_AGGRO_HIGHLIGHT , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_3_PLAYERS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_BORDER , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_USE_CLASS_COLORS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_UNK_145 , recvPacket.ReadBit()); + strlens[i] = (uint8)recvPacket.ReadBits(8); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVE , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_DISPLAY_HORIZONTAL_GROUPS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_25_PLAYERS , recvPacket.ReadBit()); + profiles[i]->BoolOptions.set(CUF_KEEP_GROUPS_TOGETHER , recvPacket.ReadBit()); + } + + for (uint8 i = 0; i < count; ++i) + { + recvPacket >> profiles[i]->Unk146; + profiles[i]->ProfileName = recvPacket.ReadString(strlens[i]); + recvPacket >> profiles[i]->Unk152; + recvPacket >> profiles[i]->FrameHeight; + recvPacket >> profiles[i]->FrameWidth; + recvPacket >> profiles[i]->Unk150; + recvPacket >> profiles[i]->HealthText; + recvPacket >> profiles[i]->Unk147; + recvPacket >> profiles[i]->SortBy; + recvPacket >> profiles[i]->Unk154; + recvPacket >> profiles[i]->Unk148; + + GetPlayer()->SaveCUFProfile(i, profiles[i]); + } + + for (uint8 i = count; i < MAX_CUF_PROFILES; ++i) + GetPlayer()->SaveCUFProfile(i, NULL); +} + +void WorldSession::SendLoadCUFProfiles() +{ + Player* player = GetPlayer(); + + uint8 count = player->GetCUFProfilesCount(); + + ByteBuffer byteBuffer(25 * count); + WorldPacket data(SMSG_LOAD_CUF_PROFILES, 5 * count + 25 * count); + + data.WriteBits(count, 20); + for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) + { + CUFProfile* profile = player->GetCUFProfile(i); + if (!profile) + continue; + + data.WriteBit(profile->BoolOptions[CUF_UNK_157]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_10_PLAYERS]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_5_PLAYERS]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_25_PLAYERS]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HEAL_PREDICTION]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVE]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HORIZONTAL_GROUPS]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_40_PLAYERS]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_3_PLAYERS]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_AGGRO_HIGHLIGHT]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_BORDER]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_2_PLAYERS]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_NON_BOSS_DEBUFFS]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_MAIN_TANK_AND_ASSIST]); + data.WriteBit(profile->BoolOptions[CUF_UNK_156]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_2]); + data.WriteBit(profile->BoolOptions[CUF_USE_CLASS_COLORS]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_POWER_BAR]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_1]); + data.WriteBits(profile->ProfileName.size(), 8); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS]); + data.WriteBit(profile->BoolOptions[CUF_KEEP_GROUPS_TOGETHER]); + data.WriteBit(profile->BoolOptions[CUF_UNK_145]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_15_PLAYERS]); + data.WriteBit(profile->BoolOptions[CUF_DISPLAY_PETS]); + data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVP]); + + byteBuffer << uint16(profile->Unk154); + byteBuffer << uint16(profile->FrameHeight); + byteBuffer << uint16(profile->Unk152); + byteBuffer << uint8(profile->Unk147); + byteBuffer << uint16(profile->Unk150); + byteBuffer << uint8(profile->Unk146); + byteBuffer << uint8(profile->HealthText); + byteBuffer << uint8(profile->SortBy); + byteBuffer << uint16(profile->FrameWidth); + byteBuffer << uint8(profile->Unk148); + byteBuffer.WriteString(profile->ProfileName); + } + + data.FlushBits(); + data.append(byteBuffer); + SendPacket(&data); +} diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 6eeb3661028..f25f8d18b0d 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -470,7 +470,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_RESURRECT_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResurrectResponseOpcode ); DEFINE_OPCODE_HANDLER(CMSG_RETURN_TO_GRAVEYARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReturnToGraveyard ); DEFINE_OPCODE_HANDLER(CMSG_ROLE_POLL_BEGIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER(CMSG_SAVE_CUF_PROFILES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(CMSG_SAVE_CUF_PROFILES, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSaveCUFProfiles ); DEFINE_OPCODE_HANDLER(CMSG_SELF_RES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSelfResOpcode ); DEFINE_OPCODE_HANDLER(CMSG_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSellItemOpcode ); DEFINE_OPCODE_HANDLER(CMSG_SEND_MAIL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendMail ); @@ -948,7 +948,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_LOGIN_VERIFY_WORLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_LOGOUT_CANCEL_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 0ac7884efe2..6ff03b9c838 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -968,6 +968,10 @@ class WorldSession void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket); int32 HandleEnableNagleAlgorithm(); + // Compact Unit Frames (4.x) + void HandleSaveCUFProfiles(WorldPacket& recvPacket); + void SendLoadCUFProfiles(); + private: void InitializeQueryCallbackParameters(); void ProcessQueryCallbacks(); |
