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 | |
| parent | f585c831248f24c93697b0c314dd015897febe39 (diff) | |
Core/DataStores: Refactor DB2 loaders to be reusable by extractors
Diffstat (limited to 'src/tools')
23 files changed, 440 insertions, 1160 deletions
diff --git a/src/tools/extractor_common/CMakeLists.txt b/src/tools/extractor_common/CMakeLists.txt index 50cc20c9682..a982ce6ad1b 100644 --- a/src/tools/extractor_common/CMakeLists.txt +++ b/src/tools/extractor_common/CMakeLists.txt @@ -14,7 +14,10 @@ CollectSourceFiles( add_library(extractor_common STATIC ${PRIVATE_SOURCES}) -target_link_libraries(extractor_common boost casc) +target_link_libraries(extractor_common + PUBLIC + casc + common) target_include_directories(extractor_common PUBLIC diff --git a/src/tools/extractor_common/CascHandles.cpp b/src/tools/extractor_common/CascHandles.cpp index 9624a1ca149..46f90d8233f 100644 --- a/src/tools/extractor_common/CascHandles.cpp +++ b/src/tools/extractor_common/CascHandles.cpp @@ -16,32 +16,29 @@ */ #include "CascHandles.h" -#include "CascLib.h" +#include <CascLib.h> #include <boost/filesystem/operations.hpp> -namespace +char const* CASC::HumanReadableCASCError(DWORD error) { - const char* HumanReadableCASCError(int error) + switch (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"; - } + 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"; } } @@ -95,6 +92,11 @@ DWORD CASC::GetFileSize(FileHandle const& file, PDWORD fileSizeHigh) return ::CascGetFileSize(file.get(), fileSizeHigh); } +DWORD CASC::GetFilePointer(FileHandle const& file) +{ + return ::CascSetFilePointer(file.get(), 0, nullptr, FILE_CURRENT); +} + bool CASC::ReadFile(FileHandle const& file, void* buffer, DWORD bytes, PDWORD bytesRead) { return ::CascReadFile(file.get(), buffer, bytes, bytesRead); diff --git a/src/tools/extractor_common/CascHandles.h b/src/tools/extractor_common/CascHandles.h index 455306ad5e0..ebfd04466ab 100644 --- a/src/tools/extractor_common/CascHandles.h +++ b/src/tools/extractor_common/CascHandles.h @@ -18,7 +18,7 @@ #ifndef CascHandles_h__ #define CascHandles_h__ -#include "CascPort.h" +#include <CascPort.h> #include <memory> namespace boost @@ -46,10 +46,13 @@ namespace CASC typedef std::unique_ptr<HANDLE, StorageDeleter> StorageHandle; typedef std::unique_ptr<HANDLE, FileDeleter> FileHandle; + char const* HumanReadableCASCError(DWORD error); + StorageHandle OpenStorage(boost::filesystem::path const& path, DWORD localeMask); FileHandle OpenFile(StorageHandle const& storage, char const* fileName, DWORD localeMask, bool printErrors = false); DWORD GetFileSize(FileHandle const& file, PDWORD fileSizeHigh); + DWORD GetFilePointer(FileHandle const& file); bool ReadFile(FileHandle const& file, void* buffer, DWORD bytes, PDWORD bytesRead); } diff --git a/src/tools/extractor_common/DB2CascFileSource.cpp b/src/tools/extractor_common/DB2CascFileSource.cpp new file mode 100644 index 00000000000..24bf47491dd --- /dev/null +++ b/src/tools/extractor_common/DB2CascFileSource.cpp @@ -0,0 +1,46 @@ +/* + * 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 "DB2CascFileSource.h" +#include <CascLib.h> + +DB2CascFileSource::DB2CascFileSource(CASC::StorageHandle const& storage, std::string fileName) +{ + _fileHandle = CASC::OpenFile(storage, fileName.c_str(), CASC_LOCALE_NONE, true); + _fileName = std::move(fileName); +} + +bool DB2CascFileSource::IsOpen() const +{ + return _fileHandle != nullptr; +} + +bool DB2CascFileSource::Read(void* buffer, std::size_t numBytes) +{ + DWORD bytesRead = 0; + return CASC::ReadFile(_fileHandle, buffer, numBytes, &bytesRead) && numBytes == bytesRead; +} + +std::size_t DB2CascFileSource::GetPosition() const +{ + return CASC::GetFilePointer(_fileHandle); +} + +char const* DB2CascFileSource::GetFileName() const +{ + return _fileName.c_str(); +} diff --git a/src/tools/extractor_common/DB2CascFileSource.h b/src/tools/extractor_common/DB2CascFileSource.h new file mode 100644 index 00000000000..b8876fdcdd1 --- /dev/null +++ b/src/tools/extractor_common/DB2CascFileSource.h @@ -0,0 +1,38 @@ +/* + * 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 DB2CascFileSource_h__ +#define DB2CascFileSource_h__ + +#include "DB2FileLoader.h" +#include "CascHandles.h" +#include <string> + +struct DB2CascFileSource : public DB2FileSource +{ + DB2CascFileSource(CASC::StorageHandle const& storage, std::string fileName); + bool IsOpen() const override; + bool Read(void* buffer, std::size_t numBytes) override; + std::size_t GetPosition() const override; + char const* GetFileName() const override; + +private: + CASC::FileHandle _fileHandle; + std::string _fileName; +}; + +#endif // DB2CascFile_h__ diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt index 3cf7dab9ea0..6347d3bc807 100644 --- a/src/tools/map_extractor/CMakeLists.txt +++ b/src/tools/map_extractor/CMakeLists.txt @@ -28,7 +28,6 @@ target_include_directories(mapextractor target_link_libraries(mapextractor PUBLIC - common extractor_common) CollectIncludeDirectories( diff --git a/src/tools/map_extractor/DB2.cpp b/src/tools/map_extractor/DB2.cpp deleted file mode 100644 index fca95476edb..00000000000 --- a/src/tools/map_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/map_extractor/DB2.h b/src/tools/map_extractor/DB2.h deleted file mode 100644 index f28aeb0e05f..00000000000 --- a/src/tools/map_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/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 4b0dc6fb74f..e1a5d860946 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -17,7 +17,20 @@ */ #define _CRT_SECURE_NO_DEPRECATE +#define WIN32_LEAN_AND_MEAN +#include "Banner.h" +#include "CascHandles.h" +#include "Common.h" +#include "DB2CascFileSource.h" +#include "DB2Meta.h" +#include "DBFilesClientList.h" +#include "StringFormat.h" +#include "adt.h" +#include "wdt.h" +#include <CascLib.h> +#include <boost/filesystem/path.hpp> +#include <boost/filesystem/operations.hpp> #include <cstdio> #include <deque> #include <fstream> @@ -25,46 +38,6 @@ #include <cstdlib> #include <cstring> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/operations.hpp> - -#include "Common.h" -#include "DBFilesClientList.h" -#include "CascLib.h" -#include "CascHandles.h" -#include "DB2.h" -#include "Banner.h" -#include "StringFormat.h" - -#include "adt.h" -#include "wdt.h" - -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"; - } - } -} - CASC::StorageHandle CascStorage; typedef struct @@ -79,36 +52,128 @@ std::set<std::string> CameraFileNames; boost::filesystem::path input_path; boost::filesystem::path output_path; -struct CinematicCameraMeta +struct CinematicCameraLoadInfo { - static DB2Meta const* Instance() + static DB2FileLoadInfo const* Instance() { + static DB2FieldMeta const fields[] = + { + { false, FT_INT, "ID" }, + { false, FT_STRING_NOT_LOCALIZED, "Model" }, + { false, FT_FLOAT, "OriginX" }, + { false, FT_FLOAT, "OriginY" }, + { false, FT_FLOAT, "OriginZ" }, + { false, FT_FLOAT, "OriginFacing" }, + { false, FT_SHORT, "SoundID" }, + }; static char const* types = "sffh"; static uint8 const arraySizes[4] = { 1, 3, 1, 1 }; - static DB2Meta instance(-1, 4, 0xA7B95349, types, arraySizes); - return &instance; + static DB2Meta const meta(-1, 4, 0xA7B95349, types, arraySizes); + static DB2FileLoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, &meta); + return &loadInfo; } }; -struct LiquidTypeMeta +struct LiquidTypeLoadInfo { - static DB2Meta const* Instance() + static DB2FileLoadInfo const* Instance() { + static DB2FieldMeta const fields[] = + { + { false, FT_INT, "ID" }, + { false, FT_STRING, "Name" }, + { false, FT_INT, "SpellID" }, + { false, FT_FLOAT, "MaxDarkenDepth" }, + { false, FT_FLOAT, "FogDarkenIntensity" }, + { false, FT_FLOAT, "AmbDarkenIntensity" }, + { false, FT_FLOAT, "DirDarkenIntensity" }, + { false, FT_FLOAT, "ParticleScale" }, + { false, FT_STRING_NOT_LOCALIZED, "Texture1" }, + { false, FT_STRING_NOT_LOCALIZED, "Texture2" }, + { false, FT_STRING_NOT_LOCALIZED, "Texture3" }, + { false, FT_STRING_NOT_LOCALIZED, "Texture4" }, + { false, FT_STRING_NOT_LOCALIZED, "Texture5" }, + { false, FT_STRING_NOT_LOCALIZED, "Texture6" }, + { false, FT_INT, "Color1" }, + { false, FT_INT, "Color2" }, + { false, FT_FLOAT, "Float1" }, + { false, FT_FLOAT, "Float2" }, + { false, FT_FLOAT, "Float3" }, + { false, FT_FLOAT, "Float4" }, + { false, FT_FLOAT, "Float5" }, + { false, FT_FLOAT, "Float6" }, + { false, FT_FLOAT, "Float7" }, + { false, FT_FLOAT, "Float8" }, + { false, FT_FLOAT, "Float9" }, + { false, FT_FLOAT, "Float10" }, + { false, FT_FLOAT, "Float11" }, + { false, FT_FLOAT, "Float12" }, + { false, FT_FLOAT, "Float13" }, + { false, FT_FLOAT, "Float14" }, + { false, FT_FLOAT, "Float15" }, + { false, FT_FLOAT, "Float16" }, + { false, FT_FLOAT, "Float17" }, + { false, FT_FLOAT, "Float18" }, + { false, FT_INT, "Int1" }, + { false, FT_INT, "Int2" }, + { false, FT_INT, "Int3" }, + { false, FT_INT, "Int4" }, + { false, FT_SHORT, "Flags" }, + { false, FT_SHORT, "LightID" }, + { false, FT_BYTE, "Type" }, + { false, FT_BYTE, "ParticleMovement" }, + { false, FT_BYTE, "ParticleTexSlots" }, + { false, FT_BYTE, "MaterialID" }, + { false, FT_BYTE, "DepthTexCount1" }, + { false, FT_BYTE, "DepthTexCount2" }, + { false, FT_BYTE, "DepthTexCount3" }, + { false, FT_BYTE, "DepthTexCount4" }, + { false, FT_BYTE, "DepthTexCount5" }, + { false, FT_BYTE, "DepthTexCount6" }, + { false, FT_INT, "SoundID" }, + }; 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; + static DB2Meta const meta(-1, 19, 0x99FC34E5, types, arraySizes); + static DB2FileLoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, &meta); + return &loadInfo; } }; -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; } }; @@ -306,29 +371,22 @@ void ReadMapDBC() { printf("Read Map.db2 file...\n"); - 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) { @@ -341,15 +399,14 @@ void ReadMapDBC() 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); } @@ -361,14 +418,10 @@ void ReadMapDBC() void ReadLiquidTypeTableDBC() { printf("Read LiquidType.db2 file...\n"); - CASC::FileHandle dbcFile = CASC::OpenFile(CascStorage, "DBFilesClient\\LiquidType.db2", CASC_LOCALE_NONE, true); - if (!dbcFile) - { - exit(1); - } + DB2CascFileSource source(CascStorage, "DBFilesClient\\LiquidType.db2"); DB2FileLoader db2; - if (!db2.Load(dbcFile, LiquidTypeMeta::Instance())) + if (!db2.Load(&source, LiquidTypeLoadInfo::Instance())) { printf("Fatal error: Invalid LiquidType.db2 file format!\n"); exit(1); @@ -376,19 +429,14 @@ void ReadLiquidTypeTableDBC() LiqType.resize(db2.GetMaxId() + 1, 0xFFFF); - for (uint32 x = 0; x < db2.GetNumRows(); ++x) + for (uint32 x = 0; x < db2.GetRecordCount(); ++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); + DB2Record record = db2.GetRecord(x); + LiqType[record.GetId()] = record.GetUInt8(13, 0); } - for (uint32 x = 0; x < db2.GetNumRowCopies(); ++x) - LiqType[db2.GetRowCopy(x).second] = LiqType[db2.GetRowCopy(x).first]; + for (uint32 x = 0; x < db2.GetRecordCopyCount(); ++x) + LiqType[db2.GetRecordCopy(x).NewRowId] = LiqType[db2.GetRecordCopy(x).SourceRowId]; printf("Done! (" SZFMTD " LiqTypes loaded)\n", LiqType.size()); } @@ -397,24 +445,19 @@ bool ReadCinematicCameraDBC() { printf("Read CinematicCamera.db2 file...\n"); - CASC::FileHandle dbcFile = CASC::OpenFile(CascStorage, "DBFilesClient\\CinematicCamera.db2", CASC_LOCALE_NONE, true); - if (!dbcFile) - { - printf("Unable to open CinematicCamera.db2. Camera extract aborted.\n"); - return false; - } - + DB2CascFileSource source(CascStorage, "DBFilesClient\\CinematicCamera.db2"); DB2FileLoader db2; - if (!db2.Load(dbcFile, CinematicCameraMeta::Instance())) + if (!db2.Load(&source, CinematicCameraLoadInfo::Instance())) { - printf("Invalid CinematicCamera.db2 file format. Camera extract aborted. %s\n", HumanReadableCASCError(GetLastError())); + printf("Invalid CinematicCamera.db2 file format. Camera extract aborted. %s\n", CASC::HumanReadableCASCError(GetLastError())); return false; } // get camera file list from DB2 - for (size_t i = 0; i < db2.GetNumRows(); ++i) + for (size_t i = 0; i < db2.GetRecordCount(); ++i) { - std::string camFile(db2.getRecord(i).getString(0, 0)); + DB2Record record = db2.GetRecord(i); + std::string camFile(record.GetString(0, 0)); size_t loc = camFile.find(".mdx"); if (loc != std::string::npos) camFile.replace(loc, 4, ".m2"); @@ -1089,23 +1132,6 @@ bool ConvertADT(std::string const& inputPath, std::string const& outputPath, int 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) { std::string storagePath; @@ -1119,8 +1145,6 @@ void ExtractMaps(uint32 build) CreateDir(output_path / "maps"); - std::set<std::string> wmoList; - printf("Convert map files\n"); for (std::size_t z = 0; z < map_ids.size(); ++z) { @@ -1131,8 +1155,6 @@ 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) { @@ -1144,11 +1166,6 @@ void ExtractMaps(uint32 build) storagePath = Trinity::StringFormat("World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y); outputFileName = Trinity::StringFormat("%s/maps/%04u_%02u_%02u.map", output_path.string().c_str(), map_ids[z].id, y, x); ConvertADT(storagePath, outputFileName, y, x, build); - - storagePath = Trinity::StringFormat("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 @@ -1156,17 +1173,6 @@ 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"); } @@ -1226,7 +1232,7 @@ void ExtractDBFilesClient(int l) ++count; } else - printf("Unable to open file %s in the archive for locale %s: %s\n", fileName, localeNames[l], HumanReadableCASCError(GetLastError())); + printf("Unable to open file %s in the archive for locale %s: %s\n", fileName, localeNames[l], CASC::HumanReadableCASCError(GetLastError())); fileName = DBFilesClientList[++index]; } @@ -1260,7 +1266,7 @@ void ExtractCameraFiles() ++count; } else - printf("Unable to open file %s in the archive: %s\n", cameraFileName.c_str(), HumanReadableCASCError(GetLastError())); + printf("Unable to open file %s in the archive: %s\n", cameraFileName.c_str(), CASC::HumanReadableCASCError(GetLastError())); } printf("Extracted %u camera files\n", count); @@ -1326,7 +1332,7 @@ void ExtractGameTables() ++count; } else - printf("Unable to open file %s in the archive: %s\n", fileName, HumanReadableCASCError(GetLastError())); + printf("Unable to open file %s in the archive: %s\n", fileName, CASC::HumanReadableCASCError(GetLastError())); fileName = GameTables[++index]; } diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index cb195f6b714..6f21c92ce5e 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -19,6 +19,7 @@ #define _CRT_SECURE_NO_DEPRECATE #include "loadlib.h" +#include <CascLib.h> u_map_fcc MverMagic = { { 'R','E','V','M' } }; @@ -40,9 +41,16 @@ bool ChunkedFile::loadFile(CASC::StorageHandle const& mpq, std::string const& fi if (!file) return false; - data_size = CASC::GetFileSize(file, nullptr); + DWORD fileSize = CASC::GetFileSize(file, nullptr); + if (fileSize == CASC_INVALID_SIZE) + return false; + + data_size = fileSize; data = new uint8[data_size]; - CASC::ReadFile(file, data, data_size, nullptr/*bytesRead*/); + DWORD bytesRead = 0; + if (!CASC::ReadFile(file, data, data_size, &bytesRead) || bytesRead != data_size) + return false; + parseChunks(); if (prepareLoadedData()) return true; diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h index 3267d944955..d6a8b9015c3 100644 --- a/src/tools/map_extractor/loadlib/loadlib.h +++ b/src/tools/map_extractor/loadlib/loadlib.h @@ -21,7 +21,6 @@ #include "Define.h" #include "CascHandles.h" -#include "CascLib.h" #include <map> #include <string> 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 |
