#include "fastfile_cod7_5_360.h" #include "zonefile_cod7_360.h" #include "compression.h" #include "encryption.h" #include #include FastFile_COD7_5_360::FastFile_COD7_5_360() : FastFile() { SetCompany(COMPANY_INFINITY_WARD); SetType(FILETYPE_FAST_FILE); SetSignage(SIGNAGE_UNSIGNED); SetMagic(0); SetVersion(0); SetPlatform("360"); SetGame("COD7.5"); } FastFile_COD7_5_360::FastFile_COD7_5_360(const QByteArray& aData) : FastFile_COD7_5_360() { if (!aData.isEmpty()) { Load(aData); } } FastFile_COD7_5_360::FastFile_COD7_5_360(const QString aFilePath) : FastFile_COD7_5_360() { if (!aFilePath.isEmpty()) { Load(aFilePath); } } FastFile_COD7_5_360::~FastFile_COD7_5_360() { } QByteArray FastFile_COD7_5_360::GetBinaryData() const { return QByteArray(); } bool FastFile_COD7_5_360::Load(const QString aFilePath) { if (aFilePath.isEmpty()) { return false; } // Check fastfile can be read QFile *file = new QFile(aFilePath); if (!file->open(QIODevice::ReadOnly)) { qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); return false; } // Decompress fastfile and close const QString fastFileStem = aFilePath.section("/", -1, -1); SetStem(fastFileStem); if (!Load(file->readAll())) { qDebug() << "Error: Failed to load fastfile: " << fastFileStem; return false; } file->close(); // Open zone file after decompressing ff and writing return true; } enum NX_Language : qint32 { LANGUAGE_ENGLISH = 0x0, LANGUAGE_FRENCH = 0x1, LANGUAGE_GERMAN = 0x2, LANGUAGE_ITALIAN = 0x3, LANGUAGE_SPANISH = 0x4, LANGUAGE_BRITISH = 0x5, LANGUAGE_RUSSIAN = 0x6, LANGUAGE_POLISH = 0x7, LANGUAGE_KOREAN = 0x8, LANGUAGE_TAIWANESE = 0x9, LANGUAGE_JAPANESE = 0xA, LANGUAGE_CHINESE = 0xB, LANGUAGE_THAI = 0xC, LANGUAGE_LEET = 0xD, LANGUAGE_CZECH = 0xE, MAX_LANGUAGES = 0xF, }; bool FastFile_COD7_5_360::Load(const QByteArray aData) { // Create a XDataStream on the input data. XDataStream fastFileStream(aData); fastFileStream.setByteOrder(XDataStream::BigEndian); QByteArray magic(8, Qt::Uninitialized); fastFileStream.readRawData(magic.data(), 8); quint32 version = fastFileStream.ParseUInt32(); if (version != 357) { qDebug() << QString("Invalid version: %1!").arg(version); return false; } bool localPatch = fastFileStream.ParseBool(); Q_UNUSED(localPatch); quint8 compressor = fastFileStream.ParseUInt8(); Q_UNUSED(compressor); // Skip fastfile date/time fastFileStream.skipRawData(8); NX_Language language = (NX_Language)fastFileStream.ParseInt32(); Q_UNUSED(language); quint32 hashCount = fastFileStream.ParseUInt32(); fastFileStream.skipRawData(12 * hashCount); fastFileStream.skipRawData(8); QByteArray decompressedData; if (magic == "NXff0100") { } else if (magic == "NXffu100") { quint32 zlibSize = aData.size() - fastFileStream.device()->pos(); QByteArray zlibData(zlibSize, Qt::Uninitialized); fastFileStream.readRawData(zlibData.data(), zlibSize); decompressedData = Compression::DecompressZLIB(zlibData); } Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD7_360* zoneFile = new ZoneFile_COD7_360(); zoneFile->SetStem(GetBaseStem() + ".zone"); if (!zoneFile->Load(decompressedData)) { qWarning() << "Failed to load ZoneFile!"; return false; } SetZoneFile(zoneFile); return true; }