root/trunk/contrib/extractor/System.cpp @ 2

Revision 2, 7.6 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1#define _CRT_SECURE_NO_DEPRECATE
2
3#include <stdio.h>
4#include <deque>
5#include <set>
6
7#ifdef WIN32
8#include "direct.h"
9#else
10#include <sys/stat.h>
11#endif
12
13#include "dbcfile.h"
14#include "mpq_libmpq.h"
15
16extern unsigned int iRes;
17extern ArchiveSet gOpenArchives;
18
19bool ConvertADT(char*,char*);
20
21typedef struct{
22    char name[64];
23    unsigned int id;
24}map_id;
25
26typedef unsigned char uint8;
27typedef unsigned short uint16;
28typedef unsigned int uint32;
29
30map_id * map_ids;
31uint16 * areas;
32char output_path[128]=".";
33char input_path[128]=".";
34
35enum Extract
36{
37    EXTRACT_MAP = 1,
38    EXTRACT_DBC = 2
39};
40int extract = EXTRACT_MAP | EXTRACT_DBC;
41
42static char* const langs[]={"deDE", "enGB", "enUS", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
43#define LANG_COUNT 12
44
45#define ADT_RES 64
46
47void CreateDir( const std::string& Path )
48{
49    #ifdef WIN32
50    _mkdir( Path.c_str());
51    #else
52    mkdir( Path.c_str(), 0777 );
53    #endif
54}
55
56bool FileExists( const char* FileName )
57{
58    if( FILE* fp = fopen( FileName, "rb" ) )
59    {
60        fclose( fp );
61        return true;
62    }
63
64    return false;
65}
66
67void Usage(char* prg)
68{
69    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\"",
70    prg,prg);
71    exit(1);
72}
73
74void HandleArgs(int argc, char * arg[])
75{
76    for(int c=1;c<argc;c++)
77    {
78        //i - input path
79        //o - output path
80        //r - resolution, array of (r * r) heights will be created
81        //e - extract only MAP(1)/DBC(2) - standard both(3)
82        if(arg[c][0] != '-')
83            Usage(arg[0]);
84
85        switch(arg[c][1])
86        {
87            case 'i':
88                if(c+1<argc)//all ok
89                    strcpy(input_path,arg[(c++) +1]);
90                else
91                    Usage(arg[0]);
92                break;
93            case 'o':
94                if(c+1<argc)//all ok
95                    strcpy(output_path,arg[(c++) +1]);
96                else
97                    Usage(arg[0]);
98                break;
99            case 'r':
100                if(c+1<argc)//all ok
101                    iRes=atoi(arg[(c++) +1]);
102                else
103                    Usage(arg[0]);
104                break;
105            case 'e':
106                if(c+1<argc)//all ok
107                {
108                    extract=atoi(arg[(c++) +1]);
109                    if(!(extract > 0 && extract < 4))
110                        Usage(arg[0]);
111                }
112                else
113                    Usage(arg[0]);
114                break;
115        }
116    }
117}
118
119uint32 ReadMapDBC()
120{
121    printf("Read Map.dbc file... ");
122    DBCFile dbc("DBFilesClient\\Map.dbc");
123    dbc.open();
124
125    uint32 map_count=dbc.getRecordCount();
126    map_ids=new map_id[map_count];
127    for(unsigned int x=0;x<map_count;x++)
128    {
129        map_ids[x].id=dbc.getRecord(x).getUInt(0);
130        strcpy(map_ids[x].name,dbc.getRecord(x).getString(1));
131    }
132    printf("Done! (%u maps loaded)\n", map_count);
133    return map_count;
134}
135
136void ReadAreaTableDBC()
137{
138    printf("Read AreaTable.dbc file... ");
139    DBCFile dbc("DBFilesClient\\AreaTable.dbc");
140    dbc.open();
141
142    unsigned int area_count=dbc.getRecordCount();
143    uint32 maxid = dbc.getMaxId();
144    areas=new uint16[maxid + 1];
145    memset(areas, 0xff, sizeof(areas));
146    for(unsigned int x=0; x<area_count;++x)
147        areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
148
149    printf("Done! (%u areas loaded)\n", area_count);
150}
151
152void ExtractMapsFromMpq()
153{
154    char mpq_filename[1024];
155    char output_filename[1024];
156
157    printf("Extracting maps...\n");
158
159    uint32 map_count = ReadMapDBC();
160
161    ReadAreaTableDBC();
162
163    unsigned int total=map_count*ADT_RES*ADT_RES;
164    unsigned int done=0;
165
166    std::string path = output_path;
167    path += "/maps/";
168    CreateDir(path);
169
170    for(int x = 0; x < ADT_RES; ++x)
171    {
172        for(int y = 0; y < ADT_RES; ++y)
173        {
174            for(int z = 0; z < map_count; ++z)
175            {
176                sprintf(mpq_filename,"World\\Maps\\%s\\%s_%u_%u.adt",map_ids[z].name,map_ids[z].name,x,y);
177                sprintf(output_filename,"%s/maps/%03u%02u%02u.map",output_path,map_ids[z].id,y,x);
178                ConvertADT(mpq_filename,output_filename);
179                done++;
180            }
181            //draw progess bar
182            printf("Processing........................%d%%\r",(100*done)/total);
183        }
184    }
185
186    delete [] areas;
187    delete [] map_ids;
188}
189
190//bool WMO(char* filename);
191
192void ExtractDBCFiles()
193{
194    printf("Extracting dbc files...\n");
195
196    set<string> dbcfiles;
197
198    // get DBC file list
199    for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
200    {
201        vector<string> files = (*i)->GetFileList();
202        for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
203            if (iter->rfind(".dbc") == iter->length() - strlen(".dbc"))
204                    dbcfiles.insert(*iter);
205    }
206
207    std::string path = output_path;
208    path += "/dbc/";
209    CreateDir(path);
210
211    // extract DBCs
212    int count = 0;
213    for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
214    {
215        string filename = output_path;
216        filename += "/dbc/";
217        filename += (iter->c_str() + strlen("DBFilesClient\\"));
218
219        //cout << filename << endl;
220
221        FILE *output=fopen(filename.c_str(),"wb");
222        if(!output)
223        {
224            printf("Can't create the output file '%s'\n",filename.c_str());
225            continue;
226        }
227        MPQFile m(iter->c_str());
228        if(!m.isEof())
229            fwrite(m.getPointer(),1,m.getSize(),output);
230
231        fclose(output);
232        ++count;
233    }
234    printf("Extracted %u DBC files\n", count);
235}
236
237int GetLocale()
238{
239    for (int i = 0; i < LANG_COUNT; i++)
240    {
241        char tmp1[512];
242        sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
243        if (FileExists(tmp1))
244        {
245            printf("Detected locale: %s\n", langs[i]);
246            return i;
247        }
248    }
249
250    printf("Could not detect locale.\n");
251    return -1;
252}
253
254void LoadMPQFiles(int const locale)
255{
256    char filename[512];
257
258    sprintf(filename,"%s/Data/%s/locale-%s.MPQ",input_path,langs[locale],langs[locale]);
259    new MPQArchive(filename);
260
261    for(int i = 1; i < 5; ++i)
262    {
263        char ext[3] = "";
264        if(i > 1)
265            sprintf(ext, "-%i", i);
266
267        sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ",input_path,langs[locale],langs[locale],ext);
268        if(!FileExists(filename))
269            break;
270        new MPQArchive(filename);
271    }
272
273    //need those files only if extract maps
274    if(extract & EXTRACT_MAP)
275    {
276        sprintf(filename,"%s/Data/common.MPQ",input_path);
277        new MPQArchive(filename);
278        sprintf(filename,"%s/Data/expansion.MPQ",input_path);
279        new MPQArchive(filename);
280
281        for(int i = 1; i < 5; ++i)
282        {
283            char ext[3] = "";
284            if(i > 1)
285                sprintf(ext, "-%i", i);
286
287            sprintf(filename,"%s/Data/patch%s.MPQ",input_path,ext);
288            if(!FileExists(filename))
289                break;
290            new MPQArchive(filename);
291        }
292    }
293}
294
295int main(int argc, char * arg[])
296{
297    printf("Map & DBC Extractor\n");
298    printf("===================\n");
299
300    HandleArgs(argc, arg);
301
302    int const locale = GetLocale();
303    if(locale < 0)
304        return 1;
305
306    LoadMPQFiles(locale);
307
308    if(extract & EXTRACT_DBC)
309        ExtractDBCFiles();
310
311    if(extract & EXTRACT_MAP)
312        ExtractMapsFromMpq();
313
314    //Close MPQs
315    for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
316        (*i)->close();
317    gOpenArchives.clear();
318
319    return 0;
320}
Note: See TracBrowser for help on using the browser.