diff options
| author | Shauren <shauren.trinity@gmail.com> | 2021-01-19 22:48:46 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2022-10-04 00:19:38 +0200 |
| commit | ab12e77cf72bcd361a380c8d1ed37d12fe0e1bbb (patch) | |
| tree | cfda9c15ec15003ee32c2aa466af7afb4901bec9 /src/server/game | |
| parent | 4ce1c6cdf419b52b889ad9dac7fb69d0059a1fe6 (diff) | |
Core/Commands: Restore instance management commands
Diffstat (limited to 'src/server/game')
| -rw-r--r-- | src/server/game/Accounts/RBAC.h | 2 | ||||
| -rw-r--r-- | src/server/game/Instances/InstanceLockMgr.cpp | 56 | ||||
| -rw-r--r-- | src/server/game/Instances/InstanceLockMgr.h | 27 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Miscellaneous/Language.h | 4 |
5 files changed, 91 insertions, 4 deletions
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index c06c9fbe8df..11f3698732d 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -285,7 +285,7 @@ enum RBACPermissions RBAC_PERM_COMMAND_INSTANCE_LISTBINDS = 413, RBAC_PERM_COMMAND_INSTANCE_UNBIND = 414, RBAC_PERM_COMMAND_INSTANCE_STATS = 415, - RBAC_PERM_COMMAND_INSTANCE_SAVEDATA = 416, + // 416 previously used, do not reuse RBAC_PERM_COMMAND_LEARN = 417, // 418 previously used, do not reuse RBAC_PERM_COMMAND_LEARN_ALL_MY = 419, diff --git a/src/server/game/Instances/InstanceLockMgr.cpp b/src/server/game/Instances/InstanceLockMgr.cpp index 7443a7f192d..97687ef8a8e 100644 --- a/src/server/game/Instances/InstanceLockMgr.cpp +++ b/src/server/game/Instances/InstanceLockMgr.cpp @@ -29,7 +29,7 @@ InstanceLockData::InstanceLockData() = default; InstanceLockData::~InstanceLockData() = default; InstanceLock::InstanceLock(uint32 mapId, Difficulty difficultyId, InstanceResetTimePoint expiryTime, uint32 instanceId) - : _mapId(mapId), _difficultyId(difficultyId), _instanceId(instanceId), _expiryTime(expiryTime), _extended(false) + : _mapId(mapId), _difficultyId(difficultyId), _instanceId(instanceId), _expiryTime(expiryTime), _extended(false), _isInUse(false) { } @@ -460,6 +460,60 @@ std::pair<InstanceResetTimePoint, InstanceResetTimePoint> InstanceLockMgr::Updat return { InstanceResetTimePoint::min(), InstanceResetTimePoint::min() }; } +void InstanceLockMgr::ResetInstanceLocksForPlayer(ObjectGuid const& playerGuid, Optional<uint32> mapId, Optional<Difficulty> difficulty, + std::vector<InstanceLock const*>* locksReset, std::vector<InstanceLock const*>* locksFailedToReset) +{ + auto playerLocksItr = _instanceLocksByPlayer.find(playerGuid); + if (playerLocksItr == _instanceLocksByPlayer.end()) + return; + + for (PlayerLockMap::value_type const& playerLockPair : playerLocksItr->second) + { + if (playerLockPair.second->IsInUse()) + { + locksFailedToReset->push_back(playerLockPair.second.get()); + continue; + } + + if (mapId && *mapId != playerLockPair.second->GetMapId()) + continue; + + if (difficulty && *difficulty != playerLockPair.second->GetDifficultyId()) + continue; + + locksReset->push_back(playerLockPair.second.get()); + } + + if (!locksReset->empty()) + { + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + for (InstanceLock const* instanceLock : *locksReset) + { + MapDb2Entries entries(instanceLock->GetMapId(), instanceLock->GetDifficultyId()); + InstanceResetTimePoint newExpiryTime = GetNextResetTime(entries) - Seconds(entries.MapDifficulty->GetRaidDuration()); + // set reset time to last reset time + const_cast<InstanceLock*>(instanceLock)->SetExpiryTime(newExpiryTime); + const_cast<InstanceLock*>(instanceLock)->SetExtended(false); + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_INSTANCE_LOCK_FORCE_EXPIRE); + stmt->setUInt64(0, uint64(std::chrono::system_clock::to_time_t(newExpiryTime))); + stmt->setUInt64(1, playerGuid.GetCounter()); + stmt->setUInt32(2, entries.MapDifficulty->MapID); + stmt->setUInt32(3, entries.MapDifficulty->LockID); + trans->Append(stmt); + } + CharacterDatabase.CommitTransaction(trans); + } +} + +InstanceLocksStatistics InstanceLockMgr::GetStatistics() const +{ + InstanceLocksStatistics statistics; + statistics.InstanceCount = _instanceLockDataById.size(); + statistics.PlayerCount = _instanceLocksByPlayer.size(); + return statistics; +} + InstanceResetTimePoint InstanceLockMgr::GetNextResetTime(MapDb2Entries const& entries) { tm dateTime = *GameTime::GetDateAndTime(); diff --git a/src/server/game/Instances/InstanceLockMgr.h b/src/server/game/Instances/InstanceLockMgr.h index 3f8aebf6d25..b860335b48f 100644 --- a/src/server/game/Instances/InstanceLockMgr.h +++ b/src/server/game/Instances/InstanceLockMgr.h @@ -112,6 +112,9 @@ public: InstanceResetTimePoint GetEffectiveExpiryTime() const; + bool IsInUse() const { return _isInUse; } + void SetInUse(bool inUse) { _isInUse = inUse; } + private: uint32 _mapId; Difficulty _difficultyId; @@ -119,6 +122,7 @@ private: std::chrono::system_clock::time_point _expiryTime; bool _extended; InstanceLockData _data; + bool _isInUse; }; struct SharedInstanceLockData : InstanceLockData @@ -193,6 +197,12 @@ struct InstanceLockUpdateEvent Optional<uint32> EntranceWorldSafeLocId; }; +struct InstanceLocksStatistics +{ + uint32 InstanceCount = 0; // Number of existing ID-based locks + uint32 PlayerCount = 0; // Number of players that have any lock +}; + class TC_GAME_API InstanceLockMgr { public: @@ -264,6 +274,23 @@ public: */ std::pair<InstanceResetTimePoint, InstanceResetTimePoint> UpdateInstanceLockExtensionForPlayer(ObjectGuid const& playerGuid, MapDb2Entries const& entries, bool extended); + /** + @brief Resets instances that match given filter - for use in GM commands + @param playerGuid Guid of player whose locks will be removed + @param mapId (Optional) Map id of instance locks to reset + @param difficulty (Optional) Difficulty of instance locks to reset + @param locksReset All locks that were reset + @param locksFailedToReset Locks that could not be reset because they are used by existing instance map + */ + void ResetInstanceLocksForPlayer(ObjectGuid const& playerGuid, Optional<uint32> mapId, Optional<Difficulty> difficulty, + std::vector<InstanceLock const*>* locksReset, std::vector<InstanceLock const*>* locksFailedToReset); + + /** + @brief Retrieves instance lock statistics - for use in GM commands + @return Statistics info + */ + InstanceLocksStatistics GetStatistics() const; + static InstanceLockMgr& Instance(); static InstanceResetTimePoint GetNextResetTime(MapDb2Entries const& entries); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index fbf89f37050..d69b5581179 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2781,10 +2781,16 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty sWorldStateMgr->SetValue(WS_TEAM_IN_INSTANCE_ALLIANCE, InstanceTeam == TEAM_ALLIANCE, false, this); sWorldStateMgr->SetValue(WS_TEAM_IN_INSTANCE_HORDE, InstanceTeam == TEAM_HORDE, false, this); + + if (i_instanceLock) + i_instanceLock->SetInUse(true); } InstanceMap::~InstanceMap() { + if (i_instanceLock) + i_instanceLock->SetInUse(false); + delete i_data; delete i_scenario; } diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 18f1a1e6ff2..19a0712b3d8 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1100,14 +1100,14 @@ enum TrinityStrings // Instance commands LANG_COMMAND_LIST_BIND_INFO = 5045, LANG_COMMAND_LIST_BIND_PLAYER_BINDS = 5046, - LANG_COMMAND_LIST_BIND_GROUP_BINDS = 5047, + LANG_COMMAND_INST_UNBIND_FAILED = 5047, LANG_COMMAND_INST_UNBIND_UNBINDING = 5048, LANG_COMMAND_INST_UNBIND_UNBOUND = 5049, LANG_COMMAND_INST_STAT_LOADED_INST = 5050, LANG_COMMAND_INST_STAT_PLAYERS_IN = 5051, LANG_COMMAND_INST_STAT_SAVES = 5052, LANG_COMMAND_INST_STAT_PLAYERSBOUND = 5053, - LANG_COMMAND_INST_STAT_GROUPSBOUND = 5054, + // = 5054, // old LANG_COMMAND_INST_STAT_GROUPSBOUND LANG_NOT_DUNGEON = 5055, // Map is not a dungeon. LANG_NO_INSTANCE_DATA = 5056, // Map has no instance data. LANG_COMMAND_INST_SET_BOSS_STATE = 5057, |
