aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Object/Object.cpp2
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.cpp2
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp1
-rw-r--r--src/server/game/Server/Packet.h8
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.cpp33
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.h38
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h12
-rw-r--r--src/server/game/Server/WorldPacket.cpp25
-rw-r--r--src/server/game/Server/WorldPacket.h2
-rw-r--r--src/server/game/Server/WorldSession.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
-rw-r--r--src/server/game/Server/WorldSocket.cpp77
12 files changed, 123 insertions, 81 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 6fc422c65cf..fa9634add80 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -1317,7 +1317,7 @@ void Object::AddDynamicValue(uint16 index, uint32 value)
}
}
-void Object::RemoveDynamicValue(uint16 index, uint32 value)
+void Object::RemoveDynamicValue(uint16 index, uint32 /*value*/)
{
ASSERT(index < _dynamicValuesCount || PrintIndexError(index, false));
/// TODO: Research if this is actually needed
diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp
index b51493bcd23..126916c4364 100644
--- a/src/server/game/Entities/Object/ObjectGuid.cpp
+++ b/src/server/game/Entities/Object/ObjectGuid.cpp
@@ -181,7 +181,7 @@ public:
inline static ObjectGuid MapSpecific(HighGuid type, uint8 subType, uint16 mapId, uint32 serverId, uint32 entry, ObjectGuid::LowType counter)
{
- return ObjectGuid(uint64((uint64(type) << 58) | (uint64(realmHandle.Index & 0x1FFF) << 42) | (uint64(mapId & 0x1FFF) << 29) | (uint64(entry & 0x7FFFFF) << 6)),
+ return ObjectGuid(uint64((uint64(type) << 58) | (uint64(realmHandle.Index & 0x1FFF) << 42) | (uint64(mapId & 0x1FFF) << 29) | (uint64(entry & 0x7FFFFF) << 6) | (uint64(subType) & 0x3F)),
uint64((uint64(serverId & 0xFFFFFF) << 40) | (counter & UI64LIT(0xFFFFFFFFFF))));
}
};
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 083d08cc41a..e9799a3c648 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -770,7 +770,6 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner)
bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask)
{
TC_LOG_DEBUG("entities.pet", "Pet::CreateBaseForTamed");
- uint32 petId = sObjectMgr->GeneratePetNumber();
if (!Create(sObjectMgr->GetGenerator<HighGuid::Pet>()->Generate(), map, phaseMask, cinfo->Entry))
return false;
diff --git a/src/server/game/Server/Packet.h b/src/server/game/Server/Packet.h
index ebfa5c302a9..bda0166098d 100644
--- a/src/server/game/Server/Packet.h
+++ b/src/server/game/Server/Packet.h
@@ -48,6 +48,14 @@ namespace WorldPackets
size_t GetSize() const { return _worldPacket.size(); }
void Reset() { _worldPacket.clear(); }
};
+
+ class ClientPacket : public Packet
+ {
+ public:
+ ClientPacket(WorldPacket&& packet) : Packet(std::move(packet)) { }
+
+ void Write() override final { ASSERT(!"Write not allowed for client packets."); }
+ };
}
#endif
diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp
index 1d20c582b0b..c64ef37d320 100644
--- a/src/server/game/Server/Packets/AuthenticationPackets.cpp
+++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp
@@ -17,6 +17,37 @@
#include "AuthenticationPackets.h"
+void WorldPackets::Auth::AuthChallenge::Write()
+{
+ _worldPacket << uint32(Challenge);
+ _worldPacket.append(DosChallenge, sizeof(DosChallenge));
+ _worldPacket << uint8(DosZeroBits);
+}
+
+void WorldPackets::Auth::AuthSession::Read()
+{
+ uint32 addonDataSize;
+
+ _worldPacket >> LoginServerID;
+ _worldPacket >> Build;
+ _worldPacket >> RegionID;
+ _worldPacket >> BattlegroupID;
+ _worldPacket >> RealmID;
+ _worldPacket >> LoginServerType;
+ _worldPacket >> BuildType;
+ _worldPacket >> LocalChallenge;
+ _worldPacket >> DosResponse;
+ _worldPacket.read(Digest, SHA_DIGEST_LENGTH);
+ Account = _worldPacket.ReadString(_worldPacket.ReadBits(11));
+ UseIPv6 = _worldPacket.ReadBit(); // UseIPv6
+ _worldPacket >> addonDataSize;
+ if (addonDataSize)
+ {
+ AddonInfo.resize(addonDataSize);
+ _worldPacket.read(AddonInfo.contents(), addonDataSize);
+ }
+}
+
WorldPackets::Auth::AuthResponse::AuthResponse()
: ServerPacket(SMSG_AUTH_RESPONSE, 132)
{
@@ -104,4 +135,4 @@ void WorldPackets::Auth::AuthResponse::Write()
}
_worldPacket.FlushBits();
-} \ No newline at end of file
+}
diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h
index dd5fea06e10..41b3d7cb257 100644
--- a/src/server/game/Server/Packets/AuthenticationPackets.h
+++ b/src/server/game/Server/Packets/AuthenticationPackets.h
@@ -19,11 +19,49 @@
#include "Packet.h"
#include "Util.h"
+#include <SHA1.h>
namespace WorldPackets
{
namespace Auth
{
+ class AuthChallenge final : public ServerPacket
+ {
+ public:
+ AuthChallenge() : ServerPacket(SMSG_AUTH_CHALLENGE, 8 + 32 + 1), Challenge(0) { }
+
+ void Write() override;
+
+ uint32 Challenge;
+ uint32 DosChallenge[8]; ///< Encryption seeds
+ uint8 DosZeroBits;
+ };
+
+ class AuthSession final : public ClientPacket
+ {
+ public:
+ AuthSession(WorldPacket&& packet) : ClientPacket(std::move(packet))
+ {
+ memset(Digest, 0, SHA_DIGEST_LENGTH);
+ }
+
+ void Read() override;
+
+ uint32 BattlegroupID = 0;
+ int8 LoginServerType = 0; ///< Auth type used - 0 GRUNT, 1 battle.net
+ int8 BuildType = 0;
+ uint32 RealmID = 0;
+ uint16 Build = 0;
+ uint32 LocalChallenge = 0;
+ int32 LoginServerID = 0;
+ uint32 RegionID = 0;
+ uint64 DosResponse = 0;
+ uint8 Digest[SHA_DIGEST_LENGTH];
+ std::string Account;
+ bool UseIPv6 = false;
+ ByteBuffer AddonInfo;
+ };
+
class AuthResponse final : public ServerPacket
{
public:
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index bd56173ba38..5c995664dbb 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -31,7 +31,6 @@ enum OpcodeMisc : uint32
NUM_OPCODE_HANDLERS = (MAX_OPCODE + 1),
UNKNOWN_OPCODE = (0xFFFF + 1),
NULL_OPCODE = 0,
- COMPRESSED_OPCODE_MASK = 0x8000
};
// CMSGs
@@ -69,7 +68,7 @@ enum OpcodeClient : uint32
CMSG_AUCTION_PLACE_BID = 0x0000,
CMSG_AUCTION_REMOVE_ITEM = 0x0000,
CMSG_AUCTION_SELL_ITEM = 0x0000,
- CMSG_AUTH_SESSION = 0x1B05,
+ CMSG_AUTH_SESSION = 0x0487,
CMSG_AUTOBANK_ITEM = 0x0000,
CMSG_AUTOEQUIP_GROUND_ITEM = 0x0000,
CMSG_AUTOEQUIP_ITEM = 0x0000,
@@ -712,8 +711,8 @@ enum OpcodeServer : uint32
SMSG_AURA_POINTS_DEPLETED = 0x0000,
SMSG_AURA_UPDATE = 0x128B,
SMSG_AURA_UPDATE_ALL = 0x0000,
- SMSG_AUTH_CHALLENGE = 0x10AA,
- SMSG_AUTH_RESPONSE = 0x0564,
+ SMSG_AUTH_CHALLENGE = 0x1759,
+ SMSG_AUTH_RESPONSE = 0x0DA9,
SMSG_AVAILABLE_VOICE_CHANNEL = 0x0000,
SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0x0000,
SMSG_BARBER_SHOP_RESULT = 0x0000,
@@ -809,6 +808,7 @@ enum OpcodeServer : uint32
SMSG_COMMENTATOR_STATE_CHANGED = 0x0000,
SMSG_COMPLAIN_RESULT = 0x0000,
SMSG_COMPRESSED_MOVES = 0x0000,
+ SMSG_COMPRESSED_PACKET = 0x07CA,
SMSG_COMSAT_CONNECT_FAIL = 0x0000,
SMSG_COMSAT_DISCONNECT = 0x0000,
SMSG_COMSAT_RECONNECT_TRY = 0x0000,
@@ -1512,11 +1512,7 @@ inline std::string GetOpcodeNameForLogging(T id)
if (static_cast<uint32>(id) < UNKNOWN_OPCODE)
{
if (OpcodeHandler const* handler = opcodeTable[T(opcode & 0x7FFF)])
- {
ss << handler->Name;
- if (opcode & COMPRESSED_OPCODE_MASK)
- ss << "_COMPRESSED";
- }
else
ss << "UNKNOWN OPCODE";
}
diff --git a/src/server/game/Server/WorldPacket.cpp b/src/server/game/Server/WorldPacket.cpp
index a1a9b15f20b..ab2c0b089e2 100644
--- a/src/server/game/Server/WorldPacket.cpp
+++ b/src/server/game/Server/WorldPacket.cpp
@@ -23,13 +23,12 @@
void WorldPacket::Compress(z_stream* compressionStream)
{
OpcodeServer uncompressedOpcode = static_cast<OpcodeServer>(GetOpcode());
- if (uncompressedOpcode & COMPRESSED_OPCODE_MASK)
+ if (uncompressedOpcode == SMSG_COMPRESSED_PACKET)
{
TC_LOG_ERROR("network", "Packet with opcode 0x%04X is already compressed!", uncompressedOpcode);
return;
}
- OpcodeServer opcode = OpcodeServer(uncompressedOpcode | COMPRESSED_OPCODE_MASK);
uint32 size = wpos();
uint32 destsize = compressBound(size);
@@ -41,11 +40,12 @@ void WorldPacket::Compress(z_stream* compressionStream)
return;
clear();
- reserve(destsize + sizeof(uint32));
+ reserve(destsize + sizeof(uint32) * 2);
+ *this << uint32(uncompressedOpcode);
*this << uint32(size);
append(&storage[0], destsize);
- SetOpcode(opcode);
- TC_LOG_INFO("network", "%s (len %u) successfully compressed to %04X (len %u)", GetOpcodeNameForLogging(uncompressedOpcode).c_str(), size, opcode, destsize);
+ SetOpcode(SMSG_COMPRESSED_PACKET);
+ TC_LOG_INFO("network", "%s (len %u) successfully compressed to len %u", GetOpcodeNameForLogging(uncompressedOpcode).c_str(), size, destsize);
}
//! Compresses another packet and stores it in self (source left intact)
@@ -54,30 +54,29 @@ void WorldPacket::Compress(z_stream* compressionStream, WorldPacket const* sourc
ASSERT(source != this);
OpcodeServer uncompressedOpcode = static_cast<OpcodeServer>(source->GetOpcode());
- if (uncompressedOpcode & COMPRESSED_OPCODE_MASK)
+ if (uncompressedOpcode == SMSG_COMPRESSED_PACKET)
{
TC_LOG_ERROR("network", "Packet with opcode 0x%04X is already compressed!", uncompressedOpcode);
return;
}
- OpcodeServer opcode = OpcodeServer(uncompressedOpcode | COMPRESSED_OPCODE_MASK);
uint32 size = source->size();
uint32 destsize = compressBound(size);
- size_t sizePos = 0;
- resize(destsize + sizeof(uint32));
+ resize(destsize + sizeof(uint32) * 2);
_compressionStream = compressionStream;
- Compress(static_cast<void*>(&_storage[0] + sizeof(uint32)), &destsize, static_cast<const void*>(source->contents()), size);
+ Compress(static_cast<void*>(&_storage[0] + sizeof(uint32) * 2), &destsize, static_cast<const void*>(source->contents()), size);
if (destsize == 0)
return;
- put<uint32>(sizePos, size);
+ put<uint32>(0, uncompressedOpcode);
+ put<uint32>(4, size);
resize(destsize + sizeof(uint32));
- SetOpcode(opcode);
+ SetOpcode(SMSG_COMPRESSED_PACKET);
- TC_LOG_INFO("network", "%s (len %u) successfully compressed to %04X (len %u)", GetOpcodeNameForLogging(uncompressedOpcode).c_str(), size, opcode, destsize);
+ TC_LOG_INFO("network", "%s (len %u) successfully compressed to len %u", GetOpcodeNameForLogging(uncompressedOpcode).c_str(), size, destsize);
}
void WorldPacket::Compress(void* dst, uint32 *dst_size, const void* src, int src_size)
diff --git a/src/server/game/Server/WorldPacket.h b/src/server/game/Server/WorldPacket.h
index 7c36f8f2321..9e29026ba05 100644
--- a/src/server/game/Server/WorldPacket.h
+++ b/src/server/game/Server/WorldPacket.h
@@ -65,7 +65,7 @@ class WorldPacket : public ByteBuffer
uint32 GetOpcode() const { return m_opcode; }
void SetOpcode(uint32 opcode) { m_opcode = opcode; }
- bool IsCompressed() const { return (m_opcode & COMPRESSED_OPCODE_MASK) != 0; }
+ bool IsCompressed() const { return m_opcode == SMSG_COMPRESSED_PACKET; }
void Compress(z_stream_s* compressionStream);
void Compress(z_stream_s* compressionStream, WorldPacket const* source);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 2332829e69a..9e22e294a0a 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -806,7 +806,7 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans)
m_TutorialsChanged = false;
}
-void WorldSession::ReadAddonsInfo(WorldPacket &data)
+void WorldSession::ReadAddonsInfo(ByteBuffer& data)
{
if (data.rpos() + 4 > data.size())
return;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 254532bcf4c..ef29f0da7e6 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -268,7 +268,7 @@ class WorldSession
bool PlayerLogoutWithSave() const { return m_playerLogout && m_playerSave; }
bool PlayerRecentlyLoggedOut() const { return m_playerRecentlyLogout; }
- void ReadAddonsInfo(WorldPacket& data);
+ void ReadAddonsInfo(ByteBuffer& data);
void SendAddonsInfo();
bool IsAddonRegistered(const std::string& prefix) const;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index e9200eae84c..25ed950a37c 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -63,19 +63,20 @@ void WorldSocket::Start()
void WorldSocket::HandleSendAuthSession()
{
- WorldPacket packet(SMSG_AUTH_CHALLENGE, 37);
- packet << uint32(_authSeed);
-
BigNumber seed1;
- seed1.SetRand(16 * 8);
- packet.append(seed1.AsByteArray(16).get(), 16); // new encryption seeds
-
BigNumber seed2;
+ seed1.SetRand(16 * 8);
seed2.SetRand(16 * 8);
- packet.append(seed2.AsByteArray(16).get(), 16); // new encryption seeds
- packet << uint8(1);
- SendPacket(packet);
+ WorldPackets::Auth::AuthChallenge challenge;
+ challenge.Challenge = _authSeed;
+ memcpy(&challenge.DosChallenge[0], seed1.AsByteArray(16).get(), 16);
+ memcpy(&challenge.DosChallenge[4], seed2.AsByteArray(16).get(), 16);
+ challenge.DosZeroBits = 1;
+
+ challenge.Write();
+
+ SendPacket(challenge.GetWorldPacket());
}
void WorldSocket::ReadHandler()
@@ -334,50 +335,21 @@ void WorldSocket::SendPacket(WorldPacket& packet)
void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
{
- uint8 digest[SHA_DIGEST_LENGTH];
- uint32 clientSeed;
+ WorldPackets::Auth::AuthSession authSession(std::move(recvPacket));
+ authSession.Read();
+
uint8 security;
- uint16 clientBuild;
uint32 id;
- uint32 addonSize;
LocaleConstant locale;
- std::string account;
SHA1Hash sha;
BigNumber k;
bool wardenActive = sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED);
- WorldPacket addonsData;
- uint8 loginServerType;
- uint32 realmIndex;
-
- recvPacket.read_skip<uint32>(); // Grunt - ServerId
- recvPacket >> clientBuild;
- recvPacket.read_skip<uint32>(); // Region
- recvPacket.read_skip<uint32>(); // Battlegroup
- recvPacket >> realmIndex;
- recvPacket >> loginServerType; // could be swapped with other uint8 (both always 1)
- recvPacket.read_skip<uint8>();
- recvPacket >> clientSeed;
- recvPacket.read_skip<uint64>(); // DosResponse
-
- for (int i = 0; i < SHA_DIGEST_LENGTH; i++)
- recvPacket >> digest[i];
-
- uint32 accountNameLength = recvPacket.ReadBits(11);
- account = recvPacket.ReadString(accountNameLength);
- recvPacket.ReadBit(); // UseIPv6
- recvPacket >> addonSize;
-
- if (addonSize)
- {
- addonsData.resize(addonSize);
- recvPacket.read((uint8*)addonsData.contents(), addonSize);
- }
// Get the account information from the auth database
// 0 1 2 3 4 5 6 7 8
// SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME);
- stmt->setString(0, account);
+ stmt->setString(0, authSession.Account);
PreparedQueryResult result = LoginDatabase.Query(stmt);
@@ -405,7 +377,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_ATTEMPT_IP);
stmt->setString(0, address);
- stmt->setString(1, account);
+ stmt->setString(1, authSession.Account);
LoginDatabase.Execute(stmt);
// This also allows to check for possible "hack" attempts on account
@@ -428,7 +400,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
return;
}
- if (realmIndex != realmHandle.Index)
+ if (authSession.RealmID != realmHandle.Index)
{
SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND);
TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm).");
@@ -450,17 +422,17 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// Check that Key and account name are the same on client and server
uint32 t = 0;
- sha.UpdateData(account);
+ sha.UpdateData(authSession.Account);
sha.UpdateData((uint8*)&t, 4);
- sha.UpdateData((uint8*)&clientSeed, 4);
+ sha.UpdateData((uint8*)&authSession.LocalChallenge, 4);
sha.UpdateData((uint8*)&_authSeed, 4);
sha.UpdateBigNumbers(&k, NULL);
sha.Finalize();
- if (memcmp(sha.GetDigest(), digest, SHA_DIGEST_LENGTH) != 0)
+ if (memcmp(sha.GetDigest(), authSession.Digest, SHA_DIGEST_LENGTH) != 0)
{
SendAuthResponseError(AUTH_FAILED);
- TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str());
+ TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, authSession.Account.c_str(), address.c_str());
DelayedCloseSocket();
return;
}
@@ -500,7 +472,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
uint32 recruiter = fields[7].GetUInt32();
uint32 battlenetAccountId = 0;
- if (loginServerType == 1)
+ if (authSession.LoginServerType == 1)
battlenetAccountId = Battlenet::AccountMgr::GetIdByGameAccount(id);
// Checks gmlevel per Realm
@@ -549,8 +521,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
}
TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
- account.c_str(),
- address.c_str());
+ authSession.Account.c_str(), address.c_str());
// Check if this user is by any chance a recruiter
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_RECRUITER);
@@ -567,7 +538,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_IP);
stmt->setString(0, address);
- stmt->setString(1, account);
+ stmt->setString(1, authSession.Account);
LoginDatabase.Execute(stmt);
@@ -577,7 +548,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
_worldSession = new WorldSession(id, battlenetAccountId, shared_from_this(), AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter);
_worldSession->LoadGlobalAccountData();
_worldSession->LoadTutorialsData();
- _worldSession->ReadAddonsInfo(addonsData);
+ _worldSession->ReadAddonsInfo(authSession.AddonInfo);
_worldSession->LoadPermissions();
// Initialize Warden system only if it is enabled by config