From fa21d835d9bb643f595789b262929a81c9b0bf3d Mon Sep 17 00:00:00 2001 From: hg <4683435+hgtw@users.noreply.github.com> Date: Wed, 10 Jun 2020 23:00:34 -0400 Subject: [PATCH] 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 --- utils/sql/git/required/wip_expeditions.sql | 4 +- zone/client.cpp | 35 ++++--- zone/client.h | 3 +- zone/expedition.cpp | 55 +++++----- zone/expedition.h | 5 +- zone/expedition_database.cpp | 113 ++++++++++++++------- zone/expedition_database.h | 2 +- zone/expedition_lockout_timer.cpp | 8 +- zone/expedition_lockout_timer.h | 16 +-- zone/expedition_request.cpp | 10 +- zone/lua_client.cpp | 18 ++++ zone/lua_client.h | 2 + 12 files changed, 163 insertions(+), 108 deletions(-) diff --git a/utils/sql/git/required/wip_expeditions.sql b/utils/sql/git/required/wip_expeditions.sql index 463e5d59e..e69fca8d6 100644 --- a/utils/sql/git/required/wip_expeditions.sql +++ b/utils/sql/git/required/wip_expeditions.sql @@ -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 ; diff --git a/zone/client.cpp b/zone/client.cpp index 57063efff..b502c4381 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -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(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() ); } diff --git a/zone/client.h b/zone/client.h index 239ad72c8..f55b9502f 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1118,7 +1118,8 @@ public: uint32_t string_id, const std::initializer_list& 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, diff --git a/zone/expedition.cpp b/zone/expedition.cpp index ee0c1339c..1f15d18e7 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -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(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(new ServerPacket(ServerOP_ExpeditionLockout, pack_size)); auto buf = reinterpret_cast(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; diff --git a/zone/expedition.h b/zone/expedition.h index cc674a5cd..2dfa46f3c 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -138,13 +138,12 @@ private: static void CacheExpeditions(MySQLRequestResult& results); static void SendWorldGetOnlineMembers(const std::vector>& 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); diff --git a/zone/expedition_database.cpp b/zone/expedition_database.cpp index 5ebf33b67..18d952e4a 100644 --- a/zone/expedition_database.cpp +++ b/zone/expedition_database.cpp @@ -104,6 +104,7 @@ std::vector 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 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(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(strtoul(row[4], nullptr, 10)) // duration }); } } @@ -138,6 +140,7 @@ std::vector ExpeditionDatabase::LoadCharacterLockouts( auto query = fmt::format(SQL( SELECT + from_expedition_uuid, event_name, UNIX_TIMESTAMP(expire_time), duration @@ -155,10 +158,11 @@ std::vector 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(strtoul(row[2], nullptr, 10)) // duration + row[1], // event_name + strtoull(row[2], nullptr, 10), // expire_time + static_cast(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> 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(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(strtoul(row[5], nullptr, 10)) // original duration }); } } @@ -223,7 +227,7 @@ ExpeditionDatabase::LoadMultipleExpeditionLockouts( MySQLRequestResult ExpeditionDatabase::LoadMembersForCreateRequest( const std::vector& 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& 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); diff --git a/zone/expedition_database.h b/zone/expedition_database.h index 14bc34f1c..66aee8852 100644 --- a/zone/expedition_database.h +++ b/zone/expedition_database.h @@ -61,7 +61,7 @@ namespace ExpeditionDatabase ExpeditionMember GetExpeditionLeader(uint32_t expedition_id); void InsertCharacterLockouts( uint32_t character_id, const std::vector& lockouts, - bool update_expire_times, bool is_pending = false); + bool replace_timer, bool is_pending = false); void InsertMembersLockout(const std::vector& members, const ExpeditionLockoutTimer& lockout); void InsertLockout(uint32_t expedition_id, const ExpeditionLockoutTimer& lockout); void InsertLockouts(uint32_t expedition_id, const std::unordered_map& lockouts); diff --git a/zone/expedition_lockout_timer.cpp b/zone/expedition_lockout_timer.cpp index 25743df8d..01b1e607a 100644 --- a/zone/expedition_lockout_timer.cpp +++ b/zone/expedition_lockout_timer.cpp @@ -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) { diff --git a/zone/expedition_lockout_timer.h b/zone/expedition_lockout_timer.h index abd455ff5..af3042b0c 100644 --- a/zone/expedition_lockout_timer.h +++ b/zone/expedition_lockout_timer.h @@ -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 m_expire_time; }; diff --git a/zone/expedition_request.cpp b/zone/expedition_request.cpp index 63b14c131..2e7f77582 100644 --- a/zone/expedition_request.cpp +++ b/zone/expedition_request.cpp @@ -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& 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(strtoul(row[4], nullptr, 10)); + auto expire_time = strtoull(row[4], nullptr, 10); + auto duration = static_cast(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) diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index f4211b84f..bf896e32d 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -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) diff --git a/zone/lua_client.h b/zone/lua_client.h index bdcd04cc5..f66504616 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -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);