mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 05:21:29 +00:00
Store expeditions with dz id not instance id
This exposes dynamic zone ids for any future changes and will make it easier to preserve historic dz and expedition data. This also cleans up some dynamic zone creation for expedition requests When purging instances the expedition table is no longer updated since dynamic zone ids are not re-used like instance ids are Update #dz list commands to show dz id Add GetDynamicZoneID and get_expedition_by_dz_id quest apis
This commit is contained in:
parent
54500b0e72
commit
b46eca4ec6
@ -496,9 +496,6 @@ void Database::DeleteInstance(uint16 instance_id)
|
||||
query = fmt::format("DELETE FROM dynamic_zones WHERE instance_id={}", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
query = fmt::format("UPDATE expeditions SET instance_id = NULL WHERE instance_id={}", instance_id);
|
||||
QueryDatabase(query);
|
||||
|
||||
BuryCorpsesInInstance(instance_id);
|
||||
}
|
||||
|
||||
@ -589,7 +586,6 @@ void Database::PurgeExpiredInstances()
|
||||
QueryDatabase(fmt::format("DELETE FROM spawn_condition_values WHERE instance_id IN ({})", imploded_instance_ids));
|
||||
QueryDatabase(fmt::format("UPDATE character_corpses SET is_buried = 1, instance_id = 0 WHERE instance_id IN ({})", imploded_instance_ids));
|
||||
QueryDatabase(fmt::format("DELETE FROM dynamic_zones WHERE instance_id IN ({})", imploded_instance_ids));
|
||||
QueryDatabase(fmt::format("UPDATE expeditions SET instance_id = NULL WHERE instance_id IN ({})", imploded_instance_ids));
|
||||
}
|
||||
|
||||
void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
CREATE TABLE `expeditions` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`uuid` VARCHAR(36) NOT NULL,
|
||||
`instance_id` INT(10) NULL DEFAULT 0,
|
||||
`dynamic_zone_id` INT(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`expedition_name` VARCHAR(128) NOT NULL,
|
||||
`leader_id` INT(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`min_players` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||
@ -9,7 +9,7 @@ CREATE TABLE `expeditions` (
|
||||
`add_replay_on_join` TINYINT(3) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`is_locked` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `instance_id` (`instance_id`)
|
||||
UNIQUE INDEX `dynamic_zone_id` (`dynamic_zone_id`)
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
|
||||
@ -26,12 +26,12 @@
|
||||
|
||||
extern ZSList zoneserver_list;
|
||||
|
||||
Expedition::Expedition(
|
||||
uint32_t expedition_id, uint32_t instance_id, uint32_t dz_zone_id,
|
||||
uint32_t start_time, uint32_t duration
|
||||
Expedition::Expedition(uint32_t expedition_id, uint32_t dz_id, uint32_t dz_instance_id,
|
||||
uint32_t dz_zone_id, uint32_t start_time, uint32_t duration
|
||||
) :
|
||||
m_expedition_id(expedition_id),
|
||||
m_dz_instance_id(instance_id),
|
||||
m_dz_id(dz_id),
|
||||
m_dz_instance_id(dz_instance_id),
|
||||
m_dz_zone_id(dz_zone_id),
|
||||
m_start_time(std::chrono::system_clock::from_time_t(start_time)),
|
||||
m_duration(duration)
|
||||
|
||||
@ -30,8 +30,8 @@ class Expedition
|
||||
{
|
||||
public:
|
||||
Expedition() = default;
|
||||
Expedition(uint32_t expedition_id, uint32_t instance_id, uint32_t dz_zone_id,
|
||||
uint32_t expire_time, uint32_t duration);
|
||||
Expedition(uint32_t expedition_id, uint32_t dz_id, uint32_t dz_instance_id,
|
||||
uint32_t dz_zone_id, uint32_t expire_time, uint32_t duration);
|
||||
|
||||
void AddMember(uint32_t character_id) { m_member_ids.emplace(character_id); }
|
||||
void RemoveMember(uint32_t character_id) { m_member_ids.erase(character_id); }
|
||||
@ -43,6 +43,7 @@ public:
|
||||
bool IsEmpty() const { return m_member_ids.empty(); }
|
||||
bool IsExpired() const { return m_expire_time < std::chrono::system_clock::now(); }
|
||||
bool IsPendingDelete() const { return m_pending_delete; }
|
||||
bool IsValid() const { return m_expedition_id != 0; }
|
||||
void SendZonesDurationUpdate();
|
||||
void SendZonesExpeditionDeleted();
|
||||
void SendZonesExpireWarning(uint32_t minutes_remaining);
|
||||
@ -52,6 +53,7 @@ public:
|
||||
|
||||
private:
|
||||
uint32_t m_expedition_id = 0;
|
||||
uint32_t m_dz_id = 0;
|
||||
uint32_t m_dz_instance_id = 0;
|
||||
uint32_t m_dz_zone_id = 0;
|
||||
bool m_pending_delete = false;
|
||||
|
||||
@ -28,7 +28,8 @@ void ExpeditionDatabase::PurgeExpiredExpeditions()
|
||||
SELECT
|
||||
expeditions.id
|
||||
FROM expeditions
|
||||
LEFT JOIN instance_list ON expeditions.instance_id = instance_list.id
|
||||
LEFT JOIN dynamic_zones ON expeditions.dynamic_zone_id = dynamic_zones.id
|
||||
LEFT JOIN instance_list ON dynamic_zones.instance_id = instance_list.id
|
||||
LEFT JOIN
|
||||
(
|
||||
SELECT expedition_id, COUNT(*) member_count
|
||||
@ -64,24 +65,34 @@ void ExpeditionDatabase::PurgeExpiredCharacterLockouts()
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
|
||||
std::vector<Expedition> ExpeditionDatabase::LoadExpeditions()
|
||||
std::vector<Expedition> ExpeditionDatabase::LoadExpeditions(uint32_t select_expedition_id)
|
||||
{
|
||||
std::vector<Expedition> expeditions;
|
||||
|
||||
std::string query = SQL(
|
||||
SELECT
|
||||
expeditions.id,
|
||||
expeditions.instance_id,
|
||||
expeditions.dynamic_zone_id,
|
||||
instance_list.id,
|
||||
instance_list.zone,
|
||||
instance_list.start_time,
|
||||
instance_list.duration,
|
||||
expedition_members.character_id
|
||||
FROM expeditions
|
||||
INNER JOIN instance_list ON expeditions.instance_id = instance_list.id
|
||||
INNER JOIN dynamic_zones ON expeditions.dynamic_zone_id = dynamic_zones.id
|
||||
INNER JOIN instance_list ON dynamic_zones.instance_id = instance_list.id
|
||||
INNER JOIN expedition_members ON expedition_members.expedition_id = expeditions.id
|
||||
ORDER BY expeditions.id;
|
||||
);
|
||||
|
||||
if (select_expedition_id != 0)
|
||||
{
|
||||
query.append(fmt::format(" WHERE expeditions.id = {};", select_expedition_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
query.append(" ORDER BY expeditions.id;");
|
||||
}
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success())
|
||||
{
|
||||
@ -95,16 +106,17 @@ std::vector<Expedition> ExpeditionDatabase::LoadExpeditions()
|
||||
{
|
||||
expeditions.emplace_back(
|
||||
static_cast<uint32_t>(strtoul(row[0], nullptr, 10)), // expedition_id
|
||||
static_cast<uint32_t>(strtoul(row[1], nullptr, 10)), // dz_instance_id
|
||||
static_cast<uint32_t>(strtoul(row[2], nullptr, 10)), // dz_zone_id
|
||||
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)), // start_time
|
||||
static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) // duration
|
||||
static_cast<uint32_t>(strtoul(row[1], nullptr, 10)), // dz_id
|
||||
static_cast<uint32_t>(strtoul(row[2], nullptr, 10)), // dz_instance_id
|
||||
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)), // dz_zone_id
|
||||
static_cast<uint32_t>(strtoul(row[4], nullptr, 10)), // start_time
|
||||
static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) // duration
|
||||
);
|
||||
}
|
||||
|
||||
last_expedition_id = expedition_id;
|
||||
|
||||
uint32_t member_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
uint32_t member_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||
expeditions.back().AddMember(member_id);
|
||||
}
|
||||
}
|
||||
@ -118,41 +130,10 @@ Expedition ExpeditionDatabase::LoadExpedition(uint32_t expedition_id)
|
||||
|
||||
Expedition expedition;
|
||||
|
||||
std::string query = fmt::format(SQL(
|
||||
SELECT
|
||||
expeditions.id,
|
||||
expeditions.instance_id,
|
||||
instance_list.zone,
|
||||
instance_list.start_time,
|
||||
instance_list.duration,
|
||||
expedition_members.character_id
|
||||
FROM expeditions
|
||||
INNER JOIN instance_list ON expeditions.instance_id = instance_list.id
|
||||
INNER JOIN expedition_members ON expedition_members.expedition_id = expeditions.id
|
||||
WHERE expeditions.id = {};
|
||||
), expedition_id);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success())
|
||||
auto expeditions = LoadExpeditions(expedition_id);
|
||||
if (!expeditions.empty())
|
||||
{
|
||||
bool created = false;
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
if (!created)
|
||||
{
|
||||
expedition = Expedition{
|
||||
static_cast<uint32_t>(strtoul(row[0], nullptr, 10)), // expedition_id
|
||||
static_cast<uint32_t>(strtoul(row[1], nullptr, 10)), // dz_instance_id
|
||||
static_cast<uint32_t>(strtoul(row[2], nullptr, 10)), // dz_zone_id
|
||||
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)), // start_time
|
||||
static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) // duration
|
||||
};
|
||||
created = true;
|
||||
}
|
||||
|
||||
auto member_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
expedition.AddMember(member_id);
|
||||
}
|
||||
expedition = expeditions.front();
|
||||
}
|
||||
|
||||
return expedition;
|
||||
|
||||
@ -29,7 +29,7 @@ class Expedition;
|
||||
namespace ExpeditionDatabase
|
||||
{
|
||||
void DeleteExpeditions(const std::vector<uint32_t>& expedition_ids);
|
||||
std::vector<Expedition> LoadExpeditions();
|
||||
std::vector<Expedition> LoadExpeditions(uint32_t select_expedition_id = 0);
|
||||
Expedition LoadExpedition(uint32_t expedition_id);
|
||||
void PurgeExpiredExpeditions();
|
||||
void PurgeExpiredCharacterLockouts();
|
||||
|
||||
@ -49,7 +49,7 @@ void ExpeditionState::AddExpedition(uint32_t expedition_id)
|
||||
|
||||
auto expedition = ExpeditionDatabase::LoadExpedition(expedition_id);
|
||||
|
||||
if (expedition.GetID() == expedition_id)
|
||||
if (expedition.IsValid())
|
||||
{
|
||||
auto it = std::find_if(m_expeditions.begin(), m_expeditions.end(), [&](const Expedition& expedition) {
|
||||
return expedition.GetID() == expedition_id;
|
||||
|
||||
@ -6844,8 +6844,9 @@ void command_dz(Client* c, const Seperator* sep)
|
||||
auto seconds = expedition.second->GetDynamicZone().GetSecondsRemaining();
|
||||
|
||||
c->Message(Chat::White, fmt::format(
|
||||
"Expedition id: [{}] name: [{}] leader: [{}] zone: [{}]:[{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||
"expedition id: [{}] dz id: [{}] name: [{}] leader: [{}] zone: [{}]:[{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||
expedition.second->GetID(),
|
||||
expedition.second->GetDynamicZoneID(),
|
||||
expedition.second->GetName(),
|
||||
expedition.second->GetLeaderName(),
|
||||
ZoneName(expedition.second->GetDynamicZone().GetZoneID()),
|
||||
@ -6900,6 +6901,7 @@ void command_dz(Client* c, const Seperator* sep)
|
||||
{
|
||||
std::string query = SQL(
|
||||
SELECT
|
||||
dynamic_zones.id,
|
||||
dynamic_zones.type,
|
||||
instance_list.id,
|
||||
instance_list.zone,
|
||||
@ -6919,8 +6921,8 @@ void command_dz(Client* c, const Seperator* sep)
|
||||
c->Message(Chat::White, fmt::format("Total Dynamic Zones: [{}]", results.RowCount()).c_str());
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
{
|
||||
auto start_time = strtoul(row[4], nullptr, 10);
|
||||
auto duration = strtoul(row[5], nullptr, 10);
|
||||
auto start_time = strtoul(row[5], nullptr, 10);
|
||||
auto duration = strtoul(row[6], nullptr, 10);
|
||||
auto expire_time = std::chrono::system_clock::from_time_t(start_time + duration);
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
@ -6931,12 +6933,13 @@ void command_dz(Client* c, const Seperator* sep)
|
||||
if (!is_expired || strcasecmp(sep->arg[2], "all") == 0)
|
||||
{
|
||||
c->Message(Chat::White, fmt::format(
|
||||
"type: [{}] zone: [{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||
strtoul(row[0], nullptr, 10),
|
||||
strtoul(row[2], nullptr, 10),
|
||||
strtoul(row[1], nullptr, 10),
|
||||
strtoul(row[3], nullptr, 10),
|
||||
strtoul(row[6], nullptr, 10),
|
||||
"dz id: [{}] type: [{}] zone: [{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||
strtoul(row[0], nullptr, 10), // dynamic_zone_id
|
||||
strtoul(row[1], nullptr, 10), // dynamic_zone_type
|
||||
strtoul(row[3], nullptr, 10), // instance_zone_id
|
||||
strtoul(row[2], nullptr, 10), // instance_id
|
||||
strtoul(row[4], nullptr, 10), // instance_zone_version
|
||||
strtoul(row[7], nullptr, 10), // instance member_count
|
||||
seconds / 3600, // hours
|
||||
(seconds / 60) % 60, // minutes
|
||||
seconds % 60 // seconds
|
||||
|
||||
@ -51,36 +51,26 @@ DynamicZone::DynamicZone(
|
||||
}
|
||||
}
|
||||
|
||||
DynamicZone DynamicZone::LoadDzFromDatabase(uint32_t instance_id)
|
||||
{
|
||||
DynamicZone dynamic_zone;
|
||||
if (instance_id != 0)
|
||||
{
|
||||
dynamic_zone.LoadFromDatabase(instance_id);
|
||||
}
|
||||
return dynamic_zone;
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, DynamicZone> DynamicZone::LoadMultipleDzFromDatabase(
|
||||
const std::vector<uint32_t>& instance_ids)
|
||||
const std::vector<uint32_t>& dynamic_zone_ids)
|
||||
{
|
||||
LogDynamicZonesDetail("Loading dynamic zone data for [{}] instances", instance_ids.size());
|
||||
LogDynamicZonesDetail("Loading dynamic zone data for [{}] instances", dynamic_zone_ids.size());
|
||||
|
||||
std::string in_instance_ids_query;
|
||||
for (const auto& instance_id : instance_ids)
|
||||
std::string in_dynamic_zone_ids_query;
|
||||
for (const auto& dynamic_zone_id : dynamic_zone_ids)
|
||||
{
|
||||
fmt::format_to(std::back_inserter(in_instance_ids_query), "{},", instance_id);
|
||||
fmt::format_to(std::back_inserter(in_dynamic_zone_ids_query), "{},", dynamic_zone_id);
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, DynamicZone> dynamic_zones;
|
||||
|
||||
if (!in_instance_ids_query.empty())
|
||||
if (!in_dynamic_zone_ids_query.empty())
|
||||
{
|
||||
in_instance_ids_query.pop_back(); // trailing comma
|
||||
in_dynamic_zone_ids_query.pop_back(); // trailing comma
|
||||
|
||||
std::string query = fmt::format(SQL(
|
||||
{} WHERE dynamic_zones.instance_id IN ({});
|
||||
), DynamicZoneSelectQuery(), in_instance_ids_query);
|
||||
{} WHERE dynamic_zones.id IN ({});
|
||||
), DynamicZoneSelectQuery(), in_dynamic_zone_ids_query);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success())
|
||||
@ -89,7 +79,7 @@ std::unordered_map<uint32_t, DynamicZone> DynamicZone::LoadMultipleDzFromDatabas
|
||||
{
|
||||
DynamicZone dz;
|
||||
dz.LoadDatabaseResult(row);
|
||||
dynamic_zones.emplace(dz.GetInstanceID(), dz);
|
||||
dynamic_zones.emplace(dz.GetID(), dz);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,6 +87,23 @@ std::unordered_map<uint32_t, DynamicZone> DynamicZone::LoadMultipleDzFromDatabas
|
||||
return dynamic_zones;
|
||||
}
|
||||
|
||||
uint32_t DynamicZone::Create()
|
||||
{
|
||||
if (m_id != 0)
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
if (GetInstanceID() == 0)
|
||||
{
|
||||
CreateInstance();
|
||||
}
|
||||
|
||||
m_id = SaveToDatabase();
|
||||
|
||||
return m_id;
|
||||
}
|
||||
|
||||
uint32_t DynamicZone::CreateInstance()
|
||||
{
|
||||
if (m_instance_id)
|
||||
@ -152,6 +159,7 @@ std::string DynamicZone::DynamicZoneSelectQuery()
|
||||
instance_list.start_time,
|
||||
instance_list.duration,
|
||||
instance_list.never_expires,
|
||||
dynamic_zones.id,
|
||||
dynamic_zones.type,
|
||||
dynamic_zones.compass_zone_id,
|
||||
dynamic_zones.compass_x,
|
||||
@ -181,42 +189,22 @@ void DynamicZone::LoadDatabaseResult(MySQLRequestRow& row)
|
||||
m_duration = std::chrono::seconds(strtoul(row[4], nullptr, 10));
|
||||
m_expire_time = m_start_time + m_duration;
|
||||
m_never_expires = (strtoul(row[5], nullptr, 10) != 0);
|
||||
m_type = static_cast<DynamicZoneType>(strtoul(row[6], nullptr, 10));
|
||||
m_compass.zone_id = strtoul(row[7], nullptr, 10);
|
||||
m_compass.x = strtof(row[8], nullptr);
|
||||
m_compass.y = strtof(row[9], nullptr);
|
||||
m_compass.z = strtof(row[10], nullptr);
|
||||
m_safereturn.zone_id = strtoul(row[11], nullptr, 10);
|
||||
m_safereturn.x = strtof(row[12], nullptr);
|
||||
m_safereturn.y = strtof(row[13], nullptr);
|
||||
m_safereturn.z = strtof(row[14], nullptr);
|
||||
m_safereturn.heading = strtof(row[15], nullptr);
|
||||
m_zonein.x = strtof(row[16], nullptr);
|
||||
m_zonein.y = strtof(row[17], nullptr);
|
||||
m_zonein.z = strtof(row[18], nullptr);
|
||||
m_zonein.heading = strtof(row[19], nullptr);
|
||||
m_has_zonein = (strtoul(row[20], nullptr, 10) != 0);
|
||||
}
|
||||
|
||||
void DynamicZone::LoadFromDatabase(uint32_t instance_id)
|
||||
{
|
||||
if (instance_id == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogDynamicZonesDetail("Loading dz instance [{}] from database", instance_id);
|
||||
|
||||
std::string query = fmt::format(SQL(
|
||||
{} WHERE dynamic_zones.instance_id = {};
|
||||
), DynamicZoneSelectQuery(), instance_id);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (results.Success() && results.RowCount() > 0)
|
||||
{
|
||||
auto row = results.begin();
|
||||
LoadDatabaseResult(row);
|
||||
}
|
||||
m_id = strtoul(row[6], nullptr, 10);
|
||||
m_type = static_cast<DynamicZoneType>(strtoul(row[7], nullptr, 10));
|
||||
m_compass.zone_id = strtoul(row[8], nullptr, 10);
|
||||
m_compass.x = strtof(row[9], nullptr);
|
||||
m_compass.y = strtof(row[10], nullptr);
|
||||
m_compass.z = strtof(row[11], nullptr);
|
||||
m_safereturn.zone_id = strtoul(row[12], nullptr, 10);
|
||||
m_safereturn.x = strtof(row[13], nullptr);
|
||||
m_safereturn.y = strtof(row[14], nullptr);
|
||||
m_safereturn.z = strtof(row[15], nullptr);
|
||||
m_safereturn.heading = strtof(row[16], nullptr);
|
||||
m_zonein.x = strtof(row[17], nullptr);
|
||||
m_zonein.y = strtof(row[18], nullptr);
|
||||
m_zonein.z = strtof(row[19], nullptr);
|
||||
m_zonein.heading = strtof(row[20], nullptr);
|
||||
m_has_zonein = (strtoul(row[21], nullptr, 10) != 0);
|
||||
}
|
||||
|
||||
uint32_t DynamicZone::SaveToDatabase()
|
||||
@ -363,21 +351,6 @@ void DynamicZone::SaveZoneInLocationToDatabase()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DynamicZone::DeleteFromDatabase()
|
||||
{
|
||||
LogDynamicZonesDetail("Deleting dz instance [{}] from database", m_instance_id);
|
||||
|
||||
if (m_instance_id != 0)
|
||||
{
|
||||
std::string query = fmt::format(SQL(
|
||||
DELETE FROM dynamic_zones WHERE instance_id = {};
|
||||
), m_instance_id);
|
||||
|
||||
database.QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicZone::AddCharacter(uint32_t character_id)
|
||||
{
|
||||
database.AddClientToInstance(m_instance_id, character_id);
|
||||
|
||||
@ -59,37 +59,36 @@ public:
|
||||
DynamicZone() = default;
|
||||
DynamicZone(uint32_t zone_id, uint32_t version, uint32_t duration, DynamicZoneType type);
|
||||
DynamicZone(std::string zone_shortname, uint32_t version, uint32_t duration, DynamicZoneType type);
|
||||
DynamicZone(uint32_t instance_id) : m_instance_id(instance_id) {}
|
||||
DynamicZone(uint32_t dz_id) : m_id(dz_id) {}
|
||||
DynamicZone(DynamicZoneType type) : m_type(type) {}
|
||||
|
||||
static DynamicZone LoadDzFromDatabase(uint32_t instance_id);
|
||||
static std::unordered_map<uint32_t, DynamicZone> LoadMultipleDzFromDatabase(
|
||||
const std::vector<uint32_t>& instance_ids);
|
||||
const std::vector<uint32_t>& dynamic_zone_ids);
|
||||
static void HandleWorldMessage(ServerPacket* pack);
|
||||
|
||||
uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); }
|
||||
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_id); };
|
||||
uint32_t GetID() const { return m_id; }
|
||||
uint16_t GetInstanceID() const { return static_cast<uint16_t>(m_instance_id); }
|
||||
uint32_t GetSecondsRemaining() const;
|
||||
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); };
|
||||
uint16_t GetZoneID() const { return static_cast<uint16_t>(m_zone_id); }
|
||||
uint32_t GetZoneIndex() const { return (m_instance_id << 16) | (m_zone_id & 0xffff); }
|
||||
uint32_t GetZoneVersion() const { return m_version; };
|
||||
uint32_t GetZoneVersion() const { return m_version; }
|
||||
DynamicZoneType GetType() const { return m_type; }
|
||||
DynamicZoneLocation GetCompassLocation() const { return m_compass; }
|
||||
DynamicZoneLocation GetSafeReturnLocation() const { return m_safereturn; }
|
||||
DynamicZoneLocation GetZoneInLocation() const { return m_zonein; }
|
||||
|
||||
void AddCharacter(uint32_t character_id);
|
||||
uint32_t Create();
|
||||
uint32_t CreateInstance();
|
||||
bool HasZoneInLocation() const { return m_has_zonein; }
|
||||
bool IsCurrentZoneDzInstance() const;
|
||||
bool IsInstanceID(uint32_t instance_id) const;
|
||||
bool IsValid() const { return m_instance_id != 0; }
|
||||
bool IsSameDz(uint32_t zone_id, uint32_t instance_id) const;
|
||||
void LoadFromDatabase(uint32_t instance_id);
|
||||
void RemoveAllCharacters(bool enable_removal_timers = true);
|
||||
void RemoveCharacter(uint32_t character_id);
|
||||
void SaveInstanceMembersToDatabase(const std::vector<uint32_t>& character_ids);
|
||||
uint32_t SaveToDatabase();
|
||||
void SendInstanceCharacterChange(uint32_t character_id, bool removed);
|
||||
void SetCompass(const DynamicZoneLocation& location, bool update_db = false);
|
||||
void SetSafeReturn(const DynamicZoneLocation& location, bool update_db = false);
|
||||
@ -99,11 +98,12 @@ public:
|
||||
private:
|
||||
static std::string DynamicZoneSelectQuery();
|
||||
void LoadDatabaseResult(MySQLRequestRow& row);
|
||||
void DeleteFromDatabase();
|
||||
void SaveCompassToDatabase();
|
||||
void SaveSafeReturnToDatabase();
|
||||
void SaveZoneInLocationToDatabase();
|
||||
uint32_t SaveToDatabase();
|
||||
|
||||
uint32_t m_id = 0;
|
||||
uint32_t m_zone_id = 0;
|
||||
uint32_t m_instance_id = 0;
|
||||
uint32_t m_version = 0;
|
||||
|
||||
@ -6101,6 +6101,25 @@ XS(XS__get_expedition_by_char_id) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__get_expedition_by_dz_id);
|
||||
XS(XS__get_expedition_by_dz_id) {
|
||||
dXSARGS;
|
||||
if (items != 1) {
|
||||
Perl_croak(aTHX_ "Usage: quest::get_expedition_by_dz_id(uint32 dynamic_zone_id)");
|
||||
}
|
||||
|
||||
uint32 dz_id = (int)SvUV(ST(0));
|
||||
|
||||
Expedition* RETVAL = Expedition::FindCachedExpeditionByDynamicZoneID(dz_id);
|
||||
|
||||
ST(0) = sv_newmortal();
|
||||
if (RETVAL) {
|
||||
sv_setref_pv(ST(0), "Expedition", (void*)RETVAL);
|
||||
}
|
||||
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS__get_expedition_by_zone_instance);
|
||||
XS(XS__get_expedition_by_zone_instance) {
|
||||
dXSARGS;
|
||||
@ -6507,6 +6526,7 @@ EXTERN_C XS(boot_quest) {
|
||||
newXS(strcpy(buf, "getcurrencyid"), XS__getcurrencyid, file);
|
||||
newXS(strcpy(buf, "get_expedition"), XS__get_expedition, file);
|
||||
newXS(strcpy(buf, "get_expedition_by_char_id"), XS__get_expedition_by_char_id, file);
|
||||
newXS(strcpy(buf, "get_expedition_by_dz_id"), XS__get_expedition_by_dz_id, file);
|
||||
newXS(strcpy(buf, "get_expedition_by_zone_instance"), XS__get_expedition_by_zone_instance, file);
|
||||
newXS(strcpy(buf, "get_expedition_lockout_by_char_id"), XS__get_expedition_lockout_by_char_id, file);
|
||||
newXS(strcpy(buf, "get_expedition_lockouts_by_char_id"), XS__get_expedition_lockouts_by_char_id, file);
|
||||
|
||||
@ -78,12 +78,8 @@ Expedition* Expedition::TryCreate(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (dynamiczone.GetInstanceID() == 0)
|
||||
{
|
||||
dynamiczone.CreateInstance();
|
||||
}
|
||||
|
||||
if (dynamiczone.GetInstanceID() == 0)
|
||||
auto dynamic_zone_id = dynamiczone.Create();
|
||||
if (dynamic_zone_id == 0)
|
||||
{
|
||||
// live uses this message when trying to enter an instance that isn't ready
|
||||
// we can use it as the client error message if instance creation fails
|
||||
@ -97,7 +93,7 @@ Expedition* Expedition::TryCreate(
|
||||
// unique expedition ids are created from database via auto-increment column
|
||||
auto expedition_id = ExpeditionDatabase::InsertExpedition(
|
||||
expedition_uuid,
|
||||
dynamiczone.GetInstanceID(),
|
||||
dynamiczone.GetID(),
|
||||
request.GetExpeditionName(),
|
||||
request.GetLeaderID(),
|
||||
request.GetMinPlayers(),
|
||||
@ -106,8 +102,6 @@ Expedition* Expedition::TryCreate(
|
||||
|
||||
if (expedition_id)
|
||||
{
|
||||
dynamiczone.SaveToDatabase();
|
||||
|
||||
auto expedition = std::unique_ptr<Expedition>(new Expedition(
|
||||
expedition_id,
|
||||
expedition_uuid,
|
||||
@ -158,7 +152,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results)
|
||||
}
|
||||
|
||||
std::vector<uint32_t> expedition_ids;
|
||||
std::vector<uint32_t> instance_ids;
|
||||
std::vector<uint32_t> dynamic_zone_ids;;
|
||||
std::vector<std::pair<uint32_t, uint32_t>> expedition_character_ids;
|
||||
|
||||
using col = LoadExpeditionColumns::eLoadExpeditionColumns;
|
||||
@ -174,16 +168,14 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results)
|
||||
expedition_ids.emplace_back(expedition_id);
|
||||
|
||||
uint32_t leader_id = strtoul(row[col::leader_id], nullptr, 10);
|
||||
uint32_t instance_id = row[col::instance_id] ? strtoul(row[col::instance_id], nullptr, 10) : 0;
|
||||
if (instance_id) // can be null from fk constraint
|
||||
{
|
||||
instance_ids.emplace_back(instance_id);
|
||||
}
|
||||
uint32_t dynamic_zone_id = strtoul(row[col::dz_id], nullptr, 10);
|
||||
|
||||
dynamic_zone_ids.emplace_back(dynamic_zone_id);
|
||||
|
||||
std::unique_ptr<Expedition> expedition = std::unique_ptr<Expedition>(new Expedition(
|
||||
expedition_id,
|
||||
row[col::uuid], // expedition uuid
|
||||
DynamicZone{ instance_id },
|
||||
DynamicZone{ dynamic_zone_id },
|
||||
row[col::expedition_name], // expedition name
|
||||
ExpeditionMember{ leader_id, row[col::leader_name] }, // expedition leader id, name
|
||||
strtoul(row[col::min_players], nullptr, 10), // min_players
|
||||
@ -216,7 +208,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results)
|
||||
Expedition::SendWorldGetOnlineMembers(expedition_character_ids);
|
||||
|
||||
// bulk load dynamic zone data and expedition lockouts for cached expeditions
|
||||
auto dynamic_zones = DynamicZone::LoadMultipleDzFromDatabase(instance_ids);
|
||||
auto dynamic_zones = DynamicZone::LoadMultipleDzFromDatabase(dynamic_zone_ids);
|
||||
auto expedition_lockouts = ExpeditionDatabase::LoadMultipleExpeditionLockouts(expedition_ids);
|
||||
|
||||
for (const auto& expedition_id : expedition_ids)
|
||||
@ -224,7 +216,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results)
|
||||
auto expedition = Expedition::FindCachedExpeditionByID(expedition_id);
|
||||
if (expedition)
|
||||
{
|
||||
auto dz_iter = dynamic_zones.find(expedition->GetInstanceID());
|
||||
auto dz_iter = dynamic_zones.find(expedition->GetDynamicZoneID());
|
||||
if (dz_iter != dynamic_zones.end())
|
||||
{
|
||||
expedition->m_dynamiczone = dz_iter->second;
|
||||
@ -236,7 +228,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results)
|
||||
expedition->m_lockouts = lockout_iter->second;
|
||||
}
|
||||
|
||||
// send member updates now that all data is loaded for the cached expedition(s)
|
||||
// send member updates now that all data is loaded for the cached expedition
|
||||
expedition->SendUpdatesToZoneMembers();
|
||||
}
|
||||
}
|
||||
@ -340,6 +332,21 @@ Expedition* Expedition::FindCachedExpeditionByCharacterName(const std::string& c
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Expedition* Expedition::FindCachedExpeditionByDynamicZoneID(uint32_t dz_id)
|
||||
{
|
||||
if (zone && dz_id != 0)
|
||||
{
|
||||
for (const auto& cached_expedition : zone->expedition_cache)
|
||||
{
|
||||
if (cached_expedition.second->GetDynamicZone().GetID() == dz_id)
|
||||
{
|
||||
return cached_expedition.second.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Expedition* Expedition::FindCachedExpeditionByID(uint32_t expedition_id)
|
||||
{
|
||||
if (zone && expedition_id)
|
||||
|
||||
@ -74,8 +74,7 @@ class Expedition
|
||||
{
|
||||
public:
|
||||
Expedition() = delete;
|
||||
Expedition(
|
||||
uint32_t id, const std::string& uuid, const DynamicZone& dz, const std::string& expedition_name,
|
||||
Expedition(uint32_t id, const std::string& uuid, const DynamicZone& dz, const std::string& expedition_name,
|
||||
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players);
|
||||
|
||||
static Expedition* TryCreate(Client* requester, DynamicZone& dynamiczone, ExpeditionRequest& request);
|
||||
@ -84,6 +83,7 @@ public:
|
||||
static bool CacheAllFromDatabase();
|
||||
static Expedition* FindCachedExpeditionByCharacterID(uint32_t character_id);
|
||||
static Expedition* FindCachedExpeditionByCharacterName(const std::string& char_name);
|
||||
static Expedition* FindCachedExpeditionByDynamicZoneID(uint32_t dz_id);
|
||||
static Expedition* FindCachedExpeditionByID(uint32_t expedition_id);
|
||||
static Expedition* FindCachedExpeditionByZoneInstance(uint32_t zone_id, uint32_t instance_id);
|
||||
static std::vector<ExpeditionLockoutTimer> GetExpeditionLockoutsByCharacterID(uint32_t character_id);
|
||||
@ -102,6 +102,7 @@ public:
|
||||
const std::string& expedition_name = {}, const std::string& event_name = {});
|
||||
static void AddLockoutClients(const ExpeditionLockoutTimer& lockout, uint32_t exclude_id = 0);
|
||||
|
||||
uint32_t GetDynamicZoneID() const { return m_dynamiczone.GetID(); }
|
||||
uint32_t GetID() const { return m_id; }
|
||||
uint16_t GetInstanceID() const { return m_dynamiczone.GetInstanceID(); }
|
||||
uint32_t GetLeaderID() const { return m_leader.char_id; }
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
#include <fmt/core.h>
|
||||
|
||||
uint32_t ExpeditionDatabase::InsertExpedition(
|
||||
const std::string& uuid, uint32_t instance_id, const std::string& expedition_name,
|
||||
const std::string& uuid, uint32_t dz_id, const std::string& expedition_name,
|
||||
uint32_t leader_id, uint32_t min_players, uint32_t max_players)
|
||||
{
|
||||
LogExpeditionsDetail(
|
||||
@ -36,10 +36,10 @@ uint32_t ExpeditionDatabase::InsertExpedition(
|
||||
|
||||
std::string query = fmt::format(SQL(
|
||||
INSERT INTO expeditions
|
||||
(uuid, instance_id, expedition_name, leader_id, min_players, max_players)
|
||||
(uuid, dynamic_zone_id, expedition_name, leader_id, min_players, max_players)
|
||||
VALUES
|
||||
('{}', {}, '{}', {}, {}, {});
|
||||
), uuid, instance_id, EscapeString(expedition_name), leader_id, min_players, max_players);
|
||||
), uuid, dz_id, EscapeString(expedition_name), leader_id, min_players, max_players);
|
||||
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
@ -57,7 +57,7 @@ std::string ExpeditionDatabase::LoadExpeditionsSelectQuery()
|
||||
SELECT
|
||||
expeditions.id,
|
||||
expeditions.uuid,
|
||||
expeditions.instance_id,
|
||||
expeditions.dynamic_zone_id,
|
||||
expeditions.expedition_name,
|
||||
expeditions.leader_id,
|
||||
expeditions.min_players,
|
||||
|
||||
@ -84,7 +84,7 @@ namespace LoadExpeditionColumns
|
||||
{
|
||||
id = 0,
|
||||
uuid,
|
||||
instance_id,
|
||||
dz_id,
|
||||
expedition_name,
|
||||
leader_id,
|
||||
min_players,
|
||||
|
||||
@ -57,6 +57,11 @@ void Lua_Expedition::AddReplayLockoutDuration(int seconds, bool members_only) {
|
||||
self->AddReplayLockoutDuration(seconds, members_only);
|
||||
}
|
||||
|
||||
uint32_t Lua_Expedition::GetDynamicZoneID() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetDynamicZoneID();
|
||||
}
|
||||
|
||||
uint32_t Lua_Expedition::GetID() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetID();
|
||||
@ -248,6 +253,7 @@ luabind::scope lua_register_expedition() {
|
||||
.def("AddReplayLockout", (void(Lua_Expedition::*)(uint32_t))&Lua_Expedition::AddReplayLockout)
|
||||
.def("AddReplayLockoutDuration", (void(Lua_Expedition::*)(int))&Lua_Expedition::AddReplayLockoutDuration)
|
||||
.def("AddReplayLockoutDuration", (void(Lua_Expedition::*)(int, bool))&Lua_Expedition::AddReplayLockoutDuration)
|
||||
.def("GetDynamicZoneID", &Lua_Expedition::GetDynamicZoneID)
|
||||
.def("GetID", (uint32_t(Lua_Expedition::*)(void))&Lua_Expedition::GetID)
|
||||
.def("GetInstanceID", (int(Lua_Expedition::*)(void))&Lua_Expedition::GetInstanceID)
|
||||
.def("GetLeaderName", (std::string(Lua_Expedition::*)(void))&Lua_Expedition::GetLeaderName)
|
||||
|
||||
@ -59,6 +59,7 @@ public:
|
||||
void AddReplayLockout(uint32_t seconds);
|
||||
void AddReplayLockoutDuration(int seconds);
|
||||
void AddReplayLockoutDuration(int seconds, bool members_only);
|
||||
uint32_t GetDynamicZoneID();
|
||||
uint32_t GetID();
|
||||
int GetInstanceID();
|
||||
std::string GetLeaderName();
|
||||
|
||||
@ -2192,6 +2192,10 @@ Lua_Expedition lua_get_expedition_by_char_id(uint32 char_id) {
|
||||
return Expedition::FindCachedExpeditionByCharacterID(char_id);
|
||||
}
|
||||
|
||||
Lua_Expedition lua_get_expedition_by_dz_id(uint32 dz_id) {
|
||||
return Expedition::FindCachedExpeditionByDynamicZoneID(dz_id);
|
||||
}
|
||||
|
||||
Lua_Expedition lua_get_expedition_by_zone_instance(uint32 zone_id, uint32 instance_id) {
|
||||
return Expedition::FindCachedExpeditionByZoneInstance(zone_id, instance_id);
|
||||
}
|
||||
@ -2889,6 +2893,7 @@ luabind::scope lua_register_general() {
|
||||
|
||||
luabind::def("get_expedition", &lua_get_expedition),
|
||||
luabind::def("get_expedition_by_char_id", &lua_get_expedition_by_char_id),
|
||||
luabind::def("get_expedition_by_dz_id", &lua_get_expedition_by_dz_id),
|
||||
luabind::def("get_expedition_by_zone_instance", &lua_get_expedition_by_zone_instance),
|
||||
luabind::def("get_expedition_lockout_by_char_id", &lua_get_expedition_lockout_by_char_id),
|
||||
luabind::def("get_expedition_lockouts_by_char_id", (luabind::object(*)(lua_State*, uint32))&lua_get_expedition_lockouts_by_char_id),
|
||||
|
||||
@ -132,6 +132,19 @@ XS(XS_Expedition_AddReplayLockoutDuration) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Expedition_GetDynamicZoneID);
|
||||
XS(XS_Expedition_GetDynamicZoneID) {
|
||||
dXSARGS;
|
||||
if (items != 1) {
|
||||
Perl_croak(aTHX_ "Usage: Expedition::GetDynamicZoneID(THIS)");
|
||||
}
|
||||
|
||||
Expedition* THIS = nullptr;
|
||||
VALIDATE_THIS_IS_EXPEDITION;
|
||||
|
||||
XSRETURN_UV(THIS->GetDynamicZoneID());
|
||||
}
|
||||
|
||||
XS(XS_Expedition_GetID);
|
||||
XS(XS_Expedition_GetID) {
|
||||
dXSARGS;
|
||||
@ -623,6 +636,7 @@ XS(boot_Expedition) {
|
||||
newXSproto(strcpy(buf, "AddLockoutDuration"), XS_Expedition_AddLockoutDuration, file, "$$$;$");
|
||||
newXSproto(strcpy(buf, "AddReplayLockout"), XS_Expedition_AddReplayLockout, file, "$$");
|
||||
newXSproto(strcpy(buf, "AddReplayLockoutDuration"), XS_Expedition_AddReplayLockoutDuration, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "GetDynamicZoneID"), XS_Expedition_GetDynamicZoneID, file, "$");
|
||||
newXSproto(strcpy(buf, "GetID"), XS_Expedition_GetID, file, "$");
|
||||
newXSproto(strcpy(buf, "GetInstanceID"), XS_Expedition_GetInstanceID, file, "$");
|
||||
newXSproto(strcpy(buf, "GetLeaderName"), XS_Expedition_GetLeaderName, file, "$");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user