#include #include "lobby_server.hpp" #include "../services.hpp" #include "../keys.hpp" #include namespace demonware { lobby_server::lobby_server(std::string name) : tcp_server(std::move(name)) { this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); this->register_service(); }; void lobby_server::send_reply(reply* data) { if (!data) return; this->send(data->data()); } void lobby_server::handle(const std::string& packet) { byte_buffer buffer(packet); buffer.set_use_data_types(false); try { while (buffer.has_more_data()) { int size; buffer.read_int32(&size); if (size <= 0) { const std::string zero("\x00\x00\x00\x00", 4); raw_reply reply(zero); this->send_reply(&reply); return; } else if (size == 0xC8) { #ifndef NDEBUG logger::write(logger::LOG_TYPE_DEBUG, "[DW]: [lobby]: received client_header_ack."); #endif int c8; buffer.read_int32(&c8); std::string packet_1 = buffer.get_remaining(); demonware::queue_packet_to_hash(packet_1); /* msgType[BYTE] serverSelectedProto[DWORD] cypher210ConnID[QWORD] serverNonce[QWORD] */ /* 0x81(129) 0xD2(210) 0x3713371337133713 0x3713371337133713 */ const std::string packet_2( "\x16\x00\x00\x00\xab\x81\xd2\x00\x00\x00\x13\x37\x13\x37\x13\x37\x13\x37\x13\x37\x13\x37\x13\x37\x13\x37", 26); demonware::queue_packet_to_hash(packet_2); raw_reply reply(packet_2); this->send_reply(&reply); #ifndef NDEBUG logger::write(logger::LOG_TYPE_DEBUG, "[DW]: [lobby]: sending server_header_ack."); #endif return; } if (buffer.size() < size_t(size)) return; uint8_t check_ab; buffer.read_ubyte(&check_ab); if (check_ab == 0xAB) { uint8_t type; buffer.read_ubyte(&type); if (type == 0x82) { #ifndef NDEBUG logger::write(logger::LOG_TYPE_DEBUG, "[DW]: [lobby]: received client_auth."); #endif std::string packet_3(packet.data(), packet.size() - 8); // this 8 are client hash check? demonware::queue_packet_to_hash(packet_3); demonware::derive_keys_iw8(); char buff[14] = "\x0A\x00\x00\x00\xAB\x83"; std::memcpy(&buff[6], demonware::get_response_id().data(), 8); std::string response(buff, 14); raw_reply reply(response); this->send_reply(&reply); #ifndef NDEBUG logger::write(logger::LOG_TYPE_DEBUG, "[DW]: [lobby]: sending server_auth_done."); #endif return; } else if (type == 0x85) { uint32_t msg_count; buffer.read_uint32(&msg_count); char seed[16]; buffer.read(16, &seed); std::string enc = buffer.get_remaining(); char hash[8]; std::memcpy(hash, &(enc.data()[enc.size() - 8]), 8); std::string dec = utils::cryptography::aes::decrypt( std::string(enc.data(), enc.size() - 8), std::string(seed, 16), demonware::get_decrypt_key()); byte_buffer serv(dec); serv.set_use_data_types(false); uint32_t serv_size; serv.read_uint32(&serv_size); uint8_t magic; // 0x86 serv.read_ubyte(&magic); uint8_t service_id; serv.read_ubyte(&service_id); this->call_service(service_id, serv.get_remaining()); return; } } logger::write(logger::LOG_TYPE_DEBUG, "[DW]: [lobby]: ERROR! received unk message."); return; } } catch (...) { } } void lobby_server::call_service(const uint8_t id, const std::string& data) { const auto& it = this->services_.find(id); if (it != this->services_.end()) { it->second->exec_task(this, data); } else { logger::write(logger::LOG_TYPE_DEBUG, "[DW]: [lobby]: missing service '%s'", utils::string::va("%d", id)); // return no error byte_buffer buffer(data); uint8_t task_id; buffer.read_ubyte(&task_id); this->create_reply(task_id)->send(); } } }