From 8c980abbd2d053b96690640d9a74e990013d7e41 Mon Sep 17 00:00:00 2001 From: Ji O Date: Fri, 6 Oct 2023 02:15:16 +0900 Subject: [PATCH] WIP: Add in-game config settings --- src/VERSIONINFO.rc | 12 +- src/hook.cpp | 433 +++++++++++++++++++++++++++++++--- src/il2cpp/il2cpp_symbols.cpp | 2 + src/il2cpp/il2cpp_symbols.hpp | 24 +- src/main.cpp | 8 +- 5 files changed, 435 insertions(+), 44 deletions(-) diff --git a/src/VERSIONINFO.rc b/src/VERSIONINFO.rc index d66d50b..2c43ca3 100644 --- a/src/VERSIONINFO.rc +++ b/src/VERSIONINFO.rc @@ -7,8 +7,8 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,28,0,0 - PRODUCTVERSION 1,28,0,0 + FILEVERSION 1,29,0,0 + PRODUCTVERSION 1,29,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -25,19 +25,19 @@ BEGIN BEGIN VALUE "LegalCopyright", "Copyright © Ji O Kim\0" VALUE "FileDescription", "우마무스메 현지화 패치\0" - VALUE "FileVersion", "1.28.0.0\0" + VALUE "FileVersion", "1.29.0.0\0" VALUE "InternalName", "umamusume-localify\0" VALUE "ProductName", "Umamusume Localify\0" - VALUE "ProductVersion", "1.28.0\0" + VALUE "ProductVersion", "1.29.0\0" END BLOCK "000004b0" BEGIN VALUE "LegalCopyright", "Copyright © Ji O Kim\0" VALUE "FileDescription", "Localization patch for Umamusume\0" - VALUE "FileVersion", "1.28.0.0\0" + VALUE "FileVersion", "1.29.0.0\0" VALUE "InternalName", "umamusume-localify\0" VALUE "ProductName", "Umamusume Localify\0" - VALUE "ProductVersion", "1.28.0\0" + VALUE "ProductVersion", "1.29.0\0" END END BLOCK "VarFileInfo" diff --git a/src/hook.cpp b/src/hook.cpp index 50fe146..15bff10 100644 --- a/src/hook.cpp +++ b/src/hook.cpp @@ -940,19 +940,25 @@ namespace Il2CppDelegate* CreateDelegateWithClass(Il2CppClass* klass, Il2CppObject* target, void (*fn)(Il2CppObject*, T...)) { auto delegate = reinterpret_cast(il2cpp_object_new(klass)); - delegate->delegates = il2cpp_array_new(il2cpp_symbols::get_class("mscorlib.dll", "System", "Delegate"), 1); - il2cpp_array_setref(delegate->delegates, 0, delegate); delegate->method_ptr = reinterpret_cast(fn); auto methodInfo = reinterpret_cast(il2cpp_object_new( il2cpp_symbols::get_class("mscorlib.dll", "System.Reflection", "MethodInfo"))); methodInfo->methodPointer = delegate->method_ptr; methodInfo->klass = il2cpp_symbols::get_class("mscorlib.dll", "System.Reflection", "MethodInfo"); + methodInfo->invoker_method = *([](Il2CppMethodPointer fn, const MethodInfo* method, void* obj, void** params) + { + return reinterpret_cast(fn)(obj, params); + }); delegate->method = methodInfo; - delegate->target = target; auto object = reinterpret_cast(delegate); + // auto targetField = il2cpp_class_get_field_from_name_wrap(object->klass, "m_target"); + // auto targetDest = reinterpret_cast(object) + targetField->offset; + + il2cpp_gc_wbarrier_set_field(object, reinterpret_cast(&(delegate)->target), target); + // auto methodInfoField = il2cpp_class_get_field_from_name_wrap(object->klass, "method_info"); // il2cpp_field_set_value(object, methodInfoField, methodInfo); @@ -970,19 +976,25 @@ namespace { auto delegate = reinterpret_cast( il2cpp_object_new(il2cpp_symbols::get_class("mscorlib.dll", "System", "MulticastDelegate"))); - delegate->delegates = il2cpp_array_new(il2cpp_symbols::get_class("mscorlib.dll", "System", "Delegate"), 1); - il2cpp_array_setref(delegate->delegates, 0, delegate); delegate->method_ptr = reinterpret_cast(fn); auto methodInfo = reinterpret_cast(il2cpp_object_new( il2cpp_symbols::get_class("mscorlib.dll", "System.Reflection", "MethodInfo"))); methodInfo->methodPointer = delegate->method_ptr; methodInfo->klass = il2cpp_symbols::get_class("mscorlib.dll", "System.Reflection", "MethodInfo"); + methodInfo->invoker_method = *([](Il2CppMethodPointer fn, const MethodInfo* method, void* obj, void** params) + { + return reinterpret_cast(fn)(obj, params); + }); delegate->method = methodInfo; - delegate->target = target; auto object = reinterpret_cast(delegate); + // auto targetField = il2cpp_class_get_field_from_name_wrap(object->klass, "m_target"); + // auto targetDest = reinterpret_cast(object) + targetField->offset; + + il2cpp_gc_wbarrier_set_field(object, reinterpret_cast(&(delegate)->target), target); + // auto methodInfoField = il2cpp_class_get_field_from_name_wrap(object->klass, "method_info"); // il2cpp_field_set_value(object, methodInfoField, methodInfo); @@ -1000,19 +1012,25 @@ namespace { auto delegate = reinterpret_cast( il2cpp_object_new(il2cpp_symbols::get_class("UnityEngine.CoreModule.dll", "UnityEngine.Events", "UnityAction"))); - delegate->delegates = il2cpp_array_new(il2cpp_symbols::get_class("mscorlib.dll", "System", "Delegate"), 1); - il2cpp_array_setref(delegate->delegates, 0, delegate); delegate->method_ptr = reinterpret_cast(fn); auto methodInfo = reinterpret_cast(il2cpp_object_new( il2cpp_symbols::get_class("mscorlib.dll", "System.Reflection", "MethodInfo"))); methodInfo->methodPointer = delegate->method_ptr; methodInfo->klass = il2cpp_symbols::get_class("mscorlib.dll", "System.Reflection", "MethodInfo"); + methodInfo->invoker_method = *([](Il2CppMethodPointer fn, const MethodInfo* method, void* obj, void** params) + { + return reinterpret_cast(fn)(obj, params); + }); delegate->method = methodInfo; - delegate->target = target; auto object = reinterpret_cast(delegate); + // auto targetField = il2cpp_class_get_field_from_name_wrap(object->klass, "m_target"); + // auto targetDest = reinterpret_cast(object) + targetField->offset; + + il2cpp_gc_wbarrier_set_field(object, reinterpret_cast(&(delegate)->target), target); + // auto methodInfoField = il2cpp_class_get_field_from_name_wrap(object->klass, "method_info"); // il2cpp_field_set_value(object, methodInfoField, methodInfo); @@ -5111,6 +5129,43 @@ namespace Il2CppObject* resources_load_hook(Il2CppString* path, Il2CppObject* type); + Il2CppArraySize_t* GetRectTransformArray(Il2CppObject* object) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(object->klass, "GetComponentsInternal", 6)->methodPointer; + auto rectTransformArray = getComponents(object, reinterpret_cast(GetRuntimeType( + "UnityEngine.CoreModule.dll", "UnityEngine", "RectTransform")), true, true, false, false, nullptr); + + return rectTransformArray; + } + + Il2CppObject* GetRectTransform(Il2CppObject* object) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(object->klass, "GetComponentsInternal", 6)->methodPointer; + auto rectTransformArray = getComponents(object, reinterpret_cast(GetRuntimeType( + "UnityEngine.CoreModule.dll", "UnityEngine", "RectTransform")), true, true, false, false, nullptr); + + if (rectTransformArray->max_length) + { + return rectTransformArray->vector[0]; + } + + return nullptr; + } + + Il2CppObject* CreateGameObject() + { + auto gameObjectClass = il2cpp_symbols::get_class("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject"); + auto gameObject = il2cpp_object_new(gameObjectClass); + il2cpp_runtime_object_init(gameObject); + + return gameObject; + } + + Il2CppObject* AddComponent(Il2CppObject* gameObject, void* componentType) + { + return il2cpp_resolve_icall_type("UnityEngine.GameObject::Internal_AddComponentWithType()")(gameObject, componentType); + } + Il2CppObject* GetOptionItemTitle(const char* title) { auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitemtitle"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); @@ -5293,43 +5348,301 @@ namespace return optionItemSimple; } - Il2CppObject* GetRectTransform(Il2CppObject* object) + Il2CppObject* GetOptionItem3ToggleVertical(const char* title) { - auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(object->klass, "GetComponentsInternal", 6)->methodPointer; - auto rectTransformArray = getComponents(object, reinterpret_cast(GetRuntimeType( - "UnityEngine.CoreModule.dll", "UnityEngine", "RectTransform")), true, true, false, false, nullptr); + auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitem3togglevertical"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); - if (rectTransformArray->max_length) + auto optionItem3ToggleVertical = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(optionItem3ToggleVertical->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(optionItem3ToggleVertical, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + for (int i = 0; i < array->max_length; i++) { - return rectTransformArray->vector[0]; + auto textCommon = array->vector[i]; + + if (textCommon) + { + text_set_text(textCommon, il2cpp_string_new(title)); + + auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); + il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + } } - return nullptr; + return optionItem3ToggleVertical; } - void AddToLayout(Il2CppObject* parentRectTransform, vector objects) + Il2CppObject* GetOptionItem3Toggle(const char* title) { - for (int i = objects.size() - 1; i >= 0; i--) - // for (int i = 0; i < objects.size(); i++) + auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitem3toggle"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto optionItem3Toggle = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(optionItem3Toggle->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(optionItem3Toggle, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + for (int i = 0; i < array->max_length; i++) { - auto rectTransform = GetRectTransform(objects[i]); - il2cpp_class_get_method_from_name_type(rectTransform->klass, "SetParent", 2)->methodPointer(rectTransform, parentRectTransform, false); - il2cpp_class_get_method_from_name_type(rectTransform->klass, "SetAsFirstSibling", 0)->methodPointer(rectTransform); + auto textCommon = array->vector[i]; + + if (textCommon) + { + text_set_text(textCommon, il2cpp_string_new(title)); + + auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); + il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + } } + + return optionItem3Toggle; } - Il2CppObject* CreateGameObject() + Il2CppObject* GetOptionItem2Toggle(const char* title) { - auto gameObjectClass = il2cpp_symbols::get_class("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject"); - auto gameObject = il2cpp_object_new(gameObjectClass); - il2cpp_runtime_object_init(gameObject); + auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitem2toggle"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto optionItem2Toggle = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(optionItem2Toggle->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(optionItem2Toggle, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + for (int i = 0; i < array->max_length; i++) + { + auto textCommon = array->vector[i]; + + if (textCommon) + { + text_set_text(textCommon, il2cpp_string_new(title)); + + auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); + il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + } + } + + return optionItem2Toggle; + } + + Il2CppObject* GetOptionSlider(const char* title) + { + auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/optionsoundvolumeslider"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto optionSlider = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(optionSlider->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(optionSlider, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + auto textCommon = array->vector[0]; + + text_set_text(textCommon, il2cpp_string_new(title)); + + auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); + il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + + auto optionSoundVolumeSliderArray = getComponents(optionSlider, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "OptionSoundVolumeSlider")), true, true, false, false, nullptr); + + auto optionSoundVolumeSlider = optionSoundVolumeSliderArray->vector[0]; + + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Destroy", 1)(optionSoundVolumeSlider); + + auto sliderCommonArray = getComponents(optionSlider, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "SliderCommon")), true, true, false, false, nullptr); + + /*auto sliderCommon = sliderCommonArray->vector[0]; + + auto onValueChanged = il2cpp_class_get_method_from_name_type(sliderCommon->klass, "get_onValueChanged", 0)->methodPointer(sliderCommon); + + auto AddCall = il2cpp_class_get_method_from_name_type(onValueChanged->klass, "AddCall", 1); + + auto type = GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine.Events", "InvokableCall`1"); + auto typeArray = il2cpp_array_new(il2cpp_symbols::get_class("mscorlib.dll", "System", "Type"), 1); + il2cpp_array_setref(typeArray, 0, GetRuntimeType("mscorlib.dll", "System", "Single")); + + auto runtimeType = il2cpp_class_get_method_from_name_type(type->klass, "MakeGenericType", 1)->methodPointer(type, typeArray); + auto newType = runtimeType->type.type; + + auto valueChanged = CreateDelegateWithClass(il2cpp_class_from_type(AddCall->parameters->parameter_type), nullptr, *([](Il2CppObject*, float value) + { + cout << "Value " << value << endl; + })); + + auto invokeableCall = il2cpp_object_new(il2cpp_class_from_type(newType)); + + auto delegateField = il2cpp_class_get_field_from_name_wrap(invokeableCall->klass, "Delegate"); + il2cpp_field_set_value(invokeableCall, delegateField, valueChanged); + + AddCall->methodPointer(onValueChanged, invokeableCall);*/ + + auto transformArray = GetRectTransformArray(optionSlider); + + vector destroyTargets; + + for (int i = 0; i < transformArray->max_length; i++) + { + auto transform = transformArray->vector[i]; + + if (transform) + { + if (uobject_get_name(transform)->start_char == L"ToggleMute"s || + uobject_get_name(transform)->start_char == L"ImageIcon"s || + uobject_get_name(transform)->start_char == L"Line"s || + uobject_get_name(transform)->start_char == L"Num"s) + { + destroyTargets.emplace_back(transform); + } + } + } + + for (int i = 0; i < destroyTargets.size(); i++) + { + auto transform = destroyTargets[i]; + il2cpp_class_get_method_from_name_type(transform->klass, "SetParent", 2)->methodPointer(transform, nullptr, false); + auto gameObject = il2cpp_class_get_method_from_name_type(transform->klass, "get_gameObject", 0)->methodPointer(transform); + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Destroy", 1)(gameObject); + } + + destroyTargets.clear(); + + transformArray = GetRectTransformArray(optionSlider); + + for (int i = 0; i < transformArray->max_length; i++) + { + auto transform = transformArray->vector[i]; + + if (transform) + { + if (uobject_get_name(transform)->start_char == L"Slider"s) + { + il2cpp_class_get_method_from_name_type(transform->klass, "set_sizeDelta", 1)->methodPointer(transform, Vector2_t{ 560, 24 }); + break; + } + } + } + + auto gameObject = CreateGameObject(); + auto rootTransform = AddComponent(gameObject, GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "RectTransform")); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_sizeDelta", 1)->methodPointer(rootTransform, Vector2_t{ 0, 680 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchorMax", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchorMin", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_pivot", 1)->methodPointer(rootTransform, Vector2_t{ 0.5, 1 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchoredPosition", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + auto verticalLayoutGroup = AddComponent(gameObject, GetRuntimeType("UnityEngine.UI.dll", "UnityEngine.UI", "VerticalLayoutGroup")); + il2cpp_class_get_method_from_name_type(verticalLayoutGroup->klass, "set_childAlignment", 1)->methodPointer(verticalLayoutGroup, 1); + il2cpp_class_get_method_from_name_type(verticalLayoutGroup->klass, "set_childForceExpandWidth", 1)->methodPointer(verticalLayoutGroup, true); + il2cpp_class_get_method_from_name_type(verticalLayoutGroup->klass, "set_childControlWidth", 1)->methodPointer(verticalLayoutGroup, true); + + auto padding = il2cpp_class_get_method_from_name_type(verticalLayoutGroup->klass, "get_padding", 0)->methodPointer(verticalLayoutGroup); + il2cpp_class_get_method_from_name_type(padding->klass, "set_left", 1)->methodPointer(padding, 54); + + auto sliderTransform = GetRectTransform(optionSlider); + + il2cpp_class_get_method_from_name_type(sliderTransform->klass, "set_sizeDelta", 1)->methodPointer(sliderTransform, Vector2_t{ 1000, 86 }); + il2cpp_class_get_method_from_name_type(sliderTransform->klass, "SetParent", 2)->methodPointer(sliderTransform, rootTransform, false); return gameObject; } - Il2CppObject* AddComponent(Il2CppObject* gameObject, void* componentType) + Il2CppObject* GetDropdown(const char* name) { - return il2cpp_resolve_icall_type("UnityEngine.GameObject::Internal_AddComponentWithType()")(gameObject, componentType); + auto object = resources_load_hook(il2cpp_string_new("ui/parts/base/dropdowncommon"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto dropdownGameObject = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(dropdownGameObject->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(dropdownGameObject, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "DropDownCommon")), true, true, false, false, nullptr); + + auto dropDownCommon = array->vector[0]; + + auto optionList = il2cpp_class_get_method_from_name_type(dropDownCommon->klass, "get_options", 0)->methodPointer(dropDownCommon); + + auto optionClass = il2cpp_symbols::get_class("UnityEngine.UI.dll", "UnityEngine.UI", "Dropdown/OptionData"); + + auto option1 = il2cpp_object_new(optionClass); + il2cpp_class_get_method_from_name_type(option1->klass, "set_text", 1)->methodPointer(option1, il2cpp_string_new("Option 1")); + + auto option2 = il2cpp_object_new(optionClass); + il2cpp_class_get_method_from_name_type(option2->klass, "set_text", 1)->methodPointer(option2, il2cpp_string_new("Option 2")); + + auto array1 = il2cpp_array_new(optionClass, 2); + + il2cpp_array_setref(array1, 0, option1); + il2cpp_array_setref(array1, 1, option2); + + auto itemField = il2cpp_class_get_field_from_name_wrap(optionList->klass, "_items"); + il2cpp_field_set_value(optionList, itemField, array1); + + auto sizeField = il2cpp_class_get_field_from_name_wrap(optionList->klass, "_size"); + int size = 2; + il2cpp_field_set_value(optionList, sizeField, &size); + + + il2cpp_class_get_method_from_name_type(dropDownCommon->klass, "set_options", 1)->methodPointer(dropDownCommon, optionList); + + auto transform = GetRectTransform(dropdownGameObject); + + il2cpp_class_get_method_from_name_type(transform->klass, "set_sizeDelta", 1)->methodPointer(transform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(transform->klass, "set_anchorMax", 1)->methodPointer(transform, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(transform->klass, "set_anchorMin", 1)->methodPointer(transform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(transform->klass, "set_pivot", 1)->methodPointer(transform, Vector2_t{ 0.5, 0.5 }); + + il2cpp_class_get_method_from_name_type(transform->klass, "set_anchoredPosition", 1)->methodPointer(transform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(transform->klass, "set_localPosition", 1)->methodPointer(transform, Vector3_t{ 0, 0, -10 }); + + return dropdownGameObject; + } + + Il2CppObject* GetCheckbox(const char* name) + { + auto object = resources_load_hook(il2cpp_string_new("ui/parts/base/checkbox"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto checkbox = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + return checkbox; + } + + Il2CppObject* GetCheckboxWithText(const char* name) + { + auto object = resources_load_hook(il2cpp_string_new("ui/parts/base/checkboxwithtext"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto checkboxWithText = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + return checkboxWithText; + } + + Il2CppObject* GetRadioButtonWithText(const char* name) + { + auto object = resources_load_hook(il2cpp_string_new("ui/parts/base/radiobuttonwithtext"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto radioButtonWithText = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + return radioButtonWithText; + } + + void AddToLayout(Il2CppObject* parentRectTransform, vector objects) + { + for (int i = objects.size() - 1; i >= 0; i--) + // for (int i = 0; i < objects.size(); i++) + { + auto rectTransform = GetRectTransform(objects[i]); + il2cpp_class_get_method_from_name_type(rectTransform->klass, "SetParent", 2)->methodPointer(rectTransform, parentRectTransform, false); + il2cpp_class_get_method_from_name_type(rectTransform->klass, "SetAsFirstSibling", 0)->methodPointer(rectTransform); + } } Il2CppObject* settingsDialog; @@ -5351,6 +5664,10 @@ namespace configDocument["characterSystemTextCaption"].SetBool(GetOptionItemOnOffIsOn("character_system_text_caption")); + configDocument["championsLiveShowText"].SetBool(GetOptionItemOnOffIsOn("champions_live_show_text")); + + g_champions_live_show_text = configDocument["championsLiveShowText"].GetBool(); + config::write_config(); auto dialogData = il2cpp_object_new( @@ -5480,9 +5797,20 @@ namespace GetOptionItemTitle("Localify Settings"), GetOptionItemOnOff("character_system_text_caption", "Character System Text caption"), GetOptionItemButton("show_caption", "Show caption"), + GetOptionItemOnOff("champions_live_show_text", "Champions Live Show Text"), + GetOptionItemButton("github", "GitHub"), GetOptionItemAttention("Attention with Color\nAttention"), GetOptionItemSimple("Simple"), GetOptionItemOnOff("on_off", "On Off"), + // GetOptionItem3ToggleVertical("Text"), + GetOptionItem3Toggle("Text"), + GetOptionItem2Toggle("Text"), + GetOptionSlider("Text"), + /*GetDropdown("dropdown"), + GetCheckbox("checkbox"), + GetCheckboxWithText("checkbox_with_text"), + GetRadioButtonWithText("radiobutton_with_text"), + GetSlider("slider"),*/ GetOptionItemInfo("Info with Color\nInfo"), GetOptionItemInfo("Info with Color\nInfo"), GetOptionItemInfo("Info with Color\nInfo"), @@ -5500,15 +5828,21 @@ namespace ); bool characterSystemTextCaption = false; + bool championsLiveShowText = false; if (config::read_config()) { auto& configDocument = config::config_document; - + if (configDocument.HasMember("characterSystemTextCaption")) { characterSystemTextCaption = configDocument["characterSystemTextCaption"].GetBool(); } + + if (configDocument.HasMember("championsLiveShowText")) + { + championsLiveShowText = configDocument["championsLiveShowText"].GetBool(); + } } SetOptionItemOnOffAction("character_system_text_caption", characterSystemTextCaption, *([](Il2CppObject*, bool isOn) @@ -5516,6 +5850,11 @@ namespace // TODO })); + SetOptionItemOnOffAction("champions_live_show_text", championsLiveShowText, *([](Il2CppObject*, bool isOn) + { + // TODO + })); + SetOptionItemOnOffAction("on_off", false, *([](Il2CppObject*, bool isOn) { auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); @@ -5536,6 +5875,40 @@ namespace } })); + SetOptionItemButtonAction("github", *([](Il2CppObject*) + { + auto dialogData = il2cpp_object_new( + il2cpp_symbols::get_class("umamusume.dll", "Gallop", + "DialogCommon/Data")); + il2cpp_runtime_object_init(dialogData); + + dialogData = reinterpret_cast( + il2cpp_class_get_method_from_name(dialogData->klass, + "SetSimpleTwoButtonMessage", + 7)->methodPointer + )(dialogData, + localizeextension_text_hook(GetTextIdByName("Common0009")), + localizeextension_text_hook(GetTextIdByName("Home0073")), + CreateDelegate(nullptr, *[](Il2CppObject*) + { + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Application", "OpenURL", 1)(il2cpp_string_new("https://github.com/Kimjio/umamusume-localify")); + }), + GetTextIdByName("Common0004"), + GetTextIdByName("Common0003"), + nullptr, + 2); + + il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + })); + auto contentSizeFitter = AddComponent(contentGameObject, GetRuntimeType("umamusume.dll", "Gallop", "LayoutGroupContentSizeFitter")); auto _layoutField = il2cpp_class_get_field_from_name_wrap(contentSizeFitter->klass, "_layout"); @@ -5547,7 +5920,7 @@ namespace il2cpp_field_set_value(dialogData, ContentsObjectField, gameObject); - settingsDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + settingsDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); } void InitOptionLayout(Il2CppObject* parentRectTransform) diff --git a/src/il2cpp/il2cpp_symbols.cpp b/src/il2cpp/il2cpp_symbols.cpp index 7c5e04b..34fa157 100644 --- a/src/il2cpp/il2cpp_symbols.cpp +++ b/src/il2cpp/il2cpp_symbols.cpp @@ -65,6 +65,7 @@ il2cpp_thread_current_t il2cpp_thread_current; il2cpp_gchandle_new_t il2cpp_gchandle_new; il2cpp_gchandle_get_target_t il2cpp_gchandle_get_target; il2cpp_gchandle_free_t il2cpp_gchandle_free; +il2cpp_gc_wbarrier_set_field_t il2cpp_gc_wbarrier_set_field; char* il2cpp_array_addr_with_size(void* array, int32_t size, uintptr_t idx) { @@ -142,6 +143,7 @@ namespace il2cpp_symbols RESOLVE_IMPORT(il2cpp_gchandle_new); RESOLVE_IMPORT(il2cpp_gchandle_get_target); RESOLVE_IMPORT(il2cpp_gchandle_free); + RESOLVE_IMPORT(il2cpp_gc_wbarrier_set_field); il2cpp_domain = il2cpp_domain_get(); } diff --git a/src/il2cpp/il2cpp_symbols.hpp b/src/il2cpp/il2cpp_symbols.hpp index de15139..94d00b6 100644 --- a/src/il2cpp/il2cpp_symbols.hpp +++ b/src/il2cpp/il2cpp_symbols.hpp @@ -394,8 +394,6 @@ struct MethodInfo_t uint8_t is_marshaled_from_native : 1; }; - - struct Il2CppObject { union @@ -406,6 +404,22 @@ struct Il2CppObject void* monitor; }; + +typedef struct Il2CppReflectionType +{ + Il2CppObject object; + const Il2CppType* type; +} Il2CppReflectionType; + +// System.RuntimeType +typedef struct Il2CppReflectionRuntimeType +{ + Il2CppReflectionType type; + Il2CppObject* type_info; + Il2CppObject* genericCache; + Il2CppObject* serializationCtor; +} Il2CppReflectionRuntimeType; + // not real Il2CppString class struct Il2CppString { @@ -440,7 +454,7 @@ struct Il2CppArraySize_t void* bounds; uintptr_t max_length; alignas(8) - T vector[0]; + T vector[0]; }; static const size_t kIl2CppSizeOfArray = (offsetof(Il2CppArraySize, vector)); @@ -650,7 +664,7 @@ typedef Il2CppClass* (*il2cpp_property_get_parent_t) (const PropertyInfo* prop); typedef int (*il2cpp_field_get_flags_t)(FieldInfo* field); typedef const char* (*il2cpp_field_get_name_t)(FieldInfo* field); typedef Il2CppClass* (*il2cpp_field_get_parent_t)(FieldInfo* field); -typedef size_t (*il2cpp_field_get_offset_t)(FieldInfo* field); +typedef size_t(*il2cpp_field_get_offset_t)(FieldInfo* field); typedef const PropertyInfo* (*il2cpp_class_get_property_from_name_t)(Il2CppClass* klass, const char* name); typedef void (*il2cpp_runtime_object_init_t)(Il2CppObject* obj); typedef void (*il2cpp_runtime_object_init_exception_t)(Il2CppObject* obj, void** exc); @@ -661,6 +675,7 @@ typedef void* (*il2cpp_thread_current_t)(); typedef uint32_t(*il2cpp_gchandle_new_t)(Il2CppObject* obj, bool pinned); typedef Il2CppObject* (*il2cpp_gchandle_get_target_t)(uint32_t gchandle); typedef void (*il2cpp_gchandle_free_t)(uint32_t gchandle); +typedef void (*il2cpp_gc_wbarrier_set_field_t)(Il2CppObject* obj, void** targetAddress, void* object); // function defines extern il2cpp_string_new_utf16_t il2cpp_string_new_utf16; @@ -728,6 +743,7 @@ extern il2cpp_thread_current_t il2cpp_thread_current; extern il2cpp_gchandle_new_t il2cpp_gchandle_new; extern il2cpp_gchandle_get_target_t il2cpp_gchandle_get_target; extern il2cpp_gchandle_free_t il2cpp_gchandle_free; +extern il2cpp_gc_wbarrier_set_field_t il2cpp_gc_wbarrier_set_field; char* il2cpp_array_addr_with_size(void* arr, int32_t size, uintptr_t idx); diff --git a/src/main.cpp b/src/main.cpp index 03e28ae..7e95011 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -576,7 +576,7 @@ int __stdcall DllMain(HINSTANCE, DWORD reason, LPVOID) module_name.resize(MAX_PATH); module_name.resize(GetModuleFileName(nullptr, module_name.data(), MAX_PATH)); - filesystem::path module_path(module_name); + filesystem::path module_path(local::wide_u8(local::acp_wide(module_name))); // check name if (module_path.filename() != "umamusume.exe") @@ -600,8 +600,8 @@ int __stdcall DllMain(HINSTANCE, DWORD reason, LPVOID) DoStopSvc(); } - auto& uncheater_path = module_path.parent_path().append(module_path.filename().replace_extension().string().append("_Data\\StreamingAssets\\Uncheater"s).data()); - auto& uncheater_path_new = module_path.parent_path().append(module_path.filename().replace_extension().string().append("_Data\\StreamingAssets\\_Uncheater"s).data()); + auto uncheater_path = filesystem::path(module_path.parent_path().append(module_path.filename().replace_extension().string().append("_Data\\StreamingAssets\\Uncheater"s).data())); + auto uncheater_path_new = filesystem::path(module_path.parent_path().append(module_path.filename().replace_extension().string().append("_Data\\StreamingAssets\\_Uncheater"s).data())); if (filesystem::exists(uncheater_path_new)) { @@ -625,7 +625,7 @@ int __stdcall DllMain(HINSTANCE, DWORD reason, LPVOID) { cout << "Uncheater rename error: " << e.what() << endl; - auto& xnina_path = module_path.parent_path().append(module_path.filename().replace_extension().string().append("_Data\\StreamingAssets\\Uncheater\\xnina_x64.xem"s).data()); + auto xnina_path = filesystem::path(module_path.parent_path().append(module_path.filename().replace_extension().string().append("_Data\\StreamingAssets\\Uncheater\\xnina_x64.xem"s).data())); if (filesystem::exists(xnina_path)) { try