diff options
Diffstat (limited to 'src/server/shared')
19 files changed, 945 insertions, 125 deletions
diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index ad0e6dd6437..c86a6ee29ab 100755 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -116,7 +116,7 @@ #define I32FMT "%08I32X" #define I64FMT "%016I64X" #define snprintf _snprintf -#define atoll __atoi64 +#define atoll _atoi64 #define vsnprintf _vsnprintf #define finite(X) _finite(X) #define llabs _abs64 diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2FileLoader.cpp new file mode 100644 index 00000000000..14170845211 --- /dev/null +++ b/src/server/shared/DataStores/DB2FileLoader.cpp @@ -0,0 +1,408 @@ +/* + * 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; + + 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; +} 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..6ebca714fe6 --- /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 "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 (typename 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 eb8317fbefd..3d5c23dcb85 100755 --- a/src/server/shared/DataStores/DBCFileLoader.h +++ b/src/server/shared/DataStores/DBCFileLoader.h @@ -22,21 +22,6 @@ #include "Utilities/ByteConverter.h" #include <cassert> -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 -}; - class DBCFileLoader { public: diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h index 9965a5c1d71..0c502d3fd77 100755 --- a/src/server/shared/DataStores/DBCStore.h +++ b/src/server/shared/DataStores/DBCStore.h @@ -20,7 +20,7 @@ #define DBCSTORE_H #include "DBCFileLoader.h" -#include "Logging/Log.h" +#include "Log.h" #include "Field.h" #include "DatabaseWorkerPool.h" #include "Implementation/WorldDatabase.h" @@ -41,7 +41,7 @@ struct SqlDbc for (uint32 i = 0; i< sqlTableName.size(); ++i) { if (isalpha(sqlTableName[i])) - sqlTableName[i] = tolower(sqlTableName[i]); + sqlTableName[i] = char(tolower(sqlTableName[i])); else if (sqlTableName[i] == '.') sqlTableName[i] = '_'; } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp index d9b517c098f..c451af2ebd5 100644 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp @@ -38,8 +38,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_GUID_BY_NAME_FILTER, "SELECT guid, name FROM characters WHERE name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_SEL_BANINFO_LIST, "SELECT bandate, unbandate, bannedby, banreason FROM character_banned WHERE guid = ? ORDER BY unbandate", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_SEL_BANNED_NAME, "SELECT characters.name FROM characters, character_banned WHERE character_banned.guid = ? AND character_banned.guid = characters.guid", CONNECTION_SYNCH) - PREPARE_STATEMENT(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? ORDER BY c.guid", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? ORDER BY c.guid", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, c.slot FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, c.slot, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_PET_SLOTS, "SELECT owner, slot FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_PET_SLOTS_DETAIL, "SELECT owner, id, entry, level, name FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_SEL_PET_ENTRY, "SELECT entry FROM character_pet WHERE owner = ? AND id = ? AND slot >= ? AND slot <= ?", CONNECTION_ASYNC); @@ -64,9 +64,9 @@ void CharacterDatabaseConnection::DoPrepareStatements() // Start LoginQueryHolder content PREPARE_STATEMENT(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " - "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, " - "health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = ?", CONNECTION_ASYNC) + "resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " + "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " + "health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_AURAS, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, " @@ -97,7 +97,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, " "item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = ? ORDER BY setindex", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC) - PREPARE_STATEMENT(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, spec FROM character_talent WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC) @@ -161,7 +161,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() // 0: uint32, 1: uint8, 3: string, 4: uint32 PREPARE_STATEMENT(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, rname, rights) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_GUILD_RANKS, "DELETE FROM guild_rank WHERE guildid = ?", CONNECTION_ASYNC) // 0: uint32 - PREPARE_STATEMENT(CHAR_DEL_GUILD_LOWEST_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid >= ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 + PREPARE_STATEMENT(CHAR_DEL_GUILD_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_INS_GUILD_BANK_TAB, "INSERT INTO guild_bank_tab (guildid, TabId) VALUES (?, ?)", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_TAB, "DELETE FROM guild_bank_tab WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_DEL_GUILD_BANK_TABS, "DELETE FROM guild_bank_tab WHERE guildid = ?", CONNECTION_ASYNC) // 0: uint32 @@ -210,6 +210,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS3, "UPDATE guild_member SET BankRemSlotsTab3 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS4, "UPDATE guild_member SET BankRemSlotsTab4 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS5, "UPDATE guild_member SET BankRemSlotsTab5 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS6, "UPDATE guild_member SET BankRemSlotsTab6 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS7, "UPDATE guild_member SET BankRemSlotsTab7 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint32, 2: uint32, 3: uint32 PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS0, "UPDATE guild_member SET BankResetTimeTab0 = ?, BankRemSlotsTab0 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS1, "UPDATE guild_member SET BankResetTimeTab1 = ?, BankRemSlotsTab1 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) @@ -217,6 +219,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS3, "UPDATE guild_member SET BankResetTimeTab3 = ?, BankRemSlotsTab3 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS4, "UPDATE guild_member SET BankResetTimeTab4 = ?, BankRemSlotsTab4 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS5, "UPDATE guild_member SET BankResetTimeTab5 = ?, BankRemSlotsTab5 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS6, "UPDATE guild_member SET BankResetTimeTab6 = ?, BankRemSlotsTab6 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS7, "UPDATE guild_member SET BankResetTimeTab7 = ?, BankRemSlotsTab7 = ? WHERE guildid = ? AND guid = ?", CONNECTION_ASYNC) // 0: uint32, 1: uint8 PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME0, "UPDATE guild_member SET BankResetTimeTab0 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME1, "UPDATE guild_member SET BankResetTimeTab1 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) @@ -224,7 +228,21 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME3, "UPDATE guild_member SET BankResetTimeTab3 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME4, "UPDATE guild_member SET BankResetTimeTab4 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME5, "UPDATE guild_member SET BankResetTimeTab5 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME6, "UPDATE guild_member SET BankResetTimeTab6 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_UPD_GUILD_RANK_BANK_TIME7, "UPDATE guild_member SET BankResetTimeTab7 = 0 WHERE guildid = ? AND rank = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_DEL_GUILD_ACHIEVEMENT, "DELETE FROM guild_achievement WHERE guildId = ? AND achievement = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_INS_GUILD_ACHIEVEMENT, "INSERT INTO guild_achievement (guildId, achievement, date, guids) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ? AND criteria = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA, "INSERT INTO guild_achievement_progress (guildId, criteria, counter, date, completedGuid) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS, "DELETE FROM guild_achievement WHERE guildId = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT, "SELECT achievement, date, guids FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_UPD_GUILD_EXPERIENCE, "UPDATE guild SET level = ?, experience = ?, todayExperience = ? WHERE guildId = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, "UPDATE guild SET todayExperience = 0", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_LOAD_GUILD_NEWS, "SELECT id, eventType, playerGuid, data, flags, date FROM guild_news_log WHERE guild = ? ORDER BY guild ASC, id ASC", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SAVE_GUILD_NEWS, "INSERT INTO guild_news_log (guild, id, eventType, playerGuid, data, flags, date) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); // Chat channel handling PREPARE_STATEMENT(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH) @@ -243,6 +261,11 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_INS_AURA, "INSERT INTO character_aura (guid, caster_guid, item_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) " "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + // Currency + PREPARE_STATEMENT(CHAR_SEL_PLAYER_CURRENCY, "SELECT currency, week_count, total_count FROM character_currency WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_UPD_PLAYER_CURRENCY, "UPDATE character_currency SET week_count = ?, total_count = ? WHERE guid = ? AND currency = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_REP_PLAYER_CURRENCY, "REPLACE INTO character_currency (guid, currency, week_count, total_count) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); + // Account data PREPARE_STATEMENT(CHAR_SEL_ACCOUNT_DATA, "SELECT type, time, data FROM account_data WHERE accountId = ?", CONNECTION_SYNCH) PREPARE_STATEMENT(CHAR_REP_ACCOUNT_DATA, "REPLACE INTO account_data (accountId, type, time, data) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC) @@ -307,8 +330,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC) // Corpse - PREPARE_STATEMENT(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH) - PREPARE_STATEMENT(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH) + PREPARE_STATEMENT(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC) PREPARE_STATEMENT(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC) @@ -348,18 +371,18 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " "map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, " "taximask, cinematic, " - "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, " + "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, talentTree, " "extra_flags, stable_slots, at_login, zone, " - "death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, " - "todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, " - "power4, power5, power6, power7, latency, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); + "death_expire_time, taxi_path, totalKills, " + "todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, " + "power4, power5, latency, speccount, activespec, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES " + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?," "map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," - "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," - "arenaPoints=?,totalHonorPoints=?,todayHonorPoints=?,yesterdayHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,knownCurrencies=?," - "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,latency=?,speccount=?,activespec=?,exploredZones=?," - "equipmentCache=?,ammoId=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC); + "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,talentTree=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," + "totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?," + "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,latency=?,speccount=?,activespec=?,exploredZones=?," + "equipmentCache=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); @@ -446,14 +469,13 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_SEL_MAIL_ITEMS_BY_ENTRY, "SELECT mi.item_guid, m.sender, m.receiver, cs.account, cs.name, cr.account, cr.name FROM mail m INNER JOIN mail_items mi ON mi.mail_id = m.id INNER JOIN item_instance ii ON ii.guid = mi.item_guid INNER JOIN characters cs ON cs.guid = m.sender INNER JOIN characters cr ON cr.guid = m.receiver WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, "SELECT ah.itemguid, ah.itemowner, c.account, c.name FROM auctionhouse ah INNER JOIN characters c ON c.guid = ah.itemowner INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY, "SELECT gi.item_guid, gi.guildid, g.name FROM guild_bank_item gi INNER JOIN guild g ON g.guildid = gi.guildid INNER JOIN item_instance ii ON ii.guid = gi.item_guid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH); PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENT, "DELETE FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, "DELETE FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_ITEM_REFUND_INSTANCE, "DELETE FROM item_refund_instance WHERE item_guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_ITEM_REFUND_INSTANCE, "INSERT INTO item_refund_instance (item_guid, player_guid, paidMoney, paidExtendedCost) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_GROUP, "DELETE FROM groups WHERE guid = ?", CONNECTION_ASYNC); @@ -525,8 +547,6 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_DEL_CHAR_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_TALENT, "DELETE FROM character_talent WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_SKILLS, "DELETE FROM character_skills WHERE guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_UDP_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_UDP_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UDP_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_ACTION, "INSERT INTO character_action (guid, spec, button, action, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_UPD_CHAR_ACTION, "UPDATE character_action SET action = ?, type = ? WHERE guid = ? AND button = ? AND spec = ?", CONNECTION_ASYNC); @@ -543,14 +563,31 @@ void CharacterDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(CHAR_UDP_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs (guid, spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and spec = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(CHAR_UPD_CHAR_LIST_SLOT, "UPDATE characters SET slot = ? WHERE guid = ?", CONNECTION_ASYNC); + + // Void Storage + PREPARE_STATEMENT(CHAR_SEL_CHAR_VOID_STORAGE, "SELECT itemId, itemEntry, slot, creatorGuid, randomProperty, suffixFactor FROM character_void_storage WHERE playerGuid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_REP_CHAR_VOID_STORAGE_ITEM, "REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomProperty, suffixFactor) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC) + PREPARE_STATEMENT(CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT, "DELETE FROM character_void_storage WHERE slot = ? AND playerGuid = ?", CONNECTION_ASYNC); + + // CompactUnitFrame profiles + PREPARE_STATEMENT(CHAR_SEL_CHAR_CUF_PROFILES, "SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154 FROM character_cuf_profiles WHERE guid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_REP_CHAR_CUF_PROFILES, "REPLACE INTO character_cuf_profiles (guid, id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_CHAR_CUF_PROFILES, "DELETE FROM character_cuf_profiles WHERE guid = ? and id = ?", CONNECTION_ASYNC); + + // Guild Finder + PREPARE_STATEMENT(CHAR_REP_GUILD_FINDER_APPLICANT, "REPLACE INTO guild_finder_applicant (guildId, playerGuid, availability, classRole, interests, comment, submitTime) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_GUILD_FINDER_APPLICANT, "DELETE FROM guild_finder_applicant WHERE guildId = ? AND playerGuid = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_REP_GUILD_FINDER_GUILD_SETTINGS, "REPLACE INTO guild_finder_guild_settings (guildId, availability, classRoles, interests, level, listed, comment) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS, "DELETE FROM guild_finder_guild_settings WHERE guildId = ?", CONNECTION_ASYNC); } diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h index 88018997e4b..38f762a4a48 100644..100755 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ b/src/server/shared/Database/Implementation/CharacterDatabase.h @@ -166,7 +166,7 @@ enum CharacterDatabaseStatements CHAR_DEL_GUILD_MEMBERS, CHAR_INS_GUILD_RANK, CHAR_DEL_GUILD_RANKS, - CHAR_DEL_GUILD_LOWEST_RANK, + CHAR_DEL_GUILD_RANK, CHAR_INS_GUILD_BANK_TAB, CHAR_DEL_GUILD_BANK_TAB, CHAR_DEL_GUILD_BANK_TABS, @@ -207,19 +207,37 @@ enum CharacterDatabaseStatements CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS3, CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS4, CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS5, + CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS6, + CHAR_UPD_GUILD_MEMBER_BANK_TIME_REM_SLOTS7, CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS0, CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS1, CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS2, CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS3, CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS4, CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS5, + CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS6, + CHAR_UPD_GUILD_MEMBER_BANK_REM_SLOTS7, CHAR_UPD_GUILD_RANK_BANK_TIME0, CHAR_UPD_GUILD_RANK_BANK_TIME1, CHAR_UPD_GUILD_RANK_BANK_TIME2, CHAR_UPD_GUILD_RANK_BANK_TIME3, CHAR_UPD_GUILD_RANK_BANK_TIME4, CHAR_UPD_GUILD_RANK_BANK_TIME5, + CHAR_UPD_GUILD_RANK_BANK_TIME6, + CHAR_UPD_GUILD_RANK_BANK_TIME7, CHAR_SEL_CHAR_DATA_FOR_GUILD, + CHAR_DEL_GUILD_ACHIEVEMENT, + CHAR_INS_GUILD_ACHIEVEMENT, + CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, + CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA, + CHAR_DEL_ALL_GUILD_ACHIEVEMENTS, + CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, + CHAR_SEL_GUILD_ACHIEVEMENT, + CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, + CHAR_UPD_GUILD_EXPERIENCE, + CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, + CHAR_LOAD_GUILD_NEWS, + CHAR_SAVE_GUILD_NEWS, CHAR_SEL_CHANNEL, CHAR_INS_CHANNEL, @@ -234,6 +252,10 @@ enum CharacterDatabaseStatements CHAR_INS_AURA, + CHAR_SEL_PLAYER_CURRENCY, + CHAR_UPD_PLAYER_CURRENCY, + CHAR_REP_PLAYER_CURRENCY, + CHAR_SEL_ACCOUNT_DATA, CHAR_REP_ACCOUNT_DATA, CHAR_DEL_ACCOUNT_DATA, @@ -416,7 +438,6 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, CHAR_DEL_CHAR_REPUTATION_BY_FACTION, CHAR_INS_CHAR_REPUTATION_BY_FACTION, - CHAR_UPD_CHAR_ARENA_POINTS, CHAR_DEL_ITEM_REFUND_INSTANCE, CHAR_INS_ITEM_REFUND_INSTANCE, CHAR_DEL_GROUP, @@ -488,8 +509,6 @@ enum CharacterDatabaseStatements CHAR_DEL_CHAR_QUESTSTATUS_DAILY, CHAR_DEL_CHAR_TALENT, CHAR_DEL_CHAR_SKILLS, - CHAR_UDP_CHAR_HONOR_POINTS, - CHAR_UDP_CHAR_ARENA_POINTS, CHAR_UDP_CHAR_MONEY, CHAR_INS_CHAR_ACTION, CHAR_UPD_CHAR_ACTION, @@ -516,6 +535,20 @@ enum CharacterDatabaseStatements CHAR_INS_CHAR_TALENT, CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, + CHAR_UPD_CHAR_LIST_SLOT, + + CHAR_SEL_CHAR_VOID_STORAGE, + CHAR_REP_CHAR_VOID_STORAGE_ITEM, + CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT, + + CHAR_SEL_CHAR_CUF_PROFILES, + CHAR_REP_CHAR_CUF_PROFILES, + CHAR_DEL_CHAR_CUF_PROFILES, + + CHAR_REP_GUILD_FINDER_APPLICANT, + CHAR_DEL_GUILD_FINDER_APPLICANT, + CHAR_REP_GUILD_FINDER_GUILD_SETTINGS, + CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS, MAX_CHARACTERDATABASE_STATEMENTS }; diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp index c491852b1bd..95c888249cd 100755 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp @@ -34,9 +34,9 @@ void WorldDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(WORLD_DEL_GRAVEYARD_ZONE, "DELETE FROM game_graveyard_zone WHERE id = ? AND ghost_zone = ? AND faction = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_INS_GAME_TELE, "INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_DEL_GAME_TELE, "DELETE FROM game_tele WHERE name = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(WORLD_INS_NPC_VENODR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PREPARE_STATEMENT(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ?", CONNECTION_ASYNC); - PREPARE_STATEMENT(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry = ? ORDER BY slot ASC", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost, type) VALUES(?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ? AND type = ?", CONNECTION_ASYNC); + PREPARE_STATEMENT(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost, type FROM npc_vendor WHERE entry = ? AND type = ? ORDER BY slot ASC", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_UPD_CREATURE_MOVEMENT_TYPE, "UPDATE creature SET MovementType = ? WHERE guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_FACTION, "UPDATE creature_template SET faction_A = ?, faction_H = ? WHERE entry = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_NPCFLAG, "UPDATE creature_template SET npcflag = ? WHERE entry = ?", CONNECTION_ASYNC); @@ -78,7 +78,7 @@ void WorldDatabaseConnection::DoPrepareStatements() PREPARE_STATEMENT(WORLD_INS_CREATURE_TRANSPORT, "INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_UPD_CREATURE_TRANSPORT_EMOTE, "UPDATE creature_transport SET emote = ? WHERE transport_entry = ? AND guid = ?", CONNECTION_ASYNC); PREPARE_STATEMENT(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH); - PREPARE_STATEMENT(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); + PREPARE_STATEMENT(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH); PREPARE_STATEMENT(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h index 195d2ea8da5..31da84c5151 100755 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ b/src/server/shared/Database/Implementation/WorldDatabase.h @@ -54,7 +54,7 @@ enum WorldDatabaseStatements WORLD_DEL_GRAVEYARD_ZONE, WORLD_INS_GAME_TELE, WORLD_DEL_GAME_TELE, - WORLD_INS_NPC_VENODR, + WORLD_INS_NPC_VENDOR, WORLD_DEL_NPC_VENDOR, WORLD_SEL_NPC_VENDOR_REF, WORLD_UPD_CREATURE_MOVEMENT_TYPE, diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp index 21aef0f1834..76dc7206bd7 100755 --- a/src/server/shared/Database/PreparedStatement.cpp +++ b/src/server/shared/Database/PreparedStatement.cpp @@ -230,11 +230,16 @@ void MySQLPreparedStatement::ClearParameters() } } +static bool ParementerIndexAssertFail(uint32 stmtIndex, uint8 index, uint32 paramCount) +{ + sLog->outError(LOG_FILTER_SQL_DRIVER, "Attempted to bind parameter %u%s on a PreparedStatement %u (statement has only %u parameters)", uint32(index) + 1, (index == 1 ? "st" : (index == 2 ? "nd" : (index == 3 ? "rd" : "nd"))), stmtIndex, paramCount); + return false; +} + //- Bind on mysql level bool MySQLPreparedStatement::CheckValidIndex(uint8 index) { - if (index >= m_paramCount) - return false; + ASSERT(index < m_paramCount || ParementerIndexAssertFail(m_stmt->m_index, index, m_paramCount)); if (m_paramsSet[index]) sLog->outWarn(LOG_FILTER_SQL, "[WARNING] Prepared Statement (id: %u) trying to bind value on already bound index (%u).", m_stmt->m_index, index); diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h index 0f7c2163b7e..6958634b8ea 100755 --- a/src/server/shared/Define.h +++ b/src/server/shared/Define.h @@ -87,4 +87,18 @@ typedef ACE_UINT32 uint32; typedef ACE_UINT16 uint16; typedef ACE_UINT8 uint8; +enum DBCFormer +{ + 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/Appender.h b/src/server/shared/Logging/Appender.h index 5c4b009ef67..a4f980b30fe 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -30,7 +30,7 @@ enum LogFilterType LOG_FILTER_PETS, LOG_FILTER_VEHICLES, LOG_FILTER_TSCR, // C++ AI, instance scripts, etc. - LOG_FILTER_DATABASE_AI, // SmartAI, EventAI, Creature* * AI + LOG_FILTER_DATABASE_AI, // SmartAI, Creature* * AI LOG_FILTER_MAPSCRIPTS, LOG_FILTER_NETWORKIO, LOG_FILTER_SPELLS_AURAS, diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 4538fc75c1e..4538fc75c1e 100755..100644 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index b66e774b527..b66e774b527 100755..100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 1fa3148504a..e1e0a62db01 100755 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -21,9 +21,11 @@ #include "Common.h" #include "Debugging/Errors.h" -#include "Logging/Log.h" +#include "Log.h" #include "Utilities/ByteConverter.h" + + class ByteBufferException { public: @@ -52,7 +54,7 @@ class ByteBufferPositionException : public ByteBufferException { ACE_Stack_Trace trace; - sLog->outError(LOG_FILTER_GENERAL, "Attempted to %s value with size: "SIZEFMTD" in ByteBuffer (pos: " SIZEFMTD " size: "SIZEFMTD")\n[Stacktrace: %s]" , + sLog->outError(LOG_FILTER_GENERAL, "Attempted to %s value with size: "SIZEFMTD" in ByteBuffer (pos: " SIZEFMTD " size: "SIZEFMTD")\n[Stack trace: %s]" , (_add ? "put" : "get"), ValueSize, Pos, Size, trace.c_str()); } @@ -74,7 +76,7 @@ class ByteBufferSourceException : public ByteBufferException { ACE_Stack_Trace trace; - sLog->outError(LOG_FILTER_GENERAL, "Attempted to put a %s in ByteBuffer (pos: "SIZEFMTD" size: "SIZEFMTD")\n[Stacktrace: %s]", + sLog->outError(LOG_FILTER_GENERAL, "Attempted to put a %s in ByteBuffer (pos: "SIZEFMTD" size: "SIZEFMTD")\n[Stack trace: %s]", (ValueSize > 0 ? "NULL-pointer" : "zero-sized value"), Pos, Size, trace.c_str()); } }; @@ -85,19 +87,21 @@ 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 reserve) : _rpos(0), _wpos(0), _bitpos(8), _curbitval(0) { - _storage.reserve(res); + _storage.reserve(reserve); } // 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), + _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(buf._storage) + { + } void clear() { @@ -107,16 +111,115 @@ 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>(); + } + + return ((_curbitval >> (7-_bitpos)) & 1) != 0; + } + + 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 << (i)); + + return value; + } + + // Reads a byte (if needed) in-place + void ReadByteSeq(uint8& b) + { + if (b != 0) + b ^= read<uint8>(); + } + + void WriteByteSeq(uint8 b) + { + if (b != 0) + append<uint8>(b ^ 1); + } + template <typename T> void put(size_t pos, T value) { EndianConvert(value); put(pos, (uint8 *)&value, sizeof(value)); } + /** + * @name PutBits + * @brief Places specified amount of bits of value at specified position in packet. + * To ensure all bits are correctly written, only call this method after + * bit flush has been performed + + * @param pos Position to place the value at, in bits. The entire value must fit in the packet + * It is advised to obtain the position using bitwpos() function. + + * @param value Data to write. + * @param bitCount Number of bits to store the value on. + */ + template <typename T> void PutBits(size_t pos, T value, uint32 bitCount) + { + if (!bitCount) + throw ByteBufferSourceException((pos + bitCount) / 8, size(), 0); + + if (pos + bitCount > size() * 8) + throw ByteBufferPositionException(false, (pos + bitCount) / 8, size(), (bitCount - 1) / 8 + 1); + + for (uint32 i = 0; i < bitCount; ++i) + { + size_t wp = (pos + i) / 8; + size_t bit = (pos + i) % 8; + if ((value >> (bitCount - i - 1)) & 1) + _storage[wp] |= 1 << (7 - bit); + else + _storage[wp] &= ~(1 << (7 - bit)); + } + } + ByteBuffer &operator<<(uint8 value) { append<uint8>(value); @@ -275,9 +378,18 @@ class ByteBuffer return *this; } - uint8 operator[](size_t pos) const + uint8& operator[](size_t const pos) { - return read<uint8>(pos); + if (pos >= size()) + throw ByteBufferPositionException(false, pos, 1, size()); + return _storage[pos]; + } + + uint8 const& operator[](size_t const pos) const + { + if (pos >= size()) + throw ByteBufferPositionException(false, pos, 1, size()); + return _storage[pos]; } size_t rpos() const { return _rpos; } @@ -301,6 +413,16 @@ class ByteBuffer return _wpos; } + /// Returns position of last written bit + size_t bitwpos() const { return _wpos * 8 + 8 - _bitpos; } + + size_t bitwpos(size_t newPos) + { + _wpos = newPos / 8; + _bitpos = 8 - (newPos % 8); + return _wpos * 8 + 8 - _bitpos; + } + template<typename T> void read_skip() { read_skip(sizeof(T)); } @@ -359,6 +481,26 @@ class ByteBuffer } } + std::string ReadString(uint32 length) + { + if (!length) + return std::string(); + char* buffer = new char[length + 1]; + memset(buffer, 0, length + 1); + read((uint8*)buffer, length); + std::string retval = buffer; + delete[] buffer; + return retval; + } + + //! Method for writing strings that have their length sent separately in packet + //! without null-terminating the string + void WriteString(std::string const& str) + { + if (size_t len = str.length()) + append(str.c_str(), len); + } + uint32 ReadPackedTime() { uint32 packedDate = read<uint32>(); @@ -541,7 +683,8 @@ class ByteBuffer } protected: - size_t _rpos, _wpos; + size_t _rpos, _wpos, _bitpos; + uint8 _curbitval; std::vector<uint8> _storage; }; @@ -624,7 +767,6 @@ inline ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m) return b; } -// TODO: Make a ByteBuffer.cpp and move all this inlining to it. template<> inline std::string ByteBuffer::read<std::string>() { std::string tmp; @@ -650,5 +792,6 @@ inline void ByteBuffer::read_skip<std::string>() { read_skip<char*>(); } + #endif diff --git a/src/server/shared/Packets/WorldPacket.h b/src/server/shared/Packets/WorldPacket.h deleted file mode 100755 index 7ab95bc496d..00000000000 --- a/src/server/shared/Packets/WorldPacket.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2008-2012 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 - diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index 407d0704619..b3176beb50b 100755 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -150,9 +150,9 @@ std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly) return ss.str(); } -int32 MoneyStringToMoney(const std::string& moneyString) +int64 MoneyStringToMoney(const std::string& moneyString) { - int32 money = 0; + int64 money = 0; if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 || std::count(moneyString.begin(), moneyString.end(), 's') == 1 || @@ -169,7 +169,7 @@ int32 MoneyStringToMoney(const std::string& moneyString) if (gCount + sCount + cCount != 1) return 0; - uint32 amount = atoi(*itr); + uint64 amount = atol(*itr); if (gCount == 1) money += amount * 100 * 100; else if (sCount == 1) diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index f46fc991cc7..949fa67008f 100755 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -66,7 +66,7 @@ private: void stripLineInvisibleChars(std::string &src); -int32 MoneyStringToMoney(const std::string& moneyString); +int64 MoneyStringToMoney(const std::string& moneyString); std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false); uint32 TimeStringToSecs(const std::string& timestring); |