diff --git a/launcher/src/bootstrap/assets.cpp b/launcher/src/bootstrap/assets.cpp index d288abaff4..46dce00a3f 100644 --- a/launcher/src/bootstrap/assets.cpp +++ b/launcher/src/bootstrap/assets.cpp @@ -1,4 +1,4 @@ -#include +#include #include "bootstrap.h" #include "../util/util.h" diff --git a/launcher/src/bootstrap/bootstrap.cpp b/launcher/src/bootstrap/bootstrap.cpp index 9508b89c64..069de05f09 100644 --- a/launcher/src/bootstrap/bootstrap.cpp +++ b/launcher/src/bootstrap/bootstrap.cpp @@ -2,9 +2,9 @@ #include #include -#include +#include #include -#include +#include #include "../util/util.h" #include "bootstrap.h" diff --git a/launcher/src/bootstrap/debug.cpp b/launcher/src/bootstrap/debug.cpp index 3e6845aed2..06cdfe1ebe 100644 --- a/launcher/src/bootstrap/debug.cpp +++ b/launcher/src/bootstrap/debug.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include "bootstrap.h" diff --git a/launcher/src/bootstrap/mods.cpp b/launcher/src/bootstrap/mods.cpp index 9f925231e5..86d6bb15bb 100644 --- a/launcher/src/bootstrap/mods.cpp +++ b/launcher/src/bootstrap/mods.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include "bootstrap.h" #include "../util/util.h" diff --git a/launcher/src/bootstrap/patchelf.cpp b/launcher/src/bootstrap/patchelf.cpp index 3f2489da7c..323dd34ab2 100644 --- a/launcher/src/bootstrap/patchelf.cpp +++ b/launcher/src/bootstrap/patchelf.cpp @@ -4,7 +4,7 @@ #include -#include +#include #include #include "bootstrap.h" diff --git a/launcher/src/client/cache.cpp b/launcher/src/client/cache.cpp index 4b8560463a..254b142759 100644 --- a/launcher/src/client/cache.cpp +++ b/launcher/src/client/cache.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include "cache.h" #include "configuration.h" @@ -17,10 +18,23 @@ static std::string get_cache_path() { } // Load +template +static T simple_read(std::ifstream &stream) { + T out; + stream.read((char *) &out, sizeof(T)); + return out; +} +template <> +std::string simple_read(std::ifstream &stream) { + std::string out; + if (!std::getline(stream, out, '\0')) { + out = ""; + } + return out; +} static void read_cache(std::ifstream &stream, State &ret) { // Cache Version - unsigned char cache_version; - stream.read((char *) &cache_version, 1); + const unsigned char cache_version = simple_read(stream); if (stream.eof()) { // Unable To Read Version WARN("Unable To Read Launcher Cache Version"); @@ -28,10 +42,10 @@ static void read_cache(std::ifstream &stream, State &ret) { } // Support Older Versions - bool load_gui_scale = true; + bool load_new_fields = true; if (cache_version == 0) { // Pre-v3.0.0 Cache - load_gui_scale = false; + load_new_fields = false; } else if (cache_version != (unsigned char) CACHE_VERSION) { // Invalid Version WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", CACHE_VERSION, (int) cache_version); @@ -40,21 +54,18 @@ static void read_cache(std::ifstream &stream, State &ret) { // Load Username And Render Distance State state; - std::getline(stream, state.username, '\0'); - std::getline(stream, state.render_distance, '\0'); - if (load_gui_scale) { - stream.read((char *) &state.gui_scale, sizeof(float)); + state.username = simple_read(stream); + state.render_distance = simple_read(stream); + if (load_new_fields) { + state.gui_scale = simple_read(stream); + state.servers.load(simple_read(stream)); } // Load Feature Flags std::unordered_map flags; - std::string flag; - while (!stream.eof() && std::getline(stream, flag, '\0')) { - if (!flag.empty()) { - bool is_enabled = false; - stream.read((char *) &is_enabled, sizeof(bool)); - flags[flag] = is_enabled; - } + while (!stream.eof()) { + std::string flag = simple_read(stream); + flags[flag] = simple_read(stream); stream.peek(); } state.flags.from_cache(flags); @@ -101,24 +112,30 @@ State load_cache() { } // Save -static void write_env_to_stream(std::ostream &stream, const std::string &value) { - stream.write(value.c_str(), int(value.size()) + 1); +template +static void simple_write(std::ostream &stream, const T &val) { + stream.write((const char *) &val, sizeof(T)); +} +template <> +void simple_write(std::ostream &stream, const std::string &val) { + stream.write(val.c_str(), int(val.size()) + 1); } void write_cache(std::ostream &stream, const State &state) { // Save Cache Version constexpr unsigned char cache_version = CACHE_VERSION; - stream.write((const char *) &cache_version, 1); + simple_write(stream, cache_version); // Save Username And Render Distance - write_env_to_stream(stream, state.username); - write_env_to_stream(stream, state.render_distance); - stream.write((const char *) &state.gui_scale, sizeof(float)); + simple_write(stream, state.username); + simple_write(stream, state.render_distance); + simple_write(stream, state.gui_scale); + simple_write(stream, state.servers.to_string()); // Save Feature Flags const std::unordered_map flags_cache = state.flags.to_cache(); for (const std::pair &it : flags_cache) { - stream.write(it.first.c_str(), int(it.first.size()) + 1); - stream.write((const char *) &it.second, sizeof(bool)); + simple_write(stream, it.first); + simple_write(stream, it.second); } } void save_cache(const State &state) { diff --git a/launcher/src/client/configuration.cpp b/launcher/src/client/configuration.cpp index c93a6c795a..1e098e37b4 100644 --- a/launcher/src/client/configuration.cpp +++ b/launcher/src/client/configuration.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include "configuration.h" #include "cache.h" @@ -28,6 +28,7 @@ void State::update(const bool save) { update_from_env(MCPI_USERNAME_ENV, username, save); update_from_env(MCPI_RENDER_DISTANCE_ENV, render_distance, save); update_from_env(MCPI_GUI_SCALE_ENV, gui_scale, save); + update_from_env(MCPI_SERVER_LIST_ENV, servers, save); } bool State::operator==(const State &other) const { std::ostringstream one; diff --git a/launcher/src/client/configuration.h b/launcher/src/client/configuration.h index 7fb46666d6..727cd68f92 100644 --- a/launcher/src/client/configuration.h +++ b/launcher/src/client/configuration.h @@ -5,8 +5,8 @@ #include "../options/parser.h" #include "../ui/frame.h" -#include -#include +#include +#include // Default Configuration #define DEFAULT_USERNAME "StevePi" @@ -22,6 +22,7 @@ struct State { // Properties std::string username; std::string render_distance; + ServerList servers; float gui_scale; Flags flags; }; @@ -32,24 +33,20 @@ struct ConfigurationUI final : Frame { int render() override; private: // Bottom Row - int get_render_distance_index() const; - int draw_bottom(bool hide_reset_revert) const; + [[nodiscard]] int get_render_distance_index() const; + [[nodiscard]] int draw_bottom() const; // General void draw_main() const; // Advanced void draw_advanced() const; static void draw_category(FlagNode &category); // Server List - bool are_servers_unsaved() const; - void draw_servers(); - void draw_server_list(); + void draw_servers() const; + void draw_server_list() const; // State const State original_state; State &state; bool &save_settings; - // Server List - ServerList last_saved_servers; - ServerList servers; }; // Handle Non-Launch Commands diff --git a/launcher/src/client/ui.cpp b/launcher/src/client/ui.cpp index d1bb4e3a50..5f37f0790b 100644 --- a/launcher/src/client/ui.cpp +++ b/launcher/src/client/ui.cpp @@ -1,8 +1,7 @@ #include #include -#include -#include +#include #include "configuration.h" @@ -16,13 +15,6 @@ static constexpr std::array render_distances = { "Tiny" }; -// Tooltips/Text -static const char *revert_text = "Revert"; -static const char *revert_tooltip_text = "Last Saved"; -static std::string make_tooltip(const std::string &text, const std::string &type) { - return "Use " + text + ' ' + type; -} - // Construct static constexpr int size = 400; ConfigurationUI::ConfigurationUI(State &state_, bool &save_settings_): @@ -33,7 +25,6 @@ ConfigurationUI::ConfigurationUI(State &state_, bool &save_settings_): // Render int ConfigurationUI::render() { - bool on_servers_tab = false; if (ImGui::BeginChild("Main", ImVec2(0, -ImGui::GetFrameHeightWithSpacing() /* Leave Room For Bottom Row */), ImGuiChildFlags_None, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) { // Tabs if (ImGui::BeginTabBar("TabBar")) { @@ -48,63 +39,48 @@ int ConfigurationUI::render() { ImGui::EndTabItem(); } // Servers Tab - if (ImGui::BeginTabItem("Servers", nullptr, are_servers_unsaved() ? ImGuiTabItemFlags_UnsavedDocument : ImGuiTabItemFlags_None)) { + if (ImGui::BeginTabItem("Servers")) { draw_servers(); ImGui::EndTabItem(); - on_servers_tab = true; } ImGui::EndTabBar(); } } ImGui::EndChild(); // Bottom Row - return draw_bottom(on_servers_tab); + return draw_bottom(); } // Bottom Row -int ConfigurationUI::draw_bottom(const bool hide_reset_revert) const { +int ConfigurationUI::draw_bottom() const { // Reset Settings - if (!hide_reset_revert) { - const State default_state; - constexpr const char *tooltip_type = "Settings"; - std::vector> reset_options = { - {revert_text, make_tooltip(revert_tooltip_text, tooltip_type), &original_state}, - {"Reset", make_tooltip("Default", tooltip_type), &default_state}, - }; - for (const std::tuple &option : reset_options) { - const State &new_state = *std::get<2>(option); - ImGui::BeginDisabled(state == new_state); - if (ImGui::Button(std::get<0>(option).c_str())) { - state = new_state; - } - ImGui::SetItemTooltip("%s", std::get<1>(option).c_str()); - ImGui::EndDisabled(); - ImGui::SameLine(); + const State default_state; + std::vector> reset_options = { + {"Revert", "Last Saved", &original_state}, + {"Reset", "Default", &default_state}, + }; + for (const std::tuple &option : reset_options) { + const State &new_state = *std::get<2>(option); + ImGui::BeginDisabled(state == new_state); + if (ImGui::Button(std::get<0>(option).c_str())) { + state = new_state; } + ImGui::SetItemTooltip("Use %s Settings", std::get<1>(option).c_str()); + ImGui::EndDisabled(); + ImGui::SameLine(); } // Right-Align Buttons int ret = 0; - bool unsaved_servers = are_servers_unsaved(); - draw_right_aligned_buttons({quit_text, "Launch"}, [&ret, unsaved_servers](const int id, const bool was_clicked) { + draw_right_aligned_buttons({quit_text, "Launch"}, [&ret](const int id, const bool was_clicked) { if (id == 0) { // Quit if (was_clicked) { ret = -1; } ImGui::SetItemTooltip("Changes Will Not Be Saved!"); - // Disable Launch if Server List Is Unsaved - if (unsaved_servers) { - ImGui::BeginDisabled(); - } - } else if (id == 1) { + } else if (was_clicked) { // Launch - if (unsaved_servers) { - ImGui::SetItemTooltip("Server List Is Unsaved"); - ImGui::EndDisabled(); - } - if (was_clicked) { - ret = 1; - } + ret = 1; } }); // Return @@ -188,42 +164,23 @@ void ConfigurationUI::draw_category(FlagNode &category) { } // Servers -bool ConfigurationUI::are_servers_unsaved() const { - return servers.to_string() != last_saved_servers.to_string(); -} -void ConfigurationUI::draw_servers() { - // Add/Clear +void ConfigurationUI::draw_servers() const { + // Add bool scroll_to_bottom = false; if (ImGui::Button("Add")) { - servers.entries.emplace_back("", DEFAULT_MULTIPLAYER_PORT); + state.servers.entries.emplace_back("", DEFAULT_MULTIPLAYER_PORT); scroll_to_bottom = true; } ImGui::SameLine(); - ImGui::BeginDisabled(servers.entries.empty()); - if (ImGui::Button("Clear")) { - servers.entries.clear(); - } - ImGui::EndDisabled(); - ImGui::SameLine(); - // Revert/Save - int clicked_button = -1; - ImGui::BeginDisabled(!are_servers_unsaved()); - draw_right_aligned_buttons({revert_text, "Save"}, [&clicked_button](const int id, const bool was_clicked) { - if (id == 0) { - ImGui::SetItemTooltip("%s", make_tooltip(revert_tooltip_text, "Server List").c_str()); - } - if (was_clicked) { - clicked_button = id; - } + // Clear + bool should_clear = false; + ImGui::BeginDisabled(state.servers.entries.empty()); + draw_right_aligned_buttons({"Clear"}, [&should_clear](__attribute__((unused)) const int id, const bool was_clicked) { + should_clear = was_clicked; }); ImGui::EndDisabled(); - if (clicked_button == 1) { - // Save - servers.save(); - last_saved_servers = servers; - } else if (clicked_button == 0) { - // Revert To Last Saved Server List - servers = last_saved_servers; + if (should_clear) { + state.servers.entries.clear(); } // List if (ImGui::BeginChild("ServerList", ImVec2(0, 0), ImGuiChildFlags_Borders)) { @@ -234,9 +191,25 @@ void ConfigurationUI::draw_servers() { } ImGui::EndChild(); } -void ConfigurationUI::draw_server_list() { - for (std::vector::size_type i = 0; i < servers.entries.size(); ++i) { - ServerList::Entry &entry = servers.entries[i]; +static int server_list_address_filter(ImGuiInputTextCallbackData *data) { + // Lowercase + constexpr std::pair lower_alpha = {'a', 'z'}; + constexpr std::pair upper_alpha = {'A', 'Z'}; + ImWchar &x = data->EventChar; + if (x >= upper_alpha.first && x <= upper_alpha.second) { + x += lower_alpha.first - upper_alpha.first; + } + // Check Characters + return (x >= lower_alpha.first && x <= lower_alpha.second) || x == '.' ? 0 : 1; +} +static int server_list_port_filter(ImGuiInputTextCallbackData *data) { + // Only Allow Integers + const ImWchar &x = data->EventChar; + return x >= '0' && x <= '9' ? 0 : 1; +} +void ConfigurationUI::draw_server_list() const { + for (std::vector::size_type i = 0; i < state.servers.entries.size(); ++i) { + ServerList::Entry &entry = state.servers.entries[i]; // Calculate Item Widths const ImGuiStyle &style = ImGui::GetStyle(); @@ -254,7 +227,7 @@ void ConfigurationUI::draw_server_list() { // Address ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - width_needed); - ImGui::InputTextWithHint((base_label + address_hint).c_str(), address_hint, &entry.first, ImGuiInputTextFlags_CharsNoBlank); + ImGui::InputTextWithHint((base_label + address_hint).c_str(), address_hint, &entry.first, ImGuiInputTextFlags_CallbackCharFilter, server_list_address_filter); ImGui::PopItemWidth(); // Port @@ -262,7 +235,7 @@ void ConfigurationUI::draw_server_list() { std::string port_str = port > 0 ? std::to_string(port) : ""; ImGui::SameLine(); ImGui::PushItemWidth(port_width); - if (ImGui::InputTextWithHint((base_label + port_hint).c_str(), port_hint, &port_str, ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_NoHorizontalScroll)) { + if (ImGui::InputTextWithHint((base_label + port_hint).c_str(), port_hint, &port_str, ImGuiInputTextFlags_CallbackCharFilter | ImGuiInputTextFlags_NoHorizontalScroll, server_list_port_filter)) { port = ServerList::parse_port(port_str); } ImGui::PopItemWidth(); @@ -270,8 +243,8 @@ void ConfigurationUI::draw_server_list() { // Delete ImGui::SameLine(); if (ImGui::Button((delete_text + base_label).c_str())) { - servers.entries.erase(servers.entries.begin() + int(i)); + state.servers.entries.erase(state.servers.entries.begin() + int(i)); i--; } } -} \ No newline at end of file +} diff --git a/launcher/src/logger/crash-report.cpp b/launcher/src/logger/crash-report.cpp index a6da7933ab..8d700f011d 100644 --- a/launcher/src/logger/crash-report.cpp +++ b/launcher/src/logger/crash-report.cpp @@ -1,8 +1,8 @@ #include -#include +#include #include -#include +#include #include "logger.h" #include "../ui/frame.h" diff --git a/launcher/src/logger/logger.cpp b/launcher/src/logger/logger.cpp index 0c53d3778d..d312458c68 100644 --- a/launcher/src/logger/logger.cpp +++ b/launcher/src/logger/logger.cpp @@ -8,9 +8,11 @@ #include #include -#include +#include #include -#include +#include +#include +#include #include #include "logger.h" @@ -37,7 +39,7 @@ static void setup_log_file() { const std::string logs = get_logs_folder(); // Get Timestamp - std::string time = format_time("%Y-%m-%d"); + const std::string time = format_time("%Y-%m-%d"); // Get Log Filename std::string file; diff --git a/launcher/src/main.cpp b/launcher/src/main.cpp index b1d69c34c4..46cde35ee4 100644 --- a/launcher/src/main.cpp +++ b/launcher/src/main.cpp @@ -1,7 +1,7 @@ #include -#include -#include +#include +#include #include #include "bootstrap/bootstrap.h" diff --git a/launcher/src/options/parser.cpp b/launcher/src/options/parser.cpp index 9d24602b48..c647406aee 100644 --- a/launcher/src/options/parser.cpp +++ b/launcher/src/options/parser.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include "parser.h" @@ -20,7 +20,7 @@ static argp_option options_data[] = { #undef OPTION {nullptr, 0, nullptr, 0, "Environmental Variables:", 0}, #define ENV(name, doc) {#name, env_key--, nullptr, OPTION_DOC | OPTION_NO_USAGE | (is_env_var_internal(name##_ENV) ? OPTION_HIDDEN : 0), doc, 0}, -#include +#include #ifdef MCPI_BUILD_RUNTIME #include #endif @@ -34,7 +34,7 @@ static argp_option options_data[] = { case key: \ options->name = true; \ break; -static error_t parse_opt(int key, __attribute__((unused)) char *arg, argp_state *state) { +static error_t parse_opt(const int key, __attribute__((unused)) char *arg, argp_state *state) { options_t *options = (options_t *) state->input; switch (key) { #include "option-list.h" @@ -45,7 +45,7 @@ static error_t parse_opt(int key, __attribute__((unused)) char *arg, argp_state } #undef OPTION static argp argp = {options_data, parse_opt, nullptr, doc, nullptr, nullptr, nullptr}; -options_t parse_options(int argc, char *argv[]) { +options_t parse_options(const int argc, char *argv[]) { options_t options = {}; argp_parse(&argp, argc, argv, 0, nullptr, &options); return options; diff --git a/launcher/src/ui/frame.cpp b/launcher/src/ui/frame.cpp index 6ad8cd2659..d95a294661 100644 --- a/launcher/src/ui/frame.cpp +++ b/launcher/src/ui/frame.cpp @@ -6,8 +6,8 @@ #include #include -#include -#include +#include +#include // Init/Cleanup Frame::Frame(const char *title, const int width, const int height) { diff --git a/launcher/src/util/env.cpp b/launcher/src/util/env.cpp index d7dad887bb..8ca930f13e 100644 --- a/launcher/src/util/env.cpp +++ b/launcher/src/util/env.cpp @@ -3,7 +3,7 @@ #include "util.h" #include -#include +#include #include // $PATH diff --git a/launcher/src/util/sdk.cpp b/launcher/src/util/sdk.cpp index 7a89f1393c..858d6ec8c7 100644 --- a/launcher/src/util/sdk.cpp +++ b/launcher/src/util/sdk.cpp @@ -1,5 +1,6 @@ #include -#include +#include +#include #include #include "../bootstrap/bootstrap.h" diff --git a/launcher/src/util/util.cpp b/launcher/src/util/util.cpp index c4a0b06669..ca17c8add1 100644 --- a/launcher/src/util/util.cpp +++ b/launcher/src/util/util.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include "util.h" diff --git a/libreborn/CMakeLists.txt b/libreborn/CMakeLists.txt index 7084eebbba..2bf49667f4 100644 --- a/libreborn/CMakeLists.txt +++ b/libreborn/CMakeLists.txt @@ -11,14 +11,14 @@ add_library(reborn-util SHARED src/util/util.cpp src/util/log.cpp src/util/cp437.cpp - src/util/env.cpp + src/util/env/env.cpp src/util/config.cpp - src/util/flags/node.cpp - src/util/flags/flags.cpp - src/util/flags/available-feature-flags # Show In IDE - src/util/servers.cpp + src/util/env/flags/node.cpp + src/util/env/flags/flags.cpp + src/util/env/flags/available-feature-flags # Show In IDE + src/util/env/servers.cpp ) -embed_resource(reborn-util src/util/flags/available-feature-flags) +embed_resource(reborn-util src/util/env/flags/available-feature-flags) target_link_libraries(reborn-util PRIVATE utf8cpp) if(TARGET glfw) target_sources(reborn-util PRIVATE src/util/glfw.cpp) diff --git a/libreborn/include/libreborn/env.h b/libreborn/include/libreborn/env.h deleted file mode 100644 index f575bcefa5..0000000000 --- a/libreborn/include/libreborn/env.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#define ENV(name, ...) extern const char *const name##_ENV; -#include "env-list.h" -#undef ENV - -bool is_env_var_internal(const char *env); -void clear_internal_env_vars(); - -// Set Environmental Variable -void set_and_print_env(const char *name, const char *value); - -// Convert Variable To Value And Vice-Versa -struct Flags; -std::string obj_to_env_value(const std::string &obj); -std::string obj_to_env_value(const float &obj); -std::string obj_to_env_value(const Flags &obj); -void env_value_to_obj(std::string &out, const char *value); -void env_value_to_obj(float &out, const char *value); -void env_value_to_obj(Flags &out, const char *value); \ No newline at end of file diff --git a/libreborn/include/libreborn/env/env.h b/libreborn/include/libreborn/env/env.h new file mode 100644 index 0000000000..9fdd64d8d9 --- /dev/null +++ b/libreborn/include/libreborn/env/env.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#define ENV(name, ...) constexpr const char *name##_ENV = #name; +#include "list.h" +#undef ENV + +bool is_env_var_internal(const char *env); +void clear_internal_env_vars(); + +// Set Environmental Variable +void setenv_safe(const char *name, const char *value); +void set_and_print_env(const char *name, const char *value); + +// Convert Variable To Value And Vice-Versa +struct Flags; +struct ServerList; +#define overload(type) \ + std::string obj_to_env_value(const type &obj); \ + void env_value_to_obj(type &out, const char *value) +overload(std::string); +overload(float); +overload(Flags); +overload(ServerList); +#undef overload \ No newline at end of file diff --git a/libreborn/include/libreborn/flags.h b/libreborn/include/libreborn/env/flags.h similarity index 100% rename from libreborn/include/libreborn/flags.h rename to libreborn/include/libreborn/env/flags.h diff --git a/libreborn/include/libreborn/env-list.h b/libreborn/include/libreborn/env/list.h similarity index 95% rename from libreborn/include/libreborn/env-list.h rename to libreborn/include/libreborn/env/list.h index cd7e4baf6f..0909b98590 100644 --- a/libreborn/include/libreborn/env-list.h +++ b/libreborn/include/libreborn/env/list.h @@ -2,6 +2,7 @@ ENV(MCPI_FEATURE_FLAGS, "Client-Mode Feature Flags") ENV(MCPI_USERNAME, "Player Username") ENV(MCPI_RENDER_DISTANCE, "Render Distance") +ENV(MCPI_SERVER_LIST, "Server List") // Game Assets ENV(_MCPI_REBORN_ASSETS_PATH, "") ENV(_MCPI_VANILLA_ASSETS_PATH, "") diff --git a/libreborn/include/libreborn/servers.h b/libreborn/include/libreborn/env/servers.h similarity index 71% rename from libreborn/include/libreborn/servers.h rename to libreborn/include/libreborn/env/servers.h index fd527ef915..47147e2f1d 100644 --- a/libreborn/include/libreborn/servers.h +++ b/libreborn/include/libreborn/env/servers.h @@ -11,10 +11,9 @@ struct ServerList { typedef std::pair Entry; // Load static port_t parse_port(const std::string &s); - ServerList(); + void load(const std::string &str); // Save - std::string to_string() const; - void save() const; + [[nodiscard]] std::string to_string() const; // Entries - std::vector entries{}; + std::vector entries; }; \ No newline at end of file diff --git a/libreborn/include/libreborn/exec.h b/libreborn/include/libreborn/util/exec.h similarity index 92% rename from libreborn/include/libreborn/exec.h rename to libreborn/include/libreborn/util/exec.h index 1fc6977d28..709004f7aa 100644 --- a/libreborn/include/libreborn/exec.h +++ b/libreborn/include/libreborn/util/exec.h @@ -9,7 +9,7 @@ // fork() With I/O struct Process { static constexpr int fd_count = 3; - Process(pid_t pid_, std::array fds_); + Process(pid_t pid_, const std::array &fds_); [[nodiscard]] int close() const; const pid_t pid; const std::array fds; diff --git a/libreborn/include/libreborn/glfw.h b/libreborn/include/libreborn/util/glfw.h similarity index 100% rename from libreborn/include/libreborn/glfw.h rename to libreborn/include/libreborn/util/glfw.h diff --git a/libreborn/include/libreborn/util/io.h b/libreborn/include/libreborn/util/io.h new file mode 100644 index 0000000000..1d05c2aec6 --- /dev/null +++ b/libreborn/include/libreborn/util/io.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +// Safe Version Of pipe() +struct Pipe { + Pipe(); + const int read; + const int write; +}; + +// Lock File +int lock_file(const char *file); +void unlock_file(const char *file, int fd); + +// Safe write() +void safe_write(int fd, const void *buf, size_t size); \ No newline at end of file diff --git a/libreborn/include/libreborn/string.h b/libreborn/include/libreborn/util/string.h similarity index 54% rename from libreborn/include/libreborn/string.h rename to libreborn/include/libreborn/util/string.h index 5f69f9d2b1..8fc992c836 100644 --- a/libreborn/include/libreborn/string.h +++ b/libreborn/include/libreborn/util/string.h @@ -7,4 +7,8 @@ void sanitize_string(std::string &str, int max_length, bool allow_newlines); // CP437 std::string to_cp437(const std::string &input); -std::string from_cp437(const std::string &input); \ No newline at end of file +std::string from_cp437(const std::string &input); + +// Format Time +std::string format_time(const char *fmt); +std::string format_time(const char *fmt, int time); \ No newline at end of file diff --git a/libreborn/include/libreborn/util.h b/libreborn/include/libreborn/util/util.h similarity index 76% rename from libreborn/include/libreborn/util.h rename to libreborn/include/libreborn/util/util.h index d3900b0b6c..54686d7878 100644 --- a/libreborn/include/libreborn/util.h +++ b/libreborn/include/libreborn/util/util.h @@ -3,7 +3,7 @@ #include #include -#include "log.h" +#include "../log.h" // Align Number int align_up(int x, int alignment); @@ -24,20 +24,9 @@ int align_up(int x, int alignment); } \ extern "C" __attribute__((__used__)) return_type name args -// Safe Version Of pipe() -struct Pipe { - Pipe(); - const int read; - const int write; -}; - // Check If Two Percentages Are Different Enough To Be Logged bool is_progress_difference_significant(int32_t new_val, int32_t old_val); -// Lock File -int lock_file(const char *file); -void unlock_file(const char *file, int fd); - // Check $DISPLAY void reborn_check_display(); @@ -47,9 +36,6 @@ const char *get_home_subdirectory_for_game_data(); // Make Sure Directory Exists void ensure_directory(const char *path); -// Safe write() -void safe_write(int fd, const void *buf, size_t size); - // embed_resource() #define EMBEDDED_RESOURCE(name) \ extern unsigned char name[]; \ @@ -58,10 +44,6 @@ void safe_write(int fd, const void *buf, size_t size); // Profile Directory std::string home_get(); -// Format Time -std::string format_time(const char *fmt); -std::string format_time(const char *fmt, int time); - // Default MCPI Port // This Macro DOES NOT Control MCPI #define DEFAULT_MULTIPLAYER_PORT 19132 \ No newline at end of file diff --git a/libreborn/src/util/config.cpp b/libreborn/src/util/config.cpp index 6014a6b423..ea969b0604 100644 --- a/libreborn/src/util/config.cpp +++ b/libreborn/src/util/config.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include // Access Configuration At Runtime const char *reborn_get_version() { diff --git a/libreborn/src/util/cp437.cpp b/libreborn/src/util/cp437.cpp index 1f44c3b18e..de6fe1234c 100644 --- a/libreborn/src/util/cp437.cpp +++ b/libreborn/src/util/cp437.cpp @@ -2,7 +2,7 @@ #include "utf8.h" -#include +#include // Conversion Functions static std::u32string to_utf32(const std::string &s) { diff --git a/libreborn/src/util/env.cpp b/libreborn/src/util/env/env.cpp similarity index 74% rename from libreborn/src/util/env.cpp rename to libreborn/src/util/env/env.cpp index 3f30afb222..34612f7620 100644 --- a/libreborn/src/util/env.cpp +++ b/libreborn/src/util/env/env.cpp @@ -1,29 +1,24 @@ -#include -#include +#include +#include #include -#include - -// Define Constants -#define ENV(name, ...) const char *const name##_ENV = #name; -#include -#undef ENV +#include +#include // Clear Internal Variables bool is_env_var_internal(const char *env) { return env[0] == '_'; } void clear_internal_env_vars() { - DEBUG("Clearing Internal Environmental Variables..."); #define ENV(name, ...) \ if (is_env_var_internal(name##_ENV)) { \ set_and_print_env(name##_ENV, nullptr); \ } -#include +#include #undef ENV } // Set Environmental Variable -static void setenv_safe(const char *name, const char *value) { +void setenv_safe(const char *name, const char *value) { if (value != nullptr) { setenv(name, value, 1); } else { @@ -48,6 +43,9 @@ std::string obj_to_env_value(const float &obj) { std::string obj_to_env_value(const Flags &obj) { return obj.to_string(); } +std::string obj_to_env_value(const ServerList &obj) { + return obj.to_string(); +} void env_value_to_obj(std::string &out, const char *value) { out = value; } @@ -56,4 +54,7 @@ void env_value_to_obj(float &out, const char *value) { } void env_value_to_obj(Flags &out, const char *value) { out.from_string(value); +} +void env_value_to_obj(ServerList &out, const char *value) { + out.load(value); } \ No newline at end of file diff --git a/libreborn/src/util/flags/available-feature-flags b/libreborn/src/util/env/flags/available-feature-flags similarity index 100% rename from libreborn/src/util/flags/available-feature-flags rename to libreborn/src/util/env/flags/available-feature-flags diff --git a/libreborn/src/util/flags/flags.cpp b/libreborn/src/util/env/flags/flags.cpp similarity index 98% rename from libreborn/src/util/flags/flags.cpp rename to libreborn/src/util/env/flags/flags.cpp index 3e7a62b3b0..d31c3aabb9 100644 --- a/libreborn/src/util/flags/flags.cpp +++ b/libreborn/src/util/env/flags/flags.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include // All Flags static unsigned int find_indent_level(std::string &str) { diff --git a/libreborn/src/util/flags/node.cpp b/libreborn/src/util/env/flags/node.cpp similarity index 98% rename from libreborn/src/util/flags/node.cpp rename to libreborn/src/util/env/flags/node.cpp index 1ed4b4d7ca..71497eb947 100644 --- a/libreborn/src/util/flags/node.cpp +++ b/libreborn/src/util/env/flags/node.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include // Flag static int next_id; diff --git a/libreborn/src/util/servers.cpp b/libreborn/src/util/env/servers.cpp similarity index 60% rename from libreborn/src/util/servers.cpp rename to libreborn/src/util/env/servers.cpp index 794215f8cc..8de5321229 100644 --- a/libreborn/src/util/servers.cpp +++ b/libreborn/src/util/env/servers.cpp @@ -2,13 +2,8 @@ #include #include -#include -#include - -// File -static std::string get_server_list_path() { - return home_get() + "/servers.txt"; -} +#include +#include // Seperator #define PORT_SEPERATOR_CHAR ':' @@ -22,27 +17,22 @@ ServerList::port_t ServerList::parse_port(const std::string &s) { } return static_cast(port); } -ServerList::ServerList() { +void ServerList::load(const std::string &str) { + // Clear + entries.clear(); + // Open File - std::ifstream server_list_file(get_server_list_path()); - if (!server_list_file) { - // File Does Not Exist - return; - } + std::stringstream server_list_file(str); // Iterate Lines std::string line; while (std::getline(server_list_file, line)) { // Check Line if (!line.empty()) { - // Skip Comments - if (line[0] == '#') { - continue; - } // Parse std::string address; std::string port_str; - size_t separator_pos = line.find_last_of(PORT_SEPERATOR_CHAR); + const size_t separator_pos = line.find_last_of(PORT_SEPERATOR_CHAR); if (separator_pos == std::string::npos) { port_str = std::to_string(DEFAULT_MULTIPLAYER_PORT); address = line; @@ -54,29 +44,13 @@ ServerList::ServerList() { entries.emplace_back(address, parse_port(port_str)); } } - - // Close - server_list_file.close(); } // Save std::string ServerList::to_string() const { std::stringstream out; - out << "# External Servers File\n"; for (const Entry &entry : entries) { out << entry.first << PORT_SEPERATOR_CHAR << std::to_string(entry.second) << '\n'; } return out.str(); } -void ServerList::save() const { - // Open File - std::ofstream file(get_server_list_path()); - if (!file) { - // Failure - WARN("Unable To Save Server List"); - } - // Write - file << to_string(); - // Close - file.close(); -} diff --git a/libreborn/src/util/exec.cpp b/libreborn/src/util/exec.cpp index 07fc5250c2..0afebb682a 100644 --- a/libreborn/src/util/exec.cpp +++ b/libreborn/src/util/exec.cpp @@ -6,12 +6,12 @@ #include #include -#include #include -#include +#include +#include // Fork -Process::Process(const pid_t pid_, const std::array fds_): pid(pid_), fds(fds_) {} +Process::Process(const pid_t pid_, const std::array &fds_): pid(pid_), fds(fds_) {} int Process::close() const { for (const int fd : fds) { ::close(fd); diff --git a/libreborn/src/util/glfw.cpp b/libreborn/src/util/glfw.cpp index 44ac596b8b..1c2eb8b20e 100644 --- a/libreborn/src/util/glfw.cpp +++ b/libreborn/src/util/glfw.cpp @@ -1,8 +1,8 @@ #define GLFW_INCLUDE_NONE #include -#include -#include +#include +#include #include #include diff --git a/libreborn/src/util/log.cpp b/libreborn/src/util/log.cpp index 36a41df594..882efd8d16 100644 --- a/libreborn/src/util/log.cpp +++ b/libreborn/src/util/log.cpp @@ -3,43 +3,28 @@ #include #include -#include +#include // Debug Tag const char *reborn_debug_tag = ""; -// /dev/null FD -static int null_fd = -1; -static void setup_null_fd() { - if (null_fd == -1) { - null_fd = open("/dev/null", O_WRONLY | O_APPEND); - } -} -__attribute__((destructor)) static void close_null_fd() { - close(null_fd); -} - // Log File -static int log_fd = -1; +static constexpr int unset_fd = -1; +static int log_fd = unset_fd; int reborn_get_log_fd() { - if (log_fd >= 0) { + if (log_fd != unset_fd) { return log_fd; } // Open Log File const char *fd_str = getenv(_MCPI_LOG_FD_ENV); - if (fd_str) { - log_fd = std::stoi(fd_str); - } else { - setup_null_fd(); - log_fd = null_fd; - } + log_fd = fd_str ? std::stoi(fd_str) : -2; // Return return reborn_get_log_fd(); } void reborn_set_log(const int fd) { // Set Variable - log_fd = -1; - set_and_print_env(_MCPI_LOG_FD_ENV, fd >= 0 ? std::to_string(fd).c_str() : nullptr); + log_fd = unset_fd; + setenv_safe(_MCPI_LOG_FD_ENV, fd >= 0 ? std::to_string(fd).c_str() : nullptr); } // Debug Logging diff --git a/libreborn/src/util/string.cpp b/libreborn/src/util/string.cpp index 7cba6521de..862eb686a3 100644 --- a/libreborn/src/util/string.cpp +++ b/libreborn/src/util/string.cpp @@ -1,21 +1,42 @@ -#include +#include +#include + +#include +#include // Sanitize String void sanitize_string(std::string &str, const int max_length, const bool allow_newlines) { - // Store Message Length - size_t length = str.size(); // Truncate Message - if (max_length >= 0 && length > ((size_t) max_length)) { + if (max_length >= 0 && str.size() > ((size_t) max_length)) { str = str.substr(0, max_length); - length = max_length; } // Loop Through Message if (!allow_newlines) { - for (size_t i = 0; i < length; i++) { - if (str[i] == '\n') { + for (char &x : str) { + if (x == '\n') { // Replace Newline - str[i] = ' '; + x = ' '; } } } +} + +// Format Time +static std::string _format_time(const char *fmt, const time_t raw_time) { + const tm *time_info = localtime(&raw_time); + if (time_info == nullptr) { + ERR("Unable To Determine Current Time: %s", strerror(errno)); + } + char buf[512]; + strftime(buf, sizeof(buf), fmt, time_info); + return std::string(buf); +} +std::string format_time(const char *fmt) { + time_t raw_time; + time(&raw_time); + return _format_time(fmt, raw_time); +} +std::string format_time(const char *fmt, const int time) { + // This Will Break In 2038 + return _format_time(fmt, time); } \ No newline at end of file diff --git a/libreborn/src/util/util.cpp b/libreborn/src/util/util.cpp index 3009fb087d..94701780b8 100644 --- a/libreborn/src/util/util.cpp +++ b/libreborn/src/util/util.cpp @@ -2,12 +2,13 @@ #include #include #include -#include #include -#include +#include +#include #include -#include +#include +#include // Align Number int align_up(int x, const int alignment) { @@ -102,6 +103,9 @@ void ensure_directory(const char *path) { // Write To FD void safe_write(const int fd, const void *buf, const size_t size) { + if (fd < 0) { + return; + } const ssize_t bytes_written = write(fd, buf, size); if (bytes_written < 0) { ERR("Unable To Write Data: %s", strerror(errno)); @@ -115,24 +119,4 @@ std::string home_get() { IMPOSSIBLE(); } return std::string(home) + std::string(get_home_subdirectory_for_game_data()); -} - -// Format Time -static std::string _format_time(const char *fmt, const time_t raw_time) { - const tm *time_info = localtime(&raw_time); - if (time_info == nullptr) { - ERR("Unable To Determine Current Time: %s", strerror(errno)); - } - char buf[512]; - strftime(buf, sizeof(buf), fmt, time_info); - return std::string(buf); -} -std::string format_time(const char *fmt) { - time_t raw_time; - time(&raw_time); - return _format_time(fmt, raw_time); -} -std::string format_time(const char *fmt, const int time) { - // This Will Break In 2038 - return _format_time(fmt, time); } \ No newline at end of file diff --git a/media-layer/core/src/window/media.h b/media-layer/core/src/window/media.h index fd88272fa6..9540065265 100644 --- a/media-layer/core/src/window/media.h +++ b/media-layer/core/src/window/media.h @@ -5,8 +5,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/media-layer/trampoline/src/GLESv1_CM.cpp b/media-layer/trampoline/src/GLESv1_CM.cpp index 1cbdbf9b22..a8ecc88b4e 100644 --- a/media-layer/trampoline/src/GLESv1_CM.cpp +++ b/media-layer/trampoline/src/GLESv1_CM.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include "common/common.h" diff --git a/mods/src/atlas/atlas.cpp b/mods/src/atlas/atlas.cpp index 9d5e116643..0f0b1f1516 100644 --- a/mods/src/atlas/atlas.cpp +++ b/mods/src/atlas/atlas.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include diff --git a/mods/src/benchmark/benchmark.cpp b/mods/src/benchmark/benchmark.cpp index 7e272adbfe..82137bd693 100644 --- a/mods/src/benchmark/benchmark.cpp +++ b/mods/src/benchmark/benchmark.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/mods/src/chat/chat.cpp b/mods/src/chat/chat.cpp index 7940f62980..8c9b69d935 100644 --- a/mods/src/chat/chat.cpp +++ b/mods/src/chat/chat.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include diff --git a/mods/src/compat/sdl.cpp b/mods/src/compat/sdl.cpp index 1ecc8848bf..4f51892790 100644 --- a/mods/src/compat/sdl.cpp +++ b/mods/src/compat/sdl.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include diff --git a/mods/src/feature/feature.cpp b/mods/src/feature/feature.cpp index 64bb56b036..5726504f60 100644 --- a/mods/src/feature/feature.cpp +++ b/mods/src/feature/feature.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/mods/src/game-mode/ui.cpp b/mods/src/game-mode/ui.cpp index f26dfeaf98..3c70eeee6b 100644 --- a/mods/src/game-mode/ui.cpp +++ b/mods/src/game-mode/ui.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/mods/src/misc/api.cpp b/mods/src/misc/api.cpp index ce8021b176..8492a6ee8d 100644 --- a/mods/src/misc/api.cpp +++ b/mods/src/misc/api.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include diff --git a/mods/src/misc/graphics.cpp b/mods/src/misc/graphics.cpp index bc56bb34e3..01117a3123 100644 --- a/mods/src/misc/graphics.cpp +++ b/mods/src/misc/graphics.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include diff --git a/mods/src/misc/home.cpp b/mods/src/misc/home.cpp index 71f165017d..52502c3762 100644 --- a/mods/src/misc/home.cpp +++ b/mods/src/misc/home.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #include diff --git a/mods/src/misc/logging.cpp b/mods/src/misc/logging.cpp index 72e47ce5a5..6b77f60e8c 100644 --- a/mods/src/misc/logging.cpp +++ b/mods/src/misc/logging.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/mods/src/misc/misc.cpp b/mods/src/misc/misc.cpp index a86cd246db..701a36227d 100644 --- a/mods/src/misc/misc.cpp +++ b/mods/src/misc/misc.cpp @@ -12,10 +12,10 @@ #include #include -#include +#include #include -#include -#include +#include +#include #include diff --git a/mods/src/misc/ui.cpp b/mods/src/misc/ui.cpp index f72a3228e2..9865622fd2 100644 --- a/mods/src/misc/ui.cpp +++ b/mods/src/misc/ui.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/mods/src/multidraw/glue.cpp b/mods/src/multidraw/glue.cpp index f1463d1bef..bf6eb78082 100644 --- a/mods/src/multidraw/glue.cpp +++ b/mods/src/multidraw/glue.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include diff --git a/mods/src/multiplayer/multiplayer.cpp b/mods/src/multiplayer/multiplayer.cpp index 0bce82cc42..4bdb3097bc 100644 --- a/mods/src/multiplayer/multiplayer.cpp +++ b/mods/src/multiplayer/multiplayer.cpp @@ -5,7 +5,8 @@ #include #include -#include +#include +#include #include #include @@ -14,6 +15,14 @@ static void iterate_servers(const std::function &callback) { // Load static ServerList server_list; + static bool loaded = false; + if (!loaded) { + const char *str = getenv(MCPI_SERVER_LIST_ENV); + if (str != nullptr) { + env_value_to_obj(server_list, str); + } + loaded = true; + } // Loop for (const ServerList::Entry &entry : server_list.entries) { if (!entry.first.empty() && entry.second > 0) { diff --git a/mods/src/options/info.cpp b/mods/src/options/info.cpp index b3027a5020..0791cc615d 100644 --- a/mods/src/options/info.cpp +++ b/mods/src/options/info.cpp @@ -1,7 +1,7 @@ #include -#include +#include #include -#include +#include #include #include diff --git a/mods/src/options/options.cpp b/mods/src/options/options.cpp index e39de2e524..e4cd7ea006 100644 --- a/mods/src/options/options.cpp +++ b/mods/src/options/options.cpp @@ -6,9 +6,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/mods/src/override/override.cpp b/mods/src/override/override.cpp index 9b57f38cd4..b8eff13d3f 100644 --- a/mods/src/override/override.cpp +++ b/mods/src/override/override.cpp @@ -4,8 +4,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/mods/src/screenshot/screenshot.cpp b/mods/src/screenshot/screenshot.cpp index a0f61e51be..5f38f43805 100644 --- a/mods/src/screenshot/screenshot.cpp +++ b/mods/src/screenshot/screenshot.cpp @@ -6,7 +6,8 @@ #include "stb_image_write.h" #include -#include +#include +#include #include #include @@ -43,7 +44,7 @@ void screenshot_take(Gui *gui) { } // Get Timestamp - std::string time = format_time("%Y-%m-%d_%H.%M.%S"); + const std::string time = format_time("%Y-%m-%d_%H.%M.%S"); // Prevent Overwriting Screenshots int num = 0; diff --git a/mods/src/server/server.cpp b/mods/src/server/server.cpp index cb04bc46eb..e88c64206b 100644 --- a/mods/src/server/server.cpp +++ b/mods/src/server/server.cpp @@ -12,9 +12,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include diff --git a/mods/src/skin/loader.cpp b/mods/src/skin/loader.cpp index e9ec8580da..5a9722fbbc 100644 --- a/mods/src/skin/loader.cpp +++ b/mods/src/skin/loader.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/mods/src/textures/textures.cpp b/mods/src/textures/textures.cpp index 9bf4222699..8f68799f2a 100644 --- a/mods/src/textures/textures.cpp +++ b/mods/src/textures/textures.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include diff --git a/mods/src/title-screen/welcome.cpp b/mods/src/title-screen/welcome.cpp index 21c2d92908..88729846e4 100644 --- a/mods/src/title-screen/welcome.cpp +++ b/mods/src/title-screen/welcome.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include