mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
Use internal dz messages to process duration and location changes Add world DynamicZone class (later this will inherit from a base) Add FindDynamicZoneByID to get dz from zone and world system caches
104 lines
2.9 KiB
C++
104 lines
2.9 KiB
C++
#include "dynamic_zone.h"
|
|
#include "expedition.h"
|
|
#include "expedition_state.h"
|
|
#include "worlddb.h"
|
|
#include "zonelist.h"
|
|
#include "zoneserver.h"
|
|
#include "../common/eqemu_logsys.h"
|
|
#include "../common/repositories/instance_list_repository.h"
|
|
|
|
extern ZSList zoneserver_list;
|
|
|
|
DynamicZone::DynamicZone(
|
|
uint32_t id, uint32_t zone_id, uint32_t instance_id, uint32_t zone_version,
|
|
uint32_t start_time, uint32_t duration, DynamicZoneType type
|
|
) :
|
|
m_id(id),
|
|
m_instance_id(instance_id),
|
|
m_zone_id(zone_id),
|
|
m_zone_version(zone_version),
|
|
m_start_time(std::chrono::system_clock::from_time_t(start_time)),
|
|
m_duration(duration),
|
|
m_type(type),
|
|
m_expire_time(m_start_time + m_duration)
|
|
{
|
|
}
|
|
|
|
DynamicZone* DynamicZone::FindDynamicZoneByID(uint32_t dz_id)
|
|
{
|
|
auto expedition = expedition_state.GetExpeditionByDynamicZoneID(dz_id);
|
|
if (expedition)
|
|
{
|
|
return &expedition->GetDynamicZone();
|
|
}
|
|
// todo: other system caches
|
|
return nullptr;
|
|
}
|
|
|
|
void DynamicZone::SetSecondsRemaining(uint32_t seconds_remaining)
|
|
{
|
|
auto now = std::chrono::system_clock::now();
|
|
auto new_remaining = std::chrono::seconds(seconds_remaining);
|
|
|
|
auto current_remaining = m_expire_time - now;
|
|
if (current_remaining > new_remaining) // reduce only
|
|
{
|
|
LogDynamicZonesDetail("Updating dynamic zone [{}] instance [{}] seconds remaining to [{}]s",
|
|
GetID(), GetInstanceID(), seconds_remaining);
|
|
|
|
// preserve original start time and adjust duration instead
|
|
m_expire_time = now + new_remaining;
|
|
m_duration = std::chrono::duration_cast<std::chrono::seconds>(m_expire_time - m_start_time);
|
|
|
|
InstanceListRepository::UpdateDuration(database,
|
|
GetInstanceID(), static_cast<uint32_t>(m_duration.count()));
|
|
|
|
SendZonesDurationUpdate(); // update zone caches and actual instance's timer
|
|
}
|
|
}
|
|
|
|
void DynamicZone::SendZonesDurationUpdate()
|
|
{
|
|
constexpr uint32_t packsize = sizeof(ServerDzSetDuration_Struct);
|
|
auto pack = std::make_unique<ServerPacket>(ServerOP_DzDurationUpdate, packsize);
|
|
auto packbuf = reinterpret_cast<ServerDzSetDuration_Struct*>(pack->pBuffer);
|
|
packbuf->dz_id = GetID();
|
|
packbuf->seconds = static_cast<uint32_t>(m_duration.count());
|
|
zoneserver_list.SendPacket(pack.get());
|
|
}
|
|
|
|
void DynamicZone::HandleZoneMessage(ServerPacket* pack)
|
|
{
|
|
switch (pack->opcode)
|
|
{
|
|
case ServerOP_DzSetCompass:
|
|
case ServerOP_DzSetSafeReturn:
|
|
case ServerOP_DzSetZoneIn:
|
|
{
|
|
zoneserver_list.SendPacket(pack);
|
|
break;
|
|
}
|
|
case ServerOP_DzCharacterChange:
|
|
case ServerOP_DzRemoveAllCharacters:
|
|
{
|
|
auto buf = reinterpret_cast<ServerDzCharacter_Struct*>(pack->pBuffer);
|
|
ZoneServer* instance_zs = zoneserver_list.FindByInstanceID(buf->instance_id);
|
|
if (instance_zs)
|
|
{
|
|
instance_zs->SendPacket(pack);
|
|
}
|
|
break;
|
|
}
|
|
case ServerOP_DzSetSecondsRemaining:
|
|
{
|
|
auto buf = reinterpret_cast<ServerDzSetDuration_Struct*>(pack->pBuffer);
|
|
auto dz = DynamicZone::FindDynamicZoneByID(buf->dz_id);
|
|
if (dz)
|
|
{
|
|
dz->SetSecondsRemaining(buf->seconds);
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
}
|