Core/Instances: Implemented hourly instance limit: players are limited to entering 5 instances per hour (account wide limit)
This commit is contained in:
@@ -1514,6 +1514,17 @@ void Player::Update(uint32 p_time)
|
||||
UpdateEnchantTime(p_time);
|
||||
UpdateHomebindTime(p_time);
|
||||
|
||||
if (!_instanceResetTimes.empty())
|
||||
{
|
||||
for (InstanceTimeMap::iterator itr = _instanceResetTimes.begin(); itr != _instanceResetTimes.end();)
|
||||
{
|
||||
if (itr->second < now)
|
||||
_instanceResetTimes.erase(itr++);
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
// group update
|
||||
SendUpdateToOutOfRangeGroupMembers();
|
||||
|
||||
@@ -1948,7 +1959,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
// If the map is not created, assume it is possible to enter it.
|
||||
// It will be created in the WorldPortAck.
|
||||
Map *map = sMapMgr->FindMap(mapid);
|
||||
if (!map || map->CanEnter(this))
|
||||
if (!map || map->CanEnter(this))
|
||||
{
|
||||
//lets reset near teleport flag if it wasn't reset during chained teleports
|
||||
SetSemaphoreTeleportNear(false);
|
||||
@@ -16300,6 +16311,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
|
||||
SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[45].GetUInt16());
|
||||
|
||||
_LoadBoundInstances(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES));
|
||||
_LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES));
|
||||
_LoadBGData(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADBGDATA));
|
||||
|
||||
MapEntry const * mapEntry = sMapStore.LookupEntry(mapId);
|
||||
@@ -17632,7 +17644,8 @@ void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficu
|
||||
{
|
||||
if (itr != m_boundInstances[difficulty].end())
|
||||
{
|
||||
if (!unload) CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%u' AND instance = '%u'", GetGUIDLow(), itr->second.save->GetInstanceId());
|
||||
if (!unload)
|
||||
CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%u' AND instance = '%u'", GetGUIDLow(), itr->second.save->GetInstanceId());
|
||||
itr->second.save->RemovePlayer(this); // save can become invalid
|
||||
m_boundInstances[difficulty].erase(itr++);
|
||||
}
|
||||
@@ -18120,6 +18133,7 @@ void Player::SaveToDB()
|
||||
_SaveEquipmentSets(trans);
|
||||
GetSession()->SaveTutorialsData(trans); // changed only while character in game
|
||||
_SaveGlyphs(trans);
|
||||
_SaveInstanceTimeRestrictions(trans);
|
||||
|
||||
// check if stats should only be saved on logout
|
||||
// save stats can be out of transaction
|
||||
@@ -24463,3 +24477,34 @@ float Player::GetAverageItemLevel()
|
||||
|
||||
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::_SaveInstanceTimeRestrictions(SQLTransaction& trans)
|
||||
{
|
||||
if (_instanceResetTimes.empty())
|
||||
return;
|
||||
|
||||
PreparedStatement* 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_ADD_ACCOUNT_INSTANCE_LOCK_TIMES);
|
||||
stmt->setUInt32(0, GetSession()->GetAccountId());
|
||||
stmt->setUInt32(1, itr->first);
|
||||
stmt->setUInt64(2, itr->second);
|
||||
trans->Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,9 @@ struct SpellCooldown
|
||||
|
||||
typedef std::map<uint32, SpellCooldown> SpellCooldowns;
|
||||
|
||||
#define MAX_INSTANCES_PER_HOUR 5
|
||||
typedef UNORDERED_MAP<uint32 /*instanceId*/, time_t/*releaseTime*/> InstanceTimeMap;
|
||||
|
||||
enum TrainerSpellState
|
||||
{
|
||||
TRAINER_SPELL_GREEN = 0,
|
||||
@@ -794,7 +797,8 @@ enum PlayerLoginQueryIndex
|
||||
PLAYER_LOGIN_QUERY_LOADARENASTATS = 28,
|
||||
PLAYER_LOGIN_QUERY_LOADBANNED = 29,
|
||||
PLAYER_LOGIN_QUERY_LOADQUESTSTATUSREW = 30,
|
||||
MAX_PLAYER_LOGIN_QUERY = 31
|
||||
PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES = 31,
|
||||
MAX_PLAYER_LOGIN_QUERY,
|
||||
};
|
||||
|
||||
enum PlayerDelayedOperations
|
||||
@@ -2303,6 +2307,18 @@ class Player : public Unit, public GridObject<Player>
|
||||
static void ConvertInstancesToGroup(Player *player, Group *group = NULL, uint64 player_guid = 0);
|
||||
bool Satisfy(AccessRequirement const* ar, uint32 target_map, bool report = false);
|
||||
bool CheckInstanceLoginValid();
|
||||
bool CheckInstanceCount(uint32 instanceId) const
|
||||
{
|
||||
if (_instanceResetTimes.size() < MAX_INSTANCES_PER_HOUR)
|
||||
return true;
|
||||
return _instanceResetTimes.find(instanceId) != _instanceResetTimes.end();
|
||||
}
|
||||
|
||||
void AddInstanceEnterTime(uint32 instanceId, time_t enterTime)
|
||||
{
|
||||
if (_instanceResetTimes.find(instanceId) == _instanceResetTimes.end())
|
||||
_instanceResetTimes.insert(InstanceTimeMap::value_type(instanceId, enterTime + HOUR));
|
||||
}
|
||||
|
||||
// last used pet number (for BG's)
|
||||
uint32 GetLastPetNumber() const { return m_lastpetnumber; }
|
||||
@@ -2449,6 +2465,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void _LoadBGData(PreparedQueryResult result);
|
||||
void _LoadGlyphs(PreparedQueryResult result);
|
||||
void _LoadTalents(PreparedQueryResult result);
|
||||
void _LoadInstanceTimeRestrictions(PreparedQueryResult result);
|
||||
|
||||
/*********************************************************/
|
||||
/*** SAVE SYSTEM ***/
|
||||
@@ -2468,6 +2485,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void _SaveGlyphs(SQLTransaction& trans);
|
||||
void _SaveTalents(SQLTransaction& trans);
|
||||
void _SaveStats(SQLTransaction& trans);
|
||||
void _SaveInstanceTimeRestrictions(SQLTransaction& trans);
|
||||
|
||||
void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
|
||||
void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;
|
||||
@@ -2700,6 +2718,8 @@ class Player : public Unit, public GridObject<Player>
|
||||
uint32 m_timeSyncTimer;
|
||||
uint32 m_timeSyncClient;
|
||||
uint32 m_timeSyncServer;
|
||||
|
||||
InstanceTimeMap _instanceResetTimes;
|
||||
};
|
||||
|
||||
void AddItemsSetItem(Player*player,Item *item);
|
||||
|
||||
Reference in New Issue
Block a user