aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Instances/InstanceLockMgr.cpp1
-rw-r--r--src/server/game/Maps/Map.cpp40
-rw-r--r--src/server/game/Maps/Map.h2
3 files changed, 32 insertions, 11 deletions
diff --git a/src/server/game/Instances/InstanceLockMgr.cpp b/src/server/game/Instances/InstanceLockMgr.cpp
index 97687ef8a8e..1296fb951dd 100644
--- a/src/server/game/Instances/InstanceLockMgr.cpp
+++ b/src/server/game/Instances/InstanceLockMgr.cpp
@@ -362,7 +362,6 @@ InstanceLock* InstanceLockMgr::UpdateInstanceLockForPlayer(CharacterDatabaseTran
if (instanceLock->IsExpired())
{
- ASSERT(instanceLock->IsExtended(), "Instance lock must have been extended to create instance map from it");
instanceLock->SetExpiryTime(GetNextResetTime(entries));
instanceLock->SetExtended(false);
TC_LOG_DEBUG("instance.locks", "[%u-%s | %u-%s] Expired instance lock for %s in instance %u is now active",
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index d69b5581179..ddfe404cc34 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2769,7 +2769,6 @@ template TC_GAME_API void Map::RemoveFromMap(Conversation*, bool);
InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty SpawnMode, TeamId InstanceTeam, InstanceLock* instanceLock)
: Map(id, expiry, InstanceId, SpawnMode),
- m_shuttingDown(false),
i_data(nullptr), i_script_id(0), i_scenario(nullptr), i_instanceLock(instanceLock)
{
//lets initialize visibility distance for dungeons
@@ -2783,7 +2782,10 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty
sWorldStateMgr->SetValue(WS_TEAM_IN_INSTANCE_HORDE, InstanceTeam == TEAM_HORDE, false, this);
if (i_instanceLock)
+ {
i_instanceLock->SetInUse(true);
+ i_instanceExpireEvent = i_instanceLock->GetExpiryTime(); // ignore extension state for reset event (will ask players to accept extended save on expiration)
+ }
}
InstanceMap::~InstanceMap()
@@ -2814,9 +2816,6 @@ Map::EnterState InstanceMap::CannotEnter(Player* player)
return CANNOT_ENTER_ALREADY_IN_MAP;
}
- if (m_shuttingDown)
- return CANNOT_ENTER_INSTANCE_SHUTTING_DOWN;
-
// allow GM's to enter
if (player->IsGameMaster())
return Map::CannotEnter(player);
@@ -2904,6 +2903,12 @@ void InstanceMap::Update(uint32 t_diff)
if (i_scenario)
i_scenario->Update(t_diff);
+
+ if (i_instanceExpireEvent && i_instanceExpireEvent < GameTime::GetSystemTime())
+ {
+ Reset(InstanceResetMethod::Expire);
+ i_instanceExpireEvent = sInstanceLockMgr.GetNextResetTime({ GetEntry(), GetMapDifficulty() });
+ }
}
void InstanceMap::RemovePlayerFromMap(Player* player, bool remove)
@@ -2915,7 +2920,7 @@ void InstanceMap::RemovePlayerFromMap(Player* player, bool remove)
// if last player set unload timer
if (!m_unloadTimer && m_mapRefManager.getSize() == 1)
- m_unloadTimer = m_shuttingDown ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
+ m_unloadTimer = (i_instanceLock && i_instanceLock->IsExpired()) ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);
if (i_scenario)
i_scenario->OnPlayerExit(player);
@@ -2985,13 +2990,30 @@ InstanceResetResult InstanceMap::Reset(InstanceResetMethod method)
// no client notification
break;
case InstanceResetMethod::Expire:
- // on lock expiration boot players (do we also care about extension state?)
- // set the homebind timer for players inside (1 minute)
+ {
+ WorldPackets::Instance::RaidInstanceMessage raidInstanceMessage;
+ raidInstanceMessage.Type = RAID_INSTANCE_EXPIRED;
+ raidInstanceMessage.MapID = GetId();
+ raidInstanceMessage.DifficultyID = GetDifficultyID();
+ raidInstanceMessage.Write();
+
+ WorldPackets::Instance::PendingRaidLock pendingRaidLock;
+ pendingRaidLock.TimeUntilLock = 60000;
+ pendingRaidLock.CompletedMask = i_instanceLock->GetData()->CompletedEncountersMask;
+ pendingRaidLock.Extending = true;
+ pendingRaidLock.WarningOnly = GetEntry()->IsFlexLocking();
+ pendingRaidLock.Write();
+
for (MapReference& ref : m_mapRefManager)
- ref.GetSource()->m_InstanceValid = false;
+ {
+ ref.GetSource()->SendDirectMessage(raidInstanceMessage.GetRawPacket());
+ ref.GetSource()->SendDirectMessage(pendingRaidLock.GetRawPacket());
- m_shuttingDown = true;
+ if (!pendingRaidLock.WarningOnly)
+ ref.GetSource()->SetPendingBind(GetInstanceId(), 60000);
+ }
break;
+ }
default:
break;
}
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 732fe9210d9..985ac6f01e2 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -836,7 +836,7 @@ class TC_GAME_API InstanceMap : public Map
std::string GetDebugInfo() const override;
private:
- bool m_shuttingDown;
+ Optional<SystemTimePoint> i_instanceExpireEvent;
InstanceScript* i_data;
uint32 i_script_id;
InstanceScenario* i_scenario;