2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-12-16 15:47:47 +00:00

feat: dump iw3 xbox unsigned fastfile data

This commit is contained in:
Michael Oliver
2025-12-14 00:56:08 +00:00
parent 53c6724043
commit cc7a68de56
3 changed files with 61 additions and 29 deletions

View File

@@ -13,7 +13,8 @@ namespace IW3
public:
static constexpr const char* MAGIC_UNSIGNED = "IWffu100";
static constexpr int ZONE_VERSION = 5;
static constexpr int ZONE_VERSION_PC = 5;
static constexpr int ZONE_VERSION_XENON = 1;
static_assert(std::char_traits<char>::length(MAGIC_UNSIGNED) == sizeof(ZoneHeader::m_magic));

View File

@@ -9,15 +9,20 @@
#include "Loading/Processor/ProcessorInflate.h"
#include "Loading/Steps/StepAddProcessor.h"
#include "Loading/Steps/StepAllocXBlocks.h"
#include "Loading/Steps/StepDumpData.h"
#include "Loading/Steps/StepLoadZoneContent.h"
#include "Loading/Steps/StepLoadZoneSizes.h"
#include "Utils/ClassUtils.h"
#include "Utils/Endianness.h"
#include "Utils/Logging/Log.h"
#include <cassert>
#include <cstring>
#include <filesystem>
#include <type_traits>
using namespace IW3;
namespace fs = std::filesystem;
namespace
{
@@ -41,20 +46,35 @@ namespace
std::optional<ZoneLoaderInspectionResult> ZoneLoaderFactory::InspectZoneHeader(const ZoneHeader& header) const
{
if (header.m_version != ZoneConstants::ZONE_VERSION)
return std::nullopt;
if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits<char>::length(ZoneConstants::MAGIC_UNSIGNED)))
if (endianness::FromLittleEndian(header.m_version) == ZoneConstants::ZONE_VERSION_PC)
{
return ZoneLoaderInspectionResult{
.m_game_id = GameId::IW3,
.m_endianness = GameEndianness::LE,
.m_word_size = GameWordSize::ARCH_32,
.m_platform = GamePlatform::PC,
.m_is_official = true,
.m_is_signed = false,
.m_is_encrypted = false,
};
if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits<char>::length(ZoneConstants::MAGIC_UNSIGNED)))
{
return ZoneLoaderInspectionResult{
.m_game_id = GameId::IW3,
.m_endianness = GameEndianness::LE,
.m_word_size = GameWordSize::ARCH_32,
.m_platform = GamePlatform::PC,
.m_is_official = true,
.m_is_signed = false,
.m_is_encrypted = false,
};
}
}
else if (endianness::FromBigEndian(header.m_version) == ZoneConstants::ZONE_VERSION_XENON)
{
if (!memcmp(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, std::char_traits<char>::length(ZoneConstants::MAGIC_UNSIGNED)))
{
return ZoneLoaderInspectionResult{
.m_game_id = GameId::IW3,
.m_endianness = GameEndianness::BE,
.m_word_size = GameWordSize::ARCH_32,
.m_platform = GamePlatform::XBOX,
.m_is_official = false,
.m_is_signed = false,
.m_is_encrypted = false,
};
}
}
return std::nullopt;
@@ -81,21 +101,32 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(const ZoneH
zoneLoader->AddLoadingStep(step::CreateStepAddProcessor(processor::CreateProcessorInflate(ZoneConstants::AUTHED_CHUNK_SIZE)));
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
if (inspectResult->m_endianness == GameEndianness::LE)
{
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
// Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
[zonePtr](ZoneInputStream& stream)
{
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
std::move(progressCallback)));
// Start of the zone content
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
[zonePtr](ZoneInputStream& stream)
{
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr->Memory(),
std::move(progressCallback)));
}
else
{
fs::path dumpFileNamePath = fs::path(fileName).filename();
dumpFileNamePath.replace_extension(".dat");
std::string dumpFileName = dumpFileNamePath.string();
con::warn("Dumping xbox assets is not supported, making a full fastfile data dump to {}", dumpFileName);
zoneLoader->AddLoadingStep(step::CreateStepDumpData(dumpFileName, 0xFFFFFFFF));
}
return zoneLoader;
}

View File

@@ -38,7 +38,7 @@ namespace
ZoneHeader CreateHeaderForParams()
{
ZoneHeader header{};
header.m_version = ZoneConstants::ZONE_VERSION;
header.m_version = ZoneConstants::ZONE_VERSION_PC;
memcpy(header.m_magic, ZoneConstants::MAGIC_UNSIGNED, sizeof(ZoneHeader::m_magic));
return header;