mirror of
https://github.com/pumpitupdev/pumptools.git
synced 2026-10-01 11:17:55 +03:00
Version 1.08 with public source code release.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#include "hook/core/options.h"
|
||||
|
||||
#include "util/options.h"
|
||||
|
||||
#define HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_FILE "util.log.file"
|
||||
#define HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL "util.log.level"
|
||||
|
||||
const struct util_options_def hook_core_options_def[] = {
|
||||
{
|
||||
.name = HOOK_CORE_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 = HOOK_CORE_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,
|
||||
},
|
||||
};
|
||||
|
||||
const struct util_options_defs hook_core_options_defs = {
|
||||
.usage_header = "",
|
||||
// Just use something because this is not relevant/required here
|
||||
.usage_param = '\r',
|
||||
.defs = hook_core_options_def,
|
||||
.ndefs = lengthof(hook_core_options_def)
|
||||
};
|
||||
|
||||
void hook_core_options_init(int argc, char** argv, struct hook_core_options* options)
|
||||
{
|
||||
log_assert(argv);
|
||||
log_assert(options);
|
||||
|
||||
struct util_options_opts* options_opt;
|
||||
|
||||
util_options_init(argc, argv);
|
||||
options_opt = util_options_get(&hook_core_options_defs);
|
||||
|
||||
if (!options_opt) {
|
||||
return;
|
||||
}
|
||||
|
||||
options->log.file = util_options_get_str(options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_FILE);
|
||||
options->log.level =
|
||||
(enum util_log_level) util_options_get_int(options_opt, HOOK_CORE_OPTIONS_STR_PATCH_UTIL_LOG_LEVEL);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef HOOK_CORE_OPTIONS_H
|
||||
#define HOOK_CORE_OPTIONS_H
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
struct hook_core_options {
|
||||
struct log {
|
||||
const char* file;
|
||||
enum util_log_level level;
|
||||
} log;
|
||||
};
|
||||
|
||||
void hook_core_options_init(int argc, char** argv, struct hook_core_options* options);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,133 @@
|
||||
#define LOG_MODULE "hook-core-piu-utils"
|
||||
|
||||
#include <locale.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hook/core/options.h"
|
||||
|
||||
#include "util/fs.h"
|
||||
#include "util/glibc.h"
|
||||
#include "util/log.h"
|
||||
#include "util/proc.h"
|
||||
#include "util/str.h"
|
||||
#include "util/sys-info.h"
|
||||
|
||||
static void hook_core_piu_log_application_args(int argc, char** argv)
|
||||
{
|
||||
const char* sep = "\n";
|
||||
char* str = util_str_dup("");
|
||||
char* tmp;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (strlen(str) > 0) {
|
||||
tmp = util_str_merge(str, sep);
|
||||
free(str);
|
||||
str = tmp;
|
||||
}
|
||||
|
||||
tmp = util_str_merge(str, argv[i]);
|
||||
free(str);
|
||||
str = tmp;
|
||||
}
|
||||
|
||||
log_info("Application arguments (%d):\n%s", argc, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
void hook_core_piu_log_init(int argc, char** argv)
|
||||
{
|
||||
struct hook_core_options options;
|
||||
|
||||
hook_core_options_init(argc, argv, &options);
|
||||
|
||||
util_log_set_file(options.log.file, false);
|
||||
util_log_set_level(options.log.level);
|
||||
}
|
||||
|
||||
void hook_core_piu_log_info(int argc, char** argv)
|
||||
{
|
||||
log_info("\n"
|
||||
" _ _ \n"
|
||||
" _ __ _ _ _ __ ___ _ __ | |_ ___ ___ | |___ \n"
|
||||
" | '_ \\| | | | '_ ` _ \\| '_ \\| __/ _ \\ / _ \\| / __|\n"
|
||||
" | |_) | |_| | | | | | | |_) | || (_) | (_) | \\__ \\\n"
|
||||
" | .__/ \\__,_|_| |_| |_| .__/ \\__\\___/ \\___/|_|___/\n"
|
||||
" |_| |_| ");
|
||||
|
||||
log_info("Pumptools build " __DATE__ " " __TIME__ " gitrev %s", STRINGIFY(GITREV));
|
||||
|
||||
util_sys_info_log();
|
||||
util_proc_log_info();
|
||||
util_glibc_info_log();
|
||||
hook_core_piu_log_application_args(argc, argv);
|
||||
}
|
||||
|
||||
char* hook_core_piu_utils_get_and_verify_game_data_path(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
log_error("Missing game data path, usage for piu (stock args): piu <game folder> (e.g. piu ./game)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char* game_data_path = util_str_dup(argv[1]);
|
||||
|
||||
log_info("Game data path: %s", game_data_path);
|
||||
|
||||
/* remove trailing / for the hook. however, the game crashes without it */
|
||||
if (util_str_ends_with(game_data_path, "/")) {
|
||||
game_data_path[strlen(game_data_path) - 1] = '\0';
|
||||
} else {
|
||||
log_error("Game data path '%s' does not end with a trailing /, exiting because the game is going to "
|
||||
"crash anyway!", game_data_path);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* depending on the version, the game also just crashes if the game folder or files within it were not found */
|
||||
if (!util_fs_path_exists(game_data_path)) {
|
||||
log_error("Game data path '%s' does not exist, exiting", game_data_path);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return game_data_path;
|
||||
}
|
||||
|
||||
void hook_core_piu_utils_verify_root_user()
|
||||
{
|
||||
log_info("Verifying process is running as root user.");
|
||||
|
||||
if (!util_proc_is_running_as_root()) {
|
||||
log_error("Process not running as root which is required for the game to work correctly.");
|
||||
//exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void hook_core_piu_utils_fix_locale()
|
||||
{
|
||||
log_info("Fixing locale settings.");
|
||||
|
||||
if (setenv("LC_ALL", "C", 1) != 0) {
|
||||
log_warn("Setting locale LC_ALL failed.");
|
||||
}
|
||||
|
||||
if (unsetenv("LANGUAGE") != 0) {
|
||||
log_warn("Unsetting LANGUAGE env var failed.");
|
||||
}
|
||||
}
|
||||
|
||||
bool hook_core_piu_block_non_piu_process_recursion(int argc, char** argv)
|
||||
{
|
||||
/* Sanity check for arguments. If further child processes are started
|
||||
from the current process, and using LD_PRELOAD on the current process,
|
||||
all children are also getting the preloaded library. This causes
|
||||
multiple calls to the trap main function and just crashes our
|
||||
application at some point.
|
||||
The executable file is required to contain the "piu" substring to make
|
||||
this work properly */
|
||||
if (!strstr(argv[0], "piu")) {
|
||||
log_warn("Not attaching to non piu process %s", argv[0]);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef HOOK_CORE_PIU_UTILS_H
|
||||
#define HOOK_CORE_PIU_UTILS_H
|
||||
|
||||
/**
|
||||
* Initialize the logging system as early as possible to allow recording everything to a log file as well.
|
||||
*/
|
||||
void hook_core_piu_log_init(int argc, char** argv);
|
||||
|
||||
/**
|
||||
* Log process and system relevant information.
|
||||
*/
|
||||
void hook_core_piu_log_info(int argc, char** argv);
|
||||
|
||||
/**
|
||||
* Check and verify the game data path argument passed to the game via argv
|
||||
*
|
||||
* Executes various checks and catches errors that might result in the game
|
||||
* simply crashing without any error indication.
|
||||
*
|
||||
* @param argc Argc from piu main
|
||||
* @param argv Argv from piu main
|
||||
* @return New string with game data path extracted from argv (caller has to free)
|
||||
*/
|
||||
char* hook_core_piu_utils_get_and_verify_game_data_path(int argc, char** argv);
|
||||
|
||||
/**
|
||||
* Verify that the current process is running as root user because the game
|
||||
* needs access to various devices that require higher privileges.
|
||||
*
|
||||
* Does not return and errors if not running as root user.
|
||||
*/
|
||||
void hook_core_piu_utils_verify_root_user();
|
||||
|
||||
/**
|
||||
* Fix the locale configuration for Fiesta 2 and newer.
|
||||
*/
|
||||
void hook_core_piu_utils_fix_locale();
|
||||
|
||||
/**
|
||||
* If further child processes are started from the current process, and using
|
||||
* LD_PRELOAD on the current process, all children are also getting the preloaded
|
||||
* library. This causes multiple calls to the trap main function and just crashes our
|
||||
* application at some point. The executable file is required to contain the "piu"
|
||||
* substring to make this work properly.
|
||||
*
|
||||
* @param argc Argc from piu main
|
||||
* @param argv Argv from piu main
|
||||
* @return True if we have to block this call by another process,
|
||||
* false if the process calling this is the piu process.
|
||||
*/
|
||||
bool hook_core_piu_block_non_piu_process_recursion(int argc, char** argv);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user