fav working

This commit is contained in:
CrazyRedMachine 2024-04-28 22:42:04 +02:00
parent e838d88269
commit 5e57926b58

View File

@ -21,6 +21,7 @@
uint32_t g_playerdata_ptr_addr; //pointer to the playerdata memory zone (offset 0x08 is popn friend ID as ascii (12 char long), offset 0x1A5 is "is logged in" flag)
char *g_current_friendid;
uint32_t g_current_songid;
void (*add_song_in_list)();
//game code takes array start address from offset 0xC and the address after the list end from offset 0x10
@ -51,6 +52,29 @@ uint32_t favorites_count = 0;
songlist_t favorites_struct;
uint32_t favorites_struct_addr = (uint32_t)&favorites_struct;
void add_song_to_favorites()
{
favorites = (uint32_t *) realloc(favorites, sizeof(uint32_t)*(favorites_count+5));
favorites[favorites_count++] = g_current_songid | 0x00060000; // game wants this otherwise only easy difficulty will appear
return;
}
void remove_song_from_favorites()
{
for (uint32_t i = 0; i < favorites_count; i++)
{
if ( g_current_songid == (favorites[i] & 0x0000FFFF) )
{
for (uint32_t j = i+1; j < favorites_count; j++)
{
favorites[j-1] = favorites[j];
}
favorites_count--;
return;
}
}
return;
}
void prepare_favorite_list(){
char fav_filepath[64];
@ -77,8 +101,8 @@ void prepare_favorite_list(){
int songid = strtol(line, NULL, 10);
if ( songid != 0 )
{
favorites = (uint32_t *) realloc(favorites, sizeof(uint32_t)*(favorites_count+5));
favorites[favorites_count++] = songid | 0x00060000; // game wants this otherwise only easy difficulty will appear
g_current_songid = songid;
add_song_to_favorites();
}
}
fclose(file);
@ -86,6 +110,93 @@ void prepare_favorite_list(){
return;
}
void commit_favorites()
{
if ( favorites_count == 0 )
return;
char fav_filepath[64];
sprintf(fav_filepath, "data_mods\\%s.fav", g_current_friendid);
FILE *file = fopen(fav_filepath, "w");
if ( file == NULL )
{
file = fopen("data_mods\\default.fav", "w");
if (file == NULL)
{
return;
}
}
for (uint32_t i = 0; i < favorites_count; i++)
{
fprintf(file, "%d\n", (favorites[i] & 0x0000FFFF));
}
fclose(file);
return;
}
void (*real_song_is_in_favorite)();
void hook_song_is_in_favorite()
{
__asm("push ecx\n");
__asm("push edx\n");
//dx contains songid
__asm("mov _g_current_songid, dx\n");
for (uint32_t i = 0; i < favorites_count; i++)
{
if ( g_current_songid == (favorites[i] & 0x0000FFFF) )
{
__asm("pop edx\n");
__asm("pop ecx\n");
__asm("pop ebx\n");
__asm("mov eax, 0x01\n");
__asm("ret\n");
}
}
__asm("pop edx\n");
__asm("pop ecx\n");
__asm("pop ebx\n");
__asm("mov eax, 0x00\n");
__asm("ret\n");
}
void (*real_add_to_favorite)();
void hook_add_to_favorite()
{
__asm("push ecx\n");
//dx contains songid
__asm("mov _g_current_songid, dx\n");
add_song_to_favorites();
commit_favorites();
__asm("mov eax, [_favorites_count]\n");
__asm("mov edx, _g_current_songid\n");
__asm("pop ecx\n");
real_add_to_favorite();
}
void (*real_remove_from_favorite)();
void hook_remove_from_favorite()
{
//code pushes edi, esi and ebx as well
__asm("push ecx\n");
__asm("push edx\n");
//dx contains songid
__asm("mov _g_current_songid, cx\n");
remove_song_from_favorites();
commit_favorites();
__asm("pop edx\n");
__asm("pop ecx\n");
real_remove_from_favorite();
}
//this replaces the category handling function ( add_song_in_list is a subroutine called by the game )
void (*real_categ_favorite)();
void categ_inject_favorites()
@ -575,10 +686,6 @@ static bool patch_favorite_categ(const char *game_dll_fn) {
return false;
}
//uint64_t patch_addr = (int64_t)data + pattern_offset + 0x05 + 0x5A; //call to function when categ is favorites
uint64_t function_call_addr = (int64_t)(data + pattern_offset + 0x05 + 0x5A);
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
uint64_t function_addr = function_call_addr+5+function_offset;
@ -598,6 +705,36 @@ static bool patch_favorite_categ(const char *game_dll_fn) {
g_playerdata_ptr_addr = (*(uint32_t *)(data + pattern_offset + 0x25));
}
//hook result screen to replace 3 functions
{
int64_t pattern_offset = search(data, dllSize, "\xBF\x07\x00\x00\x00\xC6\x85\x61\xD3", 9, 0);
if (pattern_offset == -1) {
LOG("popnhax: custom_favorites: cannot find result screen function\n");
return false;
}
//song is in favorite
uint64_t function_call_addr = (int64_t)(data + pattern_offset + 0x5F);
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_song_is_in_favorite,
(void **)&real_song_is_in_favorite);
//add to favorites
uint64_t function2_call_addr = (int64_t)(data + pattern_offset + 0xBA);
uint32_t function2_offset = *((uint32_t*)(function2_call_addr +0x01));
uint64_t function2_addr = function2_call_addr+5+function2_offset;
MH_CreateHook((LPVOID)function2_addr, (LPVOID)hook_add_to_favorite,
(void **)&real_add_to_favorite);
//remove from favorites
uint64_t function3_call_addr = (int64_t)(data + pattern_offset + 0x89);
uint32_t function3_offset = *((uint32_t*)(function3_call_addr +0x01));
uint64_t function3_addr = function3_call_addr+5+function3_offset;
MH_CreateHook((LPVOID)function3_addr, (LPVOID)hook_remove_from_favorite,
(void **)&real_remove_from_favorite);
}
LOG("popnhax: custom_favorites: favorite category handling replaced\n");
return true;
}