Core/Misc: Move instance enter times handling from Player to WorldSession.
(cherry picked from commit 0327f16d110baa4479c73b4fcece6c99b2f89a8b)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user