aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2021-01-19 22:48:46 +0100
committerShauren <shauren.trinity@gmail.com>2022-10-04 00:19:38 +0200
commitab12e77cf72bcd361a380c8d1ed37d12fe0e1bbb (patch)
treecfda9c15ec15003ee32c2aa466af7afb4901bec9 /src/server/game
parent4ce1c6cdf419b52b889ad9dac7fb69d0059a1fe6 (diff)
Core/Commands: Restore instance management commands
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/Accounts/RBAC.h2
-rw-r--r--src/server/game/Instances/InstanceLockMgr.cpp56
-rw-r--r--src/server/game/Instances/InstanceLockMgr.h27
-rw-r--r--src/server/game/Maps/Map.cpp6
-rw-r--r--src/server/game/Miscellaneous/Language.h4
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,