Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 32 additions & 20 deletions src/vpkpp/format/PCK.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// ReSharper disable CppRedundantQualifier

#include <vpkpp/format/PCK.h>

#include <filesystem>
Expand All @@ -14,7 +16,7 @@ constexpr int PCK_DIRECTORY_STRING_PADDING = 4;
constexpr int PCK_FILE_DATA_PADDING = 16;

std::unique_ptr<PackFile> PCK::create(const std::string& path, uint32_t version, uint32_t godotMajorVersion, uint32_t godotMinorVersion, uint32_t godotPatchVersion) {
if (version != 1 && version != 2) {
if (version < 1 || version > 4) {
return nullptr;
}

Expand Down Expand Up @@ -53,27 +55,27 @@ std::unique_ptr<PackFile> PCK::open(const std::string& path, const EntryCallback
FileStream reader{pck->fullFilePath};
reader.seek_in(0);

if (auto signature = reader.read<uint32_t>(); signature != PCK_SIGNATURE) {
if (reader.read<uint32_t>() != PCK_SIGNATURE) {
// PCK might be embedded
reader.seek_in(sizeof(uint32_t), std::ios::end);
if (auto endSignature = reader.read<uint32_t>(); endSignature != PCK_SIGNATURE) {
if (reader.read<uint32_t>() != PCK_SIGNATURE) {
return nullptr;
}

reader.seek_in(-static_cast<int64_t>(sizeof(uint32_t) + sizeof(uint64_t)), std::ios::cur);
auto distanceIntoFile = reader.read<uint64_t>();
const auto distanceIntoFile = reader.read<uint64_t>();

reader.seek_in(-static_cast<int64_t>(distanceIntoFile + sizeof(uint64_t)), std::ios::cur);
if (auto startSignature = reader.read<uint32_t>(); startSignature != PCK_SIGNATURE) {
if (reader.read<uint32_t>() != PCK_SIGNATURE) {
return nullptr;
}

pck->startOffset = reader.tell_in() - sizeof(uint32_t);
}

reader.read(pck->header.packVersion);
if (pck->header.packVersion < 1 || pck->header.packVersion > 2) {
// We don't support v3 yet
if (pck->header.packVersion < 1 || pck->header.packVersion > 4) {
// Unknown version
return nullptr;
}

Expand All @@ -92,16 +94,21 @@ std::unique_ptr<PackFile> PCK::open(const std::string& path, const EntryCallback
// File directory is encrypted
return nullptr;
}
if (pck->header.flags & FLAG_DIR_RELATIVE_FILE_DATA) {
if (pck->header.flags & FLAG_DIR_RELATIVE_FILE_DATA || pck->header.packVersion >= 3) {
extraEntryContentsOffset += pck->startOffset;
pck->header.flags = static_cast<FlagsDirV2>(pck->header.flags & ~FLAG_DIR_RELATIVE_FILE_DATA);
}

// Reserved
reader.skip_in<int32_t>(16);
if (pck->header.packVersion >= 3) {
const auto dirOffset = reader.read<int64_t>();
reader.seek_in(dirOffset);
} else {
// Reserved
reader.skip_in<int32_t>(16);
}

// Directory
auto fileCount = reader.read<uint32_t>();
const auto fileCount = reader.read<uint32_t>();
for (uint32_t i = 0; i < fileCount; i++) {
Entry entry = createNewEntry();

Expand Down Expand Up @@ -135,8 +142,8 @@ std::unique_ptr<PackFile> PCK::open(const std::string& path, const EntryCallback
}

std::optional<std::vector<std::byte>> PCK::readEntry(const std::string& path_) const {
auto path = this->cleanEntryPath(path_);
auto entry = this->findEntry(path);
const auto path = this->cleanEntryPath(path_);
const auto entry = this->findEntry(path);
if (!entry) {
return std::nullopt;
}
Expand All @@ -158,7 +165,7 @@ std::optional<std::vector<std::byte>> PCK::readEntry(const std::string& path_) c
return stream.read_bytes(entry->length);
}

void PCK::addEntryInternal(Entry& entry, const std::string& path, std::vector<std::byte>& buffer, EntryOptions options) {
void PCK::addEntryInternal(Entry& entry, const std::string&, std::vector<std::byte>& buffer, EntryOptions) {
entry.length = buffer.size();

const auto md5 = crypto::computeMD5(buffer);
Expand All @@ -168,10 +175,15 @@ void PCK::addEntryInternal(Entry& entry, const std::string& path, std::vector<st
entry.offset = 0;
}

bool PCK::bake(const std::string& outputDir_, BakeOptions options, const EntryCallback& callback) {
bool PCK::bake(const std::string& outputDir_, BakeOptions, const EntryCallback& callback) {
if (this->header.packVersion > 2) {
// Currently unsupported
return false;
}

// Get the proper file output folder
std::string outputDir = this->getBakeOutputDir(outputDir_);
std::string outputPath = outputDir + '/' + this->getFilename();
const std::string outputDir = this->getBakeOutputDir(outputDir_);
const std::string outputPath = outputDir + '/' + this->getFilename();

// Reconstruct data for ease of access
std::vector<std::pair<std::string, Entry*>> entriesToBake;
Expand Down Expand Up @@ -244,8 +256,8 @@ bool PCK::bake(const std::string& outputDir_, BakeOptions options, const EntryCa
this->dataOffset +=
sizeof(uint32_t) + // Path length
entryPath.length() + padding + // Path
(sizeof(std::size_t) * 2) + // Offset, Length
(sizeof(std::byte) * 16); // MD5
sizeof(std::size_t) * 2 + // Offset, Length
sizeof(std::byte) * 16; // MD5

if (this->header.packVersion > 1) {
this->dataOffset += sizeof(uint32_t); // Flags
Expand Down Expand Up @@ -313,7 +325,7 @@ uint32_t PCK::getVersion() const {
}

void PCK::setVersion(uint32_t version) {
if (version == 1 || version == 2) {
if (version >= 1 || version <= 4) {
this->header.packVersion = version;
}
}
Expand Down