diff options
Diffstat (limited to 'src')
22 files changed, 222 insertions, 321 deletions
diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h index 8cd965ddffd..34f4a8a78c4 100644 --- a/src/server/collision/VMapDefinitions.h +++ b/src/server/collision/VMapDefinitions.h @@ -25,8 +25,8 @@ namespace VMAP { - const char VMAP_MAGIC[] = "VMAP_4.1"; - const char RAW_VMAP_MAGIC[] = "VMAP041"; // used in extracted vmap files with raw data + const char VMAP_MAGIC[] = "VMAP_4.2"; + const char RAW_VMAP_MAGIC[] = "VMAP042"; // used in extracted vmap files with raw data const char GAMEOBJECT_MODELS[] = "GameObjectModels.dtree"; // defined in TileAssembler.cpp currently... diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index f5f9546b7b2..608d6eb804e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -38,7 +38,7 @@ #include "VMapFactory.h" u_map_magic MapMagic = { {'M','A','P','S'} }; -u_map_magic MapVersionMagic = { {'v','1','.','3'} }; +u_map_magic MapVersionMagic = { {'v','1','.','4'} }; u_map_magic MapAreaMagic = { {'A','R','E','A'} }; u_map_magic MapHeightMagic = { {'M','H','G','T'} }; u_map_magic MapLiquidMagic = { {'M','L','I','Q'} }; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index c0736fb6c42..7843e1fdb84 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -4630,7 +4630,7 @@ enum PartyResult }; const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP' -#define MMAP_VERSION 5 +#define MMAP_VERSION 6 struct MmapTileHeader { diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 2bb05445744..1500273a51c 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -18,9 +18,10 @@ #define _CRT_SECURE_NO_DEPRECATE -#include <stdio.h> +#include <cstdio> #include <deque> #include <list> +#include <set> #include <cstdlib> #include <cstring> @@ -262,7 +263,7 @@ uint32 ReadMapDBC() printf("Read Map.dbc file... "); HANDLE dbcFile; - if (!CascOpenFile(CascStorage, "DBFilesClient\\Map.dbc", CASC_LOCALE_ALL, 0, &dbcFile)) + if (!CascOpenFile(CascStorage, "DBFilesClient\\Map.dbc", CASC_LOCALE_NONE, 0, &dbcFile)) { printf("Fatal error: Cannot find Map.dbc in archive!\n"); exit(1); @@ -292,7 +293,7 @@ void ReadAreaTableDBC() { printf("Read AreaTable.dbc file..."); HANDLE dbcFile; - if (!CascOpenFile(CascStorage, "DBFilesClient\\AreaTable.dbc", CASC_LOCALE_ALL, 0, &dbcFile)) + if (!CascOpenFile(CascStorage, "DBFilesClient\\AreaTable.dbc", CASC_LOCALE_NONE, 0, &dbcFile)) { printf("Fatal error: Cannot find AreaTable.dbc in archive!\n"); exit(1); @@ -320,7 +321,7 @@ void ReadLiquidTypeTableDBC() { printf("Read LiquidType.dbc file..."); HANDLE dbcFile; - if (!CascOpenFile(CascStorage, "DBFilesClient\\LiquidType.dbc", CASC_LOCALE_ALL, 0, &dbcFile)) + if (!CascOpenFile(CascStorage, "DBFilesClient\\LiquidType.dbc", CASC_LOCALE_NONE, 0, &dbcFile)) { printf("Fatal error: Cannot find LiquidType.dbc in archive!\n"); exit(1); @@ -351,7 +352,7 @@ void ReadLiquidTypeTableDBC() // Map file format data static char const* MAP_MAGIC = "MAPS"; -static char const* MAP_VERSION_MAGIC = "v1.3"; +static char const* MAP_VERSION_MAGIC = "v1.4"; static char const* MAP_AREA_MAGIC = "AREA"; static char const* MAP_HEIGHT_MAGIC = "MHGT"; static char const* MAP_LIQUID_MAGIC = "MLIQ"; @@ -440,7 +441,22 @@ uint16 liquid_entry[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE]; float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1]; -uint16 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID]; +uint8 holes[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID][8]; + +bool TransformToHighRes(uint16 holes, uint8 hiResHoles[8]) +{ + for (uint8 i = 0; i < 8; i++) + { + for (uint8 j = 0; j < 8; j++) + { + int32 holeIdxL = (i / 2) * 4 + (j / 2); + if (((holes >> holeIdxL) & 1) == 1) + hiResHoles[i] |= (1 << j); + } + } + + return *((uint64*)hiResHoles) != 0; +} bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, uint32 build) { @@ -599,10 +615,14 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, if (!(mcnk->flags & 0x10000)) { if (uint16 hole = mcnk->holes) - { - holes[mcnk->iy][mcnk->ix] = mcnk->holes; + if (TransformToHighRes(hole, holes[mcnk->iy][mcnk->ix])) + hasHoles = true; + } + else + { + memcpy(holes[mcnk->iy][mcnk->ix], mcnk->union_5_3_0.HighResHoles, sizeof(uint64)); + if (*((uint64*)holes[mcnk->iy][mcnk->ix]) != 0) hasHoles = true; - } } } @@ -965,6 +985,23 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, return true; } +void ExtractWmos(ChunkedFile& file, std::set<std::string>& wmoList) +{ + if (FileChunk* chunk = file.GetChunk("MWMO")) + { + file_MWMO* wmo = chunk->As<file_MWMO>(); + if (wmo->size) + { + char* fileName = wmo->FileList; + while (fileName < wmo->FileList + wmo->size) + { + wmoList.insert(fileName); + fileName += strlen(fileName) + 1; + } + } + } +} + void ExtractMaps(uint32 build) { char storagePath[1024]; @@ -981,6 +1018,8 @@ void ExtractMaps(uint32 build) path += "/maps/"; CreateDir(path); + std::set<std::string> wmoList; + printf("Convert map files\n"); for (uint32 z = 0; z < map_count; ++z) { @@ -991,6 +1030,8 @@ void ExtractMaps(uint32 build) if (!wdt.loadFile(CascStorage, storagePath, false)) continue; + ExtractWmos(wdt, wmoList); + FileChunk* chunk = wdt.GetChunk("MAIN"); for (uint32 y = 0; y < WDT_MAP_SIZE; ++y) { @@ -1002,6 +1043,11 @@ void ExtractMaps(uint32 build) sprintf(storagePath, "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(storagePath, output_filename, y, x, build); + + sprintf(storagePath, "World\\Maps\\%s\\%s_%u_%u_obj0.adt", map_ids[z].name, map_ids[z].name, x, y); + ChunkedFile adtObj; + if (adtObj.loadFile(CascStorage, storagePath, false)) + ExtractWmos(adtObj, wmoList); } // draw progress bar @@ -1009,6 +1055,17 @@ void ExtractMaps(uint32 build) } } + if (!wmoList.empty()) + { + if (FILE* wmoListFile = fopen("wmo_list.txt", "w")) + { + for (std::string const& wmo : wmoList) + fprintf(wmoListFile, "%s\n", wmo.c_str()); + + fclose(wmoListFile); + } + } + printf("\n"); delete[] areas; delete[] map_ids; diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h index 15145ccd5bf..99e74d9809b 100644 --- a/src/tools/map_extractor/adt.h +++ b/src/tools/map_extractor/adt.h @@ -107,7 +107,7 @@ public: uint32 offsMCVT; // height map uint32 offsMCNR; // Normal vectors for each vertex } offsets; - uint64 HighResHoles; // TODO: maybe use this? + uint8 HighResHoles[8]; } union_5_3_0; uint32 offsMCLY; // Texture layer definitions uint32 offsMCRF; // A list of indices into the parent file's MDDF chunk diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index 7af56d89a0c..f4829a3eb7c 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -95,6 +95,7 @@ u_map_fcc InterestingChunks[] = { { 'O', '2', 'H', 'M' }, { 'K', 'N', 'C', 'M' }, { 'T', 'V', 'C', 'M' }, + { 'O', 'M', 'W', 'M' }, { 'Q', 'L', 'C', 'M' } }; @@ -113,10 +114,9 @@ void ChunkedFile::parseChunks() while (ptr < GetData() + GetDataSize()) { u_map_fcc header = *(u_map_fcc*)ptr; - uint32 size = 0; if (IsInterestingChunk(header)) { - size = *(uint32*)(ptr + 4); + uint32 size = *(uint32*)(ptr + 4); if (size <= data_size) { std::swap(header.fcc_txt[0], header.fcc_txt[3]); @@ -126,10 +126,12 @@ void ChunkedFile::parseChunks() chunk->parseSubChunks(); chunks.insert({ std::string(header.fcc_txt, 4), chunk }); } - } - // move to next chunk - ptr += size + 8; + // move to next chunk + ptr += size + 8; + } + else + ++ptr; } } @@ -156,10 +158,9 @@ void FileChunk::parseSubChunks() while (ptr < data + size) { u_map_fcc header = *(u_map_fcc*)ptr; - uint32 subsize = 0; if (IsInterestingChunk(header)) { - subsize = *(uint32*)(ptr + 4); + uint32 subsize = *(uint32*)(ptr + 4); if (subsize < size) { std::swap(header.fcc_txt[0], header.fcc_txt[3]); @@ -169,10 +170,12 @@ void FileChunk::parseSubChunks() chunk->parseSubChunks(); subchunks.insert({ std::string(header.fcc_txt, 4), chunk }); } - } - // move to next chunk - ptr += subsize + 8; + // move to next chunk + ptr += subsize + 8; + } + else + ++ptr; } } diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h index 873aa3346b6..10d14aed114 100644 --- a/src/tools/map_extractor/loadlib/loadlib.h +++ b/src/tools/map_extractor/loadlib/loadlib.h @@ -72,6 +72,12 @@ struct file_MVER uint32 ver; }; +struct file_MWMO +{ + u_map_fcc fcc; + uint32 size; + char FileList[1]; +}; class FileChunk { diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 2f8b35fd52d..509321444ef 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -28,7 +28,7 @@ #include "DetourCommon.h" #define MMAP_MAGIC 0x4d4d4150 // 'MMAP' -#define MMAP_VERSION 5 +#define MMAP_VERSION 6 struct MmapTileHeader { diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 771275a1757..0a3237b4fe5 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -80,7 +80,7 @@ struct map_liquidHeader namespace MMAP { - char const* MAP_VERSION_MAGIC = "v1.3"; + char const* MAP_VERSION_MAGIC = "v1.4"; TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid){ } TerrainBuilder::~TerrainBuilder() { } @@ -168,7 +168,7 @@ namespace MMAP } // data used later - uint16 holes[16][16]; + uint8 holes[16][16][8]; memset(holes, 0, sizeof(holes)); uint8 liquid_type[16][16]; memset(liquid_type, 0, sizeof(liquid_type)); @@ -599,22 +599,17 @@ namespace MMAP coord[2] = v[index2]; } - static uint16 holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888}; - static uint16 holetab_v[4] = {0x000F, 0x00F0, 0x0F00, 0xF000}; - /**************************************************************************/ - bool TerrainBuilder::isHole(int square, const uint16 holes[16][16]) + bool TerrainBuilder::isHole(int square, uint8 const holes[16][16][8]) { int row = square / 128; int col = square % 128; int cellRow = row / 8; // 8 squares per cell int cellCol = col / 8; - int holeRow = row % 8 / 2; - int holeCol = (square - (row * 128 + cellCol * 8)) / 2; - - uint16 hole = holes[cellRow][cellCol]; + int holeRow = row % 8; + int holeCol = (square - (row * 128 + cellCol * 8)); - return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0; + return holes[cellRow][cellCol][holeRow] & (1 << holeCol); } /**************************************************************************/ diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 6ed88ff985f..6b692d6f3bf 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -114,7 +114,7 @@ namespace MMAP void getHeightTriangle(int square, Spot triangle, int* indices, bool liquid = false); /// Determines if the specific position's triangles should be rendered - bool isHole(int square, const uint16 holes[16][16]); + bool isHole(int square, uint8 const holes[16][16][8]); /// Get the liquid vector coordinate for a specific position void getLiquidCoord(int index, int index2, float xOffset, float yOffset, float* coord, float* v); diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index 15723e7d941..c1dee6c7339 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -77,35 +77,19 @@ char* GetExtension(char* FileName) return NULL; } -extern HANDLE WorldMpq; +extern HANDLE CascStorage; -ADTFile::ADTFile(char* filename) : ADT(WorldMpq, filename, false) +ADTFile::ADTFile(char* filename) : ADT(CascStorage, filename, false) { Adtfilename.append(filename); } bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) { - if(ADT.isEof ()) + if (ADT.isEof()) return false; uint32 size; - - string xMap; - string yMap; - - Adtfilename.erase(Adtfilename.find(".adt"),4); - string TempMapNumber; - TempMapNumber = Adtfilename.substr(Adtfilename.length()-6,6); - xMap = TempMapNumber.substr(TempMapNumber.find("_")+1,(TempMapNumber.find_last_of("_")-1) - (TempMapNumber.find("_"))); - yMap = TempMapNumber.substr(TempMapNumber.find_last_of("_")+1,(TempMapNumber.length()) - (TempMapNumber.find_last_of("_"))); - Adtfilename.erase((Adtfilename.length()-xMap.length()-yMap.length()-2), (xMap.length()+yMap.length()+2)); - //string AdtMapNumber = xMap + ' ' + yMap + ' ' + GetPlainName((char*)Adtfilename.c_str()); - //printf("Processing map %s...\n", AdtMapNumber.c_str()); - //printf("MapNumber = %s\n", TempMapNumber.c_str()); - //printf("xMap = %s\n", xMap.c_str()); - //printf("yMap = %s\n", yMap.c_str()); - std::string dirname = std::string(szWorkDirWmo) + "/dir_bin"; FILE *dirfile; dirfile = fopen(dirname.c_str(), "ab"); @@ -138,8 +122,6 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) char* buf = new char[size]; ADT.read(buf, size); char* p = buf; - int t = 0; - ModelInstanceNames = new std::string[size]; while (p < buf + size) { std::string path(p); @@ -148,7 +130,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) FixNameCase(s, strlen(s)); FixNameSpaces(s, strlen(s)); - ModelInstanceNames[t++] = s; + ModelInstanceNames.push_back(s); ExtractSingleModel(path); @@ -164,15 +146,13 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) char* buf = new char[size]; ADT.read(buf, size); char* p = buf; - int q = 0; - WmoInstanceNames = new std::string[size]; while (p < buf + size) { char* s = GetPlainName(p); FixNameCase(s, strlen(s)); FixNameSpaces(s, strlen(s)); - WmoInstanceNames[q++] = s; + WmoInstanceNames.push_back(s); p += strlen(p) + 1; } @@ -191,8 +171,8 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) ADT.read(&id, 4); ModelInstance inst(ADT, ModelInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile); } - delete[] ModelInstanceNames; - ModelInstanceNames = NULL; + + ModelInstanceNames.clear(); } } else if (!strcmp(fourcc,"MODF")) @@ -207,8 +187,7 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) WMOInstance inst(ADT, WmoInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile); } - delete[] WmoInstanceNames; - WmoInstanceNames = NULL; + WmoInstanceNames.clear(); } } diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h index 1970686f30e..2877603f1ad 100644 --- a/src/tools/vmap4_extractor/adtfile.h +++ b/src/tools/vmap4_extractor/adtfile.h @@ -119,8 +119,8 @@ public: ~ADTFile(); int nWMO; int nMDX; - std::string* WmoInstanceNames; - std::string* ModelInstanceNames; + std::vector<std::string> WmoInstanceNames; + std::vector<std::string> ModelInstanceNames; bool init(uint32 map_num, uint32 tileX, uint32 tileY); //void LoadMapChunks(); diff --git a/src/tools/vmap4_extractor/dbcfile.cpp b/src/tools/vmap4_extractor/dbcfile.cpp index a825fcacddd..5f0504ddcf8 100644 --- a/src/tools/vmap4_extractor/dbcfile.cpp +++ b/src/tools/vmap4_extractor/dbcfile.cpp @@ -27,14 +27,14 @@ DBCFile::DBCFile(HANDLE mpq, const char* filename) : bool DBCFile::open() { - if (!SFileOpenFileEx(_mpq, _filename, SFILE_OPEN_PATCHED_FILE, &_file)) + if (!CascOpenFile(_mpq, _filename, CASC_LOCALE_NONE, 0, &_file)) return false; char header[4]; unsigned int na, nb, es, ss; DWORD readBytes = 0; - SFileReadFile(_file, header, 4, &readBytes, NULL); + CascReadFile(_file, header, 4, &readBytes); if (readBytes != 4) // Number of records return false; @@ -42,22 +42,22 @@ bool DBCFile::open() return false; readBytes = 0; - SFileReadFile(_file, &na, 4, &readBytes, NULL); + CascReadFile(_file, &na, 4, &readBytes); if (readBytes != 4) // Number of records return false; readBytes = 0; - SFileReadFile(_file, &nb, 4, &readBytes, NULL); + CascReadFile(_file, &nb, 4, &readBytes); if (readBytes != 4) // Number of fields return false; readBytes = 0; - SFileReadFile(_file, &es, 4, &readBytes, NULL); + CascReadFile(_file, &es, 4, &readBytes); if (readBytes != 4) // Size of a record return false; readBytes = 0; - SFileReadFile(_file, &ss, 4, &readBytes, NULL); + CascReadFile(_file, &ss, 4, &readBytes); if (readBytes != 4) // String size return false; @@ -73,7 +73,7 @@ bool DBCFile::open() size_t data_size = _recordSize * _recordCount + _stringSize; readBytes = 0; - SFileReadFile(_file, _data, data_size, &readBytes, NULL); + CascReadFile(_file, _data, data_size, &readBytes); if (readBytes != data_size) return false; @@ -84,7 +84,7 @@ DBCFile::~DBCFile() { delete [] _data; if (_file != NULL) - SFileCloseFile(_file); + CascCloseFile(_file); } DBCFile::Record DBCFile::getRecord(size_t id) diff --git a/src/tools/vmap4_extractor/dbcfile.h b/src/tools/vmap4_extractor/dbcfile.h index 8e2edf951e1..8ccfd979811 100644 --- a/src/tools/vmap4_extractor/dbcfile.h +++ b/src/tools/vmap4_extractor/dbcfile.h @@ -20,7 +20,7 @@ #define DBCFILE_H #include <cassert> #include <string> -#include "StormLib.h" +#include "CascLib.h" class DBCFile { diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp index 3bb0ac86901..e9603e8b3d1 100644 --- a/src/tools/vmap4_extractor/gameobject_extract.cpp +++ b/src/tools/vmap4_extractor/gameobject_extract.cpp @@ -52,18 +52,25 @@ bool ExtractSingleModel(std::string& fname) return mdl.ConvertToVMAPModel(output.c_str()); } -extern HANDLE LocaleMpq; +extern HANDLE CascStorage; void ExtractGameobjectModels() { printf("Extracting GameObject models..."); - DBCFile dbc(LocaleMpq, "DBFilesClient\\GameObjectDisplayInfo.dbc"); + DBCFile dbc(CascStorage, "DBFilesClient\\GameObjectDisplayInfo.dbc"); if(!dbc.open()) { printf("Fatal error: Invalid GameObjectDisplayInfo.dbc file format!\n"); exit(1); } + DBCFile fileData(CascStorage, "DBFilesClient\\FileData.dbc"); + if (!fileData.open()) + { + printf("Fatal error: Invalid FileData.dbc file format!\n"); + exit(1); + } + std::string basepath = szWorkDirWmo; basepath += "/"; std::string path; @@ -76,9 +83,27 @@ void ExtractGameobjectModels() return; } + size_t maxFileId = fileData.getMaxId() + 1; + uint32* fileDataIndex = new uint32[maxFileId]; + memset(fileDataIndex, 0, maxFileId * sizeof(uint32)); + size_t files = fileData.getRecordCount(); + for (uint32 i = 0; i < files; ++i) + fileDataIndex[fileData.getRecord(i).getUInt(0)] = i; + for (DBCFile::Iterator it = dbc.begin(); it != dbc.end(); ++it) { - path = it->getString(1); + uint32 fileId = it->getUInt(1); + if (!fileId) + continue; + + uint32 fileIndex = fileDataIndex[fileId]; + if (!fileIndex) + continue; + + std::string filename = fileData.getRecord(fileIndex).getString(1); + std::string filepath = fileData.getRecord(fileIndex).getString(2); + + path = filepath + filename; if (path.length() < 4) continue; @@ -98,7 +123,7 @@ void ExtractGameobjectModels() result = ExtractSingleWmo(path); else if (!strcmp(ch_ext, ".mdl")) // TODO: extract .mdl files, if needed continue; - else //if (!strcmp(ch_ext, ".mdx") || !strcmp(ch_ext, ".m2")) + else if (!strcmp(ch_ext, ".mdx") || !strcmp(ch_ext, ".m2")) result = ExtractSingleModel(path); if (result) @@ -113,5 +138,7 @@ void ExtractGameobjectModels() fclose(model_list); + delete[] fileDataIndex; + printf("Done!\n"); } diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index d0a09271210..8cbc41d6c1b 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -24,7 +24,7 @@ #include <algorithm> #include <cstdio> -extern HANDLE WorldMpq; +extern HANDLE CascStorage; Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0) { @@ -33,7 +33,7 @@ Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0 bool Model::open() { - MPQFile f(WorldMpq, filename.c_str()); + MPQFile f(CascStorage, filename.c_str()); if (f.isEof()) { diff --git a/src/tools/vmap4_extractor/mpqfile.cpp b/src/tools/vmap4_extractor/mpqfile.cpp index 4e690aabee3..87b0b5b5611 100644 --- a/src/tools/vmap4_extractor/mpqfile.cpp +++ b/src/tools/vmap4_extractor/mpqfile.cpp @@ -1,7 +1,6 @@ #include "mpqfile.h" #include <deque> #include <cstdio> -#include "StormLib.h" MPQFile::MPQFile(HANDLE mpq, const char* filename, bool warnNoExist /*= true*/) : eof(false), @@ -10,7 +9,7 @@ MPQFile::MPQFile(HANDLE mpq, const char* filename, bool warnNoExist /*= true*/) size(0) { HANDLE file; - if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file)) + if (!CascOpenFile(mpq, filename, CASC_LOCALE_ALL, 0, &file)) { if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND) fprintf(stderr, "Can't open %s, err=%u!\n", filename, GetLastError()); @@ -19,12 +18,12 @@ MPQFile::MPQFile(HANDLE mpq, const char* filename, bool warnNoExist /*= true*/) } DWORD hi = 0; - size = SFileGetFileSize(file, &hi); + size = CascGetFileSize(file, &hi); if (hi) { fprintf(stderr, "Can't open %s, size[hi] = %u!\n", filename, uint32(hi)); - SFileCloseFile(file); + CascCloseFile(file); eof = true; return; } @@ -32,22 +31,22 @@ MPQFile::MPQFile(HANDLE mpq, const char* filename, bool warnNoExist /*= true*/) if (size <= 1) { fprintf(stderr, "Can't open %s, size = %u!\n", filename, uint32(size)); - SFileCloseFile(file); + CascCloseFile(file); eof = true; return; } DWORD read = 0; buffer = new char[size]; - if (!SFileReadFile(file, buffer, size, &read) || size != read) + if (!CascReadFile(file, buffer, size, &read) || size != read) { fprintf(stderr, "Can't read %s, size=%u read=%u!\n", filename, uint32(size), uint32(read)); - SFileCloseFile(file); + CascCloseFile(file); eof = true; return; } - SFileCloseFile(file); + CascCloseFile(file); } size_t MPQFile::read(void* dest, size_t bytes) diff --git a/src/tools/vmap4_extractor/mpqfile.h b/src/tools/vmap4_extractor/mpqfile.h index e7379c4f7a0..12b666f7c5d 100644 --- a/src/tools/vmap4_extractor/mpqfile.h +++ b/src/tools/vmap4_extractor/mpqfile.h @@ -11,7 +11,7 @@ #include <vector> #include <iostream> #include <deque> -#include "StormLib.h" +#include "CascLib.h" #ifdef _WIN32 #include <Windows.h> // mainly only HANDLE definition is required diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 92878e680dc..b273ebc5cbf 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -24,6 +24,7 @@ #include <errno.h> #ifdef WIN32 + #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <sys/stat.h> #include <direct.h> @@ -33,13 +34,8 @@ #define ERROR_PATH_NOT_FOUND ERROR_FILE_NOT_FOUND #endif -#undef min -#undef max - -//#pragma warning(disable : 4505) -//#pragma comment(lib, "Winmm.lib") - #include <map> +#include <fstream> //From Extractor #include "adtfile.h" @@ -57,51 +53,7 @@ //----------------------------------------------------------------------------- -HANDLE WorldMpq = NULL; -HANDLE LocaleMpq = NULL; - -uint32 CONF_TargetBuild = 15595; // 4.3.4.15595 - -// List MPQ for extract maps from -char const* CONF_mpq_list[]= -{ - "world.MPQ", - "art.MPQ", - "expansion1.MPQ", - "expansion2.MPQ", - "expansion3.MPQ", - "world2.MPQ", -}; - -uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 15354, 15595, 0}; -#define LAST_DBC_IN_DATA_BUILD 13623 // after this build mpqs with dbc are back to locale folder -#define NEW_BASE_SET_BUILD 15211 - -#define LOCALES_COUNT 15 - -char const* Locales[LOCALES_COUNT] = -{ - "enGB", "enUS", - "deDE", "esES", - "frFR", "koKR", - "zhCN", "zhTW", - "enCN", "enTW", - "esMX", "ruRU", - "ptBR", "ptPT", - "itIT" -}; - -TCHAR const* LocalesT[LOCALES_COUNT] = -{ - _T("enGB"), _T("enUS"), - _T("deDE"), _T("esES"), - _T("frFR"), _T("koKR"), - _T("zhCN"), _T("zhTW"), - _T("enCN"), _T("enTW"), - _T("esMX"), _T("ruRU"), - _T("ptBR"), _T("ptPT"), - _T("itIT"), -}; +HANDLE CascStorage = NULL; typedef struct { @@ -112,130 +64,28 @@ typedef struct map_id * map_ids; uint16 *LiqType = 0; uint32 map_count; -char output_path[128]="."; -char input_path[1024]="."; +char output_path[128] = "."; +char input_path[1024] = "."; bool preciseVectorData = false; // Constants //static const char * szWorkDirMaps = ".\\Maps"; const char* szWorkDirWmo = "./Buildings"; -const char* szRawVMAPMagic = "VMAP041"; +const char* szRawVMAPMagic = "VMAP042"; -bool LoadLocaleMPQFile(int locale) +bool OpenCascStorage() { - TCHAR buff[512]; - memset(buff, 0, sizeof(buff)); - _stprintf(buff, _T("%s%s/locale-%s.MPQ"), input_path, LocalesT[locale], LocalesT[locale]); - if (!SFileOpenArchive(buff, 0, MPQ_OPEN_READ_ONLY, &LocaleMpq)) + if (!CascOpenStorage(".\\Data", 0, &CascStorage)) { - if (GetLastError() != ERROR_PATH_NOT_FOUND) - { - _tprintf(_T("Loading %s locale MPQs\n"), LocalesT[locale]); - _tprintf(_T("Cannot open archive %s\n"), buff); - } + printf("Error %d\n", GetLastError()); return false; } - _tprintf(_T("Loading %s locale MPQs\n"), LocalesT[locale]); - char const* prefix = NULL; - for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i) - { - // Do not attempt to read older MPQ patch archives past this build, they were merged with base - // and trying to read them together with new base will not end well - if (CONF_TargetBuild >= NEW_BASE_SET_BUILD && Builds[i] < NEW_BASE_SET_BUILD) - continue; - - memset(buff, 0, sizeof(buff)); - if (Builds[i] > LAST_DBC_IN_DATA_BUILD) - { - prefix = ""; - _stprintf(buff, _T("%s%s/wow-update-%s-%u.MPQ"), input_path, LocalesT[locale], LocalesT[locale], Builds[i]); - } - else - { - prefix = Locales[locale]; - _stprintf(buff, _T("%swow-update-%u.MPQ"), input_path, Builds[i]); - } - - if (!SFileOpenPatchArchive(LocaleMpq, buff, prefix, 0)) - { - if (GetLastError() != ERROR_FILE_NOT_FOUND) - _tprintf(_T("Cannot open patch archive %s\n"), buff); - continue; - } - } - printf("\n"); return true; } -void LoadCommonMPQFiles(uint32 build) -{ - TCHAR filename[512]; - _stprintf(filename, _T("%sworld.MPQ"), input_path); - _tprintf(_T("Loading common MPQ files\n")); - if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &WorldMpq)) - { - if (GetLastError() != ERROR_PATH_NOT_FOUND) - _tprintf(_T("Cannot open archive %s\n"), filename); - return; - } - - int count = sizeof(CONF_mpq_list) / sizeof(char*); - for (int i = 1; i < count; ++i) - { - if (build < 15211 && !strcmp("world2.MPQ", CONF_mpq_list[i])) // 4.3.2 and higher MPQ - continue; - - _stprintf(filename, _T("%s%s"), input_path, CONF_mpq_list[i]); - if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0)) - { - if (GetLastError() != ERROR_PATH_NOT_FOUND) - _tprintf(_T("Cannot open archive %s\n"), filename); - else - _tprintf(_T("Not found %s\n"), filename); - } - else - _tprintf(_T("Loaded %s\n"), filename); - } - - char const* prefix = NULL; - for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i) - { - // Do not attempt to read older MPQ patch archives past this build, they were merged with base - // and trying to read them together with new base will not end well - if (CONF_TargetBuild >= NEW_BASE_SET_BUILD && Builds[i] < NEW_BASE_SET_BUILD) - continue; - - memset(filename, 0, sizeof(filename)); - if (Builds[i] > LAST_DBC_IN_DATA_BUILD) - { - prefix = ""; - _stprintf(filename, _T("%swow-update-base-%u.MPQ"), input_path, Builds[i]); - } - else - { - prefix = "base"; - _stprintf(filename, _T("%swow-update-%u.MPQ"), input_path, Builds[i]); - } - - if (!SFileOpenPatchArchive(WorldMpq, filename, prefix, 0)) - { - if (GetLastError() != ERROR_PATH_NOT_FOUND) - _tprintf(_T("Cannot open patch archive %s\n"), filename); - else - _tprintf(_T("Not found %s\n"), filename); - continue; - } - else - _tprintf(_T("Loaded %s\n"), filename); - } - - printf("\n"); -} - - // Local testing functions bool FileExists(const char* file) @@ -262,7 +112,7 @@ void ReadLiquidTypeTableDBC() { printf("Read LiquidType.dbc file..."); - DBCFile dbc(LocaleMpq, "DBFilesClient\\LiquidType.dbc"); + DBCFile dbc(CascStorage, "DBFilesClient\\LiquidType.dbc"); if(!dbc.open()) { printf("Fatal error: Invalid LiquidType.dbc file format!\n"); @@ -282,23 +132,28 @@ void ReadLiquidTypeTableDBC() bool ExtractWmo() { - bool success = false; + bool success = true; - //const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"}; + std::ifstream wmoList("wmo_list.txt"); + if (!wmoList) + { + printf("\nUnable to open wmo_list.txt! Nothing extracted.\n"); + return false; + } - SFILE_FIND_DATA data; - HANDLE find = SFileFindFirstFile(WorldMpq, "*.wmo", &data, NULL); - if (find != NULL) + std::set<std::string> wmos; + for (;;) { - do - { - std::string str = data.cFileName; - //printf("Extracting wmo %s\n", str.c_str()); - success |= ExtractSingleWmo(str); - } - while (SFileFindNextFile(find, &data)); + std::string str; + std::getline(wmoList, str); + if (str.empty()) + break; + + wmos.insert(std::move(str)); } - SFileFindClose(find); + + for (std::string str : wmos) + success &= ExtractSingleWmo(str); if (success) printf("\nExtract wmo complete (No (fatal) errors)\n"); @@ -463,11 +318,6 @@ bool processArgv(int argc, char ** argv, const char *versionString) { preciseVectorData = true; } - else if(strcmp("-b",argv[i]) == 0) - { - if (i + 1 < argc) // all ok - CONF_TargetBuild = atoi(argv[i++ + 1]); - } else { result = false; @@ -475,14 +325,13 @@ bool processArgv(int argc, char ** argv, const char *versionString) } } - if(!result) + if (!result) { printf("Extract %s.\n",versionString); printf("%s [-?][-s][-l][-d <path>]\n", argv[0]); printf(" -s : (default) small size (data size optimization), ~500MB less vmap data.\n"); printf(" -l : large size, ~500MB more vmap data. (might contain more details)\n"); printf(" -d <path>: Path to the vector data source folder.\n"); - printf(" -b : target build (default %u)\n", CONF_TargetBuild); printf(" -? : This message.\n"); } @@ -492,7 +341,6 @@ bool processArgv(int argc, char ** argv, const char *versionString) return result; } - //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // Main // @@ -504,7 +352,7 @@ bool processArgv(int argc, char ** argv, const char *versionString) int main(int argc, char ** argv) { - bool success=true; + bool success = true; const char *versionString = "V4.00 2012_02"; // Use command line arguments, when some @@ -526,7 +374,7 @@ int main(int argc, char ** argv) } } - printf("Extract %s. Beginning work ....\n\n",versionString); + printf("Extract %s. Beginning work ....\n\n", versionString); //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // Create the working directory if (mkdir(szWorkDirWmo @@ -536,22 +384,16 @@ int main(int argc, char ** argv) )) success = (errno == EEXIST); - LoadCommonMPQFiles(CONF_TargetBuild); - - for (int i = 0; i < LOCALES_COUNT; ++i) + if (!OpenCascStorage()) { - //Open MPQs - if (!LoadLocaleMPQFile(i)) - { - if (GetLastError() != ERROR_PATH_NOT_FOUND) - printf("Unable to load %s locale archives!\n", Locales[i]); - continue; - } - - printf("Detected and using locale: %s\n", Locales[i]); - break; + if (GetLastError() != ERROR_PATH_NOT_FOUND) + printf("Unable to open storage!\n"); + return 1; } + // Extract models, listed in GameObjectDisplayInfo.dbc + ExtractGameobjectModels(); + ReadLiquidTypeTableDBC(); // extract data @@ -562,42 +404,38 @@ int main(int argc, char ** argv) //map.dbc if (success) { - DBCFile * dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc"); + DBCFile * dbc = new DBCFile(CascStorage, "DBFilesClient\\Map.dbc"); if (!dbc->open()) { delete dbc; printf("FATAL ERROR: Map.dbc not found in data file.\n"); return 1; } - map_count=dbc->getRecordCount (); - map_ids=new map_id[map_count]; - for (unsigned int x=0;x<map_count;++x) + + 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("Map - %s\n",map_ids[x].name); + map_ids[x].id = dbc->getRecord(x).getUInt(0); + strcpy(map_ids[x].name, dbc->getRecord(x).getString(1)); + printf("Map - %s\n", map_ids[x].name); } - delete dbc; ParsMapFiles(); delete [] map_ids; - //nError = ERROR_SUCCESS; - // Extract models, listed in GameObjectDisplayInfo.dbc - ExtractGameobjectModels(); } - SFileCloseArchive(LocaleMpq); - SFileCloseArchive(WorldMpq); + CascCloseStorage(CascStorage); printf("\n"); if (!success) { - printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n",versionString, preciseVectorData); + printf("ERROR: Extract %s. Work NOT complete.\n Precise vector data=%d.\nPress any key.\n", versionString, preciseVectorData); getchar(); } - printf("Extract %s. Work complete. No errors.\n",versionString); + printf("Extract %s. Work complete. No errors.\n", versionString); delete [] LiqType; return 0; } diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 6e17c80e187..be83fc6008f 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -30,9 +30,9 @@ char * wdtGetPlainName(char * FileName) return FileName; } -extern HANDLE WorldMpq; +extern HANDLE CascStorage; -WDTFile::WDTFile(char* file_name, char* file_name1):WDT(WorldMpq, file_name) +WDTFile::WDTFile(char* file_name, char* file_name1):WDT(CascStorage, file_name) { filename.append(file_name1,strlen(file_name1)); } @@ -77,15 +77,13 @@ bool WDTFile::init(char* /*map_id*/, unsigned int mapID) { char *buf = new char[size]; WDT.read(buf, size); - char *p=buf; - int q = 0; - gWmoInstansName = new string[size]; + char *p = buf; while (p < buf + size) { - char* s=wdtGetPlainName(p); - FixNameCase(s,strlen(s)); - p=p+strlen(p)+1; - gWmoInstansName[q++] = s; + char* s = wdtGetPlainName(p); + FixNameCase(s, strlen(s)); + p = p + strlen(p) + 1; + gWmoInstansName.push_back(s); } delete[] buf; } @@ -101,10 +99,8 @@ bool WDTFile::init(char* /*map_id*/, unsigned int mapID) { int id; WDT.read(&id, 4); - WMOInstance inst(WDT,gWmoInstansName[id].c_str(), mapID, 65, 65, dirfile); + WMOInstance inst(WDT, gWmoInstansName[id].c_str(), mapID, 65, 65, dirfile); } - - delete[] gWmoInstansName; } } WDT.seek((int)nextpos); diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h index 637a2e0c24f..3b3656b58eb 100644 --- a/src/tools/vmap4_extractor/wdtfile.h +++ b/src/tools/vmap4_extractor/wdtfile.h @@ -22,7 +22,8 @@ #include "mpqfile.h" #include "wmo.h" #include <string> -#include "stdlib.h" +#include <vector> +#include <cstdlib> class ADTFile; @@ -30,13 +31,13 @@ class WDTFile { private: MPQFile WDT; - string filename; + std::string filename; public: WDTFile(char* file_name, char* file_name1); ~WDTFile(void); bool init(char* map_id, unsigned int mapID); - string* gWmoInstansName; + std::vector<std::string> gWmoInstansName; int gnWMO; ADTFile* GetMap(int x, int z); diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index fe79422c87e..ff4522adacb 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -39,11 +39,11 @@ WMORoot::WMORoot(std::string &filename) memset(bbcorn2, 0, sizeof(bbcorn2)); } -extern HANDLE WorldMpq; +extern HANDLE CascStorage; bool WMORoot::open() { - MPQFile f(WorldMpq, filename.c_str()); + MPQFile f(CascStorage, filename.c_str()); if(f.isEof ()) { printf("No such file.\n"); @@ -151,7 +151,7 @@ WMOGroup::WMOGroup(const std::string &filename) : bool WMOGroup::open() { - MPQFile f(WorldMpq, filename.c_str()); + MPQFile f(CascStorage, filename.c_str()); if(f.isEof ()) { printf("No such file.\n"); |