diff --git a/utils/sql/git/required/wip_expeditions.sql b/utils/sql/git/required/wip_expeditions.sql index e69fca8d6..27ca3f5ae 100644 --- a/utils/sql/git/required/wip_expeditions.sql +++ b/utils/sql/git/required/wip_expeditions.sql @@ -35,7 +35,6 @@ CREATE TABLE `expedition_members` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `expedition_id` INT(10) UNSIGNED NOT NULL DEFAULT 0, `character_id` INT(10) UNSIGNED NOT NULL DEFAULT 0, - `is_current_member` TINYINT(4) UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE INDEX `expedition_id_character_id` (`expedition_id`, `character_id`), CONSTRAINT `FK_expedition_members_expedition_details` FOREIGN KEY (`expedition_id`) REFERENCES `expedition_details` (`id`) ON DELETE CASCADE diff --git a/world/expedition.cpp b/world/expedition.cpp index 74cea7c36..98675a7c9 100644 --- a/world/expedition.cpp +++ b/world/expedition.cpp @@ -205,20 +205,19 @@ void ExpeditionCache::Process() void ExpeditionDatabase::PurgeExpiredExpeditions() { - LogExpeditionsDetail("Purging expired expeditions"); - std::string query = SQL( - DELETE expedition FROM expedition_details expedition + DELETE expedition + FROM expedition_details expedition LEFT JOIN instance_list ON expedition.instance_id = instance_list.id LEFT JOIN ( - SELECT expedition_id, COUNT(IF(is_current_member = TRUE, 1, NULL)) member_count + SELECT expedition_id, COUNT(*) member_count FROM expedition_members GROUP BY expedition_id ) AS expedition_members ON expedition_members.expedition_id = expedition.id WHERE expedition.instance_id IS NULL - OR expedition_members.member_count = 0 + OR expedition_members.member_count IS NULL OR (instance_list.start_time + instance_list.duration) <= UNIX_TIMESTAMP(); ); @@ -227,8 +226,6 @@ void ExpeditionDatabase::PurgeExpiredExpeditions() void ExpeditionDatabase::PurgeExpiredCharacterLockouts() { - LogExpeditionsDetail("Purging expired lockouts"); - std::string query = SQL( DELETE FROM expedition_character_lockouts WHERE expire_time <= NOW(); @@ -239,8 +236,6 @@ void ExpeditionDatabase::PurgeExpiredCharacterLockouts() std::vector ExpeditionDatabase::LoadExpeditions() { - LogExpeditionsDetail("Loading expeditions for world cache"); - std::vector expeditions; std::string query = SQL( @@ -253,9 +248,7 @@ std::vector ExpeditionDatabase::LoadExpeditions() expedition_members.character_id FROM expedition_details INNER JOIN instance_list ON expedition_details.instance_id = instance_list.id - INNER JOIN expedition_members - ON expedition_members.expedition_id = expedition_details.id - AND expedition_members.is_current_member = TRUE + INNER JOIN expedition_members ON expedition_members.expedition_id = expedition_details.id ORDER BY expedition_details.id; ); @@ -305,9 +298,7 @@ Expedition ExpeditionDatabase::LoadExpedition(uint32_t expedition_id) expedition_members.character_id FROM expedition_details INNER JOIN instance_list ON expedition_details.instance_id = instance_list.id - INNER JOIN expedition_members - ON expedition_members.expedition_id = expedition_details.id - AND expedition_members.is_current_member = TRUE + INNER JOIN expedition_members ON expedition_members.expedition_id = expedition_details.id WHERE expedition_details.id = {}; ), expedition_id); diff --git a/zone/dynamiczone.cpp b/zone/dynamiczone.cpp index afa5fc7b7..0a7bad7e7 100644 --- a/zone/dynamiczone.cpp +++ b/zone/dynamiczone.cpp @@ -427,7 +427,7 @@ void DynamicZone::RemoveAllCharacters(bool enable_removal_timers) database.RemoveClientsFromInstance(GetInstanceID()); } -void DynamicZone::SaveInstanceMembersToDatabase(const std::unordered_set& character_ids) +void DynamicZone::SaveInstanceMembersToDatabase(const std::vector& character_ids) { LogDynamicZonesDetail("Saving [{}] instance members to database", character_ids.size()); diff --git a/zone/dynamiczone.h b/zone/dynamiczone.h index 6951fe517..b1f56031e 100644 --- a/zone/dynamiczone.h +++ b/zone/dynamiczone.h @@ -25,7 +25,6 @@ #include #include #include -#include #include class MySQLRequestRow; @@ -75,7 +74,7 @@ public: uint32_t CreateInstance(); void AddCharacter(uint32_t character_id); - void SaveInstanceMembersToDatabase(const std::unordered_set& character_ids); + void SaveInstanceMembersToDatabase(const std::vector& character_ids); uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); } uint16_t GetInstanceID() const { return static_cast(m_instance_id); }; diff --git a/zone/expedition.cpp b/zone/expedition.cpp index 60a699293..3ad0ed113 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -212,9 +212,8 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) if (current_expedition) { auto member_id = strtoul(row[col::member_id], nullptr, 10); - bool is_current_member = (strtoul(row[col::is_current_member], nullptr, 10) != 0); current_expedition->AddInternalMember( - row[col::member_name], member_id, ExpeditionMemberStatus::Offline, is_current_member + row[col::member_name], member_id, ExpeditionMemberStatus::Offline ); expedition_character_ids.emplace_back(std::make_pair(expedition_id, member_id)); } @@ -309,14 +308,16 @@ void Expedition::SaveLockouts(ExpeditionRequest& request) void Expedition::SaveMembers(ExpeditionRequest& request) { m_members = request.GetMembers(); + + std::vector member_ids; for (const auto& member : m_members) { - m_member_id_history.emplace(member.char_id); + member_ids.emplace_back(member.char_id); } ExpeditionDatabase::InsertMembers(m_id, m_members); ExpeditionDatabase::DeleteAllMembersPendingLockouts(m_members); - m_dynamiczone.SaveInstanceMembersToDatabase(m_member_id_history); // all are current members here + m_dynamiczone.SaveInstanceMembersToDatabase(member_ids); } Expedition* Expedition::FindCachedExpeditionByCharacterID(uint32_t character_id) @@ -465,22 +466,17 @@ void Expedition::RemoveLockout(const std::string& event_name) } void Expedition::AddInternalMember( - const std::string& char_name, uint32_t character_id, ExpeditionMemberStatus status, bool is_current_member) + const std::string& char_name, uint32_t character_id, ExpeditionMemberStatus status) { - if (is_current_member) + 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()) { - 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(ExpeditionMember{character_id, char_name, status}); - } + m_members.emplace_back(ExpeditionMember{character_id, char_name, status}); } - - m_member_id_history.emplace(character_id); } bool Expedition::AddMember(const std::string& add_char_name, uint32_t add_char_id) @@ -504,7 +500,7 @@ void Expedition::RemoveAllMembers(bool enable_removal_timers) m_dynamiczone.RemoveAllCharacters(enable_removal_timers); ExpeditionDatabase::DeleteAllMembersPendingLockouts(m_members); - ExpeditionDatabase::UpdateAllMembersRemoved(m_id); + ExpeditionDatabase::DeleteAllMembers(m_id); SendUpdatesToZoneMembers(true); SendWorldExpeditionUpdate(ServerOP_ExpeditionMembersRemoved); @@ -520,7 +516,7 @@ bool Expedition::RemoveMember(const std::string& remove_char_name) return false; } - ExpeditionDatabase::UpdateMemberRemoved(m_id, member.char_id); + ExpeditionDatabase::DeleteMember(m_id, member.char_id); m_dynamiczone.RemoveCharacter(member.char_id); ProcessMemberRemoved(member.name, member.char_id); @@ -549,7 +545,7 @@ void Expedition::SwapMember(Client* add_client, const std::string& remove_char_n } // make remove and add atomic to avoid racing with separate world messages - ExpeditionDatabase::UpdateMemberRemoved(m_id, member.char_id); + ExpeditionDatabase::DeleteMember(m_id, member.char_id); ExpeditionDatabase::InsertMember(m_id, add_client->CharacterID()); m_dynamiczone.RemoveCharacter(member.char_id); m_dynamiczone.AddCharacter(add_client->CharacterID()); diff --git a/zone/expedition.h b/zone/expedition.h index 2dfa46f3c..cbd8fe896 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -27,7 +27,6 @@ #include #include #include -#include #include class Client; @@ -138,7 +137,7 @@ private: static void CacheExpeditions(MySQLRequestResult& results); static void SendWorldGetOnlineMembers(const std::vector>& expedition_character_ids); - void AddInternalMember(const std::string& char_name, uint32_t char_id, ExpeditionMemberStatus status, bool is_current_member = true); + void AddInternalMember(const std::string& char_name, uint32_t char_id, ExpeditionMemberStatus status); bool ChooseNewLeader(); bool ConfirmLeaderCommand(Client* requester); bool ProcessAddConflicts(Client* leader_client, Client* add_client, bool swapping); @@ -183,8 +182,7 @@ private: std::string m_expedition_name; DynamicZone m_dynamiczone { DynamicZoneType::Expedition }; ExpeditionMember m_leader; - std::vector m_members; // current members - std::unordered_set m_member_id_history; // track past members to allow invites for replay timer bypass + std::vector m_members; std::unordered_map m_lockouts; }; diff --git a/zone/expedition_database.cpp b/zone/expedition_database.cpp index 00c7b6418..d69e36263 100644 --- a/zone/expedition_database.cpp +++ b/zone/expedition_database.cpp @@ -65,7 +65,6 @@ std::string ExpeditionDatabase::LoadExpeditionsSelectQuery() expedition_details.is_locked, character_data.name leader_name, expedition_members.character_id, - expedition_members.is_current_member, member_data.name FROM expedition_details INNER JOIN character_data ON expedition_details.leader_id = character_data.id @@ -259,9 +258,7 @@ MySQLRequestResult ExpeditionDatabase::LoadMembersForCreateRequest( AND lockout.is_pending = FALSE AND lockout.expire_time > NOW() AND lockout.expedition_name = '{}' - LEFT JOIN expedition_members member - ON character_data.id = member.character_id - AND member.is_current_member = TRUE + LEFT JOIN expedition_members member ON character_data.id = member.character_id WHERE character_data.name IN ({}) ORDER BY character_data.id; ), expedition_name, in_character_names_query); @@ -420,8 +417,7 @@ uint32_t ExpeditionDatabase::GetExpeditionIDFromCharacterID(uint32_t character_i uint32_t expedition_id = 0; auto query = fmt::format(SQL( - SELECT expedition_id FROM expedition_members - WHERE character_id = {} AND is_current_member = TRUE; + SELECT expedition_id FROM expedition_members WHERE character_id = {}; ), character_id); auto results = database.QueryDatabase(query); @@ -641,10 +637,10 @@ void ExpeditionDatabase::InsertMember(uint32_t expedition_id, uint32_t character auto query = fmt::format(SQL( INSERT INTO expedition_members - (expedition_id, character_id, is_current_member) + (expedition_id, character_id) VALUES - ({}, {}, TRUE) - ON DUPLICATE KEY UPDATE is_current_member = TRUE; + ({}, {}) + ON DUPLICATE KEY UPDATE character_id = VALUES(character_id); ), expedition_id, character_id); database.QueryDatabase(query); @@ -659,7 +655,7 @@ void ExpeditionDatabase::InsertMembers( for (const auto& member : members) { fmt::format_to(std::back_inserter(insert_values), - "({}, {}, TRUE),", + "({}, {}),", expedition_id, member.char_id ); } @@ -669,7 +665,8 @@ void ExpeditionDatabase::InsertMembers( insert_values.pop_back(); // trailing comma auto query = fmt::format(SQL( - INSERT INTO expedition_members (expedition_id, character_id, is_current_member) + INSERT INTO expedition_members + (expedition_id, character_id) VALUES {}; ), insert_values); @@ -699,25 +696,23 @@ void ExpeditionDatabase::UpdateLockState(uint32_t expedition_id, bool is_locked) database.QueryDatabase(query); } -void ExpeditionDatabase::UpdateMemberRemoved(uint32_t expedition_id, uint32_t character_id) +void ExpeditionDatabase::DeleteMember(uint32_t expedition_id, uint32_t character_id) { LogExpeditionsDetail("Removing member [{}] from expedition [{}]", character_id, expedition_id); auto query = fmt::format(SQL( - UPDATE expedition_members SET is_current_member = FALSE - WHERE expedition_id = {} AND character_id = {}; + DELETE FROM expedition_members WHERE expedition_id = {} AND character_id = {}; ), expedition_id, character_id); database.QueryDatabase(query); } -void ExpeditionDatabase::UpdateAllMembersRemoved(uint32_t expedition_id) +void ExpeditionDatabase::DeleteAllMembers(uint32_t expedition_id) { LogExpeditionsDetail("Updating all members of expedition [{}] as removed", expedition_id); auto query = fmt::format(SQL( - UPDATE expedition_members SET is_current_member = FALSE - WHERE expedition_id = {}; + DELETE FROM expedition_members WHERE expedition_id = {}; ), expedition_id); database.QueryDatabase(query); diff --git a/zone/expedition_database.h b/zone/expedition_database.h index 66aee8852..a3c283351 100644 --- a/zone/expedition_database.h +++ b/zone/expedition_database.h @@ -47,6 +47,8 @@ namespace ExpeditionDatabase std::vector LoadCharacterLockouts(uint32_t character_id, const std::string& expedition_name); std::unordered_map> LoadMultipleExpeditionLockouts(const std::vector& expedition_ids); + void DeleteAllMembers(uint32_t expedition_id); + void DeleteMember(uint32_t expedition_id, uint32_t character_id); void DeleteAllCharacterLockouts(uint32_t character_id); void DeleteAllCharacterLockouts(uint32_t character_id, const std::string& expedition_name); void DeleteCharacterLockout(uint32_t character_id, const std::string& expedition_name, const std::string& event_name); @@ -69,8 +71,6 @@ namespace ExpeditionDatabase void InsertMembers(uint32_t expedition_id, const std::vector& members); void UpdateLeaderID(uint32_t expedition_id, uint32_t leader_id); void UpdateLockState(uint32_t expedition_id, bool is_locked); - void UpdateMemberRemoved(uint32_t expedition_id, uint32_t character_id); - void UpdateAllMembersRemoved(uint32_t expedition_id); void UpdateReplayLockoutOnJoin(uint32_t expedition_id, bool add_on_join); }; @@ -89,7 +89,6 @@ namespace LoadExpeditionColumns is_locked, leader_name, member_id, - is_current_member, member_name }; };