aboutsummaryrefslogtreecommitdiff
path: root/contrib/extractor/System.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/extractor/System.cpp')
-rw-r--r--contrib/extractor/System.cpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/contrib/extractor/System.cpp b/contrib/extractor/System.cpp
new file mode 100644
index 00000000000..090fc557ed7
--- /dev/null
+++ b/contrib/extractor/System.cpp
@@ -0,0 +1,320 @@
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include <stdio.h>
+#include <deque>
+#include <set>
+
+#ifdef WIN32
+#include "direct.h"
+#else
+#include <sys/stat.h>
+#endif
+
+#include "dbcfile.h"
+#include "mpq_libmpq.h"
+
+extern unsigned int iRes;
+extern ArchiveSet gOpenArchives;
+
+bool ConvertADT(char*,char*);
+
+typedef struct{
+ char name[64];
+ unsigned int id;
+}map_id;
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+
+map_id * map_ids;
+uint16 * areas;
+char output_path[128]=".";
+char input_path[128]=".";
+
+enum Extract
+{
+ EXTRACT_MAP = 1,
+ EXTRACT_DBC = 2
+};
+int extract = EXTRACT_MAP | EXTRACT_DBC;
+
+static char* const langs[]={"deDE", "enGB", "enUS", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
+#define LANG_COUNT 12
+
+#define ADT_RES 64
+
+void CreateDir( const std::string& Path )
+{
+ #ifdef WIN32
+ _mkdir( Path.c_str());
+ #else
+ mkdir( Path.c_str(), 0777 );
+ #endif
+}
+
+bool FileExists( const char* FileName )
+{
+ if( FILE* fp = fopen( FileName, "rb" ) )
+ {
+ fclose( fp );
+ return true;
+ }
+
+ return false;
+}
+
+void Usage(char* prg)
+{
+ 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\"",
+ prg,prg);
+ exit(1);
+}
+
+void HandleArgs(int argc, char * arg[])
+{
+ for(int c=1;c<argc;c++)
+ {
+ //i - input path
+ //o - output path
+ //r - resolution, array of (r * r) heights will be created
+ //e - extract only MAP(1)/DBC(2) - standard both(3)
+ if(arg[c][0] != '-')
+ Usage(arg[0]);
+
+ switch(arg[c][1])
+ {
+ case 'i':
+ if(c+1<argc)//all ok
+ strcpy(input_path,arg[(c++) +1]);
+ else
+ Usage(arg[0]);
+ break;
+ case 'o':
+ if(c+1<argc)//all ok
+ strcpy(output_path,arg[(c++) +1]);
+ else
+ Usage(arg[0]);
+ break;
+ case 'r':
+ if(c+1<argc)//all ok
+ iRes=atoi(arg[(c++) +1]);
+ else
+ Usage(arg[0]);
+ break;
+ case 'e':
+ if(c+1<argc)//all ok
+ {
+ extract=atoi(arg[(c++) +1]);
+ if(!(extract > 0 && extract < 4))
+ Usage(arg[0]);
+ }
+ else
+ Usage(arg[0]);
+ break;
+ }
+ }
+}
+
+uint32 ReadMapDBC()
+{
+ printf("Read Map.dbc file... ");
+ DBCFile dbc("DBFilesClient\\Map.dbc");
+ dbc.open();
+
+ uint32 map_count=dbc.getRecordCount();
+ map_ids=new map_id[map_count];
+ for(unsigned int x=0;x<map_count;x++)
+ {
+ map_ids[x].id=dbc.getRecord(x).getUInt(0);
+ strcpy(map_ids[x].name,dbc.getRecord(x).getString(1));
+ }
+ printf("Done! (%u maps loaded)\n", map_count);
+ return map_count;
+}
+
+void ReadAreaTableDBC()
+{
+ printf("Read AreaTable.dbc file... ");
+ DBCFile dbc("DBFilesClient\\AreaTable.dbc");
+ dbc.open();
+
+ unsigned int area_count=dbc.getRecordCount();
+ uint32 maxid = dbc.getMaxId();
+ areas=new uint16[maxid + 1];
+ memset(areas, 0xff, sizeof(areas));
+ for(unsigned int x=0; x<area_count;++x)
+ areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
+
+ printf("Done! (%u areas loaded)\n", area_count);
+}
+
+void ExtractMapsFromMpq()
+{
+ char mpq_filename[1024];
+ char output_filename[1024];
+
+ printf("Extracting maps...\n");
+
+ uint32 map_count = ReadMapDBC();
+
+ ReadAreaTableDBC();
+
+ unsigned int total=map_count*ADT_RES*ADT_RES;
+ unsigned int done=0;
+
+ std::string path = output_path;
+ path += "/maps/";
+ CreateDir(path);
+
+ for(int x = 0; x < ADT_RES; ++x)
+ {
+ for(int y = 0; y < ADT_RES; ++y)
+ {
+ for(int z = 0; z < map_count; ++z)
+ {
+ sprintf(mpq_filename,"World\\Maps\\%s\\%s_%u_%u.adt",map_ids[z].name,map_ids[z].name,x,y);
+ sprintf(output_filename,"%s/maps/%03u%02u%02u.map",output_path,map_ids[z].id,y,x);
+ ConvertADT(mpq_filename,output_filename);
+ done++;
+ }
+ //draw progess bar
+ printf("Processing........................%d%%\r",(100*done)/total);
+ }
+ }
+
+ delete [] areas;
+ delete [] map_ids;
+}
+
+//bool WMO(char* filename);
+
+void ExtractDBCFiles()
+{
+ printf("Extracting dbc files...\n");
+
+ set<string> dbcfiles;
+
+ // get DBC file list
+ for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
+ {
+ vector<string> files = (*i)->GetFileList();
+ for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
+ if (iter->rfind(".dbc") == iter->length() - strlen(".dbc"))
+ dbcfiles.insert(*iter);
+ }
+
+ std::string path = output_path;
+ path += "/dbc/";
+ CreateDir(path);
+
+ // extract DBCs
+ int count = 0;
+ for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
+ {
+ string filename = output_path;
+ filename += "/dbc/";
+ filename += (iter->c_str() + strlen("DBFilesClient\\"));
+
+ //cout << filename << endl;
+
+ FILE *output=fopen(filename.c_str(),"wb");
+ if(!output)
+ {
+ printf("Can't create the output file '%s'\n",filename.c_str());
+ continue;
+ }
+ MPQFile m(iter->c_str());
+ if(!m.isEof())
+ fwrite(m.getPointer(),1,m.getSize(),output);
+
+ fclose(output);
+ ++count;
+ }
+ printf("Extracted %u DBC files\n", count);
+}
+
+int GetLocale()
+{
+ for (int i = 0; i < LANG_COUNT; i++)
+ {
+ char tmp1[512];
+ sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
+ if (FileExists(tmp1))
+ {
+ printf("Detected locale: %s\n", langs[i]);
+ return i;
+ }
+ }
+
+ printf("Could not detect locale.\n");
+ return -1;
+}
+
+void LoadMPQFiles(int const locale)
+{
+ char filename[512];
+
+ sprintf(filename,"%s/Data/%s/locale-%s.MPQ",input_path,langs[locale],langs[locale]);
+ new MPQArchive(filename);
+
+ for(int i = 1; i < 5; ++i)
+ {
+ char ext[3] = "";
+ if(i > 1)
+ sprintf(ext, "-%i", i);
+
+ sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ",input_path,langs[locale],langs[locale],ext);
+ if(!FileExists(filename))
+ break;
+ new MPQArchive(filename);
+ }
+
+ //need those files only if extract maps
+ if(extract & EXTRACT_MAP)
+ {
+ sprintf(filename,"%s/Data/common.MPQ",input_path);
+ new MPQArchive(filename);
+ sprintf(filename,"%s/Data/expansion.MPQ",input_path);
+ new MPQArchive(filename);
+
+ for(int i = 1; i < 5; ++i)
+ {
+ char ext[3] = "";
+ if(i > 1)
+ sprintf(ext, "-%i", i);
+
+ sprintf(filename,"%s/Data/patch%s.MPQ",input_path,ext);
+ if(!FileExists(filename))
+ break;
+ new MPQArchive(filename);
+ }
+ }
+}
+
+int main(int argc, char * arg[])
+{
+ printf("Map & DBC Extractor\n");
+ printf("===================\n");
+
+ HandleArgs(argc, arg);
+
+ int const locale = GetLocale();
+ if(locale < 0)
+ return 1;
+
+ LoadMPQFiles(locale);
+
+ if(extract & EXTRACT_DBC)
+ ExtractDBCFiles();
+
+ if(extract & EXTRACT_MAP)
+ ExtractMapsFromMpq();
+
+ //Close MPQs
+ for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
+ (*i)->close();
+ gOpenArchives.clear();
+
+ return 0;
+}