diff options
author | KingPin <none@none> | 2008-10-21 12:43:24 -0500 |
---|---|---|
committer | KingPin <none@none> | 2008-10-21 12:43:24 -0500 |
commit | ed94fdb8bc88ed204df805ad292da5c1e2018dde (patch) | |
tree | 40a71c55053d3ccd480eba879dc916fc304f9067 /src | |
parent | d0325e253616e855df37a2d23414ff6b93db93bf (diff) |
[svn] * Added some player info cache to the core. Thanx to Rognar for patch, visaglis for testing and bugging me to add it.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Guild.cpp | 16 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 65 | ||||
-rw-r--r-- | src/game/ObjectMgr.h | 21 | ||||
-rw-r--r-- | src/game/Player.cpp | 51 | ||||
-rw-r--r-- | src/game/World.cpp | 3 |
5 files changed, 156 insertions, 0 deletions
diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index cec6507eb7c..bbf8c278ace 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -363,6 +363,21 @@ bool Guild::FillPlayerData(uint64 guid, MemberSlot* memslot) } else { + PCachePlayerInfo pInfo = objmgr.GetPlayerInfoFromCache(GUID_LOPART(guid)); + if(pInfo) + { + plName = pInfo->sPlayerName; + plClass = pInfo->unClass; + if(plClass<CLASS_WARRIOR||plClass>=MAX_CLASSES) // can be at broken `class` field + { + sLog.outError("Player (GUID: %u) has a broken data in field `characters`.`class`.",GUID_LOPART(guid)); + return false; + } + plLevel = pInfo->unLevel; + plZone = Player::GetZoneIdFromDB(guid); + } + else + { if(!objmgr.GetPlayerNameByGUID(guid, plName)) // player doesn't exist return false; @@ -386,6 +401,7 @@ bool Guild::FillPlayerData(uint64 guid, MemberSlot* memslot) delete result; } + } memslot->name = plName; memslot->level = plLevel; diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 9b37a3351d9..e069ed894de 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -167,6 +167,9 @@ ObjectMgr::~ObjectMgr() for (GuildSet::iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr) delete (*itr); + for (CachePlayerInfoMap::iterator itr = m_mPlayerInfoMap.begin(); itr != m_mPlayerInfoMap.end(); ++itr) + delete itr->second; + for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr) delete itr->second; @@ -177,6 +180,61 @@ ObjectMgr::~ObjectMgr() itr->second.Clear(); } +void ObjectMgr::LoadPlayerInfoInCache() +{ + QueryResult *result = CharacterDatabase.PQuery("SELECT guid, name, data, class FROM characters"); + if(!result) + { + sLog.outError( "ROGNAR LoadPlayerCache"); + return; + } + + PCachePlayerInfo pPPlayerInfo = NULL; + Field *fields = NULL; + Tokens tdata; + barGoLink bar( result->GetRowCount() ); + do + { + bar.step(); + fields = result->Fetch(); + pPPlayerInfo = new CachePlayerInfo(); + + pPPlayerInfo->sPlayerName = fields[1].GetString(); + + tdata.clear(); + tdata = StrSplit(fields[2].GetCppString(), " "); + + pPPlayerInfo->unLevel = (uint32)atoi(tdata[UNIT_FIELD_LEVEL].c_str()); + pPPlayerInfo->unfield = (uint32)atoi(tdata[UNIT_FIELD_BYTES_0].c_str()); + + pPPlayerInfo->unArenaInfoId0 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)].c_str()); + pPPlayerInfo->unArenaInfoId1 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)].c_str()); + pPPlayerInfo->unArenaInfoId2 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)].c_str()); + + pPPlayerInfo->unArenaInfoSlot0 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5].c_str()); + pPPlayerInfo->unArenaInfoSlot1 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5].c_str()); + pPPlayerInfo->unArenaInfoSlot2 = (uint32)atoi(tdata[PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5].c_str()); + + pPPlayerInfo->unClass = (uint32)fields[3].GetUInt32(); + m_mPlayerInfoMap[fields[0].GetUInt32()] = pPPlayerInfo; + } + while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded info about %d players", m_mPlayerInfoMap.size()); +} + +PCachePlayerInfo ObjectMgr::GetPlayerInfoFromCache(uint32 unPlayerGuid) const +{ + //Now m_mPlayerInfoMap is using only for search, but when dinamic inserting/removing + //will be implemented we should lock it to prevent simultaneous access. + //Inserting - when new created player is saving + //Removing - when player has been deleted + CachePlayerInfoMap::const_iterator ipos = m_mPlayerInfoMap.find(unPlayerGuid); + return ipos == m_mPlayerInfoMap.end() ? NULL : ipos->second; +} + Group * ObjectMgr::GetGroupByLeader(const uint64 &guid) const { for(GroupSet::const_iterator itr = mGroupSet.begin(); itr != mGroupSet.end(); ++itr) @@ -1261,6 +1319,13 @@ bool ObjectMgr::GetPlayerNameByGUID(const uint64 &guid, std::string &name) const return true; } + PCachePlayerInfo pInfo = GetPlayerInfoFromCache(GUID_LOPART(guid)); + if(pInfo) + { + name = pInfo->sPlayerName.c_str(); + return true; + } + QueryResult *result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid = '%u'", GUID_LOPART(guid)); if(result) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index f76cc232e57..898d82ea6ff 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -209,6 +209,23 @@ enum ConditionType #define MAX_CONDITION 11 // maximum value in ConditionType enum +//Player's info +typedef struct _tagCachePlayerInfo +{ + std::string sPlayerName; + uint32 unfield; + uint32 unLevel; + uint8 unClass; +//Arena + uint32 unArenaInfoId0; + uint32 unArenaInfoId1; + uint32 unArenaInfoId2; + uint32 unArenaInfoSlot0; + uint32 unArenaInfoSlot1; + uint32 unArenaInfoSlot2; +}CachePlayerInfo, *PCachePlayerInfo; +typedef HM_NAMESPACE::hash_map<uint32, PCachePlayerInfo> CachePlayerInfoMap; + struct PlayerCondition { ConditionType condition; // additional condition type @@ -568,6 +585,10 @@ class ObjectMgr uint32 GenerateMailID(); uint32 GenerateItemTextID(); uint32 GeneratePetNumber(); + + void LoadPlayerInfoInCache(); + PCachePlayerInfo GetPlayerInfoFromCache(uint32 unPlayerGuid) const; + CachePlayerInfoMap m_mPlayerInfoMap; uint32 CreateItemText(std::string text); std::string GetItemText( uint32 id ) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 8e692eaccee..c082e18a149 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -13626,6 +13626,40 @@ float Player::GetFloatValueFromArray(Tokens const& data, uint16 index) uint32 Player::GetUInt32ValueFromDB(uint16 index, uint64 guid) { + //rognar optimization + //must be improved!! "if" and "switch" - it's very not aesthetically :))) + //but we should know whith data is cached + //PLAYER_FIELD_ARENA_TEAM_INFO* very is often using with pvp&arena patch :) + if( index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5 + || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5 + || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5 + || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6) + || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6) + || index == PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6) + || index == UNIT_FIELD_LEVEL) + { + CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GUID_LOPART(guid)); + if(_iter != objmgr.m_mPlayerInfoMap.end()) + { + switch(index) + { + case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5): + return _iter->second->unArenaInfoSlot0; + case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5): + return _iter->second->unArenaInfoSlot1; + case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5): + return _iter->second->unArenaInfoSlot2; + case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)): + return _iter->second->unArenaInfoId0; + case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)): + return _iter->second->unArenaInfoId1; + case (PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)): + return _iter->second->unArenaInfoId2; + case (UNIT_FIELD_LEVEL): + return _iter->second->unLevel; + } + } + } Tokens data; if(!LoadValuesArrayFromDB(data,guid)) return 0; @@ -15219,6 +15253,23 @@ void Player::SaveToDB() // save pet (hunter pet level and experience and all type pets health/mana). if(Pet* pet = GetPet()) pet->SavePetToDB(PET_SAVE_AS_CURRENT); + + //to prevent access to DB we should cache some data, which is used very often + CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow()); + if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players + { + _iter->second->unLevel = getLevel(); + + _iter->second->unArenaInfoSlot0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 0 * 6 + 5); + _iter->second->unArenaInfoSlot1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 * 6 + 5); + _iter->second->unArenaInfoSlot2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 2 * 6 + 5); + + _iter->second->unfield = GetUInt32Value(UNIT_FIELD_BYTES_0); + + _iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6)); + _iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6)); + _iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)); + } } // fast save function for item/money cheating preventing - save only inventory and money state diff --git a/src/game/World.cpp b/src/game/World.cpp index d922e10d332..9fdd9580872 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -988,6 +988,9 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Page Texts..." ); objmgr.LoadPageTexts(); + sLog.outString( "Loading Player info in cache..." ); + objmgr.LoadPlayerInfoInCache(); + sLog.outString( "Loading Game Object Templates..." ); // must be after LoadPageTexts objmgr.LoadGameobjectInfo(); |