forked from Popn_Tools/popnhax
different favorite files per game version
This commit is contained in:
parent
e9bdbaa9f7
commit
0e1f365ac2
@ -4,6 +4,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct popnhax_config {
|
struct popnhax_config {
|
||||||
|
uint8_t game_version;
|
||||||
bool practice_mode;
|
bool practice_mode;
|
||||||
bool hidden_is_offset;
|
bool hidden_is_offset;
|
||||||
bool iidx_hard_gauge;
|
bool iidx_hard_gauge;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "minhook/hde32.h"
|
#include "minhook/hde32.h"
|
||||||
#include "minhook/include/MinHook.h"
|
#include "minhook/include/MinHook.h"
|
||||||
|
|
||||||
|
uint8_t g_game_version;
|
||||||
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)
|
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;
|
char *g_current_friendid;
|
||||||
uint32_t g_current_songid;
|
uint32_t g_current_songid;
|
||||||
@ -56,37 +57,37 @@ void add_song_to_favorites()
|
|||||||
{
|
{
|
||||||
favorites = (uint32_t *) realloc(favorites, sizeof(uint32_t)*(favorites_count+5));
|
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
|
favorites[favorites_count++] = g_current_songid | 0x00060000; // game wants this otherwise only easy difficulty will appear
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void remove_song_from_favorites()
|
void remove_song_from_favorites()
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < favorites_count; i++)
|
for (uint32_t i = 0; i < favorites_count; i++)
|
||||||
{
|
{
|
||||||
if ( g_current_songid == (favorites[i] & 0x0000FFFF) )
|
if ( g_current_songid == (favorites[i] & 0x0000FFFF) )
|
||||||
{
|
{
|
||||||
for (uint32_t j = i+1; j < favorites_count; j++)
|
for (uint32_t j = i+1; j < favorites_count; j++)
|
||||||
{
|
{
|
||||||
favorites[j-1] = favorites[j];
|
favorites[j-1] = favorites[j];
|
||||||
}
|
}
|
||||||
favorites_count--;
|
favorites_count--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare_favorite_list(){
|
void prepare_favorite_list(){
|
||||||
|
|
||||||
char fav_filepath[64];
|
char fav_filepath[64];
|
||||||
sprintf(fav_filepath, "data_mods\\%s.fav", g_current_friendid);
|
sprintf(fav_filepath, "data_mods\\%d.%s.fav", g_game_version, g_current_friendid);
|
||||||
FILE *file = fopen(fav_filepath, "rb");
|
FILE *file = fopen(fav_filepath, "rb");
|
||||||
|
|
||||||
favorites_count = 0;
|
favorites_count = 0;
|
||||||
|
|
||||||
if ( file == NULL )
|
if ( file == NULL )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char line[32];
|
char line[32];
|
||||||
|
|
||||||
@ -94,97 +95,97 @@ void prepare_favorite_list(){
|
|||||||
/* note that fgets don't strip the terminating \n, checking its
|
/* note that fgets don't strip the terminating \n, checking its
|
||||||
presence would allow to handle lines longer that sizeof(line) */
|
presence would allow to handle lines longer that sizeof(line) */
|
||||||
int songid = strtol(line, NULL, 10);
|
int songid = strtol(line, NULL, 10);
|
||||||
if ( songid != 0 )
|
if ( songid != 0 )
|
||||||
{
|
{
|
||||||
g_current_songid = songid;
|
g_current_songid = songid;
|
||||||
add_song_to_favorites();
|
add_song_to_favorites();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
//printf("added %d songs from %s to favorites\n",favorites_count,fav_filepath);
|
//printf("added %d songs from %s to favorites\n",favorites_count,fav_filepath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void commit_favorites()
|
void commit_favorites()
|
||||||
{
|
{
|
||||||
if ( favorites_count == 0 )
|
if ( favorites_count == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char fav_filepath[64];
|
char fav_filepath[64];
|
||||||
sprintf(fav_filepath, "data_mods\\%s.fav", g_current_friendid);
|
sprintf(fav_filepath, "data_mods\\%d.%s.fav", g_game_version, g_current_friendid);
|
||||||
FILE *file = fopen(fav_filepath, "w");
|
FILE *file = fopen(fav_filepath, "w");
|
||||||
|
|
||||||
if ( file == NULL )
|
if ( file == NULL )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < favorites_count; i++)
|
for (uint32_t i = 0; i < favorites_count; i++)
|
||||||
{
|
{
|
||||||
fprintf(file, "%d\n", (favorites[i] & 0x0000FFFF));
|
fprintf(file, "%d\n", (favorites[i] & 0x0000FFFF));
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*real_song_is_in_favorite)();
|
void (*real_song_is_in_favorite)();
|
||||||
void hook_song_is_in_favorite()
|
void hook_song_is_in_favorite()
|
||||||
{
|
{
|
||||||
__asm("push ecx\n");
|
__asm("push ecx\n");
|
||||||
__asm("push edx\n");
|
__asm("push edx\n");
|
||||||
//dx contains songid
|
//dx contains songid
|
||||||
__asm("mov _g_current_songid, dx\n");
|
__asm("mov _g_current_songid, dx\n");
|
||||||
|
|
||||||
for (uint32_t i = 0; i < favorites_count; i++)
|
for (uint32_t i = 0; i < favorites_count; i++)
|
||||||
{
|
{
|
||||||
if ( g_current_songid == (favorites[i] & 0x0000FFFF) )
|
if ( g_current_songid == (favorites[i] & 0x0000FFFF) )
|
||||||
{
|
{
|
||||||
__asm("pop edx\n");
|
__asm("pop edx\n");
|
||||||
__asm("pop ecx\n");
|
__asm("pop ecx\n");
|
||||||
__asm("pop ebx\n");
|
__asm("pop ebx\n");
|
||||||
__asm("mov eax, 0x01\n");
|
__asm("mov eax, 0x01\n");
|
||||||
__asm("ret\n");
|
__asm("ret\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__asm("pop edx\n");
|
__asm("pop edx\n");
|
||||||
__asm("pop ecx\n");
|
__asm("pop ecx\n");
|
||||||
__asm("pop ebx\n");
|
__asm("pop ebx\n");
|
||||||
__asm("mov eax, 0x00\n");
|
__asm("mov eax, 0x00\n");
|
||||||
__asm("ret\n");
|
__asm("ret\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*real_add_to_favorite)();
|
void (*real_add_to_favorite)();
|
||||||
void hook_add_to_favorite()
|
void hook_add_to_favorite()
|
||||||
{
|
{
|
||||||
__asm("push ecx\n");
|
__asm("push ecx\n");
|
||||||
//dx contains songid
|
//dx contains songid
|
||||||
__asm("mov _g_current_songid, dx\n");
|
__asm("mov _g_current_songid, dx\n");
|
||||||
|
|
||||||
add_song_to_favorites();
|
add_song_to_favorites();
|
||||||
commit_favorites();
|
commit_favorites();
|
||||||
|
|
||||||
__asm("mov eax, [_favorites_count]\n");
|
__asm("mov eax, [_favorites_count]\n");
|
||||||
__asm("mov edx, _g_current_songid\n");
|
__asm("mov edx, _g_current_songid\n");
|
||||||
__asm("pop ecx\n");
|
__asm("pop ecx\n");
|
||||||
real_add_to_favorite();
|
real_add_to_favorite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void (*real_remove_from_favorite)();
|
void (*real_remove_from_favorite)();
|
||||||
void hook_remove_from_favorite()
|
void hook_remove_from_favorite()
|
||||||
{
|
{
|
||||||
//code pushes edi, esi and ebx as well
|
//code pushes edi, esi and ebx as well
|
||||||
__asm("push ecx\n");
|
__asm("push ecx\n");
|
||||||
__asm("push edx\n");
|
__asm("push edx\n");
|
||||||
//dx contains songid
|
//dx contains songid
|
||||||
__asm("mov _g_current_songid, cx\n");
|
__asm("mov _g_current_songid, cx\n");
|
||||||
|
|
||||||
remove_song_from_favorites();
|
remove_song_from_favorites();
|
||||||
commit_favorites();
|
commit_favorites();
|
||||||
|
|
||||||
__asm("pop edx\n");
|
__asm("pop edx\n");
|
||||||
__asm("pop ecx\n");
|
__asm("pop ecx\n");
|
||||||
real_remove_from_favorite();
|
real_remove_from_favorite();
|
||||||
}
|
}
|
||||||
|
|
||||||
//this replaces the category handling function ( add_song_in_list is a subroutine called by the game )
|
//this replaces the category handling function ( add_song_in_list is a subroutine called by the game )
|
||||||
@ -685,7 +686,7 @@ static bool patch_favorite_categ(const char *game_dll_fn) {
|
|||||||
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
|
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
|
||||||
uint64_t function_addr = function_call_addr+5+function_offset;
|
uint64_t function_addr = function_call_addr+5+function_offset;
|
||||||
|
|
||||||
MH_CreateHook((LPVOID)function_addr, (LPVOID)categ_inject_favorites,
|
MH_CreateHook((LPVOID)function_addr, (LPVOID)categ_inject_favorites,
|
||||||
(void **)&real_categ_favorite);
|
(void **)&real_categ_favorite);
|
||||||
}
|
}
|
||||||
//categ_inject_favorites will need to force "logged in" status (for result screen)
|
//categ_inject_favorites will need to force "logged in" status (for result screen)
|
||||||
@ -964,37 +965,6 @@ static void load_databases() {
|
|||||||
}
|
}
|
||||||
LOG("\n");
|
LOG("\n");
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
bool load_favorites(){
|
|
||||||
favorites_count = subcategories[0].size;
|
|
||||||
favorites = subcategories[0].songlist;
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
bool load_favorites(){
|
|
||||||
FILE *file = fopen("data_mods\\default.fav", "rb");
|
|
||||||
|
|
||||||
if (file == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char line[32];
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), file)) {
|
|
||||||
/* note that fgets don't strip the terminating \n, checking its
|
|
||||||
presence would allow to handle lines longer that sizeof(line) */
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(file);
|
|
||||||
LOG("added %d songs to favorites\n",favorites_count);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void (*real_getversion)();
|
void (*real_getversion)();
|
||||||
void hook_getversion()
|
void hook_getversion()
|
||||||
@ -1049,12 +1019,12 @@ bool patch_exclude(const char *game_dll_fn)
|
|||||||
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
|
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
|
||||||
uint64_t function_addr = function_call_addr+5+function_offset;
|
uint64_t function_addr = function_call_addr+5+function_offset;
|
||||||
|
|
||||||
MH_CreateHook((LPVOID)function_addr, (LPVOID)hook_getversion,
|
MH_CreateHook((LPVOID)function_addr, (LPVOID)hook_getversion,
|
||||||
(void **)&real_getversion);
|
(void **)&real_getversion);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
//exclude from CS version category too
|
//exclude from CS version category too
|
||||||
{
|
{
|
||||||
int64_t pattern_offset = search(data, dllSize, "\xB8\x13\x05\x00\x00\x66\x3B\xF0", 8, 0);
|
int64_t pattern_offset = search(data, dllSize, "\xB8\x13\x05\x00\x00\x66\x3B\xF0", 8, 0);
|
||||||
if (pattern_offset == -1) {
|
if (pattern_offset == -1) {
|
||||||
LOG("popnhax: exclude_customs: cannot find getCSVersion calling function\n");
|
LOG("popnhax: exclude_customs: cannot find getCSVersion calling function\n");
|
||||||
@ -1065,12 +1035,12 @@ bool patch_exclude(const char *game_dll_fn)
|
|||||||
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
|
uint32_t function_offset = *((uint32_t*)(function_call_addr +0x01));
|
||||||
uint64_t function_addr = function_call_addr+5+function_offset;
|
uint64_t function_addr = function_call_addr+5+function_offset;
|
||||||
|
|
||||||
MH_CreateHook((LPVOID)function_addr, (LPVOID)hook_getcsversion,
|
MH_CreateHook((LPVOID)function_addr, (LPVOID)hook_getcsversion,
|
||||||
(void **)&real_getcsversion);
|
(void **)&real_getcsversion);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
LOG("popnhax: exclude_customs: Custom songs excluded from version listings\n");
|
LOG("popnhax: exclude_customs: Custom songs excluded from version listings\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool patch_custom_categs(const char *dllFilename, struct popnhax_config *config)
|
bool patch_custom_categs(const char *dllFilename, struct popnhax_config *config)
|
||||||
@ -1106,8 +1076,8 @@ LOG("custom title format is %s\n", g_customformat);
|
|||||||
return patch_custom_categ(dllFilename);
|
return patch_custom_categ(dllFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool patch_local_favorites(const char *dllFilename)
|
bool patch_local_favorites(const char *dllFilename, uint8_t version)
|
||||||
{
|
{
|
||||||
//load_favorites();
|
g_game_version = version;
|
||||||
return patch_favorite_categ(dllFilename);
|
return patch_favorite_categ(dllFilename);
|
||||||
}
|
}
|
@ -5,6 +5,6 @@
|
|||||||
#include "popnhax/config.h"
|
#include "popnhax/config.h"
|
||||||
|
|
||||||
bool patch_custom_categs(const char *dllFilename, struct popnhax_config *config);
|
bool patch_custom_categs(const char *dllFilename, struct popnhax_config *config);
|
||||||
bool patch_local_favorites(const char *dllFilename);
|
bool patch_local_favorites(const char *dllFilename, uint8_t version);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5303,6 +5303,22 @@ static bool option_net_ojama_off(){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t get_version()
|
||||||
|
{
|
||||||
|
DWORD dllSize = 0;
|
||||||
|
char *data = getDllData(g_game_dll_fn, &dllSize);
|
||||||
|
{
|
||||||
|
int64_t pattern_offset = search(data, dllSize, "\x00\x8B\x56\x04\x0F\xB7\x02\xE8", 8, 0);
|
||||||
|
if (pattern_offset == -1) {
|
||||||
|
LOG("popnhax: get_version: cannot retrieve game version (eclale or less?)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t version = *(uint8_t*)(data + pattern_offset + 14);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||||
switch (ul_reason_for_call) {
|
switch (ul_reason_for_call) {
|
||||||
case DLL_PROCESS_ATTACH: {
|
case DLL_PROCESS_ATTACH: {
|
||||||
@ -5374,7 +5390,9 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
free(tmp_name);
|
free(tmp_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("popnhax: game dll: %s\n",g_game_dll_fn);
|
uint8_t game_version = get_version();
|
||||||
|
|
||||||
|
LOG("popnhax: game dll: %s (popn%d)\n",g_game_dll_fn, game_version);
|
||||||
LOG("popnhax: config file: %s\n",g_config_fn);
|
LOG("popnhax: config file: %s\n",g_config_fn);
|
||||||
|
|
||||||
if (!_load_config(g_config_fn, &config, config_psmap))
|
if (!_load_config(g_config_fn, &config, config_psmap))
|
||||||
@ -5383,12 +5401,15 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.game_version = game_version;
|
||||||
|
|
||||||
if (force_trans_debug)
|
if (force_trans_debug)
|
||||||
config.translation_debug = true;
|
config.translation_debug = true;
|
||||||
|
|
||||||
if (force_no_omni)
|
if (force_no_omni)
|
||||||
config.patch_db = false;
|
config.patch_db = false;
|
||||||
|
|
||||||
|
|
||||||
if (!config.disable_multiboot)
|
if (!config.disable_multiboot)
|
||||||
{
|
{
|
||||||
/* automatically force datecode based on dll name when applicable (e.g. popn22_2022061300.dll and no force_datecode) */
|
/* automatically force datecode based on dll name when applicable (e.g. popn22_2022061300.dll and no force_datecode) */
|
||||||
@ -5398,21 +5419,26 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
LOG("popnhax: multiboot autotune activated (custom game dll, force_datecode off)\n");
|
LOG("popnhax: multiboot autotune activated (custom game dll, force_datecode off)\n");
|
||||||
memcpy(config.force_datecode, g_game_dll_fn+7, 10);
|
memcpy(config.force_datecode, g_game_dll_fn+7, 10);
|
||||||
LOG("popnhax: multiboot: auto set datecode to %s\n", config.force_datecode);
|
LOG("popnhax: multiboot: auto set datecode to %s\n", config.force_datecode);
|
||||||
if (config.score_challenge && ( strcmp(config.force_datecode,"2020092800") <= 0 ) )
|
if (config.score_challenge && ( config.game_version < 26 || strcmp(config.force_datecode,"2020092800") <= 0 ) )
|
||||||
{
|
{
|
||||||
LOG("popnhax: multiboot: auto disable score challenge patch (already ingame)\n");
|
LOG("popnhax: multiboot: auto disable score challenge patch (already ingame)\n");
|
||||||
config.score_challenge = false;
|
config.score_challenge = false;
|
||||||
}
|
}
|
||||||
if (config.patch_db && ( strcmp(config.force_datecode,"2016121400") < 0 ) )
|
if (config.patch_db && ( config.game_version == 0 || strcmp(config.force_datecode,"2016121400") < 0 ) )
|
||||||
{
|
{
|
||||||
LOG("popnhax: multiboot: auto disable omnimix patch (not compatible)\n");
|
LOG("popnhax: multiboot: auto disable omnimix patch (not compatible)\n");
|
||||||
config.patch_db = false;
|
config.patch_db = false;
|
||||||
}
|
}
|
||||||
if (config.guidese_off && ( strcmp(config.force_datecode,"2016121400") < 0 ) )
|
if (config.guidese_off && ( config.game_version == 0 || strcmp(config.force_datecode,"2016121400") < 0 ) )
|
||||||
{
|
{
|
||||||
LOG("popnhax: multiboot: auto disable Guide SE patch (not compatible)\n");
|
LOG("popnhax: multiboot: auto disable Guide SE patch (not compatible)\n");
|
||||||
config.guidese_off = false;
|
config.guidese_off = false;
|
||||||
}
|
}
|
||||||
|
if (config.local_favorites && ( config.game_version == 0 || strcmp(config.force_datecode,"2016121400") < 0 ) )
|
||||||
|
{
|
||||||
|
LOG("popnhax: multiboot: auto disable local favorites patch (not compatible)\n");
|
||||||
|
config.local_favorites = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5616,7 +5642,14 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config.local_favorites)
|
if (config.local_favorites)
|
||||||
patch_local_favorites(g_game_dll_fn);
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (config.force_full_opt)
|
if (config.force_full_opt)
|
||||||
option_full();
|
option_full();
|
||||||
|
Loading…
Reference in New Issue
Block a user