Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Toggle main menu visibility
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
11
u_map_fcc
MverMagic
= { {
'R'
,
'E'
,
'V'
,
'M'
} };
12
13
ChunkedFile::ChunkedFile
()
14
{
15
data
= 0;
16
data_size
= 0;
17
}
18
19
ChunkedFile::~ChunkedFile
()
20
{
21
free
();
22
}
23
24
bool
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);
38
parseChunks
();
39
if
(
prepareLoadedData
())
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
51
bool
ChunkedFile::prepareLoadedData
()
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
66
void
ChunkedFile::free
()
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
78
u_map_fcc
InterestingChunks
[] = {
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
87
bool
IsInterestingChunk
(
u_map_fcc
const
& fcc)
88
{
89
for
(
u_map_fcc
const
& f :
InterestingChunks
)
90
if
(f.fcc == fcc.
fcc
)
91
return
true
;
92
93
return
false
;
94
}
95
96
void
ChunkedFile::parseChunks
()
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
122
FileChunk
*
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
131
FileChunk::~FileChunk
()
132
{
133
for
(
auto
subchunk :
subchunks
)
134
delete
subchunk.second;
135
136
subchunks
.clear();
137
}
138
139
void
FileChunk::parseSubChunks
()
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
165
FileChunk
*
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
}
ChunkedFile::free
void free()
Definition
loadlib.cpp:66
ChunkedFile::loadFile
bool loadFile(HANDLE mpq, char *filename, bool log=true)
Definition
loadlib.cpp:24
ChunkedFile::~ChunkedFile
virtual ~ChunkedFile()
Definition
loadlib.cpp:19
ChunkedFile::GetChunk
FileChunk * GetChunk(std::string const &name)
Definition
loadlib.cpp:122
ChunkedFile::data
uint8 * data
Definition
loadlib.h:79
ChunkedFile::parseChunks
void parseChunks()
Definition
loadlib.cpp:96
ChunkedFile::chunks
std::multimap< std::string, FileChunk * > chunks
Definition
loadlib.h:91
ChunkedFile::GetDataSize
uint32 GetDataSize()
Definition
loadlib.h:82
ChunkedFile::GetData
uint8 * GetData()
Definition
loadlib.h:81
ChunkedFile::ChunkedFile
ChunkedFile()
Definition
loadlib.cpp:13
ChunkedFile::prepareLoadedData
bool prepareLoadedData()
Definition
loadlib.cpp:51
ChunkedFile::data_size
uint32 data_size
Definition
loadlib.h:80
FileChunk
Definition
loadlib.h:63
FileChunk::~FileChunk
~FileChunk()
Definition
loadlib.cpp:131
FileChunk::size
uint32 size
Definition
loadlib.h:68
FileChunk::parseSubChunks
void parseSubChunks()
Definition
loadlib.cpp:139
FileChunk::data
uint8 * data
Definition
loadlib.h:67
FileChunk::subchunks
std::multimap< std::string, FileChunk * > subchunks
Definition
loadlib.h:73
FileChunk::GetSubChunk
FileChunk * GetSubChunk(std::string const &name)
Definition
loadlib.cpp:165
MverMagic
u_map_fcc MverMagic
Definition
loadlib.cpp:11
IsInterestingChunk
bool IsInterestingChunk(u_map_fcc const &fcc)
Definition
loadlib.cpp:87
InterestingChunks
u_map_fcc InterestingChunks[]
Definition
loadlib.cpp:78
loadlib.h
uint8
uint8_t uint8
Definition
loadlib.h:36
FILE_FORMAT_VERSION
#define FILE_FORMAT_VERSION
Definition
loadlib.h:39
uint32
uint32_t uint32
Definition
loadlib.h:34
chunk
Definition
adtfile.h:46
file_MVER
Definition
loadlib.h:53
file_MVER::ver
uint32 ver
Definition
loadlib.h:59
file_MVER::fcc
uint32 fcc
Definition
loadlib.h:55
u_map_fcc
Definition
loadlib.h:44
u_map_fcc::fcc
uint32 fcc
Definition
loadlib.h:46
u_map_fcc::fcc_txt
char fcc_txt[4]
Definition
loadlib.h:45
src
tools
map_extractor
loadlib.cpp
Generated on
for Project SkyFire Core by
1.17.0