add support for uncompressed quests
This commit is contained in:
@@ -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)
|
- `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:
|
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.)
|
- 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.
|
- 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.
|
- QST format: These quests consist of only a .qst file, which contains both the .bin and .dat files within it.
|
||||||
|
|||||||
+15
-7
@@ -177,23 +177,24 @@ Quest::Quest(const string& bin_filename)
|
|||||||
this->file_format = FileFormat::QST;
|
this->file_format = FileFormat::QST;
|
||||||
this->file_basename = bin_filename.substr(0, bin_filename.size() - 4);
|
this->file_basename = bin_filename.substr(0, bin_filename.size() - 4);
|
||||||
} else if (ends_with(bin_filename, ".bin")) {
|
} else if (ends_with(bin_filename, ".bin")) {
|
||||||
|
this->file_format = FileFormat::BIN_DAT;
|
||||||
this->file_basename = bin_filename.substr(0, bin_filename.size() - 4);
|
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 {
|
} else {
|
||||||
throw runtime_error("quest does not have a valid .bin file");
|
throw runtime_error("quest does not have a valid .bin file");
|
||||||
}
|
}
|
||||||
|
|
||||||
string basename;
|
string basename;
|
||||||
{
|
{
|
||||||
size_t slash_pos = bin_filename.rfind('/');
|
size_t slash_pos = this->file_basename.rfind('/');
|
||||||
if (slash_pos != string::npos) {
|
if (slash_pos != string::npos) {
|
||||||
basename = bin_filename.substr(slash_pos + 1);
|
basename = this->file_basename.substr(slash_pos + 1);
|
||||||
} else {
|
} 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:
|
// quest filenames are like:
|
||||||
// b###-VV.bin for battle mode
|
// b###-VV.bin for battle mode
|
||||||
@@ -255,7 +256,7 @@ Quest::Quest(const string& bin_filename)
|
|||||||
});
|
});
|
||||||
this->version = name_to_version.at(tokens[1]);
|
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
|
// contents
|
||||||
|
|
||||||
auto bin_compressed = this->bin_contents();
|
auto bin_compressed = this->bin_contents();
|
||||||
@@ -369,6 +370,9 @@ shared_ptr<const string> Quest::bin_contents() const {
|
|||||||
case FileFormat::BIN_DAT:
|
case FileFormat::BIN_DAT:
|
||||||
this->bin_contents_ptr.reset(new string(load_file(this->file_basename + ".bin")));
|
this->bin_contents_ptr.reset(new string(load_file(this->file_basename + ".bin")));
|
||||||
break;
|
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:
|
case FileFormat::BIN_DAT_GCI:
|
||||||
this->bin_contents_ptr.reset(new string(this->decode_gci(this->file_basename + ".bin.gci")));
|
this->bin_contents_ptr.reset(new string(this->decode_gci(this->file_basename + ".bin.gci")));
|
||||||
break;
|
break;
|
||||||
@@ -394,6 +398,9 @@ shared_ptr<const string> Quest::dat_contents() const {
|
|||||||
case FileFormat::BIN_DAT:
|
case FileFormat::BIN_DAT:
|
||||||
this->dat_contents_ptr.reset(new string(load_file(this->file_basename + ".dat")));
|
this->dat_contents_ptr.reset(new string(load_file(this->file_basename + ".dat")));
|
||||||
break;
|
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:
|
case FileFormat::BIN_DAT_GCI:
|
||||||
this->dat_contents_ptr.reset(new string(this->decode_gci(this->file_basename + ".dat.gci")));
|
this->dat_contents_ptr.reset(new string(this->decode_gci(this->file_basename + ".dat.gci")));
|
||||||
break;
|
break;
|
||||||
@@ -617,6 +624,7 @@ QuestIndex::QuestIndex(const std::string& directory) : directory(directory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ends_with(filename, ".bin") ||
|
if (ends_with(filename, ".bin") ||
|
||||||
|
ends_with(filename, ".bind") ||
|
||||||
ends_with(filename, ".bin.gci") ||
|
ends_with(filename, ".bin.gci") ||
|
||||||
ends_with(filename, ".bin.dlq") ||
|
ends_with(filename, ".bin.dlq") ||
|
||||||
ends_with(filename, ".qst")) {
|
ends_with(filename, ".qst")) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class Quest {
|
|||||||
public:
|
public:
|
||||||
enum class FileFormat {
|
enum class FileFormat {
|
||||||
BIN_DAT = 0,
|
BIN_DAT = 0,
|
||||||
|
BIN_DAT_UNCOMPRESSED,
|
||||||
BIN_DAT_GCI,
|
BIN_DAT_GCI,
|
||||||
BIN_DAT_DLQ,
|
BIN_DAT_DLQ,
|
||||||
QST,
|
QST,
|
||||||
|
|||||||
Reference in New Issue
Block a user