From 7f7137ed81a0e42573e8c7922ac1d071e521ff75 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 28 Jul 2022 00:16:57 -0700 Subject: [PATCH] add support for uncompressed quests --- README.md | 3 ++- src/Quest.cc | 22 +++++++++++++++------- src/Quest.hh | 1 + 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e1c6943d..dcc9afe0 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,8 @@ Standard quest file names should be like `q###-CATEGORY-VERSION.EXT`; battle que - `EXT`: file extension (bin, dat, bin.gci, dat.gci, bin.dlq, dat.dlq, or qst) There are multiple PSO quest formats out there; newserv supports most of them. Specifically, newserv can use quests in any of the following formats: -- bin/dat format: These quests consist of two files with the same base name, a .bin file and a .dat file. +- Compressed bin/dat format: These quests consist of two files with the same base name, a .bin file and a .dat file. +- Uncompressed bin/dat format: These quests consist of two files with the same base name, a .bind file and a .datd file. - Unencrypted GCI format: These quests also consist of a .bin and .dat file, but an encoding is applied on top of them. The filenames should end in .bin.gci and .dat.gci. (Note that there also exists an encrypted GCI format, which newserv does not support.) - Encrypted DLQ format: These quests also consist of a .bin and .dat file, but download quest encryption is applied on top of them. The filenames should end in .bin.dlq and .dat.dlq. - QST format: These quests consist of only a .qst file, which contains both the .bin and .dat files within it. diff --git a/src/Quest.cc b/src/Quest.cc index 80511382..a8c14494 100644 --- a/src/Quest.cc +++ b/src/Quest.cc @@ -177,23 +177,24 @@ Quest::Quest(const string& bin_filename) this->file_format = FileFormat::QST; this->file_basename = bin_filename.substr(0, bin_filename.size() - 4); } else if (ends_with(bin_filename, ".bin")) { + this->file_format = FileFormat::BIN_DAT; this->file_basename = bin_filename.substr(0, bin_filename.size() - 4); + } else if (ends_with(bin_filename, ".bind")) { + this->file_format = FileFormat::BIN_DAT_UNCOMPRESSED; + this->file_basename = bin_filename.substr(0, bin_filename.size() - 5); } else { throw runtime_error("quest does not have a valid .bin file"); } string basename; { - size_t slash_pos = bin_filename.rfind('/'); + size_t slash_pos = this->file_basename.rfind('/'); if (slash_pos != string::npos) { - basename = bin_filename.substr(slash_pos + 1); + basename = this->file_basename.substr(slash_pos + 1); } else { - basename = bin_filename; + basename = this->file_basename; } } - bool has_short_extension = (this->file_format == FileFormat::BIN_DAT) || - (this->file_format == FileFormat::QST); - basename.resize(basename.size() - (has_short_extension ? 4 : 8)); // quest filenames are like: // b###-VV.bin for battle mode @@ -255,7 +256,7 @@ Quest::Quest(const string& bin_filename) }); this->version = name_to_version.at(tokens[1]); - // the rest of the information needs to be fetched from the .bin file's + // The rest of the information needs to be fetched from the .bin file's // contents auto bin_compressed = this->bin_contents(); @@ -369,6 +370,9 @@ shared_ptr Quest::bin_contents() const { case FileFormat::BIN_DAT: this->bin_contents_ptr.reset(new string(load_file(this->file_basename + ".bin"))); break; + case FileFormat::BIN_DAT_UNCOMPRESSED: + this->bin_contents_ptr.reset(new string(prs_compress(load_file(this->file_basename + ".bind")))); + break; case FileFormat::BIN_DAT_GCI: this->bin_contents_ptr.reset(new string(this->decode_gci(this->file_basename + ".bin.gci"))); break; @@ -394,6 +398,9 @@ shared_ptr Quest::dat_contents() const { case FileFormat::BIN_DAT: this->dat_contents_ptr.reset(new string(load_file(this->file_basename + ".dat"))); break; + case FileFormat::BIN_DAT_UNCOMPRESSED: + this->dat_contents_ptr.reset(new string(prs_compress(load_file(this->file_basename + ".datd")))); + break; case FileFormat::BIN_DAT_GCI: this->dat_contents_ptr.reset(new string(this->decode_gci(this->file_basename + ".dat.gci"))); break; @@ -617,6 +624,7 @@ QuestIndex::QuestIndex(const std::string& directory) : directory(directory) { } if (ends_with(filename, ".bin") || + ends_with(filename, ".bind") || ends_with(filename, ".bin.gci") || ends_with(filename, ".bin.dlq") || ends_with(filename, ".qst")) { diff --git a/src/Quest.hh b/src/Quest.hh index b3e3a448..f2dbba15 100644 --- a/src/Quest.hh +++ b/src/Quest.hh @@ -38,6 +38,7 @@ class Quest { public: enum class FileFormat { BIN_DAT = 0, + BIN_DAT_UNCOMPRESSED, BIN_DAT_GCI, BIN_DAT_DLQ, QST,