#include #include #include "bootstrap/bootstrap.h" #include "options/parser.h" #include "logger/logger.h" #include "util/util.h" #include "client/configuration.h" // Bind Options To Environmental Variable static void bind_to_env(const char *env, const bool value) { if (value) { set_and_print_env(env, "1"); } } static void setup_environment(const options_t &options) { // Clear Internal Variables clear_internal_env_vars(); // Passthrough Options To Game bind_to_env(_MCPI_SERVER_MODE_ENV, options.server_mode); bind_to_env(_MCPI_BENCHMARK_ENV, options.benchmark); bind_to_env(_MCPI_ONLY_GENERATE_ENV, options.only_generate); bind_to_env(_MCPI_FORCE_HEADLESS_ENV, options.force_headless); bind_to_env(_MCPI_FORCE_NON_HEADLESS_ENV, options.force_non_headless); // GTK Dark Mode set_and_print_env("GTK_THEME", "Adwaita:dark"); // Configure PATH { // Get Binary Directory const std::string binary_directory = get_binary_directory(); std::string new_path = binary_directory + "/bin"; // Add Existing PATH { const char *value = getenv("PATH"); if (value != nullptr && strlen(value) > 0) { new_path += std::string(":") + value; } } // Set And Free set_and_print_env("PATH", new_path.c_str()); } // Setup MCPI_HOME const char *custom_profile_directory = getenv(MCPI_PROFILE_DIRECTORY_ENV); if (custom_profile_directory != nullptr) { // Custom Directory custom_profile_directory = realpath(custom_profile_directory, nullptr); ALLOC_CHECK(custom_profile_directory); set_and_print_env(_MCPI_HOME_ENV, custom_profile_directory); free((void *) custom_profile_directory); } else if (!reborn_is_server()) { // Ensure $HOME const char *home = getenv("HOME"); if (home == nullptr) { ERR("$HOME Is Not Set"); } set_and_print_env(_MCPI_HOME_ENV, home); } else { // Set Home To Current Directory, So World Data Is Stored There char *launch_directory = getcwd(nullptr, 0); ALLOC_CHECK(launch_directory); set_and_print_env(_MCPI_HOME_ENV, launch_directory); free(launch_directory); } // Create If Needed const std::string minecraft_folder = std::string(getenv(_MCPI_HOME_ENV)) + get_home_subdirectory_for_game_data(); ensure_directory(minecraft_folder.c_str()); } // Non-Launch Commands static void handle_non_launch_commands(const options_t &options) { if (options.copy_sdk) { const std::string binary_directory = get_binary_directory(); copy_sdk(binary_directory, false); fflush(stdout); exit(EXIT_SUCCESS); } } // Start The Game static void start_game(const options_t &options) { // Disable stdout Buffering setvbuf(stdout, nullptr, _IONBF, 0); // Setup Crash Reporting if (!options.disable_logger) { setup_logger(); } // Configure Client Options if (!reborn_is_server()) { configure_client(options); } // Bootstrap bootstrap(options); } // Main int main(int argc, char *argv[]) { // Parse Options options_t options = parse_options(argc, argv); // Set Debug Tag reborn_debug_tag = "(Launcher) "; // Debug Logging unsetenv(_MCPI_LOG_FD_ENV); bind_to_env(MCPI_DEBUG_ENV, options.debug); // Setup Environment setup_environment(options); // Handle Non-Launch Commands (Copy SDK, Print Feature Flags, Etc) handle_non_launch_commands(options); handle_non_launch_client_only_commands(options); // Start The Game start_game(options); }