diff --git a/build.sh b/build.sh index 0194d22..0bd2e03 100644 --- a/build.sh +++ b/build.sh @@ -7,11 +7,11 @@ rm -rf dist/ # x86 meson setup --cross-file cross-i686-w64-mingw32.txt build32 # without `--tags runtime`, the .a files are also installed -meson install -C build32 --destdir ../dist/32bit --tags runtime +meson install -C build32 --destdir ../dist/32bit --tags runtime,doc # x86_64 meson setup --cross-file cross-x86_64-w64-mingw32.txt build64 -meson install -C build64 --destdir ../dist/64bit --tags runtime +meson install -C build64 --destdir ../dist/64bit --tags runtime,doc # docs cp -R data_mods dist/ diff --git a/meson.build b/meson.build index 9b7ef1a..1292ad6 100644 --- a/meson.build +++ b/meson.build @@ -8,6 +8,7 @@ project('layeredfs', 'c', 'cpp', version: '3.0_BETA4', ) add_project_link_arguments('-static', language: 'cpp') +add_project_arguments('-DVER_STRING="' + meson.project_version() + '"', language: 'cpp') third_party = static_library('3rd_party', sources: [ @@ -40,7 +41,6 @@ layeredfs_lib = static_library('layeredfs', sources: [ 'src/avs.cpp', 'src/dllmain.cpp', - 'src/hook.cpp', 'src/imagefs.cpp', 'src/log.cpp', 'src/modpath_handler.cpp', @@ -51,12 +51,14 @@ layeredfs_lib = static_library('layeredfs', 'src/utils.cpp', ], link_with: third_party, - cpp_args: '-DVER_STRING="' + meson.project_version() + '"', ) # has to be bare source so each special version gets a different copy layeredfs_cfg_dep = declare_dependency( - sources: 'src/config.cpp' + sources: [ + 'src/config.cpp', + 'src/hook.cpp', + ] ) executable('playpen', @@ -84,12 +86,27 @@ special_cfgs = [ ['always_devmode_and_logs_to_file', ['-DCFG_DEVMODE', '-DCFG_LOGFILE']], # "Why isn't it working???" ['always_devmode_verbose_and_logs_to_file', ['-DCFG_DEVMODE', '-DCFG_VERBOSE', '-DCFG_LOGFILE']], + # dump every file accessed via pkfs APIs to data_unpak + ['pkfs_unpack', ['-DUNPAK']] ] +# documentation for pkfs_unpak +if host_machine.cpu_family() == 'x86' + install_data( + 'pkfs_unpack_readme.txt', + install_dir: '/special_builds/pkfs_unpack', + install_tag: 'doc', + ) +endif + foreach cfg : special_cfgs folder_name = cfg[0] defines = cfg[1] + if folder_name == 'pkfs_unpack' and host_machine.cpu_family() != 'x86' + continue + endif + shared_library('ifs_hook_' + folder_name, link_with: layeredfs_lib, dependencies: layeredfs_cfg_dep, @@ -113,7 +130,7 @@ foreach cfg : injector_cfgs def_file = 'src_injector' / dll_name + '.def' if dll_name == 'dxgi_for_bombergirl' - if host_machine.cpu_family() == 'x86' + if host_machine.cpu_family() != 'x86_64' continue endif def_file = 'src_injector/dxgi.def' diff --git a/pkfs_unpack_readme.txt b/pkfs_unpack_readme.txt new file mode 100644 index 0000000..ff687ee --- /dev/null +++ b/pkfs_unpack_readme.txt @@ -0,0 +1,11 @@ +For games that use pkfs functionality (gfdm/jubeat 2008/jubeat ripples), this +will export every accessed file to a `data_unpak` folder so you can easily +extract it using gitadora-textool and make mods. + +You can tell if your game uses pkfs if the `data` folder contains +`finfolist.bin`, a `pack` folder, and a bunch of `.pak` files. + +Because .pak files do not contain a table of filenames, you have to brute-force +filenames to fully extract them. This is why there isn't an easy one-stop tool +to extract everything for editing. The "pakdump" github project comes close, but +misses a few files. diff --git a/src/hook.cpp b/src/hook.cpp index bf443e4..4abb603 100644 --- a/src/hook.cpp +++ b/src/hook.cpp @@ -131,7 +131,7 @@ class PkfsHookFile : public HookFile { std::optional> load_to_vec() override { AVS_FILE f = pkfs_fs_open(get_path_to_open().c_str()); if (f != 0) { - avs_stat stat = {0}; // file type is shared! + avs_stat stat = {0}; // stat type is shared! pkfs_fs_fstat(f, &stat); std::vector ret; ret.resize(stat.filesize); @@ -398,6 +398,30 @@ unsigned int hook_pkfs_open(const char *name) { // unpack success PkfsHookFile file(path, *norm_path); +#ifdef UNPAK + string pakdump_loc = "./data_unpak/" + file.norm_path; + if(!file_exists(pakdump_loc.c_str())) { + auto folder_terminator = pakdump_loc.rfind("/"); + auto out_folder = pakdump_loc.substr(0, folder_terminator); + auto data = file.load_to_vec(); + if(data) { + if(mkdir_p(out_folder)) { + auto dump = fopen(pakdump_loc.c_str(), "wb"); + if(dump) { + fwrite(&(*data)[0], 1, data->size(), dump); + fclose(dump); + + log_info("Dumped new pkfs file!"); + } else { + log_warning("Pakdump: Couldn't open output file"); + } + } else { + log_warning("Pakdump: Couldn't create output folder"); + } + } + } +#endif + return handle_file_open(file); } @@ -430,6 +454,9 @@ extern "C" { log_info("IFS layeredFS v" VERSION " init"); log_info("AVS DLL detected: %s", avs_loaded_dll_name); print_config(); +#ifdef UNPAK + log_info(".pak dumper mode enabled"); +#endif cache_mods();