mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 17:51:28 +00:00
[Expeditions] Refactor expedition caching (#1315)
Add common expedition base class Use repository for zone and world expedition caching World now stores members and leader as Member objects instead of ids This improves readability of the caching methods and lets world cache expedition dzs and members like zone. World also now caches expeditions as unique_ptr which will be necessary for future dz callback lambdas that capture 'this' so addresses don't change on cache vector resizes.
This commit is contained in:
parent
0534a2c6be
commit
dadc1b2843
@ -32,6 +32,7 @@ SET(common_sources
|
|||||||
eq_stream_proxy.cpp
|
eq_stream_proxy.cpp
|
||||||
eqtime.cpp
|
eqtime.cpp
|
||||||
event_sub.cpp
|
event_sub.cpp
|
||||||
|
expedition_base.cpp
|
||||||
expedition_lockout_timer.cpp
|
expedition_lockout_timer.cpp
|
||||||
extprofile.cpp
|
extprofile.cpp
|
||||||
faction.cpp
|
faction.cpp
|
||||||
@ -495,6 +496,7 @@ SET(common_headers
|
|||||||
eqtime.h
|
eqtime.h
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_sub.h
|
event_sub.h
|
||||||
|
expedition_base.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
extprofile.h
|
extprofile.h
|
||||||
faction.h
|
faction.h
|
||||||
|
|||||||
@ -474,4 +474,13 @@ enum class DynamicZoneType
|
|||||||
Quest
|
Quest
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ExpeditionMemberStatus : uint8_t
|
||||||
|
{
|
||||||
|
Unknown = 0,
|
||||||
|
Online,
|
||||||
|
Offline,
|
||||||
|
InDynamicZone,
|
||||||
|
LinkDead
|
||||||
|
};
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
93
common/expedition_base.cpp
Normal file
93
common/expedition_base.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "expedition_base.h"
|
||||||
|
#include "repositories/expeditions_repository.h"
|
||||||
|
|
||||||
|
ExpeditionBase::ExpeditionBase(uint32_t id, const std::string& uuid,
|
||||||
|
const std::string& expedition_name, const ExpeditionMember& leader,
|
||||||
|
uint32_t min_players, uint32_t max_players
|
||||||
|
) :
|
||||||
|
m_id(id),
|
||||||
|
m_uuid(uuid),
|
||||||
|
m_expedition_name(expedition_name),
|
||||||
|
m_leader(leader),
|
||||||
|
m_min_players(min_players),
|
||||||
|
m_max_players(max_players)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpeditionBase::LoadRepositoryResult(ExpeditionsRepository::ExpeditionWithLeader&& entry)
|
||||||
|
{
|
||||||
|
m_id = entry.id;
|
||||||
|
m_uuid = std::move(entry.uuid);
|
||||||
|
m_expedition_name = std::move(entry.expedition_name);
|
||||||
|
m_min_players = entry.min_players;
|
||||||
|
m_max_players = entry.max_players;
|
||||||
|
m_add_replay_on_join = entry.add_replay_on_join;
|
||||||
|
m_is_locked = entry.is_locked;
|
||||||
|
m_leader.char_id = entry.leader_id;
|
||||||
|
m_leader.name = std::move(entry.leader_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpeditionBase::AddMemberFromRepositoryResult(
|
||||||
|
ExpeditionMembersRepository::MemberWithName&& entry)
|
||||||
|
{
|
||||||
|
auto status = ExpeditionMemberStatus::Unknown;
|
||||||
|
AddInternalMember({ entry.character_id, std::move(entry.character_name), status });
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpeditionBase::AddInternalMember(const ExpeditionMember& member)
|
||||||
|
{
|
||||||
|
if (!HasMember(member.char_id))
|
||||||
|
{
|
||||||
|
m_members.emplace_back(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpeditionBase::RemoveInternalMember(uint32_t character_id)
|
||||||
|
{
|
||||||
|
m_members.erase(std::remove_if(m_members.begin(), m_members.end(),
|
||||||
|
[&](const ExpeditionMember& member) { return member.char_id == character_id; }
|
||||||
|
), m_members.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ExpeditionBase::HasMember(uint32_t character_id)
|
||||||
|
{
|
||||||
|
return std::any_of(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
||||||
|
return member.char_id == character_id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExpeditionBase::HasMember(const std::string& character_name)
|
||||||
|
{
|
||||||
|
return std::any_of(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
||||||
|
return (strcasecmp(member.name.c_str(), character_name.c_str()) == 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpeditionMember ExpeditionBase::GetMemberData(uint32_t character_id)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
||||||
|
return member.char_id == character_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
ExpeditionMember member_data;
|
||||||
|
if (it != m_members.end())
|
||||||
|
{
|
||||||
|
member_data = *it;
|
||||||
|
}
|
||||||
|
return member_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpeditionMember ExpeditionBase::GetMemberData(const std::string& character_name)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
||||||
|
return (strcasecmp(member.name.c_str(), character_name.c_str()) == 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
ExpeditionMember member_data;
|
||||||
|
if (it != m_members.end())
|
||||||
|
{
|
||||||
|
member_data = *it;
|
||||||
|
}
|
||||||
|
return member_data;
|
||||||
|
}
|
||||||
74
common/expedition_base.h
Normal file
74
common/expedition_base.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifndef COMMON_EXPEDITION_BASE_H
|
||||||
|
#define COMMON_EXPEDITION_BASE_H
|
||||||
|
|
||||||
|
#include "eq_constants.h"
|
||||||
|
#include "repositories/expeditions_repository.h"
|
||||||
|
#include "repositories/expedition_members_repository.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct ExpeditionMember
|
||||||
|
{
|
||||||
|
uint32_t char_id = 0;
|
||||||
|
std::string name;
|
||||||
|
ExpeditionMemberStatus status = ExpeditionMemberStatus::Online;
|
||||||
|
|
||||||
|
ExpeditionMember() = default;
|
||||||
|
ExpeditionMember(uint32_t id, const std::string& name_)
|
||||||
|
: char_id(id), name(name_) {}
|
||||||
|
ExpeditionMember(uint32_t id, const std::string& name_, ExpeditionMemberStatus status_)
|
||||||
|
: char_id(id), name(name_), status(status_) {}
|
||||||
|
|
||||||
|
bool IsValid() const { return char_id != 0 && !name.empty(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ExpeditionBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ExpeditionBase() = default;
|
||||||
|
ExpeditionBase(const ExpeditionBase&) = default;
|
||||||
|
ExpeditionBase(ExpeditionBase&&) = default;
|
||||||
|
ExpeditionBase& operator=(const ExpeditionBase&) = default;
|
||||||
|
ExpeditionBase& operator=(ExpeditionBase&&) = default;
|
||||||
|
|
||||||
|
uint32_t GetID() const { return m_id; }
|
||||||
|
uint32_t GetLeaderID() const { return m_leader.char_id; }
|
||||||
|
uint32_t GetMinPlayers() const { return m_min_players; }
|
||||||
|
uint32_t GetMaxPlayers() const { return m_max_players; }
|
||||||
|
uint32_t GetMemberCount() const { return static_cast<uint32_t>(m_members.size()); }
|
||||||
|
const std::string& GetName() const { return m_expedition_name; }
|
||||||
|
const std::string& GetLeaderName() const { return m_leader.name; }
|
||||||
|
const std::string& GetUUID() const { return m_uuid; }
|
||||||
|
const std::vector<ExpeditionMember>& GetMembers() const { return m_members; }
|
||||||
|
|
||||||
|
void AddInternalMember(const ExpeditionMember& member);
|
||||||
|
void ClearInternalMembers() { m_members.clear(); }
|
||||||
|
bool HasMember(const std::string& character_name);
|
||||||
|
bool HasMember(uint32_t character_id);
|
||||||
|
bool IsEmpty() const { return m_members.empty(); }
|
||||||
|
void RemoveInternalMember(uint32_t character_id);
|
||||||
|
|
||||||
|
void LoadRepositoryResult(ExpeditionsRepository::ExpeditionWithLeader&& entry);
|
||||||
|
void AddMemberFromRepositoryResult(ExpeditionMembersRepository::MemberWithName&& entry);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ExpeditionBase() = default;
|
||||||
|
ExpeditionBase(uint32_t id, const std::string& uuid, const std::string& expedition_name,
|
||||||
|
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players);
|
||||||
|
|
||||||
|
ExpeditionMember GetMemberData(uint32_t character_id);
|
||||||
|
ExpeditionMember GetMemberData(const std::string& character_name);
|
||||||
|
|
||||||
|
uint32_t m_id = 0;
|
||||||
|
uint32_t m_min_players = 0;
|
||||||
|
uint32_t m_max_players = 0;
|
||||||
|
bool m_is_locked = false;
|
||||||
|
bool m_add_replay_on_join = true;
|
||||||
|
std::string m_uuid;
|
||||||
|
std::string m_expedition_name;
|
||||||
|
ExpeditionMember m_leader;
|
||||||
|
std::vector<ExpeditionMember> m_members;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -78,7 +78,7 @@ public:
|
|||||||
entry.id = 0;
|
entry.id = 0;
|
||||||
entry.expedition_id = 0;
|
entry.expedition_id = 0;
|
||||||
entry.event_name = "";
|
entry.event_name = "";
|
||||||
entry.expire_time = current_timestamp();
|
entry.expire_time = "";
|
||||||
entry.duration = 0;
|
entry.duration = 0;
|
||||||
entry.from_expedition_uuid = "";
|
entry.from_expedition_uuid = "";
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,58 @@ public:
|
|||||||
|
|
||||||
// Custom extended repository methods here
|
// Custom extended repository methods here
|
||||||
|
|
||||||
|
struct ExpeditionLockoutsWithTimestamp {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t expedition_id;
|
||||||
|
std::string event_name;
|
||||||
|
time_t expire_time;
|
||||||
|
int duration;
|
||||||
|
std::string from_expedition_uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<ExpeditionLockoutsWithTimestamp> GetWithTimestamp(
|
||||||
|
Database& db, const std::vector<uint32_t>& expedition_ids)
|
||||||
|
{
|
||||||
|
if (expedition_ids.empty())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ExpeditionLockoutsWithTimestamp> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(fmt::format(SQL(
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
expedition_id,
|
||||||
|
event_name,
|
||||||
|
UNIX_TIMESTAMP(expire_time),
|
||||||
|
duration,
|
||||||
|
from_expedition_uuid
|
||||||
|
FROM expedition_lockouts
|
||||||
|
WHERE expedition_id IN ({})
|
||||||
|
),
|
||||||
|
fmt::join(expedition_ids, ",")
|
||||||
|
));
|
||||||
|
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
{
|
||||||
|
ExpeditionLockoutsWithTimestamp entry{};
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
|
entry.id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.expedition_id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.event_name = row[col++];
|
||||||
|
entry.expire_time = strtoull(row[col++], nullptr, 10);
|
||||||
|
entry.duration = strtol(row[col++], nullptr, 10);
|
||||||
|
entry.from_expedition_uuid = row[col++];
|
||||||
|
|
||||||
|
all_entries.emplace_back(std::move(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_EXPEDITION_LOCKOUTS_REPOSITORY_H
|
#endif //EQEMU_EXPEDITION_LOCKOUTS_REPOSITORY_H
|
||||||
|
|||||||
@ -65,6 +65,68 @@ public:
|
|||||||
|
|
||||||
// Custom extended repository methods here
|
// Custom extended repository methods here
|
||||||
|
|
||||||
|
struct MemberWithName {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t expedition_id;
|
||||||
|
uint32_t character_id;
|
||||||
|
int is_current_member;
|
||||||
|
std::string character_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string SelectMembersWithNames()
|
||||||
|
{
|
||||||
|
return std::string(SQL(
|
||||||
|
SELECT
|
||||||
|
expedition_members.id,
|
||||||
|
expedition_members.expedition_id,
|
||||||
|
expedition_members.character_id,
|
||||||
|
expedition_members.is_current_member,
|
||||||
|
character_data.name
|
||||||
|
FROM expedition_members
|
||||||
|
INNER JOIN character_data ON expedition_members.character_id = character_data.id
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<MemberWithName> GetWithNames(Database& db,
|
||||||
|
const std::vector<uint32_t>& expedition_ids)
|
||||||
|
{
|
||||||
|
if (expedition_ids.empty())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<MemberWithName> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(fmt::format(SQL(
|
||||||
|
{}
|
||||||
|
WHERE expedition_members.expedition_id IN ({})
|
||||||
|
AND expedition_members.is_current_member = TRUE;
|
||||||
|
),
|
||||||
|
SelectMembersWithNames(),
|
||||||
|
fmt::join(expedition_ids, ",")
|
||||||
|
));
|
||||||
|
|
||||||
|
if (results.Success())
|
||||||
|
{
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
{
|
||||||
|
MemberWithName entry{};
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
|
entry.id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.expedition_id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.character_id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.is_current_member = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.character_name = row[col++];
|
||||||
|
|
||||||
|
all_entries.emplace_back(std::move(entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_EXPEDITION_MEMBERS_REPOSITORY_H
|
#endif //EQEMU_EXPEDITION_MEMBERS_REPOSITORY_H
|
||||||
|
|||||||
@ -65,6 +65,100 @@ public:
|
|||||||
|
|
||||||
// Custom extended repository methods here
|
// Custom extended repository methods here
|
||||||
|
|
||||||
|
struct ExpeditionWithLeader
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
std::string uuid;
|
||||||
|
uint32_t dynamic_zone_id;
|
||||||
|
std::string expedition_name;
|
||||||
|
uint32_t min_players;
|
||||||
|
uint32_t max_players;
|
||||||
|
int add_replay_on_join;
|
||||||
|
int is_locked;
|
||||||
|
uint32_t leader_id;
|
||||||
|
std::string leader_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string SelectExpeditionsJoinLeader()
|
||||||
|
{
|
||||||
|
return std::string(SQL(
|
||||||
|
SELECT
|
||||||
|
expeditions.id,
|
||||||
|
expeditions.uuid,
|
||||||
|
expeditions.dynamic_zone_id,
|
||||||
|
expeditions.expedition_name,
|
||||||
|
expeditions.min_players,
|
||||||
|
expeditions.max_players,
|
||||||
|
expeditions.add_replay_on_join,
|
||||||
|
expeditions.is_locked,
|
||||||
|
expeditions.leader_id,
|
||||||
|
character_data.name leader_name
|
||||||
|
FROM expeditions
|
||||||
|
INNER JOIN character_data ON expeditions.leader_id = character_data.id
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
static ExpeditionWithLeader FillExpeditionWithLeaderFromRow(MySQLRequestRow& row)
|
||||||
|
{
|
||||||
|
ExpeditionWithLeader entry{};
|
||||||
|
|
||||||
|
int col = 0;
|
||||||
|
entry.id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.uuid = row[col++];
|
||||||
|
entry.dynamic_zone_id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.expedition_name = row[col++];
|
||||||
|
entry.min_players = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.max_players = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.add_replay_on_join = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.is_locked = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.leader_id = strtoul(row[col++], nullptr, 10);
|
||||||
|
entry.leader_name = row[col++];
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<ExpeditionWithLeader> GetAllWithLeaderName(Database& db)
|
||||||
|
{
|
||||||
|
std::vector<ExpeditionWithLeader> all_entries;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(fmt::format(
|
||||||
|
"{} ORDER BY expeditions.id;",
|
||||||
|
SelectExpeditionsJoinLeader()
|
||||||
|
));
|
||||||
|
|
||||||
|
if (results.Success())
|
||||||
|
{
|
||||||
|
all_entries.reserve(results.RowCount());
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
{
|
||||||
|
ExpeditionWithLeader entry = FillExpeditionWithLeaderFromRow(row);
|
||||||
|
all_entries.emplace_back(std::move(entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return all_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ExpeditionWithLeader GetWithLeaderName(Database& db, uint32_t expedition_id)
|
||||||
|
{
|
||||||
|
ExpeditionWithLeader entry{};
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(fmt::format(
|
||||||
|
"{} WHERE expeditions.id = {};",
|
||||||
|
SelectExpeditionsJoinLeader(),
|
||||||
|
expedition_id
|
||||||
|
));
|
||||||
|
|
||||||
|
if (results.Success() && results.RowCount() > 0)
|
||||||
|
{
|
||||||
|
auto row = results.begin();
|
||||||
|
entry = FillExpeditionWithLeaderFromRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
struct CharacterExpedition
|
struct CharacterExpedition
|
||||||
{
|
{
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|||||||
@ -9,21 +9,6 @@
|
|||||||
|
|
||||||
extern ZSList zoneserver_list;
|
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 = std::chrono::seconds(duration);
|
|
||||||
m_type = type;
|
|
||||||
m_expire_time = m_start_time + m_duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
Database& DynamicZone::GetDatabase()
|
Database& DynamicZone::GetDatabase()
|
||||||
{
|
{
|
||||||
return database;
|
return database;
|
||||||
|
|||||||
@ -19,10 +19,6 @@ class DynamicZone : public DynamicZoneBase
|
|||||||
public:
|
public:
|
||||||
using DynamicZoneBase::DynamicZoneBase; // inherit base constructors
|
using DynamicZoneBase::DynamicZoneBase; // inherit base constructors
|
||||||
|
|
||||||
DynamicZone() = default;
|
|
||||||
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);
|
|
||||||
|
|
||||||
static DynamicZone* FindDynamicZoneByID(uint32_t dz_id);
|
static DynamicZone* FindDynamicZoneByID(uint32_t dz_id);
|
||||||
static void HandleZoneMessage(ServerPacket* pack);
|
static void HandleZoneMessage(ServerPacket* pack);
|
||||||
|
|
||||||
|
|||||||
@ -30,37 +30,25 @@
|
|||||||
extern ClientList client_list;
|
extern ClientList client_list;
|
||||||
extern ZSList zoneserver_list;
|
extern ZSList zoneserver_list;
|
||||||
|
|
||||||
Expedition::Expedition(uint32_t expedition_id, const DynamicZone& dz, uint32_t leader_id
|
Expedition::Expedition() :
|
||||||
) :
|
|
||||||
m_expedition_id(expedition_id),
|
|
||||||
m_dynamic_zone(dz),
|
|
||||||
m_leader_id(leader_id),
|
|
||||||
m_choose_leader_cooldown_timer{ static_cast<uint32_t>(RuleI(Expedition, ChooseLeaderCooldownTime)) }
|
m_choose_leader_cooldown_timer{ static_cast<uint32_t>(RuleI(Expedition, ChooseLeaderCooldownTime)) }
|
||||||
{
|
{
|
||||||
m_warning_cooldown_timer.Enable();
|
m_warning_cooldown_timer.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Expedition::AddMember(uint32_t character_id)
|
void Expedition::SetDynamicZone(DynamicZone&& dz)
|
||||||
{
|
{
|
||||||
if (!HasMember(character_id))
|
dz.SetName(GetName());
|
||||||
{
|
dz.SetLeaderName(GetLeaderName());
|
||||||
m_member_ids.emplace_back(character_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Expedition::HasMember(uint32_t character_id)
|
m_dynamic_zone = std::move(dz);
|
||||||
{
|
|
||||||
return std::any_of(m_member_ids.begin(), m_member_ids.end(),
|
|
||||||
[&](uint32_t member_id) { return member_id == character_id; });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Expedition::RemoveMember(uint32_t character_id)
|
void Expedition::RemoveMember(uint32_t character_id)
|
||||||
{
|
{
|
||||||
m_member_ids.erase(std::remove_if(m_member_ids.begin(), m_member_ids.end(),
|
RemoveInternalMember(character_id);
|
||||||
[&](uint32_t member_id) { return member_id == character_id; }
|
|
||||||
), m_member_ids.end());
|
|
||||||
|
|
||||||
if (character_id == m_leader_id)
|
if (character_id == m_leader.char_id)
|
||||||
{
|
{
|
||||||
ChooseNewLeader();
|
ChooseNewLeader();
|
||||||
}
|
}
|
||||||
@ -68,7 +56,7 @@ void Expedition::RemoveMember(uint32_t character_id)
|
|||||||
|
|
||||||
void Expedition::ChooseNewLeader()
|
void Expedition::ChooseNewLeader()
|
||||||
{
|
{
|
||||||
if (m_member_ids.empty() || !m_choose_leader_cooldown_timer.Check())
|
if (m_members.empty() || !m_choose_leader_cooldown_timer.Check())
|
||||||
{
|
{
|
||||||
m_choose_leader_needed = true;
|
m_choose_leader_needed = true;
|
||||||
return;
|
return;
|
||||||
@ -76,34 +64,38 @@ void Expedition::ChooseNewLeader()
|
|||||||
|
|
||||||
// we don't track expedition member status in world so may choose a linkdead member
|
// we don't track expedition member status in world so may choose a linkdead member
|
||||||
// this is fine since it will trigger another change when that member goes offline
|
// this is fine since it will trigger another change when that member goes offline
|
||||||
auto it = std::find_if(m_member_ids.begin(), m_member_ids.end(), [&](uint32_t member_id) {
|
auto it = std::find_if(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
||||||
auto member_cle = (member_id != m_leader_id) ? client_list.FindCLEByCharacterID(member_id) : nullptr;
|
if (member.char_id != m_leader.char_id) {
|
||||||
return (member_id != m_leader_id && member_cle && member_cle->GetOnline() == CLE_Status::InZone);
|
auto member_cle = client_list.FindCLEByCharacterID(member.char_id);
|
||||||
|
return (member_cle && member_cle->GetOnline() == CLE_Status::InZone);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it == m_member_ids.end())
|
if (it == m_members.end())
|
||||||
{
|
{
|
||||||
// no online members found, fallback to choosing any member
|
// no online members found, fallback to choosing any member
|
||||||
it = std::find_if(m_member_ids.begin(), m_member_ids.end(),
|
it = std::find_if(m_members.begin(), m_members.end(),
|
||||||
[&](uint32_t member_id) { return (member_id != m_leader_id); });
|
[&](const ExpeditionMember& member) { return (member.char_id != m_leader.char_id); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it != m_member_ids.end() && SetNewLeader(*it))
|
if (it != m_members.end() && SetNewLeader(*it))
|
||||||
{
|
{
|
||||||
m_choose_leader_needed = false;
|
m_choose_leader_needed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Expedition::SetNewLeader(uint32_t character_id)
|
bool Expedition::SetNewLeader(const ExpeditionMember& member)
|
||||||
{
|
{
|
||||||
if (!HasMember(character_id))
|
if (!HasMember(member.char_id))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogExpeditionsModerate("Replacing [{}] leader [{}] with [{}]", m_expedition_id, m_leader_id, character_id);
|
LogExpeditionsModerate("Replacing [{}] leader [{}] with [{}]", m_id, m_leader.name, member.name);
|
||||||
ExpeditionDatabase::UpdateLeaderID(m_expedition_id, character_id);
|
ExpeditionDatabase::UpdateLeaderID(m_id, member.char_id);
|
||||||
m_leader_id = character_id;
|
m_leader = member;
|
||||||
|
m_dynamic_zone.SetLeaderName(m_leader.name);
|
||||||
SendZonesLeaderChanged();
|
SendZonesLeaderChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -133,7 +125,7 @@ void Expedition::SendZonesLeaderChanged()
|
|||||||
auto pack = std::make_unique<ServerPacket>(ServerOP_ExpeditionLeaderChanged, pack_size);
|
auto pack = std::make_unique<ServerPacket>(ServerOP_ExpeditionLeaderChanged, pack_size);
|
||||||
auto buf = reinterpret_cast<ServerExpeditionLeaderID_Struct*>(pack->pBuffer);
|
auto buf = reinterpret_cast<ServerExpeditionLeaderID_Struct*>(pack->pBuffer);
|
||||||
buf->expedition_id = GetID();
|
buf->expedition_id = GetID();
|
||||||
buf->leader_id = m_leader_id;
|
buf->leader_id = m_leader.char_id;
|
||||||
zoneserver_list.SendPacket(pack.get());
|
zoneserver_list.SendPacket(pack.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,43 +22,34 @@
|
|||||||
#define WORLD_EXPEDITION_H
|
#define WORLD_EXPEDITION_H
|
||||||
|
|
||||||
#include "dynamic_zone.h"
|
#include "dynamic_zone.h"
|
||||||
|
#include "../common/expedition_base.h"
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
#include <chrono>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class Expedition
|
class Expedition : public ExpeditionBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Expedition() = default;
|
Expedition();
|
||||||
Expedition(uint32_t expedition_id, const DynamicZone& dz, uint32_t leader_id);
|
|
||||||
|
|
||||||
void AddMember(uint32_t character_id);
|
|
||||||
void RemoveMember(uint32_t character_id);
|
void RemoveMember(uint32_t character_id);
|
||||||
void RemoveAllMembers() { m_member_ids.clear(); }
|
|
||||||
void CheckExpireWarning();
|
void CheckExpireWarning();
|
||||||
void CheckLeader();
|
void CheckLeader();
|
||||||
void ChooseNewLeader();
|
void ChooseNewLeader();
|
||||||
DynamicZone& GetDynamicZone() { return m_dynamic_zone; }
|
DynamicZone& GetDynamicZone() { return m_dynamic_zone; }
|
||||||
uint32_t GetID() const { return m_expedition_id; }
|
|
||||||
bool HasMember(uint32_t character_id);
|
|
||||||
bool IsEmpty() const { return m_member_ids.empty(); }
|
|
||||||
bool IsValid() const { return m_expedition_id != 0; }
|
|
||||||
bool Process();
|
bool Process();
|
||||||
|
|
||||||
void SendZonesExpeditionDeleted();
|
void SendZonesExpeditionDeleted();
|
||||||
void SendZonesExpireWarning(uint32_t minutes_remaining);
|
void SendZonesExpireWarning(uint32_t minutes_remaining);
|
||||||
bool SetNewLeader(uint32_t new_leader_id);
|
void SetDynamicZone(DynamicZone&& dz);
|
||||||
|
bool SetNewLeader(const ExpeditionMember& member);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SendZonesLeaderChanged();
|
void SendZonesLeaderChanged();
|
||||||
|
|
||||||
uint32_t m_expedition_id = 0;
|
|
||||||
uint32_t m_leader_id = 0;
|
|
||||||
bool m_choose_leader_needed = false;
|
bool m_choose_leader_needed = false;
|
||||||
Timer m_choose_leader_cooldown_timer;
|
Timer m_choose_leader_cooldown_timer;
|
||||||
Timer m_warning_cooldown_timer;
|
Timer m_warning_cooldown_timer;
|
||||||
DynamicZone m_dynamic_zone;
|
DynamicZone m_dynamic_zone;
|
||||||
std::vector<uint32_t> m_member_ids;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -71,90 +71,6 @@ void ExpeditionDatabase::PurgeExpiredCharacterLockouts()
|
|||||||
database.QueryDatabase(query);
|
database.QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Expedition> ExpeditionDatabase::LoadExpeditions(uint32_t select_expedition_id)
|
|
||||||
{
|
|
||||||
std::vector<Expedition> expeditions;
|
|
||||||
|
|
||||||
std::string query = SQL(
|
|
||||||
SELECT
|
|
||||||
expeditions.id,
|
|
||||||
expeditions.dynamic_zone_id,
|
|
||||||
instance_list.id,
|
|
||||||
instance_list.zone,
|
|
||||||
instance_list.version,
|
|
||||||
instance_list.start_time,
|
|
||||||
instance_list.duration,
|
|
||||||
expeditions.leader_id,
|
|
||||||
expedition_members.character_id
|
|
||||||
FROM expeditions
|
|
||||||
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
|
|
||||||
AND expedition_members.is_current_member = TRUE
|
|
||||||
);
|
|
||||||
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
uint32_t last_expedition_id = 0;
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row)
|
|
||||||
{
|
|
||||||
uint32_t expedition_id = strtoul(row[0], nullptr, 10);
|
|
||||||
|
|
||||||
if (last_expedition_id != expedition_id)
|
|
||||||
{
|
|
||||||
DynamicZone dynamic_zone{
|
|
||||||
static_cast<uint32_t>(strtoul(row[1], nullptr, 10)), // dz_id
|
|
||||||
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)), // dz_zone_id
|
|
||||||
static_cast<uint32_t>(strtoul(row[2], nullptr, 10)), // dz_instance_id
|
|
||||||
static_cast<uint32_t>(strtoul(row[4], nullptr, 10)), // dz_zone_version
|
|
||||||
static_cast<uint32_t>(strtoul(row[5], nullptr, 10)), // start_time
|
|
||||||
static_cast<uint32_t>(strtoul(row[6], nullptr, 10)), // duration
|
|
||||||
DynamicZoneType::Expedition
|
|
||||||
};
|
|
||||||
|
|
||||||
expeditions.emplace_back(
|
|
||||||
expedition_id,
|
|
||||||
dynamic_zone,
|
|
||||||
static_cast<uint32_t>(strtoul(row[7], nullptr, 10)) // leader_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
last_expedition_id = expedition_id;
|
|
||||||
|
|
||||||
uint32_t member_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
|
||||||
expeditions.back().AddMember(member_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return expeditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expedition ExpeditionDatabase::LoadExpedition(uint32_t expedition_id)
|
|
||||||
{
|
|
||||||
LogExpeditions("Loading expedition [{}] for world cache", expedition_id);
|
|
||||||
|
|
||||||
Expedition expedition;
|
|
||||||
|
|
||||||
auto expeditions = LoadExpeditions(expedition_id);
|
|
||||||
if (!expeditions.empty())
|
|
||||||
{
|
|
||||||
expedition = expeditions.front();
|
|
||||||
}
|
|
||||||
|
|
||||||
return expedition;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpeditionDatabase::DeleteExpeditions(const std::vector<uint32_t>& expedition_ids)
|
void ExpeditionDatabase::DeleteExpeditions(const std::vector<uint32_t>& expedition_ids)
|
||||||
{
|
{
|
||||||
LogExpeditionsDetail("Deleting [{}] expedition(s)", expedition_ids.size());
|
LogExpeditionsDetail("Deleting [{}] expedition(s)", expedition_ids.size());
|
||||||
|
|||||||
@ -29,8 +29,6 @@ class Expedition;
|
|||||||
namespace ExpeditionDatabase
|
namespace ExpeditionDatabase
|
||||||
{
|
{
|
||||||
void DeleteExpeditions(const std::vector<uint32_t>& expedition_ids);
|
void DeleteExpeditions(const std::vector<uint32_t>& expedition_ids);
|
||||||
std::vector<Expedition> LoadExpeditions(uint32_t select_expedition_id = 0);
|
|
||||||
Expedition LoadExpedition(uint32_t expedition_id);
|
|
||||||
void MoveMembersToSafeReturn(const std::vector<uint32_t>& expedition_ids);
|
void MoveMembersToSafeReturn(const std::vector<uint32_t>& expedition_ids);
|
||||||
void PurgeExpiredExpeditions();
|
void PurgeExpiredExpeditions();
|
||||||
void PurgeExpiredCharacterLockouts();
|
void PurgeExpiredCharacterLockouts();
|
||||||
|
|||||||
@ -43,22 +43,22 @@ void ExpeditionMessage::HandleZoneMessage(ServerPacket* pack)
|
|||||||
case ServerOP_ExpeditionCreate:
|
case ServerOP_ExpeditionCreate:
|
||||||
{
|
{
|
||||||
auto buf = reinterpret_cast<ServerExpeditionID_Struct*>(pack->pBuffer);
|
auto buf = reinterpret_cast<ServerExpeditionID_Struct*>(pack->pBuffer);
|
||||||
expedition_state.AddExpedition(buf->expedition_id);
|
expedition_state.CacheFromDatabase(buf->expedition_id);
|
||||||
zoneserver_list.SendPacket(pack);
|
zoneserver_list.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_ExpeditionMemberChange:
|
case ServerOP_ExpeditionMemberChange:
|
||||||
{
|
{
|
||||||
auto buf = reinterpret_cast<ServerExpeditionMemberChange_Struct*>(pack->pBuffer);
|
auto buf = reinterpret_cast<ServerExpeditionMemberChange_Struct*>(pack->pBuffer);
|
||||||
expedition_state.MemberChange(buf->expedition_id, buf->char_id, buf->removed);
|
expedition_state.MemberChange(buf->expedition_id, { buf->char_id, buf->char_name }, buf->removed);
|
||||||
zoneserver_list.SendPacket(pack);
|
zoneserver_list.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_ExpeditionMemberSwap:
|
case ServerOP_ExpeditionMemberSwap:
|
||||||
{
|
{
|
||||||
auto buf = reinterpret_cast<ServerExpeditionMemberSwap_Struct*>(pack->pBuffer);
|
auto buf = reinterpret_cast<ServerExpeditionMemberSwap_Struct*>(pack->pBuffer);
|
||||||
expedition_state.MemberChange(buf->expedition_id, buf->add_char_id, false);
|
expedition_state.MemberChange(buf->expedition_id, { buf->add_char_id, buf->add_char_name }, false);
|
||||||
expedition_state.MemberChange(buf->expedition_id, buf->remove_char_id, true);
|
expedition_state.MemberChange(buf->expedition_id, { buf->remove_char_id, buf->remove_char_name }, true);
|
||||||
zoneserver_list.SendPacket(pack);
|
zoneserver_list.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ void ExpeditionMessage::MakeLeader(ServerPacket* pack)
|
|||||||
auto expedition = expedition_state.GetExpedition(buf->expedition_id);
|
auto expedition = expedition_state.GetExpedition(buf->expedition_id);
|
||||||
if (expedition)
|
if (expedition)
|
||||||
{
|
{
|
||||||
buf->is_success = expedition->SetNewLeader(new_leader_cle->CharID());
|
buf->is_success = expedition->SetNewLeader({ new_leader_cle->CharID(), new_leader_cle->name() });
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->is_online = true;
|
buf->is_online = true;
|
||||||
|
|||||||
@ -21,7 +21,9 @@
|
|||||||
#include "expedition_state.h"
|
#include "expedition_state.h"
|
||||||
#include "expedition.h"
|
#include "expedition.h"
|
||||||
#include "expedition_database.h"
|
#include "expedition_database.h"
|
||||||
|
#include "worlddb.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
|
#include "../common/repositories/expedition_members_repository.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
ExpeditionState expedition_state;
|
ExpeditionState expedition_state;
|
||||||
@ -29,66 +31,99 @@ ExpeditionState expedition_state;
|
|||||||
Expedition* ExpeditionState::GetExpedition(uint32_t expedition_id)
|
Expedition* ExpeditionState::GetExpedition(uint32_t expedition_id)
|
||||||
{
|
{
|
||||||
auto it = std::find_if(m_expeditions.begin(), m_expeditions.end(),
|
auto it = std::find_if(m_expeditions.begin(), m_expeditions.end(),
|
||||||
[&](const Expedition& expedition) { return expedition.GetID() == expedition_id; });
|
[&](const std::unique_ptr<Expedition>& expedition) {
|
||||||
|
return expedition->GetID() == expedition_id;
|
||||||
|
});
|
||||||
|
|
||||||
return (it != m_expeditions.end()) ? &(*it) : nullptr;
|
return (it != m_expeditions.end()) ? it->get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expedition* ExpeditionState::GetExpeditionByDynamicZoneID(uint32_t dz_id)
|
Expedition* ExpeditionState::GetExpeditionByDynamicZoneID(uint32_t dz_id)
|
||||||
{
|
{
|
||||||
auto it = std::find_if(m_expeditions.begin(), m_expeditions.end(),
|
auto it = std::find_if(m_expeditions.begin(), m_expeditions.end(),
|
||||||
[&](Expedition& expedition) { return expedition.GetDynamicZone().GetID() == dz_id; });
|
[&](const std::unique_ptr<Expedition>& expedition) {
|
||||||
|
return expedition->GetDynamicZone().GetID() == dz_id;
|
||||||
|
});
|
||||||
|
|
||||||
return (it != m_expeditions.end()) ? &(*it) : nullptr;
|
return (it != m_expeditions.end()) ? it->get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpeditionState::LoadActiveExpeditions()
|
void ExpeditionState::CacheFromDatabase(uint32_t expedition_id)
|
||||||
{
|
{
|
||||||
BenchTimer benchmark;
|
if (expedition_id == 0 || GetExpedition(expedition_id))
|
||||||
|
|
||||||
m_expeditions = ExpeditionDatabase::LoadExpeditions();
|
|
||||||
|
|
||||||
auto elapsed = benchmark.elapsed();
|
|
||||||
LogExpeditions("World caching [{}] expeditions took [{}s]", m_expeditions.size(), elapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpeditionState::AddExpedition(uint32_t expedition_id)
|
|
||||||
{
|
|
||||||
if (expedition_id == 0)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto expedition = ExpeditionDatabase::LoadExpedition(expedition_id);
|
auto expedition = ExpeditionsRepository::GetWithLeaderName(database, expedition_id);
|
||||||
|
CacheExpeditions({ std::move(expedition) });
|
||||||
if (expedition.IsValid())
|
|
||||||
{
|
|
||||||
auto existing_expedition = GetExpedition(expedition_id);
|
|
||||||
if (!existing_expedition)
|
|
||||||
{
|
|
||||||
m_expeditions.emplace_back(expedition);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpeditionState::CacheAllFromDatabase()
|
||||||
|
{
|
||||||
|
BenchTimer benchmark;
|
||||||
|
|
||||||
|
auto expeditions = ExpeditionsRepository::GetAllWithLeaderName(database);
|
||||||
|
m_expeditions.clear();
|
||||||
|
m_expeditions.reserve(expeditions.size());
|
||||||
|
|
||||||
|
CacheExpeditions(std::move(expeditions));
|
||||||
|
|
||||||
|
LogExpeditions("Caching [{}] expedition(s) took [{}s]", m_expeditions.size(), benchmark.elapsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpeditionState::CacheExpeditions(
|
||||||
|
std::vector<ExpeditionsRepository::ExpeditionWithLeader>&& expedition_entries)
|
||||||
|
{
|
||||||
|
// bulk load expedition dzs and members before caching
|
||||||
|
std::vector<uint32_t> expedition_ids;
|
||||||
|
std::vector<uint32_t> dynamic_zone_ids;
|
||||||
|
for (const auto& entry : expedition_entries)
|
||||||
|
{
|
||||||
|
expedition_ids.emplace_back(entry.id);
|
||||||
|
dynamic_zone_ids.emplace_back(entry.dynamic_zone_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dynamic_zones = DynamicZonesRepository::GetWithInstance(database, dynamic_zone_ids);
|
||||||
|
auto expedition_members = ExpeditionMembersRepository::GetWithNames(database, expedition_ids);
|
||||||
|
|
||||||
|
for (auto& entry : expedition_entries)
|
||||||
|
{
|
||||||
|
auto expedition = std::make_unique<Expedition>();
|
||||||
|
expedition->LoadRepositoryResult(std::move(entry));
|
||||||
|
|
||||||
|
auto dz_entry_iter = std::find_if(dynamic_zones.begin(), dynamic_zones.end(),
|
||||||
|
[&](const DynamicZonesRepository::DynamicZoneInstance& dz_entry) {
|
||||||
|
return dz_entry.id == entry.dynamic_zone_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dz_entry_iter != dynamic_zones.end())
|
||||||
|
{
|
||||||
|
expedition->SetDynamicZone(std::move(*dz_entry_iter));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& member : expedition_members)
|
||||||
|
{
|
||||||
|
if (member.expedition_id == expedition->GetID())
|
||||||
|
{
|
||||||
|
expedition->AddMemberFromRepositoryResult(std::move(member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpeditionState::RemoveExpedition(uint32_t expedition_id)
|
m_expeditions.emplace_back(std::move(expedition));
|
||||||
{
|
|
||||||
m_expeditions.erase(std::remove_if(m_expeditions.begin(), m_expeditions.end(),
|
|
||||||
[&](const Expedition& expedition) {
|
|
||||||
return expedition.GetID() == expedition_id;
|
|
||||||
}
|
}
|
||||||
), m_expeditions.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpeditionState::MemberChange(uint32_t expedition_id, uint32_t character_id, bool remove)
|
void ExpeditionState::MemberChange(
|
||||||
|
uint32_t expedition_id, const ExpeditionMember& member, bool remove)
|
||||||
{
|
{
|
||||||
auto expedition = GetExpedition(expedition_id);
|
auto expedition = GetExpedition(expedition_id);
|
||||||
if (expedition)
|
if (expedition)
|
||||||
{
|
{
|
||||||
if (remove) {
|
if (remove) {
|
||||||
expedition->RemoveMember(character_id);
|
expedition->RemoveMember(member.char_id);
|
||||||
} else {
|
} else {
|
||||||
expedition->AddMember(character_id);
|
expedition->AddInternalMember(member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +133,7 @@ void ExpeditionState::RemoveAllMembers(uint32_t expedition_id)
|
|||||||
auto expedition = GetExpedition(expedition_id);
|
auto expedition = GetExpedition(expedition_id);
|
||||||
if (expedition)
|
if (expedition)
|
||||||
{
|
{
|
||||||
expedition->RemoveAllMembers();
|
expedition->ClearInternalMembers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,10 +148,10 @@ void ExpeditionState::Process()
|
|||||||
|
|
||||||
for (auto it = m_expeditions.begin(); it != m_expeditions.end();)
|
for (auto it = m_expeditions.begin(); it != m_expeditions.end();)
|
||||||
{
|
{
|
||||||
bool is_deleted = it->Process();
|
bool is_deleted = (*it)->Process();
|
||||||
if (is_deleted)
|
if (is_deleted)
|
||||||
{
|
{
|
||||||
expedition_ids.emplace_back(it->GetID());
|
expedition_ids.emplace_back((*it)->GetID());
|
||||||
}
|
}
|
||||||
it = is_deleted ? m_expeditions.erase(it) : it + 1;
|
it = is_deleted ? m_expeditions.erase(it) : it + 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#ifndef WORLD_EXPEDITION_STATE_H
|
#ifndef WORLD_EXPEDITION_STATE_H
|
||||||
#define WORLD_EXPEDITION_STATE_H
|
#define WORLD_EXPEDITION_STATE_H
|
||||||
|
|
||||||
|
#include "../common/repositories/expeditions_repository.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "../common/timer.h"
|
#include "../common/timer.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -29,21 +30,22 @@
|
|||||||
extern class ExpeditionState expedition_state;
|
extern class ExpeditionState expedition_state;
|
||||||
|
|
||||||
class Expedition;
|
class Expedition;
|
||||||
|
struct ExpeditionMember;
|
||||||
|
|
||||||
class ExpeditionState
|
class ExpeditionState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void AddExpedition(uint32_t expedition_id);
|
void CacheExpeditions(std::vector<ExpeditionsRepository::ExpeditionWithLeader>&& expedition_entries);
|
||||||
|
void CacheFromDatabase(uint32_t expedition_id);
|
||||||
|
void CacheAllFromDatabase();
|
||||||
Expedition* GetExpedition(uint32_t expedition_id);
|
Expedition* GetExpedition(uint32_t expedition_id);
|
||||||
Expedition* GetExpeditionByDynamicZoneID(uint32_t dz_id);
|
Expedition* GetExpeditionByDynamicZoneID(uint32_t dz_id);
|
||||||
void LoadActiveExpeditions();
|
void MemberChange(uint32_t expedition_id, const ExpeditionMember& member, bool remove);
|
||||||
void MemberChange(uint32_t expedition_id, uint32_t character_id, bool remove);
|
|
||||||
void Process();
|
void Process();
|
||||||
void RemoveAllMembers(uint32_t expedition_id);
|
void RemoveAllMembers(uint32_t expedition_id);
|
||||||
void RemoveExpedition(uint32_t expedition_id);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Expedition> m_expeditions;
|
std::vector<std::unique_ptr<Expedition>> m_expeditions;
|
||||||
Timer m_process_throttle_timer{static_cast<uint32_t>(RuleI(DynamicZone, WorldProcessRate))};
|
Timer m_process_throttle_timer{static_cast<uint32_t>(RuleI(DynamicZone, WorldProcessRate))};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -438,7 +438,7 @@ int main(int argc, char** argv) {
|
|||||||
PurgeInstanceTimer.Start(450000);
|
PurgeInstanceTimer.Start(450000);
|
||||||
|
|
||||||
LogInfo("Loading active expeditions");
|
LogInfo("Loading active expeditions");
|
||||||
expedition_state.LoadActiveExpeditions();
|
expedition_state.CacheAllFromDatabase();
|
||||||
|
|
||||||
LogInfo("Loading char create info");
|
LogInfo("Loading char create info");
|
||||||
content_db.LoadCharacterCreateAllocations();
|
content_db.LoadCharacterCreateAllocations();
|
||||||
|
|||||||
@ -6900,20 +6900,20 @@ void command_dz(Client* c, const Seperator* sep)
|
|||||||
auto leader_saylink = EQ::SayLinkEngine::GenerateQuestSaylink(fmt::format(
|
auto leader_saylink = EQ::SayLinkEngine::GenerateQuestSaylink(fmt::format(
|
||||||
"#goto {}", expedition->GetLeaderName()), false, expedition->GetLeaderName());
|
"#goto {}", expedition->GetLeaderName()), false, expedition->GetLeaderName());
|
||||||
auto zone_saylink = EQ::SayLinkEngine::GenerateQuestSaylink(fmt::format(
|
auto zone_saylink = EQ::SayLinkEngine::GenerateQuestSaylink(fmt::format(
|
||||||
"#zoneinstance {}", expedition->GetInstanceID()), false, "zone");
|
"#zoneinstance {}", expedition->GetDynamicZone().GetInstanceID()), false, "zone");
|
||||||
|
|
||||||
auto seconds = expedition->GetDynamicZone().GetSecondsRemaining();
|
auto seconds = expedition->GetDynamicZone().GetSecondsRemaining();
|
||||||
|
|
||||||
c->Message(Chat::White, fmt::format(
|
c->Message(Chat::White, fmt::format(
|
||||||
"expedition id: [{}] dz id: [{}] name: [{}] leader: [{}] {}: [{}]:[{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
"expedition id: [{}] dz id: [{}] name: [{}] leader: [{}] {}: [{}]:[{}]:[{}]:[{}] members: [{}] remaining: [{:02}:{:02}:{:02}]",
|
||||||
expedition->GetID(),
|
expedition->GetID(),
|
||||||
expedition->GetDynamicZoneID(),
|
expedition->GetDynamicZone().GetID(),
|
||||||
expedition->GetName(),
|
expedition->GetName(),
|
||||||
leader_saylink,
|
leader_saylink,
|
||||||
zone_saylink,
|
zone_saylink,
|
||||||
ZoneName(expedition->GetDynamicZone().GetZoneID()),
|
ZoneName(expedition->GetDynamicZone().GetZoneID()),
|
||||||
expedition->GetDynamicZone().GetZoneID(),
|
expedition->GetDynamicZone().GetZoneID(),
|
||||||
expedition->GetInstanceID(),
|
expedition->GetDynamicZone().GetInstanceID(),
|
||||||
expedition->GetDynamicZone().GetZoneVersion(),
|
expedition->GetDynamicZone().GetZoneVersion(),
|
||||||
expedition->GetMemberCount(),
|
expedition->GetMemberCount(),
|
||||||
seconds / 3600, // hours
|
seconds / 3600, // hours
|
||||||
|
|||||||
@ -64,22 +64,6 @@ DynamicZone* DynamicZone::FindDynamicZoneByID(uint32_t dz_id)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<uint32_t, DynamicZone> DynamicZone::LoadMultipleDzFromDatabase(
|
|
||||||
const std::vector<uint32_t>& dynamic_zone_ids)
|
|
||||||
{
|
|
||||||
LogDynamicZonesDetail("Loading dynamic zone data for [{}] instances", dynamic_zone_ids.size());
|
|
||||||
|
|
||||||
std::unordered_map<uint32_t, DynamicZone> dynamic_zones;
|
|
||||||
|
|
||||||
auto entries = DynamicZonesRepository::GetWithInstance(database, dynamic_zone_ids);
|
|
||||||
for (auto& entry : entries)
|
|
||||||
{
|
|
||||||
dynamic_zones.emplace(entry.id, std::move(entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
return dynamic_zones;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DynamicZone::StartAllClientRemovalTimers()
|
void DynamicZone::StartAllClientRemovalTimers()
|
||||||
{
|
{
|
||||||
for (const auto& client_iter : entity_list.GetClientList())
|
for (const auto& client_iter : entity_list.GetClientList())
|
||||||
|
|||||||
@ -42,8 +42,6 @@ public:
|
|||||||
DynamicZone(uint32_t zone_id, uint32_t version, uint32_t duration, DynamicZoneType type);
|
DynamicZone(uint32_t zone_id, uint32_t version, uint32_t duration, DynamicZoneType type);
|
||||||
|
|
||||||
static DynamicZone* FindDynamicZoneByID(uint32_t dz_id);
|
static DynamicZone* FindDynamicZoneByID(uint32_t dz_id);
|
||||||
static std::unordered_map<uint32_t, DynamicZone> LoadMultipleDzFromDatabase(
|
|
||||||
const std::vector<uint32_t>& dynamic_zone_ids);
|
|
||||||
static void HandleWorldMessage(ServerPacket* pack);
|
static void HandleWorldMessage(ServerPacket* pack);
|
||||||
|
|
||||||
void SetSecondsRemaining(uint32_t seconds_remaining) override;
|
void SetSecondsRemaining(uint32_t seconds_remaining) override;
|
||||||
|
|||||||
@ -27,6 +27,8 @@
|
|||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
#include "../common/expedition_lockout_timer.h"
|
#include "../common/expedition_lockout_timer.h"
|
||||||
|
#include "../common/repositories/expedition_lockouts_repository.h"
|
||||||
|
#include "../common/repositories/expedition_members_repository.h"
|
||||||
#include "../common/util/uuid.h"
|
#include "../common/util/uuid.h"
|
||||||
|
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
@ -49,13 +51,7 @@ const int32_t Expedition::EVENT_TIMER_ID = 1;
|
|||||||
Expedition::Expedition(
|
Expedition::Expedition(
|
||||||
uint32_t id, const std::string& uuid, DynamicZone&& dz, const std::string& expedition_name,
|
uint32_t id, const std::string& uuid, DynamicZone&& dz, const std::string& expedition_name,
|
||||||
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players
|
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players
|
||||||
) :
|
) : ExpeditionBase(id, uuid, expedition_name, leader, min_players, max_players)
|
||||||
m_id(id),
|
|
||||||
m_uuid(uuid),
|
|
||||||
m_expedition_name(expedition_name),
|
|
||||||
m_leader(leader),
|
|
||||||
m_min_players(min_players),
|
|
||||||
m_max_players(max_players)
|
|
||||||
{
|
{
|
||||||
SetDynamicZone(std::move(dz));
|
SetDynamicZone(std::move(dz));
|
||||||
}
|
}
|
||||||
@ -122,7 +118,7 @@ Expedition* Expedition::TryCreate(
|
|||||||
"Created [{}] [{}] instance id: [{}] leader: [{}] minplayers: [{}] maxplayers: [{}]",
|
"Created [{}] [{}] instance id: [{}] leader: [{}] minplayers: [{}] maxplayers: [{}]",
|
||||||
expedition->GetID(),
|
expedition->GetID(),
|
||||||
expedition->GetName(),
|
expedition->GetName(),
|
||||||
expedition->GetInstanceID(),
|
expedition->GetDynamicZone().GetInstanceID(),
|
||||||
expedition->GetLeaderName(),
|
expedition->GetLeaderName(),
|
||||||
expedition->GetMinPlayers(),
|
expedition->GetMinPlayers(),
|
||||||
expedition->GetMaxPlayers()
|
expedition->GetMaxPlayers()
|
||||||
@ -150,113 +146,88 @@ Expedition* Expedition::TryCreate(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Expedition::CacheExpeditions(MySQLRequestResult& results)
|
void Expedition::CacheExpeditions(
|
||||||
|
std::vector<ExpeditionsRepository::ExpeditionWithLeader>&& expedition_entries)
|
||||||
{
|
{
|
||||||
if (!results.Success() || !zone)
|
if (!zone)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bulk load expedition dzs, members, and internal lockouts before caching
|
||||||
std::vector<uint32_t> expedition_ids;
|
std::vector<uint32_t> expedition_ids;
|
||||||
std::vector<uint32_t> dynamic_zone_ids;;
|
std::vector<uint32_t> dynamic_zone_ids;
|
||||||
std::vector<std::pair<uint32_t, uint32_t>> expedition_character_ids;
|
for (const auto& entry : expedition_entries)
|
||||||
|
|
||||||
using col = LoadExpeditionColumns::eLoadExpeditionColumns;
|
|
||||||
|
|
||||||
uint32_t last_expedition_id = 0;
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row)
|
|
||||||
{
|
{
|
||||||
auto expedition_id = strtoul(row[col::id], nullptr, 10);
|
expedition_ids.emplace_back(entry.id);
|
||||||
|
dynamic_zone_ids.emplace_back(entry.dynamic_zone_id);
|
||||||
if (expedition_id != last_expedition_id)
|
|
||||||
{
|
|
||||||
expedition_ids.emplace_back(expedition_id);
|
|
||||||
|
|
||||||
uint32_t leader_id = strtoul(row[col::leader_id], nullptr, 10);
|
|
||||||
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::make_unique<Expedition>(
|
|
||||||
expedition_id,
|
|
||||||
row[col::uuid], // expedition uuid
|
|
||||||
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
|
|
||||||
strtoul(row[col::max_players], nullptr, 10) // max_players
|
|
||||||
);
|
|
||||||
|
|
||||||
bool add_replay_on_join = (strtoul(row[col::add_replay_on_join], nullptr, 10) != 0);
|
|
||||||
bool is_locked = (strtoul(row[col::is_locked], nullptr, 10) != 0);
|
|
||||||
|
|
||||||
expedition->SetReplayLockoutOnMemberJoin(add_replay_on_join);
|
|
||||||
expedition->SetLocked(is_locked, ExpeditionLockMessage::None);
|
|
||||||
|
|
||||||
zone->expedition_cache.emplace(expedition_id, std::move(expedition));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
last_expedition_id = expedition_id;
|
auto dynamic_zones = DynamicZonesRepository::GetWithInstance(database, dynamic_zone_ids);
|
||||||
|
auto expedition_members = ExpeditionMembersRepository::GetWithNames(database, expedition_ids);
|
||||||
|
auto expedition_lockouts = ExpeditionLockoutsRepository::GetWithTimestamp(database, expedition_ids);
|
||||||
|
|
||||||
// looping expedition members
|
std::vector<std::pair<uint32_t, uint32_t>> expedition_character_ids; // for online status request
|
||||||
auto current_expedition = Expedition::FindCachedExpeditionByID(last_expedition_id);
|
|
||||||
if (current_expedition)
|
for (auto& entry : expedition_entries)
|
||||||
{
|
{
|
||||||
auto member_id = strtoul(row[col::member_id], nullptr, 10);
|
auto expedition = std::make_unique<Expedition>();
|
||||||
current_expedition->AddInternalMember(
|
expedition->LoadRepositoryResult(std::move(entry));
|
||||||
row[col::member_name], member_id, ExpeditionMemberStatus::Offline);
|
|
||||||
expedition_character_ids.emplace_back(expedition_id, member_id);
|
auto dz_entry_iter = std::find_if(dynamic_zones.begin(), dynamic_zones.end(),
|
||||||
|
[&](const DynamicZonesRepository::DynamicZoneInstance& dz_entry) {
|
||||||
|
return dz_entry.id == entry.dynamic_zone_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dz_entry_iter != dynamic_zones.end())
|
||||||
|
{
|
||||||
|
expedition->SetDynamicZone(std::move(*dz_entry_iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& member : expedition_members)
|
||||||
|
{
|
||||||
|
if (member.expedition_id == expedition->GetID())
|
||||||
|
{
|
||||||
|
expedition->AddMemberFromRepositoryResult(std::move(member));
|
||||||
|
expedition_character_ids.emplace_back(expedition->GetID(), member.character_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& lockout_entry : expedition_lockouts)
|
||||||
|
{
|
||||||
|
if (lockout_entry.expedition_id == expedition->GetID())
|
||||||
|
{
|
||||||
|
ExpeditionLockoutTimer lockout{
|
||||||
|
std::move(lockout_entry.from_expedition_uuid),
|
||||||
|
expedition->GetName(),
|
||||||
|
std::move(lockout_entry.event_name),
|
||||||
|
static_cast<uint64_t>(lockout_entry.expire_time),
|
||||||
|
static_cast<uint32_t>(lockout_entry.duration)
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string event_name = lockout.GetEventName(); // copy for key since we're moving it
|
||||||
|
expedition->m_lockouts.emplace(std::move(event_name), std::move(lockout));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto inserted = zone->expedition_cache.emplace(entry.id, std::move(expedition));
|
||||||
|
inserted.first->second->SendUpdatesToZoneMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ask world for online members from all cached expeditions at once
|
// ask world for online members from all cached expeditions at once
|
||||||
Expedition::SendWorldGetOnlineMembers(expedition_character_ids);
|
Expedition::SendWorldGetOnlineMembers(expedition_character_ids);
|
||||||
|
|
||||||
// bulk load dynamic zone data and expedition lockouts for cached expeditions
|
|
||||||
auto dynamic_zones = DynamicZone::LoadMultipleDzFromDatabase(dynamic_zone_ids);
|
|
||||||
auto expedition_lockouts = ExpeditionDatabase::LoadMultipleExpeditionLockouts(expedition_ids);
|
|
||||||
|
|
||||||
for (const auto& expedition_id : expedition_ids)
|
|
||||||
{
|
|
||||||
auto expedition = Expedition::FindCachedExpeditionByID(expedition_id);
|
|
||||||
if (expedition)
|
|
||||||
{
|
|
||||||
auto dz_iter = dynamic_zones.find(expedition->GetDynamicZoneID());
|
|
||||||
if (dz_iter != dynamic_zones.end())
|
|
||||||
{
|
|
||||||
expedition->SetDynamicZone(std::move(dz_iter->second));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto lockout_iter = expedition_lockouts.find(expedition->GetID());
|
|
||||||
if (lockout_iter != expedition_lockouts.end())
|
|
||||||
{
|
|
||||||
expedition->m_lockouts = lockout_iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send member updates now that all data is loaded for the cached expedition
|
|
||||||
expedition->SendUpdatesToZoneMembers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Expedition::CacheFromDatabase(uint32_t expedition_id)
|
void Expedition::CacheFromDatabase(uint32_t expedition_id)
|
||||||
{
|
{
|
||||||
if (zone)
|
if (zone && expedition_id != 0)
|
||||||
{
|
{
|
||||||
BenchTimer benchmark;
|
BenchTimer benchmark;
|
||||||
|
|
||||||
auto results = ExpeditionDatabase::LoadExpedition(expedition_id);
|
auto expedition = ExpeditionsRepository::GetWithLeaderName(database, expedition_id);
|
||||||
if (!results.Success())
|
CacheExpeditions({ std::move(expedition) });
|
||||||
{
|
|
||||||
LogExpeditions("Failed to load Expedition [{}] for zone cache", expedition_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CacheExpeditions(results);
|
LogExpeditions("Caching new expedition [{}] took [{}s]", expedition_id, benchmark.elapsed());
|
||||||
|
|
||||||
auto elapsed = benchmark.elapsed();
|
|
||||||
LogExpeditions("Caching new expedition [{}] took [{}s]", expedition_id, elapsed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,20 +240,13 @@ bool Expedition::CacheAllFromDatabase()
|
|||||||
|
|
||||||
BenchTimer benchmark;
|
BenchTimer benchmark;
|
||||||
|
|
||||||
|
auto expeditions = ExpeditionsRepository::GetAllWithLeaderName(database);
|
||||||
zone->expedition_cache.clear();
|
zone->expedition_cache.clear();
|
||||||
|
zone->expedition_cache.reserve(expeditions.size());
|
||||||
|
|
||||||
// load all active expeditions and members to current zone cache
|
CacheExpeditions(std::move(expeditions));
|
||||||
auto results = ExpeditionDatabase::LoadAllExpeditions();
|
|
||||||
if (!results.Success())
|
|
||||||
{
|
|
||||||
LogExpeditions("Failed to load Expeditions for zone cache");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CacheExpeditions(results);
|
LogExpeditions("Caching [{}] expedition(s) took [{}s]", zone->expedition_cache.size(), benchmark.elapsed());
|
||||||
|
|
||||||
auto elapsed = benchmark.elapsed();
|
|
||||||
LogExpeditions("Caching [{}] expedition(s) took [{}s]", zone->expedition_cache.size(), elapsed);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -391,48 +355,6 @@ bool Expedition::HasReplayLockout()
|
|||||||
return HasLockout(DZ_REPLAY_TIMER_NAME);
|
return HasLockout(DZ_REPLAY_TIMER_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Expedition::HasMember(uint32_t character_id)
|
|
||||||
{
|
|
||||||
return std::any_of(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
|
||||||
return member.char_id == character_id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Expedition::HasMember(const std::string& character_name)
|
|
||||||
{
|
|
||||||
return std::any_of(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
|
||||||
return (strcasecmp(member.name.c_str(), character_name.c_str()) == 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpeditionMember Expedition::GetMemberData(uint32_t character_id)
|
|
||||||
{
|
|
||||||
auto it = std::find_if(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
|
||||||
return member.char_id == character_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
ExpeditionMember member_data;
|
|
||||||
if (it != m_members.end())
|
|
||||||
{
|
|
||||||
member_data = *it;
|
|
||||||
}
|
|
||||||
return member_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpeditionMember Expedition::GetMemberData(const std::string& character_name)
|
|
||||||
{
|
|
||||||
auto it = std::find_if(m_members.begin(), m_members.end(), [&](const ExpeditionMember& member) {
|
|
||||||
return (strcasecmp(member.name.c_str(), character_name.c_str()) == 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
ExpeditionMember member_data;
|
|
||||||
if (it != m_members.end())
|
|
||||||
{
|
|
||||||
member_data = *it;
|
|
||||||
}
|
|
||||||
return member_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Expedition::SetReplayLockoutOnMemberJoin(bool add_on_join, bool update_db)
|
void Expedition::SetReplayLockoutOnMemberJoin(bool add_on_join, bool update_db)
|
||||||
{
|
{
|
||||||
m_add_replay_on_join = add_on_join;
|
m_add_replay_on_join = add_on_join;
|
||||||
@ -526,20 +448,6 @@ void Expedition::RemoveLockout(const std::string& event_name)
|
|||||||
SendWorldLockoutUpdate(lockout, true);
|
SendWorldLockoutUpdate(lockout, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Expedition::AddInternalMember(
|
|
||||||
const std::string& char_name, uint32_t character_id, ExpeditionMemberStatus status)
|
|
||||||
{
|
|
||||||
auto it = std::find_if(m_members.begin(), m_members.end(),
|
|
||||||
[character_id](const ExpeditionMember& member) {
|
|
||||||
return member.char_id == character_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (it == m_members.end())
|
|
||||||
{
|
|
||||||
m_members.emplace_back(character_id, char_name, status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Expedition::AddMember(const std::string& add_char_name, uint32_t add_char_id)
|
bool Expedition::AddMember(const std::string& add_char_name, uint32_t add_char_id)
|
||||||
{
|
{
|
||||||
if (HasMember(add_char_id))
|
if (HasMember(add_char_id))
|
||||||
@ -644,10 +552,7 @@ void Expedition::UpdateMemberStatus(uint32_t update_member_id, ExpeditionMemberS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if zone already had this member status cached avoid packet update to clients
|
// if zone already had this member status cached avoid packet update to clients
|
||||||
auto it = std::find_if(m_members.begin(), m_members.end(),
|
if (member_data.status == status)
|
||||||
[&](const ExpeditionMember& member) { return member.char_id == update_member_id; });
|
|
||||||
|
|
||||||
if (it != m_members.end() && it->status == status)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1197,7 +1102,7 @@ void Expedition::ProcessMemberAdded(const std::string& char_name, uint32_t added
|
|||||||
leader_client->MessageString(Chat::Yellow, EXPEDITION_MEMBER_ADDED, char_name.c_str(), m_expedition_name.c_str());
|
leader_client->MessageString(Chat::Yellow, EXPEDITION_MEMBER_ADDED, char_name.c_str(), m_expedition_name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
AddInternalMember(char_name, added_char_id, ExpeditionMemberStatus::Online);
|
AddInternalMember({ added_char_id, char_name, ExpeditionMemberStatus::Online });
|
||||||
|
|
||||||
Client* member_client = entity_list.GetClientByCharID(added_char_id);
|
Client* member_client = entity_list.GetClientByCharID(added_char_id);
|
||||||
if (member_client)
|
if (member_client)
|
||||||
|
|||||||
@ -22,8 +22,9 @@
|
|||||||
#define EXPEDITION_H
|
#define EXPEDITION_H
|
||||||
|
|
||||||
#include "dynamic_zone.h"
|
#include "dynamic_zone.h"
|
||||||
#include "../common/eq_constants.h"
|
#include "../common/expedition_base.h"
|
||||||
#include "../common/expedition_lockout_timer.h"
|
#include "../common/expedition_lockout_timer.h"
|
||||||
|
#include "../common/repositories/expeditions_repository.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -34,21 +35,11 @@ class Client;
|
|||||||
class EQApplicationPacket;
|
class EQApplicationPacket;
|
||||||
struct ExpeditionInvite;
|
struct ExpeditionInvite;
|
||||||
class ExpeditionRequest;
|
class ExpeditionRequest;
|
||||||
class MySQLRequestResult;
|
|
||||||
class ServerPacket;
|
class ServerPacket;
|
||||||
|
|
||||||
extern const char* const DZ_YOU_NOT_ASSIGNED;
|
extern const char* const DZ_YOU_NOT_ASSIGNED;
|
||||||
extern const char* const EXPEDITION_OTHER_BELONGS;
|
extern const char* const EXPEDITION_OTHER_BELONGS;
|
||||||
|
|
||||||
enum class ExpeditionMemberStatus : uint8_t
|
|
||||||
{
|
|
||||||
Unknown = 0,
|
|
||||||
Online,
|
|
||||||
Offline,
|
|
||||||
InDynamicZone,
|
|
||||||
LinkDead
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ExpeditionLockMessage : uint8_t
|
enum class ExpeditionLockMessage : uint8_t
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
@ -56,25 +47,10 @@ enum class ExpeditionLockMessage : uint8_t
|
|||||||
Begin
|
Begin
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExpeditionMember
|
class Expedition : public ExpeditionBase
|
||||||
{
|
|
||||||
uint32_t char_id = 0;
|
|
||||||
std::string name;
|
|
||||||
ExpeditionMemberStatus status = ExpeditionMemberStatus::Online;
|
|
||||||
|
|
||||||
ExpeditionMember() = default;
|
|
||||||
ExpeditionMember(uint32_t char_id_, const std::string& name_)
|
|
||||||
: char_id(char_id_), name(name_) {}
|
|
||||||
ExpeditionMember(uint32_t char_id_, const std::string& name_, ExpeditionMemberStatus status_)
|
|
||||||
: char_id(char_id_), name(name_), status(status_) {}
|
|
||||||
|
|
||||||
bool IsValid() const { return char_id != 0 && !name.empty(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Expedition
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Expedition() = delete;
|
Expedition() = default;
|
||||||
Expedition(uint32_t id, const std::string& uuid, DynamicZone&& dz, const std::string& expedition_name,
|
Expedition(uint32_t id, const std::string& uuid, DynamicZone&& dz, const std::string& expedition_name,
|
||||||
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players);
|
const ExpeditionMember& leader, uint32_t min_players, uint32_t max_players);
|
||||||
|
|
||||||
@ -103,23 +79,10 @@ public:
|
|||||||
const std::string& expedition_name = {}, const std::string& event_name = {});
|
const std::string& expedition_name = {}, const std::string& event_name = {});
|
||||||
static void AddLockoutClients(const ExpeditionLockoutTimer& lockout, uint32_t exclude_id = 0);
|
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; }
|
|
||||||
uint32_t GetMinPlayers() const { return m_min_players; }
|
|
||||||
uint32_t GetMaxPlayers() const { return m_max_players; }
|
|
||||||
uint32_t GetMemberCount() const { return static_cast<uint32_t>(m_members.size()); }
|
|
||||||
DynamicZone& GetDynamicZone() { return m_dynamiczone; }
|
DynamicZone& GetDynamicZone() { return m_dynamiczone; }
|
||||||
const std::string& GetName() const { return m_expedition_name; }
|
|
||||||
const std::string& GetLeaderName() const { return m_leader.name; }
|
|
||||||
const std::string& GetUUID() const { return m_uuid; }
|
|
||||||
const std::unordered_map<std::string, ExpeditionLockoutTimer>& GetLockouts() const { return m_lockouts; }
|
const std::unordered_map<std::string, ExpeditionLockoutTimer>& GetLockouts() const { return m_lockouts; }
|
||||||
const std::vector<ExpeditionMember>& GetMembers() const { return m_members; }
|
|
||||||
|
|
||||||
bool AddMember(const std::string& add_char_name, uint32_t add_char_id);
|
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);
|
void RemoveAllMembers(bool enable_removal_timers = true);
|
||||||
bool RemoveMember(const std::string& remove_char_name);
|
bool RemoveMember(const std::string& remove_char_name);
|
||||||
void SetMemberStatus(Client* client, ExpeditionMemberStatus status);
|
void SetMemberStatus(Client* client, ExpeditionMemberStatus status);
|
||||||
@ -164,13 +127,12 @@ public:
|
|||||||
static const int32_t EVENT_TIMER_ID;
|
static const int32_t EVENT_TIMER_ID;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void CacheExpeditions(MySQLRequestResult& results);
|
static void CacheExpeditions(std::vector<ExpeditionsRepository::ExpeditionWithLeader>&& expeditions);
|
||||||
static void SendWorldGetOnlineMembers(const std::vector<std::pair<uint32_t, uint32_t>>& expedition_character_ids);
|
static void SendWorldGetOnlineMembers(const std::vector<std::pair<uint32_t, uint32_t>>& expedition_character_ids);
|
||||||
static void SendWorldCharacterLockout(uint32_t character_id, const ExpeditionLockoutTimer& lockout, bool remove);
|
static void SendWorldCharacterLockout(uint32_t character_id, const ExpeditionLockoutTimer& lockout, bool remove);
|
||||||
|
|
||||||
void AddLockout(const ExpeditionLockoutTimer& lockout, bool members_only = false);
|
void AddLockout(const ExpeditionLockoutTimer& lockout, bool members_only = false);
|
||||||
void AddLockoutDurationClients(const ExpeditionLockoutTimer& lockout, int seconds, uint32_t exclude_id = 0);
|
void AddLockoutDurationClients(const ExpeditionLockoutTimer& lockout, int seconds, uint32_t exclude_id = 0);
|
||||||
void AddInternalMember(const std::string& char_name, uint32_t char_id, ExpeditionMemberStatus status);
|
|
||||||
bool ConfirmLeaderCommand(Client* requester);
|
bool ConfirmLeaderCommand(Client* requester);
|
||||||
bool ProcessAddConflicts(Client* leader_client, Client* add_client, bool swapping);
|
bool ProcessAddConflicts(Client* leader_client, Client* add_client, bool swapping);
|
||||||
void ProcessLeaderChanged(uint32_t new_leader_id);
|
void ProcessLeaderChanged(uint32_t new_leader_id);
|
||||||
@ -207,8 +169,6 @@ private:
|
|||||||
const std::string& swap_remove_name, Client* leader_client = nullptr);
|
const std::string& swap_remove_name, Client* leader_client = nullptr);
|
||||||
void UpdateMemberStatus(uint32_t update_character_id, ExpeditionMemberStatus status);
|
void UpdateMemberStatus(uint32_t update_character_id, ExpeditionMemberStatus status);
|
||||||
|
|
||||||
ExpeditionMember GetMemberData(uint32_t character_id);
|
|
||||||
ExpeditionMember GetMemberData(const std::string& character_name);
|
|
||||||
std::unique_ptr<EQApplicationPacket> CreateExpireWarningPacket(uint32_t minutes_remaining);
|
std::unique_ptr<EQApplicationPacket> CreateExpireWarningPacket(uint32_t minutes_remaining);
|
||||||
std::unique_ptr<EQApplicationPacket> CreateInfoPacket(bool clear = false);
|
std::unique_ptr<EQApplicationPacket> CreateInfoPacket(bool clear = false);
|
||||||
std::unique_ptr<EQApplicationPacket> CreateInvitePacket(const std::string& inviter_name, const std::string& swap_remove_name);
|
std::unique_ptr<EQApplicationPacket> CreateInvitePacket(const std::string& inviter_name, const std::string& swap_remove_name);
|
||||||
@ -217,16 +177,7 @@ private:
|
|||||||
std::unique_ptr<EQApplicationPacket> CreateMemberListStatusPacket(const std::string& name, ExpeditionMemberStatus status);
|
std::unique_ptr<EQApplicationPacket> CreateMemberListStatusPacket(const std::string& name, ExpeditionMemberStatus status);
|
||||||
std::unique_ptr<EQApplicationPacket> CreateLeaderNamePacket();
|
std::unique_ptr<EQApplicationPacket> CreateLeaderNamePacket();
|
||||||
|
|
||||||
uint32_t m_id = 0;
|
|
||||||
uint32_t m_min_players = 0;
|
|
||||||
uint32_t m_max_players = 0;
|
|
||||||
bool m_is_locked = false;
|
|
||||||
bool m_add_replay_on_join = true;
|
|
||||||
std::string m_uuid;
|
|
||||||
std::string m_expedition_name;
|
|
||||||
DynamicZone m_dynamiczone { DynamicZoneType::Expedition };
|
DynamicZone m_dynamiczone { DynamicZoneType::Expedition };
|
||||||
ExpeditionMember m_leader;
|
|
||||||
std::vector<ExpeditionMember> m_members;
|
|
||||||
std::unordered_map<std::string, ExpeditionLockoutTimer> m_lockouts;
|
std::unordered_map<std::string, ExpeditionLockoutTimer> m_lockouts;
|
||||||
std::unordered_map<uint32_t, std::string> m_npc_loot_events; // only valid inside dz zone
|
std::unordered_map<uint32_t, std::string> m_npc_loot_events; // only valid inside dz zone
|
||||||
std::unordered_map<uint32_t, std::string> m_spawn_loot_events; // only valid inside dz zone
|
std::unordered_map<uint32_t, std::string> m_spawn_loot_events; // only valid inside dz zone
|
||||||
|
|||||||
@ -51,52 +51,6 @@ uint32_t ExpeditionDatabase::InsertExpedition(
|
|||||||
return results.LastInsertedID();
|
return results.LastInsertedID();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ExpeditionDatabase::LoadExpeditionsSelectQuery()
|
|
||||||
{
|
|
||||||
return std::string(SQL(
|
|
||||||
SELECT
|
|
||||||
expeditions.id,
|
|
||||||
expeditions.uuid,
|
|
||||||
expeditions.dynamic_zone_id,
|
|
||||||
expeditions.expedition_name,
|
|
||||||
expeditions.leader_id,
|
|
||||||
expeditions.min_players,
|
|
||||||
expeditions.max_players,
|
|
||||||
expeditions.add_replay_on_join,
|
|
||||||
expeditions.is_locked,
|
|
||||||
character_data.name leader_name,
|
|
||||||
expedition_members.character_id,
|
|
||||||
member_data.name
|
|
||||||
FROM expeditions
|
|
||||||
INNER JOIN character_data ON expeditions.leader_id = character_data.id
|
|
||||||
INNER JOIN expedition_members ON expeditions.id = expedition_members.expedition_id
|
|
||||||
AND expedition_members.is_current_member = TRUE
|
|
||||||
INNER JOIN character_data member_data ON expedition_members.character_id = member_data.id
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
MySQLRequestResult ExpeditionDatabase::LoadExpedition(uint32_t expedition_id)
|
|
||||||
{
|
|
||||||
LogExpeditionsDetail("Loading expedition [{}]", expedition_id);
|
|
||||||
|
|
||||||
std::string query = fmt::format(SQL(
|
|
||||||
{} WHERE expeditions.id = {};
|
|
||||||
), LoadExpeditionsSelectQuery(), expedition_id);
|
|
||||||
|
|
||||||
return database.QueryDatabase(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
MySQLRequestResult ExpeditionDatabase::LoadAllExpeditions()
|
|
||||||
{
|
|
||||||
LogExpeditionsDetail("Loading all expeditions from database");
|
|
||||||
|
|
||||||
std::string query = fmt::format(SQL(
|
|
||||||
{} ORDER BY expeditions.id;
|
|
||||||
), LoadExpeditionsSelectQuery());
|
|
||||||
|
|
||||||
return database.QueryDatabase(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(uint32_t character_id)
|
std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(uint32_t character_id)
|
||||||
{
|
{
|
||||||
LogExpeditionsDetail("Loading character [{}] lockouts", character_id);
|
LogExpeditionsDetail("Loading character [{}] lockouts", character_id);
|
||||||
@ -170,54 +124,6 @@ std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(
|
|||||||
return lockouts;
|
return lockouts;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<uint32_t, std::unordered_map<std::string, ExpeditionLockoutTimer>>
|
|
||||||
ExpeditionDatabase::LoadMultipleExpeditionLockouts(
|
|
||||||
const std::vector<uint32_t>& expedition_ids)
|
|
||||||
{
|
|
||||||
LogExpeditionsDetail("Loading internal lockouts for [{}] expeditions", expedition_ids.size());
|
|
||||||
|
|
||||||
std::string in_expedition_ids_query = fmt::format("{}", fmt::join(expedition_ids, ","));
|
|
||||||
|
|
||||||
// these are loaded into the same container type expeditions use to store lockouts
|
|
||||||
std::unordered_map<uint32_t, std::unordered_map<std::string, ExpeditionLockoutTimer>> lockouts;
|
|
||||||
|
|
||||||
if (!in_expedition_ids_query.empty())
|
|
||||||
{
|
|
||||||
std::string query = fmt::format(SQL(
|
|
||||||
SELECT
|
|
||||||
expedition_lockouts.expedition_id,
|
|
||||||
expedition_lockouts.from_expedition_uuid,
|
|
||||||
expeditions.expedition_name,
|
|
||||||
expedition_lockouts.event_name,
|
|
||||||
UNIX_TIMESTAMP(expedition_lockouts.expire_time),
|
|
||||||
expedition_lockouts.duration
|
|
||||||
FROM expedition_lockouts
|
|
||||||
INNER JOIN expeditions ON expedition_lockouts.expedition_id = expeditions.id
|
|
||||||
WHERE expedition_id IN ({})
|
|
||||||
ORDER BY expedition_id;
|
|
||||||
), in_expedition_ids_query);
|
|
||||||
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
|
|
||||||
if (results.Success())
|
|
||||||
{
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row)
|
|
||||||
{
|
|
||||||
auto expedition_id = strtoul(row[0], nullptr, 10);
|
|
||||||
lockouts[expedition_id].emplace(row[3], ExpeditionLockoutTimer{
|
|
||||||
row[1], // expedition_uuid
|
|
||||||
row[2], // expedition_name
|
|
||||||
row[3], // event_name
|
|
||||||
strtoull(row[4], nullptr, 10), // expire_time
|
|
||||||
static_cast<uint32_t>(strtoul(row[5], nullptr, 10)) // original duration
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lockouts;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpeditionDatabase::DeleteAllCharacterLockouts(uint32_t character_id)
|
void ExpeditionDatabase::DeleteAllCharacterLockouts(uint32_t character_id)
|
||||||
{
|
{
|
||||||
LogExpeditionsDetail("Deleting all character [{}] lockouts", character_id);
|
LogExpeditionsDetail("Deleting all character [{}] lockouts", character_id);
|
||||||
|
|||||||
@ -38,14 +38,9 @@ namespace ExpeditionDatabase
|
|||||||
uint32_t InsertExpedition(
|
uint32_t InsertExpedition(
|
||||||
const std::string& uuid, uint32_t instance_id, const std::string& expedition_name,
|
const std::string& uuid, uint32_t instance_id, const std::string& expedition_name,
|
||||||
uint32_t leader_id, uint32_t min_players, uint32_t max_players);
|
uint32_t leader_id, uint32_t min_players, uint32_t max_players);
|
||||||
std::string LoadExpeditionsSelectQuery();
|
|
||||||
MySQLRequestResult LoadExpedition(uint32_t expedition_id);
|
|
||||||
MySQLRequestResult LoadAllExpeditions();
|
|
||||||
std::vector<ExpeditionLockoutTimer> LoadCharacterLockouts(uint32_t character_id);
|
std::vector<ExpeditionLockoutTimer> LoadCharacterLockouts(uint32_t character_id);
|
||||||
std::vector<ExpeditionLockoutTimer> LoadCharacterLockouts(uint32_t character_id,
|
std::vector<ExpeditionLockoutTimer> LoadCharacterLockouts(uint32_t character_id,
|
||||||
const std::string& expedition_name);
|
const std::string& expedition_name);
|
||||||
std::unordered_map<uint32_t, std::unordered_map<std::string, ExpeditionLockoutTimer>>
|
|
||||||
LoadMultipleExpeditionLockouts(const std::vector<uint32_t>& expedition_ids);
|
|
||||||
void DeleteAllMembers(uint32_t expedition_id);
|
void DeleteAllMembers(uint32_t expedition_id);
|
||||||
void DeleteMember(uint32_t expedition_id, uint32_t character_id);
|
void DeleteMember(uint32_t expedition_id, uint32_t character_id);
|
||||||
void DeleteAllCharacterLockouts(uint32_t character_id);
|
void DeleteAllCharacterLockouts(uint32_t character_id);
|
||||||
@ -73,23 +68,4 @@ namespace ExpeditionDatabase
|
|||||||
const ExpeditionLockoutTimer& lockout, int seconds);
|
const ExpeditionLockoutTimer& lockout, int seconds);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace LoadExpeditionColumns
|
|
||||||
{
|
|
||||||
enum eLoadExpeditionColumns
|
|
||||||
{
|
|
||||||
id = 0,
|
|
||||||
uuid,
|
|
||||||
dz_id,
|
|
||||||
expedition_name,
|
|
||||||
leader_id,
|
|
||||||
min_players,
|
|
||||||
max_players,
|
|
||||||
add_replay_on_join,
|
|
||||||
is_locked,
|
|
||||||
leader_name,
|
|
||||||
member_id,
|
|
||||||
member_name
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -59,7 +59,7 @@ void Lua_Expedition::AddReplayLockoutDuration(int seconds, bool members_only) {
|
|||||||
|
|
||||||
uint32_t Lua_Expedition::GetDynamicZoneID() {
|
uint32_t Lua_Expedition::GetDynamicZoneID() {
|
||||||
Lua_Safe_Call_Int();
|
Lua_Safe_Call_Int();
|
||||||
return self->GetDynamicZoneID();
|
return self->GetDynamicZone().GetID();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Lua_Expedition::GetID() {
|
uint32_t Lua_Expedition::GetID() {
|
||||||
|
|||||||
@ -142,7 +142,7 @@ XS(XS_Expedition_GetDynamicZoneID) {
|
|||||||
Expedition* THIS = nullptr;
|
Expedition* THIS = nullptr;
|
||||||
VALIDATE_THIS_IS_EXPEDITION;
|
VALIDATE_THIS_IS_EXPEDITION;
|
||||||
|
|
||||||
XSRETURN_UV(THIS->GetDynamicZoneID());
|
XSRETURN_UV(THIS->GetDynamicZone().GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
XS(XS_Expedition_GetID);
|
XS(XS_Expedition_GetID);
|
||||||
@ -168,7 +168,7 @@ XS(XS_Expedition_GetInstanceID) {
|
|||||||
Expedition* THIS = nullptr;
|
Expedition* THIS = nullptr;
|
||||||
VALIDATE_THIS_IS_EXPEDITION;
|
VALIDATE_THIS_IS_EXPEDITION;
|
||||||
|
|
||||||
XSRETURN_UV(THIS->GetInstanceID());
|
XSRETURN_UV(THIS->GetDynamicZone().GetInstanceID());
|
||||||
}
|
}
|
||||||
|
|
||||||
XS(XS_Expedition_GetLeaderName);
|
XS(XS_Expedition_GetLeaderName);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user