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

Revision 177, 8.1 kB (checked in by yumileroy, 17 years ago)

[svn] * Avoid access to bag item prototype for getting bag size, use related item
update field instead as more fast source. source mangos.
* Further reduce of DB access in guild handlers.
* Multi-locale DBC extracting - source Foks

*** Devs not responsible if all your player items drop to the ground and get eaten by ants or rabbits.. or some kind of wierd ant-rabbits..

Original author: KingPin?
Date: 2008-11-06 08:20:26-06: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[]={"enGB", "enUS", "deDE", "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(unsigned int x = 0; x < ADT_RES; ++x)
171    {
172        for(unsigned int y = 0; y < ADT_RES; ++y)
173        {
174            for(unsigned 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(int locale, bool basicLocale)
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;
202        (*i)->GetFileListTo(files);
203        for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
204            if (iter->rfind(".dbc") == iter->length() - strlen(".dbc"))
205                    dbcfiles.insert(*iter);
206    }
207
208    string path = output_path;
209    path += "/dbc/";
210    CreateDir(path);
211    if(!basicLocale)
212    {
213        path += langs[locale];
214        path += "/";
215        CreateDir(path);
216    }
217
218    // extract DBCs
219    int count = 0;
220    for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
221    {
222        string filename = path;
223        filename += (iter->c_str() + strlen("DBFilesClient\\"));
224
225        FILE *output=fopen(filename.c_str(),"wb");
226        if(!output)
227        {
228            printf("Can't create the output file '%s'\n",filename.c_str());
229            continue;
230        }
231        MPQFile m(iter->c_str());
232        if(!m.isEof())
233            fwrite(m.getPointer(),1,m.getSize(),output);
234
235        fclose(output);
236        ++count;
237    }
238    printf("Extracted %u DBC files\n\n", count);
239}
240
241void LoadLocaleMPQFiles(int const locale)
242{
243    char filename[512];
244
245    sprintf(filename,"%s/Data/%s/locale-%s.MPQ",input_path,langs[locale],langs[locale]);
246    new MPQArchive(filename);
247
248    for(int i = 1; i < 5; ++i)
249    {
250        char ext[3] = "";
251        if(i > 1)
252            sprintf(ext, "-%i", i);
253
254        sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ",input_path,langs[locale],langs[locale],ext);
255        if(FileExists(filename))
256            new MPQArchive(filename);
257    }
258}
259   
260void LoadCommonMPQFiles()
261{
262    char filename[512];
263
264    sprintf(filename,"%s/Data/common.MPQ",input_path);
265    new MPQArchive(filename);
266    sprintf(filename,"%s/Data/expansion.MPQ",input_path);
267    new MPQArchive(filename);
268    for(int i = 1; i < 5; ++i)
269    {
270        char ext[3] = "";
271        if(i > 1)
272            sprintf(ext, "-%i", i);
273            if(FileExists(filename))
274                new MPQArchive(filename);
275    }
276}
277
278inline void CloseMPQFiles()
279{
280    for(ArchiveSet::iterator j = gOpenArchives.begin(); j != gOpenArchives.end();++j) (*j)->close();
281        gOpenArchives.clear();
282}
283
284int main(int argc, char * arg[])
285{
286    printf("Map & DBC Extractor\n");
287    printf("===================\n\n");
288
289    HandleArgs(argc, arg);
290
291    int FirstLocale = -1;
292   
293    for (int i = 0; i < LANG_COUNT; i++)
294    {
295        char tmp1[512];
296        sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
297        if (FileExists(tmp1))
298        {
299            printf("Detected locale: %s\n", langs[i]);
300           
301            //Open MPQs
302            LoadLocaleMPQFiles(i);
303           
304            if((extract & EXTRACT_DBC) == 0)
305            {
306                FirstLocale=i;
307                break;
308            }
309
310        //Extract DBC files
311        if(FirstLocale<0)
312        {
313            ExtractDBCFiles(i, true);
314            FirstLocale = i;
315        }
316        else 
317            ExtractDBCFiles(i, false);
318       
319            //Close MPQs
320            CloseMPQFiles();
321        }
322    }
323
324    if(FirstLocale<0)
325    {
326        printf("No locales detected\n");
327        return 0;
328    }
329   
330    if (extract & EXTRACT_MAP)
331    {
332        printf("Using locale: %s\n", langs[FirstLocale]);
333       
334        // Open MPQs
335        LoadLocaleMPQFiles(FirstLocale);
336        LoadCommonMPQFiles();
337       
338        // Extract maps
339        ExtractMapsFromMpq();
340
341        // Close MPQs
342        CloseMPQFiles();
343    }
344
345    return 0;
346}
Note: See TracBrowser for help on using the browser.