6#define _CRT_SECURE_NO_DEPRECATE
25 #define ERROR_PATH_NOT_FOUND ERROR_FILE_NOT_FOUND
48#define MPQ_BLOCK_SIZE 0x1000
69uint32 const Builds[] = {16016, 16048, 16057, 16309, 16357, 16516, 16650, 16844, 16965, 17116, 17266, 17325, 17345, 17538, 17645, 17688, 17898, 18273, 0};
70#define LAST_DBC_IN_DATA_BUILD 15595
71#define NEW_BASE_SET_BUILD 16016
73#define LOCALES_COUNT 15
89 _T(
"enGB"), _T(
"enUS"),
90 _T(
"deDE"), _T(
"esES"),
91 _T(
"frFR"), _T(
"koKR"),
92 _T(
"zhCN"), _T(
"zhTW"),
93 _T(
"enCN"), _T(
"enTW"),
94 _T(
"esMX"), _T(
"ruRU"),
95 _T(
"ptBR"), _T(
"ptPT"),
121 memset(buff, 0,
sizeof(buff));
123 if (!SFileOpenArchive(buff, 0, MPQ_OPEN_READ_ONLY, &
LocaleMpq))
127 _tprintf(_T(
"Loading %s locale MPQs\n"),
LocalesT[locale]);
128 _tprintf(_T(
"Cannot open archive %s\n"), buff);
133 _tprintf(_T(
"Loading %s locale MPQs\n"),
LocalesT[locale]);
134 char const* prefix = NULL;
142 memset(buff, 0,
sizeof(buff));
154 if (!SFileOpenPatchArchive(
LocaleMpq, buff, prefix, 0))
156 if (GetLastError() != ERROR_FILE_NOT_FOUND)
157 _tprintf(_T(
"Cannot open patch archive %s\n"), buff);
168 TCHAR filename[1024];
169 _stprintf(filename, _T(
"%sworld.MPQ"),
input_path);
170 _tprintf(_T(
"Loading common MPQ files\n"));
171 if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &
WorldMpq))
174 _tprintf(_T(
"Cannot open archive %s\n"), filename);
179 for (
int i = 1; i < count; ++i)
181 if (build < 15211 && !strcmp(
"world2.MPQ",
CONF_mpq_list[i]))
185 if (!SFileOpenPatchArchive(
WorldMpq, filename,
"", 0))
188 _tprintf(_T(
"Cannot open archive %s\n"), filename);
190 _tprintf(_T(
"Not found %s\n"), filename);
193 _tprintf(_T(
"Loaded %s\n"), filename);
196 char const* prefix = NULL;
204 memset(filename, 0,
sizeof(filename));
216 if (!SFileOpenPatchArchive(
WorldMpq, filename, prefix, 0))
219 _tprintf(_T(
"Cannot open patch archive %s\n"), filename);
221 _tprintf(_T(
"Not found %s\n"), filename);
225 _tprintf(_T(
"Loaded %s\n"), filename);
236 if (FILE* n = fopen(file,
"rb"))
259 snprintf(localMPQ,
sizeof(localMPQ),
"%smisc.MPQ",
input_path);
265 if (!SFileOpenArchive(localMPQ, 0, MPQ_OPEN_READ_ONLY, &localeFile))
270 printf(
"Read LiquidType.dbc file...");
273 if (!SFileOpenFileEx(localeFile,
"DBFilesClient\\LiquidType.dbc", SFILE_OPEN_FROM_MPQ, &dbcFile))
275 if (!SFileOpenFileEx(localeFile,
"DBFilesClient\\LiquidType.dbc", SFILE_OPEN_FROM_MPQ, &dbcFile))
277 printf(
"Fatal error: Cannot find LiquidType.dbc in archive!\n");
282 DBCFile dbc(localeFile,
"DBFilesClient\\LiquidType.dbc");
285 printf(
"Fatal error: Invalid LiquidType.dbc file format!\n");
290 size_t LiqType_maxid = dbc.
getMaxId();
294 for (
size_t x = 0; x < LiqType_count; ++x)
297 printf(
"Done! (%zu LiqTypes loaded)\n", LiqType_count);
303 bool success =
false;
307 SFILE_FIND_DATA data;
308 HANDLE find = SFileFindFirstFile(
WorldMpq,
"*.wmo", &data, NULL);
313 std::string str = data.cFileName;
317 while (SFileFindNextFile(find, &data));
319 SFileFindClose(find);
322 printf(
"\nExtract wmo complete (No (fatal) errors)\n");
331 char szLocalFile[1024];
333 snprintf(szLocalFile,
sizeof(szLocalFile),
"%s/%s",
szWorkDirWmo, plain_name);
341 char const* rchr = strrchr(plain_name,
'_');
345 strncpy((
char*)cpy, rchr, 4);
346 for (
int i = 0; i < 4; ++i)
358 std::cout <<
"Extracting " << fname << std::endl;
362 printf(
"Couldn't open RootWmo!!!\n");
365 FILE *output = fopen(szLocalFile,
"wb");
368 printf(
"couldn't open %s for writing!\n", szLocalFile);
372 int Wmo_nVertices = 0;
379 strncpy(temp, fname.c_str(), 1024);
380 temp[fname.length()-4] = 0;
381 char groupFileName[1024];
382 snprintf(groupFileName,
sizeof(groupFileName),
"%s_%03u.wmo", temp, i);
385 std::string s = groupFileName;
389 printf(
"Could not open all Group file for: %s\n", plain_name);
398 fseek(output, 8, SEEK_SET);
399 fwrite(&Wmo_nVertices,
sizeof(
int),1,output);
415 snprintf(
id,
sizeof(
id),
"%04u",
map_ids[i].
id);
416 snprintf(fn,
sizeof(fn),
"World\\Maps\\%s\\%s.wdt",
map_ids[i].name,
map_ids[i].name);
420 printf(
"Processing Map %u\n[",
map_ids[i].
id);
421 for (
int x=0; x<64; ++x)
423 for (
int y=0; y<64; ++y)
428 ADT->init(
map_ids[i].
id, x, y);
449bool processArgv(
int argc,
char ** argv,
const char *versionString)
452 bool hasInputPathParam =
false;
455 for(
int i = 1; i < argc; ++i)
457 if(strcmp(
"-s",argv[i]) == 0)
461 else if(strcmp(
"-d",argv[i]) == 0)
465 hasInputPathParam =
true;
478 else if(strcmp(
"-?",argv[1]) == 0)
482 else if(strcmp(
"-l",argv[i]) == 0)
486 else if(strcmp(
"-b",argv[i]) == 0)
500 printf(
"Extract %s.\n",versionString);
501 printf(
"%s [-?][-s][-l][-d <path>]\n", argv[0]);
502 printf(
" -s : (default) small size (data size optimization), ~500MB less vmap data.\n");
503 printf(
" -l : large size, ~500MB more vmap data. (might contain more details)\n");
504 printf(
" -d <path>: Path to the vector data source folder.\n");
506 printf(
" -? : This message.\n");
509 if(!hasInputPathParam)
525int main(
int argc,
char ** argv)
528 const char *versionString =
"V5.03 2025_02_09";
538 std::string sdir_bin = std::string(
szWorkDirWmo) +
"/dir_bin";
540 if (!stat(sdir.c_str(), &status) || !stat(sdir_bin.c_str(), &status))
542 printf(
"Your output directory seems to be polluted, please use an empty directory!\n");
543 printf(
"<press return to exit>");
545 return scanf(
"%c", garbage);
549 printf(
"Extract %s. Beginning work ....\n\n",versionString);
553#
if defined(__linux__) || defined(__APPLE__)
557 success = (errno == EEXIST);
567 printf(
"Unable to load %s locale archives!\n",
Locales[i]);
571 printf(
"Detected and using locale: %s\n",
Locales[i]);
581 printf(
"Unable to load Liquid %s locale archives!\n",
Locales[i]);
585 printf(
"Detected and using Liquid locale: %s\n",
Locales[i]);
603 printf(
"FATAL ERROR: Map.dbc not found in data file.\n");
612 size_t max_map_name_length =
sizeof(
map_ids[x].name);
613 if (strlen(map_name) >= max_map_name_length)
617 printf(
"FATAL ERROR: Map name too long.\n");
620 strncpy(
map_ids[x].name, map_name, max_map_name_length);
621 map_ids[x].name[max_map_name_length - 1] =
'\0';
622 printf(
"Map - %s\n",
map_ids[x].name);
638 printf(
"ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString,
preciseVectorData);
642 printf(
"Extract %s. Work complete. No errors.\n",versionString);
#define ERROR_PATH_NOT_FOUND
#define NEW_BASE_SET_BUILD
void ReadLiquidTypeTableDBC()
TCHAR const * LocalesT[LOCALES_COUNT]
char const * CONF_mpq_list[]
char const * Locales[LOCALES_COUNT]
char const * GetPlainName(char const *FileName)
void FixNameCase(char *name, size_t len)
char const * getString(size_t field) const
unsigned int getUInt(size_t field) const
Record getRecord(size_t id)
size_t getRecordCount() const
Trivial.
bool init(char *map_id, unsigned int mapID)
ADTFile * GetMap(int x, int z)
int ConvertToVMAPGroupWmo(FILE *output, WMORoot *rootWMO, bool preciseVectorData)
bool ConvertToVMAPRootWmo(FILE *output)
int main(int argc, char **argv)
void LoadCommonMPQFiles(uint32 build)
bool LoadLocaleMPQFile(int locale)
#define LAST_DBC_IN_DATA_BUILD
bool processArgv(int argc, char **argv, const char *versionString)
bool FileExists(const char *file)
const char * szWorkDirWmo
void strToLower(char *str)
const char * szRawVMAPMagic
bool ExtractSingleWmo(std::string &fname)