mirror of
https://github.com/pumpitupdev/pumptools.git
synced 2026-10-02 03:38:03 +03:00
Version 1.08 with public source code release.
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* Hook library for Pump It Up: Pro
|
||||
*/
|
||||
#define LOG_MODULE "prohook"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "capnhook/hook/lib-main.h"
|
||||
#include "capnhook/hooklib/redir.h"
|
||||
|
||||
#include "hook/core/piu-utils.h"
|
||||
|
||||
#include "hook/patch/hook-mon.h"
|
||||
#include "hook/patch/piuio.h"
|
||||
#include "hook/patch/piuio-exit.h"
|
||||
#include "hook/patch/redir.h"
|
||||
#include "hook/patch/usb-emu.h"
|
||||
#include "hook/patch/usb-init-fix.h"
|
||||
#include "hook/patch/x11-event-loop.h"
|
||||
|
||||
#include "hook/propatch/usb-fix.h"
|
||||
|
||||
#include "hook/patch/piubtn.h"
|
||||
#include "hook/patch/piuio.h"
|
||||
|
||||
#include "util/fs.h"
|
||||
#include "util/glibc.h"
|
||||
#include "util/log.h"
|
||||
#include "util/sys-info.h"
|
||||
|
||||
#include "options.h"
|
||||
|
||||
static void prohook_bootstrapping(int argc, char** argv, struct prohook_options* options)
|
||||
{
|
||||
log_assert(argc >= 0);
|
||||
log_assert(argv);
|
||||
log_assert(options);
|
||||
|
||||
if (hook_core_piu_block_non_piu_process_recursion(argc, argv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
hook_core_piu_log_init(argc, argv);
|
||||
|
||||
if (!prohook_options_init(argc, argv, options)) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
hook_core_piu_log_info(argc, argv);
|
||||
|
||||
hook_core_piu_utils_verify_root_user();
|
||||
|
||||
log_info("Initializing");
|
||||
}
|
||||
|
||||
static void prohook_patch_fs_init(struct prohook_options* options)
|
||||
{
|
||||
log_assert(options);
|
||||
|
||||
patch_hook_mon_init(
|
||||
options->patch.hook_mon.io,
|
||||
options->patch.hook_mon.file,
|
||||
options->patch.hook_mon.fs,
|
||||
options->patch.hook_mon.usb,
|
||||
options->patch.hook_mon.open);
|
||||
|
||||
patch_redir_init();
|
||||
}
|
||||
|
||||
static void prohook_fs_redir_settings(struct prohook_options* options)
|
||||
{
|
||||
if (options->game.settings) {
|
||||
if (!util_fs_path_exists(options->game.settings)) {
|
||||
log_info("Settings path %s does not exist, creating", options->game.settings);
|
||||
|
||||
if (!util_fs_mkdir(options->game.settings)) {
|
||||
log_error("Creating directory %s failed", options->game.settings);
|
||||
}
|
||||
}
|
||||
|
||||
char* abs_path = util_fs_get_abs_path(options->game.settings);
|
||||
|
||||
cnh_redir_add("/data", abs_path);
|
||||
free(abs_path);
|
||||
} else {
|
||||
log_warn("No settings (data) path specified");
|
||||
}
|
||||
}
|
||||
|
||||
static void prohook_fs_redir_data(struct prohook_options* options)
|
||||
{
|
||||
if (options->game.data) {
|
||||
char* abs_path = util_fs_get_abs_path(options->game.data);
|
||||
|
||||
cnh_redir_add("/game", abs_path);
|
||||
free(abs_path);
|
||||
} else {
|
||||
log_warn("No data (game) path specified");
|
||||
}
|
||||
}
|
||||
|
||||
static void prohook_fs_redirs_init(struct prohook_options* options)
|
||||
{
|
||||
log_assert(options);
|
||||
|
||||
prohook_fs_redir_settings(options);
|
||||
prohook_fs_redir_data(options);
|
||||
}
|
||||
|
||||
static void prohook_patch_sigsegv_init(struct prohook_options* options)
|
||||
{
|
||||
log_assert(options);
|
||||
|
||||
/* seems like pump pro doesn't like it when injecting our own signal
|
||||
handler. game crashes instantly when adding it. */
|
||||
/*
|
||||
patch_sigsegv_init();
|
||||
*/
|
||||
}
|
||||
|
||||
static void prohook_patch_x11_event_loop_init(struct prohook_options* options)
|
||||
{
|
||||
patch_x11_event_loop_init();
|
||||
|
||||
// Register up to two X11 input handlers for piuio and piubtn
|
||||
|
||||
if (options->patch.x11_event_loop.api_lib) {
|
||||
char* abs_path_lib = util_fs_get_abs_path(options->patch.x11_event_loop.api_lib);
|
||||
|
||||
patch_x11_event_loop_add_input_handler(abs_path_lib);
|
||||
free(abs_path_lib);
|
||||
}
|
||||
|
||||
if (options->patch.x11_event_loop.api_lib2) {
|
||||
char* abs_path_lib = util_fs_get_abs_path(options->patch.x11_event_loop.api_lib2);
|
||||
|
||||
patch_x11_event_loop_add_input_handler(abs_path_lib);
|
||||
free(abs_path_lib);
|
||||
}
|
||||
}
|
||||
|
||||
static void prohook_patch_usbprofiles(struct prohook_options* options)
|
||||
{
|
||||
propatch_usb_fix_init(
|
||||
options->patch.usb_profile.device_nodes,
|
||||
options->patch.usb_profile.p1_bus_port,
|
||||
options->patch.usb_profile.p2_bus_port);
|
||||
}
|
||||
|
||||
static void prohook_patch_piuio_init(struct prohook_options* options)
|
||||
{
|
||||
log_assert(options);
|
||||
|
||||
/* Hook before IO emulation */
|
||||
if (options->patch.piuio.exit_test_serv) {
|
||||
patch_piuio_exit_init();
|
||||
}
|
||||
|
||||
patch_usb_init_fix_init();
|
||||
patch_usb_emu_init();
|
||||
|
||||
if (options->patch.piuio.api_lib) {
|
||||
char* abs_path_iolib = util_fs_get_abs_path(options->patch.piuio.api_lib);
|
||||
|
||||
patch_piuio_init(abs_path_iolib);
|
||||
free(abs_path_iolib);
|
||||
}
|
||||
}
|
||||
|
||||
static void prohook_patch_piubtn_init(struct prohook_options* options)
|
||||
{
|
||||
if (options->patch.piubtn.api_lib) {
|
||||
char* abs_path_btnlib = util_fs_get_abs_path(options->patch.piubtn.api_lib);
|
||||
|
||||
patch_piubtn_init(abs_path_btnlib);
|
||||
free(abs_path_btnlib);
|
||||
}
|
||||
}
|
||||
|
||||
void prohook_constructor(void)
|
||||
{
|
||||
/* Nothing here */
|
||||
}
|
||||
|
||||
void prohook_destructor(void)
|
||||
{
|
||||
/* Nothing here */
|
||||
}
|
||||
|
||||
void prohook_trap_before_main(int argc, char** argv)
|
||||
{
|
||||
log_assert(argc >= 0);
|
||||
log_assert(argv);
|
||||
|
||||
struct prohook_options options;
|
||||
|
||||
prohook_bootstrapping(argc, argv, &options);
|
||||
prohook_patch_fs_init(&options);
|
||||
prohook_fs_redirs_init(&options);
|
||||
prohook_patch_sigsegv_init(&options);
|
||||
prohook_patch_x11_event_loop_init(&options);
|
||||
prohook_patch_usbprofiles(&options);
|
||||
prohook_patch_piuio_init(&options);
|
||||
prohook_patch_piubtn_init(&options);
|
||||
|
||||
log_info("Hooking finished");
|
||||
}
|
||||
|
||||
void prohook_trap_after_main(void)
|
||||
{
|
||||
propatch_usb_fix_shutdown();
|
||||
patch_piubtn_shutdown();
|
||||
patch_piuio_shutdown();
|
||||
}
|
||||
|
||||
LIB_MAIN_CONSTRUCTOR(prohook_constructor);
|
||||
LIB_MAIN_DESTRUCTOR(prohook_destructor);
|
||||
LIB_MAIN_TRAP_MAIN(prohook_trap_before_main, prohook_trap_after_main);
|
||||
@@ -0,0 +1,197 @@
|
||||
#include "hook/pro/options.h"
|
||||
|
||||
#include "util/options.h"
|
||||
|
||||
#define PROHOOK_OPTIONS_STR_GAME_DATA "game.data"
|
||||
#define PROHOOK_OPTIONS_STR_GAME_SETTINGS "game.settings"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE "patch.hook_mon.file"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS "patch.hook_mon.fs"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO "patch.hook_mon.io"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN "patch.hook_mon.open"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB "patch.hook_mon.usb"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB "patch.piubtn.emu_lib"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB "patch.piuio.emu_lib"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV "patch.piuio_exit.test_serv"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT "patch.usb_profile.p1.bus_port"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT "patch.usb_profile.p2.bus_port"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES "patch.usb_profile.dev_nodes"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER "patch_x11_event_loop.input_handler_lib"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2 "patch_x11_event_loop.input_handler_lib2"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file"
|
||||
#define PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level"
|
||||
|
||||
static const struct util_options_def prohook_options_def[] = {
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_GAME_DATA,
|
||||
.description = "Path to game data (game) folder",
|
||||
.param = 'd',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = "./game",
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_GAME_SETTINGS,
|
||||
.description = "Path to game settings (data) folder",
|
||||
.param = 's',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = "./save",
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE,
|
||||
.description = "Enable file call monitoring",
|
||||
.param = 'f',
|
||||
.type = UTIL_OPTIONS_TYPE_BOOL,
|
||||
.default_value.b = false,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS,
|
||||
.description = "Enable file system related call monitoring",
|
||||
.param = 'g',
|
||||
.type = UTIL_OPTIONS_TYPE_BOOL,
|
||||
.default_value.b = false,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO,
|
||||
.description = "Enable IO syscall monitoring",
|
||||
.param = 'i',
|
||||
.type = UTIL_OPTIONS_TYPE_BOOL,
|
||||
.default_value.b = false,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN,
|
||||
.description = "Enable any file/IO open call monitoring",
|
||||
.param = 'j',
|
||||
.type = UTIL_OPTIONS_TYPE_BOOL,
|
||||
.default_value.b = false,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB,
|
||||
.description = "Enable libusb call monitoring",
|
||||
.param = 'u',
|
||||
.type = UTIL_OPTIONS_TYPE_BOOL,
|
||||
.default_value.b = false,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB,
|
||||
.description = "Path to library implementing the piubtn api for piubtn emulation",
|
||||
.param = 'b',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = NULL,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB,
|
||||
.description = "Path to library implementing the piuio api for piuio emulation",
|
||||
.param = 'p',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = NULL,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV,
|
||||
.description = "Enable game exit on Test + Service",
|
||||
.param = 'e',
|
||||
.type = UTIL_OPTIONS_TYPE_BOOL,
|
||||
.default_value.b = false,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT,
|
||||
.description = "Bus and port (format: X-X, e.g. 1-2) of the USB slot to assign to Player 1 when a USB thumb "
|
||||
"drive is plugged in",
|
||||
.param = 'a',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = NULL,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT,
|
||||
.description = "Bus and port (format: X-X, e.g. 1-2) of the USB slot to assign to Player 2 when a USB thumb "
|
||||
"drive is plugged in",
|
||||
.param = 'k',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = NULL,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES,
|
||||
.description = "Device nodes of plugged in USB thumb drives to consider for mounting for usb profiles, format: "
|
||||
"sdX,sdY e.g. sde,sdf",
|
||||
.param = 't',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = NULL,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER,
|
||||
.description = "Path to a library implementing the x11-input-handler api to capture X11 keyboard inputs",
|
||||
.param = 'q',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = NULL,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2,
|
||||
.description = "Path to a second library implementing the x11-input-handler api to capture X11 keyboard inputs",
|
||||
.param = 'r',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = NULL,
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE,
|
||||
.description = "Print the log output to the specified file",
|
||||
.param = 'o',
|
||||
.type = UTIL_OPTIONS_TYPE_STR,
|
||||
.default_value.str = "pumptools.log",
|
||||
},
|
||||
{
|
||||
.name = PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL,
|
||||
.description = "Set the log level (0-4)",
|
||||
.param = 'l',
|
||||
.type = UTIL_OPTIONS_TYPE_INT,
|
||||
.default_value.i = LOG_LEVEL_DEBUG,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct util_options_defs prohook_options_defs = {
|
||||
.usage_header =
|
||||
"Pumptools prohook for Pump It Up: Pro, build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV) "\n"
|
||||
"Usage: LD_PRELOAD=./prohook.so [game exec] [game data path] <options>",
|
||||
.usage_param = 'h',
|
||||
.defs = prohook_options_def,
|
||||
.ndefs = lengthof(prohook_options_def)
|
||||
};
|
||||
|
||||
bool prohook_options_init(int argc, char** argv, struct prohook_options* options)
|
||||
{
|
||||
log_assert(argv);
|
||||
log_assert(options);
|
||||
|
||||
struct util_options_opts* options_opt;
|
||||
|
||||
util_options_init(argc, argv);
|
||||
options_opt = util_options_get(&prohook_options_defs);
|
||||
|
||||
if (!options_opt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
options->game.data = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_GAME_DATA);
|
||||
options->game.settings = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_GAME_SETTINGS);
|
||||
options->patch.hook_mon.file = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FILE);
|
||||
options->patch.hook_mon.fs = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_FS);
|
||||
options->patch.hook_mon.io = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_IO);
|
||||
options->patch.hook_mon.open = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_OPEN);
|
||||
options->patch.hook_mon.usb = util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_HOOK_MON_USB);
|
||||
options->patch.piubtn.api_lib = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUBTN_EMU_LIB);
|
||||
options->patch.piuio.api_lib = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUIO_EMU_LIB);
|
||||
options->patch.piuio.exit_test_serv =
|
||||
util_options_get_bool(options_opt, PROHOOK_OPTIONS_STR_PATCH_PIUIO_EXIT_TEST_SERV);
|
||||
options->patch.usb_profile.device_nodes =
|
||||
util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_DEV_NODES);
|
||||
options->patch.usb_profile.p1_bus_port =
|
||||
util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P1_BUS_PORT);
|
||||
options->patch.usb_profile.p2_bus_port =
|
||||
util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_USB_PROFILE_P2_BUS_PORT);
|
||||
options->patch.x11_event_loop.api_lib =
|
||||
util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER);
|
||||
options->patch.x11_event_loop.api_lib2 =
|
||||
util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_X11_EVENT_LOOP_INPUT_HANDLER2);
|
||||
options->log.file = util_options_get_str(options_opt, PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_FILE);
|
||||
options->log.level =
|
||||
(enum util_log_level) util_options_get_int(options_opt, PROHOOK_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef PROHOOK_OPTIONS_H
|
||||
#define PROHOOK_OPTIONS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
struct prohook_options {
|
||||
struct game {
|
||||
const char* data;
|
||||
const char* settings;
|
||||
} game;
|
||||
|
||||
struct patch {
|
||||
struct hook_mon {
|
||||
bool file;
|
||||
bool fs;
|
||||
bool io;
|
||||
bool open;
|
||||
bool usb;
|
||||
} hook_mon;
|
||||
|
||||
struct piubtn {
|
||||
const char* api_lib;
|
||||
} piubtn;
|
||||
|
||||
struct piuio {
|
||||
const char* api_lib;
|
||||
bool exit_test_serv;
|
||||
} piuio;
|
||||
|
||||
struct usb_profile {
|
||||
const char* device_nodes;
|
||||
const char* p1_bus_port;
|
||||
const char* p2_bus_port;
|
||||
} usb_profile;
|
||||
|
||||
struct x11_event_loop {
|
||||
const char* api_lib;
|
||||
const char* api_lib2;
|
||||
} x11_event_loop;
|
||||
} patch;
|
||||
|
||||
struct log {
|
||||
const char* file;
|
||||
enum util_log_level level;
|
||||
} log;
|
||||
};
|
||||
|
||||
bool prohook_options_init(int argc, char** argv, struct prohook_options* options);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user