Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
loadlib.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#define _CRT_SECURE_NO_DEPRECATE
7
8#include "loadlib.h"
9#include <cstdio>
10
11u_map_fcc MverMagic = { {'R','E','V','M'} };
12
14{
15 data = 0;
16 data_size = 0;
17}
18
23
24bool ChunkedFile::loadFile(HANDLE mpq, char* filename, bool log)
25{
26 free();
27 HANDLE file;
28 if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_FROM_MPQ, &file))
29 {
30 if (log)
31 printf("No such file %s\n", filename);
32 return false;
33 }
34
35 data_size = SFileGetFileSize(file, NULL);
36 data = new uint8[data_size];
37 SFileReadFile(file, data, data_size, NULL/*bytesRead*/, NULL);
40 {
41 SFileCloseFile(file);
42 return true;
43 }
44
45 printf("Error loading %s\n", filename);
46 SFileCloseFile(file);
47 free();
48 return false;
49}
50
52{
53 FileChunk* chunk = GetChunk("MVER");
54 if (!chunk)
55 return false;
56
57 // Check version
58 file_MVER* version = chunk->As<file_MVER>();
59 if (version->fcc != MverMagic.fcc)
60 return false;
61 if (version->ver != FILE_FORMAT_VERSION)
62 return false;
63 return true;
64}
65
67{
68 for (auto chunk : chunks)
69 delete chunk.second;
70
71 chunks.clear();
72
73 delete[] data;
74 data = 0;
75 data_size = 0;
76}
77
79 { 'R', 'E', 'V', 'M' },
80 { 'N', 'I', 'A', 'M' },
81 { 'O', '2', 'H', 'M' },
82 { 'K', 'N', 'C', 'M' },
83 { 'T', 'V', 'C', 'M' },
84 { 'Q', 'L', 'C', 'M' }
85};
86
88{
89 for (u_map_fcc const& f : InterestingChunks)
90 if (f.fcc == fcc.fcc)
91 return true;
92
93 return false;
94}
95
97{
98 uint8* ptr = GetData();
99 while (ptr < GetData() + GetDataSize())
100 {
101 u_map_fcc header = *(u_map_fcc*)ptr;
102 uint32 size = 0;
103 if (IsInterestingChunk(header))
104 {
105 size = *(uint32*)(ptr + 4);
106 if (size <= data_size)
107 {
108 std::swap(header.fcc_txt[0], header.fcc_txt[3]);
109 std::swap(header.fcc_txt[1], header.fcc_txt[2]);
110
111 FileChunk* chunk = new FileChunk{ ptr, size };
112 chunk->parseSubChunks();
113 chunks.insert({ std::string(header.fcc_txt, 4), chunk });
114 }
115 }
116
117 // move to next chunk
118 ptr += size + 8;
119 }
120}
121
122FileChunk* ChunkedFile::GetChunk(std::string const& name)
123{
124 auto range = chunks.equal_range(name);
125 if (std::distance(range.first, range.second) == 1)
126 return range.first->second;
127
128 return NULL;
129}
130
132{
133 for (auto subchunk : subchunks)
134 delete subchunk.second;
135
136 subchunks.clear();
137}
138
140{
141 uint8* ptr = data + 8; // skip self
142 while (ptr < data + size)
143 {
144 u_map_fcc header = *(u_map_fcc*)ptr;
145 uint32 subsize = 0;
146 if (IsInterestingChunk(header))
147 {
148 subsize = *(uint32*)(ptr + 4);
149 if (subsize < size)
150 {
151 std::swap(header.fcc_txt[0], header.fcc_txt[3]);
152 std::swap(header.fcc_txt[1], header.fcc_txt[2]);
153
154 FileChunk* chunk = new FileChunk{ ptr, subsize };
155 chunk->parseSubChunks();
156 subchunks.insert({ std::string(header.fcc_txt, 4), chunk });
157 }
158 }
159
160 // move to next chunk
161 ptr += subsize + 8;
162 }
163}
164
165FileChunk* FileChunk::GetSubChunk(std::string const& name)
166{
167 auto range = subchunks.equal_range(name);
168 if (std::distance(range.first, range.second) == 1)
169 return range.first->second;
170
171 return NULL;
172}
void free()
Definition loadlib.cpp:66
bool loadFile(HANDLE mpq, char *filename, bool log=true)
Definition loadlib.cpp:24
virtual ~ChunkedFile()
Definition loadlib.cpp:19
FileChunk * GetChunk(std::string const &name)
Definition loadlib.cpp:122
uint8 * data
Definition loadlib.h:79
void parseChunks()
Definition loadlib.cpp:96
std::multimap< std::string, FileChunk * > chunks
Definition loadlib.h:91
uint32 GetDataSize()
Definition loadlib.h:82
uint8 * GetData()
Definition loadlib.h:81
bool prepareLoadedData()
Definition loadlib.cpp:51
uint32 data_size
Definition loadlib.h:80
uint32 size
Definition loadlib.h:68
void parseSubChunks()
Definition loadlib.cpp:139
uint8 * data
Definition loadlib.h:67
std::multimap< std::string, FileChunk * > subchunks
Definition loadlib.h:73
FileChunk * GetSubChunk(std::string const &name)
Definition loadlib.cpp:165
u_map_fcc MverMagic
Definition loadlib.cpp:11
bool IsInterestingChunk(u_map_fcc const &fcc)
Definition loadlib.cpp:87
u_map_fcc InterestingChunks[]
Definition loadlib.cpp:78
uint8_t uint8
Definition loadlib.h:36
#define FILE_FORMAT_VERSION
Definition loadlib.h:39
uint32_t uint32
Definition loadlib.h:34
uint32 ver
Definition loadlib.h:59
uint32 fcc
Definition loadlib.h:55
uint32 fcc
Definition loadlib.h:46
char fcc_txt[4]
Definition loadlib.h:45