From 1971f1b4eb945f04a50670bc03d1e953c2e5280e Mon Sep 17 00:00:00 2001 From: m Date: Thu, 22 Dec 2022 11:07:51 -0600 Subject: [PATCH] use fs_game w/ mod support --- src/client/component/command.cpp | 6 +-- src/client/component/mods.cpp | 58 ++++++++++++++++++++++----- src/client/component/mods.hpp | 2 +- src/client/component/ui_scripting.cpp | 3 +- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 7a8588d5..58c0918d 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -28,7 +28,7 @@ namespace command std::unordered_map> handlers; std::unordered_map> handlers_sv; - std::string saved_fs_game; + std::optional saved_fs_game; void main_handler() { @@ -563,10 +563,10 @@ namespace command const auto new_mod_path = fs_game->current.string; // check if the last saved fs_game value isn't empty and if it doesn't equal the new fs_game - if (!saved_fs_game.empty() && saved_fs_game != new_mod_path) + if (saved_fs_game.has_value() && saved_fs_game != new_mod_path) { // unregister path to be used as a fs directory - filesystem::unregister_path(saved_fs_game); + filesystem::unregister_path(saved_fs_game.value()); } if (new_mod_path && !new_mod_path[0]) diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp index 2d8d898b..fb124d2a 100644 --- a/src/client/component/mods.cpp +++ b/src/client/component/mods.cpp @@ -17,7 +17,7 @@ namespace mods { - std::string mod_path{}; + std::optional mod_path; namespace { @@ -51,6 +51,13 @@ namespace mods void full_restart(const std::string& arg) { + if (game::environment::is_mp()) + { + // vid_restart works on multiplayer, but not on singleplayer + command::execute("vid_restart"); + return; + } + auto mode = game::environment::is_mp() ? " -multiplayer "s : " -singleplayer "s; utils::nt::relaunch_self(mode.append(arg), true); @@ -63,6 +70,38 @@ namespace mods return utils::io::file_exists(path + "/mod.ff") || utils::io::file_exists(path + "/zone/mod.ff"); } + void set_filesystem_data(const std::string& path) + { + if (mod_path.has_value()) + { + filesystem::unregister_path(mod_path.value()); + } + + if (!game::environment::is_sp()) + { + // modify fs_game on mp/dedi because its not set when we obviously vid_restart (sp does a full relaunch with command line arguments) + game::Dvar_SetFromStringByNameFromSource("fs_game", path.data(), + game::DVAR_SOURCE_INTERNAL); + } + } + + void set_mod(const std::string& path) + { + set_filesystem_data(path); + mod_path = path; + } + + void clear_mod() + { + set_filesystem_data(""); + mod_path.reset(); + } + + std::optional get_mod() + { + return mod_path; + } + class component final : public component_interface { public: @@ -98,24 +137,23 @@ namespace mods } console::info("Loading mod %s\n", path); + set_mod(path); - if (mod_requires_restart(mod_path) || mod_requires_restart(path)) + if ((mod_path.has_value() && mod_requires_restart(mod_path.value())) || + mod_requires_restart(path)) { console::info("Restarting...\n"); full_restart("+set fs_game \""s + path + "\""); } else { - filesystem::unregister_path(mod_path); - filesystem::register_path(path); - mod_path = path; restart(); } }); command::add("unloadmod", [](const command::params& params) { - if (mod_path.empty()) + if (!mod_path.has_value()) { console::info("No mod loaded\n"); return; @@ -128,17 +166,17 @@ namespace mods return; } - console::info("Unloading mod %s\n", mod_path.data()); + console::info("Unloading mod %s\n", mod_path.value().data()); - if (mod_requires_restart(mod_path)) + if (mod_requires_restart(mod_path.value())) { console::info("Restarting...\n"); + clear_mod(); full_restart(""); } else { - filesystem::unregister_path(mod_path); - mod_path.clear(); + clear_mod(); restart(); } }); diff --git a/src/client/component/mods.hpp b/src/client/component/mods.hpp index 364a2f11..f7b47293 100644 --- a/src/client/component/mods.hpp +++ b/src/client/component/mods.hpp @@ -2,5 +2,5 @@ namespace mods { - extern std::string mod_path; + std::optional get_mod(); } \ No newline at end of file diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 7e2e0d5e..1fcfb1d1 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -268,7 +268,8 @@ namespace ui_scripting game_type["getloadedmod"] = [](const game&) { - return mods::mod_path; + const auto& path = mods::get_mod(); + return path.value_or(""); }; if (::game::environment::is_sp())