cleanup + fixes

i think our sys_createfile hook needs fixed
This commit is contained in:
m 2022-09-03 17:57:24 -05:00
parent ea24a66e15
commit 4f7a5969b8
7 changed files with 31 additions and 172 deletions

View File

@ -417,6 +417,24 @@ namespace command
? "^2on"
: "^1off"));
}
void monitor_fs_game_values()
{
dvars::callback::on_register("fs_game", []()
{
register_fs_game_path();
});
// it might be overdone to change the filesystem path on every new value change, but to be fair,
// for the mods that don't need full restarts, this is good because it'll adjust and work like so
// in my opinion, this is fine. if a user tries to modify the dvar themselves, they'll have problems
// but i seriously doubt it'll be bad.
dvars::callback::on_new_value("fs_game", []()
{
console::warn("fs_game value changed, filesystem paths will be adjusted to new dvar value.");
register_fs_game_path();
});
}
}
void read_startup_variable(const std::string& dvar)
@ -585,16 +603,7 @@ namespace command
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", []()
{
console::warn("fs_game value changed, filesystem paths will be adjusted to new dvar value.");
register_fs_game_path();
});
monitor_fs_game_values();
if (game::environment::is_sp())
{

View File

@ -148,9 +148,7 @@ namespace fastfiles
if (localized)
{
const auto language = game::SEH_GetCurrentLanguageCode();
try_load_zone(language + "_"s + name, false);
if (language != "eng"s)
if (!try_load_zone(language + "_"s + name, false) && language != "eng"s)
{
try_load_zone("eng_" + name, false);
}
@ -158,6 +156,7 @@ namespace fastfiles
if (!fastfiles::exists(name))
{
console::debug("fastfile %s doesn't exist\n", name.data());
return false;
}
@ -232,12 +231,10 @@ namespace fastfiles
// ui
// common
//try_load_zone("h1_mod_common", true);
try_load_zone("h1_mod_common", true);
game::DB_LoadXAssets(data.data(), static_cast<std::uint32_t>(data.size()), syncMode);
// H2-mod has the try_load_zone for mod right here but before, we had it before the load assets call. guess quaK can let me know
// what to do about this
try_load_zone("mod", true);
}
@ -261,6 +258,7 @@ namespace fastfiles
CloseHandle(handle);
return true;
}
return false;
}
@ -339,7 +337,7 @@ namespace fastfiles
}
const auto name = params.get(1);
if (!try_load_zone(name, false, true))
if (!try_load_zone(name, false))
{
console::warn("loadzone: zone \"%s\" could not be found!\n", name);
}

View File

@ -45,9 +45,6 @@ namespace filesystem
filesystem::register_path(L".");
filesystem::register_path(L"h1-mod");
// while this clears localizations, it also calls a function to load them again
localized_strings::clear();
fs_startup_hook.invoke<void>(name);
}

View File

@ -18,13 +18,7 @@ namespace localized_strings
{
utils::hook::detour seh_string_ed_get_string_hook;
struct localize_entry
{
std::string value{};
bool volatile_{};
};
using localized_map = std::unordered_map<std::string, localize_entry>;
using localized_map = std::unordered_map<std::string, std::string>;
utils::concurrency::container<localized_map> localized_overrides;
const char* seh_string_ed_get_string(const char* reference)
@ -34,155 +28,22 @@ namespace localized_strings
const auto entry = map.find(reference);
if (entry != map.end())
{
return utils::string::va("%s", entry->second.value.data());
return utils::string::va("%s", entry->second.data());
}
return seh_string_ed_get_string_hook.invoke<const char*>(reference);
});
}
game::XAssetHeader db_find_localize_entry_stub(game::XAssetType type, const char* name, int allow_create_default)
{
const auto value = localized_overrides.access<const char*>([&](const localized_map& map)
-> const char*
{
const auto entry = map.find(name);
if (entry != map.end())
{
return utils::string::va("%s", entry->second.value.data());
}
return nullptr;
});
if (value == nullptr)
{
return game::DB_FindXAssetHeader(type, name, allow_create_default);
}
static game::LocalizeEntry entry{};
entry.value = value;
entry.name = name;
return static_cast<game::XAssetHeader>(&entry);
}
bool parse_localized_strings_file(const std::string& data)
{
rapidjson::Document j;
j.Parse(data.data());
if (!j.IsObject())
{
return false;
}
localized_overrides.access([&](localized_map& map)
{
const auto obj = j.GetObj();
for (const auto& [key, value] : obj)
{
if (!key.IsString() || !value.IsString())
{
continue;
}
const auto name = key.GetString();
const auto str = value.GetString();
const auto entry = map.find(name);
if (entry == map.end() || entry->second.volatile_)
{
map[name] = {str, true};
}
}
});
return true;
}
bool try_load_file(const std::string& path, const std::string& language)
{
const auto file = utils::string::va("%s/localizedstrings/%s.json", path.data(), language.data());
if (!utils::io::file_exists(file))
{
return false;
}
console::info("Parsing %s\n", file);
const auto data = utils::io::read_file(file);
if (!parse_localized_strings_file(data))
{
console::error("Invalid language json file\n");
return false;
}
return true;
}
void load_localized_strings()
{
bool found = false;
const auto search_paths = filesystem::get_search_paths_rev();
const auto language = game::SEH_GetCurrentLanguageName();
for (const auto& path : search_paths)
{
bool found_in_current_path = false;
if (try_load_file(path, "english"))
{
found_in_current_path = true;
found = true;
}
if (language != "english"s && !try_load_file(path, language) && found_in_current_path)
{
console::warn("No valid language file found for '%s' in '%s/localizedstrings/', falling back to 'english'\n",
language, path.data());
}
else
{
found = true;
}
}
if (!found)
{
console::warn("[Localized strings] No valid language file found!\n");
}
}
}
void override(const std::string& key, const std::string& value, bool volatile_)
void override(const std::string& key, const std::string& value)
{
localized_overrides.access([&](localized_map& map)
{
map[key] = {value, volatile_};
map[key] = value;
});
}
void clear()
{
localized_overrides.access([&](localized_map& map)
{
for (auto i = map.begin(); i != map.end();)
{
if (i->second.volatile_)
{
i = map.erase(i);
}
else
{
++i;
}
}
});
load_localized_strings();
}
class component final : public component_interface
{
public:
@ -190,7 +51,6 @@ namespace localized_strings
{
// Change some localized strings
seh_string_ed_get_string_hook.create(SELECT_VALUE(0x3E6CE0_b, 0x585DA0_b), &seh_string_ed_get_string);
utils::hook::call(SELECT_VALUE(0x3E67C9_b, 0x585889_b), db_find_localize_entry_stub);
}
};
}

View File

@ -2,6 +2,5 @@
namespace localized_strings
{
void override(const std::string& key, const std::string& value, bool volatile_ = false);
void clear();
void override(const std::string& key, const std::string& value);
}

View File

@ -32,8 +32,6 @@ namespace mods
fonts::clear();
}
localized_strings::clear();
db_release_xassets_hook.invoke<void>();
}
@ -88,7 +86,7 @@ namespace mods
if (!game::Com_InFrontend() && (game::environment::is_mp() && !game::VirtualLobby_Loaded()))
{
console::info("Cannot load mod while in-game!\n");
game::CG_GameMessage(0, "^1Cannot unload mod while in-game!");
game::CG_GameMessage(0, "^1Cannot load mod while in-game!");
return;
}
@ -103,8 +101,6 @@ namespace mods
if (mod_requires_restart(mod_path) || mod_requires_restart(path))
{
// vid_restart is still broken :(
// TODO: above was fed's comment for H2, can we actually use it just fine?
console::info("Restarting...\n");
full_restart("+set fs_game \""s + path + "\"");
}

View File

@ -219,7 +219,7 @@ namespace ui_scripting
game_type["addlocalizedstring"] = [](const game&, const std::string& string,
const std::string& value)
{
localized_strings::override(string, value, true);
localized_strings::override(string, value);
};
game_type["sharedset"] = [](const game&, const std::string& key, const std::string& value)