fix fs_startup + fs_game file path

This commit is contained in:
m 2022-09-03 04:50:08 -05:00
parent 9a39f92c26
commit 7d3eb31261
7 changed files with 93 additions and 24 deletions

View File

@ -28,6 +28,8 @@ namespace command
std::unordered_map<std::string, std::function<void(params&)>> handlers;
std::unordered_map<std::string, std::function<void(int, params_sv&)>> handlers_sv;
std::string saved_fs_game;
void main_handler()
{
params params = {};
@ -106,6 +108,33 @@ namespace command
parsed = true;
}
void register_fs_game_path()
{
console::debug("[FS] " __FUNCTION__ " called\n");
static const auto* fs_game = game::Dvar_FindVar("fs_game");
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)
{
// unregister path to be used as a fs directory
filesystem::unregister_path(saved_fs_game);
}
if (new_mod_path && !new_mod_path[0])
{
console::debug("[FS] " __FUNCTION__ " returning because new mod path is blank\n");
return;
}
console::debug("[FS] " __FUNCTION__ " registering new mod path\n");
// register fs_game value as a fs directory used for many things
filesystem::register_path(new_mod_path);
saved_fs_game = new_mod_path;
}
void parse_startup_variables()
{
auto& com_num_console_lines = *reinterpret_cast<int*>(0x35634B8_b);
@ -128,14 +157,9 @@ namespace command
}
else
{
dvars::on_register(dvar_name, [dvar_name, value]()
dvars::callback::on_register(dvar_name, [dvar_name, value]()
{
game::Dvar_SetCommand(game::generateHashValue(dvar_name.data()), "", value.data());
if (dvar_name == "fs_game")
{
filesystem::register_path(value);
}
});
}
}
@ -565,6 +589,17 @@ namespace command
public:
void post_unpack() override
{
// monitor fs_game register and new value changes to adjust our paths for searching
dvars::callback::on_register("fs_game", []()
{
register_fs_game_path();
});
dvars::callback::on_new_value("fs_game", []()
{
register_fs_game_path();
});
if (game::environment::is_sp())
{
add_commands_sp();

View File

@ -252,6 +252,23 @@ namespace dvars
}
}
namespace callback
{
static std::unordered_map<int, std::function<void()>> new_value_callbacks;
static std::unordered_map<int, std::function<void()>> dvar_on_register_function_map;
void on_new_value(const std::string& name, const std::function<void()> callback)
{
new_value_callbacks[game::generateHashValue(name.data())] = callback;
}
void on_register(const std::string& name, const std::function<void()>& callback)
{
dvar_on_register_function_map[game::generateHashValue(name.data())] = callback;
}
}
utils::hook::detour dvar_register_bool_hook;
utils::hook::detour dvar_register_bool_hashed_hook;
utils::hook::detour dvar_register_float_hook;
@ -271,6 +288,8 @@ namespace dvars
utils::hook::detour dvar_set_string_hook;
utils::hook::detour dvar_set_from_string_hook;
utils::hook::detour dvar_set_variant_hook;
game::dvar_t* dvar_register_bool(const int hash, const char* name, bool value, unsigned int flags)
{
auto* var = find_dvar(override::register_bool_overrides, hash);
@ -409,21 +428,15 @@ namespace dvars
return dvar_register_enum_hook.invoke<game::dvar_t*>(hash, name, value_list, default_index, flags);
}
std::unordered_map<int, std::function<void()>> dvar_on_register_function_map;
void on_register(const std::string& name, const std::function<void()>& callback)
{
dvar_on_register_function_map[game::generateHashValue(name.data())] = callback;
}
game::dvar_t* dvar_register_new(const int hash, const char* name, game::dvar_type type, unsigned int flags,
game::dvar_value* value, game::dvar_limits* domain, const char* description)
{
auto* dvar = dvar_register_new_hook.invoke<game::dvar_t*>(hash, name, type, flags, value, domain, description);
if (dvar && dvar_on_register_function_map.find(hash) != dvar_on_register_function_map.end())
if (dvar && callback::dvar_on_register_function_map.find(hash) != callback::dvar_on_register_function_map.end())
{
dvar_on_register_function_map[hash]();
dvar_on_register_function_map.erase(hash);
callback::dvar_on_register_function_map[hash]();
callback::dvar_on_register_function_map.erase(hash);
}
return dvar;
@ -514,6 +527,16 @@ namespace dvars
return dvar_set_from_string_hook.invoke<void>(dvar, string, source);
}
void dvar_set_variant(game::dvar_t* dvar, game::dvar_value* value, game::DvarSetSource source)
{
dvar_set_variant_hook.invoke<void>(dvar, value, source);
if (callback::new_value_callbacks.find(dvar->hash) != callback::new_value_callbacks.end())
{
callback::new_value_callbacks[dvar->hash]();
}
}
class component final : public component_interface
{
public:
@ -541,6 +564,8 @@ namespace dvars
dvar_set_int_hook.create(SELECT_VALUE(0x41BEE0_b, 0x185D10_b), &dvar_set_int);
dvar_set_string_hook.create(SELECT_VALUE(0x41C0F0_b, 0x186080_b), &dvar_set_string);
dvar_set_from_string_hook.create(SELECT_VALUE(0x41BE20_b, 0x185C60_b), &dvar_set_from_string);
dvar_set_variant_hook.create(SELECT_VALUE(0x41C190_b, 0x186120_b), &dvar_set_variant);
}
};
}

View File

@ -27,5 +27,10 @@ namespace dvars
void set_from_string(const std::string& name, const std::string& value);
}
namespace callback
{
void on_new_value(const std::string& name, const std::function<void()> callback);
void on_register(const std::string& name, const std::function<void()>& callback);
}
}

View File

@ -15,6 +15,8 @@ namespace filesystem
{
namespace
{
utils::hook::detour fs_startup_hook;
bool initialized = false;
std::deque<std::filesystem::path>& get_search_paths_internal()
@ -32,17 +34,19 @@ namespace filesystem
void fs_startup_stub(const char* name)
{
console::info("[FS] Startup\n");
console::debug("[FS] Startup\n");
initialized = true;
// hardcoded paths
filesystem::register_path(L".");
filesystem::register_path(L"h1-mod");
filesystem::register_path(L"data");
// while this clears localizations, it also calls a function to load them again
localized_strings::clear();
utils::hook::invoke<void>(SELECT_VALUE(0x40D890_b, 0x189A40_b), name);
fs_startup_hook.invoke<void>(name);
}
std::vector<std::filesystem::path> get_paths(const std::filesystem::path& path)
@ -157,7 +161,7 @@ namespace filesystem
{
if (can_insert_path(path_))
{
console::info("[FS] Registering path '%s'\n", path_.generic_string().data());
console::debug("[FS] Registering path '%s'\n", path_.generic_string().data());
get_search_paths_internal().push_front(path_);
}
}
@ -178,7 +182,7 @@ namespace filesystem
{
if (*i == path_)
{
console::info("[FS] Unregistering path '%s'\n", path_.generic_string().data());
console::debug("[FS] Unregistering path '%s'\n", path_.generic_string().data());
i = search_paths.erase(i);
}
else
@ -219,7 +223,8 @@ namespace filesystem
public:
void post_unpack() override
{
utils::hook::call(SELECT_VALUE(0x40C992_b, 0x18939F_b), fs_startup_stub);
fs_startup_hook.create(SELECT_VALUE(0x40D890_b, 0x189A40_b), fs_startup_stub);
utils::hook::jump(SELECT_VALUE(0x42CE00_b, 0x5B3440_b), sys_default_install_path_stub);
// fs_game flags

View File

@ -390,7 +390,7 @@ namespace ui_scripting
load_script("lui_updater", lui_updater);
load_script("lua_json", lua_json);
for (const auto& path : filesystem::get_search_paths())
for (const auto& path : filesystem::get_search_paths_rev())
{
load_scripts(path + "/ui_scripts/");
if (game::environment::is_sp())

View File

@ -50,7 +50,7 @@ namespace scripting::lua::engine
{
stop();
running = true;
for (const auto& path : filesystem::get_search_paths())
for (const auto& path : filesystem::get_search_paths_rev())
{
load_scripts(path + "/scripts/");
if (game::environment::is_sp())

View File

@ -202,7 +202,6 @@ void limit_parallel_dll_loading()
int main()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
ShowWindow(GetConsoleWindow(), SW_SHOW);
FARPROC entry_point;