SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Toggle main menu visibility
Loading...
Searching...
No Matches
FPX.cpp
Go to the documentation of this file.
1
#include <
vpkpp/format/FPX.h
>
2
3
#include <filesystem>
4
#include <FileStream.h>
5
#include <
sourcepp/String.h
>
6
7
using namespace
sourcepp
;
8
using namespace
vpkpp
;
9
10
std::unique_ptr<PackFile>
FPX::create
(
const
std::string& path) {
11
{
12
FileStream stream{path, FileStream::OPT_TRUNCATE | FileStream::OPT_CREATE_IF_NONEXISTENT};
13
14
Header1
header1
{};
15
header1
.signature =
FPX_SIGNATURE
;
16
header1
.version = 10;
17
header1
.treeSize = 1;
18
stream.write(
header1
);
19
20
stream.write(
'\0'
);
21
}
22
return
FPX::open
(path);
23
}
24
25
std::unique_ptr<PackFile>
FPX::open
(
const
std::string& path,
const
EntryCallback
& callback) {
26
std::unique_ptr<PackFile> fpx;
27
28
// Try loading the directory FPX first if this is a numbered archive and the dir exists
29
if
(path.length() >= 8) {
30
auto
dirPath = path.substr(0, path.length() - 8) +
"_fdr.fpx"
;
31
auto
pathEnd = path.substr(path.length() - 8, path.length());
32
if
(
string::matches
(pathEnd,
"_%d%d%d.fpx"
) && std::filesystem::exists(dirPath)) {
33
fpx =
FPX::openInternal
(dirPath, callback);
34
if
(fpx) {
35
return
fpx;
36
}
37
}
38
}
39
40
return
FPX::openInternal
(path, callback);
41
}
42
43
std::unique_ptr<PackFile>
FPX::openInternal
(
const
std::string& path,
const
EntryCallback
& callback) {
44
if
(!std::filesystem::exists(path)) {
45
// File does not exist
46
return
nullptr
;
47
}
48
49
auto
* fpx =
new
FPX
{path};
50
auto
packFile = std::unique_ptr<PackFile>(fpx);
51
52
FileStream reader{fpx->fullFilePath};
53
reader.seek_in(0);
54
reader.read(fpx->header1);
55
if
(fpx->header1.signature !=
FPX_SIGNATURE
) {
56
// File is not an FPX
57
return
nullptr
;
58
}
59
if
(fpx->header1.version != 10) {
60
// Only support v10 FPX files
61
return
nullptr
;
62
}
63
64
// Extensions
65
while
(
true
) {
66
std::string extension;
67
reader.read(extension);
68
if
(extension.empty())
69
break
;
70
71
// Directories
72
while
(
true
) {
73
std::string directory;
74
reader.read(directory);
75
if
(directory.empty())
76
break
;
77
78
std::string fullDir;
79
if
(directory ==
" "
) {
80
fullDir =
""
;
81
}
else
{
82
fullDir = directory;
83
}
84
85
// Files
86
while
(
true
) {
87
std::string entryName;
88
reader.read(entryName);
89
if
(entryName.empty())
90
break
;
91
92
Entry
entry =
createNewEntry
();
93
94
std::string entryPath;
95
if
(extension ==
" "
) {
96
entryPath = fullDir.empty() ?
""
: fullDir +
'/'
;
97
entryPath += entryName;
98
}
else
{
99
entryPath = fullDir.empty() ?
""
: fullDir +
'/'
;
100
entryPath += entryName +
'.'
;
101
entryPath += extension;
102
}
103
entryPath = fpx->cleanEntryPath(entryPath);
104
105
reader.read(entry.
crc32
);
106
auto
preloadedDataSize = reader.read<uint16_t>();
107
entry.
archiveIndex
= reader.read<uint16_t>();
108
entry.
offset
= reader.read<uint32_t>();
109
entry.
length
= reader.read<uint32_t>();
110
111
if
(reader.read<uint16_t>() !=
VPK_ENTRY_TERM
) {
112
// Invalid terminator!
113
return
nullptr
;
114
}
115
116
if
(preloadedDataSize > 0) {
117
entry.
extraData
= reader.read_bytes(preloadedDataSize);
118
entry.
length
+= preloadedDataSize;
119
}
120
121
if
(entry.
archiveIndex
!=
VPK_DIR_INDEX
&& entry.
archiveIndex
> fpx->numArchives) {
122
fpx->numArchives = entry.
archiveIndex
;
123
}
124
125
fpx->entries.emplace(entryPath, entry);
126
127
if
(callback) {
128
callback(entryPath, entry);
129
}
130
}
131
}
132
}
133
134
// If there are no archives, -1 will be incremented to 0
135
fpx->numArchives++;
136
137
return
packFile;
138
}
FPX.h
String.h
vpkpp::Entry
This class represents the metadata that a file has inside a PackFile.
Definition
Entry.h:14
vpkpp::Entry::offset
uint64_t offset
Offset, format-specific meaning - 0 if unused, or if the offset genuinely is 0.
Definition
Entry.h:33
vpkpp::Entry::archiveIndex
uint32_t archiveIndex
Which external archive this entry is in.
Definition
Entry.h:23
vpkpp::Entry::crc32
uint32_t crc32
CRC32 checksum - 0 if unused.
Definition
Entry.h:40
vpkpp::Entry::length
uint64_t length
Length in bytes (in formats with compression, this is the uncompressed length).
Definition
Entry.h:26
vpkpp::Entry::extraData
std::vector< std::byte > extraData
Format-specific (PCK: MD5 hash, VPK: Preloaded data).
Definition
Entry.h:36
vpkpp::FPX
Definition
FPX.h:13
vpkpp::FPX::openInternal
static std::unique_ptr< PackFile > openInternal(const std::string &path, const EntryCallback &callback=nullptr)
Definition
FPX.cpp:43
vpkpp::FPX::open
static std::unique_ptr< PackFile > open(const std::string &path, const EntryCallback &callback=nullptr)
Open an FPX file.
Definition
FPX.cpp:25
vpkpp::FPX::create
static std::unique_ptr< PackFile > create(const std::string &path)
Create a new directory FPX file - should end in "_dir.fpx"! This is not enforced but STRONGLY recomme...
Definition
FPX.cpp:10
vpkpp::PackFile::EntryCallback
EntryCallbackBase< void > EntryCallback
Definition
PackFile.h:38
vpkpp::PackFile::createNewEntry
static Entry createNewEntry()
Definition
PackFile.cpp:715
vpkpp::VPK::header1
Header1 header1
Definition
VPK.h:145
sourcepp::string::matches
bool matches(std::string_view in, std::string_view search)
A very basic regex-like pattern checker for ASCII strings.
Definition
String.cpp:26
sourcepp
Definition
LZMA.h:11
vpkpp
Definition
Attribute.h:5
vpkpp::VPK_ENTRY_TERM
constexpr uint16_t VPK_ENTRY_TERM
Definition
VPK.h:13
vpkpp::FPX_SIGNATURE
constexpr uint32_t FPX_SIGNATURE
Definition
FPX.h:9
vpkpp::VPK_DIR_INDEX
constexpr uint16_t VPK_DIR_INDEX
Definition
VPK.h:12
vpkpp::VPK::Header1
Definition
VPK.h:29
src
vpkpp
format
FPX.cpp
Generated on
for SourcePP by
1.17.0