Fixed some typos, updated areaflags enum
[getmangos.git] / contrib / extractor / System.cpp
blob30e28e211780971dcf8d9503835a338129896aa6
1 #define _CRT_SECURE_NO_DEPRECATE
3 #include <stdio.h>
4 #include <deque>
5 #include <set>
7 #ifdef WIN32
8 #include "direct.h"
9 #else
10 #include <sys/stat.h>
11 #endif
13 #include "dbcfile.h"
14 #include "mpq_libmpq.h"
16 extern unsigned int iRes;
17 extern ArchiveSet gOpenArchives;
19 bool ConvertADT(char*,char*);
21 typedef struct{
22 char name[64];
23 unsigned int id;
24 }map_id;
26 typedef unsigned char uint8;
27 typedef unsigned short uint16;
28 typedef unsigned int uint32;
30 map_id * map_ids;
31 uint16 * areas;
32 char output_path[128]=".";
33 char input_path[128]=".";
34 uint32 maxAreaId = 0;
36 enum Extract
38 EXTRACT_MAP = 1,
39 EXTRACT_DBC = 2
41 int extract = EXTRACT_MAP | EXTRACT_DBC;
43 static char* const langs[]={"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
44 #define LANG_COUNT 12
46 #define ADT_RES 64
48 void CreateDir( const std::string& Path )
50 #ifdef WIN32
51 _mkdir( Path.c_str());
52 #else
53 mkdir( Path.c_str(), 0777 );
54 #endif
57 bool FileExists( const char* FileName )
59 if( FILE* fp = fopen( FileName, "rb" ) )
61 fclose( fp );
62 return true;
65 return false;
68 void Usage(char* prg)
70 printf("Usage:\n%s -[var] [value]\n-i set input path\n-o set output path\n-r set resolution\n-e extract only MAP(1)/DBC(2) - standard: both(3)\nExample: %s -r 256 -i \"c:\\games\\game\"",
71 prg,prg);
72 exit(1);
75 void HandleArgs(int argc, char * arg[])
77 for(int c=1;c<argc;c++)
79 //i - input path
80 //o - output path
81 //r - resolution, array of (r * r) heights will be created
82 //e - extract only MAP(1)/DBC(2) - standard both(3)
83 if(arg[c][0] != '-')
84 Usage(arg[0]);
86 switch(arg[c][1])
88 case 'i':
89 if(c+1<argc)//all ok
90 strcpy(input_path,arg[(c++) +1]);
91 else
92 Usage(arg[0]);
93 break;
94 case 'o':
95 if(c+1<argc)//all ok
96 strcpy(output_path,arg[(c++) +1]);
97 else
98 Usage(arg[0]);
99 break;
100 case 'r':
101 if(c+1<argc)//all ok
102 iRes=atoi(arg[(c++) +1]);
103 else
104 Usage(arg[0]);
105 break;
106 case 'e':
107 if(c+1<argc)//all ok
109 extract=atoi(arg[(c++) +1]);
110 if(!(extract > 0 && extract < 4))
111 Usage(arg[0]);
113 else
114 Usage(arg[0]);
115 break;
120 uint32 ReadMapDBC()
122 printf("Read Map.dbc file... ");
123 DBCFile dbc("DBFilesClient\\Map.dbc");
124 dbc.open();
126 uint32 map_count=dbc.getRecordCount();
127 map_ids=new map_id[map_count];
128 for(unsigned int x=0;x<map_count;x++)
130 map_ids[x].id=dbc.getRecord(x).getUInt(0);
131 strcpy(map_ids[x].name,dbc.getRecord(x).getString(1));
133 printf("Done! (%u maps loaded)\n", map_count);
134 return map_count;
137 void ReadAreaTableDBC()
139 printf("Read AreaTable.dbc file... ");
140 DBCFile dbc("DBFilesClient\\AreaTable.dbc");
141 dbc.open();
143 unsigned int area_count=dbc.getRecordCount();
144 uint32 maxid = dbc.getMaxId();
145 areas=new uint16[maxid + 1];
146 memset(areas, 0xff, sizeof(areas));
147 for(unsigned int x=0; x<area_count;++x)
148 areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
150 maxAreaId = dbc.getMaxId();
152 printf("Done! (%u areas loaded)\n", area_count);
155 void ExtractMapsFromMpq()
157 char mpq_filename[1024];
158 char output_filename[1024];
160 printf("Extracting maps...\n");
162 uint32 map_count = ReadMapDBC();
164 ReadAreaTableDBC();
166 unsigned int total=map_count*ADT_RES*ADT_RES;
167 unsigned int done=0;
169 std::string path = output_path;
170 path += "/maps/";
171 CreateDir(path);
173 for(unsigned int x = 0; x < ADT_RES; ++x)
175 for(unsigned int y = 0; y < ADT_RES; ++y)
177 for(unsigned int z = 0; z < map_count; ++z)
179 sprintf(mpq_filename,"World\\Maps\\%s\\%s_%u_%u.adt",map_ids[z].name,map_ids[z].name,x,y);
180 sprintf(output_filename,"%s/maps/%03u%02u%02u.map",output_path,map_ids[z].id,y,x);
181 ConvertADT(mpq_filename,output_filename);
182 done++;
184 //draw progess bar
185 printf("Processing........................%d%%\r",(100*done)/total);
189 delete [] areas;
190 delete [] map_ids;
193 //bool WMO(char* filename);
195 void ExtractDBCFiles(int locale, bool basicLocale)
197 printf("Extracting dbc files...\n");
199 set<string> dbcfiles;
201 // get DBC file list
202 for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
204 vector<string> files;
205 (*i)->GetFileListTo(files);
206 for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
207 if (iter->rfind(".dbc") == iter->length() - strlen(".dbc"))
208 dbcfiles.insert(*iter);
211 string path = output_path;
212 path += "/dbc/";
213 CreateDir(path);
214 if(!basicLocale)
216 path += langs[locale];
217 path += "/";
218 CreateDir(path);
221 // extract DBCs
222 int count = 0;
223 for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
225 string filename = path;
226 filename += (iter->c_str() + strlen("DBFilesClient\\"));
228 FILE *output=fopen(filename.c_str(),"wb");
229 if(!output)
231 printf("Can't create the output file '%s'\n",filename.c_str());
232 continue;
234 MPQFile m(iter->c_str());
235 if(!m.isEof())
236 fwrite(m.getPointer(),1,m.getSize(),output);
238 fclose(output);
239 ++count;
241 printf("Extracted %u DBC files\n\n", count);
244 void LoadLocaleMPQFiles(int const locale)
246 char filename[512];
248 sprintf(filename,"%s/Data/%s/locale-%s.MPQ",input_path,langs[locale],langs[locale]);
249 new MPQArchive(filename);
251 for(int i = 1; i < 5; ++i)
253 char ext[3] = "";
254 if(i > 1)
255 sprintf(ext, "-%i", i);
257 sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ",input_path,langs[locale],langs[locale],ext);
258 if(FileExists(filename))
259 new MPQArchive(filename);
263 void LoadCommonMPQFiles()
265 char filename[512];
267 sprintf(filename,"%s/Data/common-2.MPQ",input_path);
268 new MPQArchive(filename);
269 sprintf(filename,"%s/Data/lichking.MPQ",input_path);
270 new MPQArchive(filename);
271 sprintf(filename,"%s/Data/expansion.MPQ",input_path);
272 new MPQArchive(filename);
274 for(int i = 1; i < 5; ++i)
276 char ext[3] = "";
277 if(i > 1)
278 sprintf(ext, "-%i", i);
280 sprintf(filename,"%s/Data/patch%s.MPQ",input_path,ext);
281 if(FileExists(filename))
282 new MPQArchive(filename);
286 inline void CloseMPQFiles()
288 for(ArchiveSet::iterator j = gOpenArchives.begin(); j != gOpenArchives.end();++j) (*j)->close();
289 gOpenArchives.clear();
292 int main(int argc, char * arg[])
294 printf("Map & DBC Extractor\n");
295 printf("===================\n\n");
297 HandleArgs(argc, arg);
299 int FirstLocale = -1;
301 for (int i = 0; i < LANG_COUNT; i++)
303 char tmp1[512];
304 sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
305 if (FileExists(tmp1))
307 printf("Detected locale: %s\n", langs[i]);
309 //Open MPQs
310 LoadLocaleMPQFiles(i);
312 if((extract & EXTRACT_DBC) == 0)
314 FirstLocale=i;
315 break;
318 //Extract DBC files
319 if(FirstLocale<0)
321 ExtractDBCFiles(i, true);
322 FirstLocale = i;
324 else
325 ExtractDBCFiles(i, false);
327 //Close MPQs
328 CloseMPQFiles();
332 if(FirstLocale<0)
334 printf("No locales detected\n");
335 return 0;
338 if (extract & EXTRACT_MAP)
340 printf("Using locale: %s\n", langs[FirstLocale]);
342 // Open MPQs
343 LoadLocaleMPQFiles(FirstLocale);
344 LoadCommonMPQFiles();
346 // Extract maps
347 ExtractMapsFromMpq();
349 // Close MPQs
350 CloseMPQFiles();
353 return 0;