diff options
| author | Shauren <shauren.trinity@gmail.com> | 2017-03-08 18:10:02 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2017-03-08 18:10:02 +0100 |
| commit | 7b235ce6e4da0e9c19fa9c6306bc7a71c7fb905d (patch) | |
| tree | 28611e02e44e55d28f60a9b1b3433831ed6772b8 /src/tools/vmap4_extractor | |
| parent | f585c831248f24c93697b0c314dd015897febe39 (diff) | |
Core/DataStores: Refactor DB2 loaders to be reusable by extractors
Diffstat (limited to 'src/tools/vmap4_extractor')
| -rw-r--r-- | src/tools/vmap4_extractor/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/DB2.cpp | 200 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/DB2.h | 176 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/adtfile.cpp | 4 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/cascfile.cpp | 46 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/cascfile.h | 51 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/gameobject_extract.cpp | 52 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/vmapexport.cpp | 246 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/wdtfile.cpp | 5 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/wdtfile.h | 1 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/wmo.cpp | 1 | ||||
| -rw-r--r-- | src/tools/vmap4_extractor/wmo.h | 2 |
12 files changed, 169 insertions, 617 deletions
diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt index 8ef299295f8..8af68c8e8ed 100644 --- a/src/tools/vmap4_extractor/CMakeLists.txt +++ b/src/tools/vmap4_extractor/CMakeLists.txt @@ -21,8 +21,6 @@ add_executable(vmap4extractor ${PRIVATE_SOURCES}) target_link_libraries(vmap4extractor PUBLIC - common - casc bzip2 extractor_common) diff --git a/src/tools/vmap4_extractor/DB2.cpp b/src/tools/vmap4_extractor/DB2.cpp deleted file mode 100644 index fca95476edb..00000000000 --- a/src/tools/vmap4_extractor/DB2.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "DB2.h" -#include <cassert> - -DB2FileLoader::DB2FileLoader() -{ - meta = nullptr; - - recordSize = 0; - recordCount = 0; - fieldCount = 0; - stringSize = 0; - tableHash = 0; - layoutHash = 0; - minIndex = 0; - maxIndex = 0; - localeMask = 0; - copyIdSize = 0; - - data = nullptr; - stringTable = nullptr; - idTable = nullptr; - idTableSize = 0; - copyTable = nullptr; - fields = nullptr; -} - -bool DB2FileLoader::Load(CASC::FileHandle const& db2Handle, DB2Meta const* meta_) -{ - if (data) - { - delete[] data; - data = nullptr; - } - - DWORD bytesRead = 0; - meta = meta_; - std::uint32_t header; - CASC::ReadFile(db2Handle, &header, sizeof(header), &bytesRead); - if (bytesRead != sizeof(header)) // Signature - return false; - - EndianConvert(header); - - if (header != 0x35424457) - return false; //'WDB5' - - CASC::ReadFile(db2Handle, &recordCount, sizeof(recordCount), &bytesRead); - if (bytesRead != sizeof(recordCount)) // Number of records - return false; - - EndianConvert(recordCount); - - CASC::ReadFile(db2Handle, &fieldCount, sizeof(fieldCount), &bytesRead); - if (bytesRead != sizeof(fieldCount)) // Number of fields - return false; - - EndianConvert(fieldCount); - - CASC::ReadFile(db2Handle, &recordSize, sizeof(recordSize), &bytesRead); - if (bytesRead != sizeof(recordSize)) // Size of a record - return false; - - EndianConvert(recordSize); - - CASC::ReadFile(db2Handle, &stringSize, sizeof(stringSize), &bytesRead); - if (bytesRead != sizeof(stringSize)) // String size - return false; - - EndianConvert(stringSize); - - CASC::ReadFile(db2Handle, &tableHash, sizeof(tableHash), &bytesRead); - if (bytesRead != sizeof(tableHash)) // Table hash - return false; - - EndianConvert(tableHash); - - CASC::ReadFile(db2Handle, &layoutHash, sizeof(layoutHash), &bytesRead); - if (bytesRead != sizeof(layoutHash)) // Layout hash - return false; - - if (layoutHash != meta->LayoutHash) - return false; - - EndianConvert(layoutHash); - - CASC::ReadFile(db2Handle, &minIndex, sizeof(minIndex), &bytesRead); - if (bytesRead != sizeof(minIndex)) // MinIndex WDB2 - return false; - - EndianConvert(minIndex); - - CASC::ReadFile(db2Handle, &maxIndex, sizeof(maxIndex), &bytesRead); - if (bytesRead != sizeof(maxIndex)) // MaxIndex WDB2 - return false; - - EndianConvert(maxIndex); - - CASC::ReadFile(db2Handle, &localeMask, sizeof(localeMask), &bytesRead); - if (bytesRead != sizeof(localeMask)) // Locales - return false; - - EndianConvert(localeMask); - - CASC::ReadFile(db2Handle, ©IdSize, sizeof(copyIdSize), &bytesRead); - if (bytesRead != sizeof(copyIdSize)) - return false; - - EndianConvert(copyIdSize); - - CASC::ReadFile(db2Handle, &metaFlags, sizeof(metaFlags), &bytesRead); - if (bytesRead != sizeof(metaFlags)) - return false; - - EndianConvert(metaFlags); - - ASSERT((metaFlags & 0x1) == 0); - ASSERT((meta->IndexField == -1) || (meta->IndexField == int32((metaFlags >> 16)))); - - fields = new FieldEntry[fieldCount]; - CASC::ReadFile(db2Handle, fields, fieldCount * sizeof(FieldEntry), &bytesRead); - if (bytesRead != fieldCount * sizeof(FieldEntry)) - return false; - - if (!meta->HasIndexFieldInData()) - idTableSize = recordCount * sizeof(std::uint32_t); - - data = new unsigned char[recordSize * recordCount + stringSize]; - stringTable = data + recordSize * recordCount; - - CASC::ReadFile(db2Handle, data, recordSize * recordCount + stringSize, &bytesRead); - if (bytesRead != recordSize * recordCount + stringSize) - return false; - - if (idTableSize) - { - idTable = new unsigned char[idTableSize]; - CASC::ReadFile(db2Handle, idTable, idTableSize, &bytesRead); - if (bytesRead != idTableSize) - return false; - } - - if (copyIdSize) - { - copyTable = new unsigned char[copyIdSize]; - CASC::ReadFile(db2Handle, copyTable, copyIdSize, &bytesRead); - if (bytesRead != copyIdSize) - return false; - } - - return true; -} - -DB2FileLoader::~DB2FileLoader() -{ - delete[] data; - delete[] idTable; - delete[] copyTable; - delete[] fields; -} - -DB2FileLoader::Record DB2FileLoader::getRecord(size_t id) -{ - assert(data); - return Record(*this, data + id * recordSize); -} - -std::pair<std::uint32_t, std::uint32_t> DB2FileLoader::GetRowCopy(std::uint32_t i) const -{ - std::uint32_t* copyIds = (std::uint32_t*)copyTable; - std::uint32_t to = copyIds[i]; - std::uint32_t from = copyIds[i + 1]; - return{ from, to }; -} - -std::uint32_t DB2FileLoader::GetMaxId() const -{ - std::uint32_t j = maxIndex; - for (std::uint32_t i = 0; i < GetNumRowCopies(); ++i) - if (j < GetRowCopy(i).second) - j = GetRowCopy(i).second; - - return j; -} diff --git a/src/tools/vmap4_extractor/DB2.h b/src/tools/vmap4_extractor/DB2.h deleted file mode 100644 index f28aeb0e05f..00000000000 --- a/src/tools/vmap4_extractor/DB2.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef MapExtractor_DB2_h__ -#define MapExtractor_DB2_h__ - -#include "DB2Meta.h" -#include "CascHandles.h" -#include "CascLib.h" -#include "Utilities/ByteConverter.h" -#include "Errors.h" - -class DB2FileLoader -{ - public: - DB2FileLoader(); - ~DB2FileLoader(); - - bool Load(CASC::FileHandle const& db2Handle, DB2Meta const* meta); - - class Record - { - public: - float getFloat(std::uint32_t field, std::uint32_t arrayIndex) const - { - ASSERT(field < file.fieldCount); - float val = *reinterpret_cast<float*>(offset + GetOffset(field) + arrayIndex * sizeof(float)); - EndianConvert(val); - return val; - } - - std::uint32_t getUInt(std::uint32_t field, std::uint32_t arrayIndex) const - { - ASSERT(field < file.fieldCount); - return GetVarInt(field, GetByteSize(field), arrayIndex); - } - - std::uint8_t getUInt8(std::uint32_t field, std::uint32_t arrayIndex) const - { - ASSERT(field < file.fieldCount); - ASSERT(GetByteSize(field) == 1); - return *reinterpret_cast<std::uint8_t*>(offset + GetOffset(field) + arrayIndex * sizeof(std::uint8_t)); - } - - std::uint16_t getUInt16(std::uint32_t field, std::uint32_t arrayIndex) const - { - ASSERT(field < file.fieldCount); - ASSERT(GetByteSize(field) == 2); - std::uint16_t val = *reinterpret_cast<std::uint16_t*>(offset + GetOffset(field) + arrayIndex * sizeof(std::uint16_t)); - EndianConvert(val); - return val; - } - - char const* getString(std::uint32_t field, std::uint32_t arrayIndex) const - { - ASSERT(field < file.fieldCount); - std::uint32_t stringOffset = *reinterpret_cast<std::uint32_t*>(offset + GetOffset(field) + arrayIndex * sizeof(std::uint32_t)); - EndianConvert(stringOffset); - ASSERT(stringOffset < file.stringSize); - return reinterpret_cast<char*>(file.stringTable + stringOffset); - } - - private: - std::uint16_t GetOffset(std::uint32_t field) const - { - ASSERT(field < file.fieldCount); - return file.fields[field].Offset; - } - - std::uint16_t GetByteSize(std::uint32_t field) const - { - ASSERT(field < file.fieldCount); - return 4 - file.fields[field].UnusedBits / 8; - } - - std::uint32_t GetVarInt(std::uint32_t field, std::uint16_t size, std::uint32_t arrayIndex) const - { - ASSERT(field < file.fieldCount); - switch (size) - { - case 1: - { - return *reinterpret_cast<std::uint8_t*>(offset + GetOffset(field) + arrayIndex * sizeof(std::uint8_t)); - } - case 2: - { - std::uint16_t val = *reinterpret_cast<std::uint16_t*>(offset + GetOffset(field) + arrayIndex * sizeof(std::uint16_t)); - EndianConvert(val); - return val; - } - case 3: - { -#pragma pack(push, 1) - struct dbcint24 { std::uint8_t v[3]; }; -#pragma pack(pop) - dbcint24 val = *reinterpret_cast<dbcint24*>(offset + GetOffset(field) + arrayIndex * sizeof(dbcint24)); - EndianConvert(val); - return std::uint32_t(val.v[0]) | (std::uint32_t(val.v[1]) << 8) | (std::uint32_t(val.v[2]) << 16); - } - case 4: - { - std::uint32_t val = *reinterpret_cast<std::uint32_t*>(offset + GetOffset(field) + arrayIndex * sizeof(std::uint32_t)); - EndianConvert(val); - return val; - } - default: - break; - } - - ASSERT(false, "GetByteSize(field) < 4"); - return 0; - } - - Record(DB2FileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) {} - unsigned char *offset; - DB2FileLoader &file; - - friend class DB2FileLoader; - }; - - // Get record by id - Record getRecord(size_t id); - std::uint32_t getId(size_t row) { return ((std::uint32_t*)idTable)[row]; } - std::pair<std::uint32_t, std::uint32_t> GetRowCopy(std::uint32_t i) const; - - std::uint32_t GetNumRows() const { return recordCount; } - std::uint32_t GetNumRowCopies() const { return copyIdSize / 8; } - std::uint32_t GetMaxId() const; - -private: -#pragma pack(push, 1) - struct FieldEntry - { - std::uint16_t UnusedBits; - std::uint16_t Offset; - }; -#pragma pack(pop) - - DB2Meta const* meta; - - // WDB2 / WCH2 fields - std::uint32_t recordSize; - std::uint32_t recordCount; - std::uint32_t fieldCount; - std::uint32_t stringSize; - std::uint32_t tableHash; - std::uint32_t layoutHash; - std::uint32_t minIndex; - std::uint32_t maxIndex; - std::uint32_t localeMask; - std::uint32_t copyIdSize; - std::uint32_t metaFlags; - - unsigned char* data; - unsigned char* stringTable; - unsigned char* idTable; - std::uint32_t idTableSize; - unsigned char* copyTable; - FieldEntry* fields; -}; - -#endif // MapExtractor_DB2_h__ diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index f4cb5b686da..e97469c0918 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -148,12 +148,16 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY) char* p = buf; while (p < buf + size) { + std::string path(p); + char* s = GetPlainName(p); FixNameCase(s, strlen(s)); FixNameSpaces(s, strlen(s)); WmoInstanceNames.push_back(s); + ExtractSingleWmo(path); + p += strlen(p) + 1; } delete[] buf; diff --git a/src/tools/vmap4_extractor/cascfile.cpp b/src/tools/vmap4_extractor/cascfile.cpp index b9074d8696e..2a54e5ba27b 100644 --- a/src/tools/vmap4_extractor/cascfile.cpp +++ b/src/tools/vmap4_extractor/cascfile.cpp @@ -1,5 +1,22 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + #include "cascfile.h" -#include <deque> +#include <CascLib.h> #include <cstdio> CASCFile::CASCFile(CASC::StorageHandle const& casc, const char* filename, bool warnNoExist /*= true*/) : @@ -12,33 +29,34 @@ CASCFile::CASCFile(CASC::StorageHandle const& casc, const char* filename, bool w if (!file) { if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND) - fprintf(stderr, "Can't open %s, err=%u!\n", filename, GetLastError()); + fprintf(stderr, "Can't open %s: %s\n", filename, CASC::HumanReadableCASCError(GetLastError())); eof = true; return; } - DWORD hi = 0; - size = CASC::GetFileSize(file, &hi); - - if (hi) + DWORD fileSizeHigh = 0; + DWORD fileSize = CASC::GetFileSize(file, &fileSizeHigh); + if (fileSize == CASC_INVALID_SIZE) { - fprintf(stderr, "Can't open %s, size[hi] = %u!\n", filename, uint32(hi)); + fprintf(stderr, "Can't open %s, failed to get size: %s!\n", filename, CASC::HumanReadableCASCError(GetLastError())); eof = true; return; } - if (size <= 1) + if (fileSizeHigh) { - fprintf(stderr, "Can't open %s, size = %u!\n", filename, uint32(size)); + fprintf(stderr, "Can't open %s, file larger than 2GB", filename); eof = true; return; } + size = fileSize; + DWORD read = 0; buffer = new char[size]; if (!CASC::ReadFile(file, buffer, size, &read) || size != read) { - fprintf(stderr, "Can't read %s, size=%u read=%u!\n", filename, uint32(size), uint32(read)); + fprintf(stderr, "Can't read %s, size=%u read=%u: %s\n", filename, uint32(size), uint32(read), CASC::HumanReadableCASCError(GetLastError())); eof = true; return; } @@ -46,10 +64,12 @@ CASCFile::CASCFile(CASC::StorageHandle const& casc, const char* filename, bool w size_t CASCFile::read(void* dest, size_t bytes) { - if (eof) return 0; + if (eof) + return 0; size_t rpos = pointer + bytes; - if (rpos > size) { + if (rpos > size) + { bytes = size - pointer; eof = true; } @@ -75,7 +95,7 @@ void CASCFile::seekRelative(int offset) void CASCFile::close() { - if (buffer) delete[] buffer; + delete[] buffer; buffer = 0; eof = true; } diff --git a/src/tools/vmap4_extractor/cascfile.h b/src/tools/vmap4_extractor/cascfile.h index 882ec116ca5..fd97fb6e008 100644 --- a/src/tools/vmap4_extractor/cascfile.h +++ b/src/tools/vmap4_extractor/cascfile.h @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + #define _CRT_SECURE_NO_DEPRECATE #ifndef _CRT_SECURE_NO_WARNINGS // fuck the police^Wwarnings #define _CRT_SECURE_NO_WARNINGS @@ -6,33 +23,12 @@ #ifndef MPQ_H #define MPQ_H -#include <string.h> -#include <ctype.h> -#include <vector> -#include <iostream> -#include <deque> -#include <cstdint> +#include "Define.h" #include "CascHandles.h" -#include "CascLib.h" - -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; - -#ifdef _WIN32 -#include <Windows.h> // mainly only HANDLE definition is required -#else -int GetLastError(); -#endif +#include <utility> class CASCFile { - //MPQHANDLE handle; bool eof; char *buffer; size_t pointer,size; @@ -57,13 +53,8 @@ public: inline void flipcc(char *fcc) { - char t; - t=fcc[0]; - fcc[0]=fcc[3]; - fcc[3]=t; - t=fcc[1]; - fcc[1]=fcc[2]; - fcc[2]=t; + std::swap(fcc[0], fcc[3]); + std::swap(fcc[1], fcc[2]); } #endif diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp index 08777315470..73fa7130f24 100644 --- a/src/tools/vmap4_extractor/gameobject_extract.cpp +++ b/src/tools/vmap4_extractor/gameobject_extract.cpp @@ -16,14 +16,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "DB2.h" -#include "model.h" #include "adtfile.h" -#include "vmapexport.h" +#include "DB2CascFileSource.h" +#include "DB2Meta.h" +#include "Errors.h" +#include "model.h" #include "StringFormat.h" - +#include "vmapexport.h" +#include <CascLib.h> #include <algorithm> -#include <stdio.h> +#include <cstdio> bool ExtractSingleModel(std::string& fname) { @@ -55,14 +57,29 @@ bool ExtractSingleModel(std::string& fname) extern CASC::StorageHandle CascStorage; -struct GameObjectDisplayInfoMeta +struct GameobjectDisplayInfoLoadInfo { - static DB2Meta const* Instance() + static DB2FileLoadInfo const* Instance() { + static DB2FieldMeta const fields[] = + { + { false, FT_INT, "ID" }, + { false, FT_INT, "FileDataID" }, + { false, FT_FLOAT, "GeoBoxMinX" }, + { false, FT_FLOAT, "GeoBoxMinY" }, + { false, FT_FLOAT, "GeoBoxMinZ" }, + { false, FT_FLOAT, "GeoBoxMaxX" }, + { false, FT_FLOAT, "GeoBoxMaxY" }, + { false, FT_FLOAT, "GeoBoxMaxZ" }, + { false, FT_FLOAT, "OverrideLootEffectScale" }, + { false, FT_FLOAT, "OverrideNameScale" }, + { false, FT_SHORT, "ObjectEffectPackageID" }, + }; static char const* types = "ifffh"; static uint8 const arraySizes[5] = { 1, 6, 1, 1, 1 }; - static DB2Meta instance(-1, 5, 0xE2D6FAB7, types, arraySizes); - return &instance; + static DB2Meta const meta(-1, 5, 0xE2D6FAB7, types, arraySizes); + static DB2FileLoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, &meta); + return &loadInfo; } }; @@ -89,15 +106,11 @@ bool GetHeaderMagic(std::string const& fileName, uint32* magic) void ExtractGameobjectModels() { - printf("Extracting GameObject models..."); - CASC::FileHandle dbcFile = CASC::OpenFile(CascStorage, "DBFilesClient\\GameObjectDisplayInfo.db2", CASC_LOCALE_NONE, true); - if (!dbcFile) - { - exit(1); - } + printf("Extracting GameObject models...\n"); + DB2CascFileSource source(CascStorage, "DBFilesClient\\GameObjectDisplayInfo.db2"); DB2FileLoader db2; - if (!db2.Load(dbcFile, GameObjectDisplayInfoMeta::Instance())) + if (!db2.Load(&source, GameobjectDisplayInfoLoadInfo::Instance())) { printf("Fatal error: Invalid GameObjectDisplayInfo.db2 file format!\n"); exit(1); @@ -114,9 +127,10 @@ void ExtractGameobjectModels() return; } - for (uint32 rec = 0; rec < db2.GetNumRows(); ++rec) + for (uint32 rec = 0; rec < db2.GetRecordCount(); ++rec) { - uint32 fileId = db2.getRecord(rec).getUInt(0, 0); + DB2Record record = db2.GetRecord(rec); + uint32 fileId = record.GetUInt32(0, 0); if (!fileId) continue; @@ -135,7 +149,7 @@ void ExtractGameobjectModels() if (result) { - uint32 displayId = db2.getId(rec); + uint32 displayId = record.GetId(); uint32 path_length = fileName.length(); fwrite(&displayId, sizeof(uint32), 1, model_list); fwrite(&path_length, sizeof(uint32), 1, model_list); diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 571b8655646..02d0df202de 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -17,14 +17,29 @@ */ #define _CRT_SECURE_NO_DEPRECATE -#include <cstdio> +#define WIN32_LEAN_AND_MEAN + +#include "adtfile.h" +#include "Banner.h" +#include "Common.h" +#include "cascfile.h" +#include "DB2CascFileSource.h" +#include "DB2Meta.h" +#include "StringFormat.h" +#include "vmapexport.h" +#include "wdtfile.h" +#include "wmo.h" +#include <CascLib.h> +#include <boost/filesystem/operations.hpp> +#include <fstream> #include <iostream> -#include <vector> #include <list> -#include <errno.h> +#include <map> +#include <vector> +#include <cstdio> +#include <cerrno> #ifdef WIN32 - #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <sys/stat.h> #include <direct.h> @@ -34,22 +49,6 @@ #define ERROR_PATH_NOT_FOUND ERROR_FILE_NOT_FOUND #endif -#include <map> -#include <fstream> - -#include "Common.h" -//From Extractor -#include "adtfile.h" -#include "wdtfile.h" -#include "DB2.h" -#include "wmo.h" -#include "cascfile.h" - -#include "vmapexport.h" -#include "Banner.h" -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/operations.hpp> - //------------------------------------------------------------------------------ // Defines @@ -66,30 +65,44 @@ typedef struct }map_id; std::vector<map_id> map_ids; -std::vector<uint16> LiqType; uint32 map_count; boost::filesystem::path input_path; bool preciseVectorData = false; -struct LiquidTypeMeta -{ - static DB2Meta const* Instance() - { - static char const* types = "sifffffsifihhbbbbbi"; - static uint8 const arraySizes[19] = { 1, 1, 1, 1, 1, 1, 1, 6, 2, 18, 4, 1, 1, 1, 1, 1, 1, 6, 1 }; - static DB2Meta instance(-1, 19, 0x99FC34E5, types, arraySizes); - return &instance; - } -}; - -struct MapMeta +struct MapLoadInfo { - static DB2Meta const* Instance() + static DB2FileLoadInfo const* Instance() { + static DB2FieldMeta const fields[] = + { + { false, FT_INT, "ID" }, + { false, FT_STRING_NOT_LOCALIZED, "Directory" }, + { false, FT_INT, "Flags1" }, + { false, FT_INT, "Flags2" }, + { false, FT_FLOAT, "MinimapIconScale" }, + { false, FT_FLOAT, "CorpsePosX" }, + { false, FT_FLOAT, "CorpsePosY" }, + { false, FT_STRING, "MapName" }, + { false, FT_STRING, "MapDescription0" }, + { false, FT_STRING, "MapDescription1" }, + { false, FT_SHORT, "AreaTableID" }, + { false, FT_SHORT, "LoadingScreenID" }, + { true, FT_SHORT, "CorpseMapID" }, + { false, FT_SHORT, "TimeOfDayOverride" }, + { true, FT_SHORT, "ParentMapID" }, + { true, FT_SHORT, "CosmeticParentMapID" }, + { false, FT_SHORT, "WindSettingsID" }, + { false, FT_BYTE, "InstanceType" }, + { false, FT_BYTE, "unk5" }, + { false, FT_BYTE, "ExpansionID" }, + { false, FT_BYTE, "MaxPlayers" }, + { false, FT_BYTE, "TimeOffset" }, + }; static char const* types = "siffssshhhhhhhbbbbb"; static uint8 const arraySizes[19] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - static DB2Meta instance(-1, 19, 0xF7CF2DA2, types, arraySizes); - return &instance; + static DB2Meta const meta(-1, 19, 0xF7CF2DA2, types, arraySizes); + static DB2FileLoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, &meta); + return &loadInfo; } }; @@ -129,32 +142,6 @@ uint32 WowLocaleToCascLocaleFlags[12] = CASC_LOCALE_ITIT, }; -namespace -{ - const char* HumanReadableCASCError(int error) - { - switch (error) - { - case ERROR_SUCCESS: return "SUCCESS"; - case ERROR_FILE_CORRUPT: return "FILE_CORRUPT"; - case ERROR_CAN_NOT_COMPLETE: return "CAN_NOT_COMPLETE"; - case ERROR_HANDLE_EOF: return "HANDLE_EOF"; - case ERROR_NO_MORE_FILES: return "NO_MORE_FILES"; - case ERROR_BAD_FORMAT: return "BAD_FORMAT"; - case ERROR_INSUFFICIENT_BUFFER: return "INSUFFICIENT_BUFFER"; - case ERROR_ALREADY_EXISTS: return "ALREADY_EXISTS"; - case ERROR_DISK_FULL: return "DISK_FULL"; - case ERROR_INVALID_PARAMETER: return "INVALID_PARAMETER"; - case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED"; - case ERROR_NOT_ENOUGH_MEMORY: return "NOT_ENOUGH_MEMORY"; - case ERROR_INVALID_HANDLE: return "INVALID_HANDLE"; - case ERROR_ACCESS_DENIED: return "ACCESS_DENIED"; - case ERROR_FILE_NOT_FOUND: return "FILE_NOT_FOUND"; - default: return "UNKNOWN"; - } - } -} - uint32 ReadBuild(int locale) { // include build info file also @@ -241,73 +228,6 @@ void strToLower(char* str) } } -// copied from src\tools\map_extractor\System.cpp -void ReadLiquidTypeTableDBC() -{ - printf("Read LiquidType.dbc file..."); - CASC::FileHandle dbcFile = CASC::OpenFile(CascStorage, "DBFilesClient\\LiquidType.db2", CASC_LOCALE_NONE, true); - if (!dbcFile) - { - exit(1); - } - - DB2FileLoader db2; - if (!db2.Load(dbcFile, LiquidTypeMeta::Instance())) - { - printf("Fatal error: Invalid LiquidType.db2 file format!\n"); - exit(1); - } - - LiqType.resize(db2.GetMaxId() + 1, 0xFFFF); - - for (uint32 x = 0; x < db2.GetNumRows(); ++x) - { - uint32 liquidTypeId; - if (LiquidTypeMeta::Instance()->HasIndexFieldInData()) - liquidTypeId = db2.getRecord(x).getUInt(LiquidTypeMeta::Instance()->GetIndexField(), 0); - else - liquidTypeId = db2.getId(x); - - LiqType[liquidTypeId] = db2.getRecord(x).getUInt8(13, 0); - } - - for (uint32 x = 0; x < db2.GetNumRowCopies(); ++x) - LiqType[db2.GetRowCopy(x).second] = LiqType[db2.GetRowCopy(x).first]; - - printf("Done! (" SZFMTD " LiqTypes loaded)\n", LiqType.size()); -} - -bool ExtractWmo() -{ - bool success = true; - - std::ifstream wmoList("wmo_list.txt"); - if (!wmoList) - { - printf("\nUnable to open wmo_list.txt! Nothing extracted.\n"); - return false; - } - - std::set<std::string> wmos; - for (;;) - { - std::string str; - std::getline(wmoList, str); - if (str.empty()) - break; - - wmos.insert(std::move(str)); - } - - for (std::string str : wmos) - success &= ExtractSingleWmo(str); - - if (success) - printf("\nExtract wmo complete (No (fatal) errors)\n"); - - return success; -} - bool ExtractSingleWmo(std::string& fname) { // Copy files from archive @@ -315,7 +235,8 @@ bool ExtractSingleWmo(std::string& fname) char szLocalFile[1024]; const char * plain_name = GetPlainName(fname.c_str()); sprintf(szLocalFile, "%s/%s", szWorkDirWmo, plain_name); - FixNameCase(szLocalFile,strlen(szLocalFile)); + FixNameCase(szLocalFile, strlen(szLocalFile)); + FixNameSpaces(szLocalFile, strlen(szLocalFile)); if (FileExists(szLocalFile)) return true; @@ -339,7 +260,7 @@ bool ExtractSingleWmo(std::string& fname) return true; bool file_ok = true; - std::cout << "Extracting " << fname << std::endl; + printf("Extracting %s\n", fname.c_str()); WMORoot froot(fname); if(!froot.open()) { @@ -355,25 +276,18 @@ bool ExtractSingleWmo(std::string& fname) froot.ConvertToVMAPRootWmo(output); int Wmo_nVertices = 0; //printf("root has %d groups\n", froot->nGroups); - if (!froot.groupFileDataIDs.empty()) + for (std::size_t i = 0; i < froot.groupFileDataIDs.size(); ++i) { - for (std::size_t i = 0; i < froot.groupFileDataIDs.size(); ++i) + std::string s = Trinity::StringFormat("FILE%08X.xxx", froot.groupFileDataIDs[i]); + WMOGroup fgroup(s); + if(!fgroup.open()) { - char groupFileName[1024]; - sprintf(groupFileName, "FILE%08X", froot.groupFileDataIDs[i]); - //printf("Trying to open groupfile %s\n",groupFileName); - - std::string s = groupFileName; - WMOGroup fgroup(s); - if(!fgroup.open()) - { - printf("Could not open all Group file for: %s\n", plain_name); - file_ok = false; - break; - } - - Wmo_nVertices += fgroup.ConvertToVMAPGroupWmo(output, &froot, preciseVectorData); + printf("Could not open all Group file for: %s\n", plain_name); + file_ok = false; + break; } + + Wmo_nVertices += fgroup.ConvertToVMAPGroupWmo(output, &froot, preciseVectorData); } fseek(output, 8, SEEK_SET); // store the correct no of vertices @@ -544,41 +458,28 @@ int main(int argc, char ** argv) // Extract models, listed in GameObjectDisplayInfo.dbc ExtractGameobjectModels(); - ReadLiquidTypeTableDBC(); - - // extract data - if (success) - success = ExtractWmo(); - //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //map.dbc if (success) { printf("Read Map.dbc file... "); - CASC::FileHandle dbcFile = CASC::OpenFile(CascStorage, "DBFilesClient\\Map.db2", CASC_LOCALE_NONE, true); - if (!dbcFile) - { - exit(1); - } - + DB2CascFileSource source(CascStorage, "DBFilesClient\\Map.db2"); DB2FileLoader db2; - if (!db2.Load(dbcFile, MapMeta::Instance())) + if (!db2.Load(&source, MapLoadInfo::Instance())) { - printf("Fatal error: Invalid Map.db2 file format! %s\n", HumanReadableCASCError(GetLastError())); + printf("Fatal error: Invalid Map.db2 file format! %s\n", CASC::HumanReadableCASCError(GetLastError())); exit(1); } - map_ids.resize(db2.GetNumRows()); + map_ids.resize(db2.GetRecordCount()); std::unordered_map<uint32, uint32> idToIndex; - for (uint32 x = 0; x < db2.GetNumRows(); ++x) + for (uint32 x = 0; x < db2.GetRecordCount(); ++x) { - if (MapMeta::Instance()->HasIndexFieldInData()) - map_ids[x].id = db2.getRecord(x).getUInt(MapMeta::Instance()->GetIndexField(), 0); - else - map_ids[x].id = db2.getId(x); + DB2Record record = db2.GetRecord(x); + map_ids[x].id = record.GetId(); - const char* map_name = db2.getRecord(x).getString(0, 0); + const char* map_name = record.GetString(0, 0); size_t max_map_name_length = sizeof(map_ids[x].name); if (strlen(map_name) >= max_map_name_length) { @@ -591,15 +492,14 @@ int main(int argc, char ** argv) idToIndex[map_ids[x].id] = x; } - for (uint32 x = 0; x < db2.GetNumRowCopies(); ++x) + for (uint32 x = 0; x < db2.GetRecordCopyCount(); ++x) { - uint32 from = db2.GetRowCopy(x).first; - uint32 to = db2.GetRowCopy(x).second; - auto itr = idToIndex.find(from); + DB2RecordCopy copy = db2.GetRecordCopy(x); + auto itr = idToIndex.find(copy.SourceRowId); if (itr != idToIndex.end()) { map_id id; - id.id = to; + id.id = copy.NewRowId; strcpy(id.name, map_ids[itr->second].name); map_ids.push_back(id); } diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index ce2e98886bf..318d16ad3bc 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -80,10 +80,15 @@ bool WDTFile::init(char* /*map_id*/, unsigned int mapID) char *p = buf; while (p < buf + size) { + std::string path(p); + char* s = wdtGetPlainName(p); FixNameCase(s, strlen(s)); + FixNameSpaces(s, strlen(s)); p = p + strlen(p) + 1; gWmoInstansName.push_back(s); + + ExtractSingleWmo(path); } delete[] buf; } diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h index 2a7d7df797c..07fc20bd9a8 100644 --- a/src/tools/vmap4_extractor/wdtfile.h +++ b/src/tools/vmap4_extractor/wdtfile.h @@ -23,7 +23,6 @@ #include "wmo.h" #include <string> #include <vector> -#include <cstdlib> class ADTFile; diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index b538da01d0e..03e32658337 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -29,7 +29,6 @@ #include "cascfile.h" using namespace std; -extern std::vector<uint16> LiqType; WMORoot::WMORoot(std::string &filename) : filename(filename), color(0), nTextures(0), nGroups(0), nPortals(0), nLights(0), diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h index 05bc940042a..adb84e022c5 100644 --- a/src/tools/vmap4_extractor/wmo.h +++ b/src/tools/vmap4_extractor/wmo.h @@ -135,8 +135,6 @@ public: uint32 indx, id, d2, d3; WMOInstance(CASCFile&f , char const* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE* pDirfile); - - static void reset(); }; #endif |
