aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared')
-rw-r--r--src/server/shared/Common.h17
-rw-r--r--src/server/shared/Cryptography/Authentication/PacketCrypt.cpp39
-rw-r--r--src/server/shared/Cryptography/Authentication/PacketCrypt.h (renamed from src/server/shared/Cryptography/Authentication/AuthCrypt.h)21
-rw-r--r--src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp (renamed from src/server/shared/Cryptography/Authentication/AuthCrypt.cpp)38
-rw-r--r--src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h34
-rw-r--r--src/server/shared/Cryptography/BigNumber.cpp14
-rw-r--r--src/server/shared/Cryptography/BigNumber.h5
-rw-r--r--src/server/shared/Cryptography/HMACSHA1.cpp57
-rw-r--r--src/server/shared/Cryptography/HmacHash.cpp66
-rw-r--r--src/server/shared/Cryptography/HmacHash.h (renamed from src/server/shared/Cryptography/HMACSHA1.h)22
-rw-r--r--src/server/shared/Cryptography/SHA256.cpp67
-rw-r--r--src/server/shared/Cryptography/SHA256.h49
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.cpp408
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.h107
-rw-r--r--src/server/shared/DataStores/DB2Store.h233
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.cpp23
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.h30
-rw-r--r--src/server/shared/DataStores/DBCStore.h10
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp96
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h35
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.cpp28
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.h23
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.cpp8
-rw-r--r--src/server/shared/Define.h15
-rw-r--r--src/server/shared/Packets/ByteBuffer.cpp3
-rw-r--r--src/server/shared/Packets/ByteBuffer.h146
-rw-r--r--src/server/shared/Packets/WorldPacket.h70
-rw-r--r--src/server/shared/Utilities/Util.cpp42
-rw-r--r--src/server/shared/Utilities/Util.h4
29 files changed, 1443 insertions, 267 deletions
diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h
index 27e6cb63514..4e23b4a4770 100644
--- a/src/server/shared/Common.h
+++ b/src/server/shared/Common.h
@@ -126,6 +126,23 @@ LocaleConstant GetLocaleByName(const std::string& name);
typedef std::vector<std::string> StringVector;
+#if defined(__GNUC__)
+#pragma pack(1)
+#else
+#pragma pack(push, 1)
+#endif
+
+struct LocalizedString
+{
+ char const* Str[TOTAL_LOCALES];
+};
+
+#if defined(__GNUC__)
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
// we always use stdlibc++ std::max/std::min, undefine some not C++ standard defines (Win API and some other platforms)
#ifdef max
#undef max
diff --git a/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp b/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp
new file mode 100644
index 00000000000..7fac311b8a2
--- /dev/null
+++ b/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PacketCrypt.h"
+
+PacketCrypt::PacketCrypt(uint32 rc4InitSize)
+ : _clientDecrypt(rc4InitSize), _serverEncrypt(rc4InitSize), _initialized(false)
+{
+}
+
+void PacketCrypt::DecryptRecv(uint8* data, size_t len)
+{
+ if (!_initialized)
+ return;
+
+ _clientDecrypt.UpdateData(len, data);
+}
+
+void PacketCrypt::EncryptSend(uint8* data, size_t len)
+{
+ if (!_initialized)
+ return;
+
+ _serverEncrypt.UpdateData(len, data);
+}
diff --git a/src/server/shared/Cryptography/Authentication/AuthCrypt.h b/src/server/shared/Cryptography/Authentication/PacketCrypt.h
index 8fa150068a2..36f3b81fb53 100644
--- a/src/server/shared/Cryptography/Authentication/AuthCrypt.h
+++ b/src/server/shared/Cryptography/Authentication/PacketCrypt.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 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
@@ -16,27 +15,29 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _AUTHCRYPT_H
-#define _AUTHCRYPT_H
+#ifndef _PACKETCRYPT_H
+#define _PACKETCRYPT_H
#include "Cryptography/ARC4.h"
class BigNumber;
-class AuthCrypt
+class PacketCrypt
{
public:
- AuthCrypt();
+ PacketCrypt(uint32 rc4InitSize);
+ virtual ~PacketCrypt() { }
- void Init(BigNumber* K);
- void DecryptRecv(uint8 *, size_t);
- void EncryptSend(uint8 *, size_t);
+ virtual void Init(BigNumber* K) = 0;
+ void DecryptRecv(uint8* data, size_t length);
+ void EncryptSend(uint8* data, size_t length);
bool IsInitialized() const { return _initialized; }
- private:
+ protected:
ARC4 _clientDecrypt;
ARC4 _serverEncrypt;
bool _initialized;
};
-#endif
+
+#endif // _PACKETCRYPT_H
diff --git a/src/server/shared/Cryptography/Authentication/AuthCrypt.cpp b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp
index ec8913ba1bc..b9d9b86005c 100644
--- a/src/server/shared/Cryptography/Authentication/AuthCrypt.cpp
+++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp
@@ -16,60 +16,38 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "AuthCrypt.h"
-#include "Cryptography/HMACSHA1.h"
+#include "WorldPacketCrypt.h"
+#include "Cryptography/HmacHash.h"
#include "Cryptography/BigNumber.h"
#include <cstring>
-AuthCrypt::AuthCrypt() :
- _clientDecrypt(SHA_DIGEST_LENGTH), _serverEncrypt(SHA_DIGEST_LENGTH),
- _initialized(false)
-{ }
+WorldPacketCrypt::WorldPacketCrypt() : PacketCrypt(SHA_DIGEST_LENGTH)
+{
+}
-void AuthCrypt::Init(BigNumber* K)
+void WorldPacketCrypt::Init(BigNumber* K)
{
uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
- HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
+ HmacSha1 serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
- HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
+ HmacSha1 clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
- //ARC4 _serverDecrypt(encryptHash);
_clientDecrypt.Init(decryptHash);
_serverEncrypt.Init(encryptHash);
- //ARC4 _clientEncrypt(decryptHash);
// Drop first 1024 bytes, as WoW uses ARC4-drop1024.
uint8 syncBuf[1024];
memset(syncBuf, 0, 1024);
_serverEncrypt.UpdateData(1024, syncBuf);
- //_clientEncrypt.UpdateData(1024, syncBuf);
memset(syncBuf, 0, 1024);
- //_serverDecrypt.UpdateData(1024, syncBuf);
_clientDecrypt.UpdateData(1024, syncBuf);
_initialized = true;
}
-
-void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
-{
- if (!_initialized)
- return;
-
- _clientDecrypt.UpdateData(len, data);
-}
-
-void AuthCrypt::EncryptSend(uint8 *data, size_t len)
-{
- if (!_initialized)
- return;
-
- _serverEncrypt.UpdateData(len, data);
-}
-
diff --git a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h
new file mode 100644
index 00000000000..7ccca11f09d
--- /dev/null
+++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008-2014 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 _WORLDPACKETCRYPT_H
+#define _WORLDPACKETCRYPT_H
+
+#include "PacketCrypt.h"
+
+class BigNumber;
+
+class WorldPacketCrypt : public PacketCrypt
+{
+ public:
+ WorldPacketCrypt();
+
+ void Init(BigNumber* K) override;
+};
+
+#endif // _WORLDPACKETCRYPT_H
diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp
index 1319e116159..b68c91001ae 100644
--- a/src/server/shared/Cryptography/BigNumber.cpp
+++ b/src/server/shared/Cryptography/BigNumber.cpp
@@ -189,13 +189,19 @@ std::unique_ptr<uint8[]> BigNumber::AsByteArray(int32 minSize, bool littleEndian
return ret;
}
-char * BigNumber::AsHexStr() const
+std::string BigNumber::AsHexStr() const
{
- return BN_bn2hex(_bn);
+ char* ch = BN_bn2hex(_bn);
+ std::string ret = ch;
+ OPENSSL_free(ch);
+ return ret;
}
-char * BigNumber::AsDecStr() const
+std::string BigNumber::AsDecStr() const
{
- return BN_bn2dec(_bn);
+ char* ch = BN_bn2dec(_bn);
+ std::string ret = ch;
+ OPENSSL_free(ch);
+ return ret;
}
diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h
index 684a25e8801..df19ba60b71 100644
--- a/src/server/shared/Cryptography/BigNumber.h
+++ b/src/server/shared/Cryptography/BigNumber.h
@@ -21,6 +21,7 @@
#include <memory>
#include "Define.h"
+#include <string>
struct bignum_st;
@@ -89,8 +90,8 @@ class BigNumber
std::unique_ptr<uint8[]> AsByteArray(int32 minSize = 0, bool littleEndian = true);
- char * AsHexStr() const;
- char * AsDecStr() const;
+ std::string AsHexStr() const;
+ std::string AsDecStr() const;
private:
struct bignum_st *_bn;
diff --git a/src/server/shared/Cryptography/HMACSHA1.cpp b/src/server/shared/Cryptography/HMACSHA1.cpp
deleted file mode 100644
index 2148a3b8a7b..00000000000
--- a/src/server/shared/Cryptography/HMACSHA1.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "HMACSHA1.h"
-#include "BigNumber.h"
-#include "Common.h"
-
-HmacHash::HmacHash(uint32 len, uint8 *seed)
-{
- HMAC_CTX_init(&m_ctx);
- HMAC_Init_ex(&m_ctx, seed, len, EVP_sha1(), NULL);
- memset(m_digest, 0, sizeof(m_digest));
-}
-
-HmacHash::~HmacHash()
-{
- HMAC_CTX_cleanup(&m_ctx);
-}
-
-void HmacHash::UpdateData(const std::string &str)
-{
- HMAC_Update(&m_ctx, (uint8 const*)str.c_str(), str.length());
-}
-
-void HmacHash::UpdateData(const uint8* data, size_t len)
-{
- HMAC_Update(&m_ctx, data, len);
-}
-
-void HmacHash::Finalize()
-{
- uint32 length = 0;
- HMAC_Final(&m_ctx, (uint8*)m_digest, &length);
- ASSERT(length == SHA_DIGEST_LENGTH);
-}
-
-uint8 *HmacHash::ComputeHash(BigNumber* bn)
-{
- HMAC_Update(&m_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
- Finalize();
- return (uint8*)m_digest;
-}
diff --git a/src/server/shared/Cryptography/HmacHash.cpp b/src/server/shared/Cryptography/HmacHash.cpp
new file mode 100644
index 00000000000..2913b9fa79a
--- /dev/null
+++ b/src/server/shared/Cryptography/HmacHash.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "HmacHash.h"
+#include "BigNumber.h"
+#include "Common.h"
+
+template<HashCreateFn HashCreator, uint32 DigestLength>
+HmacHash<HashCreator, DigestLength>::HmacHash(uint32 len, uint8 *seed)
+{
+ HMAC_CTX_init(&_ctx);
+ HMAC_Init_ex(&_ctx, seed, len, HashCreator(), NULL);
+ memset(_digest, 0, DigestLength);
+}
+
+template<HashCreateFn HashCreator, uint32 DigestLength>
+HmacHash<HashCreator, DigestLength>::~HmacHash()
+{
+ HMAC_CTX_cleanup(&_ctx);
+}
+
+template<HashCreateFn HashCreator, uint32 DigestLength>
+void HmacHash<HashCreator, DigestLength>::UpdateData(const std::string &str)
+{
+ HMAC_Update(&_ctx, (uint8 const*)str.c_str(), str.length());
+}
+
+template<HashCreateFn HashCreator, uint32 DigestLength>
+void HmacHash<HashCreator, DigestLength>::UpdateData(const uint8* data, size_t len)
+{
+ HMAC_Update(&_ctx, data, len);
+}
+
+template<HashCreateFn HashCreator, uint32 DigestLength>
+void HmacHash<HashCreator, DigestLength>::Finalize()
+{
+ uint32 length = 0;
+ HMAC_Final(&_ctx, _digest, &length);
+ ASSERT(length == DigestLength);
+}
+
+template<HashCreateFn HashCreator, uint32 DigestLength>
+uint8* HmacHash<HashCreator, DigestLength>::ComputeHash(BigNumber* bn)
+{
+ HMAC_Update(&_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
+ Finalize();
+ return _digest;
+}
+
+template class HmacHash<EVP_sha1, SHA_DIGEST_LENGTH>;
+template class HmacHash<EVP_sha256, SHA256_DIGEST_LENGTH>;
diff --git a/src/server/shared/Cryptography/HMACSHA1.h b/src/server/shared/Cryptography/HmacHash.h
index de1556d3c98..56ee55edda2 100644
--- a/src/server/shared/Cryptography/HMACSHA1.h
+++ b/src/server/shared/Cryptography/HmacHash.h
@@ -28,20 +28,26 @@ class BigNumber;
#define SEED_KEY_SIZE 16
+typedef EVP_MD const* (*HashCreateFn)();
+
+template<HashCreateFn HashCreator, uint32 DigestLength>
class HmacHash
{
public:
HmacHash(uint32 len, uint8 *seed);
~HmacHash();
- void UpdateData(const std::string &str);
- void UpdateData(const uint8* data, size_t len);
+ void UpdateData(std::string const& str);
+ void UpdateData(uint8 const* data, size_t len);
void Finalize();
- uint8 *ComputeHash(BigNumber* bn);
- uint8 *GetDigest() { return (uint8*)m_digest; }
- int GetLength() const { return SHA_DIGEST_LENGTH; }
+ uint8* ComputeHash(BigNumber* bn);
+ uint8* GetDigest() { return _digest; }
+ uint32 GetLength() const { return DigestLength; }
private:
- HMAC_CTX m_ctx;
- uint8 m_digest[SHA_DIGEST_LENGTH];
+ HMAC_CTX _ctx;
+ uint8 _digest[DigestLength];
};
-#endif
+typedef HmacHash<EVP_sha1, SHA_DIGEST_LENGTH> HmacSha1;
+typedef HmacHash<EVP_sha256, SHA256_DIGEST_LENGTH> HmacSha256;
+
+#endif
diff --git a/src/server/shared/Cryptography/SHA256.cpp b/src/server/shared/Cryptography/SHA256.cpp
new file mode 100644
index 00000000000..c562e90f29f
--- /dev/null
+++ b/src/server/shared/Cryptography/SHA256.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "SHA256.h"
+#include "BigNumber.h"
+#include <cstring>
+#include <stdarg.h>
+
+SHA256Hash::SHA256Hash()
+{
+ SHA256_Init(&mC);
+ memset(mDigest, 0, SHA256_DIGEST_LENGTH * sizeof(uint8));
+}
+
+SHA256Hash::~SHA256Hash()
+{
+ SHA256_Init(&mC);
+}
+
+void SHA256Hash::UpdateData(const uint8 *dta, int len)
+{
+ SHA256_Update(&mC, dta, len);
+}
+
+void SHA256Hash::UpdateData(const std::string &str)
+{
+ UpdateData((uint8 const*)str.c_str(), str.length());
+}
+
+void SHA256Hash::UpdateBigNumbers(BigNumber* bn0, ...)
+{
+ va_list v;
+ BigNumber* bn;
+
+ va_start(v, bn0);
+ bn = bn0;
+ while (bn)
+ {
+ UpdateData(bn->AsByteArray().get(), bn->GetNumBytes());
+ bn = va_arg(v, BigNumber*);
+ }
+ va_end(v);
+}
+
+void SHA256Hash::Initialize()
+{
+ SHA256_Init(&mC);
+}
+
+void SHA256Hash::Finalize(void)
+{
+ SHA256_Final(mDigest, &mC);
+}
diff --git a/src/server/shared/Cryptography/SHA256.h b/src/server/shared/Cryptography/SHA256.h
new file mode 100644
index 00000000000..78b3666dca8
--- /dev/null
+++ b/src/server/shared/Cryptography/SHA256.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SHA256_h__
+#define SHA256_h__
+
+#include "Define.h"
+#include <string>
+#include <openssl/sha.h>
+
+class BigNumber;
+
+class SHA256Hash
+{
+ public:
+ SHA256Hash();
+ ~SHA256Hash();
+
+ void UpdateBigNumbers(BigNumber* bn0, ...);
+
+ void UpdateData(const uint8 *dta, int len);
+ void UpdateData(const std::string &str);
+
+ void Initialize();
+ void Finalize();
+
+ uint8 *GetDigest(void) { return mDigest; };
+ int GetLength(void) const { return SHA256_DIGEST_LENGTH; };
+
+ private:
+ SHA256_CTX mC;
+ uint8 mDigest[SHA256_DIGEST_LENGTH];
+};
+
+#endif // SHA256_h__
diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2FileLoader.cpp
new file mode 100644
index 00000000000..7a27072dd20
--- /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)
+{
+ if (data)
+ {
+ delete [] data;
+ data = NULL;
+ }
+
+ FILE* f = fopen(filename, "rb");
+ if (!f)
+ return false;
+
+ uint32 header;
+ 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(&minIndex, 4, 1, f) != 1) // MinIndex WDB2
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(minIndex);
+
+ 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 - minIndex + 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, uint32 locale)
+{
+ 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
+ LocalizedString* db2str = *(LocalizedString**)(&dataTable[offset]);
+ if (db2str->Str[locale] == nullStr)
+ {
+ const char * st = getRecord(y).getString(x);
+ db2str->Str[locale] = 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..86350ebf1d6
--- /dev/null
+++ b/src/server/shared/DataStores/DB2FileLoader.h
@@ -0,0 +1,107 @@
+/*
+ * 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; }
+ uint32 GetHash() const { return tableHash; }
+ 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, uint32 locale);
+ 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 minIndex; // 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..77d6c4144e5
--- /dev/null
+++ b/src/server/shared/DataStores/DB2Store.h
@@ -0,0 +1,233 @@
+/*
+ * 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 "Common.h"
+#include "ByteBuffer.h"
+#include <vector>
+
+/// Interface class for common access
+class DB2StorageBase
+{
+public:
+ virtual ~DB2StorageBase() { }
+
+ uint32 GetHash() const { return tableHash; }
+
+ virtual bool HasRecord(uint32 id) const = 0;
+
+ virtual void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const = 0;
+
+protected:
+ uint32 tableHash;
+};
+
+template<class T>
+class DB2Storage;
+
+template<class T>
+bool DB2StorageHasEntry(DB2Storage<T> const& store, uint32 id)
+{
+ return store.LookupEntry(id) != NULL;
+}
+
+template<class T>
+void WriteDB2RecordToPacket(DB2Storage<T> const& store, uint32 id, uint32 locale, ByteBuffer& buffer)
+{
+ uint8 const* entry = (uint8 const*)store.LookupEntry(id);
+ ASSERT(entry);
+
+ std::string format = store.GetFormat();
+ for (uint32 i = 0; i < format.length(); ++i)
+ {
+ switch (format[i])
+ {
+ case FT_IND:
+ case FT_INT:
+ buffer << *(uint32*)entry;
+ entry += 4;
+ break;
+ case FT_FLOAT:
+ buffer << *(float*)entry;
+ entry += 4;
+ break;
+ case FT_BYTE:
+ buffer << *(uint8*)entry;
+ entry += 1;
+ break;
+ case FT_STRING:
+ {
+ LocalizedString* locStr = *(LocalizedString**)entry;
+ if (locStr->Str[locale][0] == '\0')
+ locale = 0;
+
+ char const* str = locStr->Str[locale];
+ size_t len = strlen(str);
+ buffer << uint16(len);
+ if (len)
+ buffer << str;
+ entry += sizeof(char*);
+ break;
+ }
+ case FT_NA:
+ case FT_SORT:
+ buffer << uint32(0);
+ break;
+ case FT_NA_BYTE:
+ buffer << uint8(0);
+ break;
+ }
+ }
+}
+
+template<class T>
+class DB2Storage : public DB2StorageBase
+{
+ typedef std::list<char*> StringPoolList;
+ typedef std::vector<T*> DataTableEx;
+ typedef bool(*EntryChecker)(DB2Storage<T> const&, uint32);
+ typedef void(*PacketWriter)(DB2Storage<T> const&, uint32, uint32, ByteBuffer&);
+public:
+ DB2Storage(char const* f, EntryChecker checkEntry = NULL, PacketWriter writePacket = NULL) :
+ nCount(0), fieldCount(0), fmt(f), m_dataTable(NULL)
+ {
+ indexTable.asT = NULL;
+ CheckEntry = checkEntry ? checkEntry : (EntryChecker)&DB2StorageHasEntry<T>;
+ WritePacket = writePacket ? writePacket : (PacketWriter)&WriteDB2RecordToPacket<T>;
+ }
+
+ ~DB2Storage() { Clear(); }
+
+ bool HasRecord(uint32 id) const { return CheckEntry(*this, id); }
+ T const* LookupEntry(uint32 id) const { return (id >= nCount) ? NULL : indexTable.asT[id]; }
+ uint32 GetNumRows() const { return nCount; }
+ char const* GetFormat() const { return fmt; }
+ uint32 GetFieldCount() const { return fieldCount; }
+ void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const
+ {
+ WritePacket(*this, id, locale, buffer);
+ }
+
+ T* CreateEntry(uint32 id, bool evenIfExists = false)
+ {
+ if (evenIfExists && LookupEntry(id))
+ return NULL;
+
+ if (id >= nCount)
+ {
+ // reallocate index table
+ char** tmpIdxTable = new char*[id + 1];
+ memset(tmpIdxTable, 0, (id + 1) * sizeof(char*));
+ memcpy(tmpIdxTable, indexTable.asChar, nCount * sizeof(char*));
+ delete[] reinterpret_cast<char*>(indexTable.asT);
+ nCount = id + 1;
+ indexTable.asChar = tmpIdxTable;
+ }
+
+ T* entryDst = new T;
+ m_dataTableEx.push_back(entryDst);
+ indexTable.asT[id] = entryDst;
+ return entryDst;
+ }
+
+ void EraseEntry(uint32 id) { indexTable.asT[id] = NULL; }
+
+ bool Load(char const* fn, uint32 locale)
+ {
+ DB2FileLoader db2;
+ // Check if load was sucessful, only then continue
+ if (!db2.Load(fn, fmt))
+ return false;
+
+ fieldCount = db2.GetCols();
+ tableHash = db2.GetHash();
+
+ // load raw non-string data
+ m_dataTable = reinterpret_cast<T*>(db2.AutoProduceData(fmt, nCount, indexTable.asChar));
+
+ // 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, locale));
+
+ // error in dbc file at loading if NULL
+ return indexTable.asT != NULL;
+ }
+
+ bool LoadStringsFrom(char const* fn, uint32 locale)
+ {
+ // DBC must be already loaded using Load
+ if (!indexTable.asT)
+ 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, locale));
+
+ return true;
+ }
+
+ void Clear()
+ {
+ if (!indexTable.asT)
+ return;
+
+ delete[] reinterpret_cast<char*>(indexTable.asT);
+ indexTable.asT = NULL;
+
+ delete[] reinterpret_cast<char*>(m_dataTable);
+ m_dataTable = NULL;
+
+ for (typename DataTableEx::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;
+ }
+
+ EntryChecker CheckEntry;
+ PacketWriter WritePacket;
+
+private:
+ uint32 nCount;
+ uint32 fieldCount;
+ char const* fmt;
+ union
+ {
+ T** asT;
+ char** asChar;
+ } indexTable;
+ T* m_dataTable;
+ DataTableEx m_dataTableEx;
+ StringPoolList m_stringPoolList;
+};
+
+#endif
diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/server/shared/DataStores/DBCFileLoader.cpp
index 1b7d34464f6..ea9bf23d383 100644
--- a/src/server/shared/DataStores/DBCFileLoader.cpp
+++ b/src/server/shared/DataStores/DBCFileLoader.cpp
@@ -90,8 +90,10 @@ bool DBCFileLoader::Load(const char* filename, const char* fmt)
for (uint32 i = 1; i < fieldCount; ++i)
{
fieldsOffset[i] = fieldsOffset[i - 1];
- if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X') // byte fields
+ if (fmt[i - 1] == FT_BYTE || fmt[i - 1] == FT_NA_BYTE) // byte fields
fieldsOffset[i] += sizeof(uint8);
+ else if (fmt[i - 1] == FT_LONG)
+ fieldsOffset[i] += sizeof(uint64);
else // 4 byte fields (int32/float/strings)
fieldsOffset[i] += sizeof(uint32);
}
@@ -150,12 +152,12 @@ uint32 DBCFileLoader::GetFormatRecordSize(const char* format, int32* index_pos)
case FT_BYTE:
recordsize += sizeof(uint8);
break;
+ case FT_LONG:
+ recordsize += sizeof(uint64);
+ break;
case FT_NA:
case FT_NA_BYTE:
break;
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
default:
ASSERT(false && "Unknown field format character in DBCfmt.h");
break;
@@ -243,13 +245,14 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**
*((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x);
offset += sizeof(uint8);
break;
+ case FT_LONG:
+ *((uint64*)(&dataTable[offset])) = getRecord(y).getUInt64(x);
+ offset += sizeof(uint64);
+ break;
case FT_STRING:
*((char**)(&dataTable[offset])) = NULL; // will replace non-empty or "" strings in AutoProduceStrings
offset += sizeof(char*);
break;
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
case FT_NA:
case FT_NA_BYTE:
case FT_SORT:
@@ -292,6 +295,9 @@ char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable)
case FT_BYTE:
offset += sizeof(uint8);
break;
+ case FT_LONG:
+ offset += sizeof(uint64);
+ break;
case FT_STRING:
{
// fill only not filled entries
@@ -304,9 +310,6 @@ char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable)
offset += sizeof(char*);
break;
}
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that does not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
case FT_NA:
case FT_NA_BYTE:
case FT_SORT:
diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h
index a665bc49c9c..f05e7800d3b 100644
--- 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 DbcFieldFormat
-{
- FT_NA='x', //not used or unknown, 4 byte size
- FT_NA_BYTE='X', //not used or unknown, byte
- FT_STRING='s', //char*
- FT_FLOAT='f', //float
- FT_INT='i', //uint32
- FT_BYTE='b', //uint8
- FT_SORT='d', //sorted by this field, field is not included
- FT_IND='n', //the same, but parsed to data
- FT_LOGIC='l', //Logical (boolean)
- FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc
- FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc
-};
-
class DBCFileLoader
{
public:
@@ -51,21 +36,26 @@ class DBCFileLoader
float getFloat(size_t field) const
{
assert(field < file.fieldCount);
- float val = *reinterpret_cast<float*>(offset+file.GetOffset(field));
+ 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));
+ 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));
+ return *reinterpret_cast<uint8*>(offset + file.GetOffset(field));
+ }
+ uint64 getUInt64(size_t field) const
+ {
+ assert(field < file.fieldCount);
+ return *reinterpret_cast<uint64*>(offset + file.GetOffset(field));
}
const char *getString(size_t field) const
@@ -78,8 +68,8 @@ class DBCFileLoader
private:
Record(DBCFileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) { }
- unsigned char *offset;
- DBCFileLoader &file;
+ unsigned char* offset;
+ DBCFileLoader& file;
friend class DBCFileLoader;
diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h
index 08b8d810b8b..055a8691a87 100644
--- 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"
@@ -186,6 +186,10 @@ class DBCStorage
*reinterpret_cast<uint8*>(&sqlDataTable[offset]) = uint8(0);
offset += 1;
break;
+ case FT_LONG:
+ *reinterpret_cast<uint64*>(&sqlDataTable[offset]) = uint64(0);
+ offset += 8;
+ break;
case FT_STRING:
// Beginning of the pool - empty string
*reinterpret_cast<char**>(&sqlDataTable[offset]) = stringPoolList.back();
@@ -211,6 +215,10 @@ class DBCStorage
*reinterpret_cast<uint8*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetUInt8();
offset += 1;
break;
+ case FT_LONG:
+ *reinterpret_cast<uint64*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetUInt64();
+ offset += 8;
+ break;
case FT_STRING:
TC_LOG_ERROR("server.loading", "Unsupported data type in table '%s' at char %d", sql->sqlTableName.c_str(), columnNumber);
return false;
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index e5e563071ec..a0fb6e74a39 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -43,14 +43,14 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"subject, deliver_time, expire_time, money, has_items FROM mail WHERE receiver = ? ", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL_LIST_ITEMS, "SELECT itemEntry,count FROM item_instance WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(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 "
+ "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 = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC);
+ "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL", CONNECTION_ASYNC);
PrepareStatement(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 = ? "
+ "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 = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC);
+ "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT guid, name FROM characters WHERE guid = ? AND account = ? AND (at_login & ?) = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH);
@@ -65,9 +65,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(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 "
+ "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);
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
@@ -115,7 +115,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(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);
PrepareStatement(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, spec FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC);
@@ -182,7 +182,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// 0: uint32, 1: uint8, 3: string, 4: uint32, 5: uint32
PrepareStatement(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, rname, rights, BankMoneyPerDay) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_RANKS, "DELETE FROM guild_rank WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
- PrepareStatement(CHAR_DEL_GUILD_LOWEST_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid >= ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8
+ PrepareStatement(CHAR_DEL_GUILD_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8
PrepareStatement(CHAR_INS_GUILD_BANK_TAB, "INSERT INTO guild_bank_tab (guildid, TabId) VALUES (?, ?)", CONNECTION_ASYNC); // 0: uint32, 1: uint8
PrepareStatement(CHAR_DEL_GUILD_BANK_TAB, "DELETE FROM guild_bank_tab WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8
PrepareStatement(CHAR_DEL_GUILD_BANK_TABS, "DELETE FROM guild_bank_tab WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
@@ -222,12 +222,24 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_GUILD_BANK_TAB_TEXT, "UPDATE guild_bank_tab SET TabText = ? WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC); // 0: string, 1: uint32, 2: uint8
PrepareStatement(CHAR_INS_GUILD_MEMBER_WITHDRAW,
- "INSERT INTO guild_member_withdraw (guid, tab0, tab1, tab2, tab3, tab4, tab5, money) VALUES (?, ?, ?, ?, ?, ?, ?, ?) "
- "ON DUPLICATE KEY UPDATE tab0 = VALUES (tab0), tab1 = VALUES (tab1), tab2 = VALUES (tab2), tab3 = VALUES (tab3), tab4 = VALUES (tab4), tab5 = VALUES (tab5)", CONNECTION_ASYNC);
+ "INSERT INTO guild_member_withdraw (guid, tab0, tab1, tab2, tab3, tab4, tab5, tab6, tab7, money) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
+ "ON DUPLICATE KEY UPDATE tab0 = VALUES (tab0), tab1 = VALUES (tab1), tab2 = VALUES (tab2), tab3 = VALUES (tab3), tab4 = VALUES (tab4), tab5 = VALUES (tab5), tab6 = VALUES (tab6), tab7 = VALUES (tab7), money = VALUES (money)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW, "TRUNCATE guild_member_withdraw", CONNECTION_ASYNC);
// 0: uint32, 1: uint32, 2: uint32
PrepareStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_DEL_GUILD_ACHIEVEMENT, "DELETE FROM guild_achievement WHERE guildId = ? AND achievement = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GUILD_ACHIEVEMENT, "INSERT INTO guild_achievement (guildId, achievement, date, guids) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ? AND criteria = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA, "INSERT INTO guild_achievement_progress (guildId, criteria, counter, date, completedGuid) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS, "DELETE FROM guild_achievement WHERE guildId = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_GUILD_ACHIEVEMENT, "SELECT achievement, date, guids FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_UPD_GUILD_EXPERIENCE, "UPDATE guild SET level = ?, experience = ?, todayExperience = ? WHERE guildId = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, "UPDATE guild SET todayExperience = 0", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GUILD_NEWS, "INSERT INTO guild_newslog (guildid, LogGuid, EventType, PlayerGuid, Flags, Value, Timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)"
+ " ON DUPLICATE KEY UPDATE LogGuid = VALUES (LogGuid), EventType = VALUES (EventType), PlayerGuid = VALUES (PlayerGuid), Flags = VALUES (Flags), Value = VALUES (Value), Timestamp = VALUES (Timestamp)", CONNECTION_ASYNC);
// Chat channel handling
PrepareStatement(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH);
@@ -250,6 +262,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(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
+ PrepareStatement(CHAR_SEL_PLAYER_CURRENCY, "SELECT currency, week_count, total_count FROM character_currency WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_PLAYER_CURRENCY, "UPDATE character_currency SET week_count = ?, total_count = ? WHERE guid = ? AND currency = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_PLAYER_CURRENCY, "REPLACE INTO character_currency (guid, currency, week_count, total_count) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+
// Account data
PrepareStatement(CHAR_SEL_ACCOUNT_DATA, "SELECT type, time, data FROM account_data WHERE accountId = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_REP_ACCOUNT_DATA, "REPLACE INTO account_data (accountId, type, time, data) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
@@ -315,8 +332,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC);
// Corpse
- PrepareStatement(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);
- PrepareStatement(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);
+ PrepareStatement(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);
+ PrepareStatement(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);
PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC);
@@ -353,18 +370,18 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(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, trans_x, trans_y, trans_z, trans_o, transguid, "
"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);
PrepareStatement(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=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,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);
PrepareStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
@@ -391,6 +408,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_ZONE, "UPDATE characters SET zone = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_LEVEL, "UPDATE characters SET level = ?, xp = 0 WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA, "DELETE FROM character_achievement_progress WHERE criteria = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA_GUILD, "DELETE FROM guild_achievement_progress WHERE criteria = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_ACHIEVMENT, "DELETE FROM character_achievement WHERE achievement = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_ADDON, "INSERT INTO addons (name, crc) VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_PET_SPELL, "DELETE FROM pet_spell WHERE spell = ?", CONNECTION_ASYNC);
@@ -461,7 +479,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_ADD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_REFUND_INSTANCE, "DELETE FROM item_refund_instance WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_ITEM_REFUND_INSTANCE, "INSERT INTO item_refund_instance (item_guid, player_guid, paidMoney, paidExtendedCost) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP, "DELETE FROM groups WHERE guid = ?", CONNECTION_ASYNC);
@@ -515,8 +532,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHAR_GLYPHS, "DELETE FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TALENT, "DELETE FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_SKILLS, "DELETE FROM character_skills WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_ACTION, "INSERT INTO character_action (guid, spec, button, action, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_ACTION, "UPDATE character_action SET action = ?, type = ? WHERE guid = ? AND button = ? AND spec = ?", CONNECTION_ASYNC);
@@ -536,17 +551,34 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, spirit, "
+ PrepareStatement(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);
+ "spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs (guid, spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and spec = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_CHAR_LIST_SLOT, "UPDATE characters SET slot = ? WHERE guid = ?", CONNECTION_ASYNC);
+
+ // Void Storage
+ PrepareStatement(CHAR_SEL_CHAR_VOID_STORAGE, "SELECT itemId, itemEntry, slot, creatorGuid, randomProperty, suffixFactor FROM character_void_storage WHERE playerGuid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_CHAR_VOID_STORAGE_ITEM, "REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomProperty, suffixFactor) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT, "DELETE FROM character_void_storage WHERE slot = ? AND playerGuid = ?", CONNECTION_ASYNC);
+
+ // CompactUnitFrame profiles
+ PrepareStatement(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);
+ PrepareStatement(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);
+ PrepareStatement(CHAR_DEL_CHAR_CUF_PROFILES, "DELETE FROM character_cuf_profiles WHERE guid = ? and id = ?", CONNECTION_ASYNC);
+
+ // Guild Finder
+ PrepareStatement(CHAR_REP_GUILD_FINDER_APPLICANT, "REPLACE INTO guild_finder_applicant (guildId, playerGuid, availability, classRole, interests, comment, submitTime) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_GUILD_FINDER_APPLICANT, "DELETE FROM guild_finder_applicant WHERE guildId = ? AND playerGuid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_GUILD_FINDER_GUILD_SETTINGS, "REPLACE INTO guild_finder_guild_settings (guildId, availability, classRoles, interests, level, listed, comment) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS, "DELETE FROM guild_finder_guild_settings WHERE guildId = ?", CONNECTION_ASYNC);
// Items that hold loot or money
PrepareStatement(CHAR_SEL_ITEMCONTAINER_ITEMS, "SELECT item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix FROM item_loot_items WHERE container_id = ?", CONNECTION_SYNCH);
@@ -586,10 +618,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_BOTH);
PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, "
"base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH);
- PrepareStatement(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);
- PrepareStatement(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);
- PrepareStatement(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);
- PrepareStatement(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);
+ PrepareStatement(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);
+ PrepareStatement(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);
+ PrepareStatement(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);
+ PrepareStatement(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);
PrepareStatement(CHAR_DEL_CHAR_PET_BY_OWNER, "DELETE FROM character_pet WHERE owner = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_PET_NAME, "UPDATE character_pet SET name = ?, renamed = 1 WHERE owner = ? AND id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ? AND id <> ?", CONNECTION_ASYNC);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 9bc11e3f525..4764d653f17 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -176,7 +176,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,
@@ -209,6 +209,17 @@ enum CharacterDatabaseStatements
CHAR_INS_GUILD_MEMBER_WITHDRAW,
CHAR_DEL_GUILD_MEMBER_WITHDRAW,
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_INS_GUILD_NEWS,
CHAR_SEL_CHANNEL,
CHAR_INS_CHANNEL,
@@ -223,6 +234,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,
@@ -331,6 +346,7 @@ enum CharacterDatabaseStatements
CHAR_UPD_ZONE,
CHAR_UPD_LEVEL,
CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA,
+ CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA_GUILD,
CHAR_DEL_INVALID_ACHIEVMENT,
CHAR_INS_ADDON,
CHAR_DEL_INVALID_PET_SPELL,
@@ -400,7 +416,6 @@ enum CharacterDatabaseStatements
CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS,
CHAR_DEL_CHAR_REPUTATION_BY_FACTION,
CHAR_INS_CHAR_REPUTATION_BY_FACTION,
- CHAR_UPD_ADD_CHAR_ARENA_POINTS,
CHAR_DEL_ITEM_REFUND_INSTANCE,
CHAR_INS_ITEM_REFUND_INSTANCE,
CHAR_DEL_GROUP,
@@ -454,8 +469,6 @@ enum CharacterDatabaseStatements
CHAR_DEL_CHAR_GLYPHS,
CHAR_DEL_CHAR_TALENT,
CHAR_DEL_CHAR_SKILLS,
- CHAR_UPD_CHAR_HONOR_POINTS,
- CHAR_UPD_CHAR_ARENA_POINTS,
CHAR_UPD_CHAR_MONEY,
CHAR_INS_CHAR_ACTION,
CHAR_UPD_CHAR_ACTION,
@@ -484,6 +497,20 @@ enum CharacterDatabaseStatements
CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC,
CHAR_INS_CHAR_TALENT,
CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC,
+ 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,
CHAR_REP_CALENDAR_EVENT,
CHAR_DEL_CALENDAR_EVENT,
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp
index a2b9091a8d5..2bdbc70933d 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp
@@ -22,7 +22,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
if (!m_reconnecting)
m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS);
- PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH);
PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_IP_BANNED, "SELECT * FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH);
@@ -37,13 +37,13 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH);
- PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.lock_country, a.last_ip, aa.gmlevel, a.v, a.s, a.token_key FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.lock_country, a.last_ip, aa.gmlevel, a.v, a.s, a.token_key, a.battlenet_account FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_LOGON_COUNTRY, "SELECT country FROM ip2nation WHERE ip < ? ORDER BY ip DESC LIMIT 0,1", CONNECTION_SYNCH);
PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH);
- PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os, battlenet_account FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH);
@@ -111,4 +111,26 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_SYNCH);
PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC);
+
+ PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT sha_pass_hash, id, locked, lock_country, last_ip, v, s FROM battlenet_accounts WHERE email = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_DEL_BNET_EXPIRED_BANS, "UPDATE battlenet_account_bans SET active = 0 WHERE active = 1 AND unbandate <> bandate AND unbandate <= UNIX_TIMESTAMP()", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, "SELECT bandate, unbandate FROM battlenet_account_bans WHERE id = ? AND active = 1", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_UPD_BNET_VS_FIELDS, "UPDATE battlenet_accounts SET v = ?, s = ? WHERE email = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ?, online = ? WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT ba.id, ba.sessionKey, a.id FROM battlenet_accounts ba LEFT JOIN account a ON ba.id = a.battlenet_account WHERE ba.email = ? AND a.username = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_account = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE username = ? AND battlenet_account = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED, "SELECT a.id, a.username, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_index = ? AND battlenet_account = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_BNET_FAILED_LOGINS, "SELECT failed_logins FROM battlenet_accounts WHERE id = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_UPD_BNET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = failed_logins + 1 WHERE email = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS, "SELECT rc.numchars, r.id, r.Region, r.Battlegroup, r.gamebuild FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_INS_BNET_ACCOUNT, "INSERT INTO battlenet_accounts (`email`,`sha_pass_hash`) VALUES (?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID, "SELECT email FROM battlenet_accounts WHERE id = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL, "SELECT id FROM battlenet_accounts WHERE email = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_UPD_BNET_PASSWORD, "UPDATE battlenet_accounts SET v = '', s = '', sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_SEL_BNET_CHECK_PASSWORD, "SELECT 1 FROM battlenet_accounts WHERE id = ? AND sha_pass_hash = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK, "UPDATE battlenet_accounts SET locked = ? WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY, "UPDATE battlenet_accounts SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT, "SELECT battlenet_account FROM account WHERE id = ?", CONNECTION_SYNCH);
}
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h
index d37149c6a76..c1816784f07 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.h
+++ b/src/server/shared/Database/Implementation/LoginDatabase.h
@@ -127,6 +127,29 @@ enum LoginDatabaseStatements
LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS,
LOGIN_INS_RBAC_ACCOUNT_PERMISSION,
LOGIN_DEL_RBAC_ACCOUNT_PERMISSION,
+
+ LOGIN_SEL_BNET_ACCOUNT_INFO,
+ LOGIN_DEL_BNET_EXPIRED_BANS,
+ LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN,
+ LOGIN_UPD_BNET_VS_FIELDS,
+ LOGIN_UPD_BNET_SESSION_KEY,
+ LOGIN_SEL_BNET_RECONNECT_INFO,
+ LOGIN_SEL_BNET_GAME_ACCOUNTS,
+ LOGIN_SEL_BNET_GAME_ACCOUNT,
+ LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED,
+ LOGIN_SEL_BNET_FAILED_LOGINS,
+ LOGIN_UPD_BNET_FAILED_LOGINS,
+ LOGIN_UPD_BNET_LAST_LOGIN_INFO,
+ LOGIN_SEL_BNET_CHARACTER_COUNTS,
+ LOGIN_INS_BNET_ACCOUNT,
+ LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID,
+ LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL,
+ LOGIN_UPD_BNET_PASSWORD,
+ LOGIN_SEL_BNET_CHECK_PASSWORD,
+ LOGIN_UPD_BNET_ACCOUNT_LOCK,
+ LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY,
+ LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT,
+
MAX_LOGINDATABASE_STATEMENTS
};
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index 2adb575b780..531d092d039 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -34,9 +34,9 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_DEL_GRAVEYARD_ZONE, "DELETE FROM game_graveyard_zone WHERE id = ? AND ghost_zone = ? AND faction = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_GAME_TELE, "INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_GAME_TELE, "DELETE FROM game_tele WHERE name = ?", CONNECTION_ASYNC);
- PrepareStatement(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ?", CONNECTION_ASYNC);
- PrepareStatement(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry = ? ORDER BY slot ASC", CONNECTION_SYNCH);
+ PrepareStatement(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost, type) VALUES(?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ? AND type = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost, type FROM npc_vendor WHERE entry = ? AND type = ? ORDER BY slot ASC", CONNECTION_SYNCH);
PrepareStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE, "UPDATE creature SET MovementType = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_UPD_CREATURE_FACTION, "UPDATE creature_template SET faction = ? WHERE entry = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_UPD_CREATURE_NPCFLAG, "UPDATE creature_template SET npcflag = ? WHERE entry = ?", CONNECTION_ASYNC);
@@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH);
- PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, 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, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, 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, HealthModifier, ManaModifier, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
+ PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, type, type_flags, type_flags2, 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, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h
index 075dd39002f..2723d287c53 100644
--- a/src/server/shared/Define.h
+++ b/src/server/shared/Define.h
@@ -104,4 +104,19 @@ typedef uint32_t uint32;
typedef uint16_t uint16;
typedef uint8_t 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_LONG = 'l', //uint64
+ FT_SORT = 'd', //sorted by this field, field is not included
+ FT_IND = 'n', //the same, but parsed to data
+ 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/Packets/ByteBuffer.cpp b/src/server/shared/Packets/ByteBuffer.cpp
index 3785d1c29fa..02713a30cc6 100644
--- a/src/server/shared/Packets/ByteBuffer.cpp
+++ b/src/server/shared/Packets/ByteBuffer.cpp
@@ -20,10 +20,9 @@
#include "MessageBuffer.h"
#include "Common.h"
#include "Log.h"
-
#include <sstream>
-ByteBuffer::ByteBuffer(MessageBuffer&& buffer) : _rpos(0), _wpos(0), _storage(buffer.Move())
+ByteBuffer::ByteBuffer(MessageBuffer&& buffer) : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0), _storage(buffer.Move())
{
}
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 3d44c975c96..d65b6c58a51 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -71,24 +71,25 @@ public:
class ByteBuffer
{
public:
- const static size_t DEFAULT_SIZE = 0x1000;
+ static size_t const DEFAULT_SIZE = 0x1000;
+ static uint8 const InitialBitPos = 8;
// constructor
- ByteBuffer() : _rpos(0), _wpos(0)
+ ByteBuffer() : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0)
{
_storage.reserve(DEFAULT_SIZE);
}
- ByteBuffer(size_t reserve) : _rpos(0), _wpos(0)
+ ByteBuffer(size_t reserve) : _rpos(0), _wpos(0), _bitpos(InitialBitPos), _curbitval(0)
{
_storage.reserve(reserve);
}
ByteBuffer(ByteBuffer&& buf) : _rpos(buf._rpos), _wpos(buf._wpos),
- _storage(std::move(buf._storage)) { }
+ _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(std::move(buf._storage)) { }
ByteBuffer(ByteBuffer const& right) : _rpos(right._rpos), _wpos(right._wpos),
- _storage(right._storage) { }
+ _bitpos(right._bitpos), _curbitval(right._curbitval), _storage(right._storage) { }
ByteBuffer(MessageBuffer&& buffer);
@@ -98,6 +99,8 @@ class ByteBuffer
{
_rpos = right._rpos;
_wpos = right._wpos;
+ _bitpos = right._bitpos;
+ _curbitval = right._curbitval;
_storage = right._storage;
}
@@ -119,6 +122,74 @@ class ByteBuffer
append((uint8 *)&value, sizeof(value));
}
+ void FlushBits()
+ {
+ if (_bitpos == 8)
+ return;
+
+ _bitpos = 8;
+
+ append((uint8 *)&_curbitval, sizeof(uint8));
+ _curbitval = 0;
+ }
+
+ 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)
{
static_assert(std::is_fundamental<T>::value, "append(compound)");
@@ -126,6 +197,37 @@ class ByteBuffer
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);
@@ -323,6 +425,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)); }
@@ -381,6 +493,25 @@ class ByteBuffer
}
}
+ std::string ReadString(uint32 length)
+ {
+ if (!length)
+ return std::string();
+ char* buffer = new char[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>();
@@ -452,6 +583,8 @@ class ByteBuffer
ASSERT(size() < 10000000);
+ FlushBits();
+
if (_storage.size() < _wpos + cnt)
_storage.resize(_wpos + cnt);
std::memcpy(&_storage[_wpos], src, cnt);
@@ -518,7 +651,8 @@ class ByteBuffer
void hexlike() const;
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 100644
index 848a00739fe..00000000000
--- a/src/server/shared/Packets/WorldPacket.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2008-2014 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) { }
-
- WorldPacket(WorldPacket&& packet) : ByteBuffer(std::move(packet)), m_opcode(packet.m_opcode)
- {
- }
-
- WorldPacket(WorldPacket const& right) : ByteBuffer(right), m_opcode(right.m_opcode)
- {
- }
-
- WorldPacket& operator=(WorldPacket const& right)
- {
- if (this != &right)
- {
- m_opcode = right.m_opcode;
- ByteBuffer::operator =(right);
- }
-
- return *this;
- }
-
- WorldPacket(uint16 opcode, MessageBuffer&& buffer) : ByteBuffer(std::move(buffer)), m_opcode(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 e577797d3e0..c4049ae6315 100644
--- a/src/server/shared/Utilities/Util.cpp
+++ b/src/server/shared/Utilities/Util.cpp
@@ -178,9 +178,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 ||
@@ -197,7 +197,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)
@@ -537,6 +537,17 @@ void vutf8printf(FILE* out, const char *str, va_list* ap)
#endif
}
+bool Utf8ToUpperOnlyLatin(std::string& utf8String)
+{
+ std::wstring wstr;
+ if (!Utf8toWStr(utf8String, wstr))
+ return false;
+
+ std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);
+
+ return WStrToUtf8(wstr, utf8String);
+}
+
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */)
{
int32 init = 0;
@@ -569,3 +580,28 @@ uint32 EventMap::GetTimeUntilEvent(uint32 eventId) const
return std::numeric_limits<uint32>::max();
}
+
+void HexStrToByteArray(std::string const& str, uint8* out, bool reverse /*= false*/)
+{
+ // string must have even number of characters
+ if (str.length() & 1)
+ return;
+
+ int32 init = 0;
+ int32 end = str.length();
+ int8 op = 1;
+
+ if (reverse)
+ {
+ init = str.length() - 2;
+ end = -2;
+ op = -1;
+ }
+
+ uint32 j = 0;
+ for (int32 i = init; i != end; i += 2 * op)
+ {
+ char buffer[3] = { str[i], str[i + 1], '\0' };
+ out[j++] = strtoul(buffer, NULL, 16);
+ }
+}
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index d88ad3be8e1..73ee37eb079 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -68,7 +68,7 @@ private:
void stripLineInvisibleChars(std::string &src);
-int32 MoneyStringToMoney(const std::string& moneyString);
+int64 MoneyStringToMoney(const std::string& moneyString);
struct tm* localtime_r(const time_t* time, struct tm *result);
@@ -338,12 +338,14 @@ bool consoleToUtf8(const std::string& conStr, std::string& utf8str);
bool Utf8FitTo(const std::string& str, std::wstring const& search);
void utf8printf(FILE* out, const char *str, ...);
void vutf8printf(FILE* out, const char *str, va_list* ap);
+bool Utf8ToUpperOnlyLatin(std::string& utf8String);
bool IsIPAddress(char const* ipaddress);
uint32 CreatePIDFile(const std::string& filename);
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
+void HexStrToByteArray(std::string const& str, uint8* out, bool reverse = false);
// simple class for not-modifyable list
template <typename T>