diff options
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 71 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 77 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Maps/MapManager.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 67 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 9 |
7 files changed, 113 insertions, 119 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 7884b183f4a..0849cd1952c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17255,9 +17255,6 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol _LoadBoundInstances(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES)); - _LoadInstanceTimeRestrictions(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES)); - UpdateInstanceEnterTimes(); - _LoadBGData(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BG_DATA)); GetSession()->SetPlayer(this); @@ -19105,41 +19102,6 @@ bool Player::CheckInstanceValidity(bool /*isLogin*/) return true; } -bool Player::UpdateAndCheckInstanceCount(uint32 instanceId) -{ - UpdateInstanceEnterTimes(); - - if (_instanceResetTimes.size() < sWorld->getIntConfig(CONFIG_MAX_INSTANCES_PER_HOUR)) - return true; - - if (instanceId == 0) - return false; - - return _instanceResetTimes.find(instanceId) != _instanceResetTimes.end(); -} - -void Player::AddInstanceEnterTime(uint32 instanceId, time_t enterTime) -{ - if (_instanceResetTimes.find(instanceId) == _instanceResetTimes.end()) - _instanceResetTimes.insert(InstanceTimeMap::value_type(instanceId, enterTime + HOUR)); -} - -void Player::UpdateInstanceEnterTimes() -{ - if (_instanceResetTimes.empty()) - return; - - time_t now = GameTime::GetGameTime(); - - for (InstanceTimeMap::iterator itr = _instanceResetTimes.begin(); itr != _instanceResetTimes.end();) - { - if (itr->second < now) - itr = _instanceResetTimes.erase(itr); - else - ++itr; - } -} - bool Player::_LoadHomeBind(PreparedQueryResult result) { PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass()); @@ -19518,7 +19480,7 @@ void Player::SaveToDB(CharacterDatabaseTransaction trans, bool create /* = false _SaveEquipmentSets(trans); GetSession()->SaveTutorialsData(trans); // changed only while character in game _SaveGlyphs(trans); - _SaveInstanceTimeRestrictions(trans); + GetSession()->SaveInstanceTimeRestrictions(trans); // check if stats should only be saved on logout // save stats can be out of transaction @@ -26443,18 +26405,6 @@ float Player::GetAverageItemLevel() const return ((float)sum) / count; } -void Player::_LoadInstanceTimeRestrictions(PreparedQueryResult result) -{ - if (!result) - return; - - do - { - Field* fields = result->Fetch(); - _instanceResetTimes.insert(InstanceTimeMap::value_type(fields[0].GetUInt32(), fields[1].GetUInt64())); - } while (result->NextRow()); -} - void Player::_LoadPetStable(uint8 petStableSlots, PreparedQueryResult result) { if (!petStableSlots && !result) @@ -26504,25 +26454,6 @@ void Player::_LoadPetStable(uint8 petStableSlots, PreparedQueryResult result) } } -void Player::_SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans) -{ - if (_instanceResetTimes.empty()) - return; - - CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES); - stmt->setUInt32(0, GetSession()->GetAccountId()); - trans->Append(stmt); - - for (InstanceTimeMap::const_iterator itr = _instanceResetTimes.begin(); itr != _instanceResetTimes.end(); ++itr) - { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES); - stmt->setUInt32(0, GetSession()->GetAccountId()); - stmt->setUInt32(1, itr->first); - stmt->setUInt64(2, itr->second); - trans->Append(stmt); - } -} - bool Player::IsInWhisperWhiteList(ObjectGuid guid) { for (GuidList::const_iterator itr = WhisperList.begin(); itr != WhisperList.end(); ++itr) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ada2bb98d7c..8b8ebde8fe9 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -155,8 +155,6 @@ typedef std::unordered_map<uint32, PlayerTalent*> PlayerTalentMap; typedef std::unordered_map<uint32, PlayerSpell> PlayerSpellMap; typedef std::unordered_set<SpellModifier*> SpellModContainer; -typedef std::unordered_map<uint32 /*instanceId*/, time_t/*releaseTime*/> InstanceTimeMap; - enum ActionButtonUpdateState { ACTIONBUTTON_UNCHANGED = 0, @@ -705,41 +703,40 @@ enum PlayedTimeIndex // used at player loading query list preparing, and later result selection enum PlayerLoginQueryIndex { - PLAYER_LOGIN_QUERY_LOAD_FROM = 0, - PLAYER_LOGIN_QUERY_LOAD_GROUP = 1, - PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES = 2, - PLAYER_LOGIN_QUERY_LOAD_AURAS = 3, - PLAYER_LOGIN_QUERY_LOAD_SPELLS = 4, - PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS = 5, - PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS = 6, - PLAYER_LOGIN_QUERY_LOAD_REPUTATION = 7, - PLAYER_LOGIN_QUERY_LOAD_INVENTORY = 8, - PLAYER_LOGIN_QUERY_LOAD_ACTIONS = 9, - PLAYER_LOGIN_QUERY_LOAD_MAILS = 10, - PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS = 11, - PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST = 12, - PLAYER_LOGIN_QUERY_LOAD_HOME_BIND = 13, - PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS = 14, - PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES = 15, - PLAYER_LOGIN_QUERY_LOAD_GUILD = 16, - PLAYER_LOGIN_QUERY_LOAD_ARENA_INFO = 17, - PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS = 18, - PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS = 19, - PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS = 20, - PLAYER_LOGIN_QUERY_LOAD_BG_DATA = 21, - PLAYER_LOGIN_QUERY_LOAD_GLYPHS = 22, - PLAYER_LOGIN_QUERY_LOAD_TALENTS = 23, - PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA = 24, - PLAYER_LOGIN_QUERY_LOAD_SKILLS = 25, - PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS = 26, - PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG = 27, - PLAYER_LOGIN_QUERY_LOAD_BANNED = 28, - PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW = 29, - PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30, - PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31, - PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32, - PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 33, - PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS = 34, + PLAYER_LOGIN_QUERY_LOAD_FROM, + PLAYER_LOGIN_QUERY_LOAD_GROUP, + PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES, + PLAYER_LOGIN_QUERY_LOAD_AURAS, + PLAYER_LOGIN_QUERY_LOAD_SPELLS, + PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS, + PLAYER_LOGIN_QUERY_LOAD_DAILY_QUEST_STATUS, + PLAYER_LOGIN_QUERY_LOAD_REPUTATION, + PLAYER_LOGIN_QUERY_LOAD_INVENTORY, + PLAYER_LOGIN_QUERY_LOAD_ACTIONS, + PLAYER_LOGIN_QUERY_LOAD_MAILS, + PLAYER_LOGIN_QUERY_LOAD_MAIL_ITEMS, + PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST, + PLAYER_LOGIN_QUERY_LOAD_HOME_BIND, + PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS, + PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES, + PLAYER_LOGIN_QUERY_LOAD_GUILD, + PLAYER_LOGIN_QUERY_LOAD_ARENA_INFO, + PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS, + PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS, + PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS, + PLAYER_LOGIN_QUERY_LOAD_BG_DATA, + PLAYER_LOGIN_QUERY_LOAD_GLYPHS, + PLAYER_LOGIN_QUERY_LOAD_TALENTS, + PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA, + PLAYER_LOGIN_QUERY_LOAD_SKILLS, + PLAYER_LOGIN_QUERY_LOAD_WEEKLY_QUEST_STATUS, + PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG, + PLAYER_LOGIN_QUERY_LOAD_BANNED, + PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW, + PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS, + PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS, + PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION, + PLAYER_LOGIN_QUERY_LOAD_PET_SLOTS, MAX_PLAYER_LOGIN_QUERY }; @@ -2090,9 +2087,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendSavedInstances(); bool Satisfy(AccessRequirement const* ar, uint32 target_map, bool report = false); bool CheckInstanceValidity(bool /*isLogin*/); - bool UpdateAndCheckInstanceCount(uint32 instanceId); - void AddInstanceEnterTime(uint32 instanceId, time_t enterTime); - void UpdateInstanceEnterTimes(); // last used pet number (for BG's) uint32 GetLastPetNumber() const { return m_lastpetnumber; } @@ -2270,7 +2264,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void _LoadBGData(PreparedQueryResult result); void _LoadGlyphs(PreparedQueryResult result); void _LoadTalents(PreparedQueryResult result); - void _LoadInstanceTimeRestrictions(PreparedQueryResult result); void _LoadPetStable(uint8 petStableSlots, PreparedQueryResult result); /*********************************************************/ @@ -2293,7 +2286,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void _SaveGlyphs(CharacterDatabaseTransaction trans) const; void _SaveTalents(CharacterDatabaseTransaction trans); void _SaveStats(CharacterDatabaseTransaction trans) const; - void _SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans); /*********************************************************/ /*** ENVIRONMENTAL SYSTEM ***/ @@ -2514,7 +2506,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint32 m_ChampioningFaction; - InstanceTimeMap _instanceResetTimes; uint32 _pendingBindId; uint32 _pendingBindTimer; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 1678a942926..29b39902a5e 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -205,10 +205,6 @@ bool LoginQueryHolder::Initialize() stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES); - stmt->setUInt32(0, m_accountId); - res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES, stmt); - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_LOCATION); stmt->setUInt32(0, lowGuid); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION, stmt); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index b4aeab293ea..765852581fd 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -3908,7 +3908,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) // increase current instances (hourly limit) if (!group || !group->isLFGGroup()) - player->AddInstanceEnterTime(GetInstanceId(), GameTime::GetGameTime()); + player->GetSession()->AddInstanceEnterTime(GetInstanceId(), GameTime::GetSystemTime()); // get or create an instance save for the map InstanceSave* mapSave = sInstanceSaveMgr->GetInstanceSave(GetInstanceId()); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index acf3d604f2b..7f83cb1c054 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -205,7 +205,7 @@ Map::EnterState MapManager::PlayerCannotEnter(uint32 mapid, Player* player, bool instanceIdToCheck = save->GetInstanceId(); // instanceId can never be 0 - will not be found - if (!player->UpdateAndCheckInstanceCount(instanceIdToCheck) && !player->isDead()) + if (!player->GetSession()->UpdateAndCheckInstanceCount(instanceIdToCheck) && !player->isDead()) return Map::CANNOT_ENTER_TOO_MANY_INSTANCES; } diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 465e2efe683..2950b72ce8e 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -26,6 +26,7 @@ #include "CharacterPackets.h" #include "Config.h" #include "Common.h" +#include "Containers.h" #include "DatabaseEnv.h" #include "DBCStructure.h" #include "GameClient.h" @@ -889,6 +890,66 @@ void WorldSession::SaveTutorialsData(CharacterDatabaseTransaction trans) m_TutorialsChanged &= ~TUTORIALS_FLAG_CHANGED; } +void WorldSession::LoadInstanceTimeRestrictions(PreparedQueryResult result) +{ + if (!result) + return; + + SystemTimePoint now = GameTime::GetSystemTime(); + do + { + Field* fields = result->Fetch(); + SystemTimePoint restrictionExpireTime = SystemTimePoint::clock::from_time_t(fields[1].GetUInt64()); + if (restrictionExpireTime > now) + _instanceResetTimes.try_emplace(fields[0].GetUInt32(), restrictionExpireTime); + } while (result->NextRow()); +} + +void WorldSession::SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans) +{ + if (_instanceResetTimes.empty()) + return; + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES); + stmt->setUInt32(0, GetAccountId()); + trans->Append(stmt); + + for (auto const& [instanceId, restrictionExpireTime] : _instanceResetTimes) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES); + stmt->setUInt32(0, GetAccountId()); + stmt->setUInt32(1, instanceId); + stmt->setUInt64(2, SystemTimePoint::clock::to_time_t(restrictionExpireTime)); + trans->Append(stmt); + } +} + +bool WorldSession::UpdateAndCheckInstanceCount(uint32 instanceId) +{ + UpdateInstanceEnterTimes(); + + if (_instanceResetTimes.size() < sWorld->getIntConfig(CONFIG_MAX_INSTANCES_PER_HOUR)) + return true; + + if (instanceId == 0) + return false; + + return _instanceResetTimes.contains(instanceId); +} + +void WorldSession::AddInstanceEnterTime(uint32 instanceId, SystemTimePoint enterTime) +{ + _instanceResetTimes.try_emplace(instanceId, enterTime + 1h); +} + +void WorldSession::UpdateInstanceEnterTimes() +{ + Trinity::Containers::EraseIf(_instanceResetTimes, [now = GameTime::GetSystemTime()](std::pair<uint32 const, SystemTimePoint> const& value) + { + return value.second < now; + }); +} + void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi) { data >> mi->flags; @@ -1290,6 +1351,7 @@ public: { GLOBAL_ACCOUNT_DATA = 0, TUTORIALS, + INSTANCE_TIMES, MAX_QUERIES }; @@ -1308,6 +1370,10 @@ public: stmt->setUInt32(0, accountId); ok = SetPreparedQuery(TUTORIALS, stmt) && ok; + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES); + stmt->setUInt32(0, accountId); + ok = SetPreparedQuery(INSTANCE_TIMES, stmt) && ok; + return ok; } }; @@ -1331,6 +1397,7 @@ void WorldSession::InitializeSessionCallback(CharacterDatabaseQueryHolder const& { LoadAccountData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK); LoadTutorialsData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS)); + LoadInstanceTimeRestrictions(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::INSTANCE_TIMES)); if (!m_inQueue) SendAuthResponse(AUTH_OK, true); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 5b367defd57..843a2565cd5 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -26,6 +26,7 @@ #include "AsyncCallbackProcessor.h" #include "AuthDefines.h" #include "DatabaseEnvFwd.h" +#include "Duration.h" #include "LockedQueue.h" #include "ObjectGuid.h" #include "Packet.h" @@ -570,6 +571,11 @@ class TC_GAME_API WorldSession m_TutorialsChanged |= TUTORIALS_FLAG_CHANGED; } } + void LoadInstanceTimeRestrictions(PreparedQueryResult result); + void SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans); + bool UpdateAndCheckInstanceCount(uint32 instanceId); + void AddInstanceEnterTime(uint32 instanceId, SystemTimePoint enterTime); + void UpdateInstanceEnterTimes(); //auction void SendAuctionHello(ObjectGuid guid, Creature* unit); void SendAuctionCommandResult(uint32 auctionItemId, AuctionAction command, AuctionError errorCode, InventoryResult bagResult = InventoryResult(0)); @@ -1244,6 +1250,9 @@ class TC_GAME_API WorldSession AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]; uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]; uint8 m_TutorialsChanged; + + std::unordered_map<uint32 /*instanceId*/, SystemTimePoint/*releaseTime*/> _instanceResetTimes; + struct Addons { struct SecureAddonInfo |