From 3976f34dc76b029a125a2831efc2738c8fb9969c Mon Sep 17 00:00:00 2001 From: Ji O Date: Sat, 11 May 2024 17:31:17 +0900 Subject: [PATCH] Various enhancements --- .gitmodules | 4 + deps/msgpack11 | 1 + deps/msgpack11.lua | 30 + premake5.lua | 6 +- src/SaveIcon.cpp | 153 + src/SaveIcon.h | 36 + src/VERSIONINFO.rc | 81 +- src/config.hpp | 8 + src/hook.cpp | 3447 +++++++++++++---- src/hook.h | 8 + src/il2cpp/il2cpp-api-functions.hpp | 3 + src/il2cpp/il2cpp_symbols.hpp | 40 + src/local/local.hpp | 4 + src/main.cpp | 38 +- src/masterdb/masterdb.hpp | 96 + src/msgpack/msgpack_data.hpp | 259 ++ src/msgpack/msgpack_modify.hpp | 701 ++++ .../DesktopNotificationManagerCompat.cpp | 544 +++ .../DesktopNotificationManagerCompat.h | 126 + src/settings_text.hpp | 130 + src/stdinclude.hpp | 7 + 21 files changed, 5010 insertions(+), 712 deletions(-) create mode 160000 deps/msgpack11 create mode 100644 deps/msgpack11.lua create mode 100644 src/SaveIcon.cpp create mode 100644 src/SaveIcon.h create mode 100644 src/hook.h create mode 100644 src/masterdb/masterdb.hpp create mode 100644 src/msgpack/msgpack_data.hpp create mode 100644 src/msgpack/msgpack_modify.hpp create mode 100644 src/notification/DesktopNotificationManagerCompat.cpp create mode 100644 src/notification/DesktopNotificationManagerCompat.h diff --git a/.gitmodules b/.gitmodules index c4f3d6d..1e2522a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,7 @@ [submodule "deps/SQLiteCpp"] path = deps/SQLiteCpp url = https://github.com/SRombauts/SQLiteCpp.git +[submodule "deps/msgpack11"] + path = deps/msgpack11 + url = https://github.com/ar90n/msgpack11.git + diff --git a/deps/msgpack11 b/deps/msgpack11 new file mode 160000 index 0000000..aa0cc8a --- /dev/null +++ b/deps/msgpack11 @@ -0,0 +1 @@ +Subproject commit aa0cc8a00ddb7752b9455b25e47db9b0fab7fd60 diff --git a/deps/msgpack11.lua b/deps/msgpack11.lua new file mode 100644 index 0000000..a86accb --- /dev/null +++ b/deps/msgpack11.lua @@ -0,0 +1,30 @@ +msgpack11 = { + source = path.join(dependencies.basePath, "msgpack11"), +} + +function msgpack11.import() + links { "msgpack11" } + msgpack11.includes() +end + +function msgpack11.includes() + includedirs { + msgpack11.source + } +end + +function msgpack11.project() + project "msgpack11" + language "C++" + + msgpack11.includes() + + files { + path.join(msgpack11.source, "msgpack11.cpp") + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, msgpack11) diff --git a/premake5.lua b/premake5.lua index 5e6dd65..f842c2d 100644 --- a/premake5.lua +++ b/premake5.lua @@ -31,6 +31,7 @@ end include "deps/minhook.lua" include "deps/rapidjson.lua" include "deps/SQLiteCpp.lua" +include "deps/msgpack11.lua" workspace "umamusume-localify" location "./build" @@ -92,6 +93,7 @@ workspace "umamusume-localify" "Shlwapi", "WinHttp", "ntdll", + "runtimeobject", "./deps/discord_game_sdk/discord_game_sdk.dll.lib" } @@ -101,8 +103,8 @@ workspace "umamusume-localify" } nuget { - "Microsoft.Web.WebView2:1.0.2151.40", - "Microsoft.Windows.ImplementationLibrary:1.0.231028.1" + "Microsoft.Web.WebView2:1.0.2420.47", + "Microsoft.Windows.ImplementationLibrary:1.0.240122.1" } dependencies.imports() diff --git a/src/SaveIcon.cpp b/src/SaveIcon.cpp new file mode 100644 index 0000000..800dbdb --- /dev/null +++ b/src/SaveIcon.cpp @@ -0,0 +1,153 @@ +#include "SaveIcon.h" + +BOOL SaveIconToFile(HICON hIcon, LPWSTR szFileName, int nBit) +{ + BOOL ret = FALSE; + PVOID MonoBits; + PVOID ColorBits; + DWORD dwWrite; + HANDLE hFile; + ICONINFO IconInfo; + TIconRes tIR; + TIconHeader tIH; + DWORD MonoInfoSize, ColorInfoSize, MonoBitsSize, ColorBitsSize; + BITMAPINFO* MonoInfo; + BITMAPINFO* ColorInfo; + + switch (nBit) + { + case 0: case 1: case 4: case 8: case 16: case 24: case 32: + break; + default: + return FALSE; + } + if (!hIcon || !szFileName) + { + return FALSE; + } + + GetIconInfo(hIcon, &IconInfo); + + if (IconInfo.fIcon) + { + if (INVALID_HANDLE_VALUE != + (hFile = CreateFileW(szFileName, GENERIC_WRITE, + FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0)) + ) + { + ZeroMemory(&tIH, sizeof(TIconHeader)); + ZeroMemory(&tIR, sizeof(TIconRes)); + GetDIBSizes(IconInfo.hbmMask, MonoInfoSize, MonoBitsSize, 1); + GetDIBSizes(IconInfo.hbmColor, ColorInfoSize, ColorBitsSize, nBit); + MonoInfo = reinterpret_cast(malloc(MonoInfoSize)); + ColorInfo = reinterpret_cast(malloc(ColorInfoSize)); + MonoBits = malloc(MonoBitsSize); + ColorBits = malloc(ColorBitsSize); + GetDIB(IconInfo.hbmMask, MonoInfo, MonoBits, 1); + GetDIB(IconInfo.hbmColor, ColorInfo, ColorBits, nBit); + tIH.wType = static_cast(IconInfo.fIcon); + tIH.Count = 1; + ret = WriteFile(hFile, &tIH, sizeof(TIconHeader), &dwWrite, NULL); + + if (!ColorInfo) + { + return FALSE; + } + + tIR.Width = static_cast(ColorInfo->bmiHeader.biWidth); + tIR.Height = static_cast(ColorInfo->bmiHeader.biHeight); + tIR.Colors = ColorInfo->bmiHeader.biPlanes * ColorInfo->bmiHeader.biBitCount; + tIR.DIBSize = ColorInfoSize + ColorBitsSize + MonoBitsSize; + tIR.DIBOffset = sizeof(TIconHeader) + sizeof(TIconRes); + ret &= WriteFile(hFile, &tIR, sizeof(TIconRes), &dwWrite, NULL); + ColorInfo->bmiHeader.biHeight *= 2; + ret &= WriteFile(hFile, ColorInfo, ColorInfoSize, &dwWrite, NULL); + ret &= WriteFile(hFile, ColorBits, ColorBitsSize, &dwWrite, NULL); + ret &= WriteFile(hFile, MonoBits, MonoBitsSize, &dwWrite, NULL); + CloseHandle(hFile); + free(ColorInfo); + free(MonoInfo); + free(ColorBits); + free(MonoBits); + } + + } + + DeleteObject(IconInfo.hbmColor); + DeleteObject(IconInfo.hbmMask); + + return ret; +} + +VOID InitBmpHeader(HBITMAP hBitmap, BITMAPINFOHEADER& BI, int nBit) +{ + INT Bytes; + DIBSECTION DS; + DS.dsBmih.biSize = 0; + Bytes = GetObject(hBitmap, sizeof(DIBSECTION), &DS); + if (Bytes >= sizeof(DS.dsBm) + sizeof(DS.dsBmih) && + DS.dsBmih.biSize >= sizeof(DS.dsBmih)) + { + CopyMemory(&BI, &DS.dsBmih, sizeof(BITMAPINFOHEADER)); + } + else + { + ZeroMemory(&BI, sizeof(BI)); + BI.biSize = sizeof(BI); + BI.biWidth = DS.dsBm.bmWidth; + BI.biHeight = DS.dsBm.bmHeight; + BI.biBitCount = DS.dsBm.bmPlanes * DS.dsBm.bmBitsPixel; + } + if (nBit) + { + BI.biBitCount = static_cast(nBit); + } + if (BI.biBitCount <= 8) + { + BI.biClrUsed = 1 << BI.biBitCount; + } + + BI.biPlanes = 1; + + if (BI.biClrImportant > BI.biClrUsed) + { + BI.biClrImportant = BI.biClrUsed; + } + if (BI.biSizeImage == 0) + { + BI.biSizeImage = + ((BI.biWidth * BI.biBitCount + 31) / 32) * 4 * BI.biHeight; + } +} + +VOID GetDIBSizes(HBITMAP Bitmap, + DWORD& InfoSize, + DWORD& ImageSize, + int nBit) +{ + BITMAPINFOHEADER BI; + InitBmpHeader(Bitmap, BI, nBit); + InfoSize = sizeof(BITMAPINFOHEADER); + if (BI.biBitCount > 8) + { + if (BI.biCompression & BI_BITFIELDS) + { + InfoSize = InfoSize + 12; + } + } + else + { + InfoSize += sizeof(RGBQUAD) * + (BI.biClrUsed != 0 ? BI.biClrUsed : (1 << BI.biBitCount)); + } + ImageSize = BI.biSizeImage; +} + +VOID GetDIB(HBITMAP Bitmap, BITMAPINFO* BmpInfo, PVOID Bits, INT nBit) +{ + HDC DC = CreateCompatibleDC(NULL); + InitBmpHeader(Bitmap, BmpInfo->bmiHeader, nBit); + GetDIBits(DC, Bitmap, 0, + BmpInfo->bmiHeader.biHeight, Bits, BmpInfo, DIB_RGB_COLORS); + DeleteDC(DC); +} diff --git a/src/SaveIcon.h b/src/SaveIcon.h new file mode 100644 index 0000000..0110b52 --- /dev/null +++ b/src/SaveIcon.h @@ -0,0 +1,36 @@ +#ifndef HS_HEADER_DEF_ICONMEMFUNC_H +#define HS_HEADER_DEF_ICONMEMFUNC_H + +#if _MSC_VER >= 1000 +#pragma once +#endif +////////////////////////////////////////////////////////////////////////// +#include + +struct TIconHeader +{ +WORD Reserved; +WORD wType; +WORD Count; +}; + +struct TIconRes +{ +BYTE Width; +BYTE Height; +WORD Colors; +WORD Reserved1; +WORD Reserved2; +DWORD DIBSize; +DWORD DIBOffset; +}; + +VOID InitBmpHeader(HBITMAP hBitmap, BITMAPINFOHEADER& BI, int nBit); + +VOID GetDIBSizes(HBITMAP Bitmap, DWORD &InfoSize, DWORD &ImageSize, int nBit); + +VOID GetDIB(HBITMAP Bitmap, BITMAPINFO* BmpInfo, PVOID Bits, INT nBit); + +BOOL SaveIconToFile(HICON hIcon, LPWSTR szFileName, int nBit); + +#endif //HS_HEADER_DEF_ICONMEMFUNC_H \ No newline at end of file diff --git a/src/VERSIONINFO.rc b/src/VERSIONINFO.rc index 7f192b8..8a472c8 100644 --- a/src/VERSIONINFO.rc +++ b/src/VERSIONINFO.rc @@ -1,14 +1,20 @@ // Microsoft Visual C++ generated resource script. // #include "resource.h" +///////////////////////////////////////////////////////////////////////////// +// 한국어(대한민국) resources + +#if !defined(AFX_RESOURCE_DLL) +#pragma code_page(65001) + ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,32,0,0 - PRODUCTVERSION 1,32,0,0 + FILEVERSION 1,33,0,0 + PRODUCTVERSION 1,33,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -21,27 +27,68 @@ VS_VERSION_INFO VERSIONINFO BEGIN BLOCK "StringFileInfo" BEGIN - BLOCK "041204b0" + BLOCK "000004b0" BEGIN - VALUE "LegalCopyright", "Copyright © Ji O Kim\0" - VALUE "FileDescription", "우마무스메 현지화 패치\0" - VALUE "FileVersion", "1.32.0.0\0" - VALUE "InternalName", "umamusume-localify\0" - VALUE "ProductName", "Umamusume Localify\0" - VALUE "ProductVersion", "1.32.0\0" + VALUE "FileDescription", "Localization patch for Umamusume" + VALUE "FileVersion", "1.33.0.0" + VALUE "InternalName", "umamusume-localify" + VALUE "LegalCopyright", "Copyright ⓒ Ji O Kim" + VALUE "ProductName", "Umamusume Localify" + VALUE "ProductVersion", "1.33.0.0" END - BLOCK "000004b0" + BLOCK "041204b0" BEGIN - VALUE "LegalCopyright", "Copyright © Ji O Kim\0" - VALUE "FileDescription", "Localization patch for Umamusume\0" - VALUE "FileVersion", "1.32.0.0\0" - VALUE "InternalName", "umamusume-localify\0" - VALUE "ProductName", "Umamusume Localify\0" - VALUE "ProductVersion", "1.32.0\0" + VALUE "FileDescription", "우마무스메 현지화 패치" + VALUE "FileVersion", "1.33.0.0" + VALUE "InternalName", "umamusume-localify" + VALUE "LegalCopyright", "Copyright ⓒ Ji O Kim" + VALUE "ProductName", "Umamusume Localify" + VALUE "ProductVersion", "1.33.0.0" END END BLOCK "VarFileInfo" BEGIN - VALUE "Translation", 0x0412, 1200, 0x0, 1200 + VALUE "Translation", 0x412, 1200, 0x0, 1200 END END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // 한국어(대한민국) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/config.hpp b/src/config.hpp index bc010bc..1d0d74a 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -9,6 +9,7 @@ using namespace std; namespace config { rapidjson::Document config_document; + rapidjson::Document backup_document; bool read_config() { @@ -24,6 +25,8 @@ namespace config config_document.ParseStream(wrapper); config_stream.close(); + backup_document.CopyFrom(config_document, backup_document.GetAllocator(), true); + return !config_document.HasParseError(); } @@ -38,4 +41,9 @@ namespace config config_stream << buffer.GetString() << endl; config_stream.close(); } + + void rollback_config() + { + config_document.CopyFrom(backup_document, config_document.GetAllocator(), true); + } } diff --git a/src/hook.cpp b/src/hook.cpp index 0bc55e3..77a7e3d 100644 --- a/src/hook.cpp +++ b/src/hook.cpp @@ -1,3 +1,5 @@ +#include "hook.h" + #include #include @@ -7,6 +9,8 @@ #include +#include + #include #include @@ -23,6 +27,9 @@ #include #include +#include +#include + #include #include @@ -49,9 +56,20 @@ #include "openxr/openxr.hpp" +#include "msgpack/msgpack_modify.hpp" +#include "masterdb/masterdb.hpp" + +#include "notification/DesktopNotificationManagerCompat.h" + +#include +#include + using namespace std; using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; +using namespace Windows::Foundation; +using namespace ABI::Windows::Data::Xml::Dom; namespace { @@ -335,6 +353,129 @@ namespace il2cpp_field_set_value(notification, _tweenerField, _tweener); } + unsigned long GetEnumValue(Il2CppObject* runtimeEnum); + Il2CppObject* ParseEnum(Il2CppObject* runtimeType, const string& name); + + void SetNotificationFontSize(int size) + { + if (!notification) + { + return; + } + + if (!uobject_IsNativeObjectAlive(notification)) + { + return; + } + + auto _LabelField = il2cpp_class_get_field_from_name_wrap(notification->klass, "_Label"); + Il2CppObject* _Label; + il2cpp_field_get_value(notification, _LabelField, &_Label); + + il2cpp_class_get_method_from_name_type(_Label->klass, "set_fontSize", 1)->methodPointer(_Label, size); + } + + void SetNotificationFontColor(string color) + { + if (!notification) + { + return; + } + + if (!uobject_IsNativeObjectAlive(notification)) + { + return; + } + + auto _LabelField = il2cpp_class_get_field_from_name_wrap(notification->klass, "_Label"); + Il2CppObject* _Label; + il2cpp_field_get_value(notification, _LabelField, &_Label); + + il2cpp_class_get_method_from_name_type(_Label->klass, "set_FontColor", 1)->methodPointer(_Label, GetEnumValue(ParseEnum(GetRuntimeType("umamusume.dll", "Gallop", "FontColorType"), color.data()))); + } + + void SetNotificationOutlineSize(string size) + { + if (!notification) + { + return; + } + + if (!uobject_IsNativeObjectAlive(notification)) + { + return; + } + + auto _LabelField = il2cpp_class_get_field_from_name_wrap(notification->klass, "_Label"); + Il2CppObject* _Label; + il2cpp_field_get_value(notification, _LabelField, &_Label); + + il2cpp_class_get_method_from_name_type(_Label->klass, "set_OutlineSize", 1)->methodPointer(_Label, GetEnumValue(ParseEnum(GetRuntimeType("umamusume.dll", "Gallop", "OutlineSizeType"), size.data()))); + il2cpp_class_get_method_from_name_type(_Label->klass, "UpdateOutline", 0)->methodPointer(_Label); + } + + void SetNotificationOutlineColor(string color) + { + if (!notification) + { + return; + } + + if (!uobject_IsNativeObjectAlive(notification)) + { + return; + } + + auto _LabelField = il2cpp_class_get_field_from_name_wrap(notification->klass, "_Label"); + Il2CppObject* _Label; + il2cpp_field_get_value(notification, _LabelField, &_Label); + + il2cpp_class_get_method_from_name_type(_Label->klass, "set_OutlineColor", 1)->methodPointer(_Label, GetEnumValue(ParseEnum(GetRuntimeType("umamusume.dll", "Gallop", "OutlineColorType"), color.data()))); + } + + void SetNotificationBackgroundAlpha(float alpha) + { + if (!notification) + { + return; + } + + if (!uobject_IsNativeObjectAlive(notification)) + { + return; + } + + auto gameObject = il2cpp_class_get_method_from_name_type(notification->klass, "get_gameObject", 0)->methodPointer(notification); + auto background = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject", "GetComponentInChildren", 2)(gameObject, GetRuntimeType("umamusume.dll", "Gallop", "ImageCommon"), true); + il2cpp_class_get_method_from_name_type(background->klass, "SetAlpha", 1)->methodPointer(background, alpha); + } + + void SetNotificationPosition(float x, float y) + { + if (!notification) + { + return; + } + + if (!uobject_IsNativeObjectAlive(notification)) + { + return; + } + + auto canvasGroupField = il2cpp_class_get_field_from_name_wrap(notification->klass, "canvasGroup"); + Il2CppObject* canvasGroup; + il2cpp_field_get_value(notification, canvasGroupField, &canvasGroup); + + auto canvasGroupTransform = il2cpp_class_get_method_from_name_type(canvasGroup->klass, "get_transform", 0)->methodPointer(canvasGroup); + + auto position = il2cpp_class_get_method_from_name_type(canvasGroupTransform->klass, "get_position", 0)->methodPointer(canvasGroupTransform); + + position.x = x; + position.y = y; + + il2cpp_class_get_method_from_name_type(canvasGroupTransform->klass, "set_position", 1)->methodPointer(canvasGroupTransform, position); + } + void ShowCaptionByNotification(Il2CppObject* audioManager, Il2CppObject* elem) { if (!audioManager || !elem) @@ -391,9 +532,30 @@ namespace if (wstring(cueSheet->start_char).find(L"_training_") != string::npos && (cueId < 29 || cueId == 39)) { - if (voiceId < 93000 && !(cueId == 8 || cueId == 9 || cueId == 12 || cueId == 13)) + if (!(voiceId >= 2030 && voiceId <= 2037) && voiceId < 93000 && !(cueId == 8 || cueId == 9 || cueId == 12 || cueId == 13)) { - return; + if (voiceId == 20025) + { + auto sceneManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "SceneManager")); + + if (sceneManager) + { + auto viewId = il2cpp_class_get_method_from_name_type(sceneManager->klass, "GetCurrentViewId", 0)->methodPointer(sceneManager); + + if (viewId != 5901) + { + return; + } + } + else + { + return; + } + } + else + { + return; + } } } @@ -662,8 +824,8 @@ namespace } } - void* CirMana_SetFileNew_orig = nullptr; - void CirMana_SetFileNew_hook(int player_id, void* binder, const char* path) + void* CriMana_SetFileNew_orig = nullptr; + void CriMana_SetFileNew_hook(int player_id, void* binder, const char* path) { string pathString = path; replaceAll(pathString, "\\", "/"); @@ -679,15 +841,15 @@ namespace if (g_replace_assets.find(fileName) != g_replace_assets.end()) { auto& replaceAsset = g_replace_assets.at(fileName); - reinterpret_cast(CirMana_SetFileNew_orig)(player_id, binder, replaceAsset.path.data()); + reinterpret_cast(CriMana_SetFileNew_orig)(player_id, binder, replaceAsset.path.data()); return; } - reinterpret_cast(CirMana_SetFileNew_orig)(player_id, binder, path); + reinterpret_cast(CriMana_SetFileNew_orig)(player_id, binder, path); } - void* CirMana_SetFileAppend_orig = nullptr; - bool CirMana_SetFileAppend_hook(int player_id, void* binder, const char* path, bool repeat) + void* CriMana_SetFileAppend_orig = nullptr; + bool CriMana_SetFileAppend_hook(int player_id, void* binder, const char* path, bool repeat) { string pathString = path; replaceAll(pathString, "\\", "/"); @@ -703,10 +865,10 @@ namespace if (g_replace_assets.find(fileName) != g_replace_assets.end()) { auto& replaceAsset = g_replace_assets.at(fileName); - return reinterpret_cast(CirMana_SetFileAppend_orig)(player_id, binder, replaceAsset.path.data(), repeat); + return reinterpret_cast(CriMana_SetFileAppend_orig)(player_id, binder, replaceAsset.path.data(), repeat); } - return reinterpret_cast(CirMana_SetFileAppend_orig)(player_id, binder, path, repeat); + return reinterpret_cast(CriMana_SetFileAppend_orig)(player_id, binder, path, repeat); } void* delete_cookies_orig = nullptr; @@ -980,25 +1142,35 @@ namespace if (!g_replace_assetbundle_file_paths.empty()) { - auto CirMana_SetFileNew_addr = GetProcAddress(criware, "CRIWARE8778888A"); + auto CriMana_SetFileNew_addr = GetProcAddress(criware, "CRIWARE8778888A"); - if (!CirMana_SetFileNew_addr) + if (!CriMana_SetFileNew_addr) { - CirMana_SetFileNew_addr = GetProcAddress(criware, "CRIWARE310ABCEC"); + CriMana_SetFileNew_addr = GetProcAddress(criware, "CRIWARE310ABCEC"); } - MH_CreateHook(CirMana_SetFileNew_addr, CirMana_SetFileNew_hook, &CirMana_SetFileNew_orig); - MH_EnableHook(CirMana_SetFileNew_addr); + if (!CriMana_SetFileNew_addr) + { + CriMana_SetFileNew_addr = GetProcAddress(criware, "CRIWARE6A5D4549"); + } + + MH_CreateHook(CriMana_SetFileNew_addr, CriMana_SetFileNew_hook, &CriMana_SetFileNew_orig); + MH_EnableHook(CriMana_SetFileNew_addr); + + auto CriMana_SetFileAppend_addr = GetProcAddress(criware, "CRIWAREE7861E0D"); - auto CirMana_SetFileAppend_addr = GetProcAddress(criware, "CRIWAREE7861E0D"); + if (!CriMana_SetFileAppend_addr) + { + CriMana_SetFileAppend_addr = GetProcAddress(criware, "CRIWARE925FC233"); + } - if (!CirMana_SetFileAppend_addr) + if (!CriMana_SetFileAppend_addr) { - CirMana_SetFileAppend_addr = GetProcAddress(criware, "CRIWARE925FC233"); + CriMana_SetFileAppend_addr = GetProcAddress(criware, "CRIWARE46A04F06"); } - MH_CreateHook(CirMana_SetFileAppend_addr, CirMana_SetFileAppend_hook, &CirMana_SetFileAppend_orig); - MH_EnableHook(CirMana_SetFileAppend_addr); + MH_CreateHook(CriMana_SetFileAppend_addr, CriMana_SetFileAppend_hook, &CriMana_SetFileAppend_orig); + MH_EnableHook(CriMana_SetFileAppend_addr); } return criware; @@ -1648,8 +1820,6 @@ namespace unordered_map text_queries; unordered_map replacement_queries_can_next; - SQLite::Database* replacementMDB; - void* query_setup_orig = nullptr; void query_setup_hook(Il2CppObject* _this, void* conn, Il2CppString* sql) { @@ -1667,9 +1837,9 @@ namespace il2cpp_field_get_value(_this, stmtField, &stmtPtr); try { - if (replacementMDB) + if (MasterDB::replacementMasterDB) { - text_queries.emplace(stmtPtr, new SQLite::Statement(*replacementMDB, local::wide_u8(ssql))); + text_queries.emplace(stmtPtr, new SQLite::Statement(*MasterDB::replacementMasterDB, local::wide_u8(ssql))); } else { @@ -2305,12 +2475,12 @@ namespace { if (width < height) { - float scale = min(g_freeform_ui_scale_portrait, max(1, height * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, height * ratio_vertical) * g_freeform_ui_scale_portrait); set_scale_factor(_this, scale); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, width / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, width / ratio_horizontal) * g_freeform_ui_scale_landscape); set_scale_factor(_this, scale); } } @@ -2319,12 +2489,12 @@ namespace // set scale factor to make ui bigger on hi-res screen if (width < height) { - float scale = min(g_ui_scale, max(1, height * ratio_vertical) * g_ui_scale); + float scale = min(g_ui_scale, max(1.0f, height * ratio_vertical) * g_ui_scale); set_scale_factor(_this, scale); } else { - float scale = min(g_ui_scale, max(1, width / ratio_horizontal) * g_ui_scale); + float scale = min(g_ui_scale, max(1.0f, width / ratio_horizontal) * g_ui_scale); set_scale_factor(_this, scale); } } @@ -2461,7 +2631,12 @@ namespace void* UIManager_ChangeResizeUIForPC_orig = nullptr; void UIManager_ChangeResizeUIForPC_hook(Il2CppObject* _this, int width, int height) { - // reinterpret_cast(UIManager_ChangeResizeUIForPC_orig)(_this, width, height); + if (!g_unlock_size && !g_freeform_window) + { + reinterpret_cast(UIManager_ChangeResizeUIForPC_orig)(_this, width, height); + return; + } + Il2CppArraySize_t* scalers; if (Game::CurrentGameRegion == Game::Region::KOR) { @@ -2503,12 +2678,12 @@ namespace { if (width < height) { - float scale = min(g_freeform_ui_scale_portrait, max(1, height * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, height * ratio_vertical) * g_freeform_ui_scale_portrait); il2cpp_class_get_method_from_name_type(scaler->klass, "set_referenceResolution", 1)->methodPointer(scaler, Vector2_t{ static_cast(width / scale), static_cast(height / scale) }); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, width / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, width / ratio_horizontal) * g_freeform_ui_scale_landscape); il2cpp_class_get_method_from_name_type(scaler->klass, "set_referenceResolution", 1)->methodPointer(scaler, Vector2_t{ static_cast(width / scale), static_cast(height / scale) }); } @@ -2518,12 +2693,12 @@ namespace { if (width < height) { - float scale = min(g_freeform_ui_scale_portrait, max(1, height * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, height * ratio_vertical) * g_freeform_ui_scale_portrait); il2cpp_class_get_method_from_name_type(scaler->klass, "set_scaleFactor", 1)->methodPointer(scaler, scale); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, width / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, width / ratio_horizontal) * g_freeform_ui_scale_landscape); il2cpp_class_get_method_from_name_type(scaler->klass, "set_scaleFactor", 1)->methodPointer(scaler, scale); } } @@ -2534,12 +2709,12 @@ namespace { if (width < height) { - float scale = min(g_ui_scale, max(1, height * ratio_vertical) * g_ui_scale); + float scale = min(g_ui_scale, max(1.0f, height * ratio_vertical) * g_ui_scale); il2cpp_class_get_method_from_name_type(scaler->klass, "set_referenceResolution", 1)->methodPointer(scaler, Vector2_t{ static_cast(width / scale), static_cast(height / scale) }); } else { - float scale = min(g_ui_scale, max(1, width / ratio_horizontal) * g_ui_scale); + float scale = min(g_ui_scale, max(1.0f, width / ratio_horizontal) * g_ui_scale); il2cpp_class_get_method_from_name_type(scaler->klass, "set_referenceResolution", 1)->methodPointer(scaler, Vector2_t{ static_cast(width / scale), static_cast(height / scale) }); } } @@ -2548,12 +2723,12 @@ namespace // set scale factor to make ui bigger on hi-res screen if (width < height) { - float scale = min(g_ui_scale, max(1, height * ratio_vertical) * g_ui_scale); + float scale = min(g_ui_scale, max(1.0f, height * ratio_vertical) * g_ui_scale); il2cpp_class_get_method_from_name_type(scaler->klass, "set_scaleFactor", 1)->methodPointer(scaler, scale); } else { - float scale = min(g_ui_scale, max(1, width / ratio_horizontal) * g_ui_scale); + float scale = min(g_ui_scale, max(1.0f, width / ratio_horizontal) * g_ui_scale); il2cpp_class_get_method_from_name_type(scaler->klass, "set_scaleFactor", 1)->methodPointer(scaler, scale); } } @@ -3096,6 +3271,10 @@ namespace } } + + Il2CppObject* GetOptionSlider(const char* name); + float GetOptionSliderValue(Il2CppObject* slider); + void resizeWindow(HWND hWnd, int updateWidth, int updateHeight) { if (updateWidth < 72 || updateHeight < 72) @@ -3369,15 +3548,14 @@ namespace il2cpp_class_get_method_from_name_type(gameObject->klass, "SetActive", 1)->methodPointer(gameObject, true); - /*if (isPortrait) { - float scale = min(g_freeform_ui_scale_portrait, max(1, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_referenceResolution", 1)->methodPointer(canvasScaler, Vector2_t{ static_cast(contentWidth / scale), static_cast(contentHeight / scale) }); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_referenceResolution", 1)->methodPointer(canvasScaler, Vector2_t{ static_cast(contentWidth / scale), static_cast(contentHeight / scale) }); }*/ @@ -3393,12 +3571,12 @@ namespace { if (isPortrait) { - float scale = min(g_freeform_ui_scale_portrait, max(1, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_referenceResolution", 1)->methodPointer(canvasScaler, Vector2_t{ static_cast(contentWidth / scale), static_cast(contentHeight / scale) }); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_referenceResolution", 1)->methodPointer(canvasScaler, Vector2_t{ static_cast(contentWidth / scale), static_cast(contentHeight / scale) }); } } @@ -3407,12 +3585,12 @@ namespace { if (isPortrait) { - float scale = min(g_freeform_ui_scale_portrait, max(1, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_scaleFactor", 1)->methodPointer(canvasScaler, scale); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_scaleFactor", 1)->methodPointer(canvasScaler, scale); } } @@ -3542,12 +3720,12 @@ namespace { if (contentWidth < contentHeight) { - float scale = min(g_freeform_ui_scale_portrait, max(1, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, contentHeight * ratio_vertical) * g_freeform_ui_scale_portrait); il2cpp_class_get_method_from_name_type(root->klass, "SetScreenReferenceSize", 1)->methodPointer(root, Vector2_t{ ratio_16_9 * static_cast(contentHeight / scale), static_cast(contentHeight / scale) }); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, contentWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); il2cpp_class_get_method_from_name_type(root->klass, "SetScreenReferenceSize", 1)->methodPointer(root, Vector2_t{ ratio_16_9 * static_cast(contentHeight / scale), static_cast(contentHeight / scale) }); } } @@ -4034,6 +4212,13 @@ namespace { if (controller->klass->name == "SingleModeMainViewController"s) { + auto IsStoryActive = il2cpp_class_get_method_from_name_type(controller->klass, "get_IsStoryActive", 0)->methodPointer(controller); + + if (IsStoryActive) + { + return; + } + auto trainingController = il2cpp_class_get_method_from_name_type(controller->klass, "get_TrainingController", 0)->methodPointer(controller); if (il2cpp_class_get_method_from_name_type(trainingController->klass, "get_IsInTraining", 0)->methodPointer(trainingController)) { @@ -4058,13 +4243,20 @@ namespace if (wParam == VK_RETURN) { - auto _onClickEnableField = il2cpp_class_get_field_from_name_wrap(footer->klass, "_onClickEnable"); - bool _onClickEnable = true; - il2cpp_field_set_value(footer, _onClickEnableField, &_onClickEnable); + auto enabledObscured = il2cpp_class_get_method_from_name_type(selectedMenu->klass, "get_IsEnable", 0)->methodPointer(selectedMenu); + auto ObscuredBoolClass = il2cpp_symbols::get_class("Plugins.dll", "CodeStage.AntiCheat.ObscuredTypes", "ObscuredBool"); + auto enabled = il2cpp_class_get_method_from_name_type(ObscuredBoolClass, "InternalDecrypt", 0)->methodPointer(enabledObscured); + + if (enabled) + { + auto _onClickEnableField = il2cpp_class_get_field_from_name_wrap(footer->klass, "_onClickEnable"); + bool _onClickEnable = true; + il2cpp_field_set_value(footer, _onClickEnableField, &_onClickEnable); - il2cpp_class_get_method_from_name_type(footer->klass, "OnClickItem", 2)->methodPointer(footer, selectedItem, selectedMenu); + il2cpp_class_get_method_from_name_type(footer->klass, "OnClickItem", 2)->methodPointer(footer, selectedItem, selectedMenu); + } } - else if ((0 < (wParam - 48) && (wParam - 48) <= 5)) + else if ((0 < (wParam - 48) && (wParam - 48) <= 9)) { if (isNumKeyDown) { @@ -4073,6 +4265,10 @@ namespace int number = wParam - 48; + if (number > count) { + number = count; + } + auto _preSelectedMenuField = il2cpp_class_get_field_from_name_wrap(footer->klass, "_preSelectedMenu"); Il2CppObject* footerItem = arr->vector[number - 1]; @@ -4083,11 +4279,18 @@ namespace if (selectedMenu == trainingMenu) { - auto _onClickEnableField = il2cpp_class_get_field_from_name_wrap(footer->klass, "_onClickEnable"); - bool _onClickEnable = true; - il2cpp_field_set_value(footer, _onClickEnableField, &_onClickEnable); + auto enabledObscured = il2cpp_class_get_method_from_name_type(selectedMenu->klass, "get_IsEnable", 0)->methodPointer(selectedMenu); + auto ObscuredBoolClass = il2cpp_symbols::get_class("Plugins.dll", "CodeStage.AntiCheat.ObscuredTypes", "ObscuredBool"); + auto enabled = il2cpp_class_get_method_from_name_type(ObscuredBoolClass, "InternalDecrypt", 0)->methodPointer(enabledObscured); - il2cpp_class_get_method_from_name_type(footer->klass, "OnClickItem", 2)->methodPointer(footer, selectedItem, selectedMenu); + if (enabled) + { + auto _onClickEnableField = il2cpp_class_get_field_from_name_wrap(footer->klass, "_onClickEnable"); + bool _onClickEnable = true; + il2cpp_field_set_value(footer, _onClickEnableField, &_onClickEnable); + + il2cpp_class_get_method_from_name_type(footer->klass, "OnClickItem", 2)->methodPointer(footer, selectedItem, selectedMenu); + } return; } @@ -4167,7 +4370,7 @@ namespace if (uMsg == WM_KEYDOWN) { - if (wParam == VK_LEFT || wParam == VK_RIGHT || wParam == VK_RETURN || (0 < (wParam - 48) && (wParam - 48) <= 5)) + if (wParam == VK_LEFT || wParam == VK_RIGHT || wParam == VK_RETURN || (0 < (wParam - 48) && (wParam - 48) <= 9)) { StepTrainingItem(wParam); return TRUE; @@ -4397,6 +4600,26 @@ namespace } } + if ((uMsg == WM_EXITSIZEMOVE || uMsg == WM_SIZE) && g_character_system_text_caption) + { + auto callback = CreateDelegateWithClassStatic(il2cpp_symbols::get_class("DOTween.dll", "DG.Tweening", "TweenCallback"), *([](void*) + { + auto sliderX = GetOptionSlider("character_system_text_caption_position_x"); + auto sliderY = GetOptionSlider("character_system_text_caption_position_y"); + + if (sliderX && sliderY) + { + SetNotificationPosition(GetOptionSliderValue(sliderX) / 10, GetOptionSliderValue(sliderY) / 10); + } + else + { + SetNotificationPosition(g_character_system_text_caption_position_x, g_character_system_text_caption_position_y); + } + })); + + il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.01, callback, true); + } + if (uMsg == WM_SIZE && g_freeform_window) { auto StandaloneWindowResize = il2cpp_symbols::get_class("umamusume.dll", "Gallop", "StandaloneWindowResize"); @@ -4601,7 +4824,6 @@ namespace il2cpp_class_get_method_from_name_type(tapEffectController->klass, "Enable", 0)->methodPointer(tapEffectController); - rect->right += borderWidth; rect->bottom += borderHeight; @@ -4623,7 +4845,6 @@ namespace { UIManager_ChangeResizeUIForPC_hook(uiManager, isVirt ? min(last_display_width, last_display_height) : max(last_display_width, last_display_height), isVirt ? max(last_display_width, last_display_height) : min(last_display_width, last_display_height)); - } else { @@ -5918,6 +6139,65 @@ namespace return il2cpp_resolve_icall_type("UnityEngine.GameObject::Internal_AddComponentWithType()")(gameObject, componentType); } + 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* GetTextCommon(const char* name) + { + auto gameObject = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.GameObject::Find()"))(il2cpp_string_new(name)); + + if (gameObject) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(gameObject->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(gameObject, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + return array->vector[0]; + } + return nullptr; + } + + void SetTextCommonText(Il2CppObject* textCommon, const char* text) + { + text_set_text(textCommon, il2cpp_string_new(text)); + + auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); + il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + } + + void SetTextCommonTextWithCustomTag(Il2CppObject* textCommon, const char* text) + { + il2cpp_class_get_method_from_name_type(textCommon->klass, "SetTextWithCustomTag", 3)->methodPointer(textCommon, il2cpp_string_new(text), 1, 0); + + auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); + il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + } + + void SetTextCommonFontColor(Il2CppObject* textCommon, const char* color) + { + il2cpp_class_get_method_from_name_type(textCommon->klass, "set_FontColor", 1)->methodPointer(textCommon, GetEnumValue(ParseEnum(GetRuntimeType("umamusume.dll", "Gallop", "FontColorType"), color))); + } + + void SetTextCommonOutlineSize(Il2CppObject* textCommon, const char* size) + { + il2cpp_class_get_method_from_name_type(textCommon->klass, "set_OutlineSize", 1)->methodPointer(textCommon, GetEnumValue(ParseEnum(GetRuntimeType("umamusume.dll", "Gallop", "OutlineSizeType"), size))); + il2cpp_class_get_method_from_name_type(textCommon->klass, "UpdateOutline", 0)->methodPointer(textCommon); + } + + void SetTextCommonOutlineColor(Il2CppObject* textCommon, const char* color) + { + il2cpp_class_get_method_from_name_type(textCommon->klass, "set_OutlineColor", 1)->methodPointer(textCommon, GetEnumValue(ParseEnum(GetRuntimeType("umamusume.dll", "Gallop", "OutlineColorType"), color))); + il2cpp_class_get_method_from_name_type(textCommon->klass, "RebuildOutline", 0)->methodPointer(textCommon); + } + Il2CppObject* GetOptionItemTitle(const char* title) { auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitemtitle"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); @@ -5930,10 +6210,7 @@ namespace 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); + SetTextCommonText(textCommon, title); return optionItemTitle; } @@ -5952,11 +6229,28 @@ namespace auto textCommon = array->vector[0]; - text_set_text(textCommon, il2cpp_string_new(title)); text_set_verticalOverflow(textCommon, 1); + SetTextCommonText(textCommon, title); - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + return optionItemOnOff; + } + + Il2CppObject* GetOptionItemOnOffQualityRich(const char* name, const char* title) + { + auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptioniteminfo_qualityrich"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto optionItemOnOff = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + uobject_set_name(optionItemOnOff, il2cpp_string_new(name)); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(optionItemOnOff->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(optionItemOnOff, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + auto textCommon = array->vector[0]; + + text_set_verticalOverflow(textCommon, 1); + SetTextCommonText(textCommon, title); return optionItemOnOff; } @@ -6009,10 +6303,7 @@ namespace auto textCommon = array1->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); + SetTextCommonText(textCommon, title); auto array2 = getComponents(optionItemButton, reinterpret_cast(GetRuntimeType( "umamusume.dll", "Gallop", "ButtonCommon")), true, true, false, false, nullptr); @@ -6053,10 +6344,7 @@ namespace auto textCommon = array->vector[0]; - text_set_text(textCommon, il2cpp_string_new(text)); - - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + SetTextCommonText(textCommon, text); return optionItemAttention; } @@ -6073,15 +6361,28 @@ namespace auto textCommon = array->vector[0]; - text_set_text(textCommon, il2cpp_string_new(text)); + SetTextCommonTextWithCustomTag(textCommon, text); - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + auto contentSizeFitter = AddComponent(optionItemInfo, GetRuntimeType("umamusume.dll", "Gallop", "LayoutGroupContentSizeFitter")); - return optionItemInfo; - } + auto verticalLayoutGroup = AddComponent(optionItemInfo, 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); - Il2CppObject* GetOptionItemSimple(const char* title) + 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, 64); + il2cpp_class_get_method_from_name_type(padding->klass, "set_right", 1)->methodPointer(padding, 64); + + auto _layoutField = il2cpp_class_get_field_from_name_wrap(contentSizeFitter->klass, "_layout"); + il2cpp_field_set_value(contentSizeFitter, _layoutField, verticalLayoutGroup); + + il2cpp_class_get_method_from_name_type(contentSizeFitter->klass, "SetSize", 0)->methodPointer(contentSizeFitter); + + return optionItemInfo; + } + + Il2CppObject* GetOptionItemSimple(const char* title) { auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitemsimple"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); @@ -6093,88 +6394,194 @@ namespace auto textCommon = array->vector[0]; - text_set_text(textCommon, il2cpp_string_new(title)); + SetTextCommonText(textCommon, title); - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + return optionItemSimple; + } + + Il2CppObject* GetOptionItemSimpleWithButton(const char* name, const char* title, const char* text) + { + auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitemsimple"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto optionItemSimple = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + + uobject_set_name(optionItemSimple, il2cpp_string_new((name + "_simple"s).data())); + + auto rectTransform = GetRectTransform(optionItemSimple); + + il2cpp_class_get_method_from_name_type(rectTransform->klass, "set_anchoredPosition", 1)->methodPointer(rectTransform, Vector2_t{ 71.583984375, -18 }); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(optionItemSimple->klass, "GetComponentsInternal", 6)->methodPointer; + + auto buttonObject = resources_load_hook(il2cpp_string_new("ui/parts/base/buttons00"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto buttons00 = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(buttonObject); + + uobject_set_name(buttons00, il2cpp_string_new(name)); + + auto array2 = getComponents(buttons00, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ButtonCommon")), true, true, false, false, nullptr); + + auto buttonCommon = array2->vector[0]; + + il2cpp_class_get_method_from_name_type(buttonCommon->klass, "SetInteractable", 1)->methodPointer(buttonCommon, true); + + auto buttonRectTransform = GetRectTransform(buttons00); + + il2cpp_class_get_method_from_name_type(buttonRectTransform->klass, "set_sizeDelta", 1)->methodPointer(buttonRectTransform, Vector2_t{ 167, 67 }); + + il2cpp_class_get_method_from_name_type(buttonRectTransform->klass, "set_anchoredPosition", 1)->methodPointer(buttonRectTransform, Vector2_t{ 382.5, 0 }); + + AddToLayout(rectTransform, vector{ buttons00 }); + + auto array = getComponents(optionItemSimple, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + SetTextCommonText(array->vector[0], text); + SetTextCommonText(array->vector[1], title); return optionItemSimple; } - Il2CppObject* GetOptionItem3ToggleVertical(const char* title) + Il2CppObject* GetOptionItemSimpleWithButtonTextCommon(const char* name) + { + auto gameObject = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.GameObject::Find()"))(il2cpp_string_new((name + "_simple"s).data())); + + if (gameObject) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(gameObject->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(gameObject, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + return array->vector[1]; + } + return nullptr; + } + + Il2CppObject* GetToggleCommon(const char* name) + { + auto toggleObject = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.GameObject::Find()"))(il2cpp_string_new(name)); + + if (toggleObject) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(toggleObject->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(toggleObject, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ToggleCommon")), true, true, false, false, nullptr); + + auto toggleCommon = array->vector[0]; + + return toggleCommon; + } + return nullptr; + } + + Il2CppObject* GetToggleGroupCommon(Il2CppObject* toggleGroupObject) + { + if (toggleGroupObject) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(toggleGroupObject->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(toggleGroupObject, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ToggleGroupCommon")), true, true, false, false, nullptr); + + auto toggleGroupCommon = array->vector[0]; + + return toggleGroupCommon; + } + return nullptr; + } + + Il2CppObject* GetToggleGroupCommon(const char* name) + { + auto toggleGroupCommon = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.GameObject::Find()"))(il2cpp_string_new(name)); + + if (toggleGroupCommon) + { + return GetToggleGroupCommon(toggleGroupCommon); + } + return nullptr; + } + + int GetToggleGroupCommonValue(const char* name) + { + auto gameObject = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.GameObject::Find()"))(il2cpp_string_new(name)); + + if (gameObject) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(gameObject->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(gameObject, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ToggleGroupCommon")), true, true, false, false, nullptr); + + auto toggleGroupCommon = array->vector[0]; + + return il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "GetOnIndex", 0)->methodPointer(toggleGroupCommon); + } + return -1; + } + + Il2CppObject* GetOptionItem3ToggleVertical(const char* name, const char* title, const char* oprion1, const char* oprion2, const char* oprion3, int selectedIndex) { auto object = resources_load_hook(il2cpp_string_new("ui/parts/outgame/option/partsoptionitem3togglevertical"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); auto optionItem3ToggleVertical = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingle", 1)(object); + uobject_set_name(optionItem3ToggleVertical, il2cpp_string_new(name)); + 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++) - { - auto textCommon = array->vector[i]; - - if (textCommon) - { - text_set_text(textCommon, il2cpp_string_new(title)); + SetTextCommonText(array->vector[0], title); + SetTextCommonText(array->vector[1], oprion1); + SetTextCommonText(array->vector[2], oprion2); + SetTextCommonText(array->vector[3], oprion3); - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); - } - } + auto toggleGroupCommon = GetToggleGroupCommon(optionItem3ToggleVertical); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "SetToggleOnFromNumber", 1)->methodPointer(toggleGroupCommon, selectedIndex); return optionItem3ToggleVertical; } - Il2CppObject* GetOptionItem3Toggle(const char* title) + Il2CppObject* GetOptionItem3Toggle(const char* name, const char* title, const char* oprion1, const char* oprion2, const char* oprion3, int selectedIndex) { 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); + uobject_set_name(optionItem3Toggle, il2cpp_string_new(name)); + 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 textCommon = array->vector[i]; - - if (textCommon) - { - text_set_text(textCommon, il2cpp_string_new(title)); + SetTextCommonText(array->vector[0], title); + SetTextCommonText(array->vector[1], oprion1); + SetTextCommonText(array->vector[2], oprion2); + SetTextCommonText(array->vector[3], oprion3); - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); - } - } + auto toggleGroupCommon = GetToggleGroupCommon(optionItem3Toggle); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "SetToggleOnFromNumber", 1)->methodPointer(toggleGroupCommon, selectedIndex); return optionItem3Toggle; } - Il2CppObject* GetOptionItem2Toggle(const char* title) + Il2CppObject* GetOptionItem2Toggle(const char* name, const char* title, const char* oprion1, const char* oprion2, int selectedIndex) { 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); + uobject_set_name(optionItem2Toggle, il2cpp_string_new(name)); + 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)); + SetTextCommonText(array->vector[0], title); + SetTextCommonText(array->vector[1], oprion1); + SetTextCommonText(array->vector[2], oprion2); - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); - } - } + auto toggleGroupCommon = GetToggleGroupCommon(optionItem2Toggle); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "SetToggleOnFromNumber", 1)->methodPointer(toggleGroupCommon, selectedIndex); return optionItem2Toggle; } @@ -6190,6 +6597,11 @@ namespace return array->vector[0]; } + float GetOptionSliderValue(Il2CppObject* slider) + { + return il2cpp_class_get_method_from_name_type(slider->klass, "get_value", 0)->methodPointer(slider); + } + float GetOptionSliderValue(const char* name) { auto optionSlider = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.GameObject::Find()"))(il2cpp_string_new(name)); @@ -6202,14 +6614,24 @@ namespace auto sliderCommon = array->vector[0]; - return il2cpp_class_get_method_from_name_type(sliderCommon->klass, "get_value", 0)->methodPointer(sliderCommon); + return GetOptionSliderValue(sliderCommon); } return 0; } - float GetOptionSliderValue(Il2CppObject* slider) + Il2CppObject* GetOptionSlider(const char* name) { - return il2cpp_class_get_method_from_name_type(slider->klass, "get_value", 0)->methodPointer(slider); + auto optionSlider = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.GameObject::Find()"))(il2cpp_string_new(name)); + + if (optionSlider) + { + 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", "SliderCommon")), true, true, false, false, nullptr); + + return array->vector[0]; + } + return nullptr; } Il2CppObject* GetOptionSlider(const char* name, const char* title, float value = 0, float min = 0, float max = 10, bool wholeNumbers = true, void (*onChange)(Il2CppObject*) = nullptr) @@ -6224,11 +6646,8 @@ namespace auto textCommon = array->vector[0]; - text_set_text(textCommon, il2cpp_string_new(title)); text_set_verticalOverflow(textCommon, 1); - - auto textIdStrField = il2cpp_class_get_field_from_name_wrap(textCommon->klass, "m_textid_str"); - il2cpp_field_set_value(textCommon, textIdStrField, nullptr); + SetTextCommonText(textCommon, title); auto optionSoundVolumeSliderArray = getComponents(optionSlider, reinterpret_cast(GetRuntimeType( "umamusume.dll", "Gallop", "OptionSoundVolumeSlider")), true, true, false, false, nullptr); @@ -6438,24 +6857,23 @@ namespace return checkboxWithText; } - Il2CppObject* GetRadioButtonWithText(const char* name) + Il2CppObject* GetRadioButtonWithText(const char* name, const char* title) { 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; - } + uobject_set_name(radioButtonWithText, il2cpp_string_new(name)); - 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); - } + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(radioButtonWithText->klass, "GetComponentsInternal", 6)->methodPointer; + auto array = getComponents(radioButtonWithText, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "TextCommon")), true, true, false, false, nullptr); + + auto textCommon = array->vector[0]; + + SetTextCommonText(textCommon, title); + + return radioButtonWithText; } Il2CppObject* settingsDialog; @@ -6476,60 +6894,45 @@ namespace } } - void OpenSettings() + void AddOrSetString(rapidjson::Document& document, char* name, char* value) + { + char* copy = new char[strlen(value) + 1]; + strcpy(copy, value); + + if (document.HasMember(name)) + { + document[name].SetString(rapidjson::StringRef(copy)); + } + else + { + rapidjson::Value v; + v.SetString(rapidjson::StringRef(copy)); + + document.AddMember(rapidjson::StringRef(name), v, document.GetAllocator()); + } + } + + Il2CppObject* selectOptionDialog; + + function optionSelected; + + void OpenSelectOption(const char* title, vector options, int selectedIndex, function optionSelected) { + ::optionSelected = optionSelected; + auto dialogData = il2cpp_object_new( il2cpp_symbols::get_class("umamusume.dll", "Gallop", "DialogCommon/Data")); il2cpp_runtime_object_init(dialogData); auto onLeft = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) { - il2cpp_class_get_method_from_name_type(settingsDialog->klass, "Close", 0)->methodPointer(settingsDialog); + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); }); auto onRight = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) { - auto& configDocument = config::config_document; - - AddOrSet(configDocument, "characterSystemTextCaption", GetOptionItemOnOffIsOn("character_system_text_caption")); - - AddOrSet(configDocument, "championsLiveShowText", GetOptionItemOnOffIsOn("champions_live_show_text")); - - AddOrSet(configDocument, "allowDeleteCookie", GetOptionItemOnOffIsOn("allow_delete_cookie")); - - AddOrSet(configDocument, "cySpringUpdateMode", static_cast(GetOptionSliderValue("cyspring_update_mode"))); - - AddOrSet(configDocument, "uiAnimationScale", static_cast(roundf(GetOptionSliderValue("ui_animation_scale") * 100)) / 100.0f); - - g_champions_live_show_text = configDocument["championsLiveShowText"].GetBool(); - - g_cyspring_update_mode = configDocument["cySpringUpdateMode"].GetInt(); - - g_ui_animation_scale = configDocument["uiAnimationScale"].GetFloat(); - - config::write_config(); - - 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, "SetSimpleOneButtonMessage", - 4)->methodPointer - )(dialogData, GetTextIdByName("AccoutDataLink0061"), localize_get_hook(GetTextIdByName("Outgame0309")), nullptr, GetTextIdByName("Common0007")); - - auto onDestroy = CreateDelegateStatic(*[]() - { - il2cpp_class_get_method_from_name_type(settingsDialog->klass, "Close", 0)->methodPointer(settingsDialog); - settingsDialog = nullptr; - }); - - il2cpp_class_get_method_from_name_type(dialogData->klass, "AddDestroyCallback", 1)->methodPointer(dialogData, onDestroy); - il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); + ::optionSelected(GetToggleGroupCommonValue("option_toggle_group_content")); }); dialogData = reinterpret_cast( il2cpp_class_get_method_from_name(dialogData->klass, "SetSimpleTwoButtonMessage", 7)->methodPointer - )(dialogData, il2cpp_string_new(LocalifySettings::GetText("title")), nullptr, onRight, GetTextIdByName("Common0004"), GetTextIdByName("Common0261"), onLeft, 10); + )(dialogData, il2cpp_string_new(title), nullptr, onRight, GetTextIdByName("Common0004"), GetTextIdByName("Common0003"), onLeft, 10); auto DispStackTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "DispStackType"); int DispStackType = 2; @@ -6610,7 +7013,7 @@ namespace Il2CppObject* m_Content; il2cpp_field_get_value(scrollRect, m_ContentField, &m_Content); - il2cpp_class_get_method_from_name_type(m_Content->klass, "set_sizeDelta", 1)->methodPointer(m_Content, Vector2_t{ 56, 0 }); + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_sizeDelta", 1)->methodPointer(m_Content, Vector2_t{ 56, 150.0f * ceilf(options.size() / 2.0f) }); il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMax", 1)->methodPointer(m_Content, Vector2_t{ 1, 1 }); @@ -6622,69 +7025,1059 @@ namespace auto contentGameObject = il2cpp_class_get_method_from_name_type(m_Content->klass, "get_gameObject", 0)->methodPointer(m_Content); - auto verticalLayoutGroup = AddComponent(contentGameObject, 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 gridLayoutGroup = AddComponent(contentGameObject, GetRuntimeType("UnityEngine.UI.dll", "UnityEngine.UI", "GridLayoutGroup")); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_childAlignment", 1)->methodPointer(gridLayoutGroup, 0); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_constraintCount", 1)->methodPointer(gridLayoutGroup, 2); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_cellSize", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 400, 100 }); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_spacing", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 34, 50 }); - 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_top", 1)->methodPointer(padding, -20); - il2cpp_class_get_method_from_name_type(padding->klass, "set_bottom", 1)->methodPointer(padding, 16); + auto padding = il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "get_padding", 0)->methodPointer(gridLayoutGroup); + il2cpp_class_get_method_from_name_type(padding->klass, "set_top", 1)->methodPointer(padding, 26); + il2cpp_class_get_method_from_name_type(padding->klass, "set_left", 1)->methodPointer(padding, 48); - bool characterSystemTextCaption = false; - bool championsLiveShowText = false; - bool allowDeleteCookie = false; - int cySpringUpdateMode = -1; - float uiAnimationScale = 1; + auto toggleGroupCommon = AddComponent(contentGameObject, GetRuntimeType("umamusume.dll", "Gallop", "ToggleGroupCommon")); - if (config::read_config()) + uobject_set_name(contentGameObject, il2cpp_string_new("option_toggle_group_content")); + + vector toggles; + + for (auto& pair : options) { - auto& configDocument = config::config_document; + toggles.emplace_back(GetRadioButtonWithText(("radio_"s + pair).data(), pair.data())); + } - if (configDocument.HasMember("characterSystemTextCaption")) - { - characterSystemTextCaption = configDocument["characterSystemTextCaption"].GetBool(); - } + AddToLayout(m_Content, toggles); - if (configDocument.HasMember("championsLiveShowText")) - { - championsLiveShowText = configDocument["championsLiveShowText"].GetBool(); - } + auto toggleArray = il2cpp_array_new_type(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "ToggleCommon"), toggles.size()); - if (configDocument.HasMember("allowDeleteCookie")) - { - allowDeleteCookie = configDocument["allowDeleteCookie"].GetBool(); - } + for (int i = 0; i < options.size(); i++) + { + auto& pair = options[i]; + il2cpp_array_setref(toggleArray, i, GetToggleCommon(("radio_"s + pair).data())); + } - if (configDocument.HasMember("cySpringUpdateMode")) - { - cySpringUpdateMode = configDocument["cySpringUpdateMode"].GetInt(); - } + il2cpp_class_get_method_from_name_type*)>(toggleGroupCommon->klass, "set_ToggleArray", 1)->methodPointer(toggleGroupCommon, toggleArray); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "SetToggleOnFromNumber", 1)->methodPointer(toggleGroupCommon, selectedIndex); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "Awake", 0)->methodPointer(toggleGroupCommon); - if (configDocument.HasMember("uiAnimationScale")) + auto ContentsObjectField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ContentsObject"); + + il2cpp_field_set_value(dialogData, ContentsObjectField, gameObject); + + selectOptionDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + } + + void OpenSelectFontColorOption(const char* title, vector options, int selectedIndex, function optionSelected) + { + ::optionSelected = optionSelected; + + auto dialogData = il2cpp_object_new( + il2cpp_symbols::get_class("umamusume.dll", "Gallop", "DialogCommon/Data")); + il2cpp_runtime_object_init(dialogData); + + auto onLeft = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) { - uiAnimationScale = configDocument["uiAnimationScale"].GetFloat(); - } - } + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); + }); - AddToLayout(m_Content, + auto onRight = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); + ::optionSelected(GetToggleGroupCommonValue("option_toggle_group_content")); + }); + + dialogData = reinterpret_cast( + il2cpp_class_get_method_from_name(dialogData->klass, "SetSimpleTwoButtonMessage", + 7)->methodPointer + )(dialogData, il2cpp_string_new(title), nullptr, onRight, GetTextIdByName("Common0004"), GetTextIdByName("Common0003"), onLeft, 10); + + auto DispStackTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "DispStackType"); + int DispStackType = 2; + il2cpp_field_set_value(dialogData, DispStackTypeField, &DispStackType); + + auto ObjParentTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ObjParentType"); + int ObjParentType = 1; + il2cpp_field_set_value(dialogData, ObjParentTypeField, &ObjParentType); + + auto AutoCloseField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "AutoClose"); + bool AutoClose = false; + il2cpp_field_set_value(dialogData, AutoCloseField, &AutoClose); + + 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, 0 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchorMax", 1)->methodPointer(rootTransform, Vector2_t{ 1, 1 }); + + 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, 0.5 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchoredPosition", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + auto scrollViewBase = resources_load_hook(il2cpp_string_new("ui/parts/base/scrollviewbase"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + auto _mainCanvasField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_mainCanvas"); + Il2CppObject* _mainCanvas; + il2cpp_field_get_value(uiManager, _mainCanvasField, &_mainCanvas); + + auto transform = il2cpp_class_get_method_from_name_type(_mainCanvas->klass, "get_transform", 0)->methodPointer(_mainCanvas); + + scrollViewBase = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingleWithParent", 3) + (scrollViewBase, transform, false); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(scrollViewBase->klass, "GetComponentsInternal", 6)->methodPointer; + + auto scrollRectArray = getComponents(scrollViewBase, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ScrollRectCommon")), true, true, false, false, nullptr); + + auto scrollRect = scrollRectArray->vector[0]; + + auto m_ViewportField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Viewport"); + Il2CppObject* m_Viewport; + il2cpp_field_get_value(scrollRect, m_ViewportField, &m_Viewport); + + auto scrollRectTransform = il2cpp_class_get_method_from_name_type(m_Viewport->klass, "get_parent", 0)->methodPointer(m_Viewport); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_sizeDelta", 1)->methodPointer(scrollRectTransform, Vector2_t{ -24, -12 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMax", 1)->methodPointer(scrollRectTransform, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMin", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_pivot", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0.5, 0.5 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchoredPosition", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, -6 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "SetParent", 2)->methodPointer(scrollRectTransform, rootTransform, false); + + auto m_ContentField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Content"); + Il2CppObject* m_Content; + il2cpp_field_get_value(scrollRect, m_ContentField, &m_Content); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_sizeDelta", 1)->methodPointer(m_Content, Vector2_t{ 56, 150.0f * ceilf(options.size() / 2.0f) }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMax", 1)->methodPointer(m_Content, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMin", 1)->methodPointer(m_Content, Vector2_t{ 0, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_pivot", 1)->methodPointer(m_Content, Vector2_t{ 0.5, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchoredPosition", 1)->methodPointer(m_Content, Vector2_t{ 0, 0 }); + + auto contentGameObject = il2cpp_class_get_method_from_name_type(m_Content->klass, "get_gameObject", 0)->methodPointer(m_Content); + + auto gridLayoutGroup = AddComponent(contentGameObject, GetRuntimeType("UnityEngine.UI.dll", "UnityEngine.UI", "GridLayoutGroup")); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_childAlignment", 1)->methodPointer(gridLayoutGroup, 0); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_constraintCount", 1)->methodPointer(gridLayoutGroup, 2); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_cellSize", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 400, 100 }); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_spacing", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 34, 50 }); + + auto padding = il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "get_padding", 0)->methodPointer(gridLayoutGroup); + il2cpp_class_get_method_from_name_type(padding->klass, "set_top", 1)->methodPointer(padding, 26); + il2cpp_class_get_method_from_name_type(padding->klass, "set_left", 1)->methodPointer(padding, 48); + + auto toggleGroupCommon = AddComponent(contentGameObject, GetRuntimeType("umamusume.dll", "Gallop", "ToggleGroupCommon")); + + uobject_set_name(contentGameObject, il2cpp_string_new("option_toggle_group_content")); + + vector toggles; + + for (auto& color : options) + { + toggles.emplace_back(GetRadioButtonWithText(("radio_"s + color).data(), color.data())); + SetTextCommonFontColor(GetTextCommon(("radio_"s + color).data()), color.data()); + } + + AddToLayout(m_Content, toggles); + + auto toggleArray = il2cpp_array_new_type(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "ToggleCommon"), toggles.size()); + + for (int i = 0; i < options.size(); i++) + { + auto& color = options[i]; + + il2cpp_array_setref(toggleArray, i, GetToggleCommon(("radio_"s + color).data())); + } + + il2cpp_class_get_method_from_name_type*)>(toggleGroupCommon->klass, "set_ToggleArray", 1)->methodPointer(toggleGroupCommon, toggleArray); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "SetToggleOnFromNumber", 1)->methodPointer(toggleGroupCommon, selectedIndex); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "Awake", 0)->methodPointer(toggleGroupCommon); + + auto ContentsObjectField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ContentsObject"); + + il2cpp_field_set_value(dialogData, ContentsObjectField, gameObject); + + selectOptionDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + } + + void OpenSelectOutlineSizeOption(const char* title, vector options, int selectedIndex, function optionSelected) + { + ::optionSelected = optionSelected; + + auto dialogData = il2cpp_object_new( + il2cpp_symbols::get_class("umamusume.dll", "Gallop", "DialogCommon/Data")); + il2cpp_runtime_object_init(dialogData); + + auto onLeft = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); + }); + + auto onRight = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); + ::optionSelected(GetToggleGroupCommonValue("option_toggle_group_content")); + }); + + dialogData = reinterpret_cast( + il2cpp_class_get_method_from_name(dialogData->klass, "SetSimpleTwoButtonMessage", + 7)->methodPointer + )(dialogData, il2cpp_string_new(title), nullptr, onRight, GetTextIdByName("Common0004"), GetTextIdByName("Common0003"), onLeft, 10); + + auto DispStackTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "DispStackType"); + int DispStackType = 2; + il2cpp_field_set_value(dialogData, DispStackTypeField, &DispStackType); + + auto ObjParentTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ObjParentType"); + int ObjParentType = 1; + il2cpp_field_set_value(dialogData, ObjParentTypeField, &ObjParentType); + + auto AutoCloseField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "AutoClose"); + bool AutoClose = false; + il2cpp_field_set_value(dialogData, AutoCloseField, &AutoClose); + + 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, 0 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchorMax", 1)->methodPointer(rootTransform, Vector2_t{ 1, 1 }); + + 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, 0.5 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchoredPosition", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + auto scrollViewBase = resources_load_hook(il2cpp_string_new("ui/parts/base/scrollviewbase"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + auto _mainCanvasField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_mainCanvas"); + Il2CppObject* _mainCanvas; + il2cpp_field_get_value(uiManager, _mainCanvasField, &_mainCanvas); + + auto transform = il2cpp_class_get_method_from_name_type(_mainCanvas->klass, "get_transform", 0)->methodPointer(_mainCanvas); + + scrollViewBase = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingleWithParent", 3) + (scrollViewBase, transform, false); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(scrollViewBase->klass, "GetComponentsInternal", 6)->methodPointer; + + auto scrollRectArray = getComponents(scrollViewBase, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ScrollRectCommon")), true, true, false, false, nullptr); + + auto scrollRect = scrollRectArray->vector[0]; + + auto m_ViewportField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Viewport"); + Il2CppObject* m_Viewport; + il2cpp_field_get_value(scrollRect, m_ViewportField, &m_Viewport); + + auto scrollRectTransform = il2cpp_class_get_method_from_name_type(m_Viewport->klass, "get_parent", 0)->methodPointer(m_Viewport); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_sizeDelta", 1)->methodPointer(scrollRectTransform, Vector2_t{ -24, -12 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMax", 1)->methodPointer(scrollRectTransform, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMin", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_pivot", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0.5, 0.5 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchoredPosition", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, -6 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "SetParent", 2)->methodPointer(scrollRectTransform, rootTransform, false); + + auto m_ContentField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Content"); + Il2CppObject* m_Content; + il2cpp_field_get_value(scrollRect, m_ContentField, &m_Content); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_sizeDelta", 1)->methodPointer(m_Content, Vector2_t{ 56, 150.0f * ceilf(options.size() / 2.0f) }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMax", 1)->methodPointer(m_Content, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMin", 1)->methodPointer(m_Content, Vector2_t{ 0, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_pivot", 1)->methodPointer(m_Content, Vector2_t{ 0.5, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchoredPosition", 1)->methodPointer(m_Content, Vector2_t{ 0, 0 }); + + auto contentGameObject = il2cpp_class_get_method_from_name_type(m_Content->klass, "get_gameObject", 0)->methodPointer(m_Content); + + auto gridLayoutGroup = AddComponent(contentGameObject, GetRuntimeType("UnityEngine.UI.dll", "UnityEngine.UI", "GridLayoutGroup")); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_childAlignment", 1)->methodPointer(gridLayoutGroup, 0); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_constraintCount", 1)->methodPointer(gridLayoutGroup, 2); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_cellSize", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 400, 100 }); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_spacing", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 34, 50 }); + + auto padding = il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "get_padding", 0)->methodPointer(gridLayoutGroup); + il2cpp_class_get_method_from_name_type(padding->klass, "set_top", 1)->methodPointer(padding, 26); + il2cpp_class_get_method_from_name_type(padding->klass, "set_left", 1)->methodPointer(padding, 48); + + auto toggleGroupCommon = AddComponent(contentGameObject, GetRuntimeType("umamusume.dll", "Gallop", "ToggleGroupCommon")); + + uobject_set_name(contentGameObject, il2cpp_string_new("option_toggle_group_content")); + + vector toggles; + + for (auto& size : options) + { + toggles.emplace_back(GetRadioButtonWithText(("radio_"s + size).data(), size.data())); + SetTextCommonFontColor(GetTextCommon(("radio_"s + size).data()), "White"); + SetTextCommonOutlineSize(GetTextCommon(("radio_"s + size).data()), size.data()); + SetTextCommonOutlineColor(GetTextCommon(("radio_"s + size).data()), "Brown"); + } + + AddToLayout(m_Content, toggles); + + auto toggleArray = il2cpp_array_new_type(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "ToggleCommon"), toggles.size()); + + for (int i = 0; i < options.size(); i++) + { + auto& color = options[i]; + + il2cpp_array_setref(toggleArray, i, GetToggleCommon(("radio_"s + color).data())); + } + + il2cpp_class_get_method_from_name_type*)>(toggleGroupCommon->klass, "set_ToggleArray", 1)->methodPointer(toggleGroupCommon, toggleArray); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "SetToggleOnFromNumber", 1)->methodPointer(toggleGroupCommon, selectedIndex); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "Awake", 0)->methodPointer(toggleGroupCommon); + + auto ContentsObjectField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ContentsObject"); + + il2cpp_field_set_value(dialogData, ContentsObjectField, gameObject); + + selectOptionDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + } + + void OpenSelectOutlineColorOption(const char* title, vector options, int selectedIndex, function optionSelected) + { + ::optionSelected = optionSelected; + + auto dialogData = il2cpp_object_new( + il2cpp_symbols::get_class("umamusume.dll", "Gallop", "DialogCommon/Data")); + il2cpp_runtime_object_init(dialogData); + + auto onLeft = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); + }); + + auto onRight = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + il2cpp_class_get_method_from_name_type(selectOptionDialog->klass, "Close", 0)->methodPointer(selectOptionDialog); + ::optionSelected(GetToggleGroupCommonValue("option_toggle_group_content")); + }); + + dialogData = reinterpret_cast( + il2cpp_class_get_method_from_name(dialogData->klass, "SetSimpleTwoButtonMessage", + 7)->methodPointer + )(dialogData, il2cpp_string_new(title), nullptr, onRight, GetTextIdByName("Common0004"), GetTextIdByName("Common0003"), onLeft, 10); + + auto DispStackTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "DispStackType"); + int DispStackType = 2; + il2cpp_field_set_value(dialogData, DispStackTypeField, &DispStackType); + + auto ObjParentTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ObjParentType"); + int ObjParentType = 1; + il2cpp_field_set_value(dialogData, ObjParentTypeField, &ObjParentType); + + auto AutoCloseField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "AutoClose"); + bool AutoClose = false; + il2cpp_field_set_value(dialogData, AutoCloseField, &AutoClose); + + 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, 0 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchorMax", 1)->methodPointer(rootTransform, Vector2_t{ 1, 1 }); + + 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, 0.5 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchoredPosition", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + auto scrollViewBase = resources_load_hook(il2cpp_string_new("ui/parts/base/scrollviewbase"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + auto _mainCanvasField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_mainCanvas"); + Il2CppObject* _mainCanvas; + il2cpp_field_get_value(uiManager, _mainCanvasField, &_mainCanvas); + + auto transform = il2cpp_class_get_method_from_name_type(_mainCanvas->klass, "get_transform", 0)->methodPointer(_mainCanvas); + + scrollViewBase = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingleWithParent", 3) + (scrollViewBase, transform, false); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(scrollViewBase->klass, "GetComponentsInternal", 6)->methodPointer; + + auto scrollRectArray = getComponents(scrollViewBase, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ScrollRectCommon")), true, true, false, false, nullptr); + + auto scrollRect = scrollRectArray->vector[0]; + + auto m_ViewportField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Viewport"); + Il2CppObject* m_Viewport; + il2cpp_field_get_value(scrollRect, m_ViewportField, &m_Viewport); + + auto scrollRectTransform = il2cpp_class_get_method_from_name_type(m_Viewport->klass, "get_parent", 0)->methodPointer(m_Viewport); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_sizeDelta", 1)->methodPointer(scrollRectTransform, Vector2_t{ -24, -12 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMax", 1)->methodPointer(scrollRectTransform, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMin", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_pivot", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0.5, 0.5 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchoredPosition", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, -6 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "SetParent", 2)->methodPointer(scrollRectTransform, rootTransform, false); + + auto m_ContentField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Content"); + Il2CppObject* m_Content; + il2cpp_field_get_value(scrollRect, m_ContentField, &m_Content); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_sizeDelta", 1)->methodPointer(m_Content, Vector2_t{ 56, 150.0f * ceilf(options.size() / 2.0f) }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMax", 1)->methodPointer(m_Content, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMin", 1)->methodPointer(m_Content, Vector2_t{ 0, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_pivot", 1)->methodPointer(m_Content, Vector2_t{ 0.5, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchoredPosition", 1)->methodPointer(m_Content, Vector2_t{ 0, 0 }); + + auto contentGameObject = il2cpp_class_get_method_from_name_type(m_Content->klass, "get_gameObject", 0)->methodPointer(m_Content); + + auto gridLayoutGroup = AddComponent(contentGameObject, GetRuntimeType("UnityEngine.UI.dll", "UnityEngine.UI", "GridLayoutGroup")); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_childAlignment", 1)->methodPointer(gridLayoutGroup, 0); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_constraintCount", 1)->methodPointer(gridLayoutGroup, 2); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_cellSize", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 400, 100 }); + il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "set_spacing", 1)->methodPointer(gridLayoutGroup, Vector2_t{ 34, 50 }); + + auto padding = il2cpp_class_get_method_from_name_type(gridLayoutGroup->klass, "get_padding", 0)->methodPointer(gridLayoutGroup); + il2cpp_class_get_method_from_name_type(padding->klass, "set_top", 1)->methodPointer(padding, 26); + il2cpp_class_get_method_from_name_type(padding->klass, "set_left", 1)->methodPointer(padding, 48); + + auto toggleGroupCommon = AddComponent(contentGameObject, GetRuntimeType("umamusume.dll", "Gallop", "ToggleGroupCommon")); + + uobject_set_name(contentGameObject, il2cpp_string_new("option_toggle_group_content")); + + vector toggles; + + for (auto& color : options) + { + toggles.emplace_back(GetRadioButtonWithText(("radio_"s + color).data(), color.data())); + SetTextCommonOutlineColor(GetTextCommon(("radio_"s + color).data()), color.data()); + } + + AddToLayout(m_Content, toggles); + + auto toggleArray = il2cpp_array_new_type(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "ToggleCommon"), toggles.size()); + + for (int i = 0; i < options.size(); i++) + { + auto& color = options[i]; + + il2cpp_array_setref(toggleArray, i, GetToggleCommon(("radio_"s + color).data())); + } + + il2cpp_class_get_method_from_name_type*)>(toggleGroupCommon->klass, "set_ToggleArray", 1)->methodPointer(toggleGroupCommon, toggleArray); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "SetToggleOnFromNumber", 1)->methodPointer(toggleGroupCommon, selectedIndex); + il2cpp_class_get_method_from_name_type(toggleGroupCommon->klass, "Awake", 0)->methodPointer(toggleGroupCommon); + + auto ContentsObjectField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ContentsObject"); + + il2cpp_field_set_value(dialogData, ContentsObjectField, gameObject); + + selectOptionDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + } + + vector GetFontColorOptions() + { + vector options; + + const auto klass = il2cpp_symbols::get_class("umamusume.dll", "Gallop", "FontColorType"); + + void* iter = nullptr; + while (auto field = il2cpp_class_get_fields(klass, &iter)) + { + auto attrs = il2cpp_field_get_flags(field); + + if (attrs & FIELD_ATTRIBUTE_LITERAL && il2cpp_class_is_enum(klass)) + { + auto name = il2cpp_field_get_name(field); + + options.emplace_back(name); + } + } + + return options; + } + + vector GetOutlineSizeOptions() + { + vector options; + + const auto klass = il2cpp_symbols::get_class("umamusume.dll", "Gallop", "OutlineSizeType"); + + void* iter = nullptr; + while (auto field = il2cpp_class_get_fields(klass, &iter)) + { + auto attrs = il2cpp_field_get_flags(field); + + if (attrs & FIELD_ATTRIBUTE_LITERAL && il2cpp_class_is_enum(klass)) + { + auto name = il2cpp_field_get_name(field); + + options.emplace_back(name); + } + } + + return options; + } + + vector GetOutlineColorOptions() + { + vector options; + + const auto klass = il2cpp_symbols::get_class("umamusume.dll", "Gallop", "OutlineColorType"); + + void* iter = nullptr; + while (auto field = il2cpp_class_get_fields(klass, &iter)) + { + auto attrs = il2cpp_field_get_flags(field); + + if (attrs & FIELD_ATTRIBUTE_LITERAL && il2cpp_class_is_enum(klass)) + { + auto name = il2cpp_field_get_name(field); + + options.emplace_back(name); + } + } + + return options; + } + + vector GetGraphicsQualityOptions() + { + vector options = { "Default" }; + + const auto klass = il2cpp_symbols::get_class("umamusume.dll", "Gallop", "GraphicSettings/GraphicsQuality"); + + void* iter = nullptr; + while (auto field = il2cpp_class_get_fields(klass, &iter)) + { + auto attrs = il2cpp_field_get_flags(field); + + if (attrs & FIELD_ATTRIBUTE_LITERAL && il2cpp_class_is_enum(klass)) + { + auto name = il2cpp_field_get_name(field); + + if (name != "Max"s) + { + options.emplace_back(name); + } + } + } + + return options; + } + + void OpenSettings() + { + auto dialogData = il2cpp_object_new( + il2cpp_symbols::get_class("umamusume.dll", "Gallop", "DialogCommon/Data")); + il2cpp_runtime_object_init(dialogData); + + auto onLeft = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + il2cpp_class_get_method_from_name_type(settingsDialog->klass, "Close", 0)->methodPointer(settingsDialog); + + SetNotificationBackgroundAlpha(g_character_system_text_caption_background_alpha); + SetNotificationPosition(g_character_system_text_caption_position_x, g_character_system_text_caption_position_y); + SetNotificationFontColor(g_character_system_text_caption_font_color); + SetNotificationOutlineSize(g_character_system_text_caption_outline_size); + SetNotificationOutlineColor(g_character_system_text_caption_outline_color); + + config::rollback_config(); + }); + + auto onRight = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + auto& configDocument = config::config_document; + + AddOrSet(configDocument, "antiAliasing", vector{ -1, 0, 2, 4, 8 }[GetOptionSliderValue("anti_aliasing")]); + + AddOrSet(configDocument, "characterSystemTextCaption", GetOptionItemOnOffIsOn("character_system_text_caption")); + + AddOrSet(configDocument, "characterSystemTextCaptionPositionX", GetOptionSliderValue("character_system_text_caption_position_x") / 10); + + AddOrSet(configDocument, "characterSystemTextCaptionPositionY", GetOptionSliderValue("character_system_text_caption_position_y") / 10); + + AddOrSet(configDocument, "characterSystemTextCaptionBackgroundAlpha", GetOptionSliderValue("character_system_text_caption_background_alpha") / 100); + + AddOrSet(configDocument, "championsLiveShowText", GetOptionItemOnOffIsOn("champions_live_show_text")); + + AddOrSet(configDocument, "championsLiveYear", GetToggleGroupCommonValue("champions_live_year") + 2022); + + AddOrSet(configDocument, "allowDeleteCookie", GetOptionItemOnOffIsOn("allow_delete_cookie")); + + AddOrSet(configDocument, "cySpringUpdateMode", static_cast(GetOptionSliderValue("cyspring_update_mode"))); + + AddOrSet(configDocument, "uiAnimationScale", static_cast(roundf(GetOptionSliderValue("ui_animation_scale") * 100)) / 100.0f); + + AddOrSet(configDocument, "resolution3dScale", static_cast(roundf(GetOptionSliderValue("resolution_3d_scale") * 100)) / 100.0f); + + AddOrSet(configDocument, "notificationTp", GetOptionItemOnOffIsOn("notification_tp")); + + AddOrSet(configDocument, "notificationRp", GetOptionItemOnOffIsOn("notification_rp")); + + AddOrSet(configDocument, "dumpMsgPack", GetOptionItemOnOffIsOn("dump_msgpack")); + + AddOrSet(configDocument, "dumpMsgPackRequest", GetOptionItemOnOffIsOn("dump_msgpack_request")); + +#ifdef _DEBUG + AddOrSet(configDocument, "unlockLiveChara", GetOptionItemOnOffIsOn("unlock_live_chara")); +#endif + AddOrSet(configDocument, "unlockSize", GetOptionItemOnOffIsOn("unlock_size")); + + AddOrSet(configDocument, "unlockSizeUseSystemResolution", GetOptionItemOnOffIsOn("use_system_resolution")); + + AddOrSet(configDocument, "uiScale", static_cast(roundf(GetOptionSliderValue("ui_scale") * 100)) / 100.0f); + + AddOrSet(configDocument, "autoFullscreen", GetOptionItemOnOffIsOn("auto_fullscreen")); + + AddOrSet(configDocument, "freeFormWindow", GetOptionItemOnOffIsOn("freeform_window")); + + AddOrSet(configDocument, "freeFormUiScalePortrait", static_cast(roundf(GetOptionSliderValue("ui_scale_portrait") * 100)) / 100.0f); + + AddOrSet(configDocument, "freeFormUiScaleLandscape", static_cast(roundf(GetOptionSliderValue("ui_scale_landscape") * 100)) / 100.0f); + + g_graphics_quality = configDocument["graphicsQuality"].GetInt(); + + g_anti_aliasing = configDocument["antiAliasing"].GetInt(); + + g_character_system_text_caption_background_alpha = configDocument["characterSystemTextCaptionBackgroundAlpha"].GetFloat(); + + g_character_system_text_caption_position_x = configDocument["characterSystemTextCaptionPositionX"].GetFloat(); + + g_character_system_text_caption_position_y = configDocument["characterSystemTextCaptionPositionY"].GetFloat(); + + g_character_system_text_caption_font_color = configDocument["characterSystemTextCaptionFontColor"].GetString(); + + g_character_system_text_caption_outline_size = configDocument["characterSystemTextCaptionOutlineSize"].GetString(); + + g_character_system_text_caption_outline_color = configDocument["characterSystemTextCaptionOutlineColor"].GetString(); + + g_champions_live_show_text = configDocument["championsLiveShowText"].GetBool(); + + g_champions_live_year = configDocument["championsLiveYear"].GetInt(); + + g_champions_live_resource_id = configDocument["championsLiveResourceId"].GetInt(); + + g_cyspring_update_mode = configDocument["cySpringUpdateMode"].GetInt(); + + g_ui_animation_scale = configDocument["uiAnimationScale"].GetFloat(); + + g_resolution_3d_scale = configDocument["resolution3dScale"].GetFloat(); + + if (Game::CurrentGameRegion == Game::Region::KOR) + { + auto graphicSettings = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "GraphicSettings")); + + if (graphicSettings) + { + auto _resolutionScaleField = il2cpp_class_get_field_from_name_wrap(graphicSettings->klass, "_resolutionScale"); + + il2cpp_field_set_value(graphicSettings, _resolutionScaleField, &g_resolution_3d_scale); + + auto _resolutionScale2DField = il2cpp_class_get_field_from_name_wrap(graphicSettings->klass, "_resolutionScale2D"); + + il2cpp_field_set_value(graphicSettings, _resolutionScale2DField, &g_resolution_3d_scale); + } + } + + auto nowLoading = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "NowLoading", "get_Instance", -1)(); + il2cpp_class_get_method_from_name_type(nowLoading->klass, "DeleteMiniCharacter", 0)->methodPointer(nowLoading); + il2cpp_class_get_method_from_name_type(nowLoading->klass, "CreateMiniCharacter", 0)->methodPointer(nowLoading); + + g_unlock_size_use_system_resolution = configDocument["unlockSizeUseSystemResolution"].GetBool(); + + g_ui_scale = configDocument["uiScale"].GetFloat(); + + g_auto_fullscreen = configDocument["autoFullscreen"].GetBool(); + + g_freeform_ui_scale_portrait = configDocument["freeFormUiScalePortrait"].GetFloat(); + + g_freeform_ui_scale_landscape = configDocument["freeFormUiScaleLandscape"].GetFloat(); + + g_notification_tp = configDocument["notificationTp"].GetBool(); + + if (g_notification_tp) + { + MsgPackData::RegisterTPScheduledToast(); + } + else + { + DesktopNotificationManagerCompat::RemoveFromScheduleByTag(L"TP"); + } + + g_notification_rp = configDocument["notificationRp"].GetBool(); + + if (g_notification_rp) + { + MsgPackData::RegisterRPScheduledToast(); + } + else + { + DesktopNotificationManagerCompat::RemoveFromScheduleByTag(L"RP"); + } + + g_dump_msgpack = configDocument["dumpMsgPack"].GetBool(); + + g_dump_msgpack_request = configDocument["dumpMsgPackRequest"].GetBool(); + +#ifdef _DEBUG + g_unlock_live_chara = configDocument["unlockLiveChara"].GetBool(); +#endif + config::write_config(); + + 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, "SetSimpleOneButtonMessage", + 4)->methodPointer + )(dialogData, GetTextIdByName("AccoutDataLink0061"), localize_get_hook(GetTextIdByName("Outgame0309")), nullptr, GetTextIdByName("Common0007")); + + auto onDestroy = CreateDelegateStatic(*[]() + { + il2cpp_class_get_method_from_name_type(settingsDialog->klass, "Close", 0)->methodPointer(settingsDialog); + settingsDialog = nullptr; + }); + + il2cpp_class_get_method_from_name_type(dialogData->klass, "AddDestroyCallback", 1)->methodPointer(dialogData, onDestroy); + il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + }); + + dialogData = reinterpret_cast( + il2cpp_class_get_method_from_name(dialogData->klass, "SetSimpleTwoButtonMessage", + 7)->methodPointer + )(dialogData, il2cpp_string_new(LocalifySettings::GetText("title")), nullptr, onRight, GetTextIdByName("Common0004"), GetTextIdByName("Common0261"), onLeft, 10); + + auto DispStackTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "DispStackType"); + int DispStackType = 2; + il2cpp_field_set_value(dialogData, DispStackTypeField, &DispStackType); + + auto ObjParentTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ObjParentType"); + int ObjParentType = 1; + il2cpp_field_set_value(dialogData, ObjParentTypeField, &ObjParentType); + + auto AutoCloseField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "AutoClose"); + bool AutoClose = false; + il2cpp_field_set_value(dialogData, AutoCloseField, &AutoClose); + + 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, 0 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchorMax", 1)->methodPointer(rootTransform, Vector2_t{ 1, 1 }); + + 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, 0.5 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchoredPosition", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + auto scrollViewBase = resources_load_hook(il2cpp_string_new("ui/parts/base/scrollviewbase"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + auto _mainCanvasField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_mainCanvas"); + Il2CppObject* _mainCanvas; + il2cpp_field_get_value(uiManager, _mainCanvasField, &_mainCanvas); + + auto transform = il2cpp_class_get_method_from_name_type(_mainCanvas->klass, "get_transform", 0)->methodPointer(_mainCanvas); + + scrollViewBase = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingleWithParent", 3) + (scrollViewBase, transform, false); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(scrollViewBase->klass, "GetComponentsInternal", 6)->methodPointer; + + auto scrollRectArray = getComponents(scrollViewBase, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ScrollRectCommon")), true, true, false, false, nullptr); + + auto scrollRect = scrollRectArray->vector[0]; + + auto m_ViewportField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Viewport"); + Il2CppObject* m_Viewport; + il2cpp_field_get_value(scrollRect, m_ViewportField, &m_Viewport); + + auto scrollRectTransform = il2cpp_class_get_method_from_name_type(m_Viewport->klass, "get_parent", 0)->methodPointer(m_Viewport); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_sizeDelta", 1)->methodPointer(scrollRectTransform, Vector2_t{ -24, -12 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMax", 1)->methodPointer(scrollRectTransform, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMin", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_pivot", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0.5, 0.5 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchoredPosition", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, -6 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "SetParent", 2)->methodPointer(scrollRectTransform, rootTransform, false); + + auto m_ContentField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Content"); + Il2CppObject* m_Content; + il2cpp_field_get_value(scrollRect, m_ContentField, &m_Content); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_sizeDelta", 1)->methodPointer(m_Content, Vector2_t{ 56, 0 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMax", 1)->methodPointer(m_Content, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMin", 1)->methodPointer(m_Content, Vector2_t{ 0, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_pivot", 1)->methodPointer(m_Content, Vector2_t{ 0.5, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchoredPosition", 1)->methodPointer(m_Content, Vector2_t{ 0, 0 }); + + auto contentGameObject = il2cpp_class_get_method_from_name_type(m_Content->klass, "get_gameObject", 0)->methodPointer(m_Content); + + auto verticalLayoutGroup = AddComponent(contentGameObject, 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_top", 1)->methodPointer(padding, -20); + il2cpp_class_get_method_from_name_type(padding->klass, "set_bottom", 1)->methodPointer(padding, 16); + + int antiAliasing = 0; + bool characterSystemTextCaption = false; + bool championsLiveShowText = false; + int championsLiveYear = 2022; + float characterSystemTextCaptionPositionX = 0; + float characterSystemTextCaptionPositionY = 0; + float characterSystemTextCaptionBackgroundAlpha = 0; + bool allowDeleteCookie = false; + int cySpringUpdateMode = -1; + float resolution3dScale = 1; + float uiAnimationScale = 1; + bool notificationTp = false; + bool notificationRp = false; + bool dumpMsgPack = false; + bool dumpMsgPackRequest = false; + bool unlockLiveChara = false; + bool unlockSize = false; + bool unlockSizeUseSystemResolution = false; + float uiScale = 0; + bool autoFullscreen = false; + bool freeFormWindow = false; + float freeFormUiScalePortrait = 0; + float freeFormUiScaleLandscape = 0; + + if (config::read_config()) + { + auto& configDocument = config::config_document; + + if (configDocument.HasMember("antiAliasing")) + { + vector options = { -1, 0, 2, 4, 8 }; + antiAliasing = find(options.begin(), options.end(), configDocument["antiAliasing"].GetInt()) - options.begin(); + } + + if (configDocument.HasMember("characterSystemTextCaption")) + { + characterSystemTextCaption = configDocument["characterSystemTextCaption"].GetBool(); + } + + if (configDocument.HasMember("championsLiveShowText")) + { + championsLiveShowText = configDocument["championsLiveShowText"].GetBool(); + } + + if (configDocument.HasMember("championsLiveYear")) + { + championsLiveYear = configDocument["championsLiveYear"].GetInt(); + } + + if (configDocument.HasMember("characterSystemTextCaptionPositionX")) + { + characterSystemTextCaptionPositionX = configDocument["characterSystemTextCaptionPositionX"].GetFloat(); + } + + if (configDocument.HasMember("characterSystemTextCaptionPositionY")) + { + characterSystemTextCaptionPositionY = configDocument["characterSystemTextCaptionPositionY"].GetFloat(); + } + + if (configDocument.HasMember("characterSystemTextCaptionBackgroundAlpha")) + { + characterSystemTextCaptionBackgroundAlpha = configDocument["characterSystemTextCaptionBackgroundAlpha"].GetFloat(); + } + + if (configDocument.HasMember("allowDeleteCookie")) + { + allowDeleteCookie = configDocument["allowDeleteCookie"].GetBool(); + } + + if (configDocument.HasMember("cySpringUpdateMode")) + { + cySpringUpdateMode = configDocument["cySpringUpdateMode"].GetInt(); + } + + if (configDocument.HasMember("resolution3dScale")) + { + resolution3dScale = configDocument["resolution3dScale"].GetFloat(); + } + + if (configDocument.HasMember("uiAnimationScale")) + { + uiAnimationScale = configDocument["uiAnimationScale"].GetFloat(); + } + + if (configDocument.HasMember("notificationTp")) + { + notificationTp = configDocument["notificationTp"].GetBool(); + } + + if (configDocument.HasMember("notificationRp")) + { + notificationRp = configDocument["notificationRp"].GetBool(); + } + + if (configDocument.HasMember("dumpMsgPack")) + { + dumpMsgPack = configDocument["dumpMsgPack"].GetBool(); + } + + if (configDocument.HasMember("dumpMsgPackRequest")) + { + dumpMsgPackRequest = configDocument["dumpMsgPackRequest"].GetBool(); + } + +#ifdef _DEBUG + if (configDocument.HasMember("unlockLiveChara")) + { + unlockLiveChara = configDocument["unlockLiveChara"].GetBool(); + } +#endif + if (configDocument.HasMember("unlockSize")) + { + unlockSize = configDocument["unlockSize"].GetBool(); + } + + if (configDocument.HasMember("unlockSizeUseSystemResolution")) + { + unlockSizeUseSystemResolution = configDocument["unlockSizeUseSystemResolution"].GetBool(); + } + + if (configDocument.HasMember("uiScale")) + { + uiScale = configDocument["uiScale"].GetFloat(); + } + + if (configDocument.HasMember("autoFullscreen")) + { + autoFullscreen = configDocument["autoFullscreen"].GetBool(); + } + + if (configDocument.HasMember("freeFormWindow")) + { + freeFormWindow = configDocument["freeFormWindow"].GetBool(); + } + + if (configDocument.HasMember("freeFormUiScalePortrait")) + { + freeFormUiScalePortrait = configDocument["freeFormUiScalePortrait"].GetFloat(); + } + + if (configDocument.HasMember("freeFormUiScaleLandscape")) + { + freeFormUiScaleLandscape = configDocument["freeFormUiScaleLandscape"].GetFloat(); + } + } + + vector graphicsQualityOptions = GetGraphicsQualityOptions(); + + AddToLayout(m_Content, { - GetOptionItemTitle(LocalifySettings::GetText("title")), - GetOptionItemOnOff("character_system_text_caption", LocalifySettings::GetText("character_system_text_caption")), - GetOptionItemButton("show_caption", LocalifySettings::GetText("show_caption")), - GetOptionItemAttention(LocalifySettings::GetText("applied_after_restart")), - GetOptionItemOnOff("champions_live_show_text", LocalifySettings::GetText("champions_live_show_text")), - Game::CurrentGameRegion == Game::Region::JAP ? - GetOptionItemButton("clear_webview_cache", LocalifySettings::GetText("clear_webview_cache")) : - GetOptionItemOnOff("allow_delete_cookie", LocalifySettings::GetText("allow_delete_cookie")), - // GetOptionItemAttention("Attention with Color\nAttention"), - // GetOptionItemSimple("Simple"), - // GetOptionItemOnOff("on_off", "On Off"), - // GetOptionItem3ToggleVertical("Text"), - // GetOptionItem3Toggle("Text"), - // GetOptionItem2Toggle("Text"), GetOptionItemTitle(LocalifySettings::GetText("graphics")), - GetOptionSlider("ui_animation_scale", LocalifySettings::GetText("ui_animation_scale"), uiAnimationScale, 0.1, 5.1, false), + GetOptionItemSimpleWithButton("graphics_quality", (LocalifySettings::GetText("graphics_quality") + ": "s + graphicsQualityOptions[config::config_document["graphicsQuality"].GetInt() + 1]).data(), + local::wide_u8(localize_get_hook(GetTextIdByName("Circle0206"))->start_char).data()), + GetOptionSlider("anti_aliasing", LocalifySettings::GetText("anti_aliasing"), antiAliasing, 0, 4, true, *[](Il2CppObject* slider) { + auto numText = GetOptionSliderNumText(slider); + auto value = GetOptionSliderValue(slider); + + switch (static_cast(value)) + { + case 0: + text_set_text(numText, il2cpp_string_new("Default")); + break; + case 1: + text_set_text(numText, il2cpp_string_new("OFF")); + break; + case 2: + text_set_text(numText, il2cpp_string_new("x2")); + break; + case 3: + text_set_text(numText, il2cpp_string_new("x4")); + break; + case 4: + text_set_text(numText, il2cpp_string_new("x8")); + break; + } + }), + GetOptionSlider("ui_animation_scale", LocalifySettings::GetText("ui_animation_scale"), uiAnimationScale, 0.1, 5.0, false), + GetOptionSlider("resolution_3d_scale", LocalifySettings::GetText("resolution_3d_scale"), resolution3dScale, 0.1, 2.0, false), GetOptionSlider("cyspring_update_mode", LocalifySettings::GetText("cyspring_update_mode"), cySpringUpdateMode, -1, 3, true, *[](Il2CppObject* slider) { auto numText = GetOptionSliderNumText(slider); auto value = GetOptionSliderValue(slider); @@ -6707,69 +8100,300 @@ namespace text_set_text(numText, il2cpp_string_new("SkipFramePostAlways")); break; } - }), - /*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"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"), - GetOptionItemInfo("Info with Color\nInfo"),*/ + }), + GetOptionItemTitle(LocalifySettings::GetText("screen")), + GetOptionItemOnOff("unlock_size", LocalifySettings::GetText("unlock_size")), + GetOptionItemAttention(LocalifySettings::GetText("applied_after_restart")), + GetOptionItemOnOff("use_system_resolution", LocalifySettings::GetText("use_system_resolution")), + GetOptionSlider("ui_scale", LocalifySettings::GetText("ui_scale"), uiScale, 0.1, 2.0, false), + GetOptionItemOnOff("auto_fullscreen", LocalifySettings::GetText("auto_fullscreen")), + GetOptionItemOnOff("freeform_window", LocalifySettings::GetText("freeform_window")), + GetOptionItemAttention(LocalifySettings::GetText("applied_after_restart")), + GetOptionSlider("ui_scale_portrait", LocalifySettings::GetText("ui_scale_portrait"), freeFormUiScalePortrait, 0.1, 2.0, false), + GetOptionSlider("ui_scale_landscape", LocalifySettings::GetText("ui_scale_landscape"), freeFormUiScaleLandscape, 0.1, 2.0, false), + GetOptionItemTitle(local::wide_u8(localize_get_hook(GetTextIdByName("Common0035"))->start_char).data()), + GetOptionItemOnOff("champions_live_show_text", LocalifySettings::GetText("champions_live_show_text")), + GetOptionItemSimpleWithButton("champions_live_resource_id", (LocalifySettings::GetText("champions_live_resource_id") + ": "s + MasterDB::GetChampionsResources()[config::config_document["championsLiveResourceId"].GetInt() - 1]).data(), + local::wide_u8(localize_get_hook(GetTextIdByName("Circle0206"))->start_char).data()), + GetOptionItem3Toggle("champions_live_year", LocalifySettings::GetText("champions_live_year"), "2022", "2023", "2024", championsLiveYear - 2022), + GetOptionItemSimple(""), + GetOptionItemTitle(LocalifySettings::GetText("character_system_text_caption")), + GetOptionItemOnOff("character_system_text_caption", LocalifySettings::GetText("character_system_text_caption")), + GetOptionSlider("character_system_text_caption_position_x", LocalifySettings::GetText("character_system_text_caption_position_x"), characterSystemTextCaptionPositionX * 10, -100, 100, true, *[](Il2CppObject* slider) { + auto numText = GetOptionSliderNumText(slider); + auto value = GetOptionSliderValue(slider); + value = value / 10; + + text_set_text(numText, il2cpp_string_new(format("{:.2f}", value).data())); + + SetNotificationPosition(value, GetOptionSliderValue("character_system_text_caption_position_y") / 10); + SetNotificationDisplayTime(1); + ShowNotification(il2cpp_string_new(LocalifySettings::GetText("sample_caption"))); + }), + GetOptionSlider("character_system_text_caption_position_y", LocalifySettings::GetText("character_system_text_caption_position_y"), characterSystemTextCaptionPositionY * 10, -100, 100, true, *[](Il2CppObject* slider) { + auto numText = GetOptionSliderNumText(slider); + auto value = GetOptionSliderValue(slider); + value = value / 10; + + text_set_text(numText, il2cpp_string_new(format("{:.2f}", value).data())); + + SetNotificationPosition(GetOptionSliderValue("character_system_text_caption_position_x") / 10, value); + SetNotificationDisplayTime(1); + ShowNotification(il2cpp_string_new(LocalifySettings::GetText("sample_caption"))); + }), + GetOptionSlider("character_system_text_caption_background_alpha", LocalifySettings::GetText("character_system_text_caption_background_alpha"), characterSystemTextCaptionBackgroundAlpha * 100, 0, 100, true, *[](Il2CppObject* slider) { + auto numText = GetOptionSliderNumText(slider); + auto value = GetOptionSliderValue(slider); + value = value / 100; + + text_set_text(numText, il2cpp_string_new(format("{:.2f}", value).data())); + + SetNotificationBackgroundAlpha(value); + SetNotificationDisplayTime(1); + ShowNotification(il2cpp_string_new(LocalifySettings::GetText("sample_caption"))); + }), + GetOptionItemSimpleWithButton("character_system_text_caption_font_color", (LocalifySettings::GetText("character_system_text_caption_font_color") + ": "s + config::config_document["characterSystemTextCaptionFontColor"].GetString()).data(), + local::wide_u8(localize_get_hook(GetTextIdByName("Circle0206"))->start_char).data()), + GetOptionItemSimpleWithButton("character_system_text_caption_outline_size", (LocalifySettings::GetText("character_system_text_caption_outline_size") + ": "s + config::config_document["characterSystemTextCaptionOutlineSize"].GetString()).data(), + local::wide_u8(localize_get_hook(GetTextIdByName("Circle0206"))->start_char).data()), + GetOptionItemSimpleWithButton("character_system_text_caption_outline_color", (LocalifySettings::GetText("character_system_text_caption_outline_color") + ": "s + config::config_document["characterSystemTextCaptionOutlineColor"].GetString()).data(), + local::wide_u8(localize_get_hook(GetTextIdByName("Circle0206"))->start_char).data()), + GetOptionItemButton("show_caption", LocalifySettings::GetText("show_caption")), + GetOptionItemAttention(LocalifySettings::GetText("applied_after_restart")), + GetOptionItemTitle(local::wide_u8(localize_get_hook(GetTextIdByName("Outgame0293"))->start_char).data()), + GetOptionItemOnOff("notification_tp", local::wide_u8(localize_get_hook(GetTextIdByName("Outgame0294"))->start_char).data()), + GetOptionItemOnOff("notification_rp", local::wide_u8(localize_get_hook(GetTextIdByName("Outgame0437"))->start_char).data()), + GetOptionItemButton("show_notification", LocalifySettings::GetText("show_notification")), + GetOptionItemAttention(local::wide_u8(localize_get_hook(GetTextIdByName("Outgame0297"))->start_char).data()), + GetOptionItemTitle(LocalifySettings::GetText("title")), + Game::CurrentGameRegion == Game::Region::JAP ? + GetOptionItemButton("clear_webview_cache", LocalifySettings::GetText("clear_webview_cache")) : + GetOptionItemOnOff("allow_delete_cookie", LocalifySettings::GetText("allow_delete_cookie")), + GetOptionItemOnOff("dump_msgpack", LocalifySettings::GetText("dump_msgpack")), + GetOptionItemOnOff("dump_msgpack_request", LocalifySettings::GetText("dump_msgpack_request")), +#ifdef _DEBUG + GetOptionItemOnOff("unlock_live_chara", LocalifySettings::GetText("unlock_live_chara")), + GetOptionItemInfo(LocalifySettings::GetText("unlock_live_chara_info")), +#endif GetOptionItemButton("github", "GitHub"), GetOptionItemTitle(LocalifySettings::GetText("experiments")), GetOptionItemButton("toggle_vr", "Toggle VR"), + // GetOptionItemSimple("Simple"), + // GetOptionItemOnOff("on_off", "On Off"), + // GetOptionItem3ToggleVertical("Text"), + // GetOptionItem3Toggle("Text"), + // GetOptionItem2Toggle("Text"), + /*GetDropdown("dropdown"), + GetCheckbox("checkbox"), + GetCheckboxWithText("checkbox_with_text"), + GetRadioButtonWithText("radiobutton_with_text", "Test"),*/ + /*GetSlider("slider"),*/ + /*GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"), + GetOptionItemInfo("Info with Color\nInfo"),*/ } ); SetOptionItemOnOffAction("character_system_text_caption", characterSystemTextCaption, *([](Il2CppObject*, bool isOn) { - // TODO })); SetOptionItemOnOffAction("champions_live_show_text", championsLiveShowText, *([](Il2CppObject*, bool isOn) { - // TODO })); - if (Game::CurrentGameRegion == Game::Region::KOR) - { - SetOptionItemOnOffAction("allow_delete_cookie", allowDeleteCookie, *([](Il2CppObject*, bool isOn) - { - // TODO - })); - } + SetOptionItemOnOffAction("notification_tp", notificationTp, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("notification_rp", notificationRp, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("dump_msgpack", dumpMsgPack, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("dump_msgpack_request", dumpMsgPackRequest, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("unlock_size", unlockSize, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("use_system_resolution", unlockSizeUseSystemResolution, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("auto_fullscreen", autoFullscreen, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("freeform_window", freeFormWindow, *([](Il2CppObject*, bool isOn) + { + })); + + SetOptionItemOnOffAction("unlock_live_chara", unlockLiveChara, *([](Il2CppObject*, bool isOn) + { + })); + + if (Game::CurrentGameRegion == Game::Region::KOR) + { + SetOptionItemOnOffAction("allow_delete_cookie", allowDeleteCookie, *([](Il2CppObject*, bool isOn) + { + // TODO + })); + } + + SetOptionItemOnOffAction("on_off", false, *([](Il2CppObject*, bool isOn) + { + stringstream text; + + text << "Changed to " << (isOn ? "On" : "Off"); + + ShowUINotification(il2cpp_string_new(text.str().data())); + })); + + SetOptionItemButtonAction("show_caption", *([](Il2CppObject*) + { + if (g_character_system_text_caption) + { + SetNotificationDisplayTime(1); + ShowNotification(il2cpp_string_new(LocalifySettings::GetText("sample_caption"))); + } + else + { + ShowUINotification(il2cpp_string_new(LocalifySettings::GetText("setting_disabled"))); + } + })); + + SetOptionItemButtonAction("show_notification", *([](Il2CppObject*) + { + auto leader_chara_id = MsgPackData::user_info["leader_chara_id"].int_value(); + auto title = local::u8_wide(MasterDB::GetTextData(6, leader_chara_id)); + auto contentU8 = MasterDB::GetTextData(163, leader_chara_id); + replaceAll(contentU8, "\\n", "\n"); + auto content = local::u8_wide(contentU8); + + DesktopNotificationManagerCompat::ShowToastNotification(title.data(), content.data(), MsgPackData::GetIconPath(leader_chara_id)->start_char); + })); + + SetOptionItemButtonAction("graphics_quality", *([](Il2CppObject*) + { + OpenSelectOption(LocalifySettings::GetText("graphics_quality"), GetGraphicsQualityOptions(), config::config_document["graphicsQuality"].GetInt() + 1, [](int value) { + AddOrSet(config::config_document, "graphicsQuality", value - 1); + + auto textCommon = GetOptionItemSimpleWithButtonTextCommon("graphics_quality"); + SetTextCommonText(textCommon, (LocalifySettings::GetText("graphics_quality") + ": "s + GetGraphicsQualityOptions()[config::config_document["graphicsQuality"].GetInt() + 1]).data()); + }); + })); + + SetOptionItemButtonAction("champions_live_resource_id", *([](Il2CppObject*) + { + OpenSelectOption(LocalifySettings::GetText("champions_live_resource_id"), MasterDB::GetChampionsResources(), config::config_document["championsLiveResourceId"].GetInt() - 1, [](int value) { + AddOrSet(config::config_document, "championsLiveResourceId", value + 1); + + auto textCommon = GetOptionItemSimpleWithButtonTextCommon("champions_live_resource_id"); + SetTextCommonText(textCommon, (LocalifySettings::GetText("champions_live_resource_id") + ": "s + MasterDB::GetChampionsResources()[config::config_document["championsLiveResourceId"].GetInt() - 1]).data()); + }); + })); + + auto fontColorTextCommon = GetOptionItemSimpleWithButtonTextCommon("character_system_text_caption_font_color"); + SetTextCommonOutlineColor(fontColorTextCommon, "Brown"); + SetTextCommonFontColor(fontColorTextCommon, + config::config_document["characterSystemTextCaptionFontColor"].GetString()); - SetOptionItemOnOffAction("on_off", false, *([](Il2CppObject*, bool isOn) + SetOptionItemButtonAction("character_system_text_caption_font_color", *([](Il2CppObject*) { - stringstream text; + auto options = GetFontColorOptions(); + auto value = config::config_document["characterSystemTextCaptionFontColor"].GetString(); + auto found = find(options.begin(), options.end(), value); + int index = 0; - text << "Changed to " << (isOn ? "On" : "Off"); + if (found != options.end()) + { + index = found - options.begin(); + } - ShowUINotification(il2cpp_string_new(text.str().data())); + OpenSelectFontColorOption(LocalifySettings::GetText("character_system_text_caption_font_color"), options, index, [](int value) { + auto options = GetFontColorOptions(); + string color = options[value]; + AddOrSetString(config::config_document, "characterSystemTextCaptionFontColor", color.data()); + + auto textCommon = GetOptionItemSimpleWithButtonTextCommon("character_system_text_caption_font_color"); + SetTextCommonText(textCommon, (LocalifySettings::GetText("character_system_text_caption_font_color") + ": "s + config::config_document["characterSystemTextCaptionFontColor"].GetString()).data()); + SetTextCommonFontColor(textCommon, color.data()); + SetNotificationFontColor(color.data()); + }); })); - SetOptionItemButtonAction("show_caption", *([](Il2CppObject*) + auto outlineSizeTextCommon = GetOptionItemSimpleWithButtonTextCommon("character_system_text_caption_outline_size"); + SetTextCommonFontColor(outlineSizeTextCommon, "White"); + SetTextCommonOutlineColor(outlineSizeTextCommon, "Brown"); + SetTextCommonOutlineSize(outlineSizeTextCommon, + config::config_document["characterSystemTextCaptionOutlineSize"].GetString()); + + SetOptionItemButtonAction("character_system_text_caption_outline_size", *([](Il2CppObject*) { - if (g_character_system_text_caption) + auto options = GetOutlineSizeOptions(); + auto value = config::config_document["characterSystemTextCaptionOutlineSize"].GetString(); + auto found = find(options.begin(), options.end(), value); + int index = 0; + + if (found != options.end()) { - SetNotificationDisplayTime(1); - ShowNotification(il2cpp_string_new(LocalifySettings::GetText("sample_caption"))); + index = found - options.begin(); } - else + + OpenSelectOutlineSizeOption(LocalifySettings::GetText("character_system_text_caption_outline_size"), options, index, [](int value) { + auto options = GetOutlineSizeOptions(); + string color = options[value]; + AddOrSetString(config::config_document, "characterSystemTextCaptionOutlineSize", color.data()); + + auto textCommon = GetOptionItemSimpleWithButtonTextCommon("character_system_text_caption_outline_size"); + SetTextCommonText(textCommon, (LocalifySettings::GetText("character_system_text_caption_outline_size") + ": "s + config::config_document["characterSystemTextCaptionOutlineSize"].GetString()).data()); + SetTextCommonOutlineSize(textCommon, color.data()); + SetNotificationOutlineSize(color.data()); + }); + })); + + auto outlineColorTextCommon = GetOptionItemSimpleWithButtonTextCommon("character_system_text_caption_outline_color"); + SetTextCommonOutlineColor(outlineColorTextCommon, + config::config_document["characterSystemTextCaptionOutlineColor"].GetString()); + + SetOptionItemButtonAction("character_system_text_caption_outline_color", *([](Il2CppObject*) + { + auto options = GetOutlineColorOptions(); + auto value = config::config_document["characterSystemTextCaptionOutlineColor"].GetString(); + auto found = find(options.begin(), options.end(), value); + int index = 0; + + if (found != options.end()) { - ShowUINotification(il2cpp_string_new(LocalifySettings::GetText("setting_disabled"))); + index = found - options.begin(); } + + OpenSelectOutlineColorOption(LocalifySettings::GetText("character_system_text_caption_outline_color"), options, index, [](int value) { + auto options = GetOutlineColorOptions(); + string color = options[value]; + AddOrSetString(config::config_document, "characterSystemTextCaptionOutlineColor", color.data()); + + auto textCommon = GetOptionItemSimpleWithButtonTextCommon("character_system_text_caption_outline_color"); + SetTextCommonText(textCommon, (LocalifySettings::GetText("character_system_text_caption_outline_color") + ": "s + config::config_document["characterSystemTextCaptionOutlineColor"].GetString()).data()); + SetTextCommonOutlineColor(textCommon, color.data()); + SetNotificationOutlineColor(color.data()); + }); })); SetOptionItemButtonAction("toggle_vr", *([](Il2CppObject*) @@ -6827,61 +8451,274 @@ namespace "umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); })); - if (Game::CurrentGameRegion != Game::Region::KOR) - { - SetOptionItemButtonAction("clear_webview_cache", *([](Il2CppObject*) - { - auto dialogData = il2cpp_object_new( - il2cpp_symbols::get_class("umamusume.dll", "Gallop", - "DialogCommon/Data")); - il2cpp_runtime_object_init(dialogData); + if (Game::CurrentGameRegion != Game::Region::KOR) + { + SetOptionItemButtonAction("clear_webview_cache", *([](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("Race0652")), + il2cpp_string_new(LocalifySettings::GetText("clear_webview_cache_confirm")), + CreateDelegateStatic(*[]() + { + PWSTR path; + SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, &path); + + wstring combinedPath = wstring(path).append(L"\\DMMWebView2"); + + try + { + filesystem::remove_all(combinedPath); + ShowUINotification(il2cpp_string_new(LocalifySettings::GetText("deleted"))); + } + catch (exception& e) + { + cout << e.what() << endl; + } + }), + 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"); + il2cpp_field_set_value(contentSizeFitter, _layoutField, verticalLayoutGroup); + + il2cpp_class_get_method_from_name_type(contentSizeFitter->klass, "SetSize", 0)->methodPointer(contentSizeFitter); + + auto ContentsObjectField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ContentsObject"); + + il2cpp_field_set_value(dialogData, ContentsObjectField, gameObject); + + settingsDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + } + + void OpenLiveSettings() + { + auto dialogData = il2cpp_object_new( + il2cpp_symbols::get_class("umamusume.dll", "Gallop", "DialogCommon/Data")); + il2cpp_runtime_object_init(dialogData); + + auto onLeft = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + il2cpp_class_get_method_from_name_type(settingsDialog->klass, "Close", 0)->methodPointer(settingsDialog); + + config::rollback_config(); + }); + + auto onRight = CreateDelegateStatic(*[](void*, Il2CppObject* dialog) + { + auto& configDocument = config::config_document; + + AddOrSet(configDocument, "championsLiveShowText", GetOptionItemOnOffIsOn("champions_live_show_text")); + + AddOrSet(configDocument, "championsLiveYear", GetToggleGroupCommonValue("champions_live_year") + 2022); + + g_champions_live_show_text = configDocument["championsLiveShowText"].GetBool(); + + g_champions_live_year = configDocument["championsLiveYear"].GetInt(); + + g_champions_live_resource_id = configDocument["championsLiveResourceId"].GetInt(); + + config::write_config(); + + 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, "SetSimpleOneButtonMessage", + 4)->methodPointer + )(dialogData, GetTextIdByName("AccoutDataLink0061"), localize_get_hook(GetTextIdByName("Outgame0309")), nullptr, GetTextIdByName("Common0007")); + + auto onDestroy = CreateDelegateStatic(*[]() + { + il2cpp_class_get_method_from_name_type(settingsDialog->klass, "Close", 0)->methodPointer(settingsDialog); + settingsDialog = nullptr; + }); + + il2cpp_class_get_method_from_name_type(dialogData->klass, "AddDestroyCallback", 1)->methodPointer(dialogData, onDestroy); + il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); + }); + + dialogData = reinterpret_cast( + il2cpp_class_get_method_from_name(dialogData->klass, "SetSimpleTwoButtonMessage", + 7)->methodPointer + )(dialogData, il2cpp_string_new(LocalifySettings::GetText("title")), nullptr, onRight, GetTextIdByName("Common0004"), GetTextIdByName("Common0261"), onLeft, 10); + + auto DispStackTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "DispStackType"); + int DispStackType = 2; + il2cpp_field_set_value(dialogData, DispStackTypeField, &DispStackType); + + auto ObjParentTypeField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ObjParentType"); + int ObjParentType = 1; + il2cpp_field_set_value(dialogData, ObjParentTypeField, &ObjParentType); + + auto AutoCloseField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "AutoClose"); + bool AutoClose = false; + il2cpp_field_set_value(dialogData, AutoCloseField, &AutoClose); + + 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, 0 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchorMax", 1)->methodPointer(rootTransform, Vector2_t{ 1, 1 }); + + 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, 0.5 }); + + il2cpp_class_get_method_from_name_type(rootTransform->klass, "set_anchoredPosition", 1)->methodPointer(rootTransform, Vector2_t{ 0, 0 }); + + auto scrollViewBase = resources_load_hook(il2cpp_string_new("ui/parts/base/scrollviewbase"), GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "GameObject")); + + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + auto _mainCanvasField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_mainCanvas"); + Il2CppObject* _mainCanvas; + il2cpp_field_get_value(uiManager, _mainCanvasField, &_mainCanvas); + + auto transform = il2cpp_class_get_method_from_name_type(_mainCanvas->klass, "get_transform", 0)->methodPointer(_mainCanvas); + + scrollViewBase = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Internal_CloneSingleWithParent", 3) + (scrollViewBase, transform, false); + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(scrollViewBase->klass, "GetComponentsInternal", 6)->methodPointer; + + auto scrollRectArray = getComponents(scrollViewBase, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "ScrollRectCommon")), true, true, false, false, nullptr); + + auto scrollRect = scrollRectArray->vector[0]; + + auto m_ViewportField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Viewport"); + Il2CppObject* m_Viewport; + il2cpp_field_get_value(scrollRect, m_ViewportField, &m_Viewport); + + auto scrollRectTransform = il2cpp_class_get_method_from_name_type(m_Viewport->klass, "get_parent", 0)->methodPointer(m_Viewport); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_sizeDelta", 1)->methodPointer(scrollRectTransform, Vector2_t{ -24, -12 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMax", 1)->methodPointer(scrollRectTransform, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchorMin", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, 0 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_pivot", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0.5, 0.5 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "set_anchoredPosition", 1)->methodPointer(scrollRectTransform, Vector2_t{ 0, -6 }); + + il2cpp_class_get_method_from_name_type(scrollRectTransform->klass, "SetParent", 2)->methodPointer(scrollRectTransform, rootTransform, false); + + auto m_ContentField = il2cpp_class_get_field_from_name_wrap(scrollRect->klass, "m_Content"); + Il2CppObject* m_Content; + il2cpp_field_get_value(scrollRect, m_ContentField, &m_Content); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_sizeDelta", 1)->methodPointer(m_Content, Vector2_t{ 56, 0 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMax", 1)->methodPointer(m_Content, Vector2_t{ 1, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchorMin", 1)->methodPointer(m_Content, Vector2_t{ 0, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_pivot", 1)->methodPointer(m_Content, Vector2_t{ 0.5, 1 }); + + il2cpp_class_get_method_from_name_type(m_Content->klass, "set_anchoredPosition", 1)->methodPointer(m_Content, Vector2_t{ 0, 0 }); + + auto contentGameObject = il2cpp_class_get_method_from_name_type(m_Content->klass, "get_gameObject", 0)->methodPointer(m_Content); + + auto verticalLayoutGroup = AddComponent(contentGameObject, 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_top", 1)->methodPointer(padding, -20); + il2cpp_class_get_method_from_name_type(padding->klass, "set_bottom", 1)->methodPointer(padding, 16); + + bool championsLiveShowText = false; + int championsLiveYear = 2023; + + if (config::read_config()) + { + auto& configDocument = config::config_document; + + if (configDocument.HasMember("championsLiveShowText")) + { + championsLiveShowText = configDocument["championsLiveShowText"].GetBool(); + } + + if (configDocument.HasMember("championsLiveYear")) + { + championsLiveYear = configDocument["championsLiveYear"].GetInt(); + } + } - dialogData = reinterpret_cast( - il2cpp_class_get_method_from_name(dialogData->klass, - "SetSimpleTwoButtonMessage", - 7)->methodPointer - )(dialogData, - localizeextension_text_hook(GetTextIdByName("Race0652")), - il2cpp_string_new(LocalifySettings::GetText("clear_webview_cache_confirm")), - CreateDelegateStatic(*[]() - { - PWSTR path; - SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, &path); + AddToLayout(m_Content, + { + GetOptionItemTitle(local::wide_u8(localize_get_hook(GetTextIdByName("Common0035"))->start_char).data()), + GetOptionItemOnOff("champions_live_show_text", LocalifySettings::GetText("champions_live_show_text")), + GetOptionItemSimpleWithButton("champions_live_resource_id", (LocalifySettings::GetText("champions_live_resource_id") + ": "s + MasterDB::GetChampionsResources()[config::config_document["championsLiveResourceId"].GetInt() - 1]).data(), + local::wide_u8(localize_get_hook(GetTextIdByName("Circle0206"))->start_char).data()), + GetOptionItem3Toggle("champions_live_year", LocalifySettings::GetText("champions_live_year"), "2022", "2023", "2024", championsLiveYear - 2022), + GetOptionItemSimple(""), + } + ); - wstring combinedPath = wstring(path).append(L"\\DMMWebView2"); + SetOptionItemOnOffAction("champions_live_show_text", championsLiveShowText, *([](Il2CppObject*, bool isOn) + { + // TODO + })); - try - { - filesystem::remove_all(combinedPath); - ShowUINotification(il2cpp_string_new(LocalifySettings::GetText("deleted"))); - } - catch (exception& e) - { - cout << e.what() << endl; - } - }), - GetTextIdByName("Common0004"), - GetTextIdByName("Common0003"), - nullptr, - 2); + SetOptionItemButtonAction("champions_live_resource_id", *([](Il2CppObject*) + { + OpenSelectOption(LocalifySettings::GetText("champions_live_resource_id"), MasterDB::GetChampionsResources(), config::config_document["championsLiveResourceId"].GetInt() - 1, [](int value) { + AddOrSet(config::config_document, "championsLiveResourceId", value + 1); - il2cpp_symbols::get_method_pointer( - "umamusume.dll", "Gallop", "DialogManager", "PushDialog", 1)(dialogData); - })); - } + auto textCommon = GetOptionItemSimpleWithButtonTextCommon("champions_live_resource_id"); + SetTextCommonText(textCommon, (LocalifySettings::GetText("champions_live_resource_id") + ": "s + MasterDB::GetChampionsResources()[config::config_document["championsLiveResourceId"].GetInt() - 1]).data()); + }); + })); auto contentSizeFitter = AddComponent(contentGameObject, GetRuntimeType("umamusume.dll", "Gallop", "LayoutGroupContentSizeFitter")); auto _layoutField = il2cpp_class_get_field_from_name_wrap(contentSizeFitter->klass, "_layout"); il2cpp_field_set_value(contentSizeFitter, _layoutField, verticalLayoutGroup); + bool _autoUpdate = true; + auto _autoUpdateField = il2cpp_class_get_field_from_name_wrap(contentSizeFitter->klass, "_autoUpdate"); + il2cpp_field_set_value(contentSizeFitter, _autoUpdateField, &_autoUpdate); + il2cpp_class_get_method_from_name_type(contentSizeFitter->klass, "SetSize", 0)->methodPointer(contentSizeFitter); auto ContentsObjectField = il2cpp_class_get_field_from_name_wrap(dialogData->klass, "ContentsObject"); @@ -6909,6 +8746,14 @@ namespace })); } + void SetupLiveOptionLayout() + { + SetOptionItemButtonAction("open_settings", *([](Il2CppObject*) + { + OpenLiveSettings(); + })); + } + void* Object_Internal_CloneSingleWithParent_orig = nullptr; Il2CppObject* Object_Internal_CloneSingleWithParent_hook(Il2CppObject* data, Il2CppObject* parent, bool worldPositionStays) { @@ -6916,9 +8761,68 @@ namespace if (wstring(uobject_get_name(cloned)->start_char).find(L"DialogOptionHome") != wstring::npos) { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(cloned->klass, "GetComponentsInternal", 6)->methodPointer; + auto rectTransformArray = getComponents(cloned, reinterpret_cast(GetRuntimeType( + "UnityEngine.CoreModule.dll", "UnityEngine", "RectTransform")), true, true, false, false, nullptr); + + for (int i = 0; i < rectTransformArray->max_length; i++) + { + auto rectTransform = rectTransformArray->vector[i]; + + if (rectTransform && local::wide_u8(uobject_get_name(rectTransform)->start_char) == "Content") + { + InitOptionLayout(rectTransform); + break; + } + } + SetupOptionLayout(); } + if (wstring(uobject_get_name(cloned)->start_char).find(L"DialogOptionLiveTheater") != wstring::npos) + { + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(cloned->klass, "GetComponentsInternal", 6)->methodPointer; + auto rectTransformArray = getComponents(cloned, reinterpret_cast(GetRuntimeType( + "UnityEngine.CoreModule.dll", "UnityEngine", "RectTransform")), true, true, false, false, nullptr); + + for (int i = 0; i < rectTransformArray->max_length; i++) + { + auto rectTransform = rectTransformArray->vector[i]; + + if (rectTransform && local::wide_u8(uobject_get_name(rectTransform)->start_char) == "Content") + { + InitOptionLayout(rectTransform); + break; + } + } + + SetupLiveOptionLayout(); + } + + if (wstring(uobject_get_name(cloned)->start_char).find(L"CharacterHomeTopUI") != wstring::npos) + { + auto getComponent = il2cpp_class_get_method_from_name_type(cloned->klass, "GetComponent", 1)->methodPointer; + auto CharacterHomeTopUI = getComponent(cloned, GetRuntimeType("umamusume.dll", "Gallop", "CharacterHomeTopUI")); + + if (CharacterHomeTopUI) + { + auto _cardRootButtonField = il2cpp_class_get_field_from_name_wrap(CharacterHomeTopUI->klass, "_cardRootButton"); + Il2CppObject* _cardRootButton; + il2cpp_field_get_value(CharacterHomeTopUI, _cardRootButtonField, &_cardRootButton); + + if (_cardRootButton) + { + auto targetText = il2cpp_class_get_method_from_name_type(_cardRootButton->klass, "get_TargetText", 0)->methodPointer(_cardRootButton); + + if (targetText) + { + text_set_horizontalOverflow(targetText, 1); + text_set_verticalOverflow(targetText, 1); + } + } + } + } + if (wstring(uobject_get_name(cloned)->start_char).find(L"LiveChampionsTextController") != wstring::npos) { auto updateScreenReferenceSize = CreateDelegateWithClass(il2cpp_symbols::get_class("DOTween.dll", "DG.Tweening", "TweenCallback"), cloned, *([](Il2CppObject* _this) @@ -6950,13 +8854,13 @@ namespace if (unityWidth < unityHeight) { - float scale = min(g_freeform_ui_scale_portrait, max(1, unityHeight * ratio_vertical) * g_freeform_ui_scale_portrait); + float scale = min(g_freeform_ui_scale_portrait, max(1.0f, unityHeight * ratio_vertical) * g_freeform_ui_scale_portrait); il2cpp_class_get_method_from_name_type(_flashCanvasScaler->klass, "set_referenceResolution", 1)->methodPointer(_flashCanvasScaler, Vector2_t{ static_cast(unityWidth / scale), static_cast(unityHeight / scale) }); il2cpp_class_get_method_from_name_type(root->klass, "SetScreenReferenceSize", 1)->methodPointer(root, Vector2_t{ ratio_16_9 * static_cast(unityHeight / scale), static_cast(unityHeight / scale) }); } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, unityWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, unityWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); il2cpp_class_get_method_from_name_type(_flashCanvasScaler->klass, "set_referenceResolution", 1)->methodPointer(_flashCanvasScaler, Vector2_t{ static_cast(unityWidth / scale), static_cast(unityHeight / scale) }); il2cpp_class_get_method_from_name_type(root->klass, "SetScreenReferenceSize", 1)->methodPointer(root, Vector2_t{ ratio_16_9 * static_cast(unityHeight / scale), static_cast(unityHeight / scale) }); } @@ -6999,7 +8903,7 @@ namespace il2cpp_field_get_value(component, imgField, &imgCommon); auto texture = GetReplacementAssets( il2cpp_string_new("utx_obj_title_logo_umamusume.png"), - (Il2CppType*)GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "Texture2D")); + reinterpret_cast(GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "Texture2D"))); auto m_TextureField = il2cpp_class_get_field_from_name_wrap(imgCommon->klass->parent, "m_Texture"); il2cpp_field_set_value(imgCommon, m_TextureField, texture); return gameObj; @@ -7072,7 +8976,59 @@ namespace if (rectTransform && local::wide_u8(uobject_get_name(rectTransform)->start_char) == "Content") { - InitOptionLayout(rectTransform); + // InitOptionLayout(rectTransform); + break; + } + } + } + } + } + + return object; + } + + + if (u8Name.ends_with("dialogoptionlivetheater")) + { + auto object = reinterpret_cast(resources_load_orig)(path, type); + + if (object != currentOptionObj) + { + currentOptionObj = object; + } + else + { + return object; + } + + auto getComponents = il2cpp_class_get_method_from_name_type *(*)(Il2CppObject*, Il2CppType*, bool, bool, bool, bool, Il2CppObject*)>(object->klass, "GetComponentsInternal", 6)->methodPointer; + + il2cpp_class_get_method_from_name_type(object->klass, "SetActive", 1)->methodPointer(object, true); + + + auto array = getComponents(object, reinterpret_cast(GetRuntimeType( + "umamusume.dll", "Gallop", "PartsOptionPageLive")), true, true, false, false, nullptr); + + if (array) + { + for (int i = 0; i < array->max_length; i++) + { + auto obj = array->vector[i]; + + if (obj && obj->klass->name == "PartsOptionPageLive"s) + { + auto gameObject = il2cpp_class_get_method_from_name_type(obj->klass, "get_gameObject", 0)->methodPointer(obj); + + auto rectTransformArray = getComponents(gameObject, reinterpret_cast(GetRuntimeType( + "UnityEngine.CoreModule.dll", "UnityEngine", "RectTransform")), true, true, false, false, nullptr); + + for (int j = 0; j < rectTransformArray->max_length; j++) + { + auto rectTransform = rectTransformArray->vector[j]; + + if (rectTransform && local::wide_u8(uobject_get_name(rectTransform)->start_char) == "Content") + { + // InitOptionLayout(rectTransform); break; } } @@ -7511,12 +9467,12 @@ namespace if (defaultResolution.x < defaultResolution.y) { - float scale = min(1, max(1, defaultResolution.y / 1080) * g_freeform_ui_scale_portrait / (defaultResolution.y / 1080)); + float scale = min(1, max(1.0f, defaultResolution.y / 1080) * g_freeform_ui_scale_portrait / (defaultResolution.y / 1080)); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_scaleFactor", 1)->methodPointer(canvasScaler, scale); } else { - float scale = min(1, max(1, defaultResolution.x / 1920) * g_freeform_ui_scale_landscape / (defaultResolution.x / 1920)); + float scale = min(1, max(1.0f, defaultResolution.x / 1920) * g_freeform_ui_scale_landscape / (defaultResolution.x / 1920)); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_scaleFactor", 1)->methodPointer(canvasScaler, scale); } } @@ -7668,7 +9624,7 @@ namespace } else { - float scale = min(g_freeform_ui_scale_landscape, max(1, rWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); + float scale = min(g_freeform_ui_scale_landscape, max(1.0f, rWidth / ratio_horizontal) * g_freeform_ui_scale_landscape); if (roundf(dispRectWH.y * scale) != rHeight) { @@ -7744,24 +9700,6 @@ namespace errorDialog = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "PushSystemDialog", 2)(dialogData, true); } - void* CriMana_Player_SetFile_orig = nullptr; - bool CriMana_Player_SetFile_hook(Il2CppObject* _this, Il2CppObject* binder, Il2CppString* moviePath, int setMode) - { - stringstream pathStream(local::wide_u8(moviePath->start_char)); - string segment; - vector splited; - while (getline(pathStream, segment, '\\')) - { - splited.emplace_back(segment); - } - if (g_replace_assets.find(splited[splited.size() - 1]) != g_replace_assets.end()) - { - auto& replaceAsset = g_replace_assets.at(splited[splited.size() - 1]); - moviePath = il2cpp_string_new(replaceAsset.path.data()); - } - return reinterpret_cast(CriMana_Player_SetFile_orig)(_this, binder, moviePath, setMode); - } - Il2CppObject* voiceButtonTarget = nullptr; Il2CppDelegate* updateVoiceButton = nullptr; @@ -8046,12 +9984,12 @@ namespace if (defaultResolution.x < defaultResolution.y) { - float scale = min(1, max(1, defaultResolution.y / 1080) * g_freeform_ui_scale_portrait / (defaultResolution.y / 1080)); + float scale = min(1.0f, max(1.0f, defaultResolution.y / 1080) * g_freeform_ui_scale_portrait / (defaultResolution.y / 1080)); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_scaleFactor", 1)->methodPointer(canvasScaler, scale); } else { - float scale = min(1, max(1, defaultResolution.x / 1920) * g_freeform_ui_scale_landscape / (defaultResolution.x / 1920)); + float scale = min(1.0f, max(1.0f, defaultResolution.x / 1920) * g_freeform_ui_scale_landscape / (defaultResolution.x / 1920)); il2cpp_class_get_method_from_name_type(canvasScaler->klass, "set_scaleFactor", 1)->methodPointer(canvasScaler, scale); } } @@ -8388,12 +10326,12 @@ namespace wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; - wcex.hIcon = LoadIcon(hInstance, (LPCSTR)IDI_APP_ICON); + wcex.hIcon = LoadIcon(hInstance, reinterpret_cast(IDI_APP_ICON)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = reinterpret_cast(COLOR_WINDOW + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = "WebViewWindow"; - wcex.hIconSm = LoadIcon(wcex.hInstance, reinterpret_cast(0x67)); + wcex.hIconSm = LoadIcon(wcex.hInstance, reinterpret_cast(IDI_APP_ICON)); RegisterClassEx(&wcex); @@ -8586,27 +10524,185 @@ namespace const auto dmmId = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "Certification", "get_dmmViewerId", -1)(); const auto dmmOnetimeToken = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "Certification", "get_dmmOnetimeToken", -1)(); - if (dmmId && !wstring(dmmId->start_char).empty() && - dmmOnetimeToken && !wstring(dmmOnetimeToken->start_char).empty()) + if (dmmId && !wstring(dmmId->start_char).empty() && + dmmOnetimeToken && !wstring(dmmOnetimeToken->start_char).empty()) + { + reinterpret_cast(TitleViewController_OnClickPushStart_orig)(_this); + } + else + { + const auto AudioManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "AudioManager")); + + il2cpp_class_get_method_from_name_type(AudioManager->klass, "PlaySe_UIDecide", 0)->methodPointer(AudioManager); + + if (!isLoginWebViewOpen) + { + isLoginWebViewOpen = true; + + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + CreateThread(NULL, 0, reinterpret_cast(WebViewThread), NULL, NULL, NULL); + } + + } + } + + void DumpMsgPackFile(const string& file_path, const char* buffer, const size_t len) { + auto parent_path = filesystem::path(file_path).parent_path(); + if (!filesystem::exists(parent_path)) { + filesystem::create_directories(parent_path); + } + ofstream file{ file_path, ios::binary }; + file.write(buffer, static_cast(len)); + file.flush(); + file.close(); + } + + int64_t current_time() { + auto ms = chrono::duration_cast( + chrono::system_clock::now().time_since_epoch()); + return ms.count(); + } + + void* UploadHandlerRaw_Create_orig = nullptr; + + void* UploadHandlerRaw_Create_hook(Il2CppObject* self, Il2CppArraySize_t* data) + { + const char* buf = reinterpret_cast(data) + kIl2CppSizeOfArray; + + if (g_dump_msgpack && g_dump_msgpack_request) + { + string out_path = + "msgpack_dump/"s.append(to_string(current_time())).append("Q.msgpack"); + + DumpMsgPackFile(out_path, buf, data->max_length); + } + +#ifdef _DEBUG + if (g_unlock_live_chara) + { + auto modified = MsgPackModify::ModifyRequest(buf, data->max_length); + + if (!modified.empty()) + { + data = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "Byte"), modified.size()); + + char* buf1 = reinterpret_cast(data) + kIl2CppSizeOfArray; + memcpy(buf1, modified.data(), modified.size()); + } + } +#endif + + return reinterpret_cast(UploadHandlerRaw_Create_orig)(self, data); + } + + void* DownloadHandler_InternalGetByteArray_orig = nullptr; + + Il2CppArraySize_t* DownloadHandler_InternalGetByteArray_hook(Il2CppObject* self) + { + auto data = reinterpret_cast(DownloadHandler_InternalGetByteArray_orig)(self); + + const char* buf = reinterpret_cast(data) + kIl2CppSizeOfArray; + + if (g_dump_msgpack) + { + string out_path = + "msgpack_dump/"s.append(to_string(current_time())).append("R.msgpack"); + + DumpMsgPackFile(out_path, buf, data->max_length); + } + +#ifdef _DEBUG + if (g_unlock_live_chara) + { + auto modified = MsgPackModify::ModifyResponse(buf, data->max_length); + + if (!modified.empty()) + { + data = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "Byte"), modified.size()); + + char* buf1 = reinterpret_cast(data) + kIl2CppSizeOfArray; + memcpy(buf1, modified.data(), modified.size()); + } + } +#endif + + MsgPackData::ReadResponse(buf, data->max_length); + + return data; + } + + void* HttpHelper_CompressRequest_orig = nullptr; + + Il2CppArraySize_t* HttpHelper_CompressRequest_hook(Il2CppArraySize_t* data) + { + const char* buf = reinterpret_cast(data) + kIl2CppSizeOfArray; + + if (g_dump_msgpack && g_dump_msgpack_request) + { + string out_path = + "msgpack_dump/"s.append(to_string(current_time())).append("Q.msgpack"); + + DumpMsgPackFile(out_path, buf, data->max_length); + } + +#ifdef _DEBUG + if (g_unlock_live_chara) + { + auto modified = MsgPackModify::ModifyRequest(buf, data->max_length); + + if (!modified.empty()) + { + data = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "Byte"), modified.size()); + + char* buf1 = reinterpret_cast(data) + kIl2CppSizeOfArray; + memcpy(buf1, modified.data(), modified.size()); + } + } +#endif + + return reinterpret_cast(HttpHelper_CompressRequest_orig)(data); + } + + void* HttpHelper_DecompressResponse_orig = nullptr; + + Il2CppArraySize_t* HttpHelper_DecompressResponse_hook(Il2CppArraySize_t* compressed) + { + auto data = reinterpret_cast(HttpHelper_DecompressResponse_orig)(compressed); + + const char* buf = reinterpret_cast(data) + kIl2CppSizeOfArray; + + if (g_dump_msgpack) { - reinterpret_cast(TitleViewController_OnClickPushStart_orig)(_this); + string out_path = + "msgpack_dump/"s.append(to_string(current_time())).append("R.msgpack"); + + DumpMsgPackFile(out_path, buf, data->max_length); } - else - { - const auto AudioManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "AudioManager")); - il2cpp_class_get_method_from_name_type(AudioManager->klass, "PlaySe_UIDecide", 0)->methodPointer(AudioManager); +#ifdef _DEBUG + if (g_unlock_live_chara) + { + auto modified = MsgPackModify::ModifyResponse(buf, data->max_length); - if (!isLoginWebViewOpen) + if (!modified.empty()) { - isLoginWebViewOpen = true; + data = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "Byte"), modified.size()); - CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - - CreateThread(NULL, 0, reinterpret_cast(WebViewThread), NULL, NULL, NULL); + char* buf1 = reinterpret_cast(data) + kIl2CppSizeOfArray; + memcpy(buf1, modified.data(), modified.size()); } - } +#endif + + MsgPackData::ReadResponse(buf, data->max_length); + + return data; + } + + Il2CppObject* GetFrontDialog() + { + return il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogManager", "GetForeFrontDialog", -1)(); } LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam); @@ -8626,23 +10722,6 @@ namespace return CallNextHookEx(g_hCBTHook, nCode, wParam, lParam); } - void DumpMsgPackFile(const string& file_path, const char* buffer, const size_t len) { - auto parent_path = filesystem::path(file_path).parent_path(); - if (!filesystem::exists(parent_path)) { - filesystem::create_directories(parent_path); - } - ofstream file{ file_path, ios::binary }; - file.write(buffer, static_cast(len)); - file.flush(); - file.close(); - } - - string current_time() { - auto ms = chrono::duration_cast( - chrono::system_clock::now().time_since_epoch()); - return to_string(ms.count()); - } - void adjust_size() { thread([]() @@ -8720,61 +10799,6 @@ namespace uint64_t startTime; - void SetHttpFunc() - { - auto httpManager = GetSingletonInstanceByMethod(il2cpp_symbols::get_class("Cute.Http.Assembly.dll", "Cute.Http", "HttpManager")); - - auto type = il2cpp_class_from_type(il2cpp_class_get_method_from_name(httpManager->klass, "get_CompressFunc", 0)->return_type); - - auto CompressFunc = CreateDelegateWithClassStatic(type, - *([](void*, Il2CppArraySize_t* in) { - cout << "IN " << in << endl; - if (in->obj.klass->name == "Byte[]"s) - { - char* buf = reinterpret_cast(in) + kIl2CppSizeOfArray; - auto out_path = - "msgpack_dump/"s.append(current_time()).append("Q.msgpack"); - - DumpMsgPackFile(out_path, buf, in->max_length); - } - else - { - SetHttpFunc(); - return static_cast*>(nullptr); - } - - return in; - })); - - reinterpret_cast(il2cpp_class_get_method_from_name( - httpManager->klass, "set_CompressFunc", 1)->methodPointer)(httpManager, - CompressFunc); - - auto DecompressFunc = CreateDelegateWithClassStatic(type, - *([](void*, Il2CppArraySize_t* in) { - if (in->obj.klass->name == "Byte[]"s) - { - char* buf = reinterpret_cast(in) + kIl2CppSizeOfArray; - auto out_path = - "msgpack_dump/"s.append(current_time()).append("R.msgpack"); - - DumpMsgPackFile(out_path, buf, in->max_length); - } - else - { - SetHttpFunc(); - return static_cast*>(nullptr); - } - - return in; - })); - - reinterpret_cast(il2cpp_class_get_method_from_name( - httpManager->klass, "set_DecompressFunc", 1)->methodPointer)(httpManager, - DecompressFunc); - } - void path_game_assembly() { if (Game::CurrentGameRegion == Game::Region::KOR) @@ -9250,8 +11274,6 @@ namespace auto StoryViewController_ctor_addr = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "StoryViewController", ".ctor", 0); - auto CriMana_Player_SetFile_addr = il2cpp_symbols::get_method_pointer("CriMw.CriWare.Runtime.dll", "CriWare.CriMana", "Player", "SetFile", 3); - auto DialogCircleItemDonate_Initialize_addr = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogCircleItemDonate", "Initialize", 2); auto UIManager_GetCameraSizeByOrientation_addr = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "UIManager", "GetCameraSizeByOrientation", 1); @@ -9268,6 +11290,14 @@ namespace auto Certification_initDmmPlatformData_addr = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "Certification", "initDmmPlatformData", -1); + auto UploadHandlerRaw_Create_addr = il2cpp_resolve_icall("UnityEngine.Networking.UploadHandlerRaw::Create()"); + + auto DownloadHandler_InternalGetByteArray_addr = il2cpp_resolve_icall("UnityEngine.Networking.DownloadHandler::InternalGetByteArray()"); + + auto HttpHelper_CompressRequest_addr = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "HttpHelper", "CompressRequest", 1); + + auto HttpHelper_DecompressResponse_addr = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "HttpHelper", "DecompressResponse", 1); + auto load_scene_internal_addr = il2cpp_resolve_icall("UnityEngine.SceneManagement.SceneManager::LoadSceneAsyncNameIndexInternal_Injected(System.String,System.Int32,UnityEngine.SceneManagement.LoadSceneParameters&,System.bool)"); #pragma endregion @@ -9284,14 +11314,31 @@ namespace ADD_HOOK(DialogCircleItemDonate_Initialize, "Gallop.DialogCircleItemDonate::Initialize at %p\n"); - ADD_HOOK(CriMana_Player_SetFile, "CriWare.CriMana.Player::SetFile at %p\n"); - // ADD_HOOK(DialogCommon_Close, "Gallop.DialogCommon.Close() at %p\n"); // ADD_HOOK(GallopUtil_GotoTitleOnError, "Gallop.GallopUtil.GotoTitleOnError() at %p\n"); ADD_HOOK(set_shadowResolution, "UnityEngine.QualitySettings.set_shadowResolution(ShadowResolution) at %p\n"); + if (Game::CurrentGameRegion == Game::Region::KOR) + { + ADD_HOOK(DownloadHandler_InternalGetByteArray, "UnityEngine.Networking.DownloadHandler::InternalGetByteArray at %p\n"); + + if ((g_dump_msgpack && g_dump_msgpack_request) || g_unlock_live_chara) + { + ADD_HOOK(UploadHandlerRaw_Create, "UnityEngine.Networking.UploadHandlerRaw::Create at %p\n"); + } + } + else + { + ADD_HOOK(HttpHelper_DecompressResponse, "Gallop.HttpHelper::DecompressResponse at %p\n"); + + if ((g_dump_msgpack && g_dump_msgpack_request) || g_unlock_live_chara) + { + ADD_HOOK(HttpHelper_CompressRequest, "Gallop.HttpHelper::CompressRequest at %p\n"); + } + } + if (g_anisotropic_filtering != -1) { ADD_HOOK(set_anisotropicFiltering, "UnityEngine.QualitySettings.set_anisotropicFiltering(UnityEngine.AnisotropicFiltering) at %p\n"); @@ -9357,7 +11404,7 @@ namespace { try { - replacementMDB = new SQLite::Database(g_replace_text_db_path.data()); + MasterDB::InitReplacementMasterDB(g_replace_text_db_path.data()); ADD_HOOK(Plugin_sqlite3_step, "Plugin::sqlite3_step at %p\n"); ADD_HOOK(Plugin_sqlite3_reset, "Plugin::sqlite3_reset at %p\n"); ADD_HOOK(query_step, "Query::Step at %p\n"); @@ -9500,11 +11547,6 @@ namespace ADD_HOOK(rendertexture_set_anti_aliasing, "UnityEngine.RenderTexture.set_antiAliasing(int) at %p\n"); } - if (Game::CurrentGameRegion == Game::Region::KOR && false) - { - SetHttpFunc(); - } - if (!external_dlls_path.empty()) { for (int i = 0; i < external_dlls_path.size(); i++) @@ -9522,14 +11564,14 @@ namespace return; } - if (notification) + /*if (notification) { if (uobject_IsNativeObjectAlive(notification)) { il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Object", "Destroy", 1)(notification); } notification = nullptr; - } + }*/ auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); auto _noticeCanvasField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_noticeCanvas"); @@ -9571,7 +11613,6 @@ namespace il2cpp_class_get_method_from_name_type(canvasGroupTransform->klass, "set_position", 1)->methodPointer(canvasGroupTransform, position); - auto gameObject = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Component", "get_gameObject", 0)(notification); if (gameObject) { @@ -9589,6 +11630,16 @@ namespace void patch_after_criware() { + auto amuid = wstring(il2cpp_resolve_icall_type("UnityEngine.Application::get_companyName()")()->start_char) + L".Gallop"; + + DesktopNotificationManagerCompat::RegisterAumidAndComServer(amuid.data(), localize_get_hook(GetTextIdByName("Outgame0028"))->start_char); + + DesktopNotificationManagerCompat::RegisterActivator(); + + unique_ptr history; + DesktopNotificationManagerCompat::get_History(&history); + history->Clear(); + auto get_virt_size_addr = il2cpp_symbols::get_method_pointer( "umamusume.dll", "Gallop", "StandaloneWindowResize", "getOptimizedWindowSizeVirt", 2 @@ -10102,6 +12153,8 @@ namespace wcout << il2cpp_class_get_method_from_name_type(gameObject->klass, "get_tag", 0)->methodPointer(gameObject)->start_char << endl; il2cpp_class_get_method_from_name_type(gameObject->klass, "set_tag", 1)->methodPointer(gameObject, il2cpp_string_new("MainCamera"));*/ + fullScreenFl = il2cpp_resolve_icall_type("UnityEngine.Screen::get_fullScreen()")(); + if (g_discord_rich_presence) { discord::Core::Create(1080397170215223367, static_cast(discord::CreateFlags::NoRequireDiscord), &discord); @@ -10215,338 +12268,354 @@ namespace } } + auto sceneManagerClass = il2cpp_symbols::get_class("UnityEngine.CoreModule.dll", "UnityEngine.SceneManagement", "SceneManager"); - if (g_max_fps > -1 || g_unlock_size || g_freeform_window || g_discord_rich_presence || g_character_system_text_caption) - { - auto sceneManagerClass = il2cpp_symbols::get_class("UnityEngine.CoreModule.dll", "UnityEngine.SceneManagement", "SceneManager"); + auto activeSceneChangedField = il2cpp_class_get_field_from_name_wrap(sceneManagerClass, "activeSceneChanged"); - auto activeSceneChangedField = il2cpp_class_get_field_from_name_wrap(sceneManagerClass, "activeSceneChanged"); + auto action = CreateDelegateWithClassStatic(il2cpp_class_from_type(activeSceneChangedField->type), *([](void*, Scene scene, Scene scene1) + { + auto hWnd = GetHWND(); - auto action = CreateDelegateWithClassStatic(il2cpp_class_from_type(activeSceneChangedField->type), *([](void*, Scene scene, Scene scene1) + if (g_freeform_window) { - auto hWnd = GetHWND(); + long style = GetWindowLongW(hWnd, GWL_STYLE); + style |= WS_MAXIMIZEBOX; + SetWindowLongPtrW(hWnd, GWL_STYLE, style); + } - if (g_freeform_window) + isPortraitBeforeFullscreen = false; + + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + + if (g_resolution_3d_scale != 1.0f && Game::CurrentGameRegion == Game::Region::KOR) + { + auto graphicSettings = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "GraphicSettings")); + + if (graphicSettings) { - long style = GetWindowLongW(hWnd, GWL_STYLE); - style |= WS_MAXIMIZEBOX; - SetWindowLongPtrW(hWnd, GWL_STYLE, style); - } + auto _resolutionScaleField = il2cpp_class_get_field_from_name_wrap(graphicSettings->klass, "_resolutionScale"); + + il2cpp_field_set_value(graphicSettings, _resolutionScaleField, &g_resolution_3d_scale); - isPortraitBeforeFullscreen = false; + auto _resolutionScale2DField = il2cpp_class_get_field_from_name_wrap(graphicSettings->klass, "_resolutionScale2D"); - auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + il2cpp_field_set_value(graphicSettings, _resolutionScale2DField, &g_resolution_3d_scale); + } + } + if (g_graphics_quality > -1) + { auto graphicSettings = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "GraphicSettings")); if (graphicSettings) { apply_graphics_quality_hook(graphicSettings, g_graphics_quality, true); } + } - auto active = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine.SceneManagement", "SceneManager", "GetActiveScene", -1)(); + auto active = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine.SceneManagement", "SceneManager", "GetActiveScene", -1)(); - auto handleName = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine.SceneManagement", "Scene", "GetNameInternal", 1)(active.handle); + auto handleName = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine.SceneManagement", "Scene", "GetNameInternal", 1)(active.handle); - if (!handleName) - { - return; - } + if (!handleName) + { + return; + } - /*Il2CppArraySize_t* CriWareInitializerList; - if (Game::CurrentGameRegion == Game::Region::KOR) - { - CriWareInitializerList = il2cpp_resolve_icall_type*(*)(Il2CppObject*, int, int)>("UnityEngine.Object::FindObjectsByType()")( - GetRuntimeType("CriMw.CriWare.Runtime.dll", "CriWare", "CriWareInitializer"), 1, 0); - } - else + /*Il2CppArraySize_t* CriWareInitializerList; + if (Game::CurrentGameRegion == Game::Region::KOR) + { + CriWareInitializerList = il2cpp_resolve_icall_type*(*)(Il2CppObject*, int, int)>("UnityEngine.Object::FindObjectsByType()")( + GetRuntimeType("CriMw.CriWare.Runtime.dll", "CriWare", "CriWareInitializer"), 1, 0); + } + else + { + CriWareInitializerList = il2cpp_resolve_icall_type*(*)(Il2CppObject*, bool)>("UnityEngine.Object::FindObjectsOfType()")( + GetRuntimeType("CriMw.CriWare.Runtime.dll", "CriWare", "CriWareInitializer"), true); + } + + if (CriWareInitializerList && CriWareInitializerList->max_length) + { + auto obj = CriWareInitializerList->vector[0]; + auto useDecrypterField = il2cpp_class_get_field_from_name_wrap(obj->klass, "useDecrypter"); + bool useDecrypter; + il2cpp_field_get_value(obj, useDecrypterField, &useDecrypter); + + cout << "useDecrypter " << boolalpha << useDecrypter << noboolalpha << endl; + + if (useDecrypter) { - CriWareInitializerList = il2cpp_resolve_icall_type*(*)(Il2CppObject*, bool)>("UnityEngine.Object::FindObjectsOfType()")( - GetRuntimeType("CriMw.CriWare.Runtime.dll", "CriWare", "CriWareInitializer"), true); + auto decrypterConfigField = il2cpp_class_get_field_from_name_wrap(obj->klass, "decrypterConfig"); + Il2CppObject* decrypterConfig; + il2cpp_field_get_value(obj, decrypterConfigField, &decrypterConfig); + + if (decrypterConfig) + { + auto keyField = il2cpp_class_get_field_from_name_wrap(decrypterConfig->klass, "key"); + Il2CppString* key; + il2cpp_field_get_value(decrypterConfig, keyField, &key); + + cout << "key: " << local::wide_u8(key->start_char) << endl; + } } + }*/ - if (CriWareInitializerList && CriWareInitializerList->max_length) - { - auto obj = CriWareInitializerList->vector[0]; - auto useDecrypterField = il2cpp_class_get_field_from_name_wrap(obj->klass, "useDecrypter"); - bool useDecrypter; - il2cpp_field_get_value(obj, useDecrypterField, &useDecrypter); + string sceneName = local::wide_u8(handleName->start_char); - cout << "useDecrypter " << boolalpha << useDecrypter << noboolalpha << endl; + if (sceneName == "Title") + { + if (g_freeform_window && Game::CurrentGameRegion == Game::Region::KOR) + { + static bool initialResize = false; - if (useDecrypter) - { - auto decrypterConfigField = il2cpp_class_get_field_from_name_wrap(obj->klass, "decrypterConfig"); - Il2CppObject* decrypterConfig; - il2cpp_field_get_value(obj, decrypterConfigField, &decrypterConfig); + if (!initialResize) { + initialResize = true; - if (decrypterConfig) - { - auto keyField = il2cpp_class_get_field_from_name_wrap(decrypterConfig->klass, "key"); - Il2CppString* key; - il2cpp_field_get_value(decrypterConfig, keyField, &key); + auto hWnd = GetHWND(); - cout << "key: " << local::wide_u8(key->start_char) << endl; - } + RECT windowRect; + GetWindowRect(hWnd, &windowRect); + int windowWidth = windowRect.right - windowRect.left, + windowHeight = windowRect.bottom - windowRect.top; + resizeWindow(hWnd, windowWidth, windowHeight); } - }*/ + } - string sceneName = local::wide_u8(handleName->start_char); + if (g_character_system_text_caption) + { + isRequiredInitNotification = true; + } - if (sceneName == "Title") + if (g_max_fps > -1 || g_unlock_size || g_freeform_window) { - if (Game::CurrentGameRegion == Game::Region::KOR) + if (isWndProcInitRequired) { - static bool initialResize = false; + isWndProcInitRequired = false; + auto StandaloneWindowResize = il2cpp_symbols::get_class("umamusume.dll", "Gallop", "StandaloneWindowResize"); + WNDPROC oldWndProcPtr = nullptr; + WNDPROC newWndProcPtr = nullptr; - if (!initialResize) { - initialResize = true; + auto oldWndProcPtrField = il2cpp_class_get_field_from_name_wrap(StandaloneWindowResize, "oldWndProcPtr"); + auto newWndProcPtrField = il2cpp_class_get_field_from_name_wrap(StandaloneWindowResize, "newWndProcPtr"); + il2cpp_field_static_get_value(oldWndProcPtrField, &oldWndProcPtr); + il2cpp_field_static_get_value(newWndProcPtrField, &newWndProcPtr); - auto hWnd = GetHWND(); + reinterpret_cast(SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast(oldWndProcPtr))); + auto oldWndProcPtr2 = reinterpret_cast(SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast(wndproc_hook))); + il2cpp_field_static_set_value(oldWndProcPtrField, &oldWndProcPtr2); - RECT windowRect; - GetWindowRect(hWnd, &windowRect); - int windowWidth = windowRect.right - windowRect.left, - windowHeight = windowRect.bottom - windowRect.top; - resizeWindow(hWnd, windowWidth, windowHeight); + if ((g_unlock_size || g_freeform_window) && g_initial_width > 72 && g_initial_height > 72) + { + if (g_initial_width < g_initial_height) + { + reinterpret_cast(set_resolution_orig)(last_virt_window_width, last_virt_window_height, 3, 0); + } + else + { + reinterpret_cast(set_resolution_orig)(last_hriz_window_width, last_hriz_window_height, 3, 0); + } } } - if (g_character_system_text_caption) + if (uiManager) { - isRequiredInitNotification = true; + auto _bgCameraField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_bgCamera"); + Il2CppObject* _bgCamera; + il2cpp_field_get_value(uiManager, _bgCameraField, &_bgCamera); + + /*il2cpp_class_get_method_from_name_type(_bgCamera->klass, "set_backgroundColor", 1)->methodPointer(_bgCamera, + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Color", "get_clear", -1)());*/ } + } - if (g_max_fps > -1 || g_unlock_size || g_freeform_window) - { - if (isWndProcInitRequired) + if (Game::CurrentGameRegion == Game::Region::KOR) + { + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + updateVoiceButton = CreateDelegateWithClass(il2cpp_symbols::get_class("DOTween.dll", "DG.Tweening", "TweenCallback"), uiManager, *([](Il2CppObject* _this) { - isWndProcInitRequired = false; - auto StandaloneWindowResize = il2cpp_symbols::get_class("umamusume.dll", "Gallop", "StandaloneWindowResize"); - WNDPROC oldWndProcPtr = nullptr; - WNDPROC newWndProcPtr = nullptr; + UpdateVoiceButton(); + il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, updateVoiceButton, true); + })); - auto oldWndProcPtrField = il2cpp_class_get_field_from_name_wrap(StandaloneWindowResize, "oldWndProcPtr"); - auto newWndProcPtrField = il2cpp_class_get_field_from_name_wrap(StandaloneWindowResize, "newWndProcPtr"); - il2cpp_field_static_get_value(oldWndProcPtrField, &oldWndProcPtr); - il2cpp_field_static_get_value(newWndProcPtrField, &newWndProcPtr); + // Delay 50ms + il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, updateVoiceButton, true); + } - reinterpret_cast(SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast(oldWndProcPtr))); - auto oldWndProcPtr2 = reinterpret_cast(SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast(wndproc_hook))); - il2cpp_field_static_set_value(oldWndProcPtrField, &oldWndProcPtr2); + if (g_freeform_window) + { + int width = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_width", -1)(); + int height = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_height", -1)(); - if ((g_unlock_size || g_freeform_window) && g_initial_width > 72 && g_initial_height > 72) - { - if (g_initial_width < g_initial_height) - { - reinterpret_cast(set_resolution_orig)(last_virt_window_width, last_virt_window_height, 3, 0); - } - else - { - reinterpret_cast(set_resolution_orig)(last_hriz_window_width, last_hriz_window_height, 3, 0); - } - } - } + bool isVirt = width < height; + il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "StandaloneWindowResize", "set_IsVirt", 1)(isVirt); - if (uiManager) + auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); + moviePlayerResize = CreateDelegateWithClassStatic(il2cpp_symbols::get_class("DOTween.dll", "DG.Tweening", "TweenCallback"), *([]() { - auto _bgCameraField = il2cpp_class_get_field_from_name_wrap(uiManager->klass, "_bgCamera"); - Il2CppObject* _bgCamera; - il2cpp_field_get_value(uiManager, _bgCameraField, &_bgCamera); + ResizeMoviePlayer(); + il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, moviePlayerResize, true); + })); - /*il2cpp_class_get_method_from_name_type(_bgCamera->klass, "set_backgroundColor", 1)->methodPointer(_bgCamera, - il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Color", "get_clear", -1)());*/ - } - } + // Delay 50ms + il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, moviePlayerResize, true); + } - if (Game::CurrentGameRegion == Game::Region::KOR) - { - auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); - updateVoiceButton = CreateDelegateWithClass(il2cpp_symbols::get_class("DOTween.dll", "DG.Tweening", "TweenCallback"), uiManager, *([](Il2CppObject* _this) - { - UpdateVoiceButton(); - il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, updateVoiceButton, true); - })); + if (uiManager && (g_unlock_size || g_freeform_window)) + { + int width = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_width", -1)(); + int height = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_height", -1)(); - // Delay 50ms - il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, updateVoiceButton, true); - } + bool isVirt = width < height; if (g_freeform_window) { - int width = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_width", -1)(); - int height = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_height", -1)(); - - bool isVirt = width < height; - il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "StandaloneWindowResize", "set_IsVirt", 1)(isVirt); - - auto uiManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "UIManager")); - moviePlayerResize = CreateDelegateWithClassStatic(il2cpp_symbols::get_class("DOTween.dll", "DG.Tweening", "TweenCallback"), *([]() - { - ResizeMoviePlayer(); - il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, moviePlayerResize, true); - })); - - // Delay 50ms - il2cpp_symbols::get_method_pointer("DOTween.dll", "DG.Tweening", "DOVirtual", "DelayedCall", 3)(0.05, moviePlayerResize, true); + UIManager_ChangeResizeUIForPC_hook(uiManager, isVirt ? min(last_virt_window_width, last_virt_window_height) : max(last_hriz_window_width, last_hriz_window_height), + isVirt ? max(last_virt_window_width, last_virt_window_height) : min(last_hriz_window_width, last_hriz_window_height)); } - - if (uiManager && (g_unlock_size || g_freeform_window)) + else { - int width = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_width", -1)(); - int height = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Screen", "get_height", -1)(); - - bool isVirt = width < height; - - if (g_freeform_window) - { - UIManager_ChangeResizeUIForPC_hook(uiManager, isVirt ? min(last_virt_window_width, last_virt_window_height) : max(last_hriz_window_width, last_hriz_window_height), - isVirt ? max(last_virt_window_width, last_virt_window_height) : min(last_hriz_window_width, last_hriz_window_height)); - } - else - { - UIManager_ChangeResizeUIForPC_hook(uiManager, isVirt ? min(last_display_width, last_display_height) : max(last_display_width, last_display_height), - isVirt ? max(last_display_width, last_display_height) : min(last_display_width, last_display_height)); - } + UIManager_ChangeResizeUIForPC_hook(uiManager, isVirt ? min(last_display_width, last_display_height) : max(last_display_width, last_display_height), + isVirt ? max(last_display_width, last_display_height) : min(last_display_width, last_display_height)); } } + } - if (sceneName == "Home") + if (sceneName == "Home") + { + if (g_character_system_text_caption) { - if (g_character_system_text_caption) - { - InitNotification(); - } + InitNotification(); + } - thread([]() - { - auto t = il2cpp_thread_attach(il2cpp_domain_get()); + auto readDisclaimer = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "PlayerPrefs", "GetInt", 2)(il2cpp_string_new("ReadDisclaimer"), 0); - while (true) - { - Sleep(100); - __try + if (!readDisclaimer) + { + il2cpp_symbols::get_method_pointer + ("umamusume.dll", "Gallop", "DialogSimpleCheckNoWarning", "OpenMiddleOneButton", 9)(localize_get_hook(GetTextIdByName("Common0081")), il2cpp_string_new( + (LocalifySettings::GetText("initial_disclaimer_1") + local::wide_u8(localize_get_hook(GetTextIdByName("Common187002"))->start_char) + LocalifySettings::GetText("initial_disclaimer_2")).data()), + localize_get_hook(GetTextIdByName("Common187002")), GetTextIdByName("Common0007"), + CreateDelegateStatic(*[](void*, Il2CppObject* dialog) { - Il2CppArraySize_t* CharacterHomeTopUIList; - if (Game::CurrentGameRegion == Game::Region::KOR) - { - CharacterHomeTopUIList = il2cpp_resolve_icall_type*(*)(Il2CppObject*, int, int)>("UnityEngine.Object::FindObjectsByType()")( - GetRuntimeType("umamusume.dll", "Gallop", "CharacterHomeTopUI"), 1, 0); - } - else - { - CharacterHomeTopUIList = il2cpp_resolve_icall_type*(*)(Il2CppObject*, bool)>("UnityEngine.Object::FindObjectsOfType()")( - GetRuntimeType("umamusume.dll", "Gallop", "CharacterHomeTopUI"), true); - } + il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "DialogCommon", "Close", 0)(GetFrontDialog()); + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "PlayerPrefs", "SetInt", 2)(il2cpp_string_new("ReadDisclaimer"), 1); + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "PlayerPrefs", "Save", -1); + }), nullptr, false, true, nullptr); + } - for (int i = 0; i < CharacterHomeTopUIList->max_length; i++) - { - auto CharacterHomeTopUI = CharacterHomeTopUIList->vector[i]; - if (CharacterHomeTopUI) - { - auto _cardRootButtonField = il2cpp_class_get_field_from_name_wrap(CharacterHomeTopUI->klass, "_cardRootButton"); - Il2CppObject* _cardRootButton; - il2cpp_field_get_value(CharacterHomeTopUI, _cardRootButtonField, &_cardRootButton); + if (g_unlock_live_chara) + { + auto charaList = MsgPackModify::GetCharaList(); - if (_cardRootButton) - { - auto targetText = il2cpp_class_get_method_from_name_type(_cardRootButton->klass, "get_TargetText", 0)->methodPointer(_cardRootButton); + auto workDataManager = GetSingletonInstance(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "WorkDataManager")); - if (targetText) - { - text_set_horizontalOverflow(targetText, 1); - text_set_verticalOverflow(targetText, 1); + auto workCharaData = il2cpp_class_get_method_from_name_type(workDataManager->klass, "get_CharaData", 0)->methodPointer(workDataManager); - il2cpp_thread_detach(t); - return; - } - } - } - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - } + auto UserCharaClass = il2cpp_symbols::get_class("umamusume.Http.dll", "Gallop", "UserChara"); + + for (auto& chara : charaList) + { + auto userChara = il2cpp_object_new(UserCharaClass); - }).detach(); + auto chara_id_field = il2cpp_class_get_field_from_name_wrap(userChara->klass, "chara_id"); + int chara_id = chara["chara_id"].int32_value(); + il2cpp_field_set_value(userChara, chara_id_field, &chara_id); + + auto training_num_field = il2cpp_class_get_field_from_name_wrap(userChara->klass, "training_num"); + int training_num = chara["training_num"].int32_value(); + il2cpp_field_set_value(userChara, training_num_field, &training_num); + + auto love_point_field = il2cpp_class_get_field_from_name_wrap(userChara->klass, "love_point"); + int love_point = chara["love_point"].int32_value(); + il2cpp_field_set_value(userChara, love_point_field, &love_point); + + auto love_point_pool_field = il2cpp_class_get_field_from_name_wrap(userChara->klass, "love_point_pool"); + int love_point_pool = chara["love_point_pool"].int32_value(); + il2cpp_field_set_value(userChara, love_point_pool_field, &love_point_pool); + + auto fan_field = il2cpp_class_get_field_from_name_wrap(userChara->klass, "fan"); + uint64_t fan = chara["fan"].uint64_value(); + il2cpp_field_set_value(userChara, fan_field, &fan); + + il2cpp_class_get_method_from_name_type(workCharaData->klass, "UpdateCharaData", 1)->methodPointer(workCharaData, userChara); + } } + } + + if (sceneName == "Live" && g_champions_live_show_text) + { + auto loadSettings = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop.Live", "Director", "get_LoadSettings", -1)(); + auto musicId = il2cpp_class_get_method_from_name_type(loadSettings->klass, "get_MusicId", 0)->methodPointer(loadSettings); - if (sceneName == "Live" && g_champions_live_show_text) + if (musicId == 1054) { - auto loadSettings = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop.Live", "Director", "get_LoadSettings", -1)(); - auto musicId = il2cpp_class_get_method_from_name_type(loadSettings->klass, "get_MusicId", 0)->methodPointer(loadSettings); + auto raceInfo = il2cpp_class_get_method_from_name_type(loadSettings->klass, "get_raceInfo", 0)->methodPointer(loadSettings); - if (musicId == 1054) - { - auto raceInfo = il2cpp_class_get_method_from_name_type(loadSettings->klass, "get_raceInfo", 0)->methodPointer(loadSettings); + auto resourceId = il2cpp_class_get_method_from_name_type(raceInfo->klass, "get_ChampionsMeetingResourceId", 0)->methodPointer(raceInfo); - auto resourceId = il2cpp_class_get_method_from_name_type(raceInfo->klass, "get_ChampionsMeetingResourceId", 0)->methodPointer(raceInfo); + if (resourceId == 0) + { + auto charaNameArray = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "String"), 9); + auto trainerNameArray = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "String"), 9); - if (resourceId == 0) - { - auto charaNameArray = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "String"), 9); - auto trainerNameArray = il2cpp_array_new_type(il2cpp_symbols::get_class("mscorlib.dll", "System", "String"), 9); + il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_CharacterNameArray", 1)->methodPointer(raceInfo, charaNameArray); + il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_TrainerNameArray", 1)->methodPointer(raceInfo, trainerNameArray); - il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_CharacterNameArray", 1)->methodPointer(raceInfo, charaNameArray); - il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_TrainerNameArray", 1)->methodPointer(raceInfo, trainerNameArray); + il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_CharacterNameArrayForChampionsText", 1)->methodPointer(raceInfo, nullptr); + il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_TrainerNameArrayForChampionsText", 1)->methodPointer(raceInfo, nullptr); - il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_CharacterNameArrayForChampionsText", 1)->methodPointer(raceInfo, nullptr); - il2cpp_class_get_method_from_name_type*)>(raceInfo->klass, "set_TrainerNameArrayForChampionsText", 1)->methodPointer(raceInfo, nullptr); + auto charaInfoList = il2cpp_class_get_method_from_name_type(loadSettings->klass, "get_CharacterInfoList", 0)->methodPointer(loadSettings); - auto charaInfoList = il2cpp_class_get_method_from_name_type(loadSettings->klass, "get_CharacterInfoList", 0)->methodPointer(loadSettings); + FieldInfo* itemsField = il2cpp_class_get_field_from_name_wrap(charaInfoList->klass, "_items"); + Il2CppArraySize_t* charaInfoArr; + il2cpp_field_get_value(charaInfoList, itemsField, &charaInfoArr); - FieldInfo* itemsField = il2cpp_class_get_field_from_name_wrap(charaInfoList->klass, "_items"); - Il2CppArraySize_t* charaInfoArr; - il2cpp_field_get_value(charaInfoList, itemsField, &charaInfoArr); + for (int i = 0; i < 9; i++) + { + auto info = charaInfoArr->vector[i]; + auto charaId = il2cpp_class_get_method_from_name_type(info->klass, "get_CharaId", 0)->methodPointer(info); + auto mobId = il2cpp_class_get_method_from_name_type(info->klass, "get_MobId", 0)->methodPointer(info); - for (int i = 0; i < 9; i++) + Il2CppString* charaName; + if (charaId == 1) { - auto info = charaInfoArr->vector[i]; - auto charaId = il2cpp_class_get_method_from_name_type(info->klass, "get_CharaId", 0)->methodPointer(info); - auto mobId = il2cpp_class_get_method_from_name_type(info->klass, "get_MobId", 0)->methodPointer(info); - - Il2CppString* charaName; - if (charaId == 1) - { - charaName = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "TextUtil", "GetMasterText", 2)(59, mobId); - } - else - { - charaName = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "TextUtil", "GetMasterText", 2)(6, charaId); - } - - il2cpp_array_setref(charaNameArray, i, charaName); - il2cpp_array_setref(trainerNameArray, i, il2cpp_string_new("")); + charaName = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "TextUtil", "GetMasterText", 2)(59, mobId); + } + else + { + charaName = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "TextUtil", "GetMasterText", 2)(6, charaId); } - il2cpp_class_get_method_from_name_type(raceInfo->klass, "set_ChampionsMeetingResourceId", 1)->methodPointer(raceInfo, g_champions_live_resource_id); - il2cpp_class_get_method_from_name_type(raceInfo->klass, "set_DateYear", 1)->methodPointer(raceInfo, g_champions_live_year); + il2cpp_array_setref(charaNameArray, i, charaName); + il2cpp_array_setref(trainerNameArray, i, il2cpp_string_new("")); } + + il2cpp_class_get_method_from_name_type(raceInfo->klass, "set_ChampionsMeetingResourceId", 1)->methodPointer(raceInfo, g_champions_live_resource_id); + il2cpp_class_get_method_from_name_type(raceInfo->klass, "set_DateYear", 1)->methodPointer(raceInfo, g_champions_live_year); } } + } - if (g_discord_rich_presence && discord) - { - auto detail = GetSceneName(sceneName); + if (g_discord_rich_presence && discord) + { + auto detail = GetSceneName(sceneName); - discord::Activity activity{}; - activity.GetAssets().SetLargeImage("umamusume"); - activity.SetDetails(detail.data()); - activity.GetTimestamps().SetStart(startTime); - if (sceneName == "Live"s) - { - activity.SetType(discord::ActivityType::Watching); - } - else - { - activity.SetType(discord::ActivityType::Playing); - } - discord->ActivityManager().UpdateActivity(activity, [](discord::Result res) {}); + discord::Activity activity{}; + activity.GetAssets().SetLargeImage("umamusume"); + activity.SetDetails(detail.data()); + activity.GetTimestamps().SetStart(startTime); + if (sceneName == "Live"s) + { + activity.SetType(discord::ActivityType::Watching); } - }) - ); - il2cpp_field_static_set_value(activeSceneChangedField, action); - } + else + { + activity.SetType(discord::ActivityType::Playing); + } + discord->ActivityManager().UpdateActivity(activity, [](discord::Result res) {}); + } + }) + ); + il2cpp_field_static_set_value(activeSceneChangedField, action); } } diff --git a/src/hook.h b/src/hook.h new file mode 100644 index 0000000..93af091 --- /dev/null +++ b/src/hook.h @@ -0,0 +1,8 @@ +#include "il2cpp/il2cpp_symbols.hpp" + +namespace +{ + Il2CppObject* GetRuntimeType(const char* assemblyName, const char* namespaze, const char* klassName); + Il2CppObject* GetSingletonInstance(Il2CppClass* klass); + Il2CppObject* GetSingletonInstanceByMethod(Il2CppClass* klass); +} diff --git a/src/il2cpp/il2cpp-api-functions.hpp b/src/il2cpp/il2cpp-api-functions.hpp index d08a982..2333ac3 100644 --- a/src/il2cpp/il2cpp-api-functions.hpp +++ b/src/il2cpp/il2cpp-api-functions.hpp @@ -1,4 +1,7 @@ #pragma once + +#include + template T il2cpp_resolve_icall_type(const char* name) { return reinterpret_cast(il2cpp_resolve_icall(name)); diff --git a/src/il2cpp/il2cpp_symbols.hpp b/src/il2cpp/il2cpp_symbols.hpp index 2abb81d..6d9af95 100644 --- a/src/il2cpp/il2cpp_symbols.hpp +++ b/src/il2cpp/il2cpp_symbols.hpp @@ -1,5 +1,11 @@ #pragma once +#define NOMINMAX + +#include + +#include + #if _MSC_VER typedef wchar_t Il2CppChar; #elif __has_feature(cxx_unicode_literals) @@ -485,6 +491,13 @@ typedef struct Il2CppException Il2CppArraySize* native_trace_ips; } Il2CppException; +template +struct Nullable +{ + T value; + bool has_value; +}; + template struct Entry { @@ -654,6 +667,33 @@ struct OrderBlock Il2CppDelegate* callback; }; +struct ObscuredBool +{ + uint8_t currentCryptoKey; + int hiddenValue; + bool inited; + bool fakeValue; + bool fakeValueActive; +}; + +struct ObscuredInt +{ + int currentCryptoKey; + int hiddenValue; + bool inited; + int fakeValue; + bool fakeValueActive; +}; + +struct ObscuredString +{ + Il2CppString* currentCryptoKey; + Il2CppArraySize_t* hiddenValue; + bool inited; + Il2CppString* fakeValue; + bool fakeValueActive; +}; + // function types typedef Il2CppString* (*il2cpp_string_new_utf16_t)(const wchar_t* str, unsigned int len); typedef Il2CppString* (*il2cpp_string_new_t)(const char* str); diff --git a/src/local/local.hpp b/src/local/local.hpp index 0f25e32..98dc812 100644 --- a/src/local/local.hpp +++ b/src/local/local.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include "il2cpp/il2cpp_symbols.hpp" + namespace local { std::string wide_u8(const std::wstring& str); diff --git a/src/main.cpp b/src/main.cpp index 1dec9d8..028ad59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,6 +57,11 @@ bool g_hide_now_loading = false; bool g_discord_rich_presence = false; bool g_allow_delete_cookie = false; bool g_localify_settings_force_korean = false; +bool g_dump_msgpack = false; +bool g_dump_msgpack_request = false; +bool g_unlock_live_chara = false; +bool g_notification_tp = false; +bool g_notification_rp = false; std::string text_id_dict; @@ -259,21 +264,21 @@ namespace { g_anti_aliasing = document["antiAliasing"].GetInt(); std::vector options = { 0, 2, 4, 8, -1 }; - g_anti_aliasing = std::find(options.begin(), options.end(), g_anti_aliasing) - options.begin(); + g_anti_aliasing = options[std::find(options.begin(), options.end(), g_anti_aliasing) - options.begin()]; } if (document.HasMember("anisotropicFiltering")) { g_anisotropic_filtering = document["anisotropicFiltering"].GetInt(); std::vector options = { 0, 1, 2, -1 }; - g_anisotropic_filtering = std::find(options.begin(), options.end(), g_anisotropic_filtering) - options.begin(); + g_anisotropic_filtering = options[std::find(options.begin(), options.end(), g_anisotropic_filtering) - options.begin()]; } if (document.HasMember("vSyncCount")) { g_vsync_count = document["vSyncCount"].GetInt(); std::vector options = { 0, 1, 2, 3, 4, -1 }; - g_vsync_count = std::find(options.begin(), options.end(), g_vsync_count) - options.begin(); + g_vsync_count = options[std::find(options.begin(), options.end(), g_vsync_count) - options.begin()]; } if (document.HasMember("uiLoadingShowOrientationGuide")) @@ -400,7 +405,7 @@ namespace { g_cyspring_update_mode = document["cySpringUpdateMode"].GetInt(); std::vector options = { 0, 1, 2, 3, -1 }; - g_cyspring_update_mode = std::find(options.begin(), options.end(), g_cyspring_update_mode) - options.begin(); + g_cyspring_update_mode = options[std::find(options.begin(), options.end(), g_cyspring_update_mode) - options.begin()]; } else if (g_max_fps > 30) { @@ -450,6 +455,31 @@ namespace g_localify_settings_force_korean = document["localifySettingsForceKorean"].GetBool(); } + if (document.HasMember("dumpMsgPack")) + { + g_dump_msgpack = document["dumpMsgPack"].GetBool(); + } + + if (document.HasMember("dumpMsgPackRequest")) + { + g_dump_msgpack_request = document["dumpMsgPackRequest"].GetBool(); + } + + if (document.HasMember("unlockLiveChara")) + { + g_unlock_live_chara = document["unlockLiveChara"].GetBool(); + } + + if (document.HasMember("notificationTp")) + { + g_notification_tp = document["notificationTp"].GetBool(); + } + + if (document.HasMember("notificationRp")) + { + g_notification_rp = document["notificationRp"].GetBool(); + } + if (document.HasMember("dicts") && document["dicts"].IsArray()) { auto array = document["dicts"].GetArray(); diff --git a/src/masterdb/masterdb.hpp b/src/masterdb/masterdb.hpp new file mode 100644 index 0000000..b42260d --- /dev/null +++ b/src/masterdb/masterdb.hpp @@ -0,0 +1,96 @@ +#pragma once +#include + +#include "il2cpp/il2cpp_symbols.hpp" +#include "local/local.hpp" +#include "game.hpp" + +namespace MasterDB +{ + SQLite::Database* replacementMasterDB; + SQLite::Database* masterDB; + SQLite::Database* metaDB; + + string masterDBPath; + + void InitMasterDB() + { + auto path = local::wide_u8(il2cpp_symbols::get_method_pointer("Cute.Core.Assembly.dll", "Cute.Core", "Device", "GetPersistentDataPath", -1)()->start_char); + auto metaDBPath = path + R"(\meta)"; + masterDBPath = path + R"(\master\master.mdb)"; + + metaDB = new SQLite::Database(":memory:", SQLite::OPEN_READWRITE); + metaDB->backup(metaDBPath.data(), SQLite::Database::Load); + + masterDB = new SQLite::Database(":memory:", SQLite::OPEN_READWRITE); + masterDB->backup(masterDBPath.data(), SQLite::Database::Load); + } + + void InitReplacementMasterDB(string path) + { + replacementMasterDB = new SQLite::Database(path.data(), SQLite::OPEN_READONLY); + } + + void ReloadMasterDB() + { + masterDB->backup(masterDBPath.data(), SQLite::Database::Load); + } + + vector GetChampionsResources() + { + if (!masterDB) + { + InitMasterDB(); + } + + vector pairs; + + auto statement = new SQLite::Statement(*masterDB, R"(SELECT c.resource_id, t.text FROM champions_schedule c LEFT OUTER JOIN text_data t on t.category = 206 AND t."index" = c.id GROUP BY c.resource_id)"); + + while (statement->executeStep()) + { + pairs.emplace_back(statement->getColumn(1).getString()); + } + + delete statement; + + return pairs; + } + + string GetTextData(int category, int index) + { + if (!masterDB) + { + InitMasterDB(); + } + + if (replacementMasterDB) + { + auto statement = new SQLite::Statement(*replacementMasterDB, R"(SELECT text FROM text_data WHERE "category" = ?1 AND "index" = ?2)"); + statement->bind(1, category); + statement->bind(2, index); + + while (statement->executeStep()) + { + auto text = statement->getColumn(0).getString(); + delete statement; + return text; + } + } + + auto statement = new SQLite::Statement(*masterDB, R"(SELECT text FROM text_data WHERE "category" = ?1 AND "index" = ?2)"); + statement->bind(1, category); + statement->bind(2, index); + + while (statement->executeStep()) + { + auto text = statement->getColumn(0).getString(); + delete statement; + return text; + } + + delete statement; + + return ""; + } +} diff --git a/src/msgpack/msgpack_data.hpp b/src/msgpack/msgpack_data.hpp new file mode 100644 index 0000000..44b8668 --- /dev/null +++ b/src/msgpack/msgpack_data.hpp @@ -0,0 +1,259 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "il2cpp/il2cpp_symbols.hpp" +#include "il2cpp/il2cpp-api-functions.hpp" +#include "local/local.hpp" +#include "game.hpp" + +#include "masterdb/masterdb.hpp" + +#include "hook.h" + +#include "notification/DesktopNotificationManagerCompat.h" + +using namespace std; +using namespace msgpack11; +using namespace Microsoft::WRL; + +extern bool g_notification_tp; +extern bool g_notification_rp; + +namespace MsgPackData +{ + MsgPack::object user_info; + + MsgPack::object tp_info; + MsgPack::object rp_info; + + Il2CppString* GetIconPath(int unitId) + { + return il2cpp_class_get_method_from_name_type(il2cpp_symbols::get_class("umamusume.dll", "Gallop", "PushNotificationManager"), "createFavIconFilePath", 1)->methodPointer(nullptr, unitId); + } + + void DumpTexture2D(int unitId, Il2CppObject* texture) + { + auto width = il2cpp_class_get_method_from_name_type(texture->klass, "get_width", 0)->methodPointer(texture); + + auto height = il2cpp_class_get_method_from_name_type(texture->klass, "get_height", 0)->methodPointer(texture); + + auto renderTexture = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "RenderTexture", "GetTemporary", 4)(width, height, 0, 0); + + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "Graphics", "Blit", 2)(texture, renderTexture); + + auto previous = il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "RenderTexture", "get_active", -1)(); + + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "RenderTexture", "set_active", 1)(renderTexture); + + auto readableTexture = il2cpp_object_new(il2cpp_symbols::get_class("UnityEngine.CoreModule.dll", "UnityEngine", "Texture2D")); + il2cpp_class_get_method_from_name_type(readableTexture->klass, ".ctor", 2)->methodPointer(readableTexture, width, height); + + il2cpp_class_get_method_from_name_type(readableTexture->klass, "ReadPixels", 3)->methodPointer(readableTexture, Rect_t{ 0, 0, static_cast(width), static_cast(height) }, 0, 0); + il2cpp_class_get_method_from_name_type(readableTexture->klass, "Apply", 0)->methodPointer(readableTexture); + + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "RenderTexture", "set_active", 1)(previous); + + il2cpp_symbols::get_method_pointer("UnityEngine.CoreModule.dll", "UnityEngine", "RenderTexture", "ReleaseTemporary", 1)(renderTexture); + + auto method = il2cpp_symbols::get_method("UnityEngine.ImageConversionModule.dll", "UnityEngine", "ImageConversion", "EncodeToPNG", 1); + + void** params = new void* [1]; + params[0] = readableTexture; + + Il2CppException* exception; + + auto pngData = reinterpret_cast*>(il2cpp_runtime_invoke(method, nullptr, params, &exception)); + + if (exception) + { + il2cpp_raise_exception(exception); + return; + } + + auto wPath = GetIconPath(unitId); + auto path = local::wide_u8(wPath->start_char); + auto parentDir = filesystem::path(path).parent_path(); + + if (!filesystem::exists(parentDir)) + { + filesystem::create_directories(parentDir); + } + + il2cpp_symbols::get_method_pointer*)>("mscorlib.dll", "System.IO", "File", "WriteAllBytes", 2)(il2cpp_string_new(path.data()), pngData); + } + + void RegisterTPScheduledToast() + { + if (!MsgPackData::user_info.empty() || !MsgPackData::tp_info.empty()) + { + int leader_chara_id = MsgPackData::user_info["leader_chara_id"].int_value(); + int leader_chara_dress_id = MsgPackData::user_info["leader_chara_dress_id"].int_value(); + + auto old_str = to_string(leader_chara_dress_id); + size_t n_zero = 6; + auto new_str = std::string(n_zero - std::min(n_zero, old_str.length()), '0') + old_str; + + auto push_icon = "push_icon_"s + to_string(leader_chara_id) + "_" + new_str; + auto path = "chara/chr"s + to_string(leader_chara_id) + "/" + push_icon; + + auto loader = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "AssetManager", "get_Loader", -1)(); + auto asset = il2cpp_class_get_method_from_name_type(loader->klass, "LoadAssetHandle", 2)->methodPointer(loader, il2cpp_string_new(path.data()), false); + auto assetBundle = il2cpp_class_get_method_from_name_type(asset->klass, "get_assetBundle", 0)->methodPointer(asset); + + auto texture2DType = reinterpret_cast(::GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "Texture2D")); + auto texture2D = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.AssetBundle::LoadAsset_Internal(System.String,System.Type)"))(assetBundle, il2cpp_string_new(push_icon.data()), texture2DType); + + DumpTexture2D(leader_chara_id, texture2D); + + if (g_notification_tp) + { + // unique_ptr history; + // DesktopNotificationManagerCompat::get_History(&history); + + if ((!MsgPackData::user_info.empty() || !MsgPackData::tp_info.empty()) && g_notification_tp) + { + DesktopNotificationManagerCompat::RemoveFromScheduleByTag(L"TP"); + auto title = local::u8_wide(MasterDB::GetTextData(6, leader_chara_id)); + auto content = local::u8_wide(MasterDB::GetTextData(184, leader_chara_id)); + // history->RemoveGroupedTag(L"TP", L"Generic"); + DesktopNotificationManagerCompat::AddScheduledToastNotification(title.data(), content.data(), L"TP", GetIconPath(leader_chara_id)->start_char, MsgPackData::tp_info["max_recovery_time"].int64_value() * 1000); + } + } + } + } + + void RegisterRPScheduledToast() + { + if (!MsgPackData::user_info.empty() || !MsgPackData::rp_info.empty()) + { + int leader_chara_id = MsgPackData::user_info["leader_chara_id"].int_value(); + int leader_chara_dress_id = MsgPackData::user_info["leader_chara_dress_id"].int_value(); + + auto old_str = to_string(leader_chara_dress_id); + size_t n_zero = 6; + auto new_str = std::string(n_zero - std::min(n_zero, old_str.length()), '0') + old_str; + + auto push_icon = "push_icon_"s + to_string(leader_chara_id) + "_" + new_str; + auto path = "chara/chr"s + to_string(leader_chara_id) + "/" + push_icon; + + auto loader = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "AssetManager", "get_Loader", -1)(); + auto asset = il2cpp_class_get_method_from_name_type(loader->klass, "LoadAssetHandle", 2)->methodPointer(loader, il2cpp_string_new(path.data()), false); + auto assetBundle = il2cpp_class_get_method_from_name_type(asset->klass, "get_assetBundle", 0)->methodPointer(asset); + + auto texture2DType = reinterpret_cast(::GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "Texture2D")); + auto texture2D = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.AssetBundle::LoadAsset_Internal(System.String,System.Type)"))(assetBundle, il2cpp_string_new(push_icon.data()), texture2DType); + + DumpTexture2D(leader_chara_id, texture2D); + + if (g_notification_rp) + { + // unique_ptr history; + // DesktopNotificationManagerCompat::get_History(&history); + + if ((!MsgPackData::user_info.empty() || !MsgPackData::rp_info.empty()) && g_notification_rp) + { + DesktopNotificationManagerCompat::RemoveFromScheduleByTag(L"RP"); + auto title = local::u8_wide(MasterDB::GetTextData(6, leader_chara_id)); + auto content = local::u8_wide(MasterDB::GetTextData(185, leader_chara_id)); + // history->RemoveGroupedTag(L"TP", L"Generic"); + DesktopNotificationManagerCompat::AddScheduledToastNotification(title.data(), content.data(), L"RP", GetIconPath(leader_chara_id)->start_char, MsgPackData::rp_info["max_recovery_time"].int64_value() * 1000); + } + } + } + } + + void ReadResponse(const char* data, size_t size) + { + string error; + auto parsed = MsgPack::parse(data, size, error); + + if (error.empty()) + { + if (parsed.is_object()) + { + MsgPack::object object = parsed.object_items(); + + if (object["data"].is_object()) + { + MsgPack::object data = object["data"].object_items(); + + if (data["tp_info"].is_object() || data["rp_info"].is_object() || data["user_info"].is_object()) + { + int leader_chara_id; + int leader_chara_dress_id; + + if (data["user_info"].is_object()) + { + MsgPackData::user_info = data["user_info"].object_items(); + } + + if (data["tp_info"].is_object()) + { + MsgPackData::tp_info = data["tp_info"].object_items(); + } + + if (data["rp_info"].is_object()) + { + MsgPackData::rp_info = data["rp_info"].object_items(); + } + + leader_chara_id = MsgPackData::user_info["leader_chara_id"].int_value(); + leader_chara_dress_id = MsgPackData::user_info["leader_chara_dress_id"].int_value(); + + auto old_str = to_string(leader_chara_dress_id); + size_t n_zero = 6; + auto new_str = std::string(n_zero - std::min(n_zero, old_str.length()), '0') + old_str; + + auto push_icon = "push_icon_"s + to_string(leader_chara_id) + "_" + new_str; + auto path = "chara/chr"s + to_string(leader_chara_id) + "/" + push_icon; + + auto loader = il2cpp_symbols::get_method_pointer("umamusume.dll", "Gallop", "AssetManager", "get_Loader", -1)(); + auto asset = il2cpp_class_get_method_from_name_type(loader->klass, "LoadAssetHandle", 2)->methodPointer(loader, il2cpp_string_new(path.data()), false); + + if (!asset) + { + return; + } + + auto assetBundle = il2cpp_class_get_method_from_name_type(asset->klass, "get_assetBundle", 0)->methodPointer(asset); + + auto texture2DType = reinterpret_cast(::GetRuntimeType("UnityEngine.CoreModule.dll", "UnityEngine", "Texture2D")); + auto texture2D = reinterpret_cast(il2cpp_resolve_icall("UnityEngine.AssetBundle::LoadAsset_Internal(System.String,System.Type)"))(assetBundle, il2cpp_string_new(push_icon.data()), texture2DType); + + DumpTexture2D(leader_chara_id, texture2D); + + if (g_notification_tp || g_notification_rp) + { + // unique_ptr history; + // DesktopNotificationManagerCompat::get_History(&history); + + auto title = local::u8_wide(MasterDB::GetTextData(6, leader_chara_id)); + if ((data["user_info"].is_object() || data["tp_info"].is_object()) && g_notification_tp) + { + DesktopNotificationManagerCompat::RemoveFromScheduleByTag(L"TP"); + auto content = local::u8_wide(MasterDB::GetTextData(184, leader_chara_id)); + // history->RemoveGroupedTag(L"TP", L"Generic"); + DesktopNotificationManagerCompat::AddScheduledToastNotification(title.data(), content.data(), L"TP", GetIconPath(leader_chara_id)->start_char, MsgPackData::tp_info["max_recovery_time"].int64_value() * 1000); + } + if ((data["user_info"].is_object() || data["rp_info"].is_object()) && g_notification_rp) + { + DesktopNotificationManagerCompat::RemoveFromScheduleByTag(L"RP"); + auto content = local::u8_wide(MasterDB::GetTextData(185, leader_chara_id)); + // history->RemoveGroupedTag(L"RP", L"Generic"); + DesktopNotificationManagerCompat::AddScheduledToastNotification(title.data(), content.data(), L"RP", GetIconPath(leader_chara_id)->start_char, MsgPackData::rp_info["max_recovery_time"].int64_value() * 1000); + } + } + } + } + } + } + } +} diff --git a/src/msgpack/msgpack_modify.hpp b/src/msgpack/msgpack_modify.hpp new file mode 100644 index 0000000..044fa4b --- /dev/null +++ b/src/msgpack/msgpack_modify.hpp @@ -0,0 +1,701 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "il2cpp/il2cpp_symbols.hpp" +#include "il2cpp/il2cpp-api-functions.hpp" +#include "local/local.hpp" +#include "game.hpp" + +#include "masterdb/masterdb.hpp" + +#include "hook.h" + +#include "notification/DesktopNotificationManagerCompat.h" + +#include "masterdb/masterdb.hpp" + +#include "msgpack_data.hpp" + +using namespace std; +using namespace msgpack11; + +namespace MsgPackModify +{ + unordered_map liveTheaterSaveInfoMap; + + unordered_map availableCharaIds; + unordered_map defaultAvailableDressIds; + unordered_map availableDressIds; + unordered_map availableMusicIds; + + vector mobIds; + queue mobIdQueue; + + MsgPack::array charaList; + + bool charaListInit = false; + + int64_t current_time() { + auto ms = chrono::duration_cast( + chrono::system_clock::now().time_since_epoch()); + return ms.count(); + } + + void SuffleMobIds() + { + vector ids = mobIds; + + random_device device; + shuffle(ids.begin(), ids.end(), default_random_engine(device())); + + queue q; + + for (auto id : ids) + { + q.push(id); + } + + mobIdQueue = q; + } + + int GetRandomMobId() + { + auto num = mobIdQueue.front(); + mobIdQueue.pop(); + mobIdQueue.push(num); + return num; + } + + void InitMasterDB() + { + MasterDB::InitMasterDB(); + + auto db = new SQLite::Database(MasterDB::masterDBPath, SQLite::OPEN_READWRITE); + + db->exec("UPDATE dress_data SET use_live = 1, use_live_theater = 1"); + + db->exec("UPDATE dress_data SET start_time = 1483196400 WHERE start_time > "s.append(to_string(current_time())).data()); + + db->exec("UPDATE dress_data SET general_purpose = 1, costume_type = 1 WHERE id >= 200000 AND id <= 299999 AND body_type = 100"); + + db->exec("UPDATE dress_data SET body_type = 230 WHERE id > 299999 AND body_type = 100"); + + db->exec("UPDATE dress_data SET body_type = 230 WHERE id LIKE '1___60'"); + + /*db->exec("UPDATE fan_raid_data SET end_date = 2524575600 WHERE fan_raid_id = 1001"); + + db->exec("UPDATE fan_raid_top_data SET start_date = 2524575600, end_date = 2524575600"); + + db->exec("UPDATE fan_raid_top_data SET start_date = 1648782000, end_date = 2524575600 WHERE id = 1");*/ + + db->exec("UPDATE live_data SET start_date = 1483196400 WHERE has_live = 1 AND start_date > "s.append(to_string(current_time())).data()); + + db->exec("UPDATE chara_data SET start_date = 1483196400 WHERE start_date > "s.append(to_string(current_time())).data()); + + db->exec("UPDATE chara_data SET shape = 1 WHERE id = 9001"); + + unordered_map masterCardIds; + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT id FROM card_data"); + while (statement.executeStep()) + { + masterCardIds[statement.getColumn(0).getInt()] = true; + } + + auto statement1 = SQLite::Statement(*MasterDB::masterDB, "SELECT id FROM dress_data WHERE (condition_type = 1 OR condition_type = 4 OR condition_type = 5) AND use_live_theater = 1 AND id < 999"); + while (statement1.executeStep()) + { + defaultAvailableDressIds[statement1.getColumn(0).getInt()] = true; + } + + auto statement2 = SQLite::Statement(*MasterDB::masterDB, "SELECT mob_id FROM mob_data WHERE use_live = 1"); + while (statement2.executeStep()) + { + mobIds.emplace_back(statement2.getColumn(0).getInt()); + } + + vector metaDressIds; + + auto mstatement = SQLite::Statement(*MasterDB::metaDB, "SELECT n FROM a WHERE n LIKE '%pfb_bdy1____0_'"); + while (mstatement.executeStep()) + { + auto name = mstatement.getColumn(0).getString(); + auto chara_id = name.substr(32, 4); + auto body_type = name.substr(37, 2); + + if (stoi(body_type) <= 1) + { + body_type = "01"; + metaDressIds.emplace_back(stoi(chara_id + body_type)); + } + } + + auto mstatement1 = SQLite::Statement(*MasterDB::metaDB, "SELECT n FROM a WHERE n LIKE '%pfb_bdy2____0_'"); + while (mstatement1.executeStep()) + { + auto name = mstatement1.getColumn(0).getString(); + auto chara_id = name.substr(32, 4); + auto body_type = name.substr(37, 2); + + if (stoi(body_type) <= 1) + { + body_type = "01"; + metaDressIds.emplace_back(stoi(chara_id + body_type)); + } + } + + for (auto dressId : metaDressIds) + { + if (!masterCardIds.contains(dressId)) + { + auto chara_id = to_string(dressId).substr(0, 4); + auto sub_type = stoi(to_string(dressId).substr(3, 2)); + stringstream ss; + ss << to_string(dressId) << ","; + ss << chara_id << ","; + ss << "3, 0, 100101, 0, 20, 0, 0, 10, 100101, 1, 100101, 3"; + + if (Game::CurrentGameRegion == Game::Region::KOR) + { + ss << ", 1483196400"; + } + + db->exec("INSERT INTO card_data VALUES("s.append(ss.str()).append(")").data()); + + stringstream ss1; + ss1 << to_string(dressId); + ss1 << "03, "; + ss1 << to_string(dressId); + ss1 << ", 3, "; + ss1 << to_string(dressId); + ss1 << ", 10010103, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 7, 7, 1, 7, 7, 5, 7, 1, 101,"; + ss1 << to_string(dressId); + + db->exec("INSERT INTO card_rarity_data VALUES("s.append(ss1.str()).append(")").data()); + availableDressIds[dressId] = true; + } + } + + delete db; + + MasterDB::ReloadMasterDB(); + + SuffleMobIds(); + } + + string ModifyRequest(const char* data, size_t size) + { + string error; + auto parsed = MsgPack::parse(data, size, error); + + string dump; + + if (error.empty()) + { + if (parsed.is_object()) + { + MsgPack::object object = parsed.object_items(); + + if (object["live_theater_save_info"].is_object()) + { + MsgPack::object info = object["live_theater_save_info"].object_items(); + auto music_id = info["music_id"].int32_value(); + MsgPack::array member_info_array = info["member_info_array"].array_items(); + + if (liveTheaterSaveInfoMap.contains(music_id)) + { + bool valid = true; + + for (auto& member : member_info_array) + { + int chara_id = member["chara_id"].int32_value(); + + if (chara_id > 0 && !availableCharaIds.contains(chara_id)) + { + cout << "Invalid Chara: " << chara_id << endl; + valid = false; + break; + } + + int dress_id = member["dress_id"].int32_value(); + int dress_id2 = member["dress_id2"].int32_value(); + + if (dress_id > 0 && + !(availableDressIds.contains(dress_id) || defaultAvailableDressIds.contains(dress_id))) + { + cout << "Invalid Dress: " << dress_id << endl; + valid = false; + break; + } + + if (dress_id2 > 0 && + !(availableDressIds.contains(dress_id2) || defaultAvailableDressIds.contains(dress_id2))) + { + cout << "Invalid Dress 2: " << dress_id2 << endl; + valid = false; + break; + } + } + + if (!valid) + { + // rollback data + object["live_theater_save_info"] = liveTheaterSaveInfoMap[music_id]; + } + } + else if (availableMusicIds[music_id]) + { + bool valid = true; + + for (auto& member : member_info_array) + { + int chara_id = member["chara_id"].int32_value(); + + if (chara_id > 0 && !availableCharaIds.contains(chara_id)) + { + cout << "Invalid Chara: " << chara_id << endl; + valid = false; + break; + } + + int dress_id = member["dress_id"].int32_value(); + int dress_id2 = member["dress_id2"].int32_value(); + + if (dress_id > 0 && + !(availableDressIds.contains(dress_id) || defaultAvailableDressIds.contains(dress_id))) + { + cout << "Invalid Dress: " << dress_id << endl; + valid = false; + break; + } + + if (dress_id2 > 0 && + !(availableDressIds.contains(dress_id2) || defaultAvailableDressIds.contains(dress_id2))) + { + cout << "Invalid Dress 2: " << dress_id2 << endl; + valid = false; + break; + } + } + + if (!valid) + { + if (liveTheaterSaveInfoMap.empty()) + { + MsgPack::array new_member_info_array; + for (auto& member : member_info_array) + { + MsgPack::object new_member; + + int chara_id = member["chara_id"].int32_value(); + int mob_id = member["mob_id"].int32_value(); + + if (chara_id > 0 && !availableCharaIds.contains(chara_id)) + { + new_member["chara_id"] = 0; + new_member["mob_id"] = GetRandomMobId(); + } + else if (chara_id == 0 && mob_id == 0) + { + new_member["mob_id"] = GetRandomMobId(); + } + + int dress_id = member["dress_id"].int32_value(); + int dress_id2 = member["dress_id2"].int32_value(); + + if (!(availableDressIds.contains(dress_id) || defaultAvailableDressIds.contains(dress_id))) + { + new_member["dress_id"] = 7; + } + else if (!availableCharaIds.contains(chara_id) && + (availableDressIds.contains(dress_id) || defaultAvailableDressIds.contains(dress_id))) + { + new_member["dress_id"] = 7; + } + + if (dress_id2 > 0) + { + if (!(availableDressIds.contains(dress_id2) || defaultAvailableDressIds.contains(dress_id2))) + { + new_member["dress_id2"] = 7; + } + else if (!availableCharaIds.contains(chara_id) && + (availableDressIds.contains(dress_id2) || defaultAvailableDressIds.contains(dress_id2))) + { + new_member["dress_id2"] = 7; + } + } + + new_member_info_array.emplace_back(new_member); + } + info["member_info_array"] = new_member_info_array; + } + else + { + // fallback data + pair first = *liveTheaterSaveInfoMap.begin(); + object["live_theater_save_info"] = first.second; + } + } + } + else + { + if (liveTheaterSaveInfoMap.empty()) + { + if (!availableMusicIds.empty()) + { + pair first = *availableMusicIds.begin(); + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT live_member_number FROM live_data WHERE music_id = ?"); + statement.bind(0, first.first); + + int memberCount; + + while (statement.executeStep()) + { + memberCount = statement.getColumn(0).getInt(); + } + + MsgPack::array new_member_info_array; + for (int i = 0; i < memberCount; i++) + { + MsgPack::object new_member; + + new_member["mob_id"] = GetRandomMobId(); + new_member["dress_id"] = 7; + + + new_member_info_array.emplace_back(new_member); + } + info["member_info_array"] = new_member_info_array; + } + } + else + { + // fallback data + pair first = *liveTheaterSaveInfoMap.begin(); + object["live_theater_save_info"] = first.second; + } + } + } + + MsgPack{ object }.dump(dump); + } + } + + return dump; + } + + MsgPack::array GetCharaList() + { + return charaList; + } + + string ModifyResponse(const char* data, size_t size) + { + string error; + auto parsed = MsgPack::parse(data, size, error); + + string dump; + + if (error.empty()) + { + if (parsed.is_object()) + { + MsgPack::object object = parsed.object_items(); + + /*if (object["data_headers"].is_object()) + { + MsgPack::object header = object["data_headers"].object_items(); + + if (header["result_code"].int32_value() == 9151) + { + header["result_code"] = 1; + + MsgPack::object fakeFanRaidData = MsgPack::object + { + { + "fan_raid_fans_info", + MsgPack::object + { + { "all_gained_fans", INT_MAX }, + { "individual_gained_fans", INT_MAX } + } + }, + { "checked_fan_raid_all_reward_id_array", MsgPack::array{} }, + { "fan_raid_polling_interval", INT_MAX }, + { "is_cleared_fan_raid_condition", 1 } + }; + + object["data"] = fakeFanRaidData; + } + + object["data_headers"] = header; + }*/ + + if (object["data"].is_object()) + { + MsgPack::object data = object["data"].object_items(); + + if (data["common_define"].is_object()) + { + if (!MasterDB::masterDB) + { + InitMasterDB(); + } + } + + /*if (data["fan_raid_id"].is_int()) + { + data["fan_raid_id"] = 1001; + }*/ + + if (data["chara_list"].is_array()) + { + MsgPack::array chara_list = data["chara_list"].array_items(); + + unordered_map chara_map; + + availableCharaIds.clear(); + for (auto& chara : chara_list) + { + MsgPack::object charaObject = chara.object_items(); + + int chara_id = charaObject["chara_id"].int32_value(); + + availableCharaIds[chara_id] = true; + chara_map[chara_id] = charaObject; + } + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT id FROM chara_data"); + + MsgPack::array charas; + while (statement.executeStep()) + { + int chara_id = statement.getColumn(0).getInt(); + + if (chara_map.contains(chara_id)) + { + charas.emplace_back(chara_map[chara_id]); + } + else + { + charas.emplace_back( + MsgPack::object + { + { "chara_id", statement.getColumn(0).getInt() }, + { "training_num", 0 }, + { "love_point", 0 }, + { "fan", 1 }, + { "max_grade", 0 }, + { "dress_id", 2 }, + { "mini_dress_id", 2 }, + { "love_point_pool", 0 }, + } + ); + } + } + + charaList = charas; + } + + if (data["chara_profile_array"].is_array()) + { + MsgPack::array chara_profile_array = data["chara_profile_array"].array_items(); + + unordered_map chara_profile_map; + + for (auto& chara_profile : chara_profile_array) + { + MsgPack::object charaProfileObject = chara_profile.object_items(); + + int chara_id = charaProfileObject["chara_id"].int32_value(); + + chara_profile_map[chara_id] = charaProfileObject; + } + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT id FROM chara_data"); + + MsgPack::array chara_profiles; + while (statement.executeStep()) + { + int chara_id = statement.getColumn(0).getInt(); + + if (chara_profile_map.contains(chara_id)) + { + chara_profiles.emplace_back(chara_profile_map[chara_id]); + } + else + { + chara_profiles.emplace_back( + MsgPack::object + { + { "chara_id", statement.getColumn(0).getInt() }, + { "data_id", 1 }, + { "new_flag", 0 }, + } + ); + } + } + + data["chara_profile_array"] = chara_profiles; + } + + if (data["release_card_array"].is_array()) + { + MsgPack::array release_card_array = data["release_card_array"].array_items(); + + unordered_map release_card_map; + + for (auto& release_card : release_card_array) + { + auto release_card_id = release_card.int32_value(); + + release_card_map[release_card_id] = true; + } + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT id FROM card_data WHERE id <= 999999"); + + MsgPack::array release_cards; + while (statement.executeStep()) + { + int release_card_id = statement.getColumn(0).getInt(); + + release_cards.emplace_back(release_card_id); + } + + data["release_card_array"] = release_cards; + } + + if (data["card_list"].is_array()) + { + MsgPack::array card_list = data["card_list"].array_items(); + + unordered_map card_map; + + for (auto& card : card_list) + { + MsgPack::object cardObject = card.object_items(); + + int card_id = cardObject["card_id"].int32_value(); + + card_map[card_id] = cardObject; + } + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT id, default_rarity FROM card_data WHERE id <= 999999"); + + MsgPack::array cards; + while (statement.executeStep()) + { + int card_id = statement.getColumn(0).getInt(); + + if (card_map.contains(card_id)) + { + MsgPack::object card = card_map[card_id]; + if (card["rarity"].int32_value() < 3) + { + card["rarity"] = 3; + } + + cards.emplace_back(card); + } + else + { + cards.emplace_back( + MsgPack::object + { + { "null", 1 }, + { "card_id", statement.getColumn(0).getInt() }, + { "rarity", statement.getColumn(1).getInt() }, + { "talent_level", 1 }, + { "create_time", "2022-07-01 12:00:00" }, + { "skill_data_array", MsgPack::array{} }, + } + ); + } + } + + data["card_list"] = cards; + } + + if (data["cloth_list"].is_array()) + { + MsgPack::array cloth_list = data["cloth_list"].array_items(); + + availableDressIds.clear(); + for (auto& cloth : cloth_list) + { + MsgPack::object clothObject = cloth.object_items(); + availableDressIds[clothObject["cloth_id"].int32_value()] = true; + } + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT id FROM dress_data"); + + MsgPack::array dresses; + while (statement.executeStep()) + { + dresses.emplace_back(MsgPack::object{ {"cloth_id", statement.getColumn(0).getInt()} }); + } + + data["cloth_list"] = dresses; + } + + if (data["music_list"].is_array()) + { + MsgPack::array music_list = data["music_list"].array_items(); + + availableMusicIds.clear(); + for (auto& music : music_list) + { + MsgPack::object musicObject = music.object_items(); + availableMusicIds[musicObject["music_id"].int32_value()] = true; + } + + auto statement = SQLite::Statement(*MasterDB::masterDB, "SELECT music_id FROM live_data"); + + MsgPack::array musicIds; + while (statement.executeStep()) + { + musicIds.emplace_back( + MsgPack::object + { + { "music_id", statement.getColumn(0).getInt() }, + { "acquisition_time", "2022-07-01 12:00:00" } + } + ); + } + + data["music_list"] = musicIds; + } + + if (data["live_theater_save_info_array"].is_array()) + { + MsgPack::array live_theater_save_info_array = data["live_theater_save_info_array"].array_items(); + + liveTheaterSaveInfoMap.clear(); + + for (auto& live_theater_save_info : live_theater_save_info_array) + { + auto saveInfo = MsgPack::object{ live_theater_save_info.object_items() }; + liveTheaterSaveInfoMap.emplace(saveInfo["music_id"].int32_value(), saveInfo); + } + } + + object["data"] = data; + } + + MsgPack{ object }.dump(dump); + } + } + + return dump; + } +} diff --git a/src/notification/DesktopNotificationManagerCompat.cpp b/src/notification/DesktopNotificationManagerCompat.cpp new file mode 100644 index 0000000..25fe6b6 --- /dev/null +++ b/src/notification/DesktopNotificationManagerCompat.cpp @@ -0,0 +1,544 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +#include "DesktopNotificationManagerCompat.h" +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include "SaveIcon.h" + +#include "il2cpp/il2cpp_symbols.hpp" +#include "local/local.hpp" +#include "game.hpp" + +#define RETURN_IF_FAILED(hr) do { HRESULT _hrTemp = hr; if (FAILED(_hrTemp)) { cout << #hr << " FAILED Last Error: " << GetLastError() << endl; return _hrTemp; } } while (false) + +using namespace std; +using namespace ABI::Windows::Data::Xml::Dom; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +namespace DesktopNotificationManagerCompat +{ + HRESULT RegisterAUMID(const wchar_t* aumid, GUID clsid, const wchar_t* displayName, const wchar_t exePath[]); + HRESULT RegisterComServer(GUID clsid, const wchar_t exePath[]); + HRESULT EnsureRegistered(); + wstring GetAppDataFolderIconPath(const wchar_t* amuid); + + bool s_registeredAumidAndComServer = false; + // wstring s_aumid; + bool s_registeredActivator = false; + bool s_hasCheckedIsRunningAsUwp = false; + bool s_isRunningAsUwp = false; + + HRESULT GetGuidByRegion(LPIID lpiid) + { + if (Game::CurrentGameRegion == Game::Region::KOR) + { + return IIDFromString(L"{A42CD370-8D06-4E3C-BC45-32A61F9E375B}", lpiid); + } + + return IIDFromString(L"{A42CD370-8D06-4E3C-BC45-32A61F9E375A}", lpiid); + } + + HRESULT RegisterAumidAndComServer(const wchar_t* aumid, const wchar_t* displayName) + { + GUID clsid; + + GetGuidByRegion(&clsid); + + // Copy the aumid + s_aumid = wstring(aumid); + + // Get the EXE path + wchar_t exePath[MAX_PATH]; + DWORD charWritten = GetModuleFileNameW(nullptr, exePath, ARRAYSIZE(exePath)); + RETURN_IF_FAILED(charWritten > 0 ? S_OK : HRESULT_FROM_WIN32(::GetLastError())); + + HICON hIcon; + ExtractIconExW(exePath, 0, &hIcon, nullptr, 1); + + auto path = GetAppDataFolderIconPath(aumid); + + if (!filesystem::exists(filesystem::path(local::wide_u8(path)).parent_path())) + { + filesystem::create_directories(filesystem::path(local::wide_u8(path)).parent_path()); + } + + SaveIconToFile(hIcon, GetAppDataFolderIconPath(aumid).data(), 32); + + RETURN_IF_FAILED(RegisterAUMID(aumid, clsid, displayName, exePath)); + + // Register the COM server + RETURN_IF_FAILED(RegisterComServer(clsid, exePath)); + + s_registeredAumidAndComServer = true; + return S_OK; + } + + HRESULT RegisterActivator() + { + // Module needs a callback registered before it can be used. + // Since we don't care about when it shuts down, we'll pass an empty lambda here. + Module::Create([] {}); + + // If a local server process only hosts the COM object then COM expects + // the COM server host to shutdown when the references drop to zero. + // Since the user might still be using the program after activating the notification, + // we don't want to shutdown immediately. Incrementing the object count tells COM that + // we aren't done yet. + Module::GetModule().IncrementObjectCount(); + + RETURN_IF_FAILED(Module::GetModule().RegisterObjects()); + + s_registeredActivator = true; + return S_OK; + } + + HRESULT RegisterAUMID(const wchar_t* aumid, GUID clsid, const wchar_t* displayName, const wchar_t exePath[]) + { + // Turn the GUID into a string + OLECHAR* clsidOlechar; + StringFromCLSID(clsid, &clsidOlechar); + wstring clsidStr(clsidOlechar); + ::CoTaskMemFree(clsidOlechar); + + // Create the subkey + // Something like SOFTWARE\Classes\AppUserModelId\Cygames.Gallop + wstring subKey = LR"(SOFTWARE\Classes\AppUserModelId\)" + s_aumid; + + DWORD dataSize = static_cast((clsidStr.length() + 1) * sizeof(WCHAR)); + + RETURN_IF_FAILED(HRESULT_FROM_WIN32(RegSetKeyValueW( + HKEY_CURRENT_USER, + subKey.c_str(), + L"CustomActivator", + REG_SZ, + reinterpret_cast(clsidStr.c_str()), + dataSize))); + + wstring displayNameStr(displayName); + + dataSize = static_cast((displayNameStr.length() + 1) * sizeof(WCHAR)); + + RETURN_IF_FAILED(HRESULT_FROM_WIN32(RegSetKeyValueW( + HKEY_CURRENT_USER, + subKey.c_str(), + L"DisplayName", + REG_SZ, + reinterpret_cast(displayNameStr.c_str()), + dataSize))); + + wstring color(L"FFDDDDDD"); + + dataSize = static_cast((color.length() + 1) * sizeof(WCHAR)); + + RETURN_IF_FAILED(HRESULT_FROM_WIN32(RegSetKeyValueW( + HKEY_CURRENT_USER, + subKey.c_str(), + L"IconBackgroundColor", + REG_SZ, + reinterpret_cast(color.c_str()), + dataSize))); + + // Include -ToastActivated launch args on the exe + wstring iconPath = GetAppDataFolderIconPath(aumid); + + // We don't need to worry about overflow here as ::GetModuleFileName won't + // return anything bigger than the max file system path (much fewer than max of DWORD). + dataSize = static_cast((iconPath.length() + 1) * sizeof(WCHAR)); + + // Register the EXE for the COM server + RETURN_IF_FAILED(HRESULT_FROM_WIN32(RegSetKeyValueW( + HKEY_CURRENT_USER, + subKey.c_str(), + L"IconUri", + REG_SZ, + reinterpret_cast(iconPath.c_str()), + dataSize))); + + return S_OK; + } + + HRESULT RegisterComServer(GUID clsid, const wchar_t exePath[]) + { + // Turn the GUID into a string + OLECHAR* clsidOlechar; + StringFromCLSID(clsid, &clsidOlechar); + wstring clsidStr(clsidOlechar); + ::CoTaskMemFree(clsidOlechar); + + // Create the subkey + // Something like SOFTWARE\Classes\CLSID\{23A5B06E-20BB-4E7E-A0AC-6982ED6A6041}\LocalServer32 + wstring subKey = LR"(SOFTWARE\Classes\CLSID\)" + clsidStr + LR"(\LocalServer32)"; + + wstring exePathStr(exePath); + exePathStr = L"\"" + exePathStr + L"\""; + + // We don't need to worry about overflow here as ::GetModuleFileName won't + // return anything bigger than the max file system path (much fewer than max of DWORD). + DWORD dataSize = static_cast((exePathStr.length() + 1) * sizeof(WCHAR)); + + // Register the EXE for the COM server + return HRESULT_FROM_WIN32(RegSetKeyValueW( + HKEY_CURRENT_USER, + subKey.c_str(), + nullptr, + REG_SZ, + reinterpret_cast(exePathStr.c_str()), + dataSize)); + } + + HRESULT CreateToastNotifier(ABI::IToastNotifier** notifier) + { + RETURN_IF_FAILED(EnsureRegistered()); + + ComPtr toastStatics; + RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( + HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), + &toastStatics)); + + return toastStatics->CreateToastNotifierWithId(HStringReference(s_aumid.c_str()).Get(), notifier); + } + + HRESULT CreateXmlDocumentFromString(const wchar_t* xmlString, IXmlDocument** doc) + { + ComPtr answer; + RETURN_IF_FAILED(Windows::Foundation::ActivateInstance(HStringReference(RuntimeClass_Windows_Data_Xml_Dom_XmlDocument).Get(), &answer)); + + ComPtr docIO; + RETURN_IF_FAILED(answer.As(&docIO)); + + // Load the XML string + RETURN_IF_FAILED(docIO->LoadXml(HStringReference(xmlString).Get())); + + return answer.CopyTo(doc); + } + + HRESULT CreateToastNotification(IXmlDocument* content, ABI::IToastNotification** notification) + { + ComPtr factory; + RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( + HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), + &factory)); + + return factory->CreateToastNotification(content, notification); + } + + HRESULT CreateScheduledToastNotification(IXmlDocument* content, DateTime deliveryTime, ABI::IScheduledToastNotification** notification) + { + ComPtr factory; + RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( + HStringReference(RuntimeClass_Windows_UI_Notifications_ScheduledToastNotification).Get(), + &factory)); + + return factory->CreateScheduledToastNotification(content, deliveryTime, notification); + } + + HRESULT get_History(unique_ptr* history) + { + RETURN_IF_FAILED(EnsureRegistered()); + + ComPtr toastStatics; + RETURN_IF_FAILED(Windows::Foundation::GetActivationFactory( + HStringReference(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), + &toastStatics)); + + ComPtr toastStatics2; + RETURN_IF_FAILED(toastStatics.As(&toastStatics2)); + + ComPtr nativeHistory; + RETURN_IF_FAILED(toastStatics2->get_History(&nativeHistory)); + + *history = unique_ptr(new DesktopNotificationHistoryCompat(s_aumid.c_str(), nativeHistory)); + return S_OK; + } + + HRESULT PreRegisterIdentityLessApp() + { + RETURN_IF_FAILED(EnsureRegistered()); + + wstring subKey = LR"(SOFTWARE\Classes\AppUserModelId\)" + s_aumid; + + DWORD HasSentNotification = FALSE; + + DWORD cbData = sizeof(DWORD); + RegGetValueW( + HKEY_CURRENT_USER, + subKey.c_str(), + L"HasSentNotification", + RRF_RT_REG_DWORD, nullptr, &HasSentNotification, &cbData); + + if (HasSentNotification == TRUE) + { + return S_OK; + } + + ComPtr doc; + RETURN_IF_FAILED(CreateXmlDocumentFromString( + LR"( + New Notification + )", &doc)); + + ComPtr notifier; + RETURN_IF_FAILED(CreateToastNotifier(¬ifier)); + + ComPtr toast1; + RETURN_IF_FAILED(CreateToastNotification(doc.Get(), &toast1)); + + ComPtr toast2; + RETURN_IF_FAILED(toast1.As(&toast2)); + + winrt::Windows::Foundation::IReference dt{ winrt::clock::now() + chrono::seconds(15) }; + winrt::com_ptr> ptr{ dt.as>() }; + RETURN_IF_FAILED(toast2.Get()->put_SuppressPopup(true)); + RETURN_IF_FAILED(toast2.Get()->put_Group(HStringReference(L"toolkitGroupNull").Get())); + RETURN_IF_FAILED(toast2.Get()->put_Tag(HStringReference(L"toolkit1stNotif").Get())); + RETURN_IF_FAILED(toast1.Get()->put_ExpirationTime(ptr.get())); + + RETURN_IF_FAILED(notifier->Show(toast1.Get())); + + unique_ptr history; + RETURN_IF_FAILED(get_History(&history)); + RETURN_IF_FAILED(history->RemoveGroupedTag(L"toolkit1stNotif", L"toolkitGroupNull")); + + DWORD data = 1; + + return HRESULT_FROM_WIN32(RegSetKeyValueW( + HKEY_CURRENT_USER, + subKey.c_str(), + L"HasSentNotification", + REG_DWORD, + &data, + sizeof(data))); + } + + HRESULT ShowToastNotification(const wchar_t* title, const wchar_t* content, const wchar_t* iconPath) + { + RETURN_IF_FAILED(EnsureRegistered()); + + ComPtr doc; + RETURN_IF_FAILED(CreateXmlDocumentFromString( + (LR"( + + )" + title + LR"( + )" + content + LR"( + )").data(), &doc)); + + // Create the notifier + // Desktop apps must use the compat method to create the notifier. + ComPtr notifier; + RETURN_IF_FAILED(CreateToastNotifier(¬ifier)); + + unique_ptr history; + RETURN_IF_FAILED(get_History(&history)); + history->RemoveGroupedTag(L"Preview", L"Generic"); + + // Create the notification itself (using helper method from compat library) + ComPtr toast; + RETURN_IF_FAILED(CreateToastNotification(doc.Get(), &toast)); + + ComPtr toast2; + RETURN_IF_FAILED(toast.As(&toast2)); + + toast2.Get()->put_Group(HStringReference(L"Generic").Get()); + toast2.Get()->put_Tag(HStringReference(L"Preview").Get()); + + return notifier->Show(toast.Get()); + } + + HRESULT AddScheduledToastNotification(const wchar_t* title, const wchar_t* content, const wchar_t* tag, const wchar_t* iconPath, int64_t epoch) + { + RETURN_IF_FAILED(EnsureRegistered()); + + RETURN_IF_FAILED(PreRegisterIdentityLessApp()); + + ComPtr doc; + RETURN_IF_FAILED(CreateXmlDocumentFromString( + (LR"( + + )" + title + LR"( + )" + content + LR"( + )").data(), &doc)); + + // Create the notifier + // Desktop apps must use the compat method to create the notifier. + ComPtr notifier; + RETURN_IF_FAILED(CreateToastNotifier(¬ifier)); + + auto time = winrt::clock::from_sys(chrono::time_point( + winrt::clock::duration(chrono::milliseconds(epoch)) + )).time_since_epoch().count(); + + if (time < winrt::clock::now().time_since_epoch().count()) + { + return S_OK; + } + + // Create the notification itself (using helper method from compat library) + ComPtr toast; + RETURN_IF_FAILED(CreateScheduledToastNotification(doc.Get(), { time }, &toast)); + + ComPtr toast2; + RETURN_IF_FAILED(toast.As(&toast2)); + + toast2.Get()->put_Group(HStringReference(L"Generic").Get()); + toast2.Get()->put_Tag(HStringReference(tag).Get()); + + return notifier->AddToSchedule(toast.Get()); + } + + HRESULT RemoveFromScheduleByTag(const wchar_t* tag) + { + RETURN_IF_FAILED(EnsureRegistered()); + + // Create the notifier + // Desktop apps must use the compat method to create the notifier. + ComPtr notifier; + RETURN_IF_FAILED(CreateToastNotifier(¬ifier)); + + ABI::Windows::Foundation::Collections::IVectorView* toasts; + RETURN_IF_FAILED(notifier.Get()->GetScheduledToastNotifications(&toasts)); + + uint32_t size; + RETURN_IF_FAILED(toasts->get_Size(&size)); + for (int i = 0; i < size; i++) + { + ABI::IScheduledToastNotification* toast; + RETURN_IF_FAILED(toasts->GetAt(i, &toast)); + + ABI::IScheduledToastNotification2* toast2; + RETURN_IF_FAILED(toast->QueryInterface(&toast2)); + + HSTRING hTag; + RETURN_IF_FAILED(toast2->get_Tag(&hTag)); + + auto tag1 = WindowsGetStringRawBuffer(hTag, nullptr); + + if (tag1 == tag) + { + RETURN_IF_FAILED(notifier.Get()->RemoveFromSchedule(toast)); + } + } + + return S_OK; + } + + HRESULT EnsureRegistered() + { + // If not registered AUMID yet + if (!s_registeredAumidAndComServer) + { + // Otherwise, incorrect usage, must call RegisterAumidAndComServer first + return E_ILLEGAL_METHOD_CALL; + } + + // If not registered activator yet + if (!s_registeredActivator) + { + // Incorrect usage, must call RegisterActivator first + return E_ILLEGAL_METHOD_CALL; + } + + return S_OK; + } + + wstring GetAppDataFolderIconPath(const wchar_t* amuid) + { + PWSTR path; + SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path); + + wstringstream stream; + stream << path << LR"(\ToastNotificationManagerCompat\Apps\)" << amuid << LR"(\Icon.ico)"; + + return stream.str(); + } + + class DECLSPEC_UUID("A42CD370-8D06-4E3C-BC45-32A61F9E375A") NotificationActivator WrlSealed + : public RuntimeClass, INotificationActivationCallback> + { + public: + virtual HRESULT STDMETHODCALLTYPE Activate( + _In_ LPCWSTR appUserModelId, + _In_ LPCWSTR invokedArgs, + _In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA * data, + ULONG dataCount) override + { + return S_OK; + } + }; + + class DECLSPEC_UUID("A42CD370-8D06-4E3C-BC45-32A61F9E375B") NotificationActivator2 WrlSealed + : public RuntimeClass, INotificationActivationCallback> + { + public: + virtual HRESULT STDMETHODCALLTYPE Activate( + _In_ LPCWSTR appUserModelId, + _In_ LPCWSTR invokedArgs, + _In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA * data, + ULONG dataCount) override + { + return S_OK; + } + }; + + // Flag class as COM creatable + CoCreatableClass(NotificationActivator); + CoCreatableClass(NotificationActivator2); +} + +DesktopNotificationHistoryCompat::DesktopNotificationHistoryCompat(const wchar_t* aumid, ComPtr history) +{ + m_aumid = wstring(aumid); + m_history = history; +} + +HRESULT DesktopNotificationHistoryCompat::Clear() +{ + return m_history->ClearWithId(HStringReference(m_aumid.c_str()).Get()); +} + +HRESULT DesktopNotificationHistoryCompat::GetHistory(ABI::Windows::Foundation::Collections::IVectorView** toasts) +{ + ComPtr history2; + RETURN_IF_FAILED(m_history.As(&history2)); + + return history2->GetHistoryWithId(HStringReference(m_aumid.c_str()).Get(), toasts); +} + +HRESULT DesktopNotificationHistoryCompat::Remove(const wchar_t* tag) +{ + return m_history->Remove(HStringReference(tag).Get()); +} + +HRESULT DesktopNotificationHistoryCompat::RemoveGroupedTag(const wchar_t* tag, const wchar_t* group) +{ + return m_history->RemoveGroupedTagWithId(HStringReference(tag).Get(), HStringReference(group).Get(), HStringReference(m_aumid.c_str()).Get()); + +} + +HRESULT DesktopNotificationHistoryCompat::RemoveGroup(const wchar_t* group) +{ + return m_history->RemoveGroupWithId(HStringReference(group).Get(), HStringReference(m_aumid.c_str()).Get()); + +} diff --git a/src/notification/DesktopNotificationManagerCompat.h b/src/notification/DesktopNotificationManagerCompat.h new file mode 100644 index 0000000..15b6de0 --- /dev/null +++ b/src/notification/DesktopNotificationManagerCompat.h @@ -0,0 +1,126 @@ +// ****************************************************************** +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THE CODE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH +// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE. +// ****************************************************************** + +#pragma once +#include +#include +#include +#include +#include +#include + +#include + +namespace ABI { + using namespace Windows::UI::Notifications; +} + +using namespace ABI::Windows::Foundation; + +class DesktopNotificationHistoryCompat; + +namespace DesktopNotificationManagerCompat +{ + inline std::wstring s_aumid; + + HRESULT GetGuidByRegion(LPIID lpiid); + + /// + /// If not running under the Desktop Bridge, you must call this method to register your AUMID with the Compat library and to + /// register your COM CLSID and EXE in LocalServer32 registry. Feel free to call this regardless, and we will no-op if running + /// under Desktop Bridge. Call this upon application startup, before calling any other APIs. + /// + /// An AUMID that uniquely identifies your application. + /// The CLSID of your NotificationActivator class. + HRESULT RegisterAumidAndComServer(const wchar_t* aumid, const wchar_t* displayName); + + /// + /// Registers your module to handle COM activations. Call this upon application startup. + /// + HRESULT RegisterActivator(); + + /// + /// Creates a toast notifier. You must have called RegisterActivator first (and also RegisterAumidAndComServer if you're a classic Win32 app), or this will throw an exception. + /// + HRESULT CreateToastNotifier(ABI::IToastNotifier** notifier); + + /// + /// Creates an XmlDocument initialized with the specified string. This is simply a convenience helper method. + /// + HRESULT CreateXmlDocumentFromString(const wchar_t* xmlString, ABI::Windows::Data::Xml::Dom::IXmlDocument** doc); + + /// + /// Creates a toast notification. This is simply a convenience helper method. + /// + HRESULT CreateToastNotification(ABI::Windows::Data::Xml::Dom::IXmlDocument* content, ABI::IToastNotification** notification); + + /// + /// Creates a scheduled toast notification. This is simply a convenience helper method. + /// + HRESULT CreateScheduledToastNotification(ABI::Windows::Data::Xml::Dom::IXmlDocument* content, DateTime deliveryTime, ABI::IScheduledToastNotification** notification); + + HRESULT ShowToastNotification(const wchar_t* title, const wchar_t* content, const wchar_t* iconPath); + + HRESULT AddScheduledToastNotification(const wchar_t* title, const wchar_t* content, const wchar_t* tag, const wchar_t* iconPath, int64_t epoch); + + HRESULT RemoveFromScheduleByTag(const wchar_t* tag); + + /// + /// Gets the DesktopNotificationHistoryCompat object. You must have called RegisterActivator first (and also RegisterAumidAndComServer if you're a classic Win32 app), or this will throw an exception. + /// + HRESULT get_History(std::unique_ptr* history); + + HRESULT PreRegisterIdentityLessApp(); +} + +class DesktopNotificationHistoryCompat +{ +public: + + /// + /// Removes all notifications sent by this app from action center. + /// + HRESULT Clear(); + + /// + /// Gets all notifications sent by this app that are currently still in Action Center. + /// + HRESULT GetHistory(ABI::Windows::Foundation::Collections::IVectorView** history); + + /// + /// Removes an individual toast, with the specified tag label, from action center. + /// + /// The tag label of the toast notification to be removed. + HRESULT Remove(const wchar_t* tag); + + /// + /// Removes a toast notification from the action using the notification's tag and group labels. + /// + /// The tag label of the toast notification to be removed. + /// The group label of the toast notification to be removed. + HRESULT RemoveGroupedTag(const wchar_t* tag, const wchar_t* group); + + /// + /// Removes a group of toast notifications, identified by the specified group label, from action center. + /// + /// The group label of the toast notifications to be removed. + HRESULT RemoveGroup(const wchar_t* group); + + /// + /// Do not call this. Instead, call DesktopNotificationManagerCompat.get_History() to obtain an instance. + /// + DesktopNotificationHistoryCompat(const wchar_t* aumid, Microsoft::WRL::ComPtr history); + +private: + std::wstring m_aumid; + Microsoft::WRL::ComPtr m_history = nullptr; +}; diff --git a/src/settings_text.hpp b/src/settings_text.hpp index b5707f7..1f33daa 100644 --- a/src/settings_text.hpp +++ b/src/settings_text.hpp @@ -34,16 +34,61 @@ namespace LocalifySettings return isKor ? "변경 사항은 게임 재실행 후 반영됩니다" : "変更はゲームの再実行後に反映されます"; } + if (id == "anti_aliasing") + { + return isKor ? "안티 엘리어싱" : "アンチエイリアシング"; + } + + if (id == "graphics_quality") + { + return isKor ? "그래픽 품질" : "グラフィックの品質"; + } + if (id == "character_system_text_caption") { return isKor ? "캐릭터 대사 자막" : "キャラクターのダイアログテキストを\nキャプションで表示"; } + if (id == "character_system_text_caption_position_x") + { + return isKor ? "X좌표" : "X座標"; + } + + if (id == "character_system_text_caption_position_y") + { + return isKor ? "Y좌표" : "Y座標"; + } + + if (id == "character_system_text_caption_background_alpha") + { + return isKor ? "배경 투명도" : "背景透明度"; + } + + if (id == "character_system_text_caption_font_color") + { + return isKor ? "폰트 색상" : ""; + } + + if (id == "character_system_text_caption_outline_size") + { + return isKor ? "외곽선 크기" : ""; + } + + if (id == "character_system_text_caption_outline_color") + { + return isKor ? "외곽선 색상" : ""; + } + if (id == "show_caption") { return isKor ? "자막 표시" : "字幕表示"; } + if (id == "show_notification") + { + return isKor ? "알림 표시" : "通知表示"; + } + if (id == "sample_caption") { return isKor ? "샘플 자막" : "サンプル字幕"; @@ -54,6 +99,36 @@ namespace LocalifySettings return isKor ? "Ms. VICTORIA 챔피언스 미팅 순위 표시" : "Ms. VICTORIAチャンピオンズミーティングの\n順位表示"; } + if (id == "champions_live_resource_id") + { + return isKor ? "챔피언스 미팅 일정" : "チャンピオンズミーティングスケジュール"; + } + + if (id == "champions_live_year") + { + return isKor ? "챔피언스 미팅 년도" : "チャンピオンズミーティングの年"; + } + + if (id == "dump_msgpack") + { + return isKor ? "MessagePack 덤프" : "MessagePackダンプ"; + } + + if (id == "dump_msgpack_request") + { + return isKor ? "MessagePack 요청 덤프" : "MessagePackリクエストダンプ"; + } + + if (id == "unlock_live_chara") + { + return isKor ? "라이브 시어터 전체 해방" : "ライブシアター全体解放"; + } + + if (id == "unlock_live_chara_info") + { + return isKor ? "미해금/미해방/미공개 곡 및 우마무스메와 드레스를 사용 가능하게 변경합니다." : "未解禁/未解放/未公開曲及びウマ娘とドレスを使えるように変更します。"; + } + if (id == "allow_delete_cookie") { return isKor ? "WebView Cookie 삭제 허용" : "WebView Cookieの削除を許可する"; @@ -89,11 +164,66 @@ namespace LocalifySettings return isKor ? "UI 애니메이션 배율" : "UIアニメーションスケール"; } + if (id == "resolution_3d_scale") + { + return isKor ? "3D 렌더링 해상도 배율" : "3Dレンダリングの解像度スケール"; + } + + if (id == "screen") + { + return isKor ? "화면" : "画面"; + } + + if (id == "unlock_size") + { + return isKor ? "해상도 고정 해제" : "解像度固定解除"; + } + + if (id == "use_system_resolution") + { + return isKor ? "시스템 해상도 사용" : "システムの解像度を使用する"; + } + + if (id == "ui_scale") + { + return isKor ? "UI 스케일" : "UIスケール"; + } + + if (id == "auto_fullscreen") + { + return isKor ? "자동 전체화면" : "自動全画面"; + } + + if (id == "freeform_window") + { + return isKor ? "자유 형식 창" : "自由形式ウィンドウ"; + } + + if (id == "ui_scale_portrait") + { + return isKor ? "UI 스케일 (세로)" : "UIスケール(縦)"; + } + + if (id == "ui_scale_landscape") + { + return isKor ? "UI 스케일 (가로)" : "UIスケール(横)"; + } + if (id == "experiments") { return "Experiments"; } + if (id == "initial_disclaimer_1") + { + return isKor ? "본 개선 모드를 사용함으로서 발생하는 이용 제한, 진행 오류 또는\n이외 기타 문제에 대한 책임은 본인에게 있습니다.\n\n계속 진행하려면 " : "本改善モードを使用することによって発生する利用制限、進行エラーまたは\nその他の問題に対する責任は本人にあります。\n\n続行するには、"; + } + + if (id == "initial_disclaimer_2") + { + return isKor ? " 를 체크해주세요." : "をチェックしてください。"; + } + return ""; } } diff --git a/src/stdinclude.hpp b/src/stdinclude.hpp index 3ad948c..69f0483 100644 --- a/src/stdinclude.hpp +++ b/src/stdinclude.hpp @@ -1,5 +1,7 @@ #pragma once +#define NOMINMAX + #include #include #include @@ -96,6 +98,11 @@ extern bool g_hide_now_loading; extern bool g_discord_rich_presence; extern bool g_allow_delete_cookie; extern bool g_localify_settings_force_korean; +extern bool g_dump_msgpack; +extern bool g_dump_msgpack_request; +extern bool g_unlock_live_chara; +extern bool g_notification_tp; +extern bool g_notification_rp; extern rapidjson::Document code_map;