Fix data compression, byte order handling, and tag parsing in COD Wii fastfile.

This commit is contained in:
= 2025-06-04 22:25:12 -04:00
parent 22062c2a6e
commit 95349eaa5b
33 changed files with 152 additions and 195 deletions

View File

@ -99,7 +99,7 @@ bool FastFile_COD10_360::Load(const QByteArray aData) {
decompressedData = Encryption::decryptFastFile_BO2(aData); decompressedData = Encryption::decryptFastFile_BO2(aData);
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -107,7 +107,7 @@ bool FastFile_COD10_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_360 zoneFile; ZoneFile_COD10_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD10_360>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD10_360>(zoneFile));

View File

@ -91,11 +91,11 @@ bool FastFile_COD11_360::Load(const QByteArray aData) {
decompressedData = Encryption::decryptFastFile_BO3(encryptedData); decompressedData = Encryption::decryptFastFile_BO3(encryptedData);
// Output for verification/testing // Output for verification/testing
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
// Load the zone file with decompressed data // Load the zone file with decompressed data
ZoneFile_COD11_360 zoneFile; ZoneFile_COD11_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
if (!zoneFile.Load(decompressedData)) { if (!zoneFile.Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -91,11 +91,11 @@ bool FastFile_COD12_360::Load(const QByteArray aData) {
decompressedData = Encryption::decryptFastFile_BO3(encryptedData); decompressedData = Encryption::decryptFastFile_BO3(encryptedData);
// Output for verification/testing // Output for verification/testing
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
// Load the zone file with decompressed data // Load the zone file with decompressed data
ZoneFile_COD12_360 zoneFile; ZoneFile_COD12_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
if (!zoneFile.Load(decompressedData)) { if (!zoneFile.Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -55,10 +55,9 @@ bool FastFile_COD2_360::Load(const QString aFilePath) {
} }
// Decompress fastfile and close // Decompress fastfile and close
const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); SetStem(aFilePath.section("/", -1, -1));
SetStem(fastFileStem);
if (!Load(file->readAll())) { if (!Load(file->readAll())) {
qDebug() << "Error: Failed to load fastfile: " << fastFileStem; qDebug() << "Error: Failed to load fastfile: " << GetStem();
return false; return false;
} }
@ -77,11 +76,11 @@ bool FastFile_COD2_360::Load(const QByteArray aData) {
QByteArray compressedData = aData.mid(fastFileStream.device()->pos()); QByteArray compressedData = aData.mid(fastFileStream.device()->pos());
QByteArray decompressedData = Compression::DecompressZLIB(compressedData); QByteArray decompressedData = Compression::DecompressZLIB(compressedData);
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD2_360 zoneFile; ZoneFile_COD2_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD2_360>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD2_360>(zoneFile));

View File

@ -75,17 +75,63 @@ bool FastFile_COD4_360::Load(const QByteArray aData) {
StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000);
QByteArray decompressedData; QByteArray decompressedData;
// Create a QDataStream on the input data. const QString header = aData.left(8);
QDataStream fastFileStream(aData); if (header == "IWffu100") {
fastFileStream.setByteOrder(QDataStream::LittleEndian); // For COD5, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12));
} else if (header == "IWff0100") {
// Create a QDataStream on the input data.
QDataStream fastFileStream(aData.mid(12));
fastFileStream.setByteOrder(QDataStream::LittleEndian);
// For COD5, simply decompress from offset 12. QByteArray magic(8, Qt::Uninitialized);
decompressedData = Compression::DecompressZLIB(aData.mid(12)); fastFileStream.readRawData(magic.data(), 8);
if (magic != "IWffs100") {
qDebug() << "Found invalid signed header: " << magic;
return false;
}
fastFileStream.skipRawData(4);
Utils::ExportData(GetStem() + ".zone", decompressedData); QByteArray rsaSigChecksum(32, Qt::Uninitialized);
fastFileStream.readRawData(rsaSigChecksum.data(), 32);
QByteArray rsaSig(256, Qt::Uninitialized);
fastFileStream.readRawData(rsaSig.data(), 256);
QByteArray fileName(32, Qt::Uninitialized);
fastFileStream.readRawData(fileName.data(), 32);
fastFileStream.skipRawData(4);
QByteArray bigSigBlock(7856, Qt::Uninitialized);
fastFileStream.readRawData(bigSigBlock.data(), 7856);
QVector<QByteArray> sigBlocks = QVector<QByteArray>();
QByteArray compressedData;
for (int i = 0; i < (aData.size() / 202000) + 1; i++)
{
QByteArray newSigBlocks;
for (int j = 0; j < 256; j++) {
QByteArray newSigBlock(32, Qt::Uninitialized);
fastFileStream.readRawData(newSigBlock.data(), 32);
sigBlocks.append(newSigBlock);
}
newSigBlocks.append(newSigBlocks);
for (int j = 0; j < 256; j++) {
QByteArray compressedChunk(8192, Qt::Uninitialized);
fastFileStream.readRawData(compressedChunk.data(), 8192);
compressedData.append(compressedChunk);
}
}
decompressedData = Compression::DecompressZLIB(compressedData);
}
Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD4_360 zoneFile; ZoneFile_COD4_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD4_360>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD4_360>(zoneFile));

View File

@ -78,10 +78,10 @@ bool FastFile_COD5_360::Load(const QByteArray aData) {
// For COD5, simply decompress from offset 12. // For COD5, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12)); decompressedData = Compression::DecompressZLIB(aData.mid(12));
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD5_360 zoneFile; ZoneFile_COD5_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD5_360>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD5_360>(zoneFile));

View File

@ -3,6 +3,7 @@
#include "compression.h" #include "compression.h"
#include "encryption.h" #include "encryption.h"
#include "utils.h"
#include <QFile> #include <QFile>
#include <QDebug> #include <QDebug>
@ -69,83 +70,40 @@ bool FastFile_COD6_360::Load(const QString aFilePath) {
} }
bool FastFile_COD6_360::Load(const QByteArray aData) { bool FastFile_COD6_360::Load(const QByteArray aData) {
QByteArray decompressedData; const qint64 zlibOffset = Compression::FindZlibOffset(aData);
if (zlibOffset == -1)
// Create a QDataStream on the input data. {
QDataStream fastFileStream(aData); qWarning() << "Z-Lib stream not found";
// Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD6_360 zoneFile;
zoneFile.SetStem(GetStem());
// For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::BigEndian);
// Select key based on game.
QByteArray key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d");
fastFileStream.skipRawData(4);
// Read the 8-byte magic.
QByteArray fileMagic(8, Qt::Uninitialized);
fastFileStream.readRawData(fileMagic.data(), 8);
if (fileMagic != "PHEEBs71") {
qWarning() << "Invalid fast file magic!";
return false; return false;
} }
fastFileStream.skipRawData(4); QByteArray compressed = aData.mid(zlibOffset);
// Read IV table name (32 bytes). // 2. Try plain decompression first ------------------------------
QByteArray fileName(32, Qt::Uninitialized); QByteArray decompressed = Compression::DecompressZLIB(compressed);
fastFileStream.readRawData(fileName.data(), 32);
// Build the IV table from the fileName. // 3. If that failed or looks too small, try stripping hash blocks
QByteArray ivTable = Encryption::InitIVTable(fileName); if (decompressed.isEmpty() || decompressed.size() < 1024)
{
// Skip the RSA signature (256 bytes). QByteArray stripped = Compression::StripHashBlocks(compressed);
QByteArray rsaSignature(256, Qt::Uninitialized); QByteArray retry = Compression::DecompressZLIB(stripped);
fastFileStream.readRawData(rsaSignature.data(), 256); if (!retry.isEmpty())
decompressed.swap(retry);
// Now the stream should be positioned at 0x13C, where sections begin.
int sectionIndex = 0;
while (true) {
qint32 sectionSize = 0;
fastFileStream >> sectionSize;
qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize
<< "Pos:" << fastFileStream.device()->pos();
if (sectionSize == 0)
break;
// Read the section data.
QByteArray sectionData;
sectionData.resize(sectionSize);
fastFileStream.readRawData(sectionData.data(), sectionSize);
// Compute the IV for this section.
QByteArray iv = Encryption::GetIV(ivTable, sectionIndex);
// Decrypt the section using Salsa20.
QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv);
// Compute SHA1 hash of the decrypted data.
QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1);
// Update the IV table based on the section hash.
Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash);
// Build a compressed data buffer by prepending the two-byte zlib header.
QByteArray compressedData;
compressedData.append(char(0x78));
compressedData.append(char(0x01));
compressedData.append(decData);
decompressedData.append(Compression::DecompressZLIB(compressedData));
sectionIndex++;
} }
zoneFile.Load(decompressedData); if (decompressed.isEmpty())
{
qWarning() << "Unable to decompress fast-file";
return false;
}
SetZoneFile(std::make_shared<ZoneFile_COD6_360>(zoneFile)); // Optional keep a copy on disk for quick inspection
Utils::ExportData(GetBaseStem() + ".zone", decompressed);
// 4. Forward to zone-file loader --------------------------------
auto zoneFile = std::make_shared<ZoneFile_COD6_360>();
zoneFile->SetStem(GetStem());
zoneFile->Load(decompressed);
SetZoneFile(zoneFile);
return true; return true;
} }

View File

@ -76,7 +76,7 @@ bool FastFile_COD7_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD7_360 zoneFile; ZoneFile_COD7_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::BigEndian); fastFileStream.setByteOrder(QDataStream::BigEndian);

View File

@ -99,7 +99,7 @@ bool FastFile_COD8_360::Load(const QByteArray aData) {
decompressedData = Encryption::decryptFastFile_BO2(aData); decompressedData = Encryption::decryptFastFile_BO2(aData);
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -107,7 +107,7 @@ bool FastFile_COD8_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD8_360 zoneFile; ZoneFile_COD8_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD8_360>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD8_360>(zoneFile));

View File

@ -99,7 +99,7 @@ bool FastFile_COD9_360::Load(const QByteArray aData) {
decompressedData = Encryption::decryptFastFile_BO2(aData); decompressedData = Encryption::decryptFastFile_BO2(aData);
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -107,7 +107,7 @@ bool FastFile_COD9_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD9_360 zoneFile; ZoneFile_COD9_360 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD9_360>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD9_360>(zoneFile));

View File

@ -121,7 +121,7 @@ bool FastFile_COD10_PC::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -129,7 +129,7 @@ bool FastFile_COD10_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_PC zoneFile; ZoneFile_COD10_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD10_PC>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD10_PC>(zoneFile));

View File

@ -121,7 +121,7 @@ bool FastFile_COD11_PC::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -129,7 +129,7 @@ bool FastFile_COD11_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD11_PC zoneFile; ZoneFile_COD11_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD11_PC>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD11_PC>(zoneFile));

View File

@ -78,7 +78,7 @@ bool FastFile_COD12_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD12_PC zoneFile; ZoneFile_COD12_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// Skip header magic // Skip header magic
fastFileStream.skipRawData(8); fastFileStream.skipRawData(8);
@ -141,7 +141,7 @@ bool FastFile_COD12_PC::Load(const QByteArray aData) {
fastFileStream.device()->seek(blockPosition + 16 + blockSize); fastFileStream.device()->seek(blockPosition + 16 + blockSize);
} }
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);

View File

@ -44,7 +44,7 @@ QByteArray FastFile_COD4_PC::GetBinaryData() {
} }
bool FastFile_COD4_PC::Load(const QString aFilePath) { bool FastFile_COD4_PC::Load(const QString aFilePath) {
StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); StatusBarManager::instance().updateStatus("Loading " + GetGame() + " Fast File w/path", 1000);
if (aFilePath.isEmpty()) { if (aFilePath.isEmpty()) {
return false; return false;
@ -82,10 +82,10 @@ bool FastFile_COD4_PC::Load(const QByteArray aData) {
// For COD5, simply decompress from offset 12. // For COD5, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12)); decompressedData = Compression::DecompressZLIB(aData.mid(12));
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD4_PC zoneFile; ZoneFile_COD4_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD4_PC>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD4_PC>(zoneFile));

View File

@ -82,10 +82,10 @@ bool FastFile_COD5_PC::Load(const QByteArray aData) {
// For COD5, simply decompress from offset 12. // For COD5, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12)); decompressedData = Compression::DecompressZLIB(aData.mid(12));
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD5_PC zoneFile; ZoneFile_COD5_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD5_PC>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD5_PC>(zoneFile));

View File

@ -75,17 +75,14 @@ bool FastFile_COD6_PC::Load(const QByteArray aData) {
StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000);
QByteArray decompressedData; QByteArray decompressedData;
// Create a QDataStream on the input data. // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data.
QDataStream fastFileStream(aData); const QByteArray compressedData = aData.mid(21);
fastFileStream.setByteOrder(QDataStream::LittleEndian); decompressedData = Compression::DecompressZLIB(compressedData);
// For COD5, simply decompress from offset 12. Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
decompressedData = Compression::DecompressZLIB(aData.mid(12));
Utils::ExportData(GetStem() + ".zone", decompressedData);
ZoneFile_COD6_PC zoneFile; ZoneFile_COD6_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD6_PC>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD6_PC>(zoneFile));

View File

@ -88,7 +88,7 @@ bool FastFile_COD7_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD7_PC zoneFile; ZoneFile_COD7_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::LittleEndian); fastFileStream.setByteOrder(QDataStream::LittleEndian);

View File

@ -88,7 +88,7 @@ bool FastFile_COD8_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD8_PC zoneFile; ZoneFile_COD8_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::LittleEndian); fastFileStream.setByteOrder(QDataStream::LittleEndian);

View File

@ -121,7 +121,7 @@ bool FastFile_COD9_PC::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -129,7 +129,7 @@ bool FastFile_COD9_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD9_PC zoneFile; ZoneFile_COD9_PC zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD9_PC>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD9_PC>(zoneFile));

View File

@ -121,7 +121,7 @@ bool FastFile_COD10_PS3::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -129,7 +129,7 @@ bool FastFile_COD10_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_PS3 zoneFile; ZoneFile_COD10_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD10_PS3>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD10_PS3>(zoneFile));

View File

@ -121,7 +121,7 @@ bool FastFile_COD11_PS3::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -129,7 +129,7 @@ bool FastFile_COD11_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD11_PS3 zoneFile; ZoneFile_COD11_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD11_PS3>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD11_PS3>(zoneFile));

View File

@ -121,7 +121,7 @@ bool FastFile_COD12_PS3::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -129,7 +129,7 @@ bool FastFile_COD12_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD12_PS3 zoneFile; ZoneFile_COD12_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD12_PS3>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD12_PS3>(zoneFile));

View File

@ -109,10 +109,10 @@ bool FastFile_COD4_PS3::Load(const QByteArray aData) {
pos += chunkSize; pos += chunkSize;
} }
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD4_PS3 zoneFile; ZoneFile_COD4_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD4_PS3>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD4_PS3>(zoneFile));

View File

@ -109,10 +109,10 @@ bool FastFile_COD5_PS3::Load(const QByteArray aData) {
pos += chunkSize; pos += chunkSize;
} }
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD5_PS3 zoneFile; ZoneFile_COD5_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD5_PS3>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD5_PS3>(zoneFile));

View File

@ -93,10 +93,10 @@ bool FastFile_COD6_PS3::Load(const QByteArray aData) {
// For COD5, simply decompress from offset 12. // For COD5, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12)); decompressedData = Compression::DecompressZLIB(aData.mid(12));
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD6_PS3 zoneFile; ZoneFile_COD6_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD6_PS3>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD6_PS3>(zoneFile));

View File

@ -88,7 +88,7 @@ bool FastFile_COD7_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD7_PS3 zoneFile; ZoneFile_COD7_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::BigEndian); fastFileStream.setByteOrder(QDataStream::BigEndian);

View File

@ -88,7 +88,7 @@ bool FastFile_COD8_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD8_PS3 zoneFile; ZoneFile_COD8_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::BigEndian); fastFileStream.setByteOrder(QDataStream::BigEndian);

View File

@ -121,7 +121,7 @@ bool FastFile_COD9_PS3::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -129,7 +129,7 @@ bool FastFile_COD9_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD9_PS3 zoneFile; ZoneFile_COD9_PS3 zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD9_PS3>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD9_PS3>(zoneFile));

View File

@ -69,46 +69,18 @@ bool FastFile_COD4_Wii::Load(const QString aFilePath) {
bool FastFile_COD4_Wii::Load(const QByteArray aData) { bool FastFile_COD4_Wii::Load(const QByteArray aData) {
QByteArray decompressedData; QByteArray decompressedData;
// Create a QDataStream on the input data.
QDataStream fastFileStream(aData);
fastFileStream.setByteOrder(QDataStream::LittleEndian);
// Parse header values.
SetCompany(pParseFFCompany(&fastFileStream));
SetType(pParseFFFileType(&fastFileStream));
SetSignage(pParseFFSignage(&fastFileStream));
SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD7");
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD7_Wii zoneFile; ZoneFile_COD4_Wii zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::BigEndian);
// For COD7, simply decompress from offset 12. // For COD7, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12)); decompressedData = Compression::DecompressZLIB(aData.mid(12));
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
QDir workingDir = QDir::currentPath();
workingDir.mkdir("exports");
QFile outputFile("exports/" + GetStem() + ".zone");
if (!outputFile.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to extract IPAK file.";
}
qDebug() << " - File Name: " << outputFile.fileName();
outputFile.write(decompressedData);
outputFile.close();
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD7_Wii>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD4_Wii>(zoneFile));
return true; return true;
} }

View File

@ -85,7 +85,7 @@ bool FastFile_COD7_Wii::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD7_Wii zoneFile; ZoneFile_COD7_Wii zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::BigEndian); fastFileStream.setByteOrder(QDataStream::BigEndian);
@ -93,16 +93,15 @@ bool FastFile_COD7_Wii::Load(const QByteArray aData) {
// For COD7, simply decompress from offset 12. // For COD7, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12)); decompressedData = Compression::DecompressZLIB(aData.mid(12));
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
QDir workingDir = QDir::currentPath(); QDir workingDir = QDir::currentPath();
workingDir.mkdir("exports"); workingDir.mkdir("exports");
QFile outputFile("exports/" + GetStem() + ".zone"); QFile outputFile("exports/" + GetBaseStem() + ".zone");
if (!outputFile.open(QIODevice::WriteOnly)) { if (!outputFile.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to extract IPAK file."; qDebug() << "Failed to extract IPAK file.";
} }
qDebug() << " - File Name: " << outputFile.fileName();
outputFile.write(decompressedData); outputFile.write(decompressedData);
outputFile.close(); outputFile.close();

View File

@ -14,7 +14,7 @@ FastFile_COD8_Wii::FastFile_COD8_Wii()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD7"); SetGame("COD8");
SetPlatform("Wii"); SetPlatform("Wii");
} }
@ -78,37 +78,23 @@ bool FastFile_COD8_Wii::Load(const QByteArray aData) {
SetType(pParseFFFileType(&fastFileStream)); SetType(pParseFFFileType(&fastFileStream));
SetSignage(pParseFFSignage(&fastFileStream)); SetSignage(pParseFFSignage(&fastFileStream));
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); SetVersion(pParseFFVersion(&fastFileStream));
SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD7");
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD7_Wii zoneFile; ZoneFile_COD8_Wii zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(QDataStream::BigEndian); fastFileStream.setByteOrder(QDataStream::BigEndian);
// For COD7, simply decompress from offset 12. // For COD7, simply decompress from offset 12.
decompressedData = Compression::DecompressZLIB(aData.mid(12)); decompressedData = Compression::DecompressZLIB(aData.mid(25));
Utils::ExportData(GetStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
QDir workingDir = QDir::currentPath();
workingDir.mkdir("exports");
QFile outputFile("exports/" + GetStem() + ".zone");
if (!outputFile.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to extract IPAK file.";
}
qDebug() << " - File Name: " << outputFile.fileName();
outputFile.write(decompressedData);
outputFile.close();
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD7_Wii>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD8_Wii>(zoneFile));
return true; return true;
} }

View File

@ -119,7 +119,7 @@ bool FastFile_COD10_WiiU::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -127,7 +127,7 @@ bool FastFile_COD10_WiiU::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_WiiU zoneFile; ZoneFile_COD10_WiiU zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD10_WiiU>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD10_WiiU>(zoneFile));

View File

@ -119,7 +119,7 @@ bool FastFile_COD9_WiiU::Load(const QByteArray aData) {
} }
// For COD9, write out the complete decompressed zone for testing. // For COD9, write out the complete decompressed zone for testing.
QFile testFile("exports/" + GetStem() + ".zone"); QFile testFile("exports/" + GetBaseStem() + ".zone");
if(testFile.open(QIODevice::WriteOnly)) { if(testFile.open(QIODevice::WriteOnly)) {
testFile.write(decompressedData); testFile.write(decompressedData);
testFile.close(); testFile.close();
@ -127,7 +127,7 @@ bool FastFile_COD9_WiiU::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD9_WiiU zoneFile; ZoneFile_COD9_WiiU zoneFile;
zoneFile.SetStem(GetStem()); zoneFile.SetStem(GetBaseStem() + ".zone");
zoneFile.Load(decompressedData); zoneFile.Load(decompressedData);
SetZoneFile(std::make_shared<ZoneFile_COD9_WiiU>(zoneFile)); SetZoneFile(std::make_shared<ZoneFile_COD9_WiiU>(zoneFile));