cleanup + fixes
i think our sys_createfile hook needs fixed
This commit is contained in:
parent
ea24a66e15
commit
4f7a5969b8
@ -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())
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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 + "\"");
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user