diff --git a/resources/config.json b/resources/config.json index ad1aebdc..6bd64a99 100644 --- a/resources/config.json +++ b/resources/config.json @@ -18,10 +18,10 @@ "readRequestPack": false, "extraAssetBundlePaths": ["localized_data/umamusumelocalify"], "replaceFont": true, - "customFontPath": "assets/bundledassets/umamusumelocalify/fonts/msyh.ttf", - "customFontSizeOffset": -4, - "customFontStyle": 1, - "customFontLinespacing": 0.9, + "customFontPath": "assets/bundledassets/umamusumelocalify/fonts/hanyi.otf", + "customFontSizeOffset": -1, + "customFontStyle": 0, + "customFontLinespacing": 0.6, "replaceAssets": true, "assetLoadLog": false, "live": { @@ -49,7 +49,7 @@ "z": 0 } }, - "cutin_first_persion": false, + "cutin_first_person": false, "externalPlugin": { "hotkey": "u", "path": "legend_g_plugin.exe", diff --git a/resources/config.schema.json b/resources/config.schema.json index 9e5d71e4..aebde058 100644 --- a/resources/config.schema.json +++ b/resources/config.schema.json @@ -234,7 +234,7 @@ }, "additionalProperties": false }, - "cutin_first_persion": { + "cutin_first_person": { "description": "CutIn 第一人称(使用 F 键切换)", "type": "boolean", "default": false diff --git a/resources/config_en.schema.json b/resources/config_en.schema.json index 821ea30c..49598427 100644 --- a/resources/config_en.schema.json +++ b/resources/config_en.schema.json @@ -234,8 +234,8 @@ }, "additionalProperties": false }, - "cutin_first_persion": { - "description": "CutIn first persion (perss F to switch).", + "cutin_first_person": { + "description": "CutIn first person (perss F to switch).", "type": "boolean", "default": false }, diff --git a/resources/config_zh_tw.schema.json b/resources/config_zh_tw.schema.json index 2cb2bf75..cecf2644 100644 --- a/resources/config_zh_tw.schema.json +++ b/resources/config_zh_tw.schema.json @@ -234,7 +234,7 @@ }, "additionalProperties": false }, - "cutin_first_persion": { + "cutin_first_person": { "description": "CutIn 第一人稱(F 鍵切換)", "type": "boolean", "default": false diff --git a/resources/legend_g_plugin.exe b/resources/legend_g_plugin.exe index d4768588..b894fbd1 100644 Binary files a/resources/legend_g_plugin.exe and b/resources/legend_g_plugin.exe differ diff --git a/src/hook.cpp b/src/hook.cpp index fae92d8b..443b9436 100644 --- a/src/hook.cpp +++ b/src/hook.cpp @@ -1399,11 +1399,7 @@ namespace bool (*Object_IsNativeObjectAlive)(void*); - void* TextCommon_Awake_orig; - void TextCommon_Awake_hook(void* _this) - { - reinterpret_cast(TextCommon_Awake_orig)(_this); - + void* getReplaceFont() { void* replaceFont{}; const auto& bundleHandle = GetBundleHandleByAssetName(std::get(g_replace_font).FontPath); if (std::holds_alternative(g_replace_font) && bundleHandle) @@ -1416,7 +1412,7 @@ namespace // AssetBundle 不会被干掉 if (Object_IsNativeObjectAlive(replaceFont)) { - goto FontAlive; + return replaceFont; } else { @@ -1435,8 +1431,16 @@ namespace std::wprintf(L"Cannot load asset font\n"); } } + return replaceFont; + } + + void* TextCommon_Awake_orig; + void TextCommon_Awake_hook(void* _this) + { + reinterpret_cast(TextCommon_Awake_orig)(_this); + + auto replaceFont = getReplaceFont(); - FontAlive: if (replaceFont) { Text_set_font(_this, replaceFont); @@ -1457,6 +1461,170 @@ namespace text_set_linespacing(_this, g_custom_font_linespacing); } + void* (*TMP_FontAsset_CreateFontAsset)(void* font); + void (*TMP_Text_set_font)(void* _this, void* fontAsset); + + void* TextMeshProUguiCommon_Awake_orig; + void TextMeshProUguiCommon_Awake_hook(void* _this) + { + static auto get_outlineWidth = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "get_outlineWidth", 0 + ) + ); + static auto set_outlineWidth = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "set_outlineWidth", 1 + ) + ); + static auto get_outlineColor = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "get_outlineColor", 0 + ) + ); + static auto set_outlineColor = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "set_outlineColor", 1 + ) + ); + + static auto SetOutlineThickness = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "SetOutlineThickness", 1 + ) + ); + static auto set_fontSize = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "set_fontSize", 1 + ) + ); + static auto get_fontSize = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "get_fontSize", 0 + ) + ); + + static auto u_get_OutlineColor = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", + "TextMeshProUguiCommon", "get_OutlineColor", 0 + ) + ); + static auto u_set_OutlineColor = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", + "TextMeshProUguiCommon", "set_OutlineColor", 1 + ) + ); + static auto u_get_OutlineSize = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", + "TextMeshProUguiCommon", "get_OutlineSize", 0 + ) + ); + static auto u_set_OutlineSize = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", + "TextMeshProUguiCommon", "set_OutlineSize", 1 + ) + ); + static auto UpdateOutline = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", + "TextMeshProUguiCommon", "UpdateOutline", 0 + ) + ); + + static auto set_sourceFontFile = reinterpret_cast( + il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_FontAsset", "set_sourceFontFile", 1 + ) + ); + + + auto origOutLineWidth = get_outlineWidth(_this); + auto origOutLineColor = get_outlineColor(_this); + auto origFontSize = get_fontSize(_this); + auto u_OrigColor = u_get_OutlineColor(_this); + auto u_OrigSize = u_get_OutlineSize(_this); + + // printf("TextMeshProUguiCommon_Awake: \n"); + reinterpret_cast(TextMeshProUguiCommon_Awake_orig)(_this); + + auto replaceFont = getReplaceFont(); + if (replaceFont) { + auto newFont = TMP_FontAsset_CreateFontAsset(replaceFont); + TMP_Text_set_font(_this, newFont); + + SetOutlineThickness(_this, 0.5f); + set_fontSize(_this, origFontSize + g_custom_font_size_offset); + set_outlineWidth(_this, origOutLineWidth); + set_outlineColor(_this, origOutLineColor); + u_set_OutlineColor(_this, u_OrigColor); + u_set_OutlineSize(_this, u_OrigSize); + UpdateOutline(_this); + } + } + + std::unordered_set updatedAnText{}; + + void* AnText_UpdateText_orig; + void AnText_UpdateText_hook(void* _this) { + static auto AnText_klass = il2cpp_symbols::get_class_from_instance(_this); + static FieldInfo* fontStyle_field = il2cpp_class_get_field_from_name(AnText_klass, "_fontStyle"); + static FieldInfo* fontSize_field = il2cpp_class_get_field_from_name(AnText_klass, "_fontSize"); + static FieldInfo* lineSpace_field = il2cpp_class_get_field_from_name(AnText_klass, "_lineSpace"); + + il2cpp_symbols::write_field(_this, fontStyle_field, g_custom_font_style); + il2cpp_symbols::write_field(_this, lineSpace_field, g_custom_font_linespacing); + if (!updatedAnText.contains(_this)) { + il2cpp_symbols::write_field(_this, fontSize_field, il2cpp_symbols::read_field(_this, fontSize_field) + g_custom_font_size_offset); + updatedAnText.emplace(_this); + } + + reinterpret_cast(AnText_UpdateText_orig)(_this); + } + + void* AnText_Destroy_orig; + void AnText_Destroy_hook(void* _this) { + updatedAnText.erase(_this); + reinterpret_cast(AnText_Destroy_orig)(_this); + } + + void* AnRootManager_GetFont_orig; + void* AnRootManager_GetFont_hook(void* _this, Il2CppString* fontName, bool fromCommon) { + // wprintf(L"AnRootManager_GetFont: %ls, fromCommon: %d\n", fontName->start_char, fromCommon); + // return getReplaceFont(); + return reinterpret_cast(AnRootManager_GetFont_orig)(_this, fontName, fromCommon); + } + + void* AnGlobalData_GetFont_orig; + void* AnGlobalData_GetFont_hook(void* _this, Il2CppString* fontName) { + // fontTable_key: FOT-Humming Std D + // fontTable_key: FOT-RodinWanpaku Pro EB + // fontTable_key: FOT-Yuruka Std UB + // commonFontTable 啥都没有 + + auto replaceFont = getReplaceFont(); + // wprintf(L"AnGlobalData_GetFont: %ls\n", fontName->start_char); + return replaceFont ? replaceFont : reinterpret_cast(AnGlobalData_GetFont_orig)(_this, fontName); + // return reinterpret_cast(AnGlobalData_GetFont_orig)(_this, il2cpp_string_new("FOT-Humming Std D0")); + } + void* AnGlobalData_GetFontFromCommon_orig; + void* AnGlobalData_GetFontFromCommon_hook(void* _this, Il2CppString* fontName) { + // wprintf(L"AnGlobalData_GetFontFromCommon: %ls\n", fontName->start_char); + auto replaceFont = getReplaceFont(); + return replaceFont ? replaceFont : reinterpret_cast(AnGlobalData_GetFontFromCommon_orig)(_this, fontName); + } + bool get_need_fullscreen(Resolution_t& r) { bool need_fullscreen = false; auto screen_ratio = r.width / static_cast(r.height); @@ -1877,6 +2045,13 @@ namespace _this, updateInfo); } + void* CheckSwapChara_orig; + void CheckSwapChara_hook(void* _this, int index, int oldCharaId, int oldDressId, int oldDressColorId, int oldDressId2, int oldDressColorId2, int newCharaId) { + if (g_bypass_live_205) return; + return reinterpret_cast(CheckSwapChara_orig)( + _this, index, oldCharaId, oldDressId, oldDressColorId, oldDressId2, oldDressColorId2, newCharaId); + } + void* alterupdate_camera_lookat_orig; void alterupdate_camera_lookat_hook(void* _this, Il2CppObject* sheet, int currentFrame, float currentTime, Vector3_t* outLookAt) { reinterpret_cast(alterupdate_camera_lookat_orig)( @@ -3614,7 +3789,7 @@ namespace { std::string pack(src, srcSize); std::vector new_buffer; - if (request_convert::live_bypass_pack(pack, &new_buffer)) + if (request_convert::live_bypass_pack(pack, &new_buffer) || request_convert::get_chara_bypass_pack(pack, &new_buffer)) { char* new_src = reinterpret_cast(&new_buffer[0]); memset(src + 170, 0, srcSize - 170); @@ -3739,6 +3914,13 @@ namespace return ret; } + void* WWWRequest_Post_orig; + void WWWRequest_Post_hook(void* _this, Il2CppString* url, void* postData, void* headers) { + // printf("Post url: %ls\n", url->start_char); + request_convert::setLastRequestUrl(url->start_char); + return reinterpret_cast(WWWRequest_Post_orig)(_this, url, postData, headers); + } + void dump_all_entries() { // 0 is None @@ -3953,8 +4135,20 @@ namespace "umamusume.dll", "Gallop", "TextCommon", "Awake", 0 ); + const auto TextMeshProUguiCommon_Awake_addr = il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", + "TextMeshProUguiCommon", "Awake", 0 + ); + TMP_FontAsset_CreateFontAsset = reinterpret_cast(il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_FontAsset", "CreateFontAsset", 1 + )); + TMP_Text_set_font = reinterpret_cast(il2cpp_symbols::get_method_pointer( + "Unity.TextMeshPro.dll", "TMPro", + "TMP_Text", "set_font", 1 + )); + - TextRubyDataClass = il2cpp_symbols::get_class("umamusume.dll", "", "TextRubyData"); TextRubyDataClass_DataArray = il2cpp_class_get_field_from_name(TextRubyDataClass, "DataArray"); @@ -4024,11 +4218,36 @@ namespace ) ); + //auto Unity_Text_set_font_addr = il2cpp_symbols::get_method_pointer( + // "UnityEngine.UI.dll", "UnityEngine.UI", + // "Text", "set_font", 1 + //); + + auto AnText_UpdateText_addr = il2cpp_symbols::get_method_pointer( + "Plugins.dll", "AnimateToUnity", + "AnText", "_UpdateText", 0 + ); + auto AnText_Destroy_addr = il2cpp_symbols::get_method_pointer( + "Plugins.dll", "AnimateToUnity", + "AnText", "_Destroy", 0 + ); + auto AnRootManager_GetFont_addr = il2cpp_symbols::get_method_pointer( + "Plugins.dll", "AnimateToUnity", + "AnRootManager", "_GetFont", 2 + ); + auto AnGlobalData_GetFont_addr = il2cpp_symbols::get_method_pointer( + "Plugins.dll", "AnimateToUnity", + "AnGlobalData", "_GetFont", 1 + ); + auto AnGlobalData_GetFontFromCommon_addr = il2cpp_symbols::get_method_pointer( + "Plugins.dll", "AnimateToUnity", + "AnGlobalData", "_GetFontFromCommon", 1 + ); + Text_set_font = reinterpret_cast( il2cpp_symbols::get_method_pointer( "UnityEngine.UI.dll", "UnityEngine.UI", - "Text", "set_font", 1 - ) + "Text", "set_font", 1) ); Text_set_horizontalOverflow = reinterpret_cast( @@ -4281,6 +4500,11 @@ namespace "StageController", "UpdateEnvironemntStageFovShift", 1 ); + auto CheckSwapChara_addr = il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", + "LiveTheaterCharaSelect", "CheckSwapChara", 7 + ); + auto Unity_get_fieldOfView_addr = il2cpp_resolve_icall("UnityEngine.Camera::get_fieldOfView()"); auto Unity_set_fieldOfView_addr = il2cpp_resolve_icall("UnityEngine.Camera::set_fieldOfView(System.Single)"); auto Unity_set_pos_injected_addr = il2cpp_resolve_icall("UnityEngine.Transform::set_position_Injected(UnityEngine.Vector3&)"); @@ -4536,6 +4760,12 @@ namespace MH_CreateHook(request_pack_ptr, request_pack_hook, &request_pack_orig); MH_EnableHook(request_pack_ptr); ADD_HOOK(get_ApplicationServerUrl, "get_ApplicationServerUrl at %p\n"); + + auto WWWRequest_Post_addr = il2cpp_symbols::get_method_pointer( + "Cute.Http.Assembly.dll", "Cute.Http", + "WWWRequest", "Post", 3 + ); + ADD_HOOK(WWWRequest_Post, "WWWRequest_Post at %p\n"); } #pragma endregion @@ -4553,6 +4783,7 @@ namespace ADD_HOOK(AlterUpdate_CameraPos, "AlterUpdate_CameraPos at %p\n"); ADD_HOOK(alterupdate_camera_lookat, "alterupdate_camera_lookat at %p\n"); // ADD_HOOK(UpdateEnvironemntStageFovShift, "UpdateEnvironemntStageFovShift at %p\n"); + ADD_HOOK(CheckSwapChara, "CheckSwapChara at %p\n"); ADD_HOOK(Unity_get_fieldOfView, "Unity_get_fieldOfView at %p\n"); ADD_HOOK(Unity_set_fieldOfView, "Unity_set_fieldOfView at %p\n"); ADD_HOOK(Unity_set_pos_injected, "Unity_set_pos_injected at %p\n"); @@ -4647,6 +4878,12 @@ namespace if (!std::holds_alternative(g_replace_font)) { ADD_HOOK(TextCommon_Awake, "Gallop.TextCommon::Awake at %p\n"); + ADD_HOOK(TextMeshProUguiCommon_Awake, "TextMeshProUguiCommon_Awake at %p\n"); + ADD_HOOK(AnText_UpdateText, "AnText_UpdateText at %p\n"); + ADD_HOOK(AnText_Destroy, "AnText_Destroy at %p\n"); + ADD_HOOK(AnRootManager_GetFont, "AnRootManager_GetFont at %p\n"); + ADD_HOOK(AnGlobalData_GetFont, "AnGlobalData_GetFont at %p\n"); + ADD_HOOK(AnGlobalData_GetFontFromCommon, "AnGlobalData_GetFontFromCommon at %p\n"); ADD_HOOK(text_set_size, "Text.set_size at %p\n"); if (!g_replace_assets) { diff --git a/src/local/local.cpp b/src/local/local.cpp index 2dc776f5..7e5439df 100644 --- a/src/local/local.cpp +++ b/src/local/local.cpp @@ -102,9 +102,8 @@ namespace local } std::unique_lock lock(db_lock); - if (text_db.contains(hash)) - { - *result = &text_db[hash]; + if (const auto it = text_db.find(hash); it != text_db.end()) { + *result = &it->second; return true; } diff --git a/src/main.cpp b/src/main.cpp index a2f69bdd..94c5beb9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -604,6 +604,9 @@ namespace if (document.HasMember("cutin_first_person")) { g_enable_cutin_first_person = document["cutin_first_person"].GetBool(); } + if (document.HasMember("cutin_first_persion")) { + printf("[WARNING] \"cutin_first_persion\" is an invalid configuration item. The correct one should be \"cutin_first_person\".\n"); + } if (document.HasMember("aspect_ratio_new")) { auto& asp = document["aspect_ratio_new"]; diff --git a/src/requestConvert/request_conv.cpp b/src/requestConvert/request_conv.cpp index 98606967..4b1f0e1b 100644 --- a/src/requestConvert/request_conv.cpp +++ b/src/requestConvert/request_conv.cpp @@ -9,6 +9,16 @@ std::unordered_set globalReadedNotices{}; namespace request_convert { + namespace { + std::wstring lastRequestUrl = L""; + std::unordered_set beforeGetNewCharaDataUrl{ { + std::wstring(L"https://api-umamusume.cygames.jp/umamusume/note/trainer_note"), + std::wstring(L"https://api-umamusume.cygames.jp/umamusume/card/get_release_card_array"), + std::wstring(L"https://api-umamusume.cygames.jp/umamusume/note/get_new_chara_data") + } }; + std::unordered_map musicMemberInfoArr{}; + } + web::http::http_response send_post(std::wstring url, std::wstring path, std::wstring data, int timeout) { web::http::client::http_client_config cfg; cfg.set_timeout(utility::seconds(timeout)); @@ -51,6 +61,33 @@ namespace request_convert return v.substr(4 + offset); } + void setLastRequestUrl(const std::wstring url) { + lastRequestUrl = url; + } + + bool get_chara_bypass_pack(const std::string pack, std::vector* new_buffer) + { + try + { + if (beforeGetNewCharaDataUrl.contains(lastRequestUrl)) { + auto json_data = nlohmann::json::from_msgpack(parse_request_pack(pack), false); + if (json_data.contains("chara_id")) { + if (json_data["chara_id"] < 3000) { + json_data["chara_id"] = 1001; + const auto new_buf = nlohmann::json::to_msgpack(json_data); + *new_buffer = new_buf; + return true; + } + } + } + } + catch (std::exception& e) + { + printf("Exception occurred in get_chara_bypass_pack: %s\n", e.what()); + } + return false; + } + bool live_bypass_pack(const std::string pack, std::vector* new_buffer) { try @@ -59,10 +96,22 @@ namespace request_convert if (json_data.contains("live_theater_save_info")) { printf("Catch live_theater_save_info\n"); + + int musicId = json_data["live_theater_save_info"]["music_id"]; + nlohmann::json memberInfoArray; + if (auto it = musicMemberInfoArr.find(musicId); it != musicMemberInfoArr.end()) { + memberInfoArray = it->second; + } + for (int i = 0; i < json_data["live_theater_save_info"]["member_info_array"].size(); i++) { - json_data["live_theater_save_info"]["member_info_array"][i]["chara_id"] = 0; - json_data["live_theater_save_info"]["member_info_array"][i]["mob_id"] = 8590 + i; - json_data["live_theater_save_info"]["member_info_array"][i]["dress_id"] = 7; + if (!memberInfoArray.is_array() || i >= memberInfoArray.size()) { + json_data["live_theater_save_info"]["member_info_array"][i]["chara_id"] = 0; + json_data["live_theater_save_info"]["member_info_array"][i]["mob_id"] = 8590 + i; + json_data["live_theater_save_info"]["member_info_array"][i]["dress_id"] = 7; + } + else { + json_data["live_theater_save_info"]["member_info_array"][i] = memberInfoArray[i]; + } } const auto new_buf = nlohmann::json::to_msgpack(json_data); *new_buffer = new_buf; @@ -80,6 +129,21 @@ namespace request_convert { try { + try { + auto json_data = nlohmann::json::from_msgpack(pack, false); + if (json_data.contains("data") && json_data["data"].contains("live_theater_save_info_array")) { + printf("Save live_theater_save_info_array cache.\n"); + for (auto& i : json_data["data"]["live_theater_save_info_array"]) { + int musicId = i["music_id"]; + nlohmann::json memberInfoArray = i["member_info_array"]; + musicMemberInfoArr.emplace(musicId, memberInfoArray); + } + return false; + } + } + catch (nlohmann::json::parse_error& e) { + } + if (!MHotkey::get_is_plugin_open()) return false; const auto data = send_msgpack_unparse_post(std::format(L"http://127.0.0.1:{}", http_start_port + 1), @@ -114,40 +178,38 @@ namespace request_convert } void check_and_upload_gacha_history(const std::string& pack) { - bool isHistory = false; - try { - auto jsonPack = nlohmann::json::from_msgpack(pack); - if (jsonPack.contains("data")) { - isHistory = true; - auto& data = jsonPack["data"]; - if (data.contains("gacha_exec_history_array") && data.contains("gacha_reward_history_array")) { - static auto autoupdateUrl = Get_autoupdateUrl(); - if (autoupdateUrl.empty()) return; + static auto get_UserName = reinterpret_cast(il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", "GallopUtil", "GetUserName", 0)); + static auto get_dmmViewerId = reinterpret_cast(il2cpp_symbols::get_method_pointer( + "umamusume.dll", "Gallop", "Certification", "get_dmmViewerId", 0)); - static auto get_UserName = reinterpret_cast(il2cpp_symbols::get_method_pointer( - "umamusume.dll", "Gallop", "GallopUtil", "GetUserName", 0)); - static auto get_dmmViewerId = reinterpret_cast(il2cpp_symbols::get_method_pointer( - "umamusume.dll", "Gallop", "Certification", "get_dmmViewerId", 0)); - auto userName = get_UserName(); - auto dmmViewerId = get_dmmViewerId(); - - jsonPack["user_name"] = utility::conversions::to_utf8string(userName->start_char); - jsonPack["dmm_viewer_id"] = utility::conversions::to_utf8string(dmmViewerId->start_char); - auto resp = send_post(g_upload_gacha_history_endpoint, "/api/upload/usergacha", jsonPack.dump()); - if (resp.status_code() == web::http::status_codes::OK) { - const auto userId = resp.extract_utf8string().get(); - printf("Upload gacha history success. Your id is: %s\nGo to %ls?uid=%s to view.\n", userId.c_str(), g_upload_gacha_history_endpoint.c_str(), userId.c_str()); + std::thread([pack]() { + bool isHistory = false; + try { + auto jsonPack = nlohmann::json::from_msgpack(pack); + if (jsonPack.contains("data")) { + isHistory = true; + auto& data = jsonPack["data"]; + if (data.contains("gacha_exec_history_array") && data.contains("gacha_reward_history_array")) { + auto userName = get_UserName(); + auto dmmViewerId = get_dmmViewerId(); + jsonPack["user_name"] = utility::conversions::to_utf8string(userName->start_char); + jsonPack["dmm_viewer_id"] = utility::conversions::to_utf8string(dmmViewerId->start_char); + auto resp = send_post(g_upload_gacha_history_endpoint, "/api/upload/usergacha", jsonPack.dump()); + if (resp.status_code() == web::http::status_codes::OK) { + const auto userId = resp.extract_utf8string().get(); + printf("Upload gacha history success. Your id is: %s\nGo to %ls?uid=%s to view.\n", userId.c_str(), g_upload_gacha_history_endpoint.c_str(), userId.c_str()); + } } } } - } - catch (nlohmann::json::exception& ex) { - if (ex.id != 113) printf("ParseGHError: %s\n", ex.what()); - } - catch (std::exception& ex) { - if (isHistory) printf("Upload gacha history failed: %s\n", ex.what()); - } - + catch (nlohmann::json::exception& ex) { + if (ex.id != 113) printf("ParseGHError: %s\n", ex.what()); + } + catch (std::exception& ex) { + if (isHistory) printf("Upload gacha history failed: %s\n", ex.what()); + } + }).detach(); } void updateNotice() { diff --git a/src/requestConvert/request_conv.hpp b/src/requestConvert/request_conv.hpp index 0decd0c6..5cb63a73 100644 --- a/src/requestConvert/request_conv.hpp +++ b/src/requestConvert/request_conv.hpp @@ -13,6 +13,8 @@ namespace request_convert void check_and_upload_gacha_history(const std::string& pack); bool live_bypass_pack(std::string pack, std::vector* new_buffer); bool live_unlock_dress(std::string pack, std::vector* new_buffer); + void setLastRequestUrl(const std::wstring url); + bool get_chara_bypass_pack(const std::string pack, std::vector* new_buffer); void updateNotice(); void startUpdateNotice();