/* * 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 "AuthCodes.h" #include "BattlenetBitStream.h" #include "BattlenetSocket.h" #include bool Battlenet::Socket::HandleAuthChallenge(PacketHeader& header, BitStream& packet) { AuthChallenge info(header, packet); info.Read(); printf("%s\n", info.ToString().c_str()); if (info.Program != "WoW") { AuthComplete complete; complete.SetAuthResult(AUTH_INVALID_PROGRAM); Send(complete); return true; } if (!sBattlenetMgr->HasPlatform(info.Platform)) { AuthComplete complete; complete.SetAuthResult(AUTH_INVALID_OS); Send(complete); return true; } if (!sBattlenetMgr->HasPlatform(info.Locale)) { AuthComplete complete; complete.SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE); Send(complete); return true; } for (Component const& component : info.Components) { if (!sBattlenetMgr->HasComponent(&component)) { AuthComplete complete; if (!sBattlenetMgr->HasProgram(component.Program)) complete.SetAuthResult(AUTH_INVALID_PROGRAM); else if (!sBattlenetMgr->HasPlatform(component.Platform)) complete.SetAuthResult(AUTH_INVALID_OS); else complete.SetAuthResult(AUTH_REGION_BAD_VERSION); Send(complete); return true; } } _accountName = info.Login; _locale = info.Locale; _os = info.Platform; ProofRequest request; Send(request); return true; } bool Battlenet::Socket::HandleAuthProofResponse(PacketHeader& header, BitStream& packet) { ProofResponse response(header, packet); response.Read(); printf("%s\n", response.ToString().c_str()); AuthComplete complete; complete.SetAuthResult(AUTH_USE_GRUNT_LOGON); Send(complete); return true; } std::map InitHandlers() { std::map handlers; handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_CHALLENGE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthChallenge; handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_CHALLENGE_NEW, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthChallenge; handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthProofResponse; return handlers; } std::map Handlers = InitHandlers(); Battlenet::Socket::Socket(RealmSocket& socket) : _socket(socket), _currentChannel(0) { } void Battlenet::Socket::OnRead() { while (1) { size_t length = _socket.recv_len(); if (!length) return; BitStream packet(length); if (!_socket.recv((char*)packet.GetBuffer(), length)) return; while (!packet.IsRead()) { try { PacketHeader header; header.Opcode = packet.Read(6); if (packet.Read(1)) _currentChannel = header.Channel = packet.Read(4); else header.Channel = _currentChannel; printf("Battlenet::Socket::OnRead %s\n", header.ToString().c_str()); std::map::const_iterator itr = Handlers.find(header); if (itr != Handlers.end()) { if (!(this->*(itr->second))(header, packet)) { _socket.shutdown(); return; } } else printf("Battlenet::Socket::OnRead Unhandled opcode %s\n", header.ToString().c_str()); packet.AlignToNextByte(); } catch (BitStreamPositionException const& e) { printf("Battlenet::Socket::OnRead Exception: %s\n", e.what()); _socket.shutdown(); return; } } } } void Battlenet::Socket::OnAccept() { printf("Battlenet::Socket::OnAccept\n"); } void Battlenet::Socket::OnClose() { printf("Battlenet::Socket::OnClose\n"); } void Battlenet::Socket::Send(ServerPacket& packet) { printf("Battlenet::Socket::Send %s\n", packet.ToString().c_str()); packet.Write(); _socket.send(reinterpret_cast(packet.GetData()), packet.GetSize()); }