TrinityCore
Loading...
Searching...
No Matches
loadlib.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "loadlib.h"
19#include <CascLib.h>
20#include <algorithm>
21
23{
24 data = nullptr;
25 data_size = 0;
26}
27
32
33bool ChunkedFile::loadFile(std::shared_ptr<CASC::Storage const> mpq, std::string const& fileName, bool log)
34{
35 free();
36 std::unique_ptr<CASC::File> file(mpq->OpenFile(fileName.c_str(), CASC_LOCALE_ALL_WOW, log));
37 if (!file)
38 return false;
39
40 int64 fileSize = file->GetSize();
41 if (fileSize == -1)
42 return false;
43
44 data_size = uint32(fileSize);
45 data = new uint8[data_size];
46 uint32 bytesRead = 0;
47 if (!file->ReadFile(data, data_size, &bytesRead) || bytesRead != data_size)
48 return false;
49
52 return true;
53
54 printf("Error loading %s\n", fileName.c_str());
55 free();
56
57 return false;
58}
59
60bool ChunkedFile::loadFile(std::shared_ptr<CASC::Storage const> mpq, uint32 fileDataId, std::string const& description, bool log)
61{
62 free();
63 std::unique_ptr<CASC::File> file(mpq->OpenFile(fileDataId, CASC_LOCALE_ALL_WOW, log));
64 if (!file)
65 return false;
66
67 int64 fileSize = file->GetSize();
68 if (fileSize == -1)
69 return false;
70
71 data_size = fileSize;
72 data = new uint8[data_size];
73 uint32 bytesRead = 0;
74 if (!file->ReadFile(data, data_size, &bytesRead) || bytesRead != data_size)
75 return false;
76
79 return true;
80
81 printf("Error loading %s\n", description.c_str());
82 free();
83
84 return false;
85}
86
88{
89 FileChunk const* chunk = GetChunk("MVER");
90 if (!chunk)
91 return false;
92
93 // Check version
94 file_MVER* version = chunk->As<file_MVER>();
95 if (version->ver != FILE_FORMAT_VERSION)
96 return false;
97 return true;
98}
99
101{
102 chunks.clear();
103
104 delete[] data;
105 data = nullptr;
106 data_size = 0;
107}
108
110{
111 { .fcc_txt = { 'R', 'E', 'V', 'M' } },
112 { .fcc_txt = { 'N', 'I', 'A', 'M' } },
113 { .fcc_txt = { 'O', '2', 'H', 'M' } },
114 { .fcc_txt = { 'K', 'N', 'C', 'M' } },
115 { .fcc_txt = { 'T', 'V', 'C', 'M' } },
116 { .fcc_txt = { 'O', 'M', 'W', 'M' } },
117 { .fcc_txt = { 'Q', 'L', 'C', 'M' } },
118 { .fcc_txt = { 'O', 'B', 'F', 'M' } },
119 { .fcc_txt = { 'D', 'H', 'P', 'M' } },
120 { .fcc_txt = { 'D', 'I', 'A', 'M' } }
121};
122
124{
125 for (u_map_fcc const& f : InterestingChunks)
126 if (f.fcc == fcc.fcc)
127 return true;
128
129 return false;
130}
131
133{
134 uint8* ptr = GetData();
135 // Make sure there's enough data to read u_map_fcc struct and the uint32 size after it
136 while (ptr <= GetData() + GetDataSize() - 8)
137 {
138 u_map_fcc& header = *(u_map_fcc*)ptr;
139 if (IsInterestingChunk(header))
140 {
141 uint32 size = *(uint32*)(ptr + 4);
142 if (size <= data_size)
143 {
144 std::ranges::reverse(header.fcc_txt);
145
146 FileChunk& chunk = chunks.emplace(std::piecewise_construct, std::forward_as_tuple(header.fcc_txt, 4), std::forward_as_tuple(ptr, size))->second;
147 chunk.parseSubChunks();
148 }
149
150 // move to next chunk
151 ptr += size + 8;
152 }
153 else
154 ++ptr;
155 }
156}
157
158FileChunk const* ChunkedFile::GetChunk(std::string_view name) const
159{
160 auto range = chunks.equal_range(name);
161 if (std::distance(range.first, range.second) == 1)
162 return &range.first->second;
163
164 return nullptr;
165}
166
167FileChunk::~FileChunk() = default;
168
170{
171 uint8* ptr = data + 8; // skip self
172 while (ptr < data + size)
173 {
174 u_map_fcc& header = *(u_map_fcc*)ptr;
175 if (IsInterestingChunk(header))
176 {
177 uint32 subsize = *(uint32*)(ptr + 4);
178 if (subsize < size)
179 {
180 std::ranges::reverse(header.fcc_txt);
181
182 FileChunk& chunk = subchunks.emplace(std::piecewise_construct, std::forward_as_tuple(header.fcc_txt, 4), std::forward_as_tuple(ptr, subsize))->second;
183 chunk.parseSubChunks();
184 }
185
186 // move to next chunk
187 ptr += subsize + 8;
188 }
189 else
190 ++ptr;
191 }
192}
193
194FileChunk const* FileChunk::GetSubChunk(std::string_view name) const
195{
196 auto range = subchunks.equal_range(name);
197 if (std::distance(range.first, range.second) == 1)
198 return &range.first->second;
199
200 return nullptr;
201}
uint8_t uint8
Definition Define.h:156
int64_t int64
Definition Define.h:149
uint32_t uint32
Definition Define.h:154
void free()
Definition loadlib.cpp:100
virtual ~ChunkedFile()
Definition loadlib.cpp:28
uint8 * data
Definition loadlib.h:76
void parseChunks()
Definition loadlib.cpp:132
uint32 GetDataSize()
Definition loadlib.h:80
FileChunk const * GetChunk(std::string_view name) const
Definition loadlib.cpp:158
bool loadFile(std::shared_ptr< CASC::Storage const > mpq, std::string const &fileName, bool log=true)
Definition loadlib.cpp:33
uint8 * GetData()
Definition loadlib.h:79
bool prepareLoadedData()
Definition loadlib.cpp:87
std::multimap< std::string_view, FileChunk > chunks
Definition loadlib.h:90
uint32 data_size
Definition loadlib.h:77
T * As() const
Definition loadlib.h:67
uint32 size
Definition loadlib.h:64
std::multimap< std::string_view, FileChunk > subchunks
Definition loadlib.h:69
void parseSubChunks()
Definition loadlib.cpp:169
uint8 * data
Definition loadlib.h:63
FileChunk const * GetSubChunk(std::string_view name) const
Definition loadlib.cpp:194
bool IsInterestingChunk(u_map_fcc const &fcc)
Definition loadlib.cpp:123
u_map_fcc constexpr InterestingChunks[]
Definition loadlib.cpp:109
#define FILE_FORMAT_VERSION
Definition loadlib.h:27
uint32 ver
Definition loadlib.h:47
uint32 fcc
Definition loadlib.h:34
char fcc_txt[4]
Definition loadlib.h:33