From e4483eca01b48b943cd0461e24a74ae1a3139ed4 Mon Sep 17 00:00:00 2001 From: Nicolas James Date: Wed, 12 Feb 2025 21:57:46 +1100 Subject: Update to most recent version (old initial commit) --- src/main.cc | 193 ------------------------------------------------------------ 1 file changed, 193 deletions(-) delete mode 100644 src/main.cc (limited to 'src/main.cc') diff --git a/src/main.cc b/src/main.cc deleted file mode 100644 index 56efb55..0000000 --- a/src/main.cc +++ /dev/null @@ -1,193 +0,0 @@ -#include "main.hh" - -static void set_signal(const decltype(SIGINT) signal, - void (*const callback)(int)) { - struct sigaction sa {}; - sa.sa_handler = callback; - sa.sa_flags = 0; - if (sigaction(signal, &sa, nullptr) == -1) { - throw std::runtime_error("failed to set signal handler for signal " + - std::to_string(signal)); - } -} - -// Parse arg, store result in dest after casting with boost::lexical_cast. -template -static bool maybe_parse_arg(std::vector& args, - const std::initializer_list& keys, - T& dest) noexcept { - const auto find_it = std::ranges::find_if(args, [&keys](const auto& arg) { - return std::ranges::find(keys, arg) != std::end(keys); - }); - - if (find_it == std::end(args)) { - return false; - } - - try { - const auto i = static_cast(find_it - std::begin(args)); - dest = boost::lexical_cast(args.at(i + 1u)); - } catch (const boost::bad_lexical_cast& e) { - shared::print::fault("bad type conversion for \"" + - std::string{*find_it} + "\" arg\n"); - std::exit(EXIT_FAILURE); - } catch (const std::out_of_range& e) { - shared::print::fault("missing \"" + std::string{*find_it} + "\" arg\n"); - std::exit(EXIT_FAILURE); - } - - args.erase(find_it, std::next(find_it, 2)); - - return true; -} - -// Parse arg, return true or false if arg exists. -static bool -maybe_parse_arg(std::vector& args, - const std::initializer_list& keys) noexcept { - - const auto find_it = std::ranges::find_if(args, [&keys](const auto& arg) { - return std::ranges::find(keys, arg) != std::end(keys); - }); - - if (find_it == std::end(args)) { - return false; - } - - args.erase(find_it); - return true; -} - -static void do_server(const std::string_view address, - const std::string_view port) noexcept { - try { - server::main(address, port); - } catch (const std::exception& e) { - shared::print::fault(std::string{"exception in server!\n"} + - " what: " + e.what() + '\n'); - std::exit(EXIT_FAILURE); - } -} - -static void do_client(const std::string_view address, - const std::string_view port) noexcept { - try { - client::main(address, port); - } catch (const std::exception& e) { - shared::print::fault(std::string{"exception in client!\n"} + - " what: " + e.what() + '\n'); - std::exit(EXIT_FAILURE); - } -} - -static void init() noexcept { - // Because we use noexcept liberally, exceptions are often not unwound. - std::set_terminate([]() { - try { - throw; - } catch (const std::exception& e) { - shared::print::fault(std::string{"unhandled exception!\n"} + - " what: " + e.what() + '\n'); - - constexpr std::size_t BACKTRACE_BUF_SIZE = 64; - std::array bt_buffer{}; - const int nptrs = - backtrace(std::data(bt_buffer), std::size(bt_buffer)); - char** strings = backtrace_symbols(std::data(bt_buffer), nptrs); - - shared::print::message("\n backtrace:\n", false); - for (int i = 0; i < nptrs; ++i) { - shared::print::message(" " + std::string{strings[i]} + '\n', - false); - } - free(strings); // controversial - - } catch (...) { - } - std::exit(EXIT_FAILURE); - }); - - set_signal(SIGPIPE, SIG_IGN); - set_signal(SIGINT, []([[maybe_unused]] const int signum) { - shared::print::warn(" interrupt signal received\n", false); - shared::should_exit = true; // graceful cleanup - }); - -#ifndef NDEBUG - shared::print::debug( - "This binary is a debug build and should not be used in production.\n", - false); -#endif -} - -int main(const int argc, const char* const argv[]) { - GOOGLE_PROTOBUF_VERIFY_VERSION; - - // Default argument values, which starts a multiplayer server with a client. - std::string address = "0.0.0.0"; - std::string port = "8191"; - bool has_address = false; - bool has_headless = false; - { - std::vector args; - for (auto i = 1; i < argc; ++i) { - args.emplace_back(argv[i]); - } - - if (maybe_parse_arg(args, {"--help", "-h"})) { - // clang-format off - std::cout << " --help -h : display this, quit\n" - " --address -a : connect elsewhere\n" - " --port -p : override the default port\n" - " --headless -H : run without a client\n" - " --singleplayer -s : avoid hosting a lan server\n" - " --seed -S : manually set the worldseed\n" - " --directory -d : manually set the directory\n" - " --tickrate -t : override the default tickrate\n" - " --distance -D : set the max chunk distance the server provides\n"; - // clang-format on - std::exit(EXIT_SUCCESS); - } - - has_address = maybe_parse_arg(args, {"--address", "-a"}, address); - has_headless = maybe_parse_arg(args, {"--headless", "-H"}); - - maybe_parse_arg(args, {"--port", "-p"}, port); - maybe_parse_arg(args, {"--seed", "-S"}, server::state.seed); - maybe_parse_arg(args, {"--directory", "-d"}, server::state.directory); - maybe_parse_arg(args, {"--tickrate", "-t"}, server::state.tickrate); - maybe_parse_arg(args, {"--distance", "-D"}, - server::state.draw_distance); - - if (maybe_parse_arg(args, {"--singleplayer", "-s"})) { - if (has_address) { - shared::print::warn("singleplayer argument ignored due " - "to conflicting address argument\n"); - } - address = "localhost"; - } - - std::ranges::for_each(args, [](const auto& arg) { - shared::print::warn("unused argument \"" + std::string{arg} + - "\"\n"); - }); - } - - init(); - - // Split server/client execution, while waiting for server to boot before - // running the client. - std::jthread server_thread; - if (!has_address) { - if (has_headless) { - do_server(address, port); - std::exit(EXIT_SUCCESS); - } - server_thread = std::jthread{do_server, address, port}; - while (!server::has_initialised) { - continue; - } - } - - do_client(address, port); -} -- cgit v1.2.3