mirror of
https://github.com/open-goal/jak-project
synced 2026-06-27 19:02:59 -04:00
extractor: support extracting using a folder path (#3422)
Patching up the extractor while working on the launcher, fixes: - makes it so you can compile successfully given a folder path (currently assumes your project path contains `iso_data`) - ignore `buildinfo.json` from validation code. - fixes an edge-case that could recursively fill up your entire hard-drive! - allows overriding the decompilation configuration via flag - adds a way to specify where the ISO should be extracted to
This commit is contained in:
@@ -102,7 +102,10 @@ std::tuple<std::optional<ISOMetadata>, ExtractorErrorCode> validate(
|
||||
};
|
||||
}
|
||||
|
||||
void decompile(const fs::path& iso_data_path, const std::string& data_subfolder) {
|
||||
// TODO - remove code duplication, most of this is copying what happens in decompiler's `main.cpp`
|
||||
void decompile(const fs::path& iso_data_path,
|
||||
const std::string& data_subfolder,
|
||||
const std::string& config_override) {
|
||||
using namespace decompiler;
|
||||
|
||||
// Determine which config to use from the database
|
||||
@@ -111,7 +114,7 @@ void decompile(const fs::path& iso_data_path, const std::string& data_subfolder)
|
||||
Config config = read_config_file(file_util::get_jak_project_dir() / "decompiler" / "config" /
|
||||
version_info.game_name /
|
||||
fmt::format("{}_config.jsonc", version_info.game_name),
|
||||
version_info.decomp_config_version);
|
||||
version_info.decomp_config_version, config_override);
|
||||
|
||||
std::vector<fs::path> dgos, objs, tex_strs, art_strs;
|
||||
|
||||
@@ -220,6 +223,8 @@ ExtractorErrorCode compile(const fs::path& iso_data_path, const std::string& dat
|
||||
Compiler compiler(game_name_to_version(version_info.game_name));
|
||||
compiler.make_system().set_constant("*iso-data*", absolute(iso_data_path).string());
|
||||
compiler.make_system().set_constant("*use-iso-data-path*", true);
|
||||
file_util::set_iso_data_dir(absolute(iso_data_path));
|
||||
lg::info("set iso_data_dir to {}", absolute(iso_data_path).string());
|
||||
|
||||
int flags = 0;
|
||||
for (const auto& flag : version_info.flags) {
|
||||
@@ -257,6 +262,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
fs::path input_file_path;
|
||||
fs::path project_path_override;
|
||||
fs::path extraction_path;
|
||||
bool flag_runall = false;
|
||||
bool flag_extract = false;
|
||||
bool flag_fail_on_validation = false;
|
||||
@@ -265,16 +271,22 @@ int main(int argc, char** argv) {
|
||||
bool flag_play = false;
|
||||
bool flag_folder = false;
|
||||
std::string game_name = "jak1";
|
||||
std::string decomp_config_override = "{}";
|
||||
|
||||
lg::initialize();
|
||||
|
||||
CLI::App app{"OpenGOAL Level Extraction Tool"};
|
||||
CLI::App app{"OpenGOAL Extractor (ISO Tools + Decompiler + Compiler)"};
|
||||
app.add_option("game-files-path", input_file_path,
|
||||
"The path to the folder with the ISO extracted or the ISO itself")
|
||||
->required();
|
||||
app.add_option("--proj-path", project_path_override,
|
||||
"Explicitly set the location of the 'data/' folder");
|
||||
app.add_option("--extract-path", extraction_path,
|
||||
"Explicitly set the location for where the ISO should be extracted");
|
||||
app.add_option("-g,--game", game_name, "Specify the game name, defaults to 'jak1'");
|
||||
app.add_option(
|
||||
"--decomp-config-override", decomp_config_override,
|
||||
"JSON provided will be merged with the decompiler config, use to override options");
|
||||
app.add_flag("-a,--all", flag_runall, "Run all steps, from extraction to playing the game");
|
||||
app.add_flag("-e,--extract", flag_extract, "Extract the ISO");
|
||||
app.add_flag("-v,--validate", flag_fail_on_validation,
|
||||
@@ -282,7 +294,7 @@ int main(int argc, char** argv) {
|
||||
app.add_flag("-d,--decompile", flag_decompile, "Decompile the game data");
|
||||
app.add_flag("-c,--compile", flag_compile, "Compile the game");
|
||||
app.add_flag("-p,--play", flag_play, "Play the game");
|
||||
app.add_flag("-f,--folder", flag_folder, "Extract from folder");
|
||||
app.add_flag("-f,--folder", flag_folder, "Take ISO input from a folder");
|
||||
define_common_cli_arguments(app);
|
||||
app.validate_positionals();
|
||||
CLI11_PARSE(app, argc, argv);
|
||||
@@ -347,6 +359,10 @@ int main(int argc, char** argv) {
|
||||
if (flag_extract) {
|
||||
// we extract to a temporary location because we don't know what we're extracting yet!
|
||||
fs::path temp_iso_extract_location = file_util::get_jak_project_dir() / "iso_data" / "_temp";
|
||||
if (!extraction_path.empty()) {
|
||||
temp_iso_extract_location = extraction_path / "_temp";
|
||||
}
|
||||
lg::info("Extracting ISO to temporary dir at: {}", temp_iso_extract_location.string());
|
||||
if (input_file_path != temp_iso_extract_location) {
|
||||
// in case input is also output, don't just wipe everything (weird)
|
||||
fs::remove_all(temp_iso_extract_location);
|
||||
@@ -379,14 +395,25 @@ int main(int argc, char** argv) {
|
||||
// We know the version since we just extracted it, so the user didn't need to provide this
|
||||
// explicitly
|
||||
data_subfolder = data_subfolders.at(version_info->game_name);
|
||||
iso_data_path = file_util::get_jak_project_dir() / "iso_data" / data_subfolder;
|
||||
if (fs::exists(iso_data_path)) {
|
||||
if (!extraction_path.empty()) {
|
||||
iso_data_path = extraction_path / data_subfolder;
|
||||
} else {
|
||||
iso_data_path = file_util::get_jak_project_dir() / "iso_data" / data_subfolder;
|
||||
}
|
||||
if (fs::exists(iso_data_path) && iso_data_path != temp_iso_extract_location) {
|
||||
fs::remove_all(iso_data_path);
|
||||
}
|
||||
|
||||
// std::filesystem doesn't have a rename for dirs...
|
||||
fs::copy(temp_iso_extract_location, iso_data_path, fs::copy_options::recursive);
|
||||
fs::remove_all(temp_iso_extract_location);
|
||||
// NOTE - potential disaster here, don't do either if the directories are the same location
|
||||
// or don't copy if the temp location is _inside_ the destination directory
|
||||
if (!file_util::is_dir_in_dir(iso_data_path, temp_iso_extract_location)) {
|
||||
fs::copy(temp_iso_extract_location, iso_data_path, fs::copy_options::recursive);
|
||||
}
|
||||
if (iso_data_path != temp_iso_extract_location) {
|
||||
// in case input is also output, don't just wipe everything (weird)
|
||||
fs::remove_all(temp_iso_extract_location);
|
||||
}
|
||||
}
|
||||
} else if (fs::is_directory(input_file_path)) {
|
||||
if (!flag_folder) {
|
||||
@@ -418,12 +445,16 @@ int main(int argc, char** argv) {
|
||||
} else {
|
||||
// If we did not extract, we have no clue what game the user is trying to decompile / compile
|
||||
// this is why the user has to specify this!
|
||||
iso_data_path = file_util::get_jak_project_dir() / "iso_data" / data_subfolder;
|
||||
if (flag_folder) {
|
||||
iso_data_path = input_file_path;
|
||||
} else {
|
||||
iso_data_path = file_util::get_jak_project_dir() / "iso_data" / data_subfolder;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag_decompile) {
|
||||
try {
|
||||
decompile(iso_data_path, data_subfolder);
|
||||
decompile(iso_data_path, data_subfolder, decomp_config_override);
|
||||
} catch (std::exception& e) {
|
||||
lg::error("Error during decompile: {}", e.what());
|
||||
return static_cast<int>(ExtractorErrorCode::DECOMPILATION_GENERIC_ERROR);
|
||||
|
||||
Reference in New Issue
Block a user