Skip to content

Commit

Permalink
Merge pull request #118 from chinosk6/main
Browse files Browse the repository at this point in the history
支持载入多个自定义 AssetBundle,修复 set_vSyncCount 失效的问题
  • Loading branch information
chinosk6 authored Mar 13, 2023
2 parents 6b5afd7 + 4ba9801 commit dfd14d5
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 88 deletions.
2 changes: 1 addition & 1 deletion resources/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"autoFullscreen": false,
"readRequestPack": false,
"extraAssetBundlePath": "localized_data/umamusumelocalify",
"extraAssetBundlePaths": ["localized_data/umamusumelocalify"],
"replaceFont": true,
"customFontPath": "assets/bundledassets/umamusumelocalify/fonts/MSYH.TTC",
"customFontSizeOffset": -4,
Expand Down
12 changes: 6 additions & 6 deletions resources/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@
"description": "是否读取客户端发送包信息,开启此功能可在命令行中输入reboot快速重启游戏",
"type": "boolean"
},
"extraAssetBundlePath": {
"extraAssetBundlePaths": {
"description": "图片等资源替换包的路径(需要用unity打包,一般情况下请不要改动此项)",
"type": [
"string",
"null"
]
"type": "array",
"items": {
"type": "string"
}
},
"replaceFont": {
"description": "替换字体,true:用系统默认字体或自定义字体替换;false:使用游戏原字体",
Expand Down Expand Up @@ -372,7 +372,7 @@
"maxFps",
"unlockSize",
"uiScale",
"extraAssetBundlePath",
"extraAssetBundlePaths",
"replaceFont",
"customFontPath",
"customFontSizeOffset",
Expand Down
12 changes: 6 additions & 6 deletions resources/config_en.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@
"description": "Read the msgpack sent by game, you can reboot the game quicker by typing 'reboot' in the console if you enable it.",
"type": "boolean"
},
"extraAssetBundlePath": {
"extraAssetBundlePaths": {
"description": "The location of asset bundle that is used to replace the original asset file of the game (Do not change it if you don't understand what it is)",
"type": [
"string",
"null"
]
"type": "array",
"items": {
"type": "string"
}
},
"replaceFont": {
"description": "Use system default font to show the Chinese characters that is not contained in the orignal game font",
Expand Down Expand Up @@ -372,7 +372,7 @@
"maxFps",
"unlockSize",
"uiScale",
"extraAssetBundlePath",
"extraAssetBundlePaths",
"replaceFont",
"customFontPath",
"customFontSizeOffset",
Expand Down
12 changes: 6 additions & 6 deletions resources/config_zh_tw.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@
"description": "是否讀取用戶端發包訊息,開啟此功能可在命令行中輸入reboot快速重啟遊戲",
"type": "boolean"
},
"extraAssetBundlePath": {
"extraAssetBundlePaths": {
"description": "圖片等素材替換包的路徑(需要用unity打包,一般情況下請不要改動此項)",
"type": [
"string",
"null"
]
"type": "array",
"items": {
"type": "string"
}
},
"replaceFont": {
"description": "替換字型,true:用系統默認字型或自定義字型替換;false:使用遊戲原字型",
Expand Down Expand Up @@ -372,7 +372,7 @@
"maxFps",
"unlockSize",
"uiScale",
"extraAssetBundlePath",
"extraAssetBundlePaths",
"replaceFont",
"customFontPath",
"customFontSizeOffset",
Expand Down
153 changes: 91 additions & 62 deletions src/hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -896,11 +896,14 @@ namespace
using is_transparent = void;
};

std::unordered_set<std::wstring, TransparentStringHash, std::equal_to<void>> ExtraAssetBundleAssetPaths;
// std::unordered_set<std::wstring, TransparentStringHash, std::equal_to<void>> ExtraAssetBundleAssetPaths;
typedef std::unordered_set<std::wstring, TransparentStringHash, std::equal_to<void>> AssetPathsType;
std::map<string, AssetPathsType> CustomAssetBundleAssetPaths;
void* (*AssetBundle_LoadFromFile)(Il2CppString* path);
void (*AssetBundle_Unload)(void* _this, bool unloadAllLoadedObjects);

uint32_t ExtraAssetBundleHandle;
// uint32_t ExtraAssetBundleHandle;
unordered_map<string, uint32_t> CustomAssetBundleHandleMap{};

void* StoryTimelineDataClass;
FieldInfo* StoryTimelineDataClass_StoryIdField;
Expand Down Expand Up @@ -931,6 +934,20 @@ namespace
FieldInfo* RubyDataClass_CharY;
FieldInfo* RubyDataClass_RubyText;

uint32_t GetBundleHandleByAssetName(wstring assetName) {
for (const auto& i : CustomAssetBundleAssetPaths) {
if (i.second.contains(wstring_view(assetName))) {
const auto& bundleName = i.first;
return CustomAssetBundleHandleMap.at(bundleName);
}
}
return NULL;
}

uint32_t GetBundleHandleByAssetName(string assetName) {
return GetBundleHandleByAssetName(utility::conversions::to_string_t(assetName));
}

void LocalizeStoryTextRubyData(void* textRuby) {
const auto textRubyDataArr = il2cpp_symbols::read_field(textRuby, TextRubyDataClass_DataArray);

Expand Down Expand Up @@ -1110,13 +1127,11 @@ namespace
{
UmaDatabase::setBundleHandleTargetCache(name->start_char, _this);
//const auto stackTrace = environment_get_stacktrace();
if (ExtraAssetBundleHandle)
const auto& bundleHandle = GetBundleHandleByAssetName(name->start_char);
if (bundleHandle)
{
const auto extraAssetBundle = il2cpp_gchandle_get_target(ExtraAssetBundleHandle);
if (ExtraAssetBundleAssetPaths.contains(std::wstring_view(name->start_char)))
{
return reinterpret_cast<decltype(AssetBundle_LoadAsset_hook)*>(AssetBundle_LoadAsset_orig)(extraAssetBundle, name, type);
}
const auto extraAssetBundle = il2cpp_gchandle_get_target(bundleHandle);
return reinterpret_cast<decltype(AssetBundle_LoadAsset_hook)*>(AssetBundle_LoadAsset_orig)(extraAssetBundle, name, type);
}

if (g_enable_replaceBuiltInAssets) {
Expand Down Expand Up @@ -1190,15 +1205,14 @@ namespace

const auto cls = il2cpp_symbols::get_class_from_instance(result);

if (ExtraAssetBundleHandle)
const auto& bundleHandle = GetBundleHandleByAssetName(name->start_char);
if (bundleHandle)
{
const auto extraAssetBundle = il2cpp_gchandle_get_target(ExtraAssetBundleHandle);
if (ExtraAssetBundleAssetPaths.contains(std::wstring_view(name->start_char)))
{
printf("async_extra: %ls\n", name->start_char);
return reinterpret_cast<decltype(AssetBundle_LoadAsset_hook)*>(AssetBundle_LoadAsset_orig)(extraAssetBundle, name,
static_cast<Il2CppReflectionType*>(il2cpp_class_get_type(cls)));
}
const auto extraAssetBundle = il2cpp_gchandle_get_target(bundleHandle);
printf("async_extra: %ls\n", name->start_char);
return reinterpret_cast<decltype(AssetBundle_LoadAsset_hook)*>(AssetBundle_LoadAsset_orig)(extraAssetBundle, name,
static_cast<Il2CppReflectionType*>(il2cpp_class_get_type(cls)));

}

if (g_asset_load_log) {
Expand Down Expand Up @@ -1259,7 +1273,8 @@ namespace
reinterpret_cast<decltype(TextCommon_Awake_hook)*>(TextCommon_Awake_orig)(_this);

void* replaceFont{};
if (std::holds_alternative<UseCustomFont>(g_replace_font) && ExtraAssetBundleHandle)
const auto& bundleHandle = GetBundleHandleByAssetName(std::get<UseCustomFont>(g_replace_font).FontPath);
if (std::holds_alternative<UseCustomFont>(g_replace_font) && bundleHandle)
{
if (ReplaceFontHandle)
{
Expand All @@ -1276,7 +1291,8 @@ namespace
il2cpp_gchandle_free(std::exchange(ReplaceFontHandle, 0));
}
}
const auto extraAssetBundle = il2cpp_gchandle_get_target(ExtraAssetBundleHandle);

const auto extraAssetBundle = il2cpp_gchandle_get_target(bundleHandle);
replaceFont = reinterpret_cast<decltype(AssetBundle_LoadAsset_hook)*>(AssetBundle_LoadAsset_orig)(extraAssetBundle, il2cpp_string_new(std::get<UseCustomFont>(g_replace_font).FontPath.c_str()), Font_Type);
if (replaceFont)
{
Expand Down Expand Up @@ -2312,10 +2328,7 @@ namespace
"umamusume.dll", "Gallop",
"GraphicSettings", "ApplyGraphicsQuality", 2);

auto set_vsync_count_addr = il2cpp_symbols::get_method_pointer(
"UnityEngine.CoreModule.dll", "UnityEngine",
"QualitySettings", "set_vSyncCount", 1
);
auto set_vsync_count_addr = il2cpp_resolve_icall("UnityEngine.QualitySettings::set_vSyncCount(System.Int32)");

auto wndproc_addr = il2cpp_symbols::get_method_pointer(
"umamusume.dll", "Gallop",
Expand Down Expand Up @@ -3011,31 +3024,15 @@ namespace
}
}


bool init_hook()
{
if (mh_inited)
return false;

if (MH_Initialize() != MH_OK)
return false;

mh_inited = true;

MH_CreateHook(LoadLibraryW, load_library_w_hook, &load_library_w_orig);
MH_EnableHook(LoadLibraryW);

return true;
}

void LoadExtraAssetBundle()
{
if (g_extra_assetbundle_path.empty())
if (g_extra_assetbundle_paths.empty())
{
return;
}

assert(!ExtraAssetBundleHandle && ExtraAssetBundleAssetPaths.empty());
// CustomAssetBundleHandleMap.clear();
// CustomAssetBundleAssetPaths.clear();
// assert(!ExtraAssetBundleHandle && ExtraAssetBundleAssetPaths.empty());

const auto AssetBundle_GetAllAssetNames = reinterpret_cast<void* (*)(void*)>(
il2cpp_symbols::get_method_pointer(
Expand All @@ -3044,31 +3041,63 @@ void LoadExtraAssetBundle()
)
);

const auto extraAssetBundle = AssetBundle_LoadFromFile(il2cpp_string_new(g_extra_assetbundle_path.c_str()));
if (extraAssetBundle)
{
const auto allAssetPaths = AssetBundle_GetAllAssetNames(extraAssetBundle);
il2cpp_symbols::iterate_IEnumerable<Il2CppString*>(allAssetPaths, [](Il2CppString* path)
{
ExtraAssetBundleAssetPaths.emplace(path->start_char);
});
ExtraAssetBundleHandle = il2cpp_gchandle_new(extraAssetBundle, false);
}
else
{
std::wprintf(L"Cannot load asset bundle\n");
for (const auto& i : g_extra_assetbundle_paths) {
if (CustomAssetBundleHandleMap.contains(i)) continue;

const auto extraAssetBundle = AssetBundle_LoadFromFile(il2cpp_string_new(i.c_str()));
if (extraAssetBundle)
{
const auto allAssetPaths = AssetBundle_GetAllAssetNames(extraAssetBundle);
AssetPathsType assetPath{};
il2cpp_symbols::iterate_IEnumerable<Il2CppString*>(allAssetPaths, [&assetPath](Il2CppString* path)
{
// ExtraAssetBundleAssetPaths.emplace(path->start_char);
assetPath.emplace(path->start_char);
});
CustomAssetBundleAssetPaths.emplace(i, assetPath);
CustomAssetBundleHandleMap.emplace(i, il2cpp_gchandle_new(extraAssetBundle, false));
}
else
{
printf("Cannot load asset bundle: %s\n", i.c_str());
}
}
}

void UnloadExtraAssetBundle()
{
if (ExtraAssetBundleHandle)
{
ExtraAssetBundleAssetPaths.clear();
AssetBundle_Unload(il2cpp_gchandle_get_target(ExtraAssetBundleHandle), true);
il2cpp_gchandle_free(ExtraAssetBundleHandle);
ExtraAssetBundleHandle = 0;
{
CustomAssetBundleAssetPaths.clear();
for (const auto& i : CustomAssetBundleHandleMap) {
if (i.second)
{
AssetBundle_Unload(il2cpp_gchandle_get_target(i.second), true);
il2cpp_gchandle_free(i.second);
// i.second = 0;
}
}

}

void reloadAssetBundle() {
// UnloadExtraAssetBundle();
LoadExtraAssetBundle();
}

bool init_hook()
{
if (mh_inited)
return false;

if (MH_Initialize() != MH_OK)
return false;

mh_inited = true;
onPluginReload.push_back(reloadAssetBundle);

MH_CreateHook(LoadLibraryW, load_library_w_hook, &load_library_w_orig);
MH_EnableHook(LoadLibraryW);

return true;
}

void uninit_hook()
Expand Down
32 changes: 26 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ int g_max_fps = -1;
bool g_unlock_size = false;
float g_ui_scale = 1.0f;
float g_aspect_ratio = 16.f / 9.f;
std::string g_extra_assetbundle_path;
// std::string g_extra_assetbundle_path;
std::list<std::string> g_extra_assetbundle_paths{};
std::variant<UseOriginalFont, UseDefaultFont, UseCustomFont> g_replace_font;
int g_custom_font_size_offset;
int g_custom_font_style;
Expand Down Expand Up @@ -82,6 +83,7 @@ std::string g_text_data_dict_path;
std::string g_character_system_text_dict_path;
std::string g_race_jikkyo_comment_dict_path;
std::string g_race_jikkyo_message_dict_path;
std::list<std::function<void(void)>> onPluginReload{};

constexpr const char LocalizedDataPath[] = "localized_data";
constexpr const char OldLocalizedDataPath[] = "old_localized_data";
Expand Down Expand Up @@ -431,19 +433,34 @@ namespace
http_start_port = document["httpServerPort"].GetInt();
}

const auto& extraAssetBundlePath = document["extraAssetBundlePath"];
if (extraAssetBundlePath.IsString())
{
g_extra_assetbundle_path = extraAssetBundlePath.GetString();
g_extra_assetbundle_paths.clear();

if (document.HasMember("extraAssetBundlePath")) {
const auto& extraAssetBundlePath = document["extraAssetBundlePath"];
if (extraAssetBundlePath.IsString())
{
g_extra_assetbundle_paths.push_back(extraAssetBundlePath.GetString());
}
}

if (document.HasMember("extraAssetBundlePaths")) {
const auto& extraAssetBundlePaths = document["extraAssetBundlePaths"];
if (extraAssetBundlePaths.IsArray())
{
for (const auto& i : document["extraAssetBundlePaths"].GetArray()) {
g_extra_assetbundle_paths.push_back(i.GetString());
}
}
}


const auto& replaceFont = document["replaceFont"];
if (replaceFont.GetBool())
{
const auto& customFontPath = document["customFontPath"];
if (customFontPath.IsString())
{
assert(!g_extra_assetbundle_path.empty() && "extraAssetBundlePath should be specified to use custom font");
// assert(!g_extra_assetbundle_paths.empty() && "extraAssetBundlePath should be specified to use custom font");
g_replace_font = UseCustomFont{ .FontPath = customFontPath.GetString() };
}
else
Expand Down Expand Up @@ -1465,6 +1482,9 @@ extern std::function<void()> g_on_hook_ready;
void reload_all_data() {
read_config();
reload_config();
for (const auto& i : onPluginReload) {
i();
}
}

namespace HttpServer {
Expand Down
Loading

0 comments on commit dfd14d5

Please sign in to comment.