SourcePP
Several modern C++20 libraries for sanely parsing Valve's formats.
Loading...
Searching...
No Matches
OL.cpp
Go to the documentation of this file.
1#include <vpkpp/format/OL.h>
2
3#include <filesystem>
4
5#include <FileStream.h>
6
7using namespace sourcepp;
8using namespace vpkpp;
9
10namespace {
11
12enum class OLEntryType : uint32_t {
13 RMF = 0,
14 MAP = 1,
15};
16
17} // namespace
18
19std::unique_ptr<PackFile> OL::open(const std::string& path, const EntryCallback& callback) {
20 if (!std::filesystem::exists(path)) {
21 // File does not exist
22 return nullptr;
23 }
24
25 auto* ol = new OL{path};
26 auto packFile = std::unique_ptr<PackFile>(ol);
27
28 FileStream reader{ol->fullFilePath};
29 reader.seek_in(0);
30
31 if (reader.read_string(OL_SIGNATURE.size(), false) != OL_SIGNATURE) {
32 // File is not an OL
33 return nullptr;
34 }
35
36 if (auto version = reader.read<float>(); version < 0.05 || version > 0.15) {
37 // Version must be 0.1
38 return nullptr;
39 }
40
41 auto entryOffset = reader.read<uint32_t>();
42 auto entryCount = reader.read<uint32_t>();
43
44 reader.read(ol->notes);
45
46 reader.seek_in(entryOffset);
47 for (uint32_t i = 0; i < entryCount; i++) {
48 Entry entry = createNewEntry();
49
50 entry.offset = reader.read<uint32_t>();
51 entry.length = reader.read<uint32_t>();
52
53 const auto baseEntryPath = ol->cleanEntryPath(reader.read_string(31));
54 auto entryPath = baseEntryPath;
55
56 auto notes = reader.read_string(501);
57
58 std::string extension;
59 auto type = reader.read<OLEntryType>();
60 switch (type) {
61 case OLEntryType::RMF:
62 extension = ".rmf";
63 break;
64 case OLEntryType::MAP:
65 extension = ".map";
66 break;
67 }
68 entryPath += extension;
69
70 // Entries can have the same name, but our map can't handle non-unique keys!
71 for (int j = 1; ol->entries.count(entryPath) > 0; j++) {
72 entryPath = baseEntryPath;
73 entryPath
74 .append(" (")
75 .append(std::to_string(j))
76 .append(")")
77 .append(extension);
78 }
79
80 if (!notes.empty()) {
81 entry.extraData = {reinterpret_cast<const std::byte*>(notes.data()), reinterpret_cast<const std::byte*>(notes.data() + notes.size())};
82 }
83
84 ol->entries.emplace(entryPath, entry);
85
86 if (callback) {
87 callback(entryPath, entry);
88 }
89 }
90
91 return packFile;
92}
93
94std::optional<std::vector<std::byte>> OL::readEntry(const std::string& path_) const {
95 auto path = this->cleanEntryPath(path_);
96 auto entry = this->findEntry(path);
97 if (!entry) {
98 return std::nullopt;
99 }
100 if (entry->unbaked) {
101 return readUnbakedEntry(*entry);
102 }
103
104 // It's baked into the file on disk
105 FileStream stream{this->fullFilePath};
106 if (!stream) {
107 return std::nullopt;
108 }
109 stream.seek_in_u(entry->offset);
110 return stream.read_bytes(entry->length);
111}
112
114 using enum Attribute;
115 return LENGTH;
116}
117
118const std::string& OL::getNotes() const {
119 return this->notes;
120}
121
122std::optional<std::string> OL::getEntryNotes(const std::string& path) const {
123 const auto entry = this->findEntry(path);
124 if (!entry) {
125 return std::nullopt;
126 }
127 return std::string{reinterpret_cast<const char*>(entry->extraData.data()), entry->extraData.size()};
128}
This class represents the metadata that a file has inside a PackFile.
Definition: Entry.h:14
uint64_t offset
Offset, format-specific meaning - 0 if unused, or if the offset genuinely is 0.
Definition: Entry.h:33
uint64_t length
Length in bytes (in formats with compression, this is the uncompressed length)
Definition: Entry.h:26
std::vector< std::byte > extraData
Format-specific (PCK: MD5 hash, VPK: Preloaded data)
Definition: Entry.h:36
Definition: OL.h:12
Attribute getSupportedEntryAttributes() const override
Returns a list of supported entry attributes Mostly for GUI programs that show entries and their meta...
Definition: OL.cpp:113
static std::unique_ptr< PackFile > open(const std::string &path, const EntryCallback &callback=nullptr)
Open an OL file.
Definition: OL.cpp:19
std::string notes
Definition: OL.h:38
std::optional< std::string > getEntryNotes(const std::string &path) const
Definition: OL.cpp:122
std::optional< std::vector< std::byte > > readEntry(const std::string &path_) const override
Try to read the entry's data to a bytebuffer.
Definition: OL.cpp:94
const std::string & getNotes() const
Definition: OL.cpp:118
EntryCallbackBase< void > EntryCallback
Definition: PackFile.h:30
std::optional< Entry > findEntry(const std::string &path_, bool includeUnbaked=true) const
Try to find an entry given the file path.
Definition: PackFile.cpp:163
std::string fullFilePath
Definition: PackFile.h:219
std::string cleanEntryPath(const std::string &path) const
Definition: PackFile.cpp:677
static Entry createNewEntry()
Definition: PackFile.cpp:686
static std::optional< std::vector< std::byte > > readUnbakedEntry(const Entry &entry)
Definition: PackFile.cpp:690
Definition: LZMA.h:11
Definition: Attribute.h:5
constexpr std::string_view OL_SIGNATURE
Definition: OL.h:9
Attribute
Definition: Attribute.h:7