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#include <format>
5
6#include <FileStream.h>
7
8using namespace sourcepp;
9using namespace vpkpp;
10
11namespace {
12
13enum class OLEntryType : uint32_t {
14 RMF = 0,
15 MAP = 1,
16};
17
18} // namespace
19
20std::unique_ptr<PackFile> OL::open(const std::string& path, const EntryCallback& callback) {
21 if (!std::filesystem::exists(path)) {
22 // File does not exist
23 return nullptr;
24 }
25
26 auto* ol = new OL{path};
27 auto packFile = std::unique_ptr<PackFile>(ol);
28
29 FileStream reader{ol->fullFilePath};
30 reader.seek_in(0);
31
32 if (reader.read_string(OL_SIGNATURE.size(), false) != OL_SIGNATURE) {
33 // File is not an OL
34 return nullptr;
35 }
36
37 if (auto version = reader.read<float>(); version < 0.05 || version > 0.15) {
38 // Version must be 0.1
39 return nullptr;
40 }
41
42 auto entryOffset = reader.read<uint32_t>();
43 auto entryCount = reader.read<uint32_t>();
44
45 reader.read(ol->notes);
46
47 reader.seek_in(entryOffset);
48 for (uint32_t i = 0; i < entryCount; i++) {
49 Entry entry = createNewEntry();
50
51 entry.offset = reader.read<uint32_t>();
52 entry.length = reader.read<uint32_t>();
53
54 const auto baseEntryPath = ol->cleanEntryPath(reader.read_string(31));
55 auto entryPath = baseEntryPath;
56
57 auto notes = reader.read_string(501);
58
59 std::string extension;
60 auto type = reader.read<OLEntryType>();
61 switch (type) {
62 case OLEntryType::RMF:
63 extension = ".rmf";
64 break;
65 case OLEntryType::MAP:
66 extension = ".map";
67 break;
68 }
69 entryPath += extension;
70
71 // Entries can have the same name, but our map can't handle non-unique keys!
72 for (int j = 1; ol->entries.count(entryPath) > 0; j++) {
73 entryPath = baseEntryPath + std::format(" ({}){}", j, extension);
74 }
75
76 if (!notes.empty()) {
77 entry.extraData = {reinterpret_cast<const std::byte*>(notes.data()), reinterpret_cast<const std::byte*>(notes.data() + notes.size())};
78 }
79
80 ol->entries.emplace(entryPath, entry);
81
82 if (callback) {
83 callback(entryPath, entry);
84 }
85 }
86
87 return packFile;
88}
89
90std::optional<std::vector<std::byte>> OL::readEntry(const std::string& path_) const {
91 auto path = this->cleanEntryPath(path_);
92 auto entry = this->findEntry(path);
93 if (!entry) {
94 return std::nullopt;
95 }
96 if (entry->unbaked) {
97 return readUnbakedEntry(*entry);
98 }
99
100 // It's baked into the file on disk
101 FileStream stream{this->fullFilePath};
102 if (!stream) {
103 return std::nullopt;
104 }
105 stream.seek_in_u(entry->offset);
106 return stream.read_bytes(entry->length);
107}
108
110 using enum Attribute;
111 return LENGTH;
112}
113
114const std::string& OL::getNotes() const {
115 return this->notes;
116}
117
118std::optional<std::string> OL::getEntryNotes(const std::string& path) const {
119 const auto entry = this->findEntry(path);
120 if (!entry) {
121 return std::nullopt;
122 }
123 return std::string{reinterpret_cast<const char*>(entry->extraData.data()), entry->extraData.size()};
124}
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:109
static std::unique_ptr< PackFile > open(const std::string &path, const EntryCallback &callback=nullptr)
Open an OL file.
Definition OL.cpp:20
std::string notes
Definition OL.h:32
std::optional< std::string > getEntryNotes(const std::string &path) const
Definition OL.cpp:118
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:90
const std::string & getNotes() const
Definition OL.cpp:114
EntryCallbackBase< void > EntryCallback
Definition PackFile.h:38
std::optional< Entry > findEntry(const std::string &path_, bool includeUnbaked=true) const
Try to find an entry given the file path.
Definition PackFile.cpp:172
std::string fullFilePath
Definition PackFile.h:231
std::string cleanEntryPath(const std::string &path) const
Definition PackFile.cpp:706
static Entry createNewEntry()
Definition PackFile.cpp:715
static std::optional< std::vector< std::byte > > readUnbakedEntry(const Entry &entry)
Definition PackFile.cpp:719
constexpr std::string_view OL_SIGNATURE
Definition OL.h:9
Attribute
Definition Attribute.h:7