diff --git a/DivaHook/rom/playerdata.ini b/DivaHook/rom/playerdata.ini index a627644..58e79f8 100644 --- a/DivaHook/rom/playerdata.ini +++ b/DivaHook/rom/playerdata.ini @@ -3,6 +3,7 @@ # this file has to be encoded with utf-8 player_name = NO-NAME +level_name = 忘れないでね私の声を # IDs defined in rom/gm_plate_tbl/gm_plate_id.bin level_plate_id = 0 @@ -14,4 +15,4 @@ skin_equip = 0 btn_se_equip = -1 # IDs defined in rom/gm_slide_se_tbl/gm_slide_se_id.bin -chainslide_se_equip = -1 \ No newline at end of file +chainslide_se_equip = -1 diff --git a/DivaHook/src/Components/CustomPlayerData.h b/DivaHook/src/Components/CustomPlayerData.h index 5b71d52..5500a7f 100644 --- a/DivaHook/src/Components/CustomPlayerData.h +++ b/DivaHook/src/Components/CustomPlayerData.h @@ -6,6 +6,7 @@ namespace DivaHook::Components struct CustomPlayerData { std::string *PlayerName; + std::string *LevelName; int LevelPlateId; int SkinEquip; int BtnSeEquip; diff --git a/DivaHook/src/Components/PlayerDataManager.cpp b/DivaHook/src/Components/PlayerDataManager.cpp index 42bf953..8301810 100644 --- a/DivaHook/src/Components/PlayerDataManager.cpp +++ b/DivaHook/src/Components/PlayerDataManager.cpp @@ -54,6 +54,28 @@ namespace DivaHook::Components *(uint8_t*)(SET_DEFAULT_PLAYER_DATA_ADDRESS) = RET_OPCODE; } VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), oldProtect, &oldProtect); + + // allow player to select the module and extra item + VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte)*2, PAGE_EXECUTE_READWRITE, &oldProtect); + { + *(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS) = 0xB0; // xor al,al -> ld al,1 + *(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS + 0x1) = 0x01; + } + VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte)*2, oldProtect, &oldProtect); + + // fix annoying behavior of closing after changing module or item (don't yet know the reason, maybe NW/Card checks) + { + VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect); + { + *(uint8_t*)(MODSELECTOR_CLOSE_AFTER_MODULE) = JNE_OPCODE; + } + VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), oldProtect, &oldProtect); + VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect); + { + *(uint8_t*)(MODSELECTOR_CLOSE_AFTER_CUSTOMIZE) = JNE_OPCODE; + } + VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), oldProtect, &oldProtect); + } } void PlayerDataManager::LoadConfig() @@ -87,6 +109,7 @@ namespace DivaHook::Components }; config.TryGetValue("player_name", customPlayerData->PlayerName); + config.TryGetValue("level_name", &customPlayerData->LevelName); customPlayerData->LevelPlateId = parseInt("level_plate_id"); customPlayerData->SkinEquip = parseInt("skin_equip"); @@ -107,11 +130,22 @@ namespace DivaHook::Components setIfNotEqual(&playerData->skin_equip, customPlayerData->SkinEquip, 0); setIfNotEqual(&playerData->btn_se_equip, customPlayerData->BtnSeEquip, -1); setIfNotEqual(&playerData->chainslide_se_equip, customPlayerData->ChainslideSeEquip, -1); + + playerData->use_card = 1; // required to allow for module selection + + memset((void *)MODULE_TABLE_START, 0xFF, 128); + memset((void*)ITEM_TABLE_START, 0xFF, 128); if (customPlayerData->PlayerName != nullptr) { playerData->field_DC = 0x10; playerData->player_name = (char*)customPlayerData->PlayerName->c_str(); } + + if (customPlayerData->LevelName != nullptr) { + playerData->level_name = (char*)customPlayerData->LevelName->c_str(); + playerData->field_110 = 0xFF; + playerData->field_118 = 0x1F; + } } } diff --git a/DivaHook/src/Constants.h b/DivaHook/src/Constants.h index 3e595af..b02fd9f 100644 --- a/DivaHook/src/Constants.h +++ b/DivaHook/src/Constants.h @@ -4,6 +4,8 @@ constexpr uint8_t NOP_OPCODE = 0x90; constexpr uint8_t RET_OPCODE = 0xC3; constexpr uint8_t JMP_OPCODE = 0xE9; +constexpr uint8_t JNE_OPCODE = 0x85; + constexpr uint64_t ENGINE_UPDATE_HOOK_TARGET_ADDRESS = 0x000000014018CC40; constexpr uint64_t ENGINE_UPDATE_INPUT_ADDRESS = 0x000000014018CBB0; @@ -31,4 +33,12 @@ constexpr uint64_t PLAYS_PER_SESSION_GETTER_ADDRESS = 0x000000014038AEE0; constexpr uint64_t UPDATE_TASKS_ADDRESS = 0x000000014019B980; constexpr uint64_t GLUT_SET_CURSOR_ADDRESS = 0x00000001408B68E6; constexpr uint64_t CHANGE_MODE_ADDRESS = 0x00000001401953D0; -constexpr uint64_t CHANGE_SUB_MODE_ADDRESS = 0x0000000140195260; \ No newline at end of file +constexpr uint64_t CHANGE_SUB_MODE_ADDRESS = 0x0000000140195260; + +constexpr uint64_t MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS = 0x00000001405869AD; +constexpr uint64_t MODSELECTOR_CLOSE_AFTER_MODULE = 0x0000000140583B45; +constexpr uint64_t MODSELECTOR_CLOSE_AFTER_CUSTOMIZE = 0x0000000140583C8C; +constexpr uint64_t MODULE_TABLE_START = PLAYER_DATA_ADDRESS + 0x140; +constexpr uint64_t MODULE_TABLE_END = MODULE_TABLE_START + 128; +constexpr uint64_t ITEM_TABLE_START = PLAYER_DATA_ADDRESS + 0x2B8; +constexpr uint64_t ITEM_TABLE_END = ITEM_TABLE_START + 128;