From 136e01728e258bafc5ea97b0af5102e8d3e364c4 Mon Sep 17 00:00:00 2001 From: CrazyRedMachine Date: Mon, 24 Jun 2024 22:53:18 +0200 Subject: [PATCH] local_favorites_path, local_favorite fix numpad9 --- dist/popnhax/popnhax.xml | 4 +++ popnhax/config.h | 4 ++- popnhax/custom_categs.cc | 76 ++++++++++++++++++++++++++++++++++------ popnhax/custom_categs.h | 2 +- popnhax/dllmain.cc | 57 +++++++++++++++++++++++++----- 5 files changed, 122 insertions(+), 21 deletions(-) diff --git a/dist/popnhax/popnhax.xml b/dist/popnhax/popnhax.xml index 7d32c0f..b235d66 100644 --- a/dist/popnhax/popnhax.xml +++ b/dist/popnhax/popnhax.xml @@ -163,6 +163,10 @@ + + + + 0 diff --git a/popnhax/config.h b/popnhax/config.h index 061aade..8346147 100644 --- a/popnhax/config.h +++ b/popnhax/config.h @@ -32,12 +32,13 @@ struct popnhax_config { bool netvs_off; bool guidese_off; bool local_favorites; + char local_favorites_path[MAX_PATH-18]; // xx.yyyyyyyyyyyy.fav bool patch_db; bool disable_multiboot; bool patch_xml_dump; bool ignore_music_limit; - char force_patch_xml[MAX_PATH]; + char force_patch_xml[MAX_PATH+1]; char force_datecode[11]; bool network_datecode; int8_t audio_offset; @@ -70,6 +71,7 @@ struct popnhax_config { bool survival_iidx; bool survival_spicy; bool translation_debug; + float time_multiplier; }; bool config_process(const char *filepath); // take care of updating .xml/.opt files if needed diff --git a/popnhax/custom_categs.cc b/popnhax/custom_categs.cc index 3990f76..fd33152 100644 --- a/popnhax/custom_categs.cc +++ b/popnhax/custom_categs.cc @@ -23,6 +23,7 @@ #define F_OK 0 + //game code takes array start address from offset 0xC and the address after the list end from offset 0x10 typedef struct songlist_s { uint32_t dummy[3]; @@ -44,6 +45,7 @@ bool g_subcategmode = false; const char *g_categicon; const char *g_categformat; +const char *g_favorite_path; char *g_categname; char *g_customformat; @@ -93,10 +95,10 @@ void remove_song_from_favorites() return; } -void prepare_favorite_list(){ - - char fav_filepath[64]; - sprintf(fav_filepath, "data_mods\\%d.%s.fav", g_game_version, g_current_friendid); +void prepare_favorite_list() +{ + char fav_filepath[MAX_PATH+1]; + sprintf(fav_filepath, "%s\\%d.%s.fav", g_favorite_path, g_game_version, g_current_friendid); FILE *file = fopen(fav_filepath, "rb"); favorites_count = 0; @@ -123,8 +125,8 @@ void prepare_favorite_list(){ void commit_favorites() { - char fav_filepath[64]; - sprintf(fav_filepath, "data_mods\\%d.%s.fav", g_game_version, g_current_friendid); + char fav_filepath[MAX_PATH+1]; + sprintf(fav_filepath, "%s\\%d.%s.fav", g_favorite_path, g_game_version, g_current_friendid); FILE *file = fopen(fav_filepath, "w"); if ( file == NULL ) @@ -687,6 +689,33 @@ static bool patch_custom_track_format(const char *game_dll_fn) { return true; } + +void (*real_check_event_boosts)(); +void hook_check_event_boosts() +{ + __asm("push ecx\n"); + __asm("mov eax, dword ptr [_g_playerdata_ptr_addr]\n"); + __asm("mov eax, [eax]\n"); + __asm("lea ecx, [eax+0x08]\n"); //friendid offset + __asm("mov ecx, [ecx]\n"); + __asm("cmp ecx, 0x61666564\n"); //defa + __asm("jne skip_force_false\n"); + __asm("lea ecx, [eax+0x0C]\n"); //friendid offset + __asm("mov ecx, [ecx]\n"); + __asm("cmp ecx, 0x00746C75\n"); //ult + __asm("jne skip_force_false\n"); + + //fake login detected, force return false (will prevent 9 icon to show up and 9 press to softlock game) + __asm("mov eax, 0x00000000\n"); + __asm("pop ecx\n"); + __asm("ret\n"); + + __asm("skip_force_false:\n"); + + __asm("pop ecx\n"); + real_check_event_boosts(); +} + void (*real_remove_fake_login)(); void hook_remove_fake_login() { @@ -712,7 +741,7 @@ void hook_remove_fake_login() real_remove_fake_login(); } -static bool patch_favorite_categ(const char *game_dll_fn) { +static bool patch_favorite_categ(const char *game_dll_fn, bool with_numpad9_patch) { DWORD dllSize = 0; char *data = getDllData(game_dll_fn, &dllSize); @@ -767,7 +796,7 @@ static bool patch_favorite_categ(const char *game_dll_fn) { g_playerdata_ptr_addr = (*(uint32_t *)(data + pattern_offset + 0x25)); } - //and I need to remove the fake "logged in" status on credit end to prevent a crash + //I need to remove the fake "logged in" status on credit end to prevent a crash { int64_t pattern_offset = search(data, dllSize, "\x84\xC0\x74\x07\xBB\x01\x00\x00\x00\xEB\x02\x33\xDB", 13, 0); if (pattern_offset == -1) { @@ -824,8 +853,25 @@ static bool patch_favorite_categ(const char *game_dll_fn) { uint64_t function3_addr = function3_call_addr+5+function3_offset; MH_CreateHook((LPVOID)function3_addr, (LPVOID)hook_add_to_favorite, (void **)&real_add_to_favorite); - } + + //(202310+) I need to prevent the numpad9 option in song select when fake logged in to prevent a possible softlock + if (with_numpad9_patch) + { + int64_t first_loc = search(data, dllSize, "\x0F\xB6\xC8\x51\x56\x8B\xCD\xE8", 8, 0); + if (first_loc == -1) { + LOG("WARNING: local_favorites: cannot find song select screen function, do NOT press 9 on song select\n"); + goto local_favorite_ok; + } + + uint64_t function_call_addr = (int64_t)(data + first_loc - 0x05); + uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01)); + uint64_t function_addr = function_call_addr+5+function_offset; + MH_CreateHook((LPVOID)function_addr, (LPVOID)hook_check_event_boosts, + (void **)&real_check_event_boosts); + } + +local_favorite_ok: LOG("popnhax: favorite category uses local files\n"); return true; } @@ -1108,8 +1154,16 @@ bool patch_custom_categs(const char *dllFilename, struct popnhax_config *config) return true; } -bool patch_local_favorites(const char *dllFilename, uint8_t version) +bool patch_local_favorites(const char *dllFilename, uint8_t version, char *fav_folder, bool with_numpad9_patch) { + if ( fav_folder != NULL && strlen(fav_folder) > 0 ) + { + g_favorite_path = strdup(fav_folder); + } + else + { + g_favorite_path = strdup("data_mods"); + } g_game_version = version; - return patch_favorite_categ(dllFilename); + return patch_favorite_categ(dllFilename, with_numpad9_patch); } \ No newline at end of file diff --git a/popnhax/custom_categs.h b/popnhax/custom_categs.h index a8ff472..41ad957 100644 --- a/popnhax/custom_categs.h +++ b/popnhax/custom_categs.h @@ -19,6 +19,6 @@ void add_song_to_subcateg(uint32_t songid, subcategory_s* subcateg); subcategory_s* get_subcateg(const char *title); bool patch_custom_categs(const char *dllFilename, struct popnhax_config *config); -bool patch_local_favorites(const char *dllFilename, uint8_t version); +bool patch_local_favorites(const char *dllFilename, uint8_t version, char *fav_folder, bool with_numpad9_patch); #endif diff --git a/popnhax/dllmain.cc b/popnhax/dllmain.cc index b07cbda..02fe24a 100644 --- a/popnhax/dllmain.cc +++ b/popnhax/dllmain.cc @@ -44,7 +44,6 @@ FILE *g_log_fp = NULL; #define DEBUG 0 -#if DEBUG == 1 double g_multiplier = 1.; DWORD (*real_timeGetTime)(); DWORD patch_timeGetTime() @@ -67,11 +66,17 @@ DWORD patch_timeGetTime() } -bool patch_get_time() +bool patch_get_time(double time_multiplier) { + if (time_multiplier == 0) + return true; + + g_multiplier = time_multiplier; HMODULE hinstLib = GetModuleHandleA("winmm.dll"); MH_CreateHook((LPVOID)GetProcAddress(hinstLib, "timeGetTime"), (LPVOID)patch_timeGetTime, (void **)&real_timeGetTime); + + LOG("popnhax: time multiplier: %f\n", time_multiplier); return true; } @@ -87,7 +92,6 @@ static void memdump(uint8_t* addr, uint8_t len) } } -#endif uint8_t *add_string(uint8_t *input); @@ -198,6 +202,8 @@ PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_STR, struct popnhax_config, custom_track_ti "/popnhax/custom_track_title_format2") PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, local_favorites, "/popnhax/local_favorites") +PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_STR, struct popnhax_config, local_favorites_path, + "/popnhax/local_favorites_path") PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, ignore_music_limit, "/popnhax/ignore_music_limit") PSMAP_MEMBER_REQ(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, high_framerate, @@ -219,6 +225,8 @@ PSMAP_MEMBER_OPT(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, disable_redire "/popnhax/disable_redirection", false) PSMAP_MEMBER_OPT(PSMAP_PROPERTY_TYPE_BOOL, struct popnhax_config, translation_debug, "/popnhax/translation_debug", false) +PSMAP_MEMBER_OPT(PSMAP_PROPERTY_TYPE_FLOAT, struct popnhax_config, time_multiplier, + "/popnhax/time_multiplier", 0) PSMAP_END enum BufferIndexes { @@ -8177,8 +8185,43 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv if ( config.game_version == 0 ) { LOG("popnhax: local_favorites: patch is not compatible with your game version.\n"); - } else { - patch_local_favorites(g_game_dll_fn, config.game_version); + } + else + { + if ( strlen(config.local_favorites_path) > 0 ) + { + while ( config.local_favorites_path[strlen(config.local_favorites_path)-1] == '\\' ) + { + config.local_favorites_path[strlen(config.local_favorites_path)-1] = '\0'; + } + if (access(config.local_favorites_path, F_OK) == 0) + LOG("popnhax: local_favorites: favorites are stored in %s\n", config.local_favorites_path); + else + { + LOG("WARNING: local_favorites: cannot access %s, defaulting to data_mods folder\n", config.local_favorites_path); + config.local_favorites_path[0] = '\0'; + } + } + + uint8_t *datecode = NULL; + if ( g_datecode_override != NULL ) + { + datecode = (uint8_t*) strdup(g_datecode_override); + } + else + { + property *config_xml = load_prop_file("prop/ea3-config.xml"); + READ_STR_OPT(config_xml, property_search(config_xml, NULL, "/ea3/soft"), "ext", datecode) + free(config_xml); + } + + if (datecode == NULL) { + LOG("popnhax: local_favorites: failed to retrieve datecode.\n"); + } + + patch_local_favorites(g_game_dll_fn, config.game_version, config.local_favorites_path, ( datecode != NULL && strcmp((char*)datecode,"2023101700") >= 0 ) ); + free(datecode); + } } @@ -8215,9 +8258,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv patch_hispeed_auto(config.hispeed_auto); } - #if DEBUG == 1 - patch_get_time(); - #endif + patch_get_time(config.time_multiplier); MH_EnableHook(MH_ALL_HOOKS);