/*
* Copyright (C) 2008-2014 TrinityCore
*
* 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 .
*/
#include "BattlenetPackets.h"
#include "Common.h"
#include "Util.h"
#include
#include
std::string Battlenet::PacketHeader::ToString() const
{
std::ostringstream stream;
stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel;
return stream.str();
}
Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream())
{
_stream.Write(header.Opcode, 6);
_stream.Write(1, 1);
_stream.Write(header.Channel, 4);
}
Battlenet::ServerPacket::~ServerPacket()
{
delete &_stream;
}
void Battlenet::AuthChallenge::Read()
{
Program = _stream.ReadFourCC();
Platform = _stream.ReadFourCC();
Locale = _stream.ReadFourCC();
Components.resize(_stream.Read(6));
for (size_t i = 0; i < Components.size(); ++i)
{
Component& component = Components[i];
component.Program = _stream.ReadFourCC();
component.Platform = _stream.ReadFourCC();
component.Build = _stream.Read(32);
}
if (_stream.Read(1))
Login = _stream.ReadString(9, 3);
if (GetHeader().Opcode == CMSG_AUTH_CHALLENGE_NEW)
_stream.FinishReading();
}
std::string Battlenet::AuthChallenge::ToString() const
{
std::ostringstream stream;
stream << "Battlenet::AuthChallenge Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale;
for (Component const& component : Components)
stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build;
if (!Login.empty())
stream << std::endl << "Battlenet::AuthChallenge Login: " << Login;
return stream.str();
}
Battlenet::ProofRequest::~ProofRequest()
{
for (size_t i = 0; i < Modules.size(); ++i)
delete Modules[i];
}
void Battlenet::ProofRequest::Write()
{
_stream.Write(Modules.size(), 3);
for (ModuleInfo const* info : Modules)
{
_stream.WriteBytes(info->Type.c_str(), 4);
_stream.WriteFourCC(info->Region);
_stream.WriteBytes(info->ModuleId, 32);
_stream.Write(info->DataSize, 10);
_stream.WriteBytes(info->Data, info->DataSize);
}
}
std::string Battlenet::ProofRequest::ToString() const
{
std::ostringstream stream;
stream << "Battlenet::ProofRequest modules " << Modules.size();
for (ModuleInfo const* module : Modules)
stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize);
return stream.str();
}
Battlenet::ProofResponse::~ProofResponse()
{
for (size_t i = 0; i < Modules.size(); ++i)
delete Modules[i];
}
void Battlenet::ProofResponse::Read()
{
Modules.resize(_stream.Read(3));
for (size_t i = 0; i < Modules.size(); ++i)
{
BitStream*& dataStream = Modules[i];
dataStream = new BitStream(_stream.Read(10));
memcpy(dataStream->GetBuffer(), _stream.ReadBytes(dataStream->GetSize()).get(), dataStream->GetSize());
}
}
std::string Battlenet::ProofResponse::ToString() const
{
std::ostringstream stream;
stream << "Battlenet::ProofResponse Modules " << Modules.size();
for (BitStream* module : Modules)
{
std::string hexStr = ByteArrayToHexStr(module->GetBuffer(), module->GetSize());
stream << std::endl << "Battlenet::ProofResponse::ModuleData Size: " << module->GetSize() << ", Data: " << hexStr;
}
return stream.str();
}
void Battlenet::AuthComplete::Write()
{
_stream.Write(Result != 0, 1);
if (Result == 0)
{
_stream.Write(Modules.size(), 3);
for (size_t i = 0; i < Modules.size(); ++i)
{
ModuleInfo& info = Modules[i];
_stream.WriteBytes(info.Type.c_str(), 4);
_stream.WriteFourCC(info.Region);
_stream.WriteBytes(info.ModuleId, 32);
_stream.Write(info.DataSize, 10);
_stream.WriteBytes(info.Data, info.DataSize);
}
_stream.Write(PingTimeout + std::numeric_limits::min(), 32);
_stream.Write(1, 1);
// if written == 1
{
_stream.Write(1, 1);
// if written == 1
{
_stream.Write(Threshold, 32);
_stream.Write(Rate, 32);
}
}
_stream.WriteString(FirstName, 8); // First name
_stream.WriteString(LastName, 8); // Last name - not set for WoW
_stream.Write(GameAccountId, 32);
_stream.Write(2, 8);
_stream.Write(0, 64);
_stream.Write(2, 8);
_stream.WriteString(GameAccountName, 5, -1);
_stream.Write(AccountFlags, 64);
_stream.Write(0, 32);
_stream.Write(0, 1);
}
else
{
_stream.Write(!Modules.empty(), 1);
if (!Modules.empty())
{
ModuleInfo& info = Modules[0];
_stream.WriteBytes(info.Type.c_str(), 4);
_stream.WriteFourCC(info.Region);
_stream.WriteBytes(info.ModuleId, 32);
_stream.Write(info.DataSize, 10);
_stream.WriteBytes(info.Data, info.DataSize);
}
_stream.Write(ErrorType, 2);
if (ErrorType == 1)
{
_stream.Write(Result, 16);
_stream.Write(0x80000000, 32);
}
}
}
std::string Battlenet::AuthComplete::ToString() const
{
return "Battlenet::AuthComplete";
}
void Battlenet::AuthComplete::SetAuthResult(AuthResult result)
{
ErrorType = result != AUTH_OK ? 1 : 0;
Result = result;
}
Battlenet::RealmCharacterCounts::~RealmCharacterCounts()
{
for (ServerPacket* realmData : RealmData)
delete realmData;
}
void Battlenet::RealmCharacterCounts::Write()
{
_stream.Write(false, 1); // failure
_stream.Write(CharacterCounts.size(), 7);
for (CharacterCountEntry const& entry : CharacterCounts)
{
_stream.Write(entry.Realm.Region, 8);
_stream.Write(0, 12);
_stream.Write(entry.Realm.Battlegroup, 8);
_stream.Write(entry.Realm.Index, 32);
_stream.Write(entry.CharacterCount, 16);
}
for (ServerPacket* realmData : RealmData)
{
realmData->Write();
_stream.WriteBytes(realmData->GetData(), realmData->GetSize());
}
}
std::string Battlenet::RealmCharacterCounts::ToString() const
{
std::ostringstream stream;
stream << "Battlenet::RealmCharacterCounts Realms " << CharacterCounts.size();
for (CharacterCountEntry const& entry : CharacterCounts)
stream << std::endl << "Region " << entry.Realm.Region << " Battlegroup " << entry.Realm.Region << " Index " << entry.Realm.Index << " Characters " << entry.CharacterCount;
return stream.str().c_str();
}
void Battlenet::RealmUpdate::Write()
{
_stream.Write(true, 1); // Success
_stream.Write(Timezone, 32);
_stream.WriteFloat(Population);
_stream.Write(Lock, 8);
_stream.Write(0, 19);
_stream.Write(Type + std::numeric_limits::min(), 32);
_stream.WriteString(Name, 10);
_stream.Write(!Version.empty(), 1);
if (!Version.empty())
{
_stream.WriteString(Version, 5);
_stream.Write(Build, 32);
uint32 ip = Address.get_ip_address();
uint16 port = Address.get_port_number();
EndianConvertReverse(ip);
EndianConvertReverse(port);
_stream.WriteBytes(&ip, 4);
_stream.WriteBytes(&port, 2);
}
_stream.Write(Flags, 8);
_stream.Write(Region, 8);
_stream.Write(0, 12);
_stream.Write(Battlegroup, 8);
_stream.Write(Index, 32);
}
std::string Battlenet::RealmUpdate::ToString() const
{
std::ostringstream stream;
stream << "Battlenet::RealmUpdate Timezone " << Timezone << " Population " << Population << " Lock " << Lock << " Type " << Type << " Name " << Name
<< " Flags " << Flags << " Region " << Region << " Battlegroup " << Battlegroup << " Index " << Index;
if (!Version.empty())
stream << " Version " << Version;
return stream.str().c_str();
}
void Battlenet::RealmJoinRequest::Read()
{
ClientSeed = _stream.Read(32);
Unknown = _stream.Read(20);
Realm.Region = _stream.Read(8);
_stream.Read(12);
Realm.Battlegroup = _stream.Read(8);
Realm.Index = _stream.Read(32);
}
std::string Battlenet::RealmJoinRequest::ToString() const
{
std::ostringstream stream;
stream << "Battlenet::RealmJoinRequest ClientSeed" << ClientSeed << " Region " << Realm.Region << " Battlegroup " << Realm.Battlegroup << " Index " << Realm.Index;
return stream.str().c_str();
}
void Battlenet::RealmJoinResult::Write()
{
_stream.Write(0, 1); // Fail
_stream.Write(ServerSeed, 32);
_stream.Write(IPv4.size(), 5);
for (ACE_INET_Addr const& addr : IPv4)
{
uint32 ip = addr.get_ip_address();
uint16 port = addr.get_port_number();
EndianConvertReverse(ip);
EndianConvertReverse(port);
_stream.WriteBytes(&ip, 4);
_stream.WriteBytes(&port, 2);
}
_stream.Write(0, 5); // IPv6 addresses
}
std::string Battlenet::RealmJoinResult::ToString() const
{
return "Battlenet::RealmJoinResult";
}