aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-06-27 15:29:30 +0200
committerShauren <shauren.trinity@gmail.com>2025-06-27 15:29:30 +0200
commit60400d25f5fff2dabd4aa74bbdbc0d2370360a35 (patch)
tree54f2ae7ecfdbe1387d6d6e39a4168a9385b1f230 /src/server/game/Server
parente0f3291eab271cb7dc5f39abfc7e2a4744be6ee0 (diff)
Core/Players: Implemented PlayerDataElementAccount, PlayerDataElementCharacter, PlayerDataFlagAccount and PlayerDataFlagCharacter
Diffstat (limited to 'src/server/game/Server')
-rw-r--r--src/server/game/Server/WorldSession.cpp167
-rw-r--r--src/server/game/Server/WorldSession.h34
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;