aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared')
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.cpp411
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.h106
-rw-r--r--src/server/shared/DataStores/DB2Store.h141
-rwxr-xr-xsrc/server/shared/DataStores/DBCFileLoader.h4
-rwxr-xr-xsrc/server/shared/Define.h17
-rwxr-xr-xsrc/server/shared/Logging/Log.cpp7
-rwxr-xr-xsrc/server/shared/Logging/Log.h2
-rwxr-xr-xsrc/server/shared/Packets/ByteBuffer.h67
-rwxr-xr-xsrc/server/shared/Packets/WorldPacket.h52
9 files changed, 749 insertions, 58 deletions
diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2FileLoader.cpp
new file mode 100644
index 00000000000..2b3e82764cf
--- /dev/null
+++ b/src/server/shared/DataStores/DB2FileLoader.cpp
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 "Common.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "DB2FileLoader.h"
+
+DB2FileLoader::DB2FileLoader()
+{
+ data = NULL;
+ fieldsOffset = NULL;
+}
+
+bool DB2FileLoader::Load(const char *filename, const char *fmt)
+{
+ uint32 header = 48;
+ if (data)
+ {
+ delete [] data;
+ data=NULL;
+ }
+
+ FILE * f = fopen(filename, "rb");
+ if (!f)
+ return false;
+
+ if (fread(&header, 4, 1, f) != 1) // Signature
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(header);
+
+ if (header != 0x32424457)
+ {
+ fclose(f);
+ return false; //'WDB2'
+ }
+
+ 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);
+
+ /* NEW WDB2 FIELDS*/
+ if (fread(&tableHash, 4, 1, f) != 1) // Table hash
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(tableHash);
+
+ if (fread(&build, 4, 1, f) != 1) // Build
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(build);
+
+ if (fread(&unk1, 4, 1, f) != 1) // Unknown WDB2
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(unk1);
+
+ if (build > 12880)
+ {
+ if (fread(&unk2, 4, 1, f) != 1) // Unknown WDB2
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(unk2);
+
+ if (fread(&maxIndex, 4, 1, f) != 1) // MaxIndex WDB2
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(maxIndex);
+
+ if (fread(&locale, 4, 1, f) != 1) // Locales
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(locale);
+
+ if (fread(&unk5, 4, 1, f) != 1) // Unknown WDB2
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(unk5);
+ }
+
+ if (maxIndex != 0)
+ {
+ int32 diff = maxIndex - unk2 + 1;
+ fseek(f, diff * 4 + diff * 2, SEEK_CUR); // diff * 4: an index for rows, diff * 2: a memory allocation bank
+ }
+
+ 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')
+ fieldsOffset[i] += 1;
+ else
+ fieldsOffset[i] += 4;
+ }
+
+ 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;
+}
+
+DB2FileLoader::~DB2FileLoader()
+{
+ if (data)
+ delete [] data;
+ if (fieldsOffset)
+ delete [] fieldsOffset;
+}
+
+DB2FileLoader::Record DB2FileLoader::getRecord(size_t id)
+{
+ assert(data);
+ return Record(*this, data + id*recordSize);
+}
+
+uint32 DB2FileLoader::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:
+ case FT_INT:
+ recordsize += 4;
+ break;
+ case FT_STRING:
+ recordsize += sizeof(char*);
+ break;
+ case FT_SORT:
+ i = x;
+ break;
+ case FT_IND:
+ i = x;
+ recordsize += 4;
+ break;
+ case FT_BYTE:
+ recordsize += 1;
+ break;
+ }
+ }
+
+ if (index_pos)
+ *index_pos = i;
+
+ return recordsize;
+}
+
+uint32 DB2FileLoader::GetFormatStringsFields(const char * format)
+{
+ uint32 stringfields = 0;
+ for (uint32 x=0; format[x]; ++x)
+ if (format[x] == FT_STRING)
+ ++stringfields;
+
+ return stringfields;
+}
+
+char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable)
+{
+
+ 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;
+ }
+
+ ++maxi;
+ records = maxi;
+ indexTable = new ptr[maxi];
+ memset(indexTable, 0, maxi * sizeof(ptr));
+ }
+ else
+ {
+ records = recordCount;
+ indexTable = new ptr[recordCount];
+ }
+
+ char* dataTable = new char[recordCount * 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 += 4;
+ break;
+ case FT_IND:
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = getRecord(y).getUInt(x);
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x);
+ offset += 1;
+ break;
+ case FT_STRING:
+ *((char**)(&dataTable[offset])) = NULL; // will be replaces non-empty or "" strings in AutoProduceStrings
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+
+ return dataTable;
+}
+
+static char const* const nullStr = "";
+
+char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* dataTable)
+{
+ if (strlen(format) != fieldCount)
+ return NULL;
+
+ // we store flat holders pool as single memory block
+ size_t stringFields = GetFormatStringsFields(format);
+ // each string field at load have array of string for each locale
+ size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
+ size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize;
+ size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * recordCount;
+
+ char* stringHoldersPool = new char[stringHoldersPoolSize];
+
+ // DB2 strings expected to have at least empty string
+ for (size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i)
+ ((char const**)stringHoldersPool)[i] = nullStr;
+
+ uint32 offset=0;
+
+ // assign string holders to string field slots
+ for (uint32 y = 0; y < recordCount; y++)
+ {
+ uint32 stringFieldNum = 0;
+
+ for(uint32 x = 0; x < fieldCount; x++)
+ switch(format[x])
+ {
+ case FT_FLOAT:
+ case FT_IND:
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_STRING:
+ {
+ // init db2 string field slots by pointers to string holders
+ char const*** slot = (char const***)(&dataTable[offset]);
+ *slot = (char const**)(&stringHoldersPool[stringHoldersRecordPoolSize * y + stringHolderSize*stringFieldNum]);
+ ++stringFieldNum;
+ offset += sizeof(char*);
+ break;
+ }
+ case FT_NA:
+ case FT_NA_BYTE:
+ case FT_SORT:
+ break;
+ default:
+ assert(false && "unknown format character");
+ }
+ }
+
+ //send as char* for store in char* pool list for free at unload
+ return stringHoldersPool;
+}
+
+char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable)
+{
+ if (strlen(format) != fieldCount)
+ return NULL;
+
+ // each string field at load have array of string for each locale
+ size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
+
+ 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:
+ case FT_IND:
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_STRING:
+ {
+ // fill only not filled entries
+ char** slot = (char**)(&dataTable[offset]);
+ if (**((char***)slot) == nullStr)
+ {
+ const char * st = getRecord(y).getString(x);
+ *slot=stringPool + (st-(const char*)stringTable);
+ }
+
+ offset+=sizeof(char*);
+ break;
+ }
+ }
+ }
+
+ return stringPool;
+} \ No newline at end of file
diff --git a/src/server/shared/DataStores/DB2FileLoader.h b/src/server/shared/DataStores/DB2FileLoader.h
new file mode 100644
index 00000000000..c30e33c29f6
--- /dev/null
+++ b/src/server/shared/DataStores/DB2FileLoader.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 DB2_FILE_LOADER_H
+#define DB2_FILE_LOADER_H
+
+#include "Define.h"
+#include "Utilities/ByteConverter.h"
+#include <cassert>
+
+class DB2FileLoader
+{
+ public:
+ DB2FileLoader();
+ ~DB2FileLoader();
+
+ 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(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);
+ /// Get begin iterator over records
+
+ uint32 GetNumRows() const { return recordCount;}
+ 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);
+ char* AutoProduceStringsArrayHolders(const char* fmt, char* dataTable);
+ char* AutoProduceStrings(const char* fmt, char* dataTable);
+ static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL);
+ static uint32 GetFormatStringsFields(const char * format);
+private:
+
+ uint32 recordSize;
+ uint32 recordCount;
+ uint32 fieldCount;
+ uint32 stringSize;
+ uint32 *fieldsOffset;
+ unsigned char *data;
+ unsigned char *stringTable;
+
+ // WDB2 / WCH2 fields
+ uint32 tableHash; // WDB2
+ uint32 build; // WDB2
+
+ int unk1; // WDB2 (Unix time in WCH2)
+ int unk2; // WDB2
+ int maxIndex; // WDB2 (index table)
+ int locale; // WDB2
+ int unk5; // WDB2
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h
new file mode 100644
index 00000000000..a90dba5d768
--- /dev/null
+++ b/src/server/shared/DataStores/DB2Store.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 DB2STORE_H
+#define DB2STORE_H
+
+#include "DB2FileLoader.h"
+#include "DB2fmt.h"
+#include "Logging/Log.h"
+#include "Field.h"
+#include "DatabaseWorkerPool.h"
+#include "Implementation/WorldDatabase.h"
+#include "DatabaseEnv.h"
+
+#include <vector>
+
+template<class T>
+class DB2Storage
+{
+ typedef std::list<char*> StringPoolList;
+ typedef std::vector<T*> DataTableEx;
+public:
+ explicit DB2Storage(const char *f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { }
+ ~DB2Storage() { Clear(); }
+
+ T const* LookupEntry(uint32 id) const { return (id>=nCount)?NULL:indexTable[id]; }
+ uint32 GetNumRows() const { return nCount; }
+ char const* GetFormat() const { return fmt; }
+ uint32 GetFieldCount() const { return fieldCount; }
+
+ /// Copies the provided entry and stores it.
+ void AddEntry(uint32 id, const T* entry)
+ {
+ if (LookupEntry(id))
+ return;
+
+ if (id >= nCount)
+ {
+ // reallocate index table
+ char** tmpIdxTable = new char*[id+1];
+ memset(tmpIdxTable, 0, (id+1) * sizeof(char*));
+ memcpy(tmpIdxTable, (char*)indexTable, nCount * sizeof(char*));
+ delete[] ((char*)indexTable);
+ nCount = id + 1;
+ indexTable = (T**)tmpIdxTable;
+ }
+
+ T* entryDst = new T;
+ memcpy((char*)entryDst, (char*)entry, sizeof(T));
+ m_dataTableEx.push_back(entryDst);
+ indexTable[id] = entryDst;
+ }
+
+ bool Load(char const* fn)
+ {
+ DB2FileLoader db2;
+ // Check if load was sucessful, only then continue
+ if (!db2.Load(fn, fmt))
+ return false;
+
+ fieldCount = db2.GetCols();
+
+ // load raw non-string data
+ m_dataTable = (T*)db2.AutoProduceData(fmt, nCount, (char**&)indexTable);
+
+ // create string holders for loaded string fields
+ m_stringPoolList.push_back(db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable));
+
+ // load strings from dbc data
+ m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable));
+
+ // error in dbc file at loading if NULL
+ return indexTable!=NULL;
+ }
+
+ bool LoadStringsFrom(char const* fn)
+ {
+ // DBC must be already loaded using Load
+ if (!indexTable)
+ return false;
+
+ DB2FileLoader db2;
+ // Check if load was successful, only then continue
+ if (!db2.Load(fn, fmt))
+ return false;
+
+ // load strings from another locale dbc data
+ m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable));
+
+ return true;
+ }
+
+ void Clear()
+ {
+ if (!indexTable)
+ return;
+
+ delete[] ((char*)indexTable);
+ indexTable = NULL;
+ delete[] ((char*)m_dataTable);
+ m_dataTable = NULL;
+ for (DataTableEx::const_iterator itr = m_dataTableEx.begin(); itr != m_dataTableEx.end(); ++itr)
+ delete *itr;
+ m_dataTableEx.clear();
+
+ while (!m_stringPoolList.empty())
+ {
+ delete[] m_stringPoolList.front();
+ m_stringPoolList.pop_front();
+ }
+ nCount = 0;
+ }
+
+ void EraseEntry(uint32 id) { indexTable[id] = NULL; }
+
+private:
+ uint32 nCount;
+ uint32 fieldCount;
+ uint32 recordSize;
+ char const* fmt;
+ T** indexTable;
+ T* m_dataTable;
+ DataTableEx m_dataTableEx;
+ StringPoolList m_stringPoolList;
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h
index b2d99e9302f..087827c184b 100755
--- a/src/server/shared/DataStores/DBCFileLoader.h
+++ b/src/server/shared/DataStores/DBCFileLoader.h
@@ -22,7 +22,7 @@
#include "Utilities/ByteConverter.h"
#include <cassert>
-enum
+/*enum
{
FT_NA='x', //not used or unknown, 4 byte size
FT_NA_BYTE='X', //not used or unknown, byte
@@ -35,7 +35,7 @@ enum
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 DBCFileLoader
{
diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h
index 42663fb6bd4..c590c3bf918 100755
--- a/src/server/shared/Define.h
+++ b/src/server/shared/Define.h
@@ -79,4 +79,21 @@ typedef ACE_UINT32 uint32;
typedef ACE_UINT16 uint16;
typedef ACE_UINT8 uint8;
+typedef char const* const* DBCString; //char* DBCStrings[MAX_LOCALE];
+typedef char const* const* DB2String; //char* DB2Strings[MAX_LOCALE];
+
+enum
+{
+ 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
+};
#endif //TRINITY_DEFINE_H
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index 15008f13c10..a83a7a46d0b 100755
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -986,6 +986,13 @@ void Log::outCharDump(const char * str, uint32 account_id, uint32 guid, const ch
}
}
+void Log::outOpCode(uint32 op, const char * name, bool smsg)
+{
+ if (!(m_DebugLogMask & LOG_FILTER_OPCODES))
+ return;
+ outString("%s: %s 0x%.4X (%u)", smsg ? "S->C" : "C->S", name, op, op);
+}
+
void Log::outRemote(const char * str, ...)
{
if (!str)
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index 5b2eb6aafb6..d17fbf2d4d4 100755
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -50,6 +50,7 @@ enum DebugLogFilters
LOG_FILTER_LOOT = 0x00100000, // Loot related
LOG_FILTER_GUILD = 0x00200000, // Guild related
LOG_FILTER_TRANSPORTS = 0x00400000, // Transport related
+ LOG_FILTER_OPCODES = 0x00800000, // OpCodes
};
enum LogTypes
@@ -137,6 +138,7 @@ class Log
void outArena( const char * str, ... ) ATTR_PRINTF(2, 3);
void outSQLDriver( const char* str, ... ) ATTR_PRINTF(2, 3);
void outCharDump( const char * str, uint32 account_id, uint32 guid, const char * name );
+ void outOpCode(uint32 op, const char * name, bool smsg = true);
static void outTimestamp(FILE* file);
static std::string GetTimestampStr();
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 08318aa7a5b..93a9aaa6d80 100755
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -51,19 +51,19 @@ class ByteBuffer
const static size_t DEFAULT_SIZE = 0x1000;
// constructor
- ByteBuffer(): _rpos(0), _wpos(0)
+ ByteBuffer(): _rpos(0), _wpos(0), _bitpos(8), _curbitval(0)
{
_storage.reserve(DEFAULT_SIZE);
}
// constructor
- ByteBuffer(size_t res): _rpos(0), _wpos(0)
+ ByteBuffer(size_t res): _rpos(0), _wpos(0), _bitpos(8), _curbitval(0)
{
_storage.reserve(res);
}
// copy constructor
- ByteBuffer(const ByteBuffer &buf): _rpos(buf._rpos), _wpos(buf._wpos), _storage(buf._storage) { }
+ ByteBuffer(const ByteBuffer &buf): _rpos(buf._rpos), _wpos(buf._wpos), _storage(buf._storage), _bitpos(buf._bitpos), _curbitval(buf._curbitval) { }
void clear()
{
@@ -73,10 +73,68 @@ class ByteBuffer
template <typename T> void append(T value)
{
+ flushBits();
EndianConvert(value);
append((uint8 *)&value, sizeof(value));
}
+ void flushBits()
+ {
+ if (_bitpos == 8)
+ return;
+
+ append((uint8 *)&_curbitval, sizeof(uint8));
+ _curbitval = 0;
+ _bitpos = 8;
+ }
+
+ bool writeBit(uint32 bit)
+ {
+ --_bitpos;
+ if (bit)
+ _curbitval |= (1 << (_bitpos));
+
+ if (_bitpos == 0)
+ {
+ _bitpos = 8;
+ append((uint8 *)&_curbitval, sizeof(_curbitval));
+ _curbitval = 0;
+ }
+
+ return (bit != 0);
+ }
+
+ bool readBit()
+ {
+ ++_bitpos;
+ if (_bitpos > 7)
+ {
+ _bitpos = 0;
+ _curbitval = read<uint8>();
+ }
+ bool bit = ((_curbitval >> (7-_bitpos)) & 1) != 0;
+ return bit;
+ }
+
+ template <typename T> void writeBits(T value, size_t bits)
+ {
+ for (int32 i = bits-1; i >= 0; --i)
+ writeBit((value >> i) & 1);
+ }
+
+ uint32 readBits(size_t bits)
+ {
+ uint32 value = 0;
+ for (int32 i = bits-1; i >= 0; --i)
+ {
+ if(readBit())
+ {
+ value |= (1 << (_bitpos));
+ }
+ }
+ return value;
+ }
+
template <typename T> void put(size_t pos, T value)
{
EndianConvert(value);
@@ -489,7 +547,8 @@ class ByteBuffer
}
protected:
- size_t _rpos, _wpos;
+ size_t _rpos, _wpos, _bitpos;
+ uint8 _curbitval;
std::vector<uint8> _storage;
};
diff --git a/src/server/shared/Packets/WorldPacket.h b/src/server/shared/Packets/WorldPacket.h
deleted file mode 100755
index c27801a8d58..00000000000
--- a/src/server/shared/Packets/WorldPacket.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2008-2011 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 TRINITYCORE_WORLDPACKET_H
-#define TRINITYCORE_WORLDPACKET_H
-
-#include "Common.h"
-#include "ByteBuffer.h"
-
-class WorldPacket : public ByteBuffer
-{
- public:
- // just container for later use
- WorldPacket() : ByteBuffer(0), m_opcode(0)
- {
- }
- explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { }
- // copy constructor
- WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
- {
- }
-
- void Initialize(uint16 opcode, size_t newres=200)
- {
- clear();
- _storage.reserve(newres);
- m_opcode = opcode;
- }
-
- uint16 GetOpcode() const { return m_opcode; }
- void SetOpcode(uint16 opcode) { m_opcode = opcode; }
-
- protected:
- uint16 m_opcode;
-};
-#endif
-