Horizon Official Technical Documentation
Server Class Reference

#include <Server.hpp>

+ Inheritance diagram for Server:
+ Collaboration diagram for Server:

Public Member Functions

 Server ()
 
 ~Server ()
 
void parse_exec_args (const char *argv[], int argc)
 
virtual void initialize ()
 
virtual void finalize ()
 
virtual void post_initialize ()
 
virtual void post_finalize ()
 
void print_help ()
 
struct general_server_configurationgeneral_conf ()
 
bool parse_common_configs (sol::table &cfg)
 
std::shared_ptr< boost::mysql::tcp_ssl_connection > get_database_connection ()
 
bool test_database_connection ()
 
- Public Member Functions inherited from Kernel
 Kernel (general_server_configuration &config)
 
 ~Kernel ()
 
virtual void initialize ()=0
 
virtual void finalize ()=0
 
virtual void post_initialize ()=0
 
virtual void post_finalize ()=0
 
struct general_server_configurationgeneral_conf ()
 
template<typename T >
std::shared_ptr< T > get_component (std::string uuid)
 
template<typename T >
std::shared_ptr< T > get_component_of_type (Horizon::System::runtime_module_type type, int segment_number=1)
 
template<typename T >
void register_component (Horizon::System::runtime_module_type type, T &&component)
 
template<typename T >
void register_component (Horizon::System::runtime_module_type type, std::shared_ptr< T > component)
 
void deregister_component (Horizon::System::runtime_module_type type, int segment_number=1)
 
int get_registered_component_count_of_type (Horizon::System::runtime_module_type type)
 
template<typename ComponentType , std::size_t Priority, typename Key , typename Value >
int get_segment_number_for_resource (Horizon::System::runtime_module_type module_t, Key resource_key, Value resource_not_found_value)
 
int get_component_count ()
 
KernelComponentsget_components ()
 
void system_routine_queue_push (std::shared_ptr< Horizon::System::RuntimeContext > context)
 
void system_routine_queue_push (std::shared_ptr< Horizon::System::RuntimeContextChain > context)
 
void system_routine_process_queue ()
 
void system_routine_register (Horizon::System::runtime_module_type module_t, Horizon::System::runtime_synchronization_method sync_t, std::shared_ptr< Horizon::System::RuntimeContext > context)
 
Horizon::System::SystemRoutineManagerget_system_routine_manager ()
 
boost::asio::io_context & get_io_context ()
 
void set_signal_interrupt_command_line_loop (bool signal)
 
bool get_signal_interrupt_command_line_loop ()
 

Protected Attributes

struct general_server_configuration general_config
 
- Protected Attributes inherited from Kernel
boost::asio::io_context _io_context_global
 
KernelComponents _components
 
general_server_configuration _config
 

Constructor & Destructor Documentation

◆ Server()

Server::Server ( )
301{
302 auto now = std::chrono::system_clock::now();
303 auto in_time_t = std::chrono::system_clock::to_time_t(now);
304
305 HLog(info) << "Copyright (c) https://lab.projecthorizon.onl/horizon/horizon";
306 HLog(info) << "Copyright: " << VER_LEGALCOPYRIGHT_STR;
307 HLog(info) << "Date: " << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d");
308 HLog(info) << "Compile CXX Flags: " << _CMAKE_CXX_FLAGS;
309 HLog(info) << "Version: " << VER_PRODUCTVERSION_STR;
310 HLog(info) << "Last Update: " << _DATE;
311 HLog(info) << "Branch: " << _BRANCH;
312 HLog(info) << "Boost Version: v" << (BOOST_VERSION / 100000) << "." << (BOOST_VERSION / 100 % 1000) << "." << (BOOST_VERSION % 100);
313 HLog(info) << "Client Information: " << CLIENT_TYPE << " " << PACKET_VERSION;
314}
#define PACKET_VERSION
Definition: Horizon.hpp:46
#define CLIENT_TYPE
Definition: Horizon.hpp:43
#define HLog(type)
Definition: Logger.hpp:122
Kernel(general_server_configuration &config)
Definition: Server.cpp:53
struct general_server_configuration & general_conf()
Definition: Server.hpp:570

References CLIENT_TYPE, HLog, and PACKET_VERSION.

◆ ~Server()

Server::~Server ( )
317{
318}

Member Function Documentation

◆ finalize()

void Server::finalize ( )
virtual

Implements Kernel.

Reimplemented in Horizon::Zone::ZoneKernel, Horizon::Zone::ZoneServer, Horizon::Auth::AuthServer, and Horizon::Char::CharServer.

531{
532 if (!general_conf().is_test_run() && !general_conf().is_test_run_minimal()) {
533 get_component_of_type<CommandLineProcess>(Horizon::System::RUNTIME_COMMANDLINE)->finalize();
535 }
536
537 get_component_of_type<DatabaseProcess>(Horizon::System::RUNTIME_DATABASE)->finalize();
539}
void deregister_component(Horizon::System::runtime_module_type type, int segment_number=1)
Definition: Server.hpp:493
@ RUNTIME_DATABASE
Definition: System.hpp:88
@ RUNTIME_COMMANDLINE
Definition: System.hpp:83

References Kernel::deregister_component(), general_conf(), Horizon::System::RUNTIME_COMMANDLINE, and Horizon::System::RUNTIME_DATABASE.

Referenced by Horizon::Zone::ZoneKernel::finalize(), Horizon::Auth::AuthServer::finalize(), and Horizon::Char::CharServer::finalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ general_conf()

◆ get_database_connection()

std::shared_ptr< boost::mysql::tcp_ssl_connection > Server::get_database_connection ( )
inline
575 {
576 return get_component_of_type<DatabaseProcess>(Horizon::System::RUNTIME_DATABASE)->get_connection();
577 }

References Horizon::System::RUNTIME_DATABASE.

Referenced by Horizon::Auth::AuthServer::clicmd_create_new_account(), Horizon::Auth::AuthServer::clicmd_reset_password(), and test_database_connection().

+ Here is the caller graph for this function:

◆ initialize()

void Server::initialize ( )
virtual

Initialize Commandline Interface

Implements Kernel.

Reimplemented in Horizon::Zone::ZoneKernel, Horizon::Zone::ZoneServer, Horizon::Auth::AuthServer, and Horizon::Char::CharServer.

517{
521 if (general_conf().is_test_run() && general_conf().is_test_run_minimal()) {
522 HLog(info) << "Command line not supported during test-runs... skipping.";
523 } else {
524 HLog(info) << "Horizon Command-Line initializing...";
525 register_component(Horizon::System::RUNTIME_COMMANDLINE, std::make_shared<CommandLineProcess>(this));
526 get_component_of_type<CommandLineProcess>(Horizon::System::RUNTIME_COMMANDLINE)->initialize();
527 }
528}
void register_component(Horizon::System::runtime_module_type type, T &&component)
Definition: Server.hpp:475

References general_conf(), HLog, Kernel::register_component(), and Horizon::System::RUNTIME_COMMANDLINE.

Referenced by Horizon::Zone::ZoneKernel::initialize(), Horizon::Auth::AuthServer::initialize(), and Horizon::Char::CharServer::initialize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_common_configs()

bool Server::parse_common_configs ( sol::table &  cfg)
461{
462 std::string tmp_string{""};
463
464 general_conf().set_listen_ip(tbl.get_or("bind_ip", std::string("127.0.0.1")));
465 general_conf().set_listen_port(tbl.get_or("bind_port", 0));
466
467 if (general_conf().get_listen_port() == 0) {
468 HLog(error) << "Invalid or non-existent configuration for 'bind_port', Halting...";
469 return false;
470 }
471
472 sol::table db_tbl = tbl.get<sol::table>("database_config");
473
474 if (general_conf().get_db_host().empty() || general_conf().get_db_user().empty() || general_conf().get_db_pass().empty() || general_conf().get_db_database().empty()) {
475
476 try {
477 general_conf().set_db_host(db_tbl.get_or<std::string>("host", "127.0.0.1"));
478 general_conf().set_db_user(db_tbl.get_or<std::string>("user", "horizon"));
479 general_conf().set_db_database(db_tbl.get_or<std::string>("db", "horizon"));
480 general_conf().set_db_pass(db_tbl.get_or<std::string>("pass", "horizon"));
481 general_conf().set_db_port(db_tbl.get_or<uint16_t>("port", 33060));
482
483 register_component(Horizon::System::RUNTIME_DATABASE, std::make_shared<DatabaseProcess>(this));
484
485 get_component_of_type<DatabaseProcess>(Horizon::System::RUNTIME_DATABASE)->initialize(
487 1,
488 general_conf().get_db_host(),
489 general_conf().get_db_port(),
490 general_conf().get_db_user(),
491 general_conf().get_db_pass(),
492 general_conf().get_db_database());
493
494 HLog(info) << "Database tcp://" << general_conf().get_db_user()
495 << ":" << general_conf().get_db_pass()
496 << "@" << general_conf().get_db_host()
497 << ":" << general_conf().get_db_port()
498 << "/" << general_conf().get_db_database()
499 << (test_database_connection() ? " (connected)" : " (not connected)");
500 }
501 catch (const boost::mysql::error_with_diagnostics &error) {
502 HLog(error) << error.what() << ".";
503 return false;
504 }
505 catch (const std::exception &error) {
506 HLog(error) << error.what() << ".";
507 return false;
508 }
509 }
510
511 return true;
512}
boost::asio::io_context & get_io_context()
Definition: Server.cpp:70
bool test_database_connection()
Definition: Server.cpp:555
void set_listen_ip(const std::string &listen_ip)
Definition: ServerConfiguration.hpp:62
const std::string & get_db_host() const
Definition: ServerConfiguration.hpp:69
void set_db_user(std::string &&user)
Definition: ServerConfiguration.hpp:73
const std::string & get_db_pass() const
Definition: ServerConfiguration.hpp:75
void set_db_port(uint16_t port)
Definition: ServerConfiguration.hpp:82
const uint16_t & get_db_port() const
Definition: ServerConfiguration.hpp:81
const std::string & get_db_user() const
Definition: ServerConfiguration.hpp:72
void set_listen_port(uint16_t listen_port)
Definition: ServerConfiguration.hpp:65
void set_db_pass(std::string &&pass)
Definition: ServerConfiguration.hpp:76
const std::string & get_db_database() const
Definition: ServerConfiguration.hpp:78
void set_db_database(std::string &&database)
Definition: ServerConfiguration.hpp:79
void set_db_host(std::string &&host)
Definition: ServerConfiguration.hpp:70

References general_conf(), general_server_configuration::get_db_database(), general_server_configuration::get_db_host(), general_server_configuration::get_db_pass(), general_server_configuration::get_db_port(), general_server_configuration::get_db_user(), Kernel::get_io_context(), HLog, Kernel::register_component(), Horizon::System::RUNTIME_DATABASE, general_server_configuration::set_db_database(), general_server_configuration::set_db_host(), general_server_configuration::set_db_pass(), general_server_configuration::set_db_port(), general_server_configuration::set_db_user(), general_server_configuration::set_listen_ip(), general_server_configuration::set_listen_port(), and test_database_connection().

Referenced by Horizon::Auth::AuthServer::read_config(), Horizon::Char::CharServer::read_config(), and Horizon::Zone::ZoneServer::read_config().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_exec_args()

void Server::parse_exec_args ( const char *  argv[],
int  argc 
)
326{
327 std::string started_with_args;
328 for (int i = 1; i < argc; ++i) {
329 started_with_args.append(argv[i]).append(" ");
330
331 std::string arg(argv[i]);
332 std::vector<std::string> separated_args;
333 boost::algorithm::split(separated_args, arg, boost::algorithm::is_any_of("="));
334
335 if (separated_args.size() == 1) { // for parameters with only 1 part no "=" sign
336 std::string arg = separated_args.at(0);
337 if (arg.compare("--test-run") == 0) {
338 HLog(info) << "Horizon test mode (without command-line, network) intiated.";
340 } else if (arg.compare("--test-run-with-network") == 0) {
341 HLog(info) << "Horizon test mode (with network) intiated.";
343 } else if (arg.compare("--help") == 0) {
344 print_help();
345 } else if (arg.compare("--version") == 0) {
346 HLog(info) << "Version: " << VER_PRODUCTVERSION_STR;
347 }
348 } else if (separated_args.size() == 0) { // no parameters provided
349 HLog(error) << "Horizon started with no command line arguments.";
350 print_help();
351 } else { // for parameters with 2 parts separated by "=" sign
352 std::string arg = separated_args.at(0);
353 std::string val = separated_args.at(1);
354
355 if (arg.compare("--with-config") == 0) {
356 HLog(info) << "Loading configurations from '" << val << "'.";
358 if (!exists(general_conf().get_config_file_path())) {
359 HLog(error) << "Configuration file path '" << val << "' does not exist!";
360 continue;
361 }
362 } else if (arg.compare("--db-connection") == 0) {
363 std::string conn_str = separated_args.at(1);
364 if (conn_str.empty()) {
365 HLog(error) << "No database connection string provided. Expected format: user:password@host:port/database";
366 continue;
367 }
368 // validate connection string format: user:password@host:port/database
369 std::vector<std::string> db_parts;
370 boost::algorithm::split(db_parts, conn_str, boost::algorithm::is_any_of("@"));
371 if (db_parts.size() != 2) {
372 HLog(error) << "Invalid database connection string format. Expected format: user:password@host:port/database";
373 continue;
374 }
375 std::vector<std::string> user_pass_parts;
376 boost::algorithm::split(user_pass_parts, db_parts.at(0), boost::algorithm::is_any_of(":"));
377 if (user_pass_parts.size() != 2) {
378 HLog(error) << "Invalid user:password format in database connection string. Expected format: user:password@host:port/database";
379 continue;
380 }
381 std::vector<std::string> host_port_db_parts;
382 boost::algorithm::split(host_port_db_parts, db_parts.at(1), boost::algorithm::is_any_of(":"));
383 if (host_port_db_parts.size() != 2) {
384 HLog(error) << "Invalid host:port/database format in database connection string. Expected format: user:password@host:port/database";
385 continue;
386 }
387 std::string host = host_port_db_parts.at(0);
388 // set user and password
389 if (user_pass_parts.size() != 2) {
390 HLog(error) << "Invalid user:password format in database connection string. Expected format: user:password@host:port/database";
391 continue;
392 }
393 std::string user = user_pass_parts.at(0);
394 std::string pass = user_pass_parts.at(1);
395 if (user.empty()) {
396 HLog(error) << "User cannot be empty in database connection string. Expected format: user:password@host:port/database";
397 continue;
398 }
399 if (pass.empty()) {
400 HLog(error) << "Password cannot be empty in database connection string. Expected format: user:password@host:port/database";
401 continue;
402 }
403 if (host.empty()) {
404 HLog(error) << "Host cannot be empty in database connection string. Expected format: user:password@host:port/database";
405 continue;
406 }
407 general_conf().set_db_user(std::move(user));
408 general_conf().set_db_pass(std::move(pass));
409
410 general_conf().set_db_host(std::move(host));
411
412 // get port/database
413 std::vector<std::string> db_name_parts;
414 boost::algorithm::split(db_name_parts, host_port_db_parts.at(1), boost::algorithm::is_any_of("/"));
415 if (db_name_parts.size() != 2) {
416 HLog(error) << "Invalid port/database format in database connection string. Expected format: user:password@host:port/database";
417 continue;
418 }
419 std::string db_name = db_name_parts.at(1);
420 if (db_name.empty()) {
421 HLog(error) << "Database name cannot be empty in database connection string.";
422 continue;
423 }
424 std::string db_port = db_name_parts.at(0);
425 if (db_port.empty()) {
426 HLog(error) << "Port cannot be empty in database connection string.";
427 continue;
428 }
429 general_conf().set_db_port(static_cast<uint16_t>(std::stoi(db_port)));
430 general_conf().set_db_database(std::move(db_name));
431 // set port
432
433 register_component(Horizon::System::RUNTIME_DATABASE, std::make_shared<DatabaseProcess>(this));
434
435 get_component_of_type<DatabaseProcess>(Horizon::System::RUNTIME_DATABASE)->initialize(
437 1,
438 general_conf().get_db_host(),
439 general_conf().get_db_port(),
440 general_conf().get_db_user(),
441 general_conf().get_db_pass(),
442 general_conf().get_db_database());
443
444 HLog(info) << "Manually set database connection string: tcp://" << general_conf().get_db_user()
445 << ":" << general_conf().get_db_pass()
446 << "@" << general_conf().get_db_host()
447 << ":" << general_conf().get_db_port()
448 << "/" << general_conf().get_db_database()
449 << (test_database_connection() ? " (connected)" : " (not connected)");
450 }
451 }
452 }
453
454 HLog(info) << "Started with args:" << started_with_args;
455}
@ TEST_RUN_MINIMAL
Definition: ServerConfiguration.hpp:40
@ TEST_RUN_WITH_NETWORK
Definition: ServerConfiguration.hpp:41
void print_help()
Definition: Server.cpp:320
void set_test_run(test_run_type type)
Definition: ServerConfiguration.hpp:47
void set_config_file_path(const boost::filesystem::path &path)
Definition: ServerConfiguration.hpp:56

References general_conf(), general_server_configuration::get_db_database(), general_server_configuration::get_db_host(), general_server_configuration::get_db_pass(), general_server_configuration::get_db_port(), general_server_configuration::get_db_user(), Kernel::get_io_context(), HLog, print_help(), Kernel::register_component(), Horizon::System::RUNTIME_DATABASE, general_server_configuration::set_config_file_path(), general_server_configuration::set_db_database(), general_server_configuration::set_db_host(), general_server_configuration::set_db_pass(), general_server_configuration::set_db_port(), general_server_configuration::set_db_user(), general_server_configuration::set_test_run(), test_database_connection(), TEST_RUN_MINIMAL, and TEST_RUN_WITH_NETWORK.

+ Here is the call graph for this function:

◆ post_finalize()

void Server::post_finalize ( )
virtual

Implements Kernel.

551{
553}
virtual void post_finalize()=0
Definition: Server.cpp:88

References Kernel::post_finalize().

Referenced by Horizon::Zone::ZoneServer::finalize(), Horizon::Auth::AuthServer::finalize(), and Horizon::Char::CharServer::finalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ post_initialize()

void Server::post_initialize ( )
virtual

Implements Kernel.

542{
544
545 for (auto i = _components.begin(); i != _components.end(); i++) {
546 HLog(info) << "Kernel component '" << i->second.ptr->get_type_string() << " (" << i->second.segment_number << ")': " << (i->second.ptr->is_initialized() == true ? "Online" : "Offline (Starting)") << " { CPU: " << i->second.ptr->get_thread_cpu_id() << ", uuid: " << i->first << " }";
547 }
548}
KernelComponents _components
Definition: Server.hpp:545
virtual void post_initialize()=0
Definition: Server.cpp:83

References Kernel::_components, HLog, and Kernel::post_initialize().

Referenced by Horizon::Zone::ZoneServer::initialize(), Horizon::Auth::AuthServer::initialize(), and Horizon::Char::CharServer::initialize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_help()

void Server::print_help ( )
321{
322 HLog(error) << "usage: <server> [--version] [--help] [--with-config=<file_with_path>]";
323}

References HLog.

Referenced by parse_exec_args().

+ Here is the caller graph for this function:

◆ test_database_connection()

bool Server::test_database_connection ( )
556{
557 try {
558 const char *sql = "SELECT 'Hello World!'";
559 boost::mysql::results result;
560 get_database_connection()->execute(sql, result);
561 if (result.rows().at(0).at(0).as_string().compare("Hello World!") == 0)
562 return true;
563 } catch (boost::mysql::error_with_diagnostics &error) {
564 HLog(error) << error.what();
565 }
566 return false;
567}
std::shared_ptr< boost::mysql::tcp_ssl_connection > get_database_connection()
Definition: Server.hpp:574

References get_database_connection(), and HLog.

Referenced by parse_common_configs(), and parse_exec_args().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ general_config

struct general_server_configuration Server::general_config
protected

Referenced by general_conf().


The documentation for this class was generated from the following files: