Store lockouts with source expedition uuid

Add Client::GetLockoutExpeditionUUID quest api

Refactor lockout update methods to take ExpeditionLockoutTimer parameter

Fix updating expedition lockout cache for multiple AddLockout calls

Fix updating lockout duration when replacing a lockout in database

Replace lockout timer inherited flags with expedition uuid comparisons

Remove is_inherited column from expedition_lockouts table
This commit is contained in:
hg 2020-06-10 23:00:34 -04:00
parent 6a7980ec75
commit fa21d835d9
12 changed files with 163 additions and 108 deletions

View File

@ -22,7 +22,7 @@ CREATE TABLE `expedition_lockouts` (
`event_name` VARCHAR(256) NOT NULL,
`expire_time` DATETIME NOT NULL DEFAULT current_timestamp(),
`duration` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`is_inherited` TINYINT(4) UNSIGNED NOT NULL DEFAULT 0,
`from_expedition_uuid` VARCHAR(36) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `expedition_id_event_name` (`expedition_id`, `event_name`),
CONSTRAINT `FK_expedition_lockouts_expedition_details` FOREIGN KEY (`expedition_id`) REFERENCES `expedition_details` (`id`) ON DELETE CASCADE
@ -49,6 +49,7 @@ CREATE TABLE `expedition_character_lockouts` (
`character_id` INT(10) UNSIGNED NOT NULL,
`expire_time` DATETIME NOT NULL DEFAULT current_timestamp(),
`duration` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`from_expedition_uuid` VARCHAR(36) NOT NULL,
`expedition_name` VARCHAR(128) NOT NULL,
`event_name` VARCHAR(256) NOT NULL,
`is_pending` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0,
@ -57,5 +58,4 @@ CREATE TABLE `expedition_character_lockouts` (
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
ROW_FORMAT=DYNAMIC
;

View File

@ -39,6 +39,7 @@ extern volatile bool RunLoops;
#include "../common/string_util.h"
#include "../common/data_verification.h"
#include "../common/profanity_manager.h"
#include "../common/util/uuid.h"
#include "data_bucket.h"
#include "expedition.h"
#include "expedition_database.h"
@ -9613,22 +9614,19 @@ Expedition* Client::GetExpedition() const
return nullptr;
}
void Client::AddExpeditionLockout(const ExpeditionLockoutTimer& lockout, bool update_db, bool update_client)
void Client::AddExpeditionLockout(
const ExpeditionLockoutTimer& lockout, bool update_db, bool update_client)
{
// todo: support for account based lockouts like live AoC expeditions
auto it = std::find_if(m_expedition_lockouts.begin(), m_expedition_lockouts.end(),
// if client already has this lockout, we're replacing it with the new one
m_expedition_lockouts.erase(std::remove_if(m_expedition_lockouts.begin(), m_expedition_lockouts.end(),
[&](const ExpeditionLockoutTimer& existing_lockout) {
return existing_lockout.IsSameLockout(lockout);
});
}
), m_expedition_lockouts.end());
if (it != m_expedition_lockouts.end())
{
it->SetExpireTime(lockout.GetExpireTime());
}
else
{
m_expedition_lockouts.emplace_back(lockout);
}
m_expedition_lockouts.emplace_back(lockout);
if (update_db) // for quest api
{
@ -9642,11 +9640,14 @@ void Client::AddExpeditionLockout(const ExpeditionLockoutTimer& lockout, bool up
}
void Client::AddNewExpeditionLockout(
const std::string& expedition_name, const std::string& event_name, uint32_t seconds)
const std::string& expedition_name, const std::string& event_name, uint32_t seconds, std::string uuid)
{
auto expire_at = std::chrono::system_clock::now() + std::chrono::seconds(seconds);
auto expire_time = static_cast<uint64_t>(std::chrono::system_clock::to_time_t(expire_at));
ExpeditionLockoutTimer lockout{ expedition_name, event_name, expire_time, seconds };
if (uuid.empty())
{
uuid = EQ::Util::UUID::Generate().ToString();
}
ExpeditionLockoutTimer lockout{uuid, expedition_name, event_name, 0, seconds};
lockout.Reset(); // sets expire time
AddExpeditionLockout(lockout, true);
}
@ -9794,7 +9795,9 @@ void Client::DzListTimers()
auto time_remaining = lockout.GetDaysHoursMinutesRemaining();
MessageString(
Chat::Yellow, DZLIST_REPLAY_TIMER,
time_remaining.days.c_str(), time_remaining.hours.c_str(), time_remaining.mins.c_str(),
time_remaining.days.c_str(),
time_remaining.hours.c_str(),
time_remaining.mins.c_str(),
lockout.GetExpeditionName().c_str()
);
}

View File

@ -1118,7 +1118,8 @@ public:
uint32_t string_id, const std::initializer_list<std::string>& parameters = {});
void AddExpeditionLockout(const ExpeditionLockoutTimer& lockout, bool update_db = false, bool update_client = true);
void AddNewExpeditionLockout(const std::string& expedition_name, const std::string& event_name, uint32_t duration);
void AddNewExpeditionLockout(
const std::string& expedition_name, const std::string& event_name, uint32_t duration, std::string uuid = {});
Expedition* CreateExpedition(DynamicZone& dz_instance, ExpeditionRequest& request);
Expedition* CreateExpedition(
std::string zone_name, uint32 version, uint32 duration, std::string expedition_name,

View File

@ -443,17 +443,15 @@ void Expedition::AddReplayLockout(uint32_t seconds)
void Expedition::AddLockout(const std::string& event_name, uint32_t seconds)
{
auto expire_at = std::chrono::system_clock::now() + std::chrono::seconds(seconds);
auto expire_time = static_cast<uint64_t>(std::chrono::system_clock::to_time_t(expire_at));
// both expedition and current members get the lockout data, expirations updated on duplicates
ExpeditionLockoutTimer lockout{ m_expedition_name, event_name, expire_time, seconds };
// any current lockouts for the event are updated with new expiration time
ExpeditionLockoutTimer lockout{m_uuid, m_expedition_name, event_name, 0, seconds};
lockout.Reset(); // sets expire time
ExpeditionDatabase::InsertLockout(m_id, lockout);
ExpeditionDatabase::InsertMembersLockout(m_members, lockout);
ProcessLockoutUpdate(event_name, expire_time, seconds, false);
SendWorldLockoutUpdate(event_name, expire_time, seconds);
ProcessLockoutUpdate(lockout, false);
SendWorldLockoutUpdate(lockout, false);
}
void Expedition::RemoveLockout(const std::string& event_name)
@ -461,13 +459,9 @@ void Expedition::RemoveLockout(const std::string& event_name)
ExpeditionDatabase::DeleteLockout(m_id, event_name);
ExpeditionDatabase::DeleteMembersLockout(m_members, m_expedition_name, event_name);
ProcessLockoutUpdate(event_name, 0, 0, true);
SendWorldLockoutUpdate(event_name, 0, 0, true);
}
void Expedition::AddInternalLockout(ExpeditionLockoutTimer&& lockout_timer)
{
m_lockouts.emplace(lockout_timer.GetEventName(), std::move(lockout_timer));
ExpeditionLockoutTimer lockout{m_uuid, m_expedition_name, event_name, 0, 0};
ProcessLockoutUpdate(lockout, true);
SendWorldLockoutUpdate(lockout, true);
}
void Expedition::AddInternalMember(
@ -644,7 +638,7 @@ void Expedition::SendClientExpeditionInvite(
{
// live doesn't issue a warning for the dz's replay timer
const ExpeditionLockoutTimer& lockout = lockout_iter.second;
if (!lockout.IsInherited() && !lockout.IsExpired() && !lockout.IsReplayTimer() &&
if (!lockout.IsReplayTimer() && !lockout.IsExpired() && lockout.IsFromExpedition(m_uuid) &&
!client->HasExpeditionLockout(m_expedition_name, lockout.GetEventName()))
{
if (!warned)
@ -813,7 +807,7 @@ void Expedition::DzInviteResponse(Client* add_client, bool accepted, const std::
for (const auto& lockout_iter : m_lockouts)
{
const ExpeditionLockoutTimer& lockout = lockout_iter.second;
if (!lockout.IsInherited() &&
if (lockout.IsFromExpedition(m_uuid) &&
!add_client->HasExpeditionLockout(m_expedition_name, lockout.GetEventName()))
{
// replay timers are optionally added to new members immediately on
@ -822,8 +816,9 @@ void Expedition::DzInviteResponse(Client* add_client, bool accepted, const std::
{
if (m_add_replay_on_join)
{
add_client->AddNewExpeditionLockout(
lockout.GetExpeditionName(), lockout.GetEventName(), lockout.GetDuration());
ExpeditionLockoutTimer replay_timer = lockout;
replay_timer.Reset();
add_client->AddExpeditionLockout(replay_timer, true);
}
}
else if (!lockout.IsExpired())
@ -1229,18 +1224,15 @@ void Expedition::ProcessMemberRemoved(std::string removed_char_name, uint32_t re
);
}
void Expedition::ProcessLockoutUpdate(
const std::string& event_name, uint64_t expire_time, uint32_t duration, bool remove)
void Expedition::ProcessLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove)
{
ExpeditionLockoutTimer lockout{ m_expedition_name, event_name, expire_time, duration };
if (!remove)
{
m_lockouts.emplace(event_name, lockout);
m_lockouts[lockout.GetEventName()] = lockout;
}
else
{
m_lockouts.erase(event_name);
m_lockouts.erase(lockout.GetEventName());
}
for (const auto& member : m_members)
@ -1254,7 +1246,7 @@ void Expedition::ProcessLockoutUpdate(
}
else
{
member_client->RemoveExpeditionLockout(m_expedition_name, event_name);
member_client->RemoveExpeditionLockout(m_expedition_name, lockout.GetEventName());
}
}
}
@ -1462,18 +1454,18 @@ void Expedition::SendWorldLeaderChanged()
}
void Expedition::SendWorldLockoutUpdate(
const std::string& event_name, uint64_t expire_time, uint32_t duration, bool remove)
const ExpeditionLockoutTimer& lockout, bool remove)
{
uint32_t pack_size = sizeof(ServerExpeditionLockout_Struct);
auto pack = std::unique_ptr<ServerPacket>(new ServerPacket(ServerOP_ExpeditionLockout, pack_size));
auto buf = reinterpret_cast<ServerExpeditionLockout_Struct*>(pack->pBuffer);
buf->expedition_id = GetID();
buf->expire_time = expire_time;
buf->duration = duration;
buf->expire_time = lockout.GetExpireTime();
buf->duration = lockout.GetDuration();
buf->sender_zone_id = zone ? zone->GetZoneID() : 0;
buf->sender_instance_id = zone ? zone->GetInstanceID() : 0;
buf->remove = remove;
strn0cpy(buf->event_name, event_name.c_str(), sizeof(buf->event_name));
strn0cpy(buf->event_name, lockout.GetEventName().c_str(), sizeof(buf->event_name));
worldserver.SendPacket(pack.get());
}
@ -1661,7 +1653,10 @@ void Expedition::HandleWorldMessage(ServerPacket* pack)
auto expedition = Expedition::FindCachedExpeditionByID(buf->expedition_id);
if (expedition)
{
expedition->ProcessLockoutUpdate(buf->event_name, buf->expire_time, buf->duration, buf->remove);
ExpeditionLockoutTimer lockout{
expedition->GetUUID(), expedition->GetName(), buf->event_name, buf->expire_time, buf->duration
};
expedition->ProcessLockoutUpdate(lockout, buf->remove);
}
}
break;

View File

@ -138,13 +138,12 @@ private:
static void CacheExpeditions(MySQLRequestResult& results);
static void SendWorldGetOnlineMembers(const std::vector<std::pair<uint32_t, uint32_t>>& expedition_character_ids);
void AddInternalLockout(ExpeditionLockoutTimer&& lockout_timer);
void AddInternalMember(const std::string& char_name, uint32_t char_id, ExpeditionMemberStatus status, bool is_current_member = true);
bool ChooseNewLeader();
bool ConfirmLeaderCommand(Client* requester);
bool ProcessAddConflicts(Client* leader_client, Client* add_client, bool swapping);
void ProcessLeaderChanged(uint32_t new_leader_id, const std::string& new_leader_name);
void ProcessLockoutUpdate(const std::string& event_name, uint64_t expire_time, uint32_t duration, bool remove);
void ProcessLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove);
void ProcessMakeLeader(Client* old_leader, Client* new_leader, const std::string& new_leader_name, bool is_online);
void ProcessMemberAdded(std::string added_char_name, uint32_t added_char_id);
void ProcessMemberRemoved(std::string removed_char_name, uint32_t removed_char_id);
@ -157,7 +156,7 @@ private:
void SendWorldExpeditionUpdate(uint16_t server_opcode);
void SendWorldAddPlayerInvite(const std::string& inviter_name, const std::string& swap_remove_name, const std::string& add_name, bool pending = false);
void SendWorldLeaderChanged();
void SendWorldLockoutUpdate(const std::string& event_name, uint64_t expire_time, uint32_t duration, bool remove = false);
void SendWorldLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove);
void SendWorldMakeLeaderRequest(const std::string& requester_name, const std::string& new_leader_name);
void SendWorldMemberChanged(const std::string& char_name, uint32_t char_id, bool remove);
void SendWorldMemberStatus(uint32_t character_id, ExpeditionMemberStatus status);

View File

@ -104,6 +104,7 @@ std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(ui
auto query = fmt::format(SQL(
SELECT
from_expedition_uuid,
expedition_name,
event_name,
UNIX_TIMESTAMP(expire_time),
@ -118,10 +119,11 @@ std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(ui
for (auto row = results.begin(); row != results.end(); ++row)
{
lockouts.emplace_back(ExpeditionLockoutTimer{
row[0], // expedition_name
row[1], // event_name
strtoull(row[2], nullptr, 10), // expire_time
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) // duration
row[0], // expedition_uuid
row[1], // expedition_name
row[2], // event_name
strtoull(row[3], nullptr, 10), // expire_time
static_cast<uint32_t>(strtoul(row[4], nullptr, 10)) // duration
});
}
}
@ -138,6 +140,7 @@ std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(
auto query = fmt::format(SQL(
SELECT
from_expedition_uuid,
event_name,
UNIX_TIMESTAMP(expire_time),
duration
@ -155,10 +158,11 @@ std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(
for (auto row = results.begin(); row != results.end(); ++row)
{
lockouts.emplace_back(ExpeditionLockoutTimer{
row[0], // expedition_uuid
expedition_name,
row[0], // event_name
strtoull(row[1], nullptr, 10), // expire_time
static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) // duration
row[1], // event_name
strtoull(row[2], nullptr, 10), // expire_time
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) // duration
});
}
}
@ -178,7 +182,7 @@ ExpeditionDatabase::LoadMultipleExpeditionLockouts(
fmt::format_to(std::back_inserter(in_expedition_ids_query), "{},", expedition_id);
}
// these are loaded into the same container type expedition's use to store lockouts
// 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())
@ -188,11 +192,11 @@ ExpeditionDatabase::LoadMultipleExpeditionLockouts(
std::string query = fmt::format(SQL(
SELECT
expedition_lockouts.expedition_id,
expedition_lockouts.from_expedition_uuid,
expedition_details.expedition_name,
expedition_lockouts.event_name,
UNIX_TIMESTAMP(expedition_lockouts.expire_time),
expedition_lockouts.duration,
expedition_lockouts.is_inherited,
expedition_details.expedition_name
expedition_lockouts.duration
FROM expedition_lockouts
INNER JOIN expedition_details ON expedition_lockouts.expedition_id = expedition_details.id
WHERE expedition_id IN ({})
@ -206,12 +210,12 @@ ExpeditionDatabase::LoadMultipleExpeditionLockouts(
for (auto row = results.begin(); row != results.end(); ++row)
{
auto expedition_id = strtoul(row[0], nullptr, 10);
lockouts[expedition_id].emplace(row[1], ExpeditionLockoutTimer{
row[5], // expedition_name
row[1], // event_name
strtoull(row[2], nullptr, 10), // expire_time
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)), // original duration
(strtoul(row[4], nullptr, 10) != 0) // is_inherited
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
});
}
}
@ -223,7 +227,7 @@ ExpeditionDatabase::LoadMultipleExpeditionLockouts(
MySQLRequestResult ExpeditionDatabase::LoadMembersForCreateRequest(
const std::vector<std::string>& character_names, const std::string& expedition_name)
{
LogExpeditionsDetail("Loading multiple characters data for [{}] request validation", expedition_name);
LogExpeditionsDetail("Loading multiple characters data for [{}] request", expedition_name);
std::string in_character_names_query;
for (const auto& character_name : character_names)
@ -243,6 +247,7 @@ MySQLRequestResult ExpeditionDatabase::LoadMembersForCreateRequest(
character_data.id,
character_data.name,
member.expedition_id,
lockout.from_expedition_uuid,
UNIX_TIMESTAMP(lockout.expire_time),
lockout.duration,
lockout.event_name
@ -299,7 +304,9 @@ void ExpeditionDatabase::DeleteAllCharacterLockouts(
void ExpeditionDatabase::DeleteCharacterLockout(
uint32_t character_id, const std::string& expedition_name, const std::string& event_name)
{
LogExpeditionsDetail("Deleting character [{}] lockout: [{}]:[{}]", character_id, expedition_name, event_name);
LogExpeditionsDetail(
"Deleting character [{}] lockout: [{}]:[{}]", character_id, expedition_name, event_name
);
auto query = fmt::format(SQL(
DELETE FROM expedition_character_lockouts
@ -466,7 +473,7 @@ ExpeditionMember ExpeditionDatabase::GetExpeditionLeader(uint32_t expedition_id)
void ExpeditionDatabase::InsertCharacterLockouts(
uint32_t character_id, const std::vector<ExpeditionLockoutTimer>& lockouts,
bool update_expire_times, bool is_pending)
bool replace_timer, bool is_pending)
{
LogExpeditionsDetail("Inserting character [{}] lockouts", character_id);
@ -474,10 +481,11 @@ void ExpeditionDatabase::InsertCharacterLockouts(
for (const auto& lockout : lockouts)
{
fmt::format_to(std::back_inserter(insert_values),
"({}, FROM_UNIXTIME({}), {}, '{}', '{}', {}),",
"({}, FROM_UNIXTIME({}), {}, '{}', '{}', '{}', {}),",
character_id,
lockout.GetExpireTime(),
lockout.GetDuration(),
lockout.GetExpeditionUUID(),
lockout.GetExpeditionName(),
lockout.GetEventName(),
is_pending
@ -489,15 +497,30 @@ void ExpeditionDatabase::InsertCharacterLockouts(
insert_values.pop_back(); // trailing comma
std::string on_duplicate;
if (update_expire_times) {
on_duplicate = "expire_time = VALUES(expire_time)";
} else {
if (replace_timer)
{
on_duplicate = SQL(
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = VALUES(expire_time),
duration = VALUES(duration)
);
}
else
{
on_duplicate = "character_id = VALUES(character_id)";
}
auto query = fmt::format(SQL(
INSERT INTO expedition_character_lockouts
(character_id, expire_time, duration, expedition_name, event_name, is_pending)
(
character_id,
expire_time,
duration,
from_expedition_uuid,
expedition_name,
event_name,
is_pending
)
VALUES {}
ON DUPLICATE KEY UPDATE {};
), insert_values, on_duplicate);
@ -518,10 +541,11 @@ void ExpeditionDatabase::InsertMembersLockout(
for (const auto& member : members)
{
fmt::format_to(std::back_inserter(insert_values),
"({}, FROM_UNIXTIME({}), {}, '{}', '{}'),",
"({}, FROM_UNIXTIME({}), {}, '{}', '{}', '{}'),",
member.char_id,
lockout.GetExpireTime(),
lockout.GetDuration(),
lockout.GetExpeditionUUID(),
lockout.GetExpeditionName(),
lockout.GetEventName()
);
@ -533,9 +557,12 @@ void ExpeditionDatabase::InsertMembersLockout(
auto query = fmt::format(SQL(
INSERT INTO expedition_character_lockouts
(character_id, expire_time, duration, expedition_name, event_name)
(character_id, expire_time, duration, from_expedition_uuid, expedition_name, event_name)
VALUES {}
ON DUPLICATE KEY UPDATE expire_time = VALUES(expire_time);
ON DUPLICATE KEY UPDATE
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = VALUES(expire_time),
duration = VALUES(duration);
), insert_values);
database.QueryDatabase(query);
@ -552,11 +579,20 @@ void ExpeditionDatabase::InsertLockout(
auto query = fmt::format(SQL(
INSERT INTO expedition_lockouts
(expedition_id, event_name, expire_time, duration, is_inherited)
(expedition_id, from_expedition_uuid, event_name, expire_time, duration)
VALUES
({}, '{}', FROM_UNIXTIME({}), {}, FALSE)
ON DUPLICATE KEY UPDATE expire_time = VALUES(expire_time);
), expedition_id, lockout.GetEventName(), lockout.GetExpireTime(), lockout.GetDuration());
({}, '{}', '{}', FROM_UNIXTIME({}), {})
ON DUPLICATE KEY UPDATE
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = VALUES(expire_time),
duration = VALUES(duration);
),
expedition_id,
lockout.GetExpeditionUUID(),
lockout.GetEventName(),
lockout.GetExpireTime(),
lockout.GetDuration()
);
database.QueryDatabase(query);
}
@ -570,12 +606,12 @@ void ExpeditionDatabase::InsertLockouts(
for (const auto& lockout : lockouts)
{
fmt::format_to(std::back_inserter(insert_values),
"({}, '{}', FROM_UNIXTIME({}), {}, {}),",
"({}, '{}', '{}', FROM_UNIXTIME({}), {}),",
expedition_id,
lockout.second.GetExpeditionUUID(),
lockout.second.GetEventName(),
lockout.second.GetExpireTime(),
lockout.second.GetDuration(),
lockout.second.IsInherited()
lockout.second.GetDuration()
);
}
@ -585,9 +621,12 @@ void ExpeditionDatabase::InsertLockouts(
auto query = fmt::format(SQL(
INSERT INTO expedition_lockouts
(expedition_id, event_name, expire_time, duration, is_inherited)
(expedition_id, from_expedition_uuid, event_name, expire_time, duration)
VALUES {}
ON DUPLICATE KEY UPDATE expire_time = VALUES(expire_time);
ON DUPLICATE KEY UPDATE
from_expedition_uuid = VALUES(from_expedition_uuid),
expire_time = VALUES(expire_time),
duration = VALUES(duration);
), insert_values);
database.QueryDatabase(query);

View File

@ -61,7 +61,7 @@ namespace ExpeditionDatabase
ExpeditionMember GetExpeditionLeader(uint32_t expedition_id);
void InsertCharacterLockouts(
uint32_t character_id, const std::vector<ExpeditionLockoutTimer>& lockouts,
bool update_expire_times, bool is_pending = false);
bool replace_timer, bool is_pending = false);
void InsertMembersLockout(const std::vector<ExpeditionMember>& members, const ExpeditionLockoutTimer& lockout);
void InsertLockout(uint32_t expedition_id, const ExpeditionLockoutTimer& lockout);
void InsertLockouts(uint32_t expedition_id, const std::unordered_map<std::string, ExpeditionLockoutTimer>& lockouts);

View File

@ -26,14 +26,14 @@
const char* const DZ_REPLAY_TIMER_NAME = "Replay Timer"; // see December 14, 2016 patch notes
ExpeditionLockoutTimer::ExpeditionLockoutTimer(
std::string expedition_name, std::string event_name,
uint64_t expire_time, uint32_t duration, bool inherited
const std::string& expedition_uuid, const std::string& expedition_name,
const std::string& event_name, uint64_t expire_time, uint32_t duration
) :
m_expedition_uuid(expedition_uuid),
m_expedition_name(expedition_name),
m_event_name(event_name),
m_expire_time(std::chrono::system_clock::from_time_t(expire_time)),
m_duration(duration),
m_is_inherited(inherited)
m_duration(duration)
{
if (event_name == DZ_REPLAY_TIMER_NAME)
{

View File

@ -29,10 +29,10 @@ extern const char* const DZ_REPLAY_TIMER_NAME;
class ExpeditionLockoutTimer
{
public:
ExpeditionLockoutTimer() {}
ExpeditionLockoutTimer() = default;
ExpeditionLockoutTimer(
std::string expedition_name, std::string event_name,
uint64_t expire_time, uint32_t duration, bool inherited = false);
const std::string& expedition_uuid, const std::string& expedition_name,
const std::string& event_name, uint64_t expire_time, uint32_t duration);
struct DaysHoursMinutes
{
@ -46,20 +46,20 @@ public:
uint32_t GetSecondsRemaining() const;
DaysHoursMinutes GetDaysHoursMinutesRemaining() const;
const std::string& GetExpeditionName() const { return m_expedition_name; }
const std::string& GetExpeditionUUID() const { return m_expedition_uuid; }
const std::string& GetEventName() const { return m_event_name; }
void SetExpireTime(uint64_t expire_time) { m_expire_time = std::chrono::system_clock::from_time_t(expire_time); }
void SetInherited(bool is_inherited) { m_is_inherited = is_inherited; }
bool IsExpired() const { return GetSecondsRemaining() == 0; }
bool IsInherited() const { return m_is_inherited; }
bool IsFromExpedition(const std::string& uuid) const { return uuid == m_expedition_uuid; }
bool IsReplayTimer() const { return m_is_replay_timer; }
bool IsSameLockout(const ExpeditionLockoutTimer& compare_lockout) const;
bool IsSameLockout(const std::string& expedition_name, const std::string& event_name) const;
void Reset() { m_expire_time = std::chrono::system_clock::now() + m_duration; }
private:
bool m_is_replay_timer = false;
std::string m_expedition_uuid; // expedition received in
std::string m_expedition_name;
std::string m_event_name;
bool m_is_inherited = false; // inherited from expedition leader
bool m_is_replay_timer = false;
std::chrono::seconds m_duration;
std::chrono::time_point<std::chrono::system_clock> m_expire_time;
};

View File

@ -166,8 +166,6 @@ bool ExpeditionRequest::LoadLeaderLockouts()
for (auto& lockout : lockouts)
{
lockout.SetInherited(true);
// client window hides timers with less than 60s remaining, optionally count them as expired
if (lockout.GetSecondsRemaining() <= leeway_seconds)
{
@ -243,12 +241,12 @@ bool ExpeditionRequest::CheckMembersForConflicts(const std::vector<std::string>&
last_character_id = character_id;
// compare member lockouts with leader lockouts
if (row[3] && row[4] && row[5])
if (row[3] && row[4] && row[5] && row[6])
{
auto expire_time = strtoull(row[3], nullptr, 10);
auto duration = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
auto expire_time = strtoull(row[4], nullptr, 10);
auto duration = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
ExpeditionLockoutTimer lockout{m_expedition_name, row[5], expire_time, duration};
ExpeditionLockoutTimer lockout{row[3], m_expedition_name, row[6], expire_time, duration};
// client window hides timers with less than 60s remaining, optionally count them as expired
if (lockout.GetSecondsRemaining() <= leeway_seconds)

View File

@ -1768,11 +1768,27 @@ luabind::object Lua_Client::GetExpeditionLockouts(lua_State* L, std::string expe
return lua_table;
}
std::string Lua_Client::GetLockoutExpeditionUUID(std::string expedition_name, std::string event_name) {
Lua_Safe_Call_String();
std::string uuid;
auto lockout = self->GetExpeditionLockout(expedition_name, event_name);
if (lockout)
{
uuid = lockout->GetExpeditionUUID();
}
return uuid;
}
void Lua_Client::AddExpeditionLockout(std::string expedition_name, std::string event_name, uint32 seconds) {
Lua_Safe_Call_Void();
self->AddNewExpeditionLockout(expedition_name, event_name, seconds);
}
void Lua_Client::AddExpeditionLockout(std::string expedition_name, std::string event_name, uint32 seconds, std::string uuid) {
Lua_Safe_Call_Void();
self->AddNewExpeditionLockout(expedition_name, event_name, seconds, uuid);
}
void Lua_Client::RemoveAllExpeditionLockouts() {
Lua_Safe_Call_Void();
self->RemoveAllExpeditionLockouts();
@ -2116,7 +2132,9 @@ luabind::scope lua_register_client() {
.def("GetExpedition", (Lua_Expedition(Lua_Client::*)(void))&Lua_Client::GetExpedition)
.def("GetExpeditionLockouts", (luabind::object(Lua_Client::*)(lua_State* L))&Lua_Client::GetExpeditionLockouts)
.def("GetExpeditionLockouts", (luabind::object(Lua_Client::*)(lua_State* L, std::string))&Lua_Client::GetExpeditionLockouts)
.def("GetLockoutExpeditionUUID", (std::string(Lua_Client::*)(std::string, std::string))&Lua_Client::GetLockoutExpeditionUUID)
.def("AddExpeditionLockout", (void(Lua_Client::*)(std::string, std::string, uint32))&Lua_Client::AddExpeditionLockout)
.def("AddExpeditionLockout", (void(Lua_Client::*)(std::string, std::string, uint32, std::string))&Lua_Client::AddExpeditionLockout)
.def("RemoveAllExpeditionLockouts", (void(Lua_Client::*)(void))&Lua_Client::RemoveAllExpeditionLockouts)
.def("RemoveAllExpeditionLockouts", (void(Lua_Client::*)(std::string))&Lua_Client::RemoveAllExpeditionLockouts)
.def("RemoveExpeditionLockout", (void(Lua_Client::*)(std::string, std::string))&Lua_Client::RemoveExpeditionLockout)

View File

@ -345,7 +345,9 @@ public:
Lua_Expedition GetExpedition();
luabind::object GetExpeditionLockouts(lua_State* L);
luabind::object GetExpeditionLockouts(lua_State* L, std::string expedition_name);
std::string GetLockoutExpeditionUUID(std::string expedition_name, std::string event_name);
void AddExpeditionLockout(std::string expedition_name, std::string event_name, uint32 seconds);
void AddExpeditionLockout(std::string expedition_name, std::string event_name, uint32 seconds, std::string uuid);
void RemoveAllExpeditionLockouts();
void RemoveAllExpeditionLockouts(std::string expedition_name);
void RemoveExpeditionLockout(std::string expedition_name, std::string event_name);