From b37061a2286450150b81551f1a3f12760c87c2cf Mon Sep 17 00:00:00 2001 From: frknkrc44 Date: Sun, 31 Aug 2025 02:03:02 +0300 Subject: [PATCH] Add "save sort and module mode" support No launcher implementation is required for now, because it saves the selected one after the Update() function is called. --- .../TLAC/Components/CustomPlayerData.h | 2 + .../TLAC/Components/PlayerDataManager.cpp | 39 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/source-code/source/plugins/TLAC/Components/CustomPlayerData.h b/source-code/source/plugins/TLAC/Components/CustomPlayerData.h index 5d9d3853..1f56092a 100644 --- a/source-code/source/plugins/TLAC/Components/CustomPlayerData.h +++ b/source-code/source/plugins/TLAC/Components/CustomPlayerData.h @@ -40,6 +40,8 @@ namespace TLAC::Components bool UseCard; bool GameModifierOptions; bool ActionSE; + int SortMode; + int ModuleMode; std::vector Mylist[3]; }; } diff --git a/source-code/source/plugins/TLAC/Components/PlayerDataManager.cpp b/source-code/source/plugins/TLAC/Components/PlayerDataManager.cpp index c9fd49d5..51bbadbc 100644 --- a/source-code/source/plugins/TLAC/Components/PlayerDataManager.cpp +++ b/source-code/source/plugins/TLAC/Components/PlayerDataManager.cpp @@ -217,6 +217,20 @@ namespace TLAC::Components } VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), oldProtect, &oldProtect); } + + // do not set the default module mode + { + void* initModuleModeSetter = (void*)0x1405bcba5; + size_t size = sizeof(uint8_t) * 10; + + VirtualProtect(initModuleModeSetter, size, PAGE_EXECUTE_READWRITE, &oldProtect); + { + // replace all instructions with NOP + for (int i = 0; i < 10; i++) + *(uint8_t*)(0x1405bcba5 + i) = NOP_OPCODE; + } + VirtualProtect(initModuleModeSetter, size, oldProtect, &oldProtect); + } } void PlayerDataManager::LoadConfig() @@ -236,6 +250,9 @@ namespace TLAC::Components config.TryGetValue("player_name", &customPlayerData->PlayerName); config.TryGetValue("level_name", &customPlayerData->LevelName); + customPlayerData->SortMode = config.GetIntegerValue("sort_mode", 2); + customPlayerData->ModuleMode = config.GetIntegerValue("module_mode", 2); + // ScoreSaver copies & declaring non-playerdata values std::string utf8path = TLAC::framework::GetModuleDirectory() + "/playerdata.ini"; MultiByteToWideChar(CP_UTF8, 0, utf8path.c_str(), -1, configPath, 256); @@ -292,6 +309,9 @@ namespace TLAC::Components setIfNotEqual(&playerData->slidertouch_se_equip_cmn, customPlayerData->SlidertouchSeEquip, -1); setIfNotEqual(&playerData->act_toggle, customPlayerData->ActionSE, 1); + *(int*)0x1411A8DD4 = customPlayerData->SortMode; + *(int*)0x1411A9790 = customPlayerData->ModuleMode; + std::string* mylistString; std::vector mylistStringVec; @@ -471,7 +491,24 @@ namespace TLAC::Components { playerData->use_pv_skin_equip = 1; } - + + int currentSortMode = *(int*)0x1411A8DD4; + if (currentSortMode != customPlayerData->SortMode) + { + customPlayerData->SortMode = currentSortMode; + WCHAR val[32]; + swprintf(val, 32, L"%d", currentSortMode); + WritePrivateProfileStringW(L"playerdata", L"sort_mode", val, configPath); + } + + int currentModuleMode = *(int*)0x1411A9790; + if (currentModuleMode != customPlayerData->ModuleMode) + { + customPlayerData->ModuleMode = currentModuleMode; + WCHAR val[32]; + swprintf(val, 32, L"%d", currentModuleMode); + WritePrivateProfileStringW(L"playerdata", L"module_mode", val, configPath); + } setIfNotEqual(&playerData->level, customPlayerData->LevelNum, 1); setIfNotEqual(&playerData->level_plate_id, customPlayerData->LevelPlateId, 0);