aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared')
-rw-r--r--src/server/shared/DataStores/DBCDatabaseLoader.cpp193
-rw-r--r--src/server/shared/DataStores/DBCDatabaseLoader.h43
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.cpp322
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.h113
-rw-r--r--src/server/shared/DataStores/DBCStorageIterator.h69
-rw-r--r--src/server/shared/DataStores/DBCStore.cpp76
-rw-r--r--src/server/shared/DataStores/DBCStore.h306
-rw-r--r--src/server/shared/Dynamic/FactoryHolder.h2
-rw-r--r--src/server/shared/Dynamic/LinkedList.h12
-rw-r--r--src/server/shared/Dynamic/LinkedReference/Reference.h12
-rw-r--r--src/server/shared/Dynamic/ObjectRegistry.h2
-rw-r--r--src/server/shared/Dynamic/TypeContainer.h143
-rw-r--r--src/server/shared/Dynamic/TypeContainerFunctions.h217
-rw-r--r--src/server/shared/Dynamic/TypeContainerVisitor.h104
-rw-r--r--src/server/shared/Memory.h17
-rw-r--r--src/server/shared/Networking/AsyncAcceptor.h3
-rw-r--r--src/server/shared/Packets/ByteBuffer.cpp76
-rw-r--r--src/server/shared/Packets/ByteBuffer.h167
-rw-r--r--src/server/shared/PrecompiledHeaders/sharedPCH.cpp17
-rw-r--r--src/server/shared/PrecompiledHeaders/sharedPCH.h28
-rw-r--r--src/server/shared/Realm/Realm.cpp19
-rw-r--r--src/server/shared/Realm/Realm.h11
-rw-r--r--src/server/shared/Realm/RealmList.cpp35
-rw-r--r--src/server/shared/Realm/RealmList.h33
24 files changed, 650 insertions, 1370 deletions
diff --git a/src/server/shared/DataStores/DBCDatabaseLoader.cpp b/src/server/shared/DataStores/DBCDatabaseLoader.cpp
new file mode 100644
index 00000000000..3ef3e8f64c0
--- /dev/null
+++ b/src/server/shared/DataStores/DBCDatabaseLoader.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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 "DBCDatabaseLoader.h"
+#include "Common.h"
+#include "DatabaseEnv.h"
+#include "Errors.h"
+#include "Log.h"
+#include <sstream>
+
+DBCDatabaseLoader::DBCDatabaseLoader(std::string const& storageName, std::string const& dbFormatString, std::string const& primaryKey, char const* dbcFormatString)
+ : _formatString(dbFormatString), _indexName(primaryKey), _sqlTableName(storageName), _dbcFormat(dbcFormatString), _sqlIndexPos(0), _recordSize(0)
+{
+ // Convert dbc file name to sql table name
+ std::transform(_sqlTableName.begin(), _sqlTableName.end(), _sqlTableName.begin(), ::tolower);
+ for (char& c : _sqlTableName)
+ if (c == '.')
+ c = '_';
+
+ // Get sql index position
+ int32 indexPos = -1;
+ _recordSize = DBCFileLoader::GetFormatRecordSize(_dbcFormat, &indexPos);
+ ASSERT(indexPos >= 0);
+ ASSERT(_recordSize);
+
+ uint32 uindexPos = uint32(indexPos);
+ for (uint32 x = 0; x < _formatString.size(); ++x)
+ {
+ // Count only fields present in sql
+ if (_formatString[x] == FT_SQL_PRESENT)
+ {
+ if (x == uindexPos)
+ break;
+ ++_sqlIndexPos;
+ }
+ }
+}
+
+static char const* nullStr = "";
+
+char* DBCDatabaseLoader::Load(uint32& records, char**& indexTable)
+{
+ std::ostringstream queryBuilder;
+ queryBuilder << "SELECT * FROM " << _sqlTableName
+ << " ORDER BY " << _indexName << " DESC;";
+
+ // no error if empty set
+ QueryResult result = WorldDatabase.Query(queryBuilder.str().c_str());
+ if (!result)
+ return nullptr;
+
+ // Check if sql index pos is valid
+ if (int32(result->GetFieldCount() - 1) < _sqlIndexPos)
+ {
+ ASSERT(false, "Invalid index pos for dbc:'%s'", _sqlTableName.c_str());
+ return nullptr;
+ }
+
+ // Resize index table
+ // database query *MUST* contain ORDER BY `index_field` DESC clause
+ uint32 indexTableSize = std::max(records, (*result)[_sqlIndexPos].GetUInt32() + 1);
+ if (indexTableSize > records)
+ {
+ char** tmpIdxTable = new char*[indexTableSize];
+ memset(tmpIdxTable, 0, indexTableSize * sizeof(char*));
+ memcpy(tmpIdxTable, indexTable, records * sizeof(char*));
+ delete[] indexTable;
+ indexTable = tmpIdxTable;
+ }
+
+ std::unique_ptr<char[]> dataTable = Trinity::make_unique<char[]>(result->GetRowCount() * _recordSize);
+ std::unique_ptr<uint32[]> newIndexes = Trinity::make_unique<uint32[]>(result->GetRowCount());
+ uint32 newRecords = 0;
+
+ // Insert sql data into the data array
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 offset = 0;
+
+ uint32 indexValue = fields[_sqlIndexPos].GetUInt32();
+
+ char* dataValue = indexTable[indexValue];
+ if (!dataValue)
+ {
+ newIndexes[newRecords] = indexValue;
+ dataValue = &dataTable[newRecords++ * _recordSize];
+ }
+ else
+ {
+ // Attempt to overwrite existing data
+ ASSERT(false, "Index %d already exists in dbc:'%s'", indexValue, _sqlTableName.c_str());
+ return nullptr;
+ }
+
+ uint32 columnNumber = 0;
+ uint32 sqlColumnNumber = 0;
+
+ for (; columnNumber < _formatString.size(); ++columnNumber)
+ {
+ if (_formatString[columnNumber] == FT_SQL_ABSENT)
+ {
+ switch (_dbcFormat[columnNumber])
+ {
+ case FT_FLOAT:
+ *reinterpret_cast<float*>(&dataValue[offset]) = 0.0f;
+ offset += 4;
+ break;
+ case FT_IND:
+ case FT_INT:
+ *reinterpret_cast<uint32*>(&dataValue[offset]) = uint32(0);
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *reinterpret_cast<uint8*>(&dataValue[offset]) = uint8(0);
+ offset += 1;
+ break;
+ case FT_STRING:
+ *reinterpret_cast<char**>(&dataValue[offset]) = const_cast<char*>(nullStr);
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ else if (_formatString[columnNumber] == FT_SQL_PRESENT)
+ {
+ bool validSqlColumn = true;
+ switch (_dbcFormat[columnNumber])
+ {
+ case FT_FLOAT:
+ *reinterpret_cast<float*>(&dataValue[offset]) = fields[sqlColumnNumber].GetFloat();
+ offset += 4;
+ break;
+ case FT_IND:
+ case FT_INT:
+ *reinterpret_cast<uint32*>(&dataValue[offset]) = fields[sqlColumnNumber].GetUInt32();
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *reinterpret_cast<uint8*>(&dataValue[offset]) = fields[sqlColumnNumber].GetUInt8();
+ offset += 1;
+ break;
+ case FT_STRING:
+ ASSERT(false, "Unsupported data type in table '%s' at char %d", _sqlTableName.c_str(), columnNumber);
+ return nullptr;
+ case FT_SORT:
+ break;
+ default:
+ validSqlColumn = false;
+ break;
+ }
+ if (validSqlColumn && (columnNumber != (_formatString.size() - 1)))
+ sqlColumnNumber++;
+ }
+ else
+ {
+ ASSERT(false, "Incorrect sql format string '%s' at char %d", _sqlTableName.c_str(), columnNumber);
+ break;
+ }
+ }
+
+ if (sqlColumnNumber != (result->GetFieldCount() - 1))
+ {
+ ASSERT(false, "SQL and DBC format strings are not matching for table: '%s'", _sqlTableName.c_str());
+ return nullptr;
+ }
+
+ ASSERT(offset == _recordSize);
+ } while (result->NextRow());
+
+ ASSERT(newRecords == result->GetRowCount());
+
+ // insert new records to index table
+ for (uint32 i = 0; i < newRecords; ++i)
+ indexTable[newIndexes[i]] = &dataTable[i * _recordSize];
+
+ records = indexTableSize;
+
+ return dataTable.release();
+}
diff --git a/src/server/shared/DataStores/DBCDatabaseLoader.h b/src/server/shared/DataStores/DBCDatabaseLoader.h
new file mode 100644
index 00000000000..153a0eb4dcb
--- /dev/null
+++ b/src/server/shared/DataStores/DBCDatabaseLoader.h
@@ -0,0 +1,43 @@
+/*
+ * 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 DBCDatabaseLoader_h__
+#define DBCDatabaseLoader_h__
+
+#include "DBCFileLoader.h"
+#include <string>
+#include <vector>
+
+struct TC_SHARED_API DBCDatabaseLoader
+{
+ DBCDatabaseLoader(std::string const& storageName, std::string const& dbFormatString, std::string const& primaryKey, char const* dbcFormatString);
+
+ char* Load(uint32& records, char**& indexTable);
+
+private:
+ std::string const& _formatString;
+ std::string const& _indexName;
+ std::string _sqlTableName;
+ char const* _dbcFormat;
+ int32 _sqlIndexPos;
+ uint32 _recordSize;
+
+ DBCDatabaseLoader(DBCDatabaseLoader const& right) = delete;
+ DBCDatabaseLoader& operator=(DBCDatabaseLoader const& right) = delete;
+};
+
+#endif // DBCDatabaseLoader_h__
diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/server/shared/DataStores/DBCFileLoader.cpp
deleted file mode 100644
index 8c92260e62d..00000000000
--- a/src/server/shared/DataStores/DBCFileLoader.cpp
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "DBCFileLoader.h"
-#include "Errors.h"
-
-DBCFileLoader::DBCFileLoader() : recordSize(0), recordCount(0), fieldCount(0), stringSize(0), fieldsOffset(NULL), data(NULL), stringTable(NULL) { }
-
-bool DBCFileLoader::Load(const char* filename, const char* fmt)
-{
- uint32 header;
- if (data)
- {
- delete [] data;
- data = NULL;
- }
-
- FILE* f = fopen(filename, "rb");
- if (!f)
- return false;
-
- if (fread(&header, 4, 1, f) != 1) // Number of records
- {
- fclose(f);
- return false;
- }
-
-
- EndianConvert(header);
-
- if (header != 0x43424457) //'WDBC'
- {
- fclose(f);
- return false;
- }
-
- if (fread(&recordCount, 4, 1, f) != 1) // Number of records
- {
- fclose(f);
- return false;
- }
-
- EndianConvert(recordCount);
-
- if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
- {
- fclose(f);
- return false;
- }
-
- EndianConvert(fieldCount);
-
- if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
- {
- fclose(f);
- return false;
- }
-
- EndianConvert(recordSize);
-
- if (fread(&stringSize, 4, 1, f) != 1) // String size
- {
- fclose(f);
- return false;
- }
-
- EndianConvert(stringSize);
-
- fieldsOffset = new uint32[fieldCount];
- fieldsOffset[0] = 0;
- for (uint32 i = 1; i < fieldCount; ++i)
- {
- fieldsOffset[i] = fieldsOffset[i - 1];
- if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X') // byte fields
- fieldsOffset[i] += sizeof(uint8);
- else // 4 byte fields (int32/float/strings)
- fieldsOffset[i] += sizeof(uint32);
- }
-
- data = new unsigned char[recordSize * recordCount + stringSize];
- stringTable = data + recordSize*recordCount;
-
- if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
- {
- fclose(f);
- return false;
- }
-
- fclose(f);
-
- return true;
-}
-
-DBCFileLoader::~DBCFileLoader()
-{
- delete[] data;
-
- delete[] fieldsOffset;
-}
-
-DBCFileLoader::Record DBCFileLoader::getRecord(size_t id)
-{
- assert(data);
- return Record(*this, data + id * recordSize);
-}
-
-uint32 DBCFileLoader::GetFormatRecordSize(const char* format, int32* index_pos)
-{
- uint32 recordsize = 0;
- int32 i = -1;
- for (uint32 x = 0; format[x]; ++x)
- {
- switch (format[x])
- {
- case FT_FLOAT:
- recordsize += sizeof(float);
- break;
- case FT_INT:
- recordsize += sizeof(uint32);
- break;
- case FT_STRING:
- recordsize += sizeof(char*);
- break;
- case FT_SORT:
- i = x;
- break;
- case FT_IND:
- i = x;
- recordsize += sizeof(uint32);
- break;
- case FT_BYTE:
- recordsize += sizeof(uint8);
- break;
- case FT_NA:
- case FT_NA_BYTE:
- break;
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
- default:
- ASSERT(false && "Unknown field format character in DBCfmt.h");
- break;
- }
- }
-
- if (index_pos)
- *index_pos = i;
-
- return recordsize;
-}
-
-char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char*& sqlDataTable)
-{
- /*
- format STRING, NA, FLOAT, NA, INT <=>
- struct{
- char* field0,
- float field1,
- int field2
- }entry;
-
- this func will generate entry[rows] data;
- */
-
- typedef char* ptr;
- if (strlen(format) != fieldCount)
- return NULL;
-
- //get struct size and index pos
- int32 i;
- uint32 recordsize = GetFormatRecordSize(format, &i);
-
- if (i >= 0)
- {
- uint32 maxi = 0;
- //find max index
- for (uint32 y = 0; y < recordCount; ++y)
- {
- uint32 ind = getRecord(y).getUInt(i);
- if (ind > maxi)
- maxi = ind;
- }
-
- // If higher index avalible from sql - use it instead of dbcs
- if (sqlHighestIndex > maxi)
- maxi = sqlHighestIndex;
-
- ++maxi;
- records = maxi;
- indexTable = new ptr[maxi];
- memset(indexTable, 0, maxi * sizeof(ptr));
- }
- else
- {
- records = recordCount + sqlRecordCount;
- indexTable = new ptr[recordCount + sqlRecordCount];
- }
-
- char* dataTable = new char[(recordCount + sqlRecordCount) * recordsize];
-
- uint32 offset = 0;
-
- for (uint32 y = 0; y < recordCount; ++y)
- {
- if (i >= 0)
- indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
- else
- indexTable[y] = &dataTable[offset];
-
- for (uint32 x=0; x < fieldCount; ++x)
- {
- switch (format[x])
- {
- case FT_FLOAT:
- *((float*)(&dataTable[offset])) = getRecord(y).getFloat(x);
- offset += sizeof(float);
- break;
- case FT_IND:
- case FT_INT:
- *((uint32*)(&dataTable[offset])) = getRecord(y).getUInt(x);
- offset += sizeof(uint32);
- break;
- case FT_BYTE:
- *((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x);
- offset += sizeof(uint8);
- break;
- case FT_STRING:
- *((char**)(&dataTable[offset])) = NULL; // will replace non-empty or "" strings in AutoProduceStrings
- offset += sizeof(char*);
- break;
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
- case FT_NA:
- case FT_NA_BYTE:
- case FT_SORT:
- break;
- default:
- ASSERT(false && "Unknown field format character in DBCfmt.h");
- break;
- }
- }
- }
-
- sqlDataTable = dataTable + offset;
-
- return dataTable;
-}
-
-char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable)
-{
- if (strlen(format) != fieldCount)
- return NULL;
-
- char* stringPool = new char[stringSize];
- memcpy(stringPool, stringTable, stringSize);
-
- uint32 offset = 0;
-
- for (uint32 y = 0; y < recordCount; ++y)
- {
- for (uint32 x = 0; x < fieldCount; ++x)
- {
- switch (format[x])
- {
- case FT_FLOAT:
- offset += sizeof(float);
- break;
- case FT_IND:
- case FT_INT:
- offset += sizeof(uint32);
- break;
- case FT_BYTE:
- offset += sizeof(uint8);
- break;
- case FT_STRING:
- {
- // fill only not filled entries
- char** slot = (char**)(&dataTable[offset]);
- if (!*slot || !**slot)
- {
- const char * st = getRecord(y).getString(x);
- *slot=stringPool+(st-(const char*)stringTable);
- }
- offset += sizeof(char*);
- break;
- }
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that does not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
- case FT_NA:
- case FT_NA_BYTE:
- case FT_SORT:
- break;
- default:
- ASSERT(false && "Unknown field format character in DBCfmt.h");
- break;
- }
- }
- }
-
- return stringPool;
-}
diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h
deleted file mode 100644
index 1c005a9e670..00000000000
--- a/src/server/shared/DataStores/DBCFileLoader.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * 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 DBC_FILE_LOADER_H
-#define DBC_FILE_LOADER_H
-#include "Define.h"
-#include "Utilities/ByteConverter.h"
-#include <cassert>
-
-enum DbcFieldFormat
-{
- FT_NA='x', //not used or unknown, 4 byte size
- FT_NA_BYTE='X', //not used or unknown, byte
- FT_STRING='s', //char*
- FT_FLOAT='f', //float
- FT_INT='i', //uint32
- FT_BYTE='b', //uint8
- FT_SORT='d', //sorted by this field, field is not included
- FT_IND='n', //the same, but parsed to data
- FT_LOGIC='l', //Logical (boolean)
- FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc
- FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc
-};
-
-class TC_SHARED_API DBCFileLoader
-{
- public:
- DBCFileLoader();
- ~DBCFileLoader();
-
- bool Load(const char *filename, const char *fmt);
-
- class Record
- {
- public:
- float getFloat(size_t field) const
- {
- assert(field < file.fieldCount);
- float val = *reinterpret_cast<float*>(offset+file.GetOffset(field));
- EndianConvert(val);
- return val;
- }
- uint32 getUInt(size_t field) const
- {
- assert(field < file.fieldCount);
- uint32 val = *reinterpret_cast<uint32*>(offset+file.GetOffset(field));
- EndianConvert(val);
- return val;
- }
- uint8 getUInt8(size_t field) const
- {
- assert(field < file.fieldCount);
- return *reinterpret_cast<uint8*>(offset+file.GetOffset(field));
- }
-
- const char *getString(size_t field) const
- {
- assert(field < file.fieldCount);
- size_t stringOffset = getUInt(field);
- assert(stringOffset < file.stringSize);
- return reinterpret_cast<char*>(file.stringTable + stringOffset);
- }
-
- private:
- Record(DBCFileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) { }
- unsigned char *offset;
- DBCFileLoader &file;
-
- friend class DBCFileLoader;
-
- };
-
- // Get record by id
- Record getRecord(size_t id);
- /// Get begin iterator over records
-
- uint32 GetNumRows() const { return recordCount; }
- uint32 GetRowSize() const { return recordSize; }
- uint32 GetCols() const { return fieldCount; }
- uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; }
- bool IsLoaded() const { return data != NULL; }
- char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *& sqlDataTable);
- char* AutoProduceStrings(const char* fmt, char* dataTable);
- static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL);
- private:
-
- uint32 recordSize;
- uint32 recordCount;
- uint32 fieldCount;
- uint32 stringSize;
- uint32 *fieldsOffset;
- unsigned char *data;
- unsigned char *stringTable;
-
- DBCFileLoader(DBCFileLoader const& right) = delete;
- DBCFileLoader& operator=(DBCFileLoader const& right) = delete;
-};
-#endif
diff --git a/src/server/shared/DataStores/DBCStorageIterator.h b/src/server/shared/DataStores/DBCStorageIterator.h
new file mode 100644
index 00000000000..be1e58db967
--- /dev/null
+++ b/src/server/shared/DataStores/DBCStorageIterator.h
@@ -0,0 +1,69 @@
+/*
+ * 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 DBCStorageIterator_h__
+#define DBCStorageIterator_h__
+
+#include "Define.h"
+#include <iterator>
+
+template <class T>
+class DBCStorageIterator : public std::iterator<std::forward_iterator_tag, T>
+{
+ public:
+ DBCStorageIterator() : _index(nullptr), _pos(0), _end(0) { }
+ DBCStorageIterator(T** index, uint32 size, uint32 pos = 0) : _index(index), _pos(pos), _end(size)
+ {
+ if (_pos < _end)
+ {
+ while (_pos < _end && !_index[_pos])
+ ++_pos;
+ }
+ }
+
+ T const* operator->() { return _index[_pos]; }
+ T const* operator*() { return _index[_pos]; }
+
+ bool operator==(DBCStorageIterator const& right) const { /*ASSERT(_index == right._index, "Iterator belongs to a different container")*/ return _pos == right._pos; }
+ bool operator!=(DBCStorageIterator const& right) const { return !(*this == right); }
+
+ DBCStorageIterator& operator++()
+ {
+ if (_pos < _end)
+ {
+ do
+ ++_pos;
+ while (_pos < _end && !_index[_pos]);
+ }
+
+ return *this;
+ }
+
+ DBCStorageIterator operator++(int)
+ {
+ DBCStorageIterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ private:
+ T** _index;
+ uint32 _pos;
+ uint32 _end;
+};
+
+#endif // DBCStorageIterator_h__
diff --git a/src/server/shared/DataStores/DBCStore.cpp b/src/server/shared/DataStores/DBCStore.cpp
new file mode 100644
index 00000000000..30cae057f90
--- /dev/null
+++ b/src/server/shared/DataStores/DBCStore.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 "DBCStore.h"
+#include "DBCDatabaseLoader.h"
+
+DBCStorageBase::DBCStorageBase(char const* fmt) : _fieldCount(0), _fileFormat(fmt), _dataTable(nullptr), _indexTableSize(0)
+{
+}
+
+DBCStorageBase::~DBCStorageBase()
+{
+ delete[] _dataTable;
+ delete[] _dataTableEx;
+ for (char* strings : _stringPool)
+ delete[] strings;
+}
+
+bool DBCStorageBase::Load(std::string const& path, char**& indexTable)
+{
+ indexTable = nullptr;
+
+ DBCFileLoader dbc;
+ // Check if load was sucessful, only then continue
+ if (!dbc.Load(path.c_str(), _fileFormat))
+ return false;
+
+ _fieldCount = dbc.GetCols();
+
+ // load raw non-string data
+ _dataTable = dbc.AutoProduceData(_fileFormat, _indexTableSize, indexTable);
+
+ // load strings from dbc data
+ if (char* stringBlock = dbc.AutoProduceStrings(_fileFormat, _dataTable))
+ _stringPool.push_back(stringBlock);
+
+ // error in dbc file at loading if NULL
+ return indexTable != nullptr;
+}
+
+bool DBCStorageBase::LoadStringsFrom(std::string const& path, char** indexTable)
+{
+ // DBC must be already loaded using Load
+ if (!indexTable)
+ return false;
+
+ DBCFileLoader dbc;
+ // Check if load was successful, only then continue
+ if (!dbc.Load(path.c_str(), _fileFormat))
+ return false;
+
+ // load strings from another locale dbc data
+ if (char* stringBlock = dbc.AutoProduceStrings(_fileFormat, _dataTable))
+ _stringPool.push_back(stringBlock);
+
+ return true;
+}
+
+void DBCStorageBase::LoadFromDB(std::string const& path, std::string const& dbFormat, std::string const& primaryKey, char**& indexTable)
+{
+ _dataTableEx = DBCDatabaseLoader(path, dbFormat, primaryKey, _fileFormat).Load(_indexTableSize, indexTable);
+}
diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h
index b11bb0b74d4..e04f434cf89 100644
--- a/src/server/shared/DataStores/DBCStore.h
+++ b/src/server/shared/DataStores/DBCStore.h
@@ -19,289 +19,83 @@
#ifndef DBCSTORE_H
#define DBCSTORE_H
-#include "DBCFileLoader.h"
-#include "Logging/Log.h"
-#include "Field.h"
-#include "DatabaseWorkerPool.h"
-#include "Implementation/WorldDatabase.h"
-#include "DatabaseEnv.h"
+#include "Common.h"
+#include "DBCStorageIterator.h"
+#include <vector>
-struct SqlDbc
+ /// Interface class for common access
+class TC_SHARED_API DBCStorageBase
{
- std::string const* formatString;
- std::string const* indexName;
- std::string sqlTableName;
- int32 indexPos;
- int32 sqlIndexPos;
- SqlDbc(std::string const* _filename, std::string const* _format, std::string const* _idname, char const* fmt)
- : formatString(_format), indexName (_idname), sqlIndexPos(0)
- {
- // Convert dbc file name to sql table name
- sqlTableName = *_filename;
- for (uint32 i = 0; i< sqlTableName.size(); ++i)
- {
- if (isalpha(sqlTableName[i]))
- sqlTableName[i] = char(tolower(sqlTableName[i]));
- else if (sqlTableName[i] == '.')
- sqlTableName[i] = '_';
- }
-
- // Get sql index position
- DBCFileLoader::GetFormatRecordSize(fmt, &indexPos);
- if (indexPos >= 0)
- {
- uint32 uindexPos = uint32(indexPos);
- for (uint32 x = 0; x < formatString->size(); ++x)
- {
- // Count only fields present in sql
- if ((*formatString)[x] == FT_SQL_PRESENT)
- {
- if (x == uindexPos)
- break;
- ++sqlIndexPos;
- }
- }
- }
- }
-
-private:
- SqlDbc(SqlDbc const& right) = delete;
- SqlDbc& operator=(SqlDbc const& right) = delete;
+ public:
+ DBCStorageBase(char const* fmt);
+ virtual ~DBCStorageBase();
+
+ char const* GetFormat() const { return _fileFormat; }
+ uint32 GetFieldCount() const { return _fieldCount; }
+
+ virtual bool Load(std::string const& path) = 0;
+ virtual bool LoadStringsFrom(std::string const& path) = 0;
+ virtual void LoadFromDB(std::string const& path, std::string const& dbFormat, std::string const& primaryKey) = 0;
+
+ protected:
+ bool Load(std::string const& path, char**& indexTable);
+ bool LoadStringsFrom(std::string const& path, char** indexTable);
+ void LoadFromDB(std::string const& path, std::string const& dbFormat, std::string const& primaryKey, char**& indexTable);
+
+ uint32 _fieldCount;
+ char const* _fileFormat;
+ char* _dataTable;
+ char* _dataTableEx;
+ std::vector<char*> _stringPool;
+ uint32 _indexTableSize;
};
-template<class T>
-class DBCStorage
+template <class T>
+class DBCStorage : public DBCStorageBase
{
- typedef std::list<char*> StringPoolList;
public:
- explicit DBCStorage(char const* f)
- : fmt(f), nCount(0), fieldCount(0), dataTable(NULL)
- {
- indexTable.asT = NULL;
- }
+ typedef DBCStorageIterator<T> iterator;
- ~DBCStorage() { Clear(); }
-
- T const* LookupEntry(uint32 id) const
+ explicit DBCStorage(char const* fmt) : DBCStorageBase(fmt)
{
- return (id >= nCount) ? NULL : indexTable.asT[id];
+ _indexTable.AsT = nullptr;
}
- T const* AssertEntry(uint32 id) const
+ ~DBCStorage()
{
- T const* entry = LookupEntry(id);
- ASSERT(entry);
- return entry;
+ delete[] reinterpret_cast<char*>(_indexTable.AsT);
}
- uint32 GetNumRows() const { return nCount; }
- char const* GetFormat() const { return fmt; }
- uint32 GetFieldCount() const { return fieldCount; }
-
- bool Load(char const* fn, SqlDbc* sql)
- {
- DBCFileLoader dbc;
- // Check if load was sucessful, only then continue
- if (!dbc.Load(fn, fmt))
- return false;
-
- uint32 sqlRecordCount = 0;
- uint32 sqlHighestIndex = 0;
- Field* fields = NULL;
- QueryResult result = QueryResult(NULL);
- // Load data from sql
- if (sql)
- {
- std::string query = "SELECT * FROM " + sql->sqlTableName;
- if (sql->indexPos >= 0)
- query +=" ORDER BY " + *sql->indexName + " DESC";
- query += ';';
-
-
- result = WorldDatabase.Query(query.c_str());
- if (result)
- {
- sqlRecordCount = uint32(result->GetRowCount());
- if (sql->indexPos >= 0)
- {
- fields = result->Fetch();
- sqlHighestIndex = fields[sql->sqlIndexPos].GetUInt32();
- }
-
- // Check if sql index pos is valid
- if (int32(result->GetFieldCount() - 1) < sql->sqlIndexPos)
- {
- TC_LOG_ERROR("server.loading", "Invalid index pos for dbc:'%s'", sql->sqlTableName.c_str());
- return false;
- }
- }
- }
-
- char* sqlDataTable = NULL;
- fieldCount = dbc.GetCols();
-
- dataTable = reinterpret_cast<T*>(dbc.AutoProduceData(fmt, nCount, indexTable.asChar,
- sqlRecordCount, sqlHighestIndex, sqlDataTable));
+ T const* LookupEntry(uint32 id) const { return (id >= _indexTableSize) ? nullptr : _indexTable.AsT[id]; }
+ T const* AssertEntry(uint32 id) const { return ASSERT_NOTNULL(LookupEntry(id)); }
- stringPoolList.push_back(dbc.AutoProduceStrings(fmt, reinterpret_cast<char*>(dataTable)));
+ uint32 GetNumRows() const { return _indexTableSize; }
- // Insert sql data into arrays
- if (result)
- {
- if (indexTable.asT)
- {
- uint32 offset = 0;
- uint32 rowIndex = dbc.GetNumRows();
- do
- {
- if (!fields)
- fields = result->Fetch();
-
- if (sql->indexPos >= 0)
- {
- uint32 id = fields[sql->sqlIndexPos].GetUInt32();
- if (indexTable.asT[id])
- {
- TC_LOG_ERROR("server.loading", "Index %d already exists in dbc:'%s'", id, sql->sqlTableName.c_str());
- return false;
- }
-
- indexTable.asT[id] = reinterpret_cast<T*>(&sqlDataTable[offset]);
- }
- else
- indexTable.asT[rowIndex]= reinterpret_cast<T*>(&sqlDataTable[offset]);
-
- uint32 columnNumber = 0;
- uint32 sqlColumnNumber = 0;
-
- for (; columnNumber < sql->formatString->size(); ++columnNumber)
- {
- if ((*sql->formatString)[columnNumber] == FT_SQL_ABSENT)
- {
- switch (fmt[columnNumber])
- {
- case FT_FLOAT:
- *reinterpret_cast<float*>(&sqlDataTable[offset]) = 0.0f;
- offset += 4;
- break;
- case FT_IND:
- case FT_INT:
- *reinterpret_cast<uint32*>(&sqlDataTable[offset]) = uint32(0);
- offset += 4;
- break;
- case FT_BYTE:
- *reinterpret_cast<uint8*>(&sqlDataTable[offset]) = uint8(0);
- offset += 1;
- break;
- case FT_STRING:
- // Beginning of the pool - empty string
- *reinterpret_cast<char**>(&sqlDataTable[offset]) = stringPoolList.back();
- offset += sizeof(char*);
- break;
- }
- }
- else if ((*sql->formatString)[columnNumber] == FT_SQL_PRESENT)
- {
- bool validSqlColumn = true;
- switch (fmt[columnNumber])
- {
- case FT_FLOAT:
- *reinterpret_cast<float*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetFloat();
- offset += 4;
- break;
- case FT_IND:
- case FT_INT:
- *reinterpret_cast<uint32*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetUInt32();
- offset += 4;
- break;
- case FT_BYTE:
- *reinterpret_cast<uint8*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetUInt8();
- offset += 1;
- break;
- case FT_STRING:
- TC_LOG_ERROR("server.loading", "Unsupported data type in table '%s' at char %d", sql->sqlTableName.c_str(), columnNumber);
- return false;
- case FT_SORT:
- break;
- default:
- validSqlColumn = false;
- break;
- }
- if (validSqlColumn && (columnNumber != (sql->formatString->size()-1)))
- sqlColumnNumber++;
- }
- else
- {
- TC_LOG_ERROR("server.loading", "Incorrect sql format string '%s' at char %d", sql->sqlTableName.c_str(), columnNumber);
- return false;
- }
- }
-
- if (sqlColumnNumber != (result->GetFieldCount() - 1))
- {
- TC_LOG_ERROR("server.loading", "SQL and DBC format strings are not matching for table: '%s'", sql->sqlTableName.c_str());
- return false;
- }
-
- fields = NULL;
- ++rowIndex;
- } while (result->NextRow());
- }
- }
-
- // error in dbc file at loading if NULL
- return indexTable.asT != NULL;
+ bool Load(std::string const& path) override
+ {
+ return DBCStorageBase::Load(path, _indexTable.AsChar);
}
- bool LoadStringsFrom(char const* fn)
+ bool LoadStringsFrom(std::string const& path) override
{
- // DBC must be already loaded using Load
- if (!indexTable.asT)
- return false;
-
- DBCFileLoader dbc;
- // Check if load was successful, only then continue
- if (!dbc.Load(fn, fmt))
- return false;
-
- stringPoolList.push_back(dbc.AutoProduceStrings(fmt, reinterpret_cast<char*>(dataTable)));
-
- return true;
+ return DBCStorageBase::LoadStringsFrom(path, _indexTable.AsChar);
}
- void Clear()
+ void LoadFromDB(std::string const& path, std::string const& dbFormat, std::string const& primaryKey) override
{
- if (!indexTable.asT)
- return;
-
- delete[] reinterpret_cast<char*>(indexTable.asT);
- indexTable.asT = NULL;
- delete[] reinterpret_cast<char*>(dataTable);
- dataTable = NULL;
-
- while (!stringPoolList.empty())
- {
- delete[] stringPoolList.front();
- stringPoolList.pop_front();
- }
-
- nCount = 0;
+ DBCStorageBase::LoadFromDB(path, dbFormat, primaryKey, _indexTable.AsChar);
}
- private:
- char const* fmt;
- uint32 nCount;
- uint32 fieldCount;
+ iterator begin() { return iterator(_indexTable.AsT, _indexTableSize); }
+ iterator end() { return iterator(_indexTable.AsT, _indexTableSize, _indexTableSize); }
+ private:
union
{
- T** asT;
- char** asChar;
+ T** AsT;
+ char** AsChar;
}
- indexTable;
-
- T* dataTable;
- StringPoolList stringPoolList;
+ _indexTable;
DBCStorage(DBCStorage const& right) = delete;
DBCStorage& operator=(DBCStorage const& right) = delete;
diff --git a/src/server/shared/Dynamic/FactoryHolder.h b/src/server/shared/Dynamic/FactoryHolder.h
index 9c9e2ada5e0..9e67fe11467 100644
--- a/src/server/shared/Dynamic/FactoryHolder.h
+++ b/src/server/shared/Dynamic/FactoryHolder.h
@@ -20,8 +20,8 @@
#define TRINITY_FACTORY_HOLDER
#include "Define.h"
-#include "Dynamic/TypeList.h"
#include "ObjectRegistry.h"
+#include "TypeList.h"
/** FactoryHolder holds a factory object of a specific type
*/
diff --git a/src/server/shared/Dynamic/LinkedList.h b/src/server/shared/Dynamic/LinkedList.h
index 0d64c337cbe..74f4ca553f4 100644
--- a/src/server/shared/Dynamic/LinkedList.h
+++ b/src/server/shared/Dynamic/LinkedList.h
@@ -165,13 +165,13 @@ class LinkedListHead
{ // construct with node pointer _Pnode
}
- Iterator& operator=(Iterator const &_Right)
+ Iterator& operator=(Iterator const& _Right)
{
_Ptr = _Right._Ptr;
return *this;
}
- Iterator& operator=(const_pointer const &_Right)
+ Iterator& operator=(const_pointer const& _Right)
{
_Ptr = pointer(_Right);
return *this;
@@ -213,22 +213,22 @@ class LinkedListHead
return (_Tmp);
}
- bool operator==(Iterator const &_Right) const
+ bool operator==(Iterator const& _Right) const
{ // test for iterator equality
return (_Ptr == _Right._Ptr);
}
- bool operator!=(Iterator const &_Right) const
+ bool operator!=(Iterator const& _Right) const
{ // test for iterator inequality
return (!(*this == _Right));
}
- bool operator==(pointer const &_Right) const
+ bool operator==(pointer const& _Right) const
{ // test for pointer equality
return (_Ptr != _Right);
}
- bool operator!=(pointer const &_Right) const
+ bool operator!=(pointer const& _Right) const
{ // test for pointer equality
return (!(*this == _Right));
}
diff --git a/src/server/shared/Dynamic/LinkedReference/Reference.h b/src/server/shared/Dynamic/LinkedReference/Reference.h
index c0c4ec21a80..4002de2d584 100644
--- a/src/server/shared/Dynamic/LinkedReference/Reference.h
+++ b/src/server/shared/Dynamic/LinkedReference/Reference.h
@@ -40,7 +40,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
virtual void sourceObjectDestroyLink() = 0;
public:
- Reference() { iRefTo = NULL; iRefFrom = NULL; }
+ Reference() { iRefTo = nullptr; iRefFrom = nullptr; }
virtual ~Reference() { }
// Create new link
@@ -49,7 +49,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement
ASSERT(fromObj); // fromObj MUST not be NULL
if (isValid())
unlink();
- if (toObj != NULL)
+ if (toObj != nullptr)
{
iRefTo = toObj;
iRefFrom = fromObj;
@@ -63,8 +63,8 @@ template <class TO, class FROM> class Reference : public LinkedListElement
{
targetObjectDestroyLink();
delink();
- iRefTo = NULL;
- iRefFrom = NULL;
+ iRefTo = nullptr;
+ iRefFrom = nullptr;
}
// Link is invalid due to destruction of referenced target object. Call comes from the refTo object
@@ -73,12 +73,12 @@ template <class TO, class FROM> class Reference : public LinkedListElement
{
sourceObjectDestroyLink();
delink();
- iRefTo = NULL;
+ iRefTo = nullptr;
}
bool isValid() const // Only check the iRefTo
{
- return iRefTo != NULL;
+ return iRefTo != nullptr;
}
Reference<TO, FROM> * next() { return((Reference<TO, FROM> *) LinkedListElement::next()); }
diff --git a/src/server/shared/Dynamic/ObjectRegistry.h b/src/server/shared/Dynamic/ObjectRegistry.h
index 5f614819b13..8ed72c476e8 100644
--- a/src/server/shared/Dynamic/ObjectRegistry.h
+++ b/src/server/shared/Dynamic/ObjectRegistry.h
@@ -82,6 +82,8 @@ class ObjectRegistry final
// non instanceable, only static
ObjectRegistry() { }
~ObjectRegistry() { }
+ ObjectRegistry(ObjectRegistry const&) = delete;
+ ObjectRegistry& operator=(ObjectRegistry const&) = delete;
};
#endif
diff --git a/src/server/shared/Dynamic/TypeContainer.h b/src/server/shared/Dynamic/TypeContainer.h
deleted file mode 100644
index 7e825136755..00000000000
--- a/src/server/shared/Dynamic/TypeContainer.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * 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 TRINITY_TYPECONTAINER_H
-#define TRINITY_TYPECONTAINER_H
-
-/*
- * Here, you'll find a series of containers that allow you to hold multiple
- * types of object at the same time.
- */
-
-#include <map>
-#include <unordered_map>
-#include <vector>
-#include "Define.h"
-#include "Dynamic/TypeList.h"
-#include "GridRefManager.h"
-
-/*
- * @class ContainerMapList is a mulit-type container for map elements
- * By itself its meaningless but collaborate along with TypeContainers,
- * it become the most powerfully container in the whole system.
- */
-template<class OBJECT>
-struct ContainerMapList
-{
- //std::map<OBJECT_HANDLE, OBJECT *> _element;
- GridRefManager<OBJECT> _element;
-};
-
-template<>
-struct ContainerMapList<TypeNull> /* nothing is in type null */
-{
-};
-
-template<class H, class T>
-struct ContainerMapList<TypeList<H, T> >
-{
- ContainerMapList<H> _elements;
- ContainerMapList<T> _TailElements;
-};
-
-template<class OBJECT, class KEY_TYPE>
-struct ContainerUnorderedMap
-{
- std::unordered_map<KEY_TYPE, OBJECT*> _element;
-};
-
-template<class KEY_TYPE>
-struct ContainerUnorderedMap<TypeNull, KEY_TYPE>
-{
-};
-
-template<class H, class T, class KEY_TYPE>
-struct ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>
-{
- ContainerUnorderedMap<H, KEY_TYPE> _elements;
- ContainerUnorderedMap<T, KEY_TYPE> _TailElements;
-};
-
-#include "TypeContainerFunctions.h"
-
-/*
- * @class TypeMapContainer contains a fixed number of types and is
- * determined at compile time. This is probably the most complicated
- * class and do its simplest thing, that is, holds objects
- * of different types.
- */
-
-template<class OBJECT_TYPES>
-class TypeMapContainer
-{
- public:
- template<class SPECIFIC_TYPE> size_t Count() const { return Trinity::Count(i_elements, (SPECIFIC_TYPE*)NULL); }
-
- /// inserts a specific object into the container
- template<class SPECIFIC_TYPE>
- bool insert(SPECIFIC_TYPE *obj)
- {
- SPECIFIC_TYPE* t = Trinity::Insert(i_elements, obj);
- return (t != NULL);
- }
-
- /// Removes the object from the container, and returns the removed object
- //template<class SPECIFIC_TYPE>
- //bool remove(SPECIFIC_TYPE* obj)
- //{
- // SPECIFIC_TYPE* t = Trinity::Remove(i_elements, obj);
- // return (t != NULL);
- //}
-
- ContainerMapList<OBJECT_TYPES> & GetElements(void) { return i_elements; }
- const ContainerMapList<OBJECT_TYPES> & GetElements(void) const { return i_elements;}
-
- private:
- ContainerMapList<OBJECT_TYPES> i_elements;
-};
-
-template<class OBJECT_TYPES, class KEY_TYPE>
-class TypeUnorderedMapContainer
-{
-public:
- template<class SPECIFIC_TYPE>
- bool Insert(KEY_TYPE const& handle, SPECIFIC_TYPE* obj)
- {
- return Trinity::Insert(_elements, handle, obj);
- }
-
- template<class SPECIFIC_TYPE>
- bool Remove(KEY_TYPE const& handle)
- {
- return Trinity::Remove(_elements, handle, (SPECIFIC_TYPE*)NULL);
- }
-
- template<class SPECIFIC_TYPE>
- SPECIFIC_TYPE* Find(KEY_TYPE const& handle)
- {
- return Trinity::Find(_elements, handle, (SPECIFIC_TYPE*)NULL);
- }
-
- ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE>& GetElements() { return _elements; }
- ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> const& GetElements() const { return _elements; }
-
-private:
- ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> _elements;
-};
-
-#endif
diff --git a/src/server/shared/Dynamic/TypeContainerFunctions.h b/src/server/shared/Dynamic/TypeContainerFunctions.h
deleted file mode 100644
index 97d20922a05..00000000000
--- a/src/server/shared/Dynamic/TypeContainerFunctions.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * 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 TYPECONTAINER_FUNCTIONS_H
-#define TYPECONTAINER_FUNCTIONS_H
-
-/*
- * Here you'll find a list of helper functions to make
- * the TypeContainer usefull. Without it, its hard
- * to access or mutate the container.
- */
-
-#include "Define.h"
-#include "Dynamic/TypeList.h"
-#include <map>
-#include <unordered_map>
-
-namespace Trinity
-{
- // Helpers
- // Insert helpers
- template<class SPECIFIC_TYPE, class KEY_TYPE>
- bool Insert(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj)
- {
- auto i = elements._element.find(handle);
- if (i == elements._element.end())
- {
- elements._element[handle] = obj;
- return true;
- }
- else
- {
- ASSERT(i->second == obj, "Object with certain key already in but objects are different!");
- return false;
- }
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE>
- bool Insert(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/)
- {
- return false;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE, class T>
- bool Insert(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/)
- {
- return false;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T>
- bool Insert(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj)
- {
- bool ret = Insert(elements._elements, handle, obj);
- return ret ? ret : Insert(elements._TailElements, handle, obj);
- }
-
- // Find helpers
- template<class SPECIFIC_TYPE, class KEY_TYPE>
- SPECIFIC_TYPE* Find(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/)
- {
- auto i = elements._element.find(handle);
- if (i == elements._element.end())
- return nullptr;
- else
- return i->second;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE>
- SPECIFIC_TYPE* Find(ContainerUnorderedMap<TypeNull, KEY_TYPE> const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/)
- {
- return nullptr;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE, class T>
- SPECIFIC_TYPE* Find(ContainerUnorderedMap<T, KEY_TYPE> const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/)
- {
- return nullptr;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T>
- SPECIFIC_TYPE* Find(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/)
- {
- SPECIFIC_TYPE* ret = Find(elements._elements, handle, (SPECIFIC_TYPE*)nullptr);
- return ret ? ret : Find(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr);
- }
-
- // Erase helpers
- template<class SPECIFIC_TYPE, class KEY_TYPE>
- bool Remove(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/)
- {
- elements._element.erase(handle);
- return true;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE>
- bool Remove(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/)
- {
- return false;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE, class T>
- bool Remove(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/)
- {
- return false;
- }
-
- template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T>
- bool Remove(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/)
- {
- bool ret = Remove(elements._elements, handle, (SPECIFIC_TYPE*)nullptr);
- return ret ? ret : Remove(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr);
- }
-
- /* ContainerMapList Helpers */
- // count functions
- template<class SPECIFIC_TYPE>
- size_t Count(ContainerMapList<SPECIFIC_TYPE> const& elements, SPECIFIC_TYPE* /*fake*/)
- {
- return elements._element.getSize();
- }
-
- template<class SPECIFIC_TYPE>
- size_t Count(ContainerMapList<TypeNull> const& /*elements*/, SPECIFIC_TYPE* /*fake*/)
- {
- return 0;
- }
-
- template<class SPECIFIC_TYPE, class T>
- size_t Count(ContainerMapList<T> const& /*elements*/, SPECIFIC_TYPE* /*fake*/)
- {
- return 0;
- }
-
- template<class SPECIFIC_TYPE, class T>
- size_t Count(ContainerMapList<TypeList<SPECIFIC_TYPE, T>> const& elements, SPECIFIC_TYPE* fake)
- {
- return Count(elements._elements, fake);
- }
-
- template<class SPECIFIC_TYPE, class H, class T>
- size_t Count(ContainerMapList<TypeList<H, T>> const& elements, SPECIFIC_TYPE* fake)
- {
- return Count(elements._TailElements, fake);
- }
-
- // non-const insert functions
- template<class SPECIFIC_TYPE>
- SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE>& elements, SPECIFIC_TYPE* obj)
- {
- //elements._element[hdl] = obj;
- obj->AddToGrid(elements._element);
- return obj;
- }
-
- template<class SPECIFIC_TYPE>
- SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull>& /*elements*/, SPECIFIC_TYPE* /*obj*/)
- {
- return nullptr;
- }
-
- // this is a missed
- template<class SPECIFIC_TYPE, class T>
- SPECIFIC_TYPE* Insert(ContainerMapList<T>& /*elements*/, SPECIFIC_TYPE* /*obj*/)
- {
- return nullptr; // a missed
- }
-
- // Recursion
- template<class SPECIFIC_TYPE, class H, class T>
- SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T>>& elements, SPECIFIC_TYPE* obj)
- {
- SPECIFIC_TYPE* t = Insert(elements._elements, obj);
- return (t != nullptr ? t : Insert(elements._TailElements, obj));
- }
-
- //// non-const remove method
- //template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<SPECIFIC_TYPE> & /*elements*/, SPECIFIC_TYPE *obj)
- //{
- // obj->GetGridRef().unlink();
- // return obj;
- //}
-
- //template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
- //{
- // return nullptr;
- //}
-
- //// this is a missed
- //template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
- //{
- // return nullptr; // a missed
- //}
-
- //template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj)
- //{
- // // The head element is bad
- // SPECIFIC_TYPE* t = Remove(elements._elements, obj);
- // return (t != nullptr ? t : Remove(elements._TailElements, obj));
- //}
-}
-#endif
-
diff --git a/src/server/shared/Dynamic/TypeContainerVisitor.h b/src/server/shared/Dynamic/TypeContainerVisitor.h
deleted file mode 100644
index f15cfe66758..00000000000
--- a/src/server/shared/Dynamic/TypeContainerVisitor.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * 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 TRINITY_TYPECONTAINERVISITOR_H
-#define TRINITY_TYPECONTAINERVISITOR_H
-
-/*
- * @class TypeContainerVisitor is implemented as a visitor pattern. It is
- * a visitor to the TypeContainerList or TypeContainerMapList. The visitor has
- * to overload its types as a visit method is called.
- */
-
-#include "Define.h"
-#include "Dynamic/TypeContainer.h"
-
-// forward declaration
-template<class T, class Y> class TypeContainerVisitor;
-
-// visitor helper
-template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c)
-{
- v.Visit(c);
-}
-
-// terminate condition container map list
-template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/) { }
-
-template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerMapList<T> &c)
-{
- v.Visit(c._element);
-}
-
-// recursion container map list
-template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerMapList<TypeList<H, T> > &c)
-{
- VisitorHelper(v, c._elements);
- VisitorHelper(v, c._TailElements);
-}
-
-// for TypeMapContainer
-template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c)
-{
- VisitorHelper(v, c.GetElements());
-}
-
-// TypeUnorderedMapContainer
-template<class VISITOR, class KEY_TYPE>
-void VisitorHelper(VISITOR& /*v*/, ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*c*/) { }
-
-template<class VISITOR, class KEY_TYPE, class T>
-void VisitorHelper(VISITOR& v, ContainerUnorderedMap<T, KEY_TYPE>& c)
-{
- v.Visit(c._element);
-}
-
-template<class VISITOR, class KEY_TYPE, class H, class T>
-void VisitorHelper(VISITOR& v, ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& c)
-{
- VisitorHelper(v, c._elements);
- VisitorHelper(v, c._TailElements);
-}
-
-template<class VISITOR, class OBJECT_TYPES, class KEY_TYPE>
-void VisitorHelper(VISITOR& v, TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>& c)
-{
- VisitorHelper(v, c.GetElements());
-}
-
-template<class VISITOR, class TYPE_CONTAINER>
-class TypeContainerVisitor
-{
- public:
- TypeContainerVisitor(VISITOR &v) : i_visitor(v) { }
-
- void Visit(TYPE_CONTAINER &c)
- {
- VisitorHelper(i_visitor, c);
- }
-
- void Visit(const TYPE_CONTAINER &c) const
- {
- VisitorHelper(i_visitor, c);
- }
-
- private:
- VISITOR &i_visitor;
-};
-#endif
-
diff --git a/src/server/shared/Memory.h b/src/server/shared/Memory.h
index 7aeb4dc3f0a..e41e4baf025 100644
--- a/src/server/shared/Memory.h
+++ b/src/server/shared/Memory.h
@@ -1,4 +1,19 @@
-
+/*
+ * 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 _MEMORY_H
#define _MEMORY_H
diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h
index 7c827ec4454..dc6c5332c23 100644
--- a/src/server/shared/Networking/AsyncAcceptor.h
+++ b/src/server/shared/Networking/AsyncAcceptor.h
@@ -19,7 +19,8 @@
#define __ASYNCACCEPT_H_
#include "Log.h"
-#include <boost/asio.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ip/address.hpp>
#include <functional>
#include <atomic>
diff --git a/src/server/shared/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp
index f9860f273ed..a4ab6e1daf7 100644
--- a/src/server/shared/Packets/ByteBuffer.cpp
+++ b/src/server/shared/Packets/ByteBuffer.cpp
@@ -17,11 +17,13 @@
*/
#include "ByteBuffer.h"
+#include "Errors.h"
#include "MessageBuffer.h"
#include "Common.h"
#include "Log.h"
-
+#include "Util.h"
#include <sstream>
+#include <ctime>
ByteBuffer::ByteBuffer(MessageBuffer&& buffer) : _rpos(0), _wpos(0), _storage(buffer.Move())
{
@@ -51,6 +53,78 @@ ByteBufferSourceException::ByteBufferSourceException(size_t pos, size_t size,
message().assign(ss.str());
}
+ByteBuffer& ByteBuffer::operator>>(float& value)
+{
+ value = read<float>();
+ if (!std::isfinite(value))
+ throw ByteBufferException();
+ return *this;
+}
+
+ByteBuffer& ByteBuffer::operator>>(double& value)
+{
+ value = read<double>();
+ if (!std::isfinite(value))
+ throw ByteBufferException();
+ return *this;
+}
+
+uint32 ByteBuffer::ReadPackedTime()
+{
+ uint32 packedDate = read<uint32>();
+ tm lt = tm();
+
+ lt.tm_min = packedDate & 0x3F;
+ lt.tm_hour = (packedDate >> 6) & 0x1F;
+ //lt.tm_wday = (packedDate >> 11) & 7;
+ lt.tm_mday = ((packedDate >> 14) & 0x3F) + 1;
+ lt.tm_mon = (packedDate >> 20) & 0xF;
+ lt.tm_year = ((packedDate >> 24) & 0x1F) + 100;
+
+ return uint32(mktime(&lt));
+}
+
+void ByteBuffer::append(uint8 const* src, size_t cnt)
+{
+ ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", _wpos, size());
+ ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", _wpos, size());
+ ASSERT(size() < 10000000);
+
+ size_t const newSize = _wpos + cnt;
+ if (_storage.capacity() < newSize) // custom memory allocation rules
+ {
+ if (newSize < 100)
+ _storage.reserve(300);
+ else if (newSize < 750)
+ _storage.reserve(2500);
+ else if (newSize < 6000)
+ _storage.reserve(10000);
+ else
+ _storage.reserve(400000);
+ }
+
+ if (_storage.size() < newSize)
+ _storage.resize(newSize);
+ std::memcpy(&_storage[_wpos], src, cnt);
+ _wpos = newSize;
+}
+
+void ByteBuffer::AppendPackedTime(time_t time)
+{
+ tm lt;
+ localtime_r(&time, &lt);
+ append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
+}
+
+void ByteBuffer::put(size_t pos, uint8 const* src, size_t cnt)
+{
+ ASSERT(pos + cnt <= size(), "Attempted to put value with size: " SZFMTD " in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", cnt, pos, size());
+ ASSERT(src, "Attempted to put a NULL-pointer in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", pos, size());
+ ASSERT(cnt, "Attempted to put a zero-sized value in ByteBuffer (pos: " SZFMTD " size: " SZFMTD ")", pos, size());
+
+ std::memcpy(&_storage[pos], src, cnt);
+}
+
void ByteBuffer::print_storage() const
{
if (!sLog->ShouldLog("network", LOG_LEVEL_TRACE)) // optimize disabled trace output
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 1dc5fee6a12..77f09455cc7 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -20,9 +20,9 @@
#define _BYTEBUFFER_H
#include "Define.h"
-#include "Errors.h"
#include "ByteConverter.h"
-#include "Util.h"
+#include <string>
+#include <vector>
#include <cstring>
class MessageBuffer;
@@ -109,7 +109,8 @@ class TC_SHARED_API ByteBuffer
append((uint8 *)&value, sizeof(value));
}
- template <typename T> void put(size_t pos, T value)
+ template <typename T>
+ void put(std::size_t pos, T value)
{
static_assert(std::is_fundamental<T>::value, "append(compound)");
EndianConvert(value);
@@ -249,21 +250,8 @@ class TC_SHARED_API ByteBuffer
return *this;
}
- ByteBuffer &operator>>(float &value)
- {
- value = read<float>();
- if (!std::isfinite(value))
- throw ByteBufferException();
- return *this;
- }
-
- ByteBuffer &operator>>(double &value)
- {
- value = read<double>();
- if (!std::isfinite(value))
- throw ByteBufferException();
- return *this;
- }
+ ByteBuffer &operator>>(float &value);
+ ByteBuffer &operator>>(double &value);
ByteBuffer &operator>>(std::string& value)
{
@@ -371,20 +359,7 @@ class TC_SHARED_API ByteBuffer
}
}
- uint32 ReadPackedTime()
- {
- uint32 packedDate = read<uint32>();
- tm lt = tm();
-
- lt.tm_min = packedDate & 0x3F;
- lt.tm_hour = (packedDate >> 6) & 0x1F;
- //lt.tm_wday = (packedDate >> 11) & 7;
- lt.tm_mday = ((packedDate >> 14) & 0x3F) + 1;
- lt.tm_mon = (packedDate >> 20) & 0xF;
- lt.tm_year = ((packedDate >> 24) & 0x1F) + 100;
-
- return uint32(mktime(&lt));
- }
+ uint32 ReadPackedTime();
ByteBuffer& ReadPackedTime(uint32& time)
{
@@ -432,36 +407,9 @@ class TC_SHARED_API ByteBuffer
return append((const uint8 *)src, cnt * sizeof(T));
}
- void append(const uint8 *src, size_t cnt)
- {
- if (!cnt)
- throw ByteBufferSourceException(_wpos, size(), cnt);
-
- if (!src)
- throw ByteBufferSourceException(_wpos, size(), cnt);
+ void append(uint8 const* src, size_t cnt);
- ASSERT(size() < 10000000);
-
- size_t const newSize = _wpos + cnt;
- if (_storage.capacity() < newSize) // custom memory allocation rules
- {
- if (newSize < 100)
- _storage.reserve(300);
- else if (newSize < 750)
- _storage.reserve(2500);
- else if (newSize < 6000)
- _storage.reserve(10000);
- else
- _storage.reserve(400000);
- }
-
- if (_storage.size() < newSize)
- _storage.resize(newSize);
- std::memcpy(&_storage[_wpos], src, cnt);
- _wpos = newSize;
- }
-
- void append(const ByteBuffer& buffer)
+ void append(ByteBuffer const& buffer)
{
if (buffer.wpos())
append(buffer.contents(), buffer.wpos());
@@ -496,23 +444,9 @@ class TC_SHARED_API ByteBuffer
append(packGUID, size);
}
- void AppendPackedTime(time_t time)
- {
- tm lt;
- localtime_r(&time, &lt);
- append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
- }
+ void AppendPackedTime(time_t time);
- void put(size_t pos, const uint8 *src, size_t cnt)
- {
- if (pos + cnt > size())
- throw ByteBufferPositionException(true, pos, cnt, size());
-
- if (!src)
- throw ByteBufferSourceException(_wpos, size(), cnt);
-
- std::memcpy(&_storage[pos], src, cnt);
- }
+ void put(size_t pos, const uint8 *src, size_t cnt);
void print_storage() const;
@@ -525,85 +459,6 @@ class TC_SHARED_API ByteBuffer
std::vector<uint8> _storage;
};
-template <typename T>
-inline ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
-{
- b << (uint32)v.size();
- for (typename std::vector<T>::iterator i = v.begin(); i != v.end(); ++i)
- {
- b << *i;
- }
- return b;
-}
-
-template <typename T>
-inline ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
-{
- uint32 vsize;
- b >> vsize;
- v.clear();
- while (vsize--)
- {
- T t;
- b >> t;
- v.push_back(t);
- }
- return b;
-}
-
-template <typename T>
-inline ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
-{
- b << (uint32)v.size();
- for (typename std::list<T>::iterator i = v.begin(); i != v.end(); ++i)
- {
- b << *i;
- }
- return b;
-}
-
-template <typename T>
-inline ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
-{
- uint32 vsize;
- b >> vsize;
- v.clear();
- while (vsize--)
- {
- T t;
- b >> t;
- v.push_back(t);
- }
- return b;
-}
-
-template <typename K, typename V>
-inline ByteBuffer &operator<<(ByteBuffer &b, std::map<K, V> &m)
-{
- b << (uint32)m.size();
- for (typename std::map<K, V>::iterator i = m.begin(); i != m.end(); ++i)
- {
- b << i->first << i->second;
- }
- return b;
-}
-
-template <typename K, typename V>
-inline ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m)
-{
- uint32 msize;
- b >> msize;
- m.clear();
- while (msize--)
- {
- K k;
- V v;
- b >> k >> v;
- m.insert(make_pair(k, v));
- }
- return b;
-}
-
/// @todo Make a ByteBuffer.cpp and move all this inlining to it.
template<> inline std::string ByteBuffer::read<std::string>()
{
diff --git a/src/server/shared/PrecompiledHeaders/sharedPCH.cpp b/src/server/shared/PrecompiledHeaders/sharedPCH.cpp
index 36eb3a877f0..3b045ac537a 100644
--- a/src/server/shared/PrecompiledHeaders/sharedPCH.cpp
+++ b/src/server/shared/PrecompiledHeaders/sharedPCH.cpp
@@ -1 +1,18 @@
+/*
+ * 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 "sharedPCH.h"
diff --git a/src/server/shared/PrecompiledHeaders/sharedPCH.h b/src/server/shared/PrecompiledHeaders/sharedPCH.h
index f864674d5ad..436b0453c30 100644
--- a/src/server/shared/PrecompiledHeaders/sharedPCH.h
+++ b/src/server/shared/PrecompiledHeaders/sharedPCH.h
@@ -1,4 +1,28 @@
+/*
+ * 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/>.
+ */
+
//add here most rarely modified headers to speed up debug build compilation
-#include "TypeList.h"
-#include "GitRevision.h"
+#include "Common.h"
+#include "Define.h"
+#include "Errors.h"
+#include "Log.h"
+#include <boost/asio/ip/tcp.hpp>
+#include <atomic>
+#include <memory>
+#include <string>
+#include <vector>
diff --git a/src/server/shared/Realm/Realm.cpp b/src/server/shared/Realm/Realm.cpp
index 2768e17848b..571e798cc76 100644
--- a/src/server/shared/Realm/Realm.cpp
+++ b/src/server/shared/Realm/Realm.cpp
@@ -16,8 +16,9 @@
*/
#include "Realm.h"
+#include <boost/asio/ip/basic_endpoint.hpp>
-boost::asio::ip::tcp::endpoint Realm::GetAddressForClient(boost::asio::ip::address const& clientAddr) const
+boost::asio::ip::tcp_endpoint Realm::GetAddressForClient(boost::asio::ip::address const& clientAddr) const
{
boost::asio::ip::address realmIp;
@@ -25,29 +26,27 @@ boost::asio::ip::tcp::endpoint Realm::GetAddressForClient(boost::asio::ip::addre
if (clientAddr.is_loopback())
{
// Try guessing if realm is also connected locally
- if (LocalAddress.is_loopback() || ExternalAddress.is_loopback())
+ if (LocalAddress->is_loopback() || ExternalAddress->is_loopback())
realmIp = clientAddr;
else
{
// Assume that user connecting from the machine that bnetserver is located on
// has all realms available in his local network
- realmIp = LocalAddress;
+ realmIp = *LocalAddress;
}
}
else
{
if (clientAddr.is_v4() &&
- (clientAddr.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()) ==
- (LocalAddress.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()))
+ (clientAddr.to_v4().to_ulong() & LocalSubnetMask->to_v4().to_ulong()) ==
+ (LocalAddress->to_v4().to_ulong() & LocalSubnetMask->to_v4().to_ulong()))
{
- realmIp = LocalAddress;
+ realmIp = *LocalAddress;
}
else
- realmIp = ExternalAddress;
+ realmIp = *ExternalAddress;
}
- boost::asio::ip::tcp::endpoint endpoint(realmIp, Port);
-
// Return external IP
- return endpoint;
+ return boost::asio::ip::tcp_endpoint(realmIp, Port);
}
diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h
index e3cf181c120..b9b70592f0f 100644
--- a/src/server/shared/Realm/Realm.h
+++ b/src/server/shared/Realm/Realm.h
@@ -19,8 +19,7 @@
#define Realm_h__
#include "Common.h"
-#include <boost/asio/ip/address.hpp>
-#include <boost/asio/ip/tcp.hpp>
+#include "AsioHacksFwd.h"
enum RealmFlags
{
@@ -68,9 +67,9 @@ struct TC_SHARED_API Realm
{
RealmHandle Id;
uint32 Build;
- boost::asio::ip::address ExternalAddress;
- boost::asio::ip::address LocalAddress;
- boost::asio::ip::address LocalSubnetMask;
+ std::unique_ptr<boost::asio::ip::address> ExternalAddress;
+ std::unique_ptr<boost::asio::ip::address> LocalAddress;
+ std::unique_ptr<boost::asio::ip::address> LocalSubnetMask;
uint16 Port;
std::string Name;
uint8 Type;
@@ -79,7 +78,7 @@ struct TC_SHARED_API Realm
AccountTypes AllowedSecurityLevel;
float PopulationLevel;
- boost::asio::ip::tcp::endpoint GetAddressForClient(boost::asio::ip::address const& clientAddr) const;
+ boost::asio::ip::tcp_endpoint GetAddressForClient(boost::asio::ip::address const& clientAddr) const;
};
#endif // Realm_h__
diff --git a/src/server/shared/Realm/RealmList.cpp b/src/server/shared/Realm/RealmList.cpp
index 37dd6bbaa17..a4a92ce0ec0 100644
--- a/src/server/shared/Realm/RealmList.cpp
+++ b/src/server/shared/Realm/RealmList.cpp
@@ -17,16 +17,18 @@
*/
#include "RealmList.h"
-#include "Database/DatabaseEnv.h"
+#include "DatabaseEnv.h"
+#include "Log.h"
#include "Util.h"
+#include <boost/asio/deadline_timer.hpp>
+#include <boost/asio/ip/tcp.hpp>
-RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr)
+RealmList::RealmList() : _updateInterval(0)
{
}
RealmList::~RealmList()
{
- delete _updateTimer;
}
RealmList* RealmList::Instance()
@@ -39,8 +41,8 @@ RealmList* RealmList::Instance()
void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval)
{
_updateInterval = updateInterval;
- _updateTimer = new boost::asio::deadline_timer(ioService);
- _resolver = new boost::asio::ip::tcp::resolver(ioService);
+ _updateTimer = Trinity::make_unique<boost::asio::deadline_timer>(ioService);
+ _resolver = Trinity::make_unique<boost::asio::ip::tcp::resolver>(ioService);
// Get the content of the realmlist table in the database
UpdateRealms(boost::system::error_code());
@@ -51,9 +53,9 @@ void RealmList::Close()
_updateTimer->cancel();
}
-void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, boost::asio::ip::address const& address, boost::asio::ip::address const& localAddr,
- boost::asio::ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel,
- float population)
+void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, std::string const& name,
+ boost::asio::ip::address const& address, boost::asio::ip::address const& localAddr, boost::asio::ip::address const& localSubmask,
+ uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population)
{
// Create new if not exist or update existed
Realm& realm = _realms[id];
@@ -66,9 +68,12 @@ void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, const std::stri
realm.Timezone = timezone;
realm.AllowedSecurityLevel = allowedSecurityLevel;
realm.PopulationLevel = population;
- realm.ExternalAddress = address;
- realm.LocalAddress = localAddr;
- realm.LocalSubnetMask = localSubmask;
+ if (!realm.ExternalAddress || *realm.ExternalAddress != address)
+ realm.ExternalAddress = Trinity::make_unique<boost::asio::ip::address>(address);
+ if (!realm.LocalAddress || *realm.LocalAddress != localAddr)
+ realm.LocalAddress = Trinity::make_unique<boost::asio::ip::address>(localAddr);
+ if (!realm.LocalSubnetMask || *realm.LocalSubnetMask != localSubmask)
+ realm.LocalSubnetMask = Trinity::make_unique<boost::asio::ip::address>(localSubmask);
realm.Port = port;
}
@@ -110,7 +115,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
continue;
}
- boost::asio::ip::address externalAddress = (*endPoint).endpoint().address();
+ boost::asio::ip::address externalAddress = endPoint->endpoint().address();
boost::asio::ip::tcp::resolver::query localAddressQuery(boost::asio::ip::tcp::v4(), fields[3].GetString(), "");
endPoint = _resolver->resolve(localAddressQuery, ec);
@@ -120,7 +125,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
continue;
}
- boost::asio::ip::address localAddress = (*endPoint).endpoint().address();
+ boost::asio::ip::address localAddress = endPoint->endpoint().address();
boost::asio::ip::tcp::resolver::query localSubmaskQuery(boost::asio::ip::tcp::v4(), fields[4].GetString(), "");
endPoint = _resolver->resolve(localSubmaskQuery, ec);
@@ -130,7 +135,7 @@ void RealmList::UpdateRealms(boost::system::error_code const& error)
continue;
}
- boost::asio::ip::address localSubmask = (*endPoint).endpoint().address();
+ boost::asio::ip::address localSubmask = endPoint->endpoint().address();
uint16 port = fields[5].GetUInt16();
uint8 icon = fields[6].GetUInt8();
@@ -181,5 +186,5 @@ Realm const* RealmList::GetRealm(RealmHandle const& id) const
if (itr != _realms.end())
return &itr->second;
- return NULL;
+ return nullptr;
}
diff --git a/src/server/shared/Realm/RealmList.h b/src/server/shared/Realm/RealmList.h
index 7878779b736..5d6d2c16151 100644
--- a/src/server/shared/Realm/RealmList.h
+++ b/src/server/shared/Realm/RealmList.h
@@ -19,12 +19,24 @@
#ifndef _REALMLIST_H
#define _REALMLIST_H
-#include "Common.h"
-#include "Realm/Realm.h"
-#include <boost/asio/ip/address.hpp>
-#include <boost/asio/ip/tcp.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/deadline_timer.hpp>
+#include "Define.h"
+#include "Realm.h"
+#include <map>
+#include <vector>
+#include <unordered_set>
+
+namespace boost
+{
+ namespace asio
+ {
+ class io_service;
+ }
+
+ namespace system
+ {
+ class error_code;
+ }
+}
/// Storage object for the list of realms on the server
class TC_SHARED_API RealmList
@@ -46,13 +58,14 @@ private:
RealmList();
void UpdateRealms(boost::system::error_code const& error);
- void UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, boost::asio::ip::address const& address, boost::asio::ip::address const& localAddr,
- boost::asio::ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
+ void UpdateRealm(RealmHandle const& id, uint32 build, std::string const& name,
+ boost::asio::ip::address const& address, boost::asio::ip::address const& localAddr, boost::asio::ip::address const& localSubmask,
+ uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population);
RealmMap _realms;
uint32 _updateInterval;
- boost::asio::deadline_timer* _updateTimer;
- boost::asio::ip::tcp::resolver* _resolver;
+ std::unique_ptr<boost::asio::deadline_timer> _updateTimer;
+ std::unique_ptr<boost::asio::ip::tcp_resolver> _resolver;
};
#define sRealmList RealmList::Instance()