aboutsummaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2017-03-08 18:10:02 +0100
committerShauren <shauren.trinity@gmail.com>2017-03-08 18:10:02 +0100
commit7b235ce6e4da0e9c19fa9c6306bc7a71c7fb905d (patch)
tree28611e02e44e55d28f60a9b1b3433831ed6772b8 /src/tools
parentf585c831248f24c93697b0c314dd015897febe39 (diff)
Core/DataStores: Refactor DB2 loaders to be reusable by extractors
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/extractor_common/CMakeLists.txt5
-rw-r--r--src/tools/extractor_common/CascHandles.cpp46
-rw-r--r--src/tools/extractor_common/CascHandles.h5
-rw-r--r--src/tools/extractor_common/DB2CascFileSource.cpp46
-rw-r--r--src/tools/extractor_common/DB2CascFileSource.h38
-rw-r--r--src/tools/map_extractor/CMakeLists.txt1
-rw-r--r--src/tools/map_extractor/DB2.cpp200
-rw-r--r--src/tools/map_extractor/DB2.h176
-rw-r--r--src/tools/map_extractor/System.cpp284
-rw-r--r--src/tools/map_extractor/loadlib.cpp12
-rw-r--r--src/tools/map_extractor/loadlib/loadlib.h1
-rw-r--r--src/tools/vmap4_extractor/CMakeLists.txt2
-rw-r--r--src/tools/vmap4_extractor/DB2.cpp200
-rw-r--r--src/tools/vmap4_extractor/DB2.h176
-rw-r--r--src/tools/vmap4_extractor/adtfile.cpp4
-rw-r--r--src/tools/vmap4_extractor/cascfile.cpp46
-rw-r--r--src/tools/vmap4_extractor/cascfile.h51
-rw-r--r--src/tools/vmap4_extractor/gameobject_extract.cpp52
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp246
-rw-r--r--src/tools/vmap4_extractor/wdtfile.cpp5
-rw-r--r--src/tools/vmap4_extractor/wdtfile.h1
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp1
-rw-r--r--src/tools/vmap4_extractor/wmo.h2
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, &copyIdSize, 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, &copyIdSize, 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