From 8b2b2db8486ef244c4d1f1b3645cb9797a3c6480 Mon Sep 17 00:00:00 2001 From: hg <4683435+hgtw@users.noreply.github.com> Date: Mon, 9 Nov 2020 20:09:16 -0500 Subject: [PATCH] Move offline players to dz safereturn This is an experimental change which allows members to log in at the safe return if they were offline when the expedition was deleted. Prior to this they would log in at bind instead Partially reverts commit 32c69d235d7fc8b816fa598b499be47d451ddba5 Removed expedition members are no longer hard deleted from db --- utils/sql/git/required/wip_expeditions.sql | 1 + world/expedition_database.cpp | 37 ++++++++++++++++++++-- world/expedition_database.h | 1 + world/expedition_state.cpp | 1 + world/main.cpp | 8 ++--- zone/expedition_database.cpp | 20 ++++++++---- 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/utils/sql/git/required/wip_expeditions.sql b/utils/sql/git/required/wip_expeditions.sql index 5524a2919..a51d07095 100644 --- a/utils/sql/git/required/wip_expeditions.sql +++ b/utils/sql/git/required/wip_expeditions.sql @@ -33,6 +33,7 @@ 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(3) UNSIGNED NOT NULL DEFAULT 1, PRIMARY KEY (`id`), UNIQUE INDEX `expedition_id_character_id` (`expedition_id`, `character_id`) ) diff --git a/world/expedition_database.cpp b/world/expedition_database.cpp index e3755befb..f9df67918 100644 --- a/world/expedition_database.cpp +++ b/world/expedition_database.cpp @@ -32,7 +32,7 @@ void ExpeditionDatabase::PurgeExpiredExpeditions() LEFT JOIN instance_list ON dynamic_zones.instance_id = instance_list.id LEFT JOIN ( - SELECT expedition_id, COUNT(*) member_count + SELECT expedition_id, COUNT(IF(is_current_member = TRUE, 1, NULL)) member_count FROM expedition_members GROUP BY expedition_id ) expedition_members @@ -40,6 +40,7 @@ void ExpeditionDatabase::PurgeExpiredExpeditions() WHERE instance_list.id IS NULL OR expedition_members.member_count IS NULL + OR expedition_members.member_count = 0 OR (instance_list.start_time + instance_list.duration) <= UNIX_TIMESTAMP(); ); @@ -51,7 +52,12 @@ void ExpeditionDatabase::PurgeExpiredExpeditions() { expedition_ids.emplace_back(static_cast(strtoul(row[0], nullptr, 10))); } - ExpeditionDatabase::DeleteExpeditions(expedition_ids); + + if (!expedition_ids.empty()) + { + ExpeditionDatabase::MoveMembersToSafeReturn(expedition_ids); + ExpeditionDatabase::DeleteExpeditions(expedition_ids); + } } } @@ -83,6 +89,7 @@ std::vector ExpeditionDatabase::LoadExpeditions(uint32_t select_expe 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) @@ -180,3 +187,29 @@ void ExpeditionDatabase::UpdateLeaderID(uint32_t expedition_id, uint32_t leader_ database.QueryDatabase(query); } + +void ExpeditionDatabase::MoveMembersToSafeReturn(const std::vector& expedition_ids) +{ + LogExpeditionsDetail("Moving members from [{}] expedition(s) to safereturn", expedition_ids.size()); + + // only offline members still in expired dz zones should be updated here + std::string query = fmt::format(SQL( + UPDATE character_data + INNER JOIN expedition_members ON character_data.id = expedition_members.character_id + INNER JOIN expeditions ON expedition_members.expedition_id = expeditions.id + INNER JOIN dynamic_zones ON expeditions.dynamic_zone_id = dynamic_zones.id + INNER JOIN instance_list ON dynamic_zones.instance_id = instance_list.id + AND character_data.zone_instance = instance_list.id + AND character_data.zone_id = instance_list.zone + SET + zone_id = IF(safe_return_zone_id > 0, safe_return_zone_id, zone_id), + zone_instance = IF(safe_return_zone_id > 0, 0, zone_instance), + x = IF(safe_return_zone_id > 0, safe_return_x, x), + y = IF(safe_return_zone_id > 0, safe_return_y, y), + z = IF(safe_return_zone_id > 0, safe_return_z, z), + heading = IF(safe_return_zone_id > 0, safe_return_heading, heading) + WHERE expeditions.id IN ({}); + ), fmt::join(expedition_ids, ",")); + + database.QueryDatabase(query); +} diff --git a/world/expedition_database.h b/world/expedition_database.h index 302dba3e2..16341210c 100644 --- a/world/expedition_database.h +++ b/world/expedition_database.h @@ -31,6 +31,7 @@ namespace ExpeditionDatabase void DeleteExpeditions(const std::vector& expedition_ids); std::vector LoadExpeditions(uint32_t select_expedition_id = 0); Expedition LoadExpedition(uint32_t expedition_id); + void MoveMembersToSafeReturn(const std::vector& expedition_ids); void PurgeExpiredExpeditions(); void PurgeExpiredCharacterLockouts(); void UpdateDzDuration(uint16_t instance_id, uint32_t new_duration); diff --git a/world/expedition_state.cpp b/world/expedition_state.cpp index df09a5f2f..332231f1b 100644 --- a/world/expedition_state.cpp +++ b/world/expedition_state.cpp @@ -152,6 +152,7 @@ void ExpeditionState::Process() if (!expedition_ids.empty()) { + ExpeditionDatabase::MoveMembersToSafeReturn(expedition_ids); ExpeditionDatabase::DeleteExpeditions(expedition_ids); } } diff --git a/world/main.cpp b/world/main.cpp index 01682b26a..b426d13ff 100644 --- a/world/main.cpp +++ b/world/main.cpp @@ -425,16 +425,16 @@ int main(int argc, char** argv) { adventure_manager.LoadLeaderboardInfo(); + LogInfo("Purging expired expeditions"); + ExpeditionDatabase::PurgeExpiredExpeditions(); + ExpeditionDatabase::PurgeExpiredCharacterLockouts(); + LogInfo("Purging expired instances"); database.PurgeExpiredInstances(); Timer PurgeInstanceTimer(450000); PurgeInstanceTimer.Start(450000); - LogInfo("Purging expired expeditions"); - ExpeditionDatabase::PurgeExpiredExpeditions(); - ExpeditionDatabase::PurgeExpiredCharacterLockouts(); - LogInfo("Loading active expeditions"); expedition_state.LoadActiveExpeditions(); diff --git a/zone/expedition_database.cpp b/zone/expedition_database.cpp index 69a1ebfa7..7d1fd7a3c 100644 --- a/zone/expedition_database.cpp +++ b/zone/expedition_database.cpp @@ -70,6 +70,7 @@ std::string ExpeditionDatabase::LoadExpeditionsSelectQuery() 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 )); } @@ -251,7 +252,9 @@ MySQLRequestResult ExpeditionDatabase::LoadMembersForCreateRequest( ON character_data.id = lockout.character_id AND lockout.expire_time > NOW() AND lockout.expedition_name = '{}' - LEFT JOIN expedition_members member ON character_data.id = member.character_id + LEFT JOIN expedition_members member + ON character_data.id = member.character_id + AND member.is_current_member = TRUE WHERE character_data.name IN ({}) ORDER BY FIELD(character_data.name, {}) ), EscapeString(expedition_name), in_character_names_query, in_character_names_query); @@ -357,7 +360,8 @@ 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 = {}; + SELECT expedition_id FROM expedition_members + WHERE character_id = {} AND is_current_member = TRUE; ), character_id); auto results = database.QueryDatabase(query); @@ -519,7 +523,7 @@ void ExpeditionDatabase::InsertMember(uint32_t expedition_id, uint32_t character (expedition_id, character_id) VALUES ({}, {}) - ON DUPLICATE KEY UPDATE character_id = VALUES(character_id); + ON DUPLICATE KEY UPDATE is_current_member = TRUE; ), expedition_id, character_id); database.QueryDatabase(query); @@ -546,7 +550,8 @@ void ExpeditionDatabase::InsertMembers( auto query = fmt::format(SQL( INSERT INTO expedition_members (expedition_id, character_id) - VALUES {}; + VALUES {} + ON DUPLICATE KEY UPDATE is_current_member = TRUE; ), insert_values); database.QueryDatabase(query); @@ -569,7 +574,8 @@ void ExpeditionDatabase::DeleteMember(uint32_t expedition_id, uint32_t character LogExpeditionsDetail("Removing member [{}] from expedition [{}]", character_id, expedition_id); auto query = fmt::format(SQL( - DELETE FROM expedition_members WHERE expedition_id = {} AND character_id = {}; + UPDATE expedition_members SET is_current_member = FALSE + WHERE expedition_id = {} AND character_id = {}; ), expedition_id, character_id); database.QueryDatabase(query); @@ -577,10 +583,10 @@ void ExpeditionDatabase::DeleteMember(uint32_t expedition_id, uint32_t character void ExpeditionDatabase::DeleteAllMembers(uint32_t expedition_id) { - LogExpeditionsDetail("Updating all members of expedition [{}] as removed", expedition_id); + LogExpeditionsDetail("Removing all members of expedition [{}]", expedition_id); auto query = fmt::format(SQL( - DELETE FROM expedition_members WHERE expedition_id = {}; + UPDATE expedition_members SET is_current_member = FALSE WHERE expedition_id = {}; ), expedition_id); database.QueryDatabase(query);