From 64c5292c69db643355faa086930d701c09b8f7af Mon Sep 17 00:00:00 2001 From: hg <4683435+hgtw@users.noreply.github.com> Date: Sun, 25 Sep 2022 17:14:57 -0400 Subject: [PATCH] Combine task_activity item and npc fields This will make tooling easier. While denormalizing goallists may not be ideal, it decouples tasks from rewards which share the table and removes a redundant column in favor of a using the delimited string which better matches live packet data. --- .../base/base_task_activities_repository.h | 160 +++++++----------- common/tasks.h | 4 - common/version.h | 2 +- utils/sql/db_update_manifest.txt | 1 + .../2022_09_25_task_concat_matchlists.sql | 39 +++++ zone/task_client_state.cpp | 28 +-- zone/task_manager.cpp | 4 - 7 files changed, 102 insertions(+), 136 deletions(-) create mode 100644 utils/sql/git/required/2022_09_25_task_concat_matchlists.sql diff --git a/common/repositories/base/base_task_activities_repository.h b/common/repositories/base/base_task_activities_repository.h index a28063f18..e0bb196a6 100644 --- a/common/repositories/base/base_task_activities_repository.h +++ b/common/repositories/base/base_task_activities_repository.h @@ -28,11 +28,7 @@ public: uint32_t goalmethod; int32_t goalcount; std::string description_override; - uint32_t npc_id; - uint32_t npc_goal_id; std::string npc_match_list; - uint32_t item_id; - uint32_t item_goal_id; std::string item_id_list; std::string item_list; int32_t dz_switch_id; @@ -66,11 +62,7 @@ public: "goalmethod", "goalcount", "description_override", - "npc_id", - "npc_goal_id", "npc_match_list", - "item_id", - "item_goal_id", "item_id_list", "item_list", "dz_switch_id", @@ -100,11 +92,7 @@ public: "goalmethod", "goalcount", "description_override", - "npc_id", - "npc_goal_id", "npc_match_list", - "item_id", - "item_goal_id", "item_id_list", "item_list", "dz_switch_id", @@ -168,11 +156,7 @@ public: e.goalmethod = 0; e.goalcount = 1; e.description_override = ""; - e.npc_id = 0; - e.npc_goal_id = 0; e.npc_match_list = ""; - e.item_id = 0; - e.item_goal_id = 0; e.item_id_list = ""; e.item_list = ""; e.dz_switch_id = 0; @@ -231,25 +215,21 @@ public: e.goalmethod = static_cast(strtoul(row[6], nullptr, 10)); e.goalcount = static_cast(atoi(row[7])); e.description_override = row[8] ? row[8] : ""; - e.npc_id = static_cast(strtoul(row[9], nullptr, 10)); - e.npc_goal_id = static_cast(strtoul(row[10], nullptr, 10)); - e.npc_match_list = row[11] ? row[11] : ""; - e.item_id = static_cast(strtoul(row[12], nullptr, 10)); - e.item_goal_id = static_cast(strtoul(row[13], nullptr, 10)); - e.item_id_list = row[14] ? row[14] : ""; - e.item_list = row[15] ? row[15] : ""; - e.dz_switch_id = static_cast(atoi(row[16])); - e.min_x = strtof(row[17], nullptr); - e.min_y = strtof(row[18], nullptr); - e.min_z = strtof(row[19], nullptr); - e.max_x = strtof(row[20], nullptr); - e.max_y = strtof(row[21], nullptr); - e.max_z = strtof(row[22], nullptr); - e.skill_list = row[23] ? row[23] : ""; - e.spell_list = row[24] ? row[24] : ""; - e.zones = row[25] ? row[25] : ""; - e.zone_version = static_cast(atoi(row[26])); - e.optional = static_cast(atoi(row[27])); + e.npc_match_list = row[9] ? row[9] : ""; + e.item_id_list = row[10] ? row[10] : ""; + e.item_list = row[11] ? row[11] : ""; + e.dz_switch_id = static_cast(atoi(row[12])); + e.min_x = strtof(row[13], nullptr); + e.min_y = strtof(row[14], nullptr); + e.min_z = strtof(row[15], nullptr); + e.max_x = strtof(row[16], nullptr); + e.max_y = strtof(row[17], nullptr); + e.max_z = strtof(row[18], nullptr); + e.skill_list = row[19] ? row[19] : ""; + e.spell_list = row[20] ? row[20] : ""; + e.zones = row[21] ? row[21] : ""; + e.zone_version = static_cast(atoi(row[22])); + e.optional = static_cast(atoi(row[23])); return e; } @@ -292,25 +272,21 @@ public: v.push_back(columns[6] + " = " + std::to_string(e.goalmethod)); v.push_back(columns[7] + " = " + std::to_string(e.goalcount)); v.push_back(columns[8] + " = '" + Strings::Escape(e.description_override) + "'"); - v.push_back(columns[9] + " = " + std::to_string(e.npc_id)); - v.push_back(columns[10] + " = " + std::to_string(e.npc_goal_id)); - v.push_back(columns[11] + " = '" + Strings::Escape(e.npc_match_list) + "'"); - v.push_back(columns[12] + " = " + std::to_string(e.item_id)); - v.push_back(columns[13] + " = " + std::to_string(e.item_goal_id)); - v.push_back(columns[14] + " = '" + Strings::Escape(e.item_id_list) + "'"); - v.push_back(columns[15] + " = '" + Strings::Escape(e.item_list) + "'"); - v.push_back(columns[16] + " = " + std::to_string(e.dz_switch_id)); - v.push_back(columns[17] + " = " + std::to_string(e.min_x)); - v.push_back(columns[18] + " = " + std::to_string(e.min_y)); - v.push_back(columns[19] + " = " + std::to_string(e.min_z)); - v.push_back(columns[20] + " = " + std::to_string(e.max_x)); - v.push_back(columns[21] + " = " + std::to_string(e.max_y)); - v.push_back(columns[22] + " = " + std::to_string(e.max_z)); - v.push_back(columns[23] + " = '" + Strings::Escape(e.skill_list) + "'"); - v.push_back(columns[24] + " = '" + Strings::Escape(e.spell_list) + "'"); - v.push_back(columns[25] + " = '" + Strings::Escape(e.zones) + "'"); - v.push_back(columns[26] + " = " + std::to_string(e.zone_version)); - v.push_back(columns[27] + " = " + std::to_string(e.optional)); + v.push_back(columns[9] + " = '" + Strings::Escape(e.npc_match_list) + "'"); + v.push_back(columns[10] + " = '" + Strings::Escape(e.item_id_list) + "'"); + v.push_back(columns[11] + " = '" + Strings::Escape(e.item_list) + "'"); + v.push_back(columns[12] + " = " + std::to_string(e.dz_switch_id)); + v.push_back(columns[13] + " = " + std::to_string(e.min_x)); + v.push_back(columns[14] + " = " + std::to_string(e.min_y)); + v.push_back(columns[15] + " = " + std::to_string(e.min_z)); + v.push_back(columns[16] + " = " + std::to_string(e.max_x)); + v.push_back(columns[17] + " = " + std::to_string(e.max_y)); + v.push_back(columns[18] + " = " + std::to_string(e.max_z)); + v.push_back(columns[19] + " = '" + Strings::Escape(e.skill_list) + "'"); + v.push_back(columns[20] + " = '" + Strings::Escape(e.spell_list) + "'"); + v.push_back(columns[21] + " = '" + Strings::Escape(e.zones) + "'"); + v.push_back(columns[22] + " = " + std::to_string(e.zone_version)); + v.push_back(columns[23] + " = " + std::to_string(e.optional)); auto results = db.QueryDatabase( fmt::format( @@ -341,11 +317,7 @@ public: v.push_back(std::to_string(e.goalmethod)); v.push_back(std::to_string(e.goalcount)); v.push_back("'" + Strings::Escape(e.description_override) + "'"); - v.push_back(std::to_string(e.npc_id)); - v.push_back(std::to_string(e.npc_goal_id)); v.push_back("'" + Strings::Escape(e.npc_match_list) + "'"); - v.push_back(std::to_string(e.item_id)); - v.push_back(std::to_string(e.item_goal_id)); v.push_back("'" + Strings::Escape(e.item_id_list) + "'"); v.push_back("'" + Strings::Escape(e.item_list) + "'"); v.push_back(std::to_string(e.dz_switch_id)); @@ -398,11 +370,7 @@ public: v.push_back(std::to_string(e.goalmethod)); v.push_back(std::to_string(e.goalcount)); v.push_back("'" + Strings::Escape(e.description_override) + "'"); - v.push_back(std::to_string(e.npc_id)); - v.push_back(std::to_string(e.npc_goal_id)); v.push_back("'" + Strings::Escape(e.npc_match_list) + "'"); - v.push_back(std::to_string(e.item_id)); - v.push_back(std::to_string(e.item_goal_id)); v.push_back("'" + Strings::Escape(e.item_id_list) + "'"); v.push_back("'" + Strings::Escape(e.item_list) + "'"); v.push_back(std::to_string(e.dz_switch_id)); @@ -459,25 +427,21 @@ public: e.goalmethod = static_cast(strtoul(row[6], nullptr, 10)); e.goalcount = static_cast(atoi(row[7])); e.description_override = row[8] ? row[8] : ""; - e.npc_id = static_cast(strtoul(row[9], nullptr, 10)); - e.npc_goal_id = static_cast(strtoul(row[10], nullptr, 10)); - e.npc_match_list = row[11] ? row[11] : ""; - e.item_id = static_cast(strtoul(row[12], nullptr, 10)); - e.item_goal_id = static_cast(strtoul(row[13], nullptr, 10)); - e.item_id_list = row[14] ? row[14] : ""; - e.item_list = row[15] ? row[15] : ""; - e.dz_switch_id = static_cast(atoi(row[16])); - e.min_x = strtof(row[17], nullptr); - e.min_y = strtof(row[18], nullptr); - e.min_z = strtof(row[19], nullptr); - e.max_x = strtof(row[20], nullptr); - e.max_y = strtof(row[21], nullptr); - e.max_z = strtof(row[22], nullptr); - e.skill_list = row[23] ? row[23] : ""; - e.spell_list = row[24] ? row[24] : ""; - e.zones = row[25] ? row[25] : ""; - e.zone_version = static_cast(atoi(row[26])); - e.optional = static_cast(atoi(row[27])); + e.npc_match_list = row[9] ? row[9] : ""; + e.item_id_list = row[10] ? row[10] : ""; + e.item_list = row[11] ? row[11] : ""; + e.dz_switch_id = static_cast(atoi(row[12])); + e.min_x = strtof(row[13], nullptr); + e.min_y = strtof(row[14], nullptr); + e.min_z = strtof(row[15], nullptr); + e.max_x = strtof(row[16], nullptr); + e.max_y = strtof(row[17], nullptr); + e.max_z = strtof(row[18], nullptr); + e.skill_list = row[19] ? row[19] : ""; + e.spell_list = row[20] ? row[20] : ""; + e.zones = row[21] ? row[21] : ""; + e.zone_version = static_cast(atoi(row[22])); + e.optional = static_cast(atoi(row[23])); all_entries.push_back(e); } @@ -511,25 +475,21 @@ public: e.goalmethod = static_cast(strtoul(row[6], nullptr, 10)); e.goalcount = static_cast(atoi(row[7])); e.description_override = row[8] ? row[8] : ""; - e.npc_id = static_cast(strtoul(row[9], nullptr, 10)); - e.npc_goal_id = static_cast(strtoul(row[10], nullptr, 10)); - e.npc_match_list = row[11] ? row[11] : ""; - e.item_id = static_cast(strtoul(row[12], nullptr, 10)); - e.item_goal_id = static_cast(strtoul(row[13], nullptr, 10)); - e.item_id_list = row[14] ? row[14] : ""; - e.item_list = row[15] ? row[15] : ""; - e.dz_switch_id = static_cast(atoi(row[16])); - e.min_x = strtof(row[17], nullptr); - e.min_y = strtof(row[18], nullptr); - e.min_z = strtof(row[19], nullptr); - e.max_x = strtof(row[20], nullptr); - e.max_y = strtof(row[21], nullptr); - e.max_z = strtof(row[22], nullptr); - e.skill_list = row[23] ? row[23] : ""; - e.spell_list = row[24] ? row[24] : ""; - e.zones = row[25] ? row[25] : ""; - e.zone_version = static_cast(atoi(row[26])); - e.optional = static_cast(atoi(row[27])); + e.npc_match_list = row[9] ? row[9] : ""; + e.item_id_list = row[10] ? row[10] : ""; + e.item_list = row[11] ? row[11] : ""; + e.dz_switch_id = static_cast(atoi(row[12])); + e.min_x = strtof(row[13], nullptr); + e.min_y = strtof(row[14], nullptr); + e.min_z = strtof(row[15], nullptr); + e.max_x = strtof(row[16], nullptr); + e.max_y = strtof(row[17], nullptr); + e.max_z = strtof(row[18], nullptr); + e.skill_list = row[19] ? row[19] : ""; + e.spell_list = row[20] ? row[20] : ""; + e.zones = row[21] ? row[21] : ""; + e.zone_version = static_cast(atoi(row[22])); + e.optional = static_cast(atoi(row[23])); all_entries.push_back(e); } diff --git a/common/tasks.h b/common/tasks.h index 991214349..27ef6aaae 100644 --- a/common/tasks.h +++ b/common/tasks.h @@ -77,11 +77,7 @@ struct ActivityInformation { int spell_id; // older clients, first id from above TaskMethodType goal_method; int goal_count; - uint32_t npc_id; - uint32_t npc_goal_id; std::string npc_match_list; // delimited by '|' for partial name matches but also supports ids - uint32_t item_id; - uint32_t item_goal_id; std::string item_id_list; // delimited by '|' to support multiple item ids int dz_switch_id; float min_x; diff --git a/common/version.h b/common/version.h index fe1424612..10feef34f 100644 --- a/common/version.h +++ b/common/version.h @@ -34,7 +34,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9207 +#define CURRENT_BINARY_DATABASE_VERSION 9208 #ifdef BOTS #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9029 diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 5ac089d9d..646b79977 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -461,6 +461,7 @@ 9205|2022_09_03_fix_starting_point_heading.sql|SELECT * FROM db_version WHERE version >= 9205|empty| 9206|2022_09_03_fix_door_destination_headings.sql|SELECT * FROM db_version WHERE version >= 9206|empty| 9207|2022_09_03_fix_zone_point_heading_data.sql|SELECT * FROM db_version WHERE version >= 9207|empty| +9208|2022_09_25_task_concat_matchlists.sql|SHOW COLUMNS FROM `task_activities` LIKE 'npc_id'|not_empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2022_09_25_task_concat_matchlists.sql b/utils/sql/git/required/2022_09_25_task_concat_matchlists.sql new file mode 100644 index 000000000..cb15a338a --- /dev/null +++ b/utils/sql/git/required/2022_09_25_task_concat_matchlists.sql @@ -0,0 +1,39 @@ +-- npc id +UPDATE `task_activities` +SET `task_activities`.`npc_match_list` = CONCAT_WS('|', `npc_match_list`, `npc_id`) +WHERE npc_id != 0; + +-- npc_goal_id goallists +UPDATE `task_activities` +INNER JOIN +( + SELECT `goallists`.`listid`, GROUP_CONCAT(`goallists`.`entry` ORDER BY `goallists`.`entry` SEPARATOR '|') AS `goallist_ids` + FROM `goallists` + GROUP BY `goallists`.`listid` +) AS `goallist_group` + ON `task_activities`.`npc_goal_id` = `goallist_group`.`listid` +SET `task_activities`.`npc_match_list` = CONCAT_WS('|', `npc_match_list`, `goallist_ids`) +WHERE npc_goal_id != 0; + +-- item id +UPDATE `task_activities` +SET `task_activities`.`item_id_list` = CONCAT_WS('|', `item_id_list`, `item_id`) +WHERE item_id != 0; + +-- item_goal_id goallists +UPDATE `task_activities` +INNER JOIN +( + SELECT `goallists`.`listid`, GROUP_CONCAT(`goallists`.`entry` ORDER BY `goallists`.`entry` SEPARATOR '|') AS `goallist_ids` + FROM `goallists` + GROUP BY `goallists`.`listid` +) AS `goallist_group` + ON `task_activities`.`item_goal_id` = `goallist_group`.`listid` +SET `task_activities`.`item_id_list` = CONCAT_WS('|', `item_id_list`, `goallist_ids`) +WHERE item_goal_id != 0; + +ALTER TABLE `task_activities` + DROP COLUMN `npc_id`, + DROP COLUMN `npc_goal_id`, + DROP COLUMN `item_id`, + DROP COLUMN `item_goal_id`; diff --git a/zone/task_client_state.cpp b/zone/task_client_state.cpp index 362e1f542..bed35b882 100644 --- a/zone/task_client_state.cpp +++ b/zone/task_client_state.cpp @@ -492,19 +492,6 @@ bool ClientTaskState::CanUpdate(Client* client, const TaskUpdateFilter& filter, return false; } - // item is only checked for updates that provide an item (unlike npc which may be null for non-npcs) - if (activity.item_id != 0 && filter.item_id != 0 && activity.item_id != filter.item_id) - { - LogTasks("[CanUpdate] client [{}] task [{}]-[{}] failed item id filter", client->GetName(), task_id, client_activity.activity_id); - return false; - } - - if (activity.npc_id != 0 && (!filter.npc || activity.npc_id != filter.npc->GetNPCTypeID())) - { - LogTasks("[CanUpdate] client [{}] task [{}]-[{}] failed npc id filter", client->GetName(), task_id, client_activity.activity_id); - return false; - } - if (!activity.CheckZone(zone->GetZoneID(), zone->GetInstanceVersion())) { LogTasks("[CanUpdate] client [{}] task [{}]-[{}] failed zone filter", client->GetName(), task_id, client_activity.activity_id); @@ -523,13 +510,7 @@ bool ClientTaskState::CanUpdate(Client* client, const TaskUpdateFilter& filter, } } - if (activity.item_goal_id != 0 && filter.item_id != 0 && - !task_manager->m_goal_list_manager.IsInList(activity.item_goal_id, filter.item_id)) - { - LogTasks("[CanUpdate] client [{}] task [{}]-[{}] failed item goallist filter", client->GetName(), task_id, client_activity.activity_id); - return false; - } - + // item is only checked for updates that provide an item to check (unlike npc which may be null for non-npcs) if (!activity.item_id_list.empty() && filter.item_id != 0 && !TaskGoalListManager::IsInMatchList(activity.item_id_list, std::to_string(filter.item_id))) { @@ -537,13 +518,6 @@ bool ClientTaskState::CanUpdate(Client* client, const TaskUpdateFilter& filter, return false; } - if (activity.npc_goal_id != 0 && (!filter.npc || - !task_manager->m_goal_list_manager.IsInList(activity.npc_goal_id, filter.npc->GetNPCTypeID()))) - { - LogTasks("[CanUpdate] client [{}] task [{}]-[{}] failed npc goallist filter", client->GetName(), task_id, client_activity.activity_id); - return false; - } - // npc filter supports both npc names and ids in match lists if (!activity.npc_match_list.empty() && (!filter.npc || (!TaskGoalListManager::IsInMatchListPartial(activity.npc_match_list, filter.npc->GetName()) && diff --git a/zone/task_manager.cpp b/zone/task_manager.cpp index 0b866af47..86fadab3e 100644 --- a/zone/task_manager.cpp +++ b/zone/task_manager.cpp @@ -212,11 +212,7 @@ bool TaskManager::LoadTasks(int single_task) activity_data->spell_list = task_activity.spell_list; activity_data->spell_id = Strings::IsNumber(task_activity.spell_list) ? std::stoi(task_activity.spell_list) : 0; // for older clients activity_data->description_override = task_activity.description_override; - activity_data->npc_id = task_activity.npc_id; - activity_data->npc_goal_id = task_activity.npc_goal_id; activity_data->npc_match_list = task_activity.npc_match_list; - activity_data->item_id = task_activity.item_id; - activity_data->item_goal_id = task_activity.item_goal_id; activity_data->item_id_list = task_activity.item_id_list; activity_data->dz_switch_id = task_activity.dz_switch_id; activity_data->goal_method = (TaskMethodType) task_activity.goalmethod;