mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
Let world shutdown dz early for empty expeditions
Since world now tracks empty expeditions it can determine when to shutdown dynamic zone instances when the rule is enabled rather than letting zones do it.
This commit is contained in:
+12
-26
@@ -437,32 +437,6 @@ void DynamicZone::SendInstanceCharacterChange(uint32_t character_id, bool remove
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::UpdateExpireTime(uint32_t seconds, bool reduce_only)
|
||||
{
|
||||
if (GetInstanceID() == 0 || (reduce_only && GetSecondsRemaining() < seconds))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_expire_time = std::chrono::system_clock::now() + std::chrono::seconds(seconds);
|
||||
m_duration = std::chrono::system_clock::to_time_t(m_expire_time) - m_start_time;
|
||||
|
||||
std::string query = fmt::format(SQL(
|
||||
UPDATE instance_list SET duration = {} WHERE id = {};
|
||||
), m_duration, GetInstanceID());
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success())
|
||||
{
|
||||
uint32_t packsize = sizeof(ServerInstanceUpdateTime_Struct);
|
||||
auto pack = std::unique_ptr<ServerPacket>(new ServerPacket(ServerOP_InstanceUpdateTime, packsize));
|
||||
auto packbuf = reinterpret_cast<ServerInstanceUpdateTime_Struct*>(pack->pBuffer);
|
||||
packbuf->instance_id = GetInstanceID();
|
||||
packbuf->new_duration = seconds;
|
||||
worldserver.SendPacket(pack.get());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::SetCompass(const DynamicZoneLocation& location, bool update_db)
|
||||
{
|
||||
m_compass = location;
|
||||
@@ -515,6 +489,18 @@ uint32_t DynamicZone::GetSecondsRemaining() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DynamicZone::SetUpdatedDuration(uint32_t new_duration)
|
||||
{
|
||||
// preserves original start time, just modifies duration and expire time
|
||||
m_duration = new_duration;
|
||||
m_expire_time = std::chrono::system_clock::from_time_t(m_start_time + m_duration);
|
||||
|
||||
if (zone && IsCurrentZoneDzInstance())
|
||||
{
|
||||
zone->SetInstanceTimer(GetSecondsRemaining());
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::HandleWorldMessage(ServerPacket* pack)
|
||||
{
|
||||
switch (pack->opcode)
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ public:
|
||||
void SetCompass(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void SetZoneInLocation(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void UpdateExpireTime(uint32_t seconds, bool reduce_only = true);
|
||||
void SetUpdatedDuration(uint32_t seconds);
|
||||
|
||||
void LoadFromDatabase(uint32_t instance_id);
|
||||
uint32_t SaveToDatabase();
|
||||
|
||||
+11
-18
@@ -477,15 +477,10 @@ bool Expedition::AddMember(const std::string& add_char_name, uint32_t add_char_i
|
||||
return true;
|
||||
}
|
||||
|
||||
void Expedition::RemoveAllMembers(bool enable_removal_timers, bool update_dz_expire_time)
|
||||
void Expedition::RemoveAllMembers(bool enable_removal_timers)
|
||||
{
|
||||
m_dynamiczone.RemoveAllCharacters(enable_removal_timers);
|
||||
|
||||
if (update_dz_expire_time && RuleB(Expedition, EmptyDzShutdownEnabled))
|
||||
{
|
||||
m_dynamiczone.UpdateExpireTime(RuleI(Expedition, EmptyDzShutdownDelaySeconds));
|
||||
}
|
||||
|
||||
ExpeditionDatabase::UpdateAllMembersRemoved(m_id);
|
||||
|
||||
SendUpdatesToZoneMembers(true);
|
||||
@@ -512,18 +507,6 @@ bool Expedition::RemoveMember(const std::string& remove_char_name)
|
||||
ChooseNewLeader();
|
||||
}
|
||||
|
||||
// we can't check for empty member count via cache because if other zones
|
||||
// remove members at the same time then we race. cache member count won't
|
||||
// be accurate until the world messages from other zones are processed
|
||||
uint32_t member_count = ExpeditionDatabase::GetExpeditionMemberCount(m_id);
|
||||
if (member_count == 0)
|
||||
{
|
||||
if (RuleB(Expedition, EmptyDzShutdownEnabled))
|
||||
{
|
||||
m_dynamiczone.UpdateExpireTime(RuleI(Expedition, EmptyDzShutdownDelaySeconds));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1813,6 +1796,16 @@ void Expedition::HandleWorldMessage(ServerPacket* pack)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_ExpeditionDzDuration:
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerExpeditionUpdateDuration_Struct*>(pack->pBuffer);
|
||||
auto expedition = Expedition::FindCachedExpeditionByID(buf->expedition_id);
|
||||
if (expedition)
|
||||
{
|
||||
expedition->SetDzDuration(buf->new_duration_seconds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -102,7 +102,7 @@ public:
|
||||
bool AddMember(const std::string& add_char_name, uint32_t add_char_id);
|
||||
bool HasMember(const std::string& character_name);
|
||||
bool HasMember(uint32_t character_id);
|
||||
void RemoveAllMembers(bool enable_removal_timers = true, bool update_dz_expire_time = true);
|
||||
void RemoveAllMembers(bool enable_removal_timers = true);
|
||||
bool RemoveMember(const std::string& remove_char_name);
|
||||
void SetMemberStatus(Client* client, ExpeditionMemberStatus status);
|
||||
void SetNewLeader(uint32_t new_leader_id, const std::string& new_leader_name);
|
||||
@@ -134,6 +134,7 @@ public:
|
||||
void SetDzSafeReturn(uint32_t zone_id, float x, float y, float z, float heading, bool update_db = false);
|
||||
void SetDzSafeReturn(const std::string& zone_name, float x, float y, float z, float heading, bool update_db = false);
|
||||
void SetDzZoneInLocation(float x, float y, float z, float heading, bool update_db = false);
|
||||
void SetDzDuration(uint32_t new_duration) { m_dynamiczone.SetUpdatedDuration(new_duration); }
|
||||
|
||||
static const uint32_t REPLAY_TIMER_ID;
|
||||
static const uint32_t EVENT_TIMER_ID;
|
||||
|
||||
@@ -395,25 +395,6 @@ ExpeditionMember ExpeditionDatabase::GetExpeditionLeader(uint32_t expedition_id)
|
||||
return leader;
|
||||
}
|
||||
|
||||
uint32_t ExpeditionDatabase::GetExpeditionMemberCount(uint32_t expedition_id)
|
||||
{
|
||||
auto query = fmt::format(SQL(
|
||||
SELECT COUNT(IF(is_current_member = TRUE, 1, NULL)) member_count
|
||||
FROM expedition_members
|
||||
WHERE expedition_id = {};
|
||||
), expedition_id);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
uint32_t member_count = 0;
|
||||
if (results.Success() && results.RowCount() > 0)
|
||||
{
|
||||
auto row = results.begin();
|
||||
member_count = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||
}
|
||||
return member_count;
|
||||
}
|
||||
|
||||
void ExpeditionDatabase::InsertCharacterLockouts(
|
||||
uint32_t character_id, const std::vector<ExpeditionLockoutTimer>& lockouts,
|
||||
bool update_expire_times, bool is_pending)
|
||||
|
||||
@@ -55,7 +55,6 @@ namespace ExpeditionDatabase
|
||||
uint32_t GetExpeditionIDFromCharacterID(uint32_t character_id);
|
||||
uint32_t GetExpeditionIDFromInstanceID(uint32_t instance_id);
|
||||
ExpeditionMember GetExpeditionLeader(uint32_t expedition_id);
|
||||
uint32_t GetExpeditionMemberCount(uint32_t expedition_id);
|
||||
void InsertCharacterLockouts(
|
||||
uint32_t character_id, const std::vector<ExpeditionLockoutTimer>& lockouts,
|
||||
bool update_expire_times, bool is_pending = false);
|
||||
|
||||
@@ -2915,6 +2915,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
case ServerOP_ExpeditionDzCompass:
|
||||
case ServerOP_ExpeditionDzSafeReturn:
|
||||
case ServerOP_ExpeditionDzZoneIn:
|
||||
case ServerOP_ExpeditionDzDuration:
|
||||
case ServerOP_ExpeditionRemoveCharLockouts:
|
||||
{
|
||||
Expedition::HandleWorldMessage(pack);
|
||||
|
||||
+1
-1
@@ -1495,7 +1495,7 @@ bool Zone::Process() {
|
||||
Expedition* expedition = Expedition::FindExpeditionByInstanceID(GetInstanceID());
|
||||
if (expedition)
|
||||
{
|
||||
expedition->RemoveAllMembers(false, false); // entity list will teleport clients out immediately
|
||||
expedition->RemoveAllMembers(false); // entity list will teleport clients out immediately
|
||||
}
|
||||
// todo: move corpses to non-instanced version of dz at same coords (if no graveyard)
|
||||
entity_list.GateAllClientsToSafeReturn();
|
||||
|
||||
Reference in New Issue
Block a user