diff options
| author | Shauren <shauren.trinity@gmail.com> | 2025-06-27 15:29:30 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2025-06-27 15:29:30 +0200 |
| commit | 60400d25f5fff2dabd4aa74bbdbc0d2370360a35 (patch) | |
| tree | 54f2ae7ecfdbe1387d6d6e39a4168a9385b1f230 /src/server/game/Server | |
| parent | e0f3291eab271cb7dc5f39abfc7e2a4744be6ee0 (diff) | |
Core/Players: Implemented PlayerDataElementAccount, PlayerDataElementCharacter, PlayerDataFlagAccount and PlayerDataFlagCharacter
Diffstat (limited to 'src/server/game/Server')
| -rw-r--r-- | src/server/game/Server/WorldSession.cpp | 167 | ||||
| -rw-r--r-- | src/server/game/Server/WorldSession.h | 34 |
2 files changed, 201 insertions, 0 deletions
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 9c22c48a95d..88a6cc1d815 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -28,7 +28,9 @@ #include "CharacterPackets.h" #include "ChatPackets.h" #include "ClientConfigPackets.h" +#include "Containers.h" #include "DatabaseEnv.h" +#include "DB2Stores.h" #include "GameTime.h" #include "Group.h" #include "Guild.h" @@ -44,6 +46,7 @@ #include "PacketUtilities.h" #include "Player.h" #include "QueryHolder.h" +#include "QueryResultStructured.h" #include "Random.h" #include "RBAC.h" #include "RealmList.h" @@ -972,6 +975,159 @@ void WorldSession::SaveTutorialsData(CharacterDatabaseTransaction trans) _tutorialsChanged &= ~TUTORIALS_FLAG_CHANGED; } +void WorldSession::LoadPlayerDataAccount(PreparedQueryResult const& elementsResult, PreparedQueryResult const& flagsResult) +{ + if (elementsResult) + { + do + { + DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(PreparedResultSet, (playerDataElementAccountId)(floatValue)(int64Value)) fields { *elementsResult }; + + PlayerDataElementAccountEntry const* entry = sPlayerDataElementAccountStore.LookupEntry(fields.playerDataElementAccountId().GetUInt32()); + if (!entry) + continue; + + PlayerDataAccount::Element& element = _playerDataAccount.Elements.emplace_back(); + element.Id = entry->ID; + element.NeedSave = false; + + switch (entry->GetType()) + { + case PlayerDataElementType::Int64: + element.Int64Value = fields.int64Value().GetInt64(); + break; + case PlayerDataElementType::Float: + element.FloatValue = fields.floatValue().GetFloat(); + break; + default: + break; + } + } while (elementsResult->NextRow()); + } + + if (flagsResult) + { + do + { + DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(PreparedResultSet, (storageIndex)(mask)) fields { *flagsResult }; + + Trinity::Containers::EnsureWritableVectorIndex(_playerDataAccount.Flags, fields.storageIndex().GetUInt32()) = { .Value = fields.mask().GetUInt64(), .NeedSave = false }; + } while (flagsResult->NextRow()); + } +} + +void WorldSession::SavePlayerDataAccount(LoginDatabaseTransaction const& transaction) +{ + LoginDatabasePreparedStatement* stmt; + for (PlayerDataAccount::Element& element : _playerDataAccount.Elements) + { + if (!element.NeedSave) + continue; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_PLAYER_DATA_ELEMENTS_ACCOUNT); + stmt->setUInt32(0, GetBattlenetAccountId()); + stmt->setUInt32(1, element.Id); + transaction->Append(stmt); + + element.NeedSave = false; + + PlayerDataElementAccountEntry const* entry = sPlayerDataElementAccountStore.LookupEntry(element.Id); + if (!entry) + continue; + + switch (entry->GetType()) + { + case PlayerDataElementType::Int64: + if (!element.Int64Value) + continue; + stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_PLAYER_DATA_ELEMENTS_ACCOUNT); + stmt->setUInt32(0, GetBattlenetAccountId()); + stmt->setUInt32(1, element.Id); + stmt->setNull(2); + stmt->setInt64(3, element.Int64Value); + transaction->Append(stmt); + break; + case PlayerDataElementType::Float: + if (!element.FloatValue) + continue; + stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_PLAYER_DATA_ELEMENTS_ACCOUNT); + stmt->setUInt32(0, GetBattlenetAccountId()); + stmt->setUInt32(1, element.Id); + stmt->setFloat(2, element.FloatValue); + stmt->setNull(3); + transaction->Append(stmt); + break; + } + } + + for (std::size_t i = 0; i < _playerDataAccount.Flags.size(); ++i) + { + PlayerDataAccount::Flag& flag = _playerDataAccount.Flags[i]; + if (!flag.NeedSave) + continue; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_PLAYER_DATA_FLAGS_ACCOUNT); + stmt->setUInt32(0, GetBattlenetAccountId()); + stmt->setUInt32(1, i); + transaction->Append(stmt); + + flag.NeedSave = false; + + if (!flag.Value) + continue; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_PLAYER_DATA_FLAGS_ACCOUNT); + stmt->setUInt32(0, GetBattlenetAccountId()); + stmt->setUInt32(1, i); + stmt->setUInt64(2, flag.Value); + transaction->Append(stmt); + } +} + +void WorldSession::SetPlayerDataElementAccount(uint32 dataElementId, float value) +{ + auto elementItr = std::ranges::find(_playerDataAccount.Elements, dataElementId, &PlayerDataAccount::Element::Id); + if (elementItr == _playerDataAccount.Elements.end()) + { + elementItr = _playerDataAccount.Elements.emplace(_playerDataAccount.Elements.end()); + elementItr->Id = dataElementId; + } + + elementItr->NeedSave = true; + elementItr->FloatValue = value; +} + +void WorldSession::SetPlayerDataElementAccount(uint32 dataElementId, int64 value) +{ + auto elementItr = std::ranges::find(_playerDataAccount.Elements, dataElementId, &PlayerDataAccount::Element::Id); + if (elementItr == _playerDataAccount.Elements.end()) + { + elementItr = _playerDataAccount.Elements.emplace(_playerDataAccount.Elements.end()); + elementItr->Id = dataElementId; + } + + elementItr->NeedSave = true; + elementItr->Int64Value = value; +} + +void WorldSession::SetPlayerDataFlagAccount(uint32 dataFlagId, bool on) +{ + PlayerDataFlagAccountEntry const* entry = sPlayerDataFlagAccountStore.LookupEntry(dataFlagId); + if (!entry) + return; + + uint32 fieldOffset = entry->StorageIndex / PLAYER_DATA_FLAG_VALUE_BITS; + uint64 flagValue = UI64LIT(1) << (entry->StorageIndex % PLAYER_DATA_FLAG_VALUE_BITS); + + PlayerDataAccount::Flag& flag = Trinity::Containers::EnsureWritableVectorIndex(_playerDataAccount.Flags, fieldOffset); + if (on) + flag.Value |= flagValue; + else + flag.Value &= ~flagValue; + + flag.NeedSave = true; +} + bool WorldSession::IsAddonRegistered(std::string_view prefix) const { if (!_filterAddonMessages) // if we have hit the softcap (64) nothing should be filtered @@ -1118,6 +1274,8 @@ public: ITEM_FAVORITE_APPEARANCES, TRANSMOG_ILLUSIONS, WARBAND_SCENES, + PLAYER_DATA_ELEMENTS_ACCOUNT, + PLAYER_DATA_FLAGS_ACCOUNT, MAX_QUERIES }; @@ -1169,6 +1327,14 @@ public: stmt->setUInt32(0, battlenetAccountId); ok = SetPreparedQuery(WARBAND_SCENES, stmt) && ok; + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_PLAYER_DATA_ELEMENTS_ACCOUNT); + stmt->setUInt32(0, battlenetAccountId); + ok = SetPreparedQuery(PLAYER_DATA_ELEMENTS_ACCOUNT, stmt) && ok; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_PLAYER_DATA_FLAGS_ACCOUNT); + stmt->setUInt32(0, battlenetAccountId); + ok = SetPreparedQuery(PLAYER_DATA_FLAGS_ACCOUNT, stmt) && ok; + return ok; } }; @@ -1222,6 +1388,7 @@ void WorldSession::InitializeSessionCallback(LoginDatabaseQueryHolder const& hol _collectionMgr->LoadAccountItemAppearances(holder.GetPreparedResult(AccountInfoQueryHolder::ITEM_APPEARANCES), holder.GetPreparedResult(AccountInfoQueryHolder::ITEM_FAVORITE_APPEARANCES)); _collectionMgr->LoadAccountTransmogIllusions(holder.GetPreparedResult(AccountInfoQueryHolder::TRANSMOG_ILLUSIONS)); _collectionMgr->LoadAccountWarbandScenes(holder.GetPreparedResult(AccountInfoQueryHolder::WARBAND_SCENES)); + LoadPlayerDataAccount(holder.GetPreparedResult(AccountInfoQueryHolder::PLAYER_DATA_ELEMENTS_ACCOUNT), holder.GetPreparedResult(AccountInfoQueryHolder::PLAYER_DATA_FLAGS_ACCOUNT)); if (!m_inQueue) SendAuthResponse(ERROR_OK, false); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index a6c96948101..01299cc9f7c 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1116,6 +1116,39 @@ class TC_GAME_API WorldSession _tutorialsChanged |= TUTORIALS_FLAG_CHANGED; } } + + struct PlayerDataAccount + { + struct Element + { + uint32 Id; + bool NeedSave; + union + { + float FloatValue; + int64 Int64Value; + }; + }; + + struct Flag + { + uint64 Value; + bool NeedSave; + }; + + std::vector<Element> Elements; + std::vector<Flag> Flags; + }; + + void LoadPlayerDataAccount(PreparedQueryResult const& elementsResult, PreparedQueryResult const& flagsResult); + void SavePlayerDataAccount(LoginDatabaseTransaction const& transaction); + + void SetPlayerDataElementAccount(uint32 dataElementId, float value); + void SetPlayerDataElementAccount(uint32 dataElementId, int64 value); + void SetPlayerDataFlagAccount(uint32 dataFlagId, bool on); + + PlayerDataAccount const& GetPlayerDataAccount() const { return _playerDataAccount; } + // Auction void SendAuctionHello(ObjectGuid guid, Unit const* unit); @@ -1991,6 +2024,7 @@ class TC_GAME_API WorldSession AccountData _accountData[NUM_ACCOUNT_DATA_TYPES]; std::array<uint32, MAX_ACCOUNT_TUTORIAL_VALUES> _tutorials; uint8 _tutorialsChanged; + PlayerDataAccount _playerDataAccount; std::vector<std::string> _registeredAddonPrefixes; bool _filterAddonMessages; uint32 recruiterId; |
