From 9d766bf5dceb6a5f6efa91e74633ac20f298909a Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Wed, 28 Sep 2022 03:04:09 -0500 Subject: [PATCH] [World CLI] Refactor world CLI to be easier to reason about (#2441) --- world/CMakeLists.txt | 140 +++--- world/cli/copy_character.cpp | 37 ++ world/cli/database_dump.cpp | 60 +++ world/cli/database_get_schema.cpp | 68 +++ world/cli/database_set_account_status.cpp | 24 + world/cli/database_version.cpp | 21 + world/cli/test.cpp | 9 + world/cli/test_expansion.cpp | 44 ++ world/cli/test_repository.cpp | 100 +++++ world/cli/test_repository_2.cpp | 21 + world/cli/version.cpp | 24 + world/main.cpp | 2 +- world/world_boot.cpp | 4 +- world/world_server_cli.cpp | 45 ++ world/world_server_cli.h | 23 + world/world_server_command_handler.cpp | 523 ---------------------- world/world_server_command_handler.h | 42 -- 17 files changed, 549 insertions(+), 638 deletions(-) create mode 100644 world/cli/copy_character.cpp create mode 100644 world/cli/database_dump.cpp create mode 100644 world/cli/database_get_schema.cpp create mode 100644 world/cli/database_set_account_status.cpp create mode 100644 world/cli/database_version.cpp create mode 100644 world/cli/test.cpp create mode 100644 world/cli/test_expansion.cpp create mode 100644 world/cli/test_repository.cpp create mode 100644 world/cli/test_repository_2.cpp create mode 100644 world/cli/version.cpp create mode 100644 world/world_server_cli.cpp create mode 100644 world/world_server_cli.h delete mode 100644 world/world_server_command_handler.cpp delete mode 100644 world/world_server_command_handler.h diff --git a/world/CMakeLists.txt b/world/CMakeLists.txt index de58f2f4e..45c4a4397 100644 --- a/world/CMakeLists.txt +++ b/world/CMakeLists.txt @@ -1,78 +1,78 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.2) SET(world_sources - adventure.cpp - adventure_manager.cpp - client.cpp - cliententry.cpp - clientlist.cpp - console.cpp - dynamic_zone.cpp - dynamic_zone_manager.cpp - eql_config.cpp - eqemu_api_world_data_service.cpp - expedition_database.cpp - expedition_message.cpp - launcher_link.cpp - launcher_list.cpp - lfplist.cpp - login_server.cpp - login_server_list.cpp - main.cpp - queryserv.cpp - shared_task_manager.cpp - shared_task_world_messaging.cpp - ucs.cpp - web_interface.cpp - web_interface_eqw.cpp - wguild_mgr.cpp - world_event_scheduler.cpp - world_config.cpp - world_console_connection.cpp - world_server_command_handler.cpp - worlddb.cpp - world_boot.cpp - zonelist.cpp - zoneserver.cpp -) + adventure.cpp + adventure_manager.cpp + client.cpp + cliententry.cpp + clientlist.cpp + console.cpp + dynamic_zone.cpp + dynamic_zone_manager.cpp + eql_config.cpp + eqemu_api_world_data_service.cpp + expedition_database.cpp + expedition_message.cpp + launcher_link.cpp + launcher_list.cpp + lfplist.cpp + login_server.cpp + login_server_list.cpp + main.cpp + queryserv.cpp + shared_task_manager.cpp + shared_task_world_messaging.cpp + ucs.cpp + web_interface.cpp + web_interface_eqw.cpp + wguild_mgr.cpp + world_event_scheduler.cpp + world_config.cpp + world_console_connection.cpp + world_server_cli.cpp + worlddb.cpp + world_boot.cpp + zonelist.cpp + zoneserver.cpp + ) SET(world_headers - adventure.h - adventure_manager.h - adventure_template.h - client.h - cliententry.h - clientlist.h - console.h - dynamic_zone.h - dynamic_zone_manager.h - eql_config.h - eqemu_api_world_data_service.h - expedition_database.h - expedition_message.h - launcher_link.h - launcher_list.h - lfplist.h - login_server.h - login_server_list.h - queryserv.h - shared_task_manager.h - shared_task_world_messaging.h - sof_char_create_data.h - ucs.h - web_interface.h - web_interface_eqw.h - wguild_mgr.h - world_config.h - world_console_connection.h - world_tcp_connection.h - world_server_command_handler.h - worlddb.h - world_boot.h - world_event_scheduler.h - zonelist.h - zoneserver.h -) + adventure.h + adventure_manager.h + adventure_template.h + client.h + cliententry.h + clientlist.h + console.h + dynamic_zone.h + dynamic_zone_manager.h + eql_config.h + eqemu_api_world_data_service.h + expedition_database.h + expedition_message.h + launcher_link.h + launcher_list.h + lfplist.h + login_server.h + login_server_list.h + queryserv.h + shared_task_manager.h + shared_task_world_messaging.h + sof_char_create_data.h + ucs.h + web_interface.h + web_interface_eqw.h + wguild_mgr.h + world_config.h + world_console_connection.h + world_tcp_connection.h + world_server_cli.h + worlddb.h + world_boot.h + world_event_scheduler.h + zonelist.h + zoneserver.h + ) ADD_EXECUTABLE(world ${world_sources} ${world_headers}) diff --git a/world/cli/copy_character.cpp b/world/cli/copy_character.cpp new file mode 100644 index 000000000..7d915ad15 --- /dev/null +++ b/world/cli/copy_character.cpp @@ -0,0 +1,37 @@ +#include "../../common/eqemu_logsys_log_aliases.h" +#include "../worlddb.h" + +void WorldserverCLI::CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Copies a character into a destination account"; + + std::vector arguments = { + "source_character_name", + "destination_character_name", + "destination_account_name" + }; + std::vector options = {}; + + if (cmd[{"-h", "--help"}]) { + return; + } + + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + + std::string source_character_name = cmd(2).str(); + std::string destination_character_name = cmd(3).str(); + std::string destination_account_name = cmd(4).str(); + + LogInfo( + "Attempting to copy character [{}] to [{}] via account [{}]", + source_character_name, + destination_character_name, + destination_account_name + ); + + database.CopyCharacter( + source_character_name, + destination_character_name, + destination_account_name + ); +} diff --git a/world/cli/database_dump.cpp b/world/cli/database_dump.cpp new file mode 100644 index 000000000..7524efc97 --- /dev/null +++ b/world/cli/database_dump.cpp @@ -0,0 +1,60 @@ +#include "../../common/database/database_dump_service.h" + +void WorldserverCLI::DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Dumps server database tables"; + + std::vector arguments = {}; + std::vector options = { + "--all", + "--content-tables", + "--login-tables", + "--player-tables", + "--bot-tables", + "--state-tables", + "--system-tables", + "--query-serv-tables", + "--table-structure-only", + "--table-lock", + "--dump-path=", + "--dump-output-to-console", + "--drop-table-syntax-only", + "--compress" + }; + + if (cmd[{"-h", "--help"}]) { + return; + } + + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + + auto s = new DatabaseDumpService(); + bool dump_all = cmd[{"-a", "--all"}]; + + if (!cmd("--dump-path").str().empty()) { + s->SetDumpPath(cmd("--dump-path").str()); + } + + /** + * Set Option + */ + s->SetDumpContentTables(cmd[{"--content-tables"}] || dump_all); + s->SetDumpLoginServerTables(cmd[{"--login-tables"}] || dump_all); + s->SetDumpPlayerTables(cmd[{"--player-tables"}] || dump_all); + s->SetDumpBotTables(cmd[{"--bot-tables"}] || dump_all); + s->SetDumpStateTables(cmd[{"--state-tables"}] || dump_all); + s->SetDumpSystemTables(cmd[{"--system-tables"}] || dump_all); + s->SetDumpQueryServerTables(cmd[{"--query-serv-tables"}] || dump_all); + s->SetDumpAllTables(dump_all); + + s->SetDumpWithNoData(cmd[{"--table-structure-only"}]); + s->SetDumpTableLock(cmd[{"--table-lock"}]); + s->SetDumpWithCompression(cmd[{"--compress"}]); + s->SetDumpOutputToConsole(cmd[{"--dump-output-to-console"}]); + s->SetDumpDropTableSyntaxOnly(cmd[{"--drop-table-syntax-only"}]); + + /** + * Dump + */ + s->Dump(); +} diff --git a/world/cli/database_get_schema.cpp b/world/cli/database_get_schema.cpp new file mode 100644 index 000000000..b71139358 --- /dev/null +++ b/world/cli/database_get_schema.cpp @@ -0,0 +1,68 @@ +#include "../../common/database_schema.h" +#include "../../common/json/json.h" + +void WorldserverCLI::DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Displays server database schema"; + + if (cmd[{"-h", "--help"}]) { + return; + } + + Json::Value player_tables_json; + std::vector player_tables = DatabaseSchema::GetPlayerTables(); + for (const auto &table: player_tables) { + player_tables_json.append(table); + } + + Json::Value content_tables_json; + std::vector content_tables = DatabaseSchema::GetContentTables(); + for (const auto &table: content_tables) { + content_tables_json.append(table); + } + + Json::Value server_tables_json; + std::vector server_tables = DatabaseSchema::GetServerTables(); + for (const auto &table: server_tables) { + server_tables_json.append(table); + } + + Json::Value login_tables_json; + std::vector login_tables = DatabaseSchema::GetLoginTables(); + for (const auto &table: login_tables) { + login_tables_json.append(table); + } + + Json::Value state_tables_json; + std::vector state_tables = DatabaseSchema::GetStateTables(); + for (const auto &table: state_tables) { + state_tables_json.append(table); + } + + Json::Value version_tables_json; + std::vector version_tables = DatabaseSchema::GetVersionTables(); + for (const auto &table: version_tables) { + version_tables_json.append(table); + } + + Json::Value bot_tables_json; + std::vector bot_tables = DatabaseSchema::GetBotTables(); + for (const auto &table: bot_tables) { + bot_tables_json.append(table); + } + + Json::Value schema; + + schema["content_tables"] = content_tables_json; + schema["login_tables"] = login_tables_json; + schema["player_tables"] = player_tables_json; + schema["server_tables"] = server_tables_json; + schema["state_tables"] = state_tables_json; + schema["version_tables"] = version_tables_json; + schema["bot_tables"] = bot_tables_json; + + std::stringstream payload; + payload << schema; + + std::cout << payload.str() << std::endl; +} diff --git a/world/cli/database_set_account_status.cpp b/world/cli/database_set_account_status.cpp new file mode 100644 index 000000000..52e777bf4 --- /dev/null +++ b/world/cli/database_set_account_status.cpp @@ -0,0 +1,24 @@ +#include "../worlddb.h" + +void WorldserverCLI::DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Sets account status by account name"; + + std::vector arguments = { + "{name}", + "{status}" + }; + + std::vector options = {}; + + if (cmd[{"-h", "--help"}]) { + return; + } + + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + + database.SetAccountStatus( + cmd(2).str(), + std::stoi(cmd(3).str()) + ); +} diff --git a/world/cli/database_version.cpp b/world/cli/database_version.cpp new file mode 100644 index 000000000..639e7e1de --- /dev/null +++ b/world/cli/database_version.cpp @@ -0,0 +1,21 @@ +#include "../../common/version.h" +#include "../../common/json/json.h" + +void WorldserverCLI::DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Shows database version"; + + if (cmd[{"-h", "--help"}]) { + return; + } + + Json::Value database_version; + + database_version["database_version"] = CURRENT_BINARY_DATABASE_VERSION; + database_version["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION; + + std::stringstream payload; + payload << database_version; + + std::cout << payload.str() << std::endl; +} diff --git a/world/cli/test.cpp b/world/cli/test.cpp new file mode 100644 index 000000000..0a95e45e3 --- /dev/null +++ b/world/cli/test.cpp @@ -0,0 +1,9 @@ +void WorldserverCLI::TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Test command"; + + if (cmd[{"-h", "--help"}]) { + return; + } + +} diff --git a/world/cli/test_expansion.cpp b/world/cli/test_expansion.cpp new file mode 100644 index 000000000..f8028b2da --- /dev/null +++ b/world/cli/test_expansion.cpp @@ -0,0 +1,44 @@ +#include "../../common/rulesys.h" +#include "../../common/repositories/content_flags_repository.h" +#include "../../common/content/world_content_service.h" +#include "../../common/repositories/criteria/content_filter_criteria.h" +#include "../worlddb.h" + +void WorldserverCLI::ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Expansion test command"; + + if (cmd[{"-h", "--help"}]) { + return; + } + + if (!RuleManager::Instance()->LoadRules(&database, "default", false)) { + LogInfo("No rule set configured, using default rules"); + } + + content_service.SetCurrentExpansion(RuleI(Expansion, CurrentExpansion)); + + std::vector flags = {}; + auto f = ContentFlagsRepository::NewEntity(); + f.enabled = 1; + + std::vector flag_names = { + "hateplane_enabled", + "patch_nerf_7077", + }; + + for (auto &name: flag_names) { + f.flag_name = name; + flags.push_back(f); + } + + content_service.SetContentFlags(flags); + + LogInfo( + "Current expansion is [{}] ({}) is Velious Enabled [{}] Criteria [{}]", + content_service.GetCurrentExpansion(), + content_service.GetCurrentExpansionName(), + content_service.IsTheScarsOfVeliousEnabled() ? "true" : "false", + ContentFilterCriteria::apply() + ); +} diff --git a/world/cli/test_repository.cpp b/world/cli/test_repository.cpp new file mode 100644 index 000000000..a4c8f59b1 --- /dev/null +++ b/world/cli/test_repository.cpp @@ -0,0 +1,100 @@ +#include "../../common/repositories/instance_list_repository.h" +#include "../worlddb.h" + +void WorldserverCLI::TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Test command"; + + if (cmd[{"-h", "--help"}]) { + return; + } + + /** + * Insert one + */ + auto e = InstanceListRepository::NewEntity(); + + e.zone = 999; + e.version = 1; + e.is_global = 1; + e.start_time = 0; + e.duration = 0; + e.never_expires = 1; + + auto inserted = InstanceListRepository::InsertOne(database, e); + + LogInfo("Inserted ID is [{}] zone [{}]", inserted.id, inserted.zone); + + /** + * Find one + */ + auto f = InstanceListRepository::FindOne(database, inserted.id); + + LogInfo("Found ID is [{}] zone [{}]", f.id, f.zone); + + /** + * Update one + */ + LogInfo("Updating instance id [{}] zone [{}]", f.id, f.zone); + + int update_instance_list_count = InstanceListRepository::UpdateOne(database, f); + + f.zone = 777; + + LogInfo( + "Updated instance id [{}] zone [{}] affected [{}]", + f.id, + f.zone, + update_instance_list_count + ); + + + /** + * Delete one + */ + int deleted = InstanceListRepository::DeleteOne(database, f.id); + + LogInfo("Deleting one instance [{}] deleted count [{}]", f.id, deleted); + + /** + * Insert many + */ + std::vector instance_lists; + + auto b = InstanceListRepository::NewEntity(); + + b.zone = 999; + b.version = 1; + b.is_global = 1; + b.start_time = 0; + b.duration = 0; + b.never_expires = 1; + + for (int i = 0; i < 10; i++) { + instance_lists.push_back(b); + } + + /** + * Insert Many + */ + int inserted_count = InstanceListRepository::InsertMany(database, instance_lists); + + LogInfo("Bulk insertion test, inserted [{}]", inserted_count); + + for (auto &entry: InstanceListRepository::GetWhere(database, fmt::format("zone = {}", 999))) { + LogInfo("Iterating through entry id [{}] zone [{}]", entry.id, entry.zone); + } + + LogInfo("[Max ID] {}", InstanceListRepository::GetMaxId(database)); + LogInfo("[Count] {}", InstanceListRepository::Count(database)); + LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 999")); + LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 777")); + + /** + * Delete where + */ + int deleted_count = InstanceListRepository::DeleteWhere(database, fmt::format("zone = {}", 999)); + + LogInfo("Bulk deletion test, deleted [{}]", deleted_count); + +} diff --git a/world/cli/test_repository_2.cpp b/world/cli/test_repository_2.cpp new file mode 100644 index 000000000..06a2a624b --- /dev/null +++ b/world/cli/test_repository_2.cpp @@ -0,0 +1,21 @@ +#include "../../common/repositories/zone_repository.h" + +void WorldserverCLI::TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Test command"; + + if (cmd[{"-h", "--help"}]) { + return; + } + + auto zones = ZoneRepository::GetWhere(content_db, "short_name = 'anguish'"); + + for (auto &zone: zones) { + LogInfo( + "Zone [{}] long_name [{}] id [{}]", + zone.short_name, + zone.long_name, + zone.id + ); + } +} diff --git a/world/cli/version.cpp b/world/cli/version.cpp new file mode 100644 index 000000000..d03fd5e26 --- /dev/null +++ b/world/cli/version.cpp @@ -0,0 +1,24 @@ +#include "../../common/json/json.h" +#include "../../common/version.h" + +void WorldserverCLI::Version(int argc, char **argv, argh::parser &cmd, std::string &description) +{ + description = "Shows server version"; + + if (cmd[{"-h", "--help"}]) { + return; + } + + Json::Value j; + + j["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION; + j["compile_date"] = COMPILE_DATE; + j["compile_time"] = COMPILE_TIME; + j["database_version"] = CURRENT_BINARY_DATABASE_VERSION; + j["server_version"] = CURRENT_VERSION; + + std::stringstream payload; + payload << j; + + std::cout << payload.str() << std::endl; +} diff --git a/world/main.cpp b/world/main.cpp index ddbbca8b5..b7e297b76 100644 --- a/world/main.cpp +++ b/world/main.cpp @@ -88,7 +88,7 @@ union semun { #include "dynamic_zone_manager.h" #include "expedition_database.h" -#include "world_server_command_handler.h" +#include "world_server_cli.h" #include "../common/content/world_content_service.h" #include "../common/repositories/character_task_timers_repository.h" #include "../common/zone_store.h" diff --git a/world/world_boot.cpp b/world/world_boot.cpp index 0a60e86e9..c45538e0a 100644 --- a/world/world_boot.cpp +++ b/world/world_boot.cpp @@ -18,7 +18,7 @@ #include "world_boot.h" #include "world_config.h" #include "world_event_scheduler.h" -#include "world_server_command_handler.h" +#include "world_server_cli.h" #include "../common/zone_store.h" #include "worlddb.h" #include "zonelist.h" @@ -87,7 +87,7 @@ bool WorldBoot::HandleCommandInput(int argc, char **argv) WorldConfig::LoadConfig(); LoadDatabaseConnections(); LogSys.EnableConsoleLogging(); - WorldserverCommandHandler::CommandHandler(argc, argv); + WorldserverCLI::CommandHandler(argc, argv); } return false; diff --git a/world/world_server_cli.cpp b/world/world_server_cli.cpp new file mode 100644 index 000000000..48edd95b6 --- /dev/null +++ b/world/world_server_cli.cpp @@ -0,0 +1,45 @@ +#include "world_server_cli.h" +/** + * @param argc + * @param argv + */ +void WorldserverCLI::CommandHandler(int argc, char **argv) +{ + if (argc == 1) { return; } + + argh::parser cmd; + cmd.parse(argc, argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION); + EQEmuCommand::DisplayDebug(cmd); + + /** + * Declare command mapping + */ + auto function_map = EQEmuCommand::function_map; + + /** + * Register commands + */ + function_map["world:version"] = &WorldserverCLI::Version; + function_map["character:copy-character"] = &WorldserverCLI::CopyCharacter; + function_map["database:version"] = &WorldserverCLI::DatabaseVersion; + function_map["database:set-account-status"] = &WorldserverCLI::DatabaseSetAccountStatus; + function_map["database:schema"] = &WorldserverCLI::DatabaseGetSchema; + function_map["database:dump"] = &WorldserverCLI::DatabaseDump; + function_map["test:test"] = &WorldserverCLI::TestCommand; + function_map["test:expansion"] = &WorldserverCLI::ExpansionTestCommand; + function_map["test:repository"] = &WorldserverCLI::TestRepository; + function_map["test:repository2"] = &WorldserverCLI::TestRepository2; + + EQEmuCommand::HandleMenu(function_map, cmd, argc, argv); +} + +#include "cli/copy_character.cpp" +#include "cli/database_dump.cpp" +#include "cli/database_get_schema.cpp" +#include "cli/database_set_account_status.cpp" +#include "cli/database_version.cpp" +#include "cli/test.cpp" +#include "cli/test_expansion.cpp" +#include "cli/test_repository.cpp" +#include "cli/test_repository_2.cpp" +#include "cli/version.cpp" diff --git a/world/world_server_cli.h b/world/world_server_cli.h new file mode 100644 index 000000000..be3b15e55 --- /dev/null +++ b/world/world_server_cli.h @@ -0,0 +1,23 @@ +#include "iostream" +#include "../common/cli/eqemu_command_handler.h" + +#ifndef EQEMU_WORLD_SERVER_COMMAND_HANDLER_H +#define EQEMU_WORLD_SERVER_COMMAND_HANDLER_H + +class WorldserverCLI { +public: + static void CommandHandler(int argc, char **argv); + static void Version(int argc, char **argv, argh::parser &cmd, std::string &description); + static void CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description); + static void DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description); + static void DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description); + static void DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description); + static void DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description); + static void TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description); + static void ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description); + static void TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description); + static void TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description); +}; + + +#endif //EQEMU_WORLD_SERVER_COMMAND_HANDLER_H diff --git a/world/world_server_command_handler.cpp b/world/world_server_command_handler.cpp deleted file mode 100644 index dc59c6dda..000000000 --- a/world/world_server_command_handler.cpp +++ /dev/null @@ -1,523 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY except by those people which sell it, which - * are required to give you total support for your newly bought product; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "world_server_command_handler.h" -#include "../common/eqemu_logsys.h" -#include "../common/discord/discord.h" -#include "../common/json/json.h" -#include "../common/version.h" -#include "worlddb.h" -#include "../common/database_schema.h" -#include "../common/database/database_dump_service.h" -#include "../common/content/world_content_service.h" -#include "../common/repositories/criteria/content_filter_criteria.h" -#include "../common/rulesys.h" -#include "../common/repositories/instance_list_repository.h" -#include "../common/repositories/zone_repository.h" -#include "../zone/queryserv.h" - -namespace WorldserverCommandHandler { - - /** - * @param argc - * @param argv - */ - void CommandHandler(int argc, char **argv) - { - if (argc == 1) { return; } - - argh::parser cmd; - cmd.parse(argc, argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION); - EQEmuCommand::DisplayDebug(cmd); - - /** - * Declare command mapping - */ - auto function_map = EQEmuCommand::function_map; - - /** - * Register commands - */ - function_map["world:version"] = &WorldserverCommandHandler::Version; - function_map["character:copy-character"] = &WorldserverCommandHandler::CopyCharacter; - function_map["database:version"] = &WorldserverCommandHandler::DatabaseVersion; - function_map["database:set-account-status"] = &WorldserverCommandHandler::DatabaseSetAccountStatus; - function_map["database:schema"] = &WorldserverCommandHandler::DatabaseGetSchema; - function_map["database:dump"] = &WorldserverCommandHandler::DatabaseDump; - function_map["test:test"] = &WorldserverCommandHandler::TestCommand; - function_map["test:expansion"] = &WorldserverCommandHandler::ExpansionTestCommand; - function_map["test:repository"] = &WorldserverCommandHandler::TestRepository; - function_map["test:repository2"] = &WorldserverCommandHandler::TestRepository2; - - EQEmuCommand::HandleMenu(function_map, cmd, argc, argv); - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Shows database version"; - - if (cmd[{"-h", "--help"}]) { - return; - } - - Json::Value database_version; - - database_version["database_version"] = CURRENT_BINARY_DATABASE_VERSION; - database_version["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION; - - std::stringstream payload; - payload << database_version; - - std::cout << payload.str() << std::endl; - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void Version(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Shows server version"; - - if (cmd[{"-h", "--help"}]) { - return; - } - - Json::Value database_version; - - database_version["bots_database_version"] = CURRENT_BINARY_BOTS_DATABASE_VERSION; - database_version["compile_date"] = COMPILE_DATE; - database_version["compile_time"] = COMPILE_TIME; - database_version["database_version"] = CURRENT_BINARY_DATABASE_VERSION; - database_version["server_version"] = CURRENT_VERSION; - - std::stringstream payload; - payload << database_version; - - std::cout << payload.str() << std::endl; - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Sets account status by account name"; - - std::vector arguments = { - "{name}", - "{status}" - }; - - std::vector options = {}; - - if (cmd[{"-h", "--help"}]) { - return; - } - - EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); - - database.SetAccountStatus( - cmd(2).str(), - std::stoi(cmd(3).str()) - ); - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Displays server database schema"; - - if (cmd[{"-h", "--help"}]) { - return; - } - - Json::Value player_tables_json; - std::vector player_tables = DatabaseSchema::GetPlayerTables(); - for (const auto &table: player_tables) { - player_tables_json.append(table); - } - - Json::Value content_tables_json; - std::vector content_tables = DatabaseSchema::GetContentTables(); - for (const auto &table: content_tables) { - content_tables_json.append(table); - } - - Json::Value server_tables_json; - std::vector server_tables = DatabaseSchema::GetServerTables(); - for (const auto &table: server_tables) { - server_tables_json.append(table); - } - - Json::Value login_tables_json; - std::vector login_tables = DatabaseSchema::GetLoginTables(); - for (const auto &table: login_tables) { - login_tables_json.append(table); - } - - Json::Value state_tables_json; - std::vector state_tables = DatabaseSchema::GetStateTables(); - for (const auto &table: state_tables) { - state_tables_json.append(table); - } - - Json::Value version_tables_json; - std::vector version_tables = DatabaseSchema::GetVersionTables(); - for (const auto &table: version_tables) { - version_tables_json.append(table); - } - - Json::Value bot_tables_json; - std::vector bot_tables = DatabaseSchema::GetBotTables(); - for (const auto &table: bot_tables) { - bot_tables_json.append(table); - } - - Json::Value schema; - - schema["content_tables"] = content_tables_json; - schema["login_tables"] = login_tables_json; - schema["player_tables"] = player_tables_json; - schema["server_tables"] = server_tables_json; - schema["state_tables"] = state_tables_json; - schema["version_tables"] = version_tables_json; - schema["bot_tables"] = bot_tables_json; - - std::stringstream payload; - payload << schema; - - std::cout << payload.str() << std::endl; - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Dumps server database tables"; - - std::vector arguments = {}; - std::vector options = { - "--all", - "--content-tables", - "--login-tables", - "--player-tables", - "--bot-tables", - "--state-tables", - "--system-tables", - "--query-serv-tables", - "--table-structure-only", - "--table-lock", - "--dump-path=", - "--dump-output-to-console", - "--drop-table-syntax-only", - "--compress" - }; - - if (cmd[{"-h", "--help"}]) { - return; - } - - EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); - - auto database_dump_service = new DatabaseDumpService(); - bool dump_all = cmd[{"-a", "--all"}]; - - if (!cmd("--dump-path").str().empty()) { - database_dump_service->SetDumpPath(cmd("--dump-path").str()); - } - - /** - * Set Option - */ - database_dump_service->SetDumpContentTables(cmd[{"--content-tables"}] || dump_all); - database_dump_service->SetDumpLoginServerTables(cmd[{"--login-tables"}] || dump_all); - database_dump_service->SetDumpPlayerTables(cmd[{"--player-tables"}] || dump_all); - database_dump_service->SetDumpBotTables(cmd[{"--bot-tables"}] || dump_all); - database_dump_service->SetDumpStateTables(cmd[{"--state-tables"}] || dump_all); - database_dump_service->SetDumpSystemTables(cmd[{"--system-tables"}] || dump_all); - database_dump_service->SetDumpQueryServerTables(cmd[{"--query-serv-tables"}] || dump_all); - database_dump_service->SetDumpAllTables(dump_all); - - database_dump_service->SetDumpWithNoData(cmd[{"--table-structure-only"}]); - database_dump_service->SetDumpTableLock(cmd[{"--table-lock"}]); - database_dump_service->SetDumpWithCompression(cmd[{"--compress"}]); - database_dump_service->SetDumpOutputToConsole(cmd[{"--dump-output-to-console"}]); - database_dump_service->SetDumpDropTableSyntaxOnly(cmd[{"--drop-table-syntax-only"}]); - - /** - * Dump - */ - database_dump_service->Dump(); - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Test command"; - - if (cmd[{"-h", "--help"}]) { - return; - } - - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Expansion test command"; - - if (cmd[{"-h", "--help"}]) { - return; - } - - if (!RuleManager::Instance()->LoadRules(&database, "default", false)) { - LogInfo("No rule set configured, using default rules"); - } - - content_service.SetCurrentExpansion(RuleI(Expansion, CurrentExpansion)); - - std::vector flags = {}; - auto f = ContentFlagsRepository::NewEntity(); - f.enabled = 1; - - std::vector flag_names = { - "hateplane_enabled", - "patch_nerf_7077", - }; - - for (auto &name: flag_names) { - f.flag_name = name; - flags.push_back(f); - } - - content_service.SetContentFlags(flags); - - LogInfo( - "Current expansion is [{}] ({}) is Velious Enabled [{}] Criteria [{}]", - content_service.GetCurrentExpansion(), - content_service.GetCurrentExpansionName(), - content_service.IsTheScarsOfVeliousEnabled() ? "true" : "false", - ContentFilterCriteria::apply() - ); - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Test command"; - - if (cmd[{"-h", "--help"}]) { - return; - } - - /** - * Insert one - */ - auto instance_list_entry = InstanceListRepository::NewEntity(); - - instance_list_entry.zone = 999; - instance_list_entry.version = 1; - instance_list_entry.is_global = 1; - instance_list_entry.start_time = 0; - instance_list_entry.duration = 0; - instance_list_entry.never_expires = 1; - - auto instance_list_inserted = InstanceListRepository::InsertOne(database, instance_list_entry); - - LogInfo("Inserted ID is [{}] zone [{}]", instance_list_inserted.id, instance_list_inserted.zone); - - /** - * Find one - */ - auto found_instance_list = InstanceListRepository::FindOne(database, instance_list_inserted.id); - - LogInfo("Found ID is [{}] zone [{}]", found_instance_list.id, found_instance_list.zone); - - /** - * Update one - */ - LogInfo("Updating instance id [{}] zone [{}]", found_instance_list.id, found_instance_list.zone); - - int update_instance_list_count = InstanceListRepository::UpdateOne(database, found_instance_list); - - found_instance_list.zone = 777; - - LogInfo( - "Updated instance id [{}] zone [{}] affected [{}]", - found_instance_list.id, - found_instance_list.zone, - update_instance_list_count - ); - - - /** - * Delete one - */ - int deleted = InstanceListRepository::DeleteOne(database, found_instance_list.id); - - LogInfo("Deleting one instance [{}] deleted count [{}]", found_instance_list.id, deleted); - - /** - * Insert many - */ - std::vector instance_lists; - - auto instance_list_entry_bulk = InstanceListRepository::NewEntity(); - - instance_list_entry_bulk.zone = 999; - instance_list_entry_bulk.version = 1; - instance_list_entry_bulk.is_global = 1; - instance_list_entry_bulk.start_time = 0; - instance_list_entry_bulk.duration = 0; - instance_list_entry_bulk.never_expires = 1; - - for (int i = 0; i < 10; i++) { - instance_lists.push_back(instance_list_entry_bulk); - } - - /** - * Insert Many - */ - int inserted_count = InstanceListRepository::InsertMany(database, instance_lists); - - LogInfo("Bulk insertion test, inserted [{}]", inserted_count); - - for (auto &entry: InstanceListRepository::GetWhere(database, fmt::format("zone = {}", 999))) { - LogInfo("Iterating through entry id [{}] zone [{}]", entry.id, entry.zone); - } - - LogInfo("[Max ID] {}", InstanceListRepository::GetMaxId(database)); - LogInfo("[Count] {}", InstanceListRepository::Count(database)); - LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 999")); - LogInfo("[Count Where] {}", InstanceListRepository::Count(database, "zone = 777")); - - /** - * Delete where - */ - int deleted_count = InstanceListRepository::DeleteWhere(database, fmt::format("zone = {}", 999)); - - LogInfo("Bulk deletion test, deleted [{}]", deleted_count); - - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Test command"; - - if (cmd[{"-h", "--help"}]) { - return; - } - - auto zones = ZoneRepository::GetWhere(content_db, "short_name = 'anguish'"); - - for (auto &zone: zones) { - LogInfo( - "Zone [{}] long_name [{}] id [{}]", - zone.short_name, - zone.long_name, - zone.id - ); - } - } - - /** - * @param argc - * @param argv - * @param cmd - * @param description - */ - void CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description) - { - description = "Copies a character into a destination account"; - - std::vector arguments = { - "source_character_name", - "destination_character_name", - "destination_account_name" - }; - std::vector options = {}; - - if (cmd[{"-h", "--help"}]) { - return; - } - - EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); - - std::string source_character_name = cmd(2).str(); - std::string destination_character_name = cmd(3).str(); - std::string destination_account_name = cmd(4).str(); - - LogInfo( - "Attempting to copy character [{}] to [{}] via account [{}]", - source_character_name, - destination_character_name, - destination_account_name - ); - - database.CopyCharacter( - source_character_name, - destination_character_name, - destination_account_name - ); - } - -} diff --git a/world/world_server_command_handler.h b/world/world_server_command_handler.h deleted file mode 100644 index 2d7c59f8e..000000000 --- a/world/world_server_command_handler.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY except by those people which sell it, which - * are required to give you total support for your newly bought product; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "iostream" -#include "../common/cli/eqemu_command_handler.h" - -#ifndef EQEMU_WORLD_SERVER_COMMAND_HANDLER_H -#define EQEMU_WORLD_SERVER_COMMAND_HANDLER_H - -namespace WorldserverCommandHandler { - void CommandHandler(int argc, char **argv); - void Version(int argc, char **argv, argh::parser &cmd, std::string &description); - void CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description); - void DatabaseVersion(int argc, char **argv, argh::parser &cmd, std::string &description); - void DatabaseSetAccountStatus(int argc, char **argv, argh::parser &cmd, std::string &description); - void DatabaseGetSchema(int argc, char **argv, argh::parser &cmd, std::string &description); - void DatabaseDump(int argc, char **argv, argh::parser &cmd, std::string &description); - void TestCommand(int argc, char **argv, argh::parser &cmd, std::string &description); - void ExpansionTestCommand(int argc, char **argv, argh::parser &cmd, std::string &description); - void TestRepository(int argc, char **argv, argh::parser &cmd, std::string &description); - void TestRepository2(int argc, char **argv, argh::parser &cmd, std::string &description); -}; - - -#endif //EQEMU_WORLD_SERVER_COMMAND_HANDLER_H