Core/Misc: Move instance enter times handling from Player to WorldSession.

(cherry picked from commit 0327f16d110baa4479c73b4fcece6c99b2f89a8b)
This commit is contained in:
r4dish
2026-06-01 16:10:34 +02:00
committed by Shauren
parent bd81530a2a
commit 2036807a2f
6 changed files with 77 additions and 85 deletions
+1 -70
View File
@@ -18251,9 +18251,6 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::TodayHonorableKills), fields.totalKills);
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::YesterdayHonorableKills), fields.yesterdayKills);
_LoadInstanceTimeRestrictions(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES));
UpdateInstanceEnterTimes();
_LoadBGData(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BG_DATA));
GetSession()->SetPlayer(this);
@@ -20165,41 +20162,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;
}
}
WorldSafeLocsEntry const* Player::GetInstanceEntrance(uint32 targetMapId)
{
WorldSafeLocsEntry const* entranceLocation = nullptr;
@@ -20775,7 +20737,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
_SaveTransmogOutfits(trans);
_SaveCharacterSelectOutfit(trans);
GetSession()->SaveTutorialsData(trans); // changed only while character in game
_SaveInstanceTimeRestrictions(trans);
GetSession()->SaveInstanceTimeRestrictions(trans);
_SaveCurrency(trans);
_SaveCUFProfiles(trans);
_SavePlayerData(trans);
@@ -30027,18 +29989,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(uint32 summonedPetNumber, PreparedQueryResult result)
{
if (!result)
@@ -30095,25 +30045,6 @@ void Player::_LoadPetStable(uint32 summonedPetNumber, PreparedQueryResult result
m_temporaryUnsummonedPetNumber = summonedPetNumber;
}
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->setInt64(2, itr->second);
trans->Append(stmt);
}
}
bool Player::IsInWhisperWhiteList(ObjectGuid guid)
{
for (GuidList::const_iterator itr = WhisperList.begin(); itr != WhisperList.end(); ++itr)
-9
View File
@@ -353,8 +353,6 @@ typedef std::unordered_map<uint32, PlayerSpell> PlayerSpellMap;
typedef Trinity::Containers::FlatSet<SpellModifier*, SpellModifierCompare> SpellModContainer;
typedef std::unordered_map<uint32, PlayerCurrency> PlayerCurrenciesMap;
typedef std::unordered_map<uint32 /*instanceId*/, time_t/*releaseTime*/> InstanceTimeMap;
enum ActionButtonUpdateState
{
ACTIONBUTTON_UNCHANGED = 0,
@@ -1007,7 +1005,6 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_RANDOM_BG,
PLAYER_LOGIN_QUERY_LOAD_BANNED,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_REW,
PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES,
PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS,
PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS,
PLAYER_LOGIN_QUERY_LOAD_CURRENCY,
@@ -2781,9 +2778,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void SendRaidInfo();
bool Satisfy(AccessRequirement const* ar, uint32 target_map, TransferAbortParams* params = nullptr, bool report = false);
bool CheckInstanceValidity(bool /*isLogin*/);
bool UpdateAndCheckInstanceCount(uint32 instanceId);
void AddInstanceEnterTime(uint32 instanceId, time_t enterTime);
void UpdateInstanceEnterTimes();
WorldSafeLocsEntry const* GetInstanceEntrance(uint32 targetMapId);
// last used pet number (for BG's)
@@ -3155,7 +3149,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void _LoadTalents(PreparedQueryResult result);
void _LoadPvpTalents(PreparedQueryResult result);
void _LoadTraits(PreparedQueryResult configsResult, PreparedQueryResult entriesResult);
void _LoadInstanceTimeRestrictions(PreparedQueryResult result);
void _LoadPetStable(uint32 summonedPetNumber, PreparedQueryResult result);
void _LoadCurrency(PreparedQueryResult result);
void _LoadCUFProfiles(PreparedQueryResult result);
@@ -3187,7 +3180,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void _SaveTalents(CharacterDatabaseTransaction trans);
void _SaveTraits(CharacterDatabaseTransaction trans);
void _SaveStats(CharacterDatabaseTransaction trans) const;
void _SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans);
void _SaveCurrency(CharacterDatabaseTransaction trans);
void _SaveCUFProfiles(CharacterDatabaseTransaction trans);
void _SavePlayerData(CharacterDatabaseTransaction trans);
@@ -3397,7 +3389,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
uint32 m_ChampioningFaction;
InstanceTimeMap _instanceResetTimes;
uint32 _pendingBindId;
uint32 _pendingBindTimer;
@@ -310,10 +310,6 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt64(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_PLAYER_CURRENCY);
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CURRENCY, stmt);
+2 -2
View File
@@ -1836,7 +1836,7 @@ TransferAbortParams Map::PlayerCannotEnter(uint32 mapid, Player* player)
return denyReason;
// players are only allowed to enter 10 instances per hour
if (!entry->GetFlags2().HasFlag(MapFlags2::IgnoreInstanceFarmLimit) && entry->IsDungeon() && !player->UpdateAndCheckInstanceCount(instanceIdToCheck) && !player->isDead())
if (!entry->GetFlags2().HasFlag(MapFlags2::IgnoreInstanceFarmLimit) && entry->IsDungeon() && !player->GetSession()->UpdateAndCheckInstanceCount(instanceIdToCheck) && !player->isDead())
return TRANSFER_ABORT_TOO_MANY_INSTANCES;
}
@@ -2943,7 +2943,7 @@ TransferAbortParams InstanceMap::CannotEnter(Player* player)
bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/)
{
// increase current instances (hourly limit)
player->AddInstanceEnterTime(GetInstanceId(), GameTime::GetGameTime());
player->GetSession()->AddInstanceEnterTime(GetInstanceId(), GameTime::GetSystemTime());
MapDb2Entries entries{ GetEntry(), GetMapDifficulty() };
if (entries.MapDifficulty->HasResetSchedule() && i_instanceLock && !i_instanceLock->IsNew() && i_data)
+66
View File
@@ -978,6 +978,66 @@ void WorldSession::SaveTutorialsData(CharacterDatabaseTransaction trans)
_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::LoadPlayerDataAccount(PreparedQueryResult const& elementsResult, PreparedQueryResult const& flagsResult)
{
if (elementsResult)
@@ -1219,6 +1279,7 @@ public:
{
GLOBAL_ACCOUNT_DATA = 0,
TUTORIALS,
INSTANCE_TIMES,
MAX_QUERIES
};
@@ -1237,6 +1298,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;
}
};
@@ -1369,6 +1434,7 @@ void WorldSession::InitializeSessionCallback(LoginDatabaseQueryHolder const& hol
{
LoadAccountData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::GLOBAL_ACCOUNT_DATA), GLOBAL_CACHE_MASK);
LoadTutorialsData(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS));
LoadInstanceTimeRestrictions(realmHolder.GetPreparedResult(AccountInfoQueryHolderPerRealm::INSTANCE_TIMES));
_collectionMgr->LoadAccountToys(holder.GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_TOYS));
_collectionMgr->LoadAccountHeirlooms(holder.GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_HEIRLOOMS));
_collectionMgr->LoadAccountMounts(holder.GetPreparedResult(AccountInfoQueryHolder::MOUNTS));
+8
View File
@@ -1112,6 +1112,11 @@ class TC_GAME_API WorldSession
_tutorialsChanged |= TUTORIALS_FLAG_CHANGED;
}
}
void LoadInstanceTimeRestrictions(PreparedQueryResult result);
void SaveInstanceTimeRestrictions(CharacterDatabaseTransaction trans);
bool UpdateAndCheckInstanceCount(uint32 instanceId);
void AddInstanceEnterTime(uint32 instanceId, SystemTimePoint enterTime);
void UpdateInstanceEnterTimes();
struct PlayerDataAccount
{
@@ -2014,6 +2019,9 @@ class TC_GAME_API WorldSession
AccountData _accountData[NUM_ACCOUNT_DATA_TYPES];
std::array<uint32, MAX_ACCOUNT_TUTORIAL_VALUES> _tutorials;
uint8 _tutorialsChanged;
std::unordered_map<uint32 /*instanceId*/, SystemTimePoint/*releaseTime*/> _instanceResetTimes;
PlayerDataAccount _playerDataAccount;
std::vector<std::string> _registeredAddonPrefixes;
bool _filterAddonMessages;