From 4bbc22cc247e1f4a65189bcdaa0e029ed7d0bfe5 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 10 Sep 2016 00:01:37 -0700 Subject: [PATCH] Proof of concept daybreak implementation using login --- common/CMakeLists.txt | 26 +++-- common/database.h | 11 --- common/database_conversions.cpp | 4 +- common/eq_stream.cpp | 1 + common/net/crc32.cpp | 8 +- common/net/eqstream.cpp | 115 +++++++++++++++++++++ common/net/eqstream.h | 75 ++++++++++++++ common/patch/login_sod.cpp | 17 ++++ common/patch/login_sod.h | 15 +++ common/patch/login_titanium.cpp | 17 ++++ common/patch/login_titanium.h | 15 +++ common/patch/patch.cpp | 107 ++++++++++++++++++++ common/patch/patch.h | 53 ++++++++++ libs/format/fmt/format.h | 4 +- loginserver/CMakeLists.txt | 2 +- loginserver/client.cpp | 153 +++++++++++++--------------- loginserver/client.h | 26 +++-- loginserver/client_manager.cpp | 170 +++++++++++--------------------- loginserver/client_manager.h | 35 +++---- loginserver/database_mysql.cpp | 36 +++---- loginserver/main.cpp | 1 - loginserver/server_manager.cpp | 32 +++--- loginserver/world_server.cpp | 36 +++---- zone/client.h | 1 - zone/zone.cpp | 1 - 25 files changed, 648 insertions(+), 313 deletions(-) create mode 100644 common/net/eqstream.cpp create mode 100644 common/net/eqstream.h create mode 100644 common/patch/login_sod.cpp create mode 100644 common/patch/login_sod.h create mode 100644 common/patch/login_titanium.cpp create mode 100644 common/patch/login_titanium.h create mode 100644 common/patch/patch.cpp create mode 100644 common/patch/patch.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e61906c85..fd673a8d7 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -77,7 +77,11 @@ SET(common_sources platform.cpp net/crc32.cpp net/daybreak_connection.cpp + net/eqstream.cpp net/packet.cpp + patch/login_sod.cpp + patch/login_titanium.cpp + patch/patch.cpp patches/patches.cpp patches/sod.cpp patches/sod_limits.cpp @@ -220,7 +224,11 @@ SET(common_headers net/daybreak_connection.h net/daybreak_structs.h net/endian.h + net/eqstream.h net/packet.h + patch/login_sod.h + patch/login_titanium.h + patch/patch.h patches/patches.h patches/sod.h # patches/sod_itemfields.h @@ -275,13 +283,6 @@ SET(common_headers util/memory_stream.h ) -INCLUDE(CheckSymbolExists) -IF(WIN32) - check_symbol_exists(open io.h HAVE_OPEN) -ELSE() - check_symbol_exists(open fcntl.h HAVE_OPEN) -ENDIF() - SOURCE_GROUP(Event FILES event/background_task.h event/event_loop.h @@ -295,10 +296,21 @@ SOURCE_GROUP(Net FILES net/daybreak_connection.h net/daybreak_structs.h net/endian.h + net/eqstream.h + net/eqstream.cpp net/packet.cpp net/packet.h ) +SOURCE_GROUP(Patch FILES + patch/login_sod.cpp + patch/login_sod.h + patch/login_titanium.cpp + patch/login_titanium.h + patch/patch.cpp + patch/patch.h +) + SOURCE_GROUP(Patches FILES patches/patches.h patches/sod.h diff --git a/common/database.h b/common/database.h index 547e741e5..7f936df21 100644 --- a/common/database.h +++ b/common/database.h @@ -79,17 +79,6 @@ struct VarCache_Struct { class PTimerList; -#ifdef _WINDOWS -#if _MSC_VER > 1700 // greater than 2012 (2013+) -# define _ISNAN_(a) std::isnan(a) -#else -# include -# define _ISNAN_(a) _isnan(a) -#endif -#else -# define _ISNAN_(a) std::isnan(a) -#endif - class Database : public DBcore { public: Database(); diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index c282acc94..5c5b7510b 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -1327,7 +1327,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){ if (rquery != ""){ results = QueryDatabase(rquery); } /* Run Bind Home Convert */ - if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) { + if (pp->binds[4].zoneId < 999 && !std::isnan(pp->binds[4].x) && !std::isnan(pp->binds[4].y) && !std::isnan(pp->binds[4].z) && !std::isnan(pp->binds[4].heading)) { rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" " VALUES (%u, %u, %u, %f, %f, %f, %f, 1)", character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading); @@ -1335,7 +1335,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){ } /* Run Bind Convert */ - if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) { + if (pp->binds[0].zoneId < 999 && !std::isnan(pp->binds[0].x) && !std::isnan(pp->binds[0].y) && !std::isnan(pp->binds[0].z) && !std::isnan(pp->binds[0].heading)) { rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" " VALUES (%u, %u, %u, %f, %f, %f, %f, 0)", character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading); diff --git a/common/eq_stream.cpp b/common/eq_stream.cpp index 5a272e201..ac5905930 100644 --- a/common/eq_stream.cpp +++ b/common/eq_stream.cpp @@ -41,6 +41,7 @@ #include #include #include +#include "net\eqstream.h" #endif //for logsys diff --git a/common/net/crc32.cpp b/common/net/crc32.cpp index 63db7cfec..6f6f277ce 100644 --- a/common/net/crc32.cpp +++ b/common/net/crc32.cpp @@ -1,7 +1,7 @@ #include "crc32.h" #include -unsigned int CRC32Table[256] = +unsigned int CRC32EncodeTable[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, @@ -74,7 +74,7 @@ int EQ::Crc32(const void * data, int size) int crc = 0xffffffff; auto buffer = (const uint8_t *)data; for (int i = 0; i < size; ++i) { - crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32Table[(crc ^ *&buffer[i]) & 0x000000FFL]; + crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL]; } return ~crc; @@ -84,12 +84,12 @@ int EQ::Crc32(const void * data, int size, int key) { int crc = 0xffffffff; for (int i = 0; i < 4; ++i) { - crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32Table[(crc ^ ((key >> (i * 8)) & 0xff)) & 0x000000FFL]; + crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ ((key >> (i * 8)) & 0xff)) & 0x000000FFL]; } auto buffer = (const uint8_t *)data; for (int i = 0; i < size; ++i) { - crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32Table[(crc ^ *&buffer[i]) & 0x000000FFL]; + crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL]; } return ~crc; diff --git a/common/net/eqstream.cpp b/common/net/eqstream.cpp new file mode 100644 index 000000000..be7caebe2 --- /dev/null +++ b/common/net/eqstream.cpp @@ -0,0 +1,115 @@ +#include "eqstream.h" +#include + +EQ::Net::EQStreamManager::EQStreamManager(EQStreamManagerOptions &options) : m_daybreak(options.daybreak_options) +{ + m_options = options; + + m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1)); + m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2)); +} + +EQ::Net::EQStreamManager::~EQStreamManager() +{ +} + +void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr connection) +{ + std::shared_ptr stream(new EQStream(this, connection)); + m_streams.insert(std::make_pair(connection, stream)); + if (m_on_new_connection) { + m_on_new_connection(stream); + } +} + +void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr connection, DbProtocolStatus from, DbProtocolStatus to) +{ + auto iter = m_streams.find(connection); + if (iter != m_streams.end()) { + if (m_on_connection_state_change) { + m_on_connection_state_change(iter->second, from, to); + } + + if (to == EQ::Net::StatusDisconnected) { + m_streams.erase(iter); + } + } +} + +void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr connection, Packet &p) +{ + auto iter = m_streams.find(connection); + if (iter != m_streams.end()) { + auto patch = iter->second->GetRegisteredPatch(); + if (patch == nullptr && m_possible_patches.size() > 0) { + for (auto &pt : m_possible_patches) { + auto match = pt->TryIdentityMatch(p); + if (match == EQ::Patches::IdentityMatchSuccess) { + iter->second->RegisterPatch(pt.get()); + patch = pt.get(); + Log.OutF(Logs::General, Logs::Debug, "Identified patch with name {0}", pt->GetName()); + } + } + } + + if (patch) { + EmuOpcode opcode; + EQ::Net::WritablePacket out; + patch->Decode(&p, opcode, out); + + if (opcode == OP_Unknown) { + Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because the opcode was not found.\n{0}", p.ToString()); + } + else { + if (m_on_packet_recv) { + m_on_packet_recv(iter->second, opcode, out); + } + } + } + else { + Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because we don't have a patch set.\n{0}", p.ToString()); + } + } +} + +EQ::Net::EQStream::EQStream(EQStreamManager *owner, std::shared_ptr connection) +{ + m_owner = owner; + m_connection = connection; + m_patch = nullptr; +} + +EQ::Net::EQStream::~EQStream() +{ +} + +void EQ::Net::EQStream::QueuePacket(EmuOpcode type, Packet &p) +{ + if (m_patch) { + EQ::Net::WritablePacket trans; + m_patch->Encode(m_connection, type, &p); + } +} + +void EQ::Net::EQStream::ResetStats() +{ + m_connection->ResetStats(); +} + +void EQ::Net::EQStream::Close() +{ +} + +void EQ::Net::EQStream::QueuePacket(EQApplicationPacket *p) +{ + EQ::Net::ReadOnlyPacket out(p->pBuffer, p->size); + QueuePacket(p->GetOpcode(), out); + +} + +void EQ::Net::EQStream::FastQueuePacket(EQApplicationPacket **p) +{ + QueuePacket(*p); + delete *p; +} \ No newline at end of file diff --git a/common/net/eqstream.h b/common/net/eqstream.h new file mode 100644 index 000000000..04aef0d2a --- /dev/null +++ b/common/net/eqstream.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include "daybreak_connection.h" +#include + +namespace EQ +{ + namespace Net + { + struct EQStreamManagerOptions + { + EQStreamManagerOptions() { + compressed = false; + } + + DaybreakConnectionManagerOptions daybreak_options; + bool compressed; + }; + + class EQStream; + class EQStreamManager + { + public: + EQStreamManager(EQStreamManagerOptions &options); + ~EQStreamManager(); + + void OnNewConnection(std::function)> func) { m_on_new_connection = func; } + void OnConnectionStateChange(std::function, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; } + void OnPacketRecv(std::function, EmuOpcode, Packet &)> func) { m_on_packet_recv = func; } + + void RegisterPotentialPatch(EQ::Patches::BasePatch *patch) { m_possible_patches.push_back(std::unique_ptr(patch)); } + private: + EQStreamManagerOptions m_options; + DaybreakConnectionManager m_daybreak; + std::function)> m_on_new_connection; + std::function, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change; + std::function, EmuOpcode, Packet &)> m_on_packet_recv; + std::map, std::shared_ptr> m_streams; + std::vector> m_possible_patches; + + void DaybreakNewConnection(std::shared_ptr connection); + void DaybreakConnectionStateChange(std::shared_ptr connection, DbProtocolStatus from, DbProtocolStatus to); + void DaybreakPacketRecv(std::shared_ptr connection, Packet &p); + friend class EQStream; + }; + + class EQStream + { + public: + EQStream(EQStreamManager *parent, std::shared_ptr connection); + ~EQStream(); + + const std::string& RemoteEndpoint() const { return m_connection->RemoteEndpoint(); } + int RemotePort() const { return m_connection->RemotePort(); } + + void QueuePacket(EmuOpcode type, Packet &p); + const DaybreakConnectionStats& GetStats() const { return m_connection->GetStats(); } + void ResetStats(); + size_t GetRollingPing() const { return m_connection->GetRollingPing(); } + void Close(); + void QueuePacket(EQApplicationPacket *p); + void FastQueuePacket(EQApplicationPacket **p); + + void RegisterPatch(EQ::Patches::BasePatch *p) { m_patch = p; } + EQ::Patches::BasePatch *GetRegisteredPatch() { return m_patch; } + private: + EQStreamManager *m_owner; + std::shared_ptr m_connection; + EQ::Patches::BasePatch *m_patch; + friend class EQStreamManager; + }; + } +} diff --git a/common/patch/login_sod.cpp b/common/patch/login_sod.cpp new file mode 100644 index 000000000..9228fb4d0 --- /dev/null +++ b/common/patch/login_sod.cpp @@ -0,0 +1,17 @@ +#include "login_sod.h" + +EQ::Patches::LoginSoDPatch::LoginSoDPatch() +{ + m_opcode_manager.reset(new RegularOpcodeManager()); + if (!m_opcode_manager->LoadOpcodes("login_opcodes_sod.conf")) { + m_opcode_manager.release(); + } + + m_signature.match_message_opcode = 0x01; + m_signature.match_message_size = 0; + m_message_size = 2; +} + +EQ::Patches::LoginSoDPatch::~LoginSoDPatch() +{ +} diff --git a/common/patch/login_sod.h b/common/patch/login_sod.h new file mode 100644 index 000000000..56a1f928b --- /dev/null +++ b/common/patch/login_sod.h @@ -0,0 +1,15 @@ +#include + +namespace EQ +{ + namespace Patches + { + class LoginSoDPatch : public BasePatch + { + public: + LoginSoDPatch(); + virtual ~LoginSoDPatch(); + virtual std::string GetName() const { return "Login SoD+"; } + }; + } +} \ No newline at end of file diff --git a/common/patch/login_titanium.cpp b/common/patch/login_titanium.cpp new file mode 100644 index 000000000..3ccdaabcf --- /dev/null +++ b/common/patch/login_titanium.cpp @@ -0,0 +1,17 @@ +#include "login_titanium.h" + +EQ::Patches::LoginTitaniumPatch::LoginTitaniumPatch() +{ + m_opcode_manager.reset(new RegularOpcodeManager()); + if (!m_opcode_manager->LoadOpcodes("login_opcodes_titanium.conf")) { + m_opcode_manager.release(); + } + + m_signature.match_message_opcode = 0x01; + m_signature.match_message_size = 0; + m_message_size = 2; +} + +EQ::Patches::LoginTitaniumPatch::~LoginTitaniumPatch() +{ +} diff --git a/common/patch/login_titanium.h b/common/patch/login_titanium.h new file mode 100644 index 000000000..8b8e45c99 --- /dev/null +++ b/common/patch/login_titanium.h @@ -0,0 +1,15 @@ +#include + +namespace EQ +{ + namespace Patches + { + class LoginTitaniumPatch : public BasePatch + { + public: + LoginTitaniumPatch(); + virtual ~LoginTitaniumPatch(); + virtual std::string GetName() const { return "Login Titanium"; } + }; + } +} \ No newline at end of file diff --git a/common/patch/patch.cpp b/common/patch/patch.cpp new file mode 100644 index 000000000..b7bbfef4a --- /dev/null +++ b/common/patch/patch.cpp @@ -0,0 +1,107 @@ +#include "patch.h" +#include + +EQ::Patches::IdentityMatchStatus EQ::Patches::BasePatch::TryIdentityMatch(const EQ::Net::Packet &p) const +{ + if (p.Length() < m_message_size) { + return IdentityMatchFailure; + } + + int raw_opcode = 0; + switch (m_message_size) { + case 1: + raw_opcode = *(uint8_t*)p.Data(); + break; + case 2: + raw_opcode = *(uint16_t*)p.Data(); + break; + default: + return IdentityMatchFailure; + } + + if (m_signature.match_message_opcode != raw_opcode) { + return IdentityMatchFailure; + } + + if (m_signature.match_message_size > 0 && m_signature.match_message_size != p.Length() - m_message_size) { + return IdentityMatchFailure; + } + + return IdentityMatchSuccess; +} + +void EQ::Patches::BasePatch::Decode(const EQ::Net::Packet *in, EmuOpcode &opcode, EQ::Net::WritablePacket &out) +{ + int raw_opcode = 0; + switch (m_message_size) { + case 1: + raw_opcode = *(uint8_t*)in->Data(); + break; + case 2: + raw_opcode = *(uint16_t*)in->Data(); + break; + default: + opcode = OP_Unknown; + return; + } + + opcode = m_opcode_manager->EQToEmu(raw_opcode); + if (opcode == OP_Unknown) { + out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size); + return; + } + + auto decode_iter = m_decode.find(opcode); + if (decode_iter != m_decode.end()) { + EQ::Net::ReadOnlyPacket p((uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size); + decode_iter->second(&p, opcode, out); + } + else { + out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size); + } +} + +void EQ::Patches::BasePatch::Encode(std::shared_ptr connection, EmuOpcode opcode, const EQ::Net::Packet *in) +{ + auto encode_iter = m_encode.find(opcode); + if (encode_iter != m_encode.end()) { + encode_iter->second(connection, opcode, in); + } + else { + SendPacket(connection, opcode, in); + } +} + +void EQ::Patches::BasePatch::RegisterDecode(int protocol_number, DecodeStructFunction f) +{ + m_decode.insert(std::make_pair(protocol_number, f)); +} + +void EQ::Patches::BasePatch::RegisterEncode(EmuOpcode opcode, EncodeStructFunction f) +{ + m_encode.insert(std::make_pair(opcode, f)); +} + +void EQ::Patches::BasePatch::SendPacket(std::shared_ptr connection, EmuOpcode opcode, const EQ::Net::Packet *p) +{ + if (!m_opcode_manager) { + return; + } + + auto raw_opcode = m_opcode_manager->EmuToEQ(opcode); + EQ::Net::WritablePacket out; + switch (m_message_size) { + case 1: + out.PutUInt8(0, (uint8_t)raw_opcode); + out.PutPacket(1, *p); + break; + case 2: + out.PutUInt16(0, raw_opcode); + out.PutPacket(2, *p); + break; + default: + return; + } + + connection->QueuePacket(out); +} diff --git a/common/patch/patch.h b/common/patch/patch.h new file mode 100644 index 000000000..6de68a432 --- /dev/null +++ b/common/patch/patch.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace EQ +{ + namespace Patches + { + enum IdentityMatchStatus + { + IdentityMatchFailure, + IdentityMatchSuccess + }; + + struct Signature + { + int match_message_opcode; + size_t match_message_size; + }; + + class BasePatch + { + public: + typedef std::function DecodeStructFunction; + typedef std::function, EmuOpcode, const EQ::Net::Packet*)> EncodeStructFunction; + + BasePatch() { } + virtual ~BasePatch() { } + virtual std::string GetName() const = 0; + + IdentityMatchStatus TryIdentityMatch(const EQ::Net::Packet &p) const; + + void Decode(const EQ::Net::Packet *in, EmuOpcode& opcode, EQ::Net::WritablePacket& out); + void Encode(std::shared_ptr connection, EmuOpcode opcode, const EQ::Net::Packet *in); + + void RegisterDecode(int protocol_number, DecodeStructFunction f); + void RegisterEncode(EmuOpcode opcode, EncodeStructFunction f); + protected: + void SendPacket(std::shared_ptr connection, EmuOpcode opcode, const EQ::Net::Packet *p); + + std::unique_ptr m_opcode_manager; + std::map m_decode; + std::map m_encode; + Signature m_signature; + int m_message_size; + }; + } +} diff --git a/libs/format/fmt/format.h b/libs/format/fmt/format.h index b67c2e20b..47a8b74d8 100644 --- a/libs/format/fmt/format.h +++ b/libs/format/fmt/format.h @@ -297,7 +297,9 @@ inline DummyInt _ecvt_s(...) { return DummyInt(); } inline DummyInt isinf(...) { return DummyInt(); } inline DummyInt _finite(...) { return DummyInt(); } inline DummyInt isnan(...) { return DummyInt(); } -//inline DummyInt _isnan(...) { return DummyInt(); } +#ifndef _MSC_VER +inline DummyInt _isnan(...) { return DummyInt(); } +#endif // A helper function to suppress bogus "conditional expression is constant" // warnings. diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index 73f5a07ef..f239e6ce2 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -41,7 +41,7 @@ ADD_EXECUTABLE(loginserver ${eqlogin_sources} ${eqlogin_headers}) INSTALL(TARGETS loginserver RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) -TARGET_LINK_LIBRARIES(loginserver common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv) +TARGET_LINK_LIBRARIES(loginserver common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt) IF(WIN32) TARGET_LINK_LIBRARIES(loginserver "ws2_32" "psapi" "iphlpapi" "userenv") diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 9a6a81593..5b6540ed8 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -18,13 +18,13 @@ #include "client.h" #include "login_server.h" #include "login_structures.h" -#include "../common/misc_functions.h" -#include "../common/eqemu_logsys.h" +#include +#include extern EQEmuLogSys Log; extern LoginServer server; -Client::Client(std::shared_ptr c, LSClientVersion v) +Client::Client(std::shared_ptr c, LSClientVersion v) { connection = c; version = v; @@ -34,82 +34,73 @@ Client::Client(std::shared_ptr c, LSClientVersion v) play_sequence_id = 0; } -bool Client::Process() +void Client::Process(EQApplicationPacket *app) { - EQApplicationPacket *app = connection->PopPacket(); - while(app) + if(server.options.IsTraceOn()) { - if(server.options.IsTraceOn()) - { - Log.Out(Logs::General, Logs::Login_Server, "Application packet received from client (size %u)", app->Size()); - } - - if(server.options.IsDumpInPacketsOn()) - { - DumpPacket(app); - } - - switch(app->GetOpcode()) - { - case OP_SessionReady: - { - if(server.options.IsTraceOn()) - { - Log.Out(Logs::General, Logs::Login_Server, "Session ready received from client."); - } - Handle_SessionReady((const char*)app->pBuffer, app->Size()); - break; - } - case OP_Login: - { - if(app->Size() < 20) - { - Log.Out(Logs::General, Logs::Error, "Login received but it is too small, discarding."); - break; - } - - if(server.options.IsTraceOn()) - { - Log.Out(Logs::General, Logs::Login_Server, "Login received from client."); - } - - Handle_Login((const char*)app->pBuffer, app->Size()); - break; - } - case OP_ServerListRequest: - { - if(server.options.IsTraceOn()) - { - Log.Out(Logs::General, Logs::Login_Server, "Server list request received from client."); - } - - SendServerListPacket(); - break; - } - case OP_PlayEverquestRequest: - { - if(app->Size() < sizeof(PlayEverquestRequest_Struct)) - { - Log.Out(Logs::General, Logs::Error, "Play received but it is too small, discarding."); - break; - } - - Handle_Play((const char*)app->pBuffer); - break; - } - default: - { - char dump[64]; - app->build_header_dump(dump); - Log.Out(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump); - } - } - - delete app; - app = connection->PopPacket(); + Log.Out(Logs::General, Logs::Login_Server, "Application packet received from client (size %u)", app->Size()); + } + + if(server.options.IsDumpInPacketsOn()) + { + DumpPacket(app); + } + + switch(app->GetOpcode()) + { + case OP_SessionReady: + { + if(server.options.IsTraceOn()) + { + Log.Out(Logs::General, Logs::Login_Server, "Session ready received from client."); + } + Handle_SessionReady((const char*)app->pBuffer, app->Size()); + break; + } + case OP_Login: + { + if(app->Size() < 20) + { + Log.Out(Logs::General, Logs::Error, "Login received but it is too small, discarding."); + break; + } + + if(server.options.IsTraceOn()) + { + Log.Out(Logs::General, Logs::Login_Server, "Login received from client."); + } + + Handle_Login((const char*)app->pBuffer, app->Size()); + break; + } + case OP_ServerListRequest: + { + if(server.options.IsTraceOn()) + { + Log.Out(Logs::General, Logs::Login_Server, "Server list request received from client."); + } + + SendServerListPacket(); + break; + } + case OP_PlayEverquestRequest: + { + if(app->Size() < sizeof(PlayEverquestRequest_Struct)) + { + Log.Out(Logs::General, Logs::Error, "Play received but it is too small, discarding."); + break; + } + + Handle_Play((const char*)app->pBuffer); + break; + } + default: + { + char dump[64]; + app->build_header_dump(dump); + Log.Out(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump); + } } - - return true; } void Client::Handle_SessionReady(const char* data, unsigned int size) @@ -187,13 +178,13 @@ void Client::Handle_Login(const char* data, unsigned int size) status = cs_logged_in; - string entered_username; - string entered_password_hash_result; + std::string entered_username; + std::string entered_password_hash_result; char *login_packet_buffer = nullptr; unsigned int db_account_id = 0; - string db_account_password_hash; + std::string db_account_password_hash; #ifdef WIN32 login_packet_buffer = server.eq_crypto->DecryptUsernamePassword(data, size, server.options.GetEncryptionMode()); @@ -252,10 +243,8 @@ void Client::Handle_Login(const char* data, unsigned int size) server.client_manager->RemoveExistingClient(db_account_id); - in_addr in; - in.s_addr = connection->GetRemoteIP(); - server.db->UpdateLSAccountData(db_account_id, string(inet_ntoa(in))); + server.db->UpdateLSAccountData(db_account_id, connection->RemoteEndpoint()); GenerateKey(); account_id = db_account_id; diff --git a/loginserver/client.h b/loginserver/client.h index 0f5efb1f1..a30ac30b2 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -18,18 +18,14 @@ #ifndef EQEMU_CLIENT_H #define EQEMU_CLIENT_H -#include "../common/global_define.h" -#include "../common/opcodemgr.h" -#include "../common/eq_stream_type.h" -#include "../common/eq_stream_factory.h" -#include "../common/random.h" +#include +#include +#include #ifndef WIN32 #include "eq_crypto_api.h" #endif #include -using namespace std; - enum LSClientVersion { cv_titanium, @@ -59,7 +55,7 @@ public: /** * Constructor, sets our connection to c and version to v */ - Client(std::shared_ptr c, LSClientVersion v); + Client(std::shared_ptr c, LSClientVersion v); /** * Destructor. @@ -69,7 +65,7 @@ public: /** * Processes the client's connection and does various actions. */ - bool Process(); + void Process(EQApplicationPacket *app); /** * Sends our reply to session ready packet. @@ -109,12 +105,12 @@ public: /** * Gets the account name of this client. */ - string GetAccountName() const { return account_name; } + std::string GetAccountName() const { return account_name; } /** * Gets the key generated at login for this client. */ - string GetKey() const { return key; } + std::string GetKey() const { return key; } /** * Gets the server selected to be played on for this client. @@ -129,19 +125,19 @@ public: /** * Gets the connection for this client. */ - std::shared_ptr GetConnection() { return connection; } + std::shared_ptr GetConnection() { return connection; } EQEmu::Random random; private: - std::shared_ptr connection; + std::shared_ptr connection; LSClientVersion version; LSClientStatus status; - string account_name; + std::string account_name; unsigned int account_id; unsigned int play_server_id; unsigned int play_sequence_id; - string key; + std::string key; }; #endif diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index c600d58f5..4961e1c2a 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -17,148 +17,89 @@ */ #include "client_manager.h" #include "login_server.h" +#include extern LoginServer server; extern bool run_server; -#include "../common/eqemu_logsys.h" -extern EQEmuLogSys Log; - ClientManager::ClientManager() { - int titanium_port = atoi(server.config->GetVariable("Titanium", "port").c_str()); - titanium_stream = new EQStreamFactory(LoginStream, titanium_port); - titanium_ops = new RegularOpcodeManager; - if(!titanium_ops->LoadOpcodes(server.config->GetVariable("Titanium", "opcodes").c_str())) - { - Log.Out(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for Titanium file %s.", - server.config->GetVariable("Titanium", "opcodes").c_str()); - run_server = false; - } + EQ::Net::EQStreamManagerOptions titanium_opts; + titanium_opts.daybreak_options.port = atoi(server.config->GetVariable("Titanium", "port").c_str()); + titanium_stream.reset(new EQ::Net::EQStreamManager(titanium_opts)); + titanium_patch.reset(new EQ::Patches::LoginTitaniumPatch()); + titanium_stream->RegisterPotentialPatch(titanium_patch.get()); - if(titanium_stream->Open()) - { - Log.Out(Logs::General, Logs::Login_Server, "ClientManager listening on Titanium stream."); - } - else - { - Log.Out(Logs::General, Logs::Error, "ClientManager fatal error: couldn't open Titanium stream."); - run_server = false; - } + titanium_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionSod, this, std::placeholders::_1)); + titanium_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionTitanium, this, std::placeholders::_1)); + titanium_stream->OnConnectionStateChange(std::bind(&ClientManager::HandleConnectionChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + titanium_stream->OnPacketRecv(std::bind(&ClientManager::HandlePacket, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + + EQ::Net::EQStreamManagerOptions sod_opts; + sod_opts.daybreak_options.port = atoi(server.config->GetVariable("SoD", "port").c_str()); + sod_stream.reset(new EQ::Net::EQStreamManager(sod_opts)); + sod_patch.reset(new EQ::Patches::LoginSoDPatch()); + sod_stream->RegisterPotentialPatch(sod_patch.get()); + + sod_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionSod, this, std::placeholders::_1)); + sod_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionSod, this, std::placeholders::_1)); + sod_stream->OnConnectionStateChange(std::bind(&ClientManager::HandleConnectionChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + sod_stream->OnPacketRecv(std::bind(&ClientManager::HandlePacket, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - int sod_port = atoi(server.config->GetVariable("SoD", "port").c_str()); - sod_stream = new EQStreamFactory(LoginStream, sod_port); - sod_ops = new RegularOpcodeManager; - if(!sod_ops->LoadOpcodes(server.config->GetVariable("SoD", "opcodes").c_str())) - { - Log.Out(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for SoD file %s.", - server.config->GetVariable("SoD", "opcodes").c_str()); - run_server = false; - } - if(sod_stream->Open()) - { - Log.Out(Logs::General, Logs::Login_Server, "ClientManager listening on SoD stream."); - } - else - { - Log.Out(Logs::General, Logs::Error, "ClientManager fatal error: couldn't open SoD stream."); - run_server = false; - } } ClientManager::~ClientManager() { - if(titanium_stream) - { - titanium_stream->Close(); - delete titanium_stream; - } - if(titanium_ops) - { - delete titanium_ops; - } - - if(sod_stream) - { - sod_stream->Close(); - delete sod_stream; - } - - if(sod_ops) - { - delete sod_ops; - } } -void ClientManager::Process() +void ClientManager::HandleNewConnectionTitanium(std::shared_ptr connection) { - ProcessDisconnect(); - std::shared_ptr cur = titanium_stream->Pop(); - while(cur) - { - struct in_addr in; - in.s_addr = cur->GetRemoteIP(); - Log.Out(Logs::General, Logs::Login_Server, "New Titanium client connection from %s:%d", inet_ntoa(in), ntohs(cur->GetRemotePort())); + Log.OutF(Logs::General, Logs::Login_Server, "New Titanium client from {0}:{1}", connection->RemoteEndpoint(), connection->RemotePort()); + Client *c = new Client(connection, cv_titanium); + clients.push_back(std::unique_ptr(c)); +} - cur->SetOpcodeManager(&titanium_ops); - Client *c = new Client(cur, cv_titanium); - clients.push_back(c); - cur = titanium_stream->Pop(); - } +void ClientManager::HandleNewConnectionSod(std::shared_ptr connection) +{ + Log.OutF(Logs::General, Logs::Login_Server, "New SoD client from {0}:{1}", connection->RemoteEndpoint(), connection->RemotePort()); + Client *c = new Client(connection, cv_sod); + clients.push_back(std::unique_ptr(c)); +} - cur = sod_stream->Pop(); - while(cur) - { - struct in_addr in; - in.s_addr = cur->GetRemoteIP(); - Log.Out(Logs::General, Logs::Login_Server, "New SoD client connection from %s:%d", inet_ntoa(in), ntohs(cur->GetRemotePort())); - - cur->SetOpcodeManager(&sod_ops); - Client *c = new Client(cur, cv_sod); - clients.push_back(c); - cur = sod_stream->Pop(); - } - - list::iterator iter = clients.begin(); - while(iter != clients.end()) - { - if((*iter)->Process() == false) - { - Log.Out(Logs::General, Logs::Debug, "Client had a fatal error and had to be removed from the login."); - delete (*iter); - iter = clients.erase(iter); - } - else - { +void ClientManager::HandleConnectionChange(std::shared_ptr connection, EQ::Net::DbProtocolStatus old_status, EQ::Net::DbProtocolStatus new_status) +{ + if (new_status == EQ::Net::DbProtocolStatus::StatusDisconnected) { + Log.OutF(Logs::General, Logs::Login_Server, "Client has been disconnected, removing {0}:{1}", connection->RemoteEndpoint(), connection->RemotePort()); + auto iter = clients.begin(); + while (iter != clients.end()) { + if ((*iter)->GetConnection() == connection) { + clients.erase(iter); + break; + } ++iter; } } } -void ClientManager::ProcessDisconnect() +void ClientManager::HandlePacket(std::shared_ptr connection, EmuOpcode opcode, EQ::Net::Packet &p) { - list::iterator iter = clients.begin(); - while(iter != clients.end()) - { - std::shared_ptr c = (*iter)->GetConnection(); - if(c->CheckClosed()) - { - Log.Out(Logs::General, Logs::Login_Server, "Client disconnected from the server, removing client."); - delete (*iter); - iter = clients.erase(iter); - } - else - { - ++iter; + auto iter = clients.begin(); + while (iter != clients.end()) { + if ((*iter)->GetConnection() == connection) { + EQApplicationPacket app(opcode, (unsigned char*)p.Data(), (uint32)p.Length()); + (*iter)->Process(&app); + return; } + + ++iter; } } void ClientManager::UpdateServerList() { - list::iterator iter = clients.begin(); + auto iter = clients.begin(); while(iter != clients.end()) { (*iter)->SendServerListPacket(); @@ -168,13 +109,12 @@ void ClientManager::UpdateServerList() void ClientManager::RemoveExistingClient(unsigned int account_id) { - list::iterator iter = clients.begin(); + auto iter = clients.begin(); while(iter != clients.end()) { if((*iter)->GetAccountID() == account_id) { Log.Out(Logs::General, Logs::Login_Server, "Client attempting to log in and existing client already logged in, removing existing client."); - delete (*iter); iter = clients.erase(iter); } else @@ -188,12 +128,12 @@ Client *ClientManager::GetClient(unsigned int account_id) { Client *cur = nullptr; int count = 0; - list::iterator iter = clients.begin(); + auto iter = clients.begin(); while(iter != clients.end()) { if((*iter)->GetAccountID() == account_id) { - cur = (*iter); + cur = (*iter).get(); count++; } ++iter; diff --git a/loginserver/client_manager.h b/loginserver/client_manager.h index dc7637776..b76e1d761 100644 --- a/loginserver/client_manager.h +++ b/loginserver/client_manager.h @@ -18,14 +18,13 @@ #ifndef EQEMU_CLIENTMANAGER_H #define EQEMU_CLIENTMANAGER_H -#include "../common/global_define.h" -#include "../common/opcodemgr.h" -#include "../common/eq_stream_type.h" -#include "../common/eq_stream_factory.h" +#include +#include +#include +#include #include "client.h" #include - -using namespace std; +#include /** * Client manager class, holds all the client objects and does basic processing. @@ -43,11 +42,6 @@ public: */ ~ClientManager(); - /** - * Processes every client in the internal list, removes them if necessary. - */ - void Process(); - /** * Sends a new server list to every client. */ @@ -63,17 +57,16 @@ public: */ Client *GetClient(unsigned int account_id); private: + void HandleNewConnectionTitanium(std::shared_ptr connection); + void HandleNewConnectionSod(std::shared_ptr connection); + void HandleConnectionChange(std::shared_ptr connection, EQ::Net::DbProtocolStatus old_status, EQ::Net::DbProtocolStatus new_status); + void HandlePacket(std::shared_ptr connection, EmuOpcode opcode, EQ::Net::Packet &p); - /** - * Processes disconnected clients, removes them if necessary. - */ - void ProcessDisconnect(); - - list clients; - OpcodeManager *titanium_ops; - EQStreamFactory *titanium_stream; - OpcodeManager *sod_ops; - EQStreamFactory *sod_stream; + std::list> clients; + std::unique_ptr titanium_stream; + std::unique_ptr sod_stream; + std::unique_ptr titanium_patch; + std::unique_ptr sod_patch; }; #endif diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index b9536de7e..d11e38cb7 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -26,7 +26,7 @@ extern EQEmuLogSys Log; extern LoginServer server; -DatabaseMySQL::DatabaseMySQL(string user, string pass, string host, string port, string name) +DatabaseMySQL::DatabaseMySQL(std::string user, std::string pass, std::string host, std::string port, std::string name) { this->user = user; this->pass = pass; @@ -59,7 +59,7 @@ DatabaseMySQL::~DatabaseMySQL() } } -bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, unsigned int &id) +bool DatabaseMySQL::GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id) { if (!database) { @@ -68,7 +68,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, u MYSQL_RES *res; MYSQL_ROW row; - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() << " WHERE AccountName = '"; query << name; query << "'"; @@ -97,7 +97,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, u } -bool DatabaseMySQL::CreateLoginData(string name, string &password, unsigned int &id) +bool DatabaseMySQL::CreateLoginData(std::string name, std::string &password, unsigned int &id) { if (!database) { return false; @@ -105,7 +105,7 @@ bool DatabaseMySQL::CreateLoginData(string name, string &password, unsigned int MYSQL_RES *result; MYSQL_ROW row; - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "INSERT INTO " << server.options.GetAccountTable() << " (AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) "; query << " VALUES('" << name << "', '" << password << "', 'local_creation', NOW(), '127.0.0.1'); "; @@ -123,8 +123,8 @@ bool DatabaseMySQL::CreateLoginData(string name, string &password, unsigned int return false; } -bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, unsigned int &id, string &desc, unsigned int &list_id, - unsigned int &trusted, string &list_desc, string &account, string &password) +bool DatabaseMySQL::GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, + unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password) { if (!database) { @@ -137,7 +137,7 @@ bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, un unsigned long length; length = mysql_real_escape_string(database, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length()); escaped_short_name[length + 1] = 0; - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT ifnull(WSR.ServerID,999999) AS ServerID, WSR.ServerTagDescription, ifnull(WSR.ServerTrusted,0) AS ServerTrusted, ifnull(SLT.ServerListTypeID,3) AS ServerListTypeID, "; query << "SLT.ServerListTypeDescription, ifnull(WSR.ServerAdminID,0) AS ServerAdminID FROM " << server.options.GetWorldRegistrationTable(); query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID"; @@ -166,7 +166,7 @@ bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, un if (db_account_id > 0) { - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT AccountName, AccountPassword FROM " << server.options.GetWorldAdminRegistrationTable(); query << " WHERE ServerAdminID = " << db_account_id; @@ -199,14 +199,14 @@ bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, un return false; } -void DatabaseMySQL::UpdateLSAccountData(unsigned int id, string ip_address) +void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) { if (!database) { return; } - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "UPDATE " << server.options.GetAccountTable() << " SET LastIPAddress = '"; query << ip_address; query << "', LastLoginDate = now() where LoginServerID = "; @@ -218,14 +218,14 @@ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, string ip_address) } } -void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, string name, string password, string email) +void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) { if (!database) { return; } - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "REPLACE " << server.options.GetAccountTable() << " SET LoginServerID = "; query << id << ", AccountName = '" << name << "', AccountPassword = sha('"; query << password << "'), AccountCreateDate = now(), AccountEmail = '" << email; @@ -237,7 +237,7 @@ void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, string name, string pas } } -void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, string long_name, string ip_address) +void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { if (!database) { @@ -248,7 +248,7 @@ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, string long_name, s unsigned long length; length = mysql_real_escape_string(database, escaped_long_name, long_name.substr(0, 100).c_str(), long_name.substr(0, 100).length()); escaped_long_name[length + 1] = 0; - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "UPDATE " << server.options.GetWorldRegistrationTable() << " SET ServerLastLoginDate = now(), ServerLastIPAddr = '"; query << ip_address; query << "', ServerLongName = '"; @@ -262,7 +262,7 @@ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, string long_name, s } } -bool DatabaseMySQL::CreateWorldRegistration(string long_name, string short_name, unsigned int &id) +bool DatabaseMySQL::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { if (!database) { @@ -278,7 +278,7 @@ bool DatabaseMySQL::CreateWorldRegistration(string long_name, string short_name, escaped_long_name[length + 1] = 0; length = mysql_real_escape_string(database, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length()); escaped_short_name[length + 1] = 0; - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT ifnull(max(ServerID),0) FROM " << server.options.GetWorldRegistrationTable(); if (mysql_query(database, query.str().c_str()) != 0) @@ -295,7 +295,7 @@ bool DatabaseMySQL::CreateWorldRegistration(string long_name, string short_name, id = atoi(row[0]) + 1; mysql_free_result(res); - stringstream query(stringstream::in | stringstream::out); + std::stringstream query(std::stringstream::in | std::stringstream::out); query << "INSERT INTO " << server.options.GetWorldRegistrationTable() << " SET ServerID = " << id; query << ", ServerLongName = '" << escaped_long_name << "', ServerShortName = '" << escaped_short_name; query << "', ServerListTypeID = 3, ServerAdminID = 0, ServerTrusted = 0, ServerTagDescription = ''"; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 3beb2e054..2abcd35b7 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -199,7 +199,6 @@ int main() Log.Out(Logs::General, Logs::Login_Server, "Server Started."); EQ::Timer timer(10, true, []() { Timer::SetCurrentTime(); - server.client_manager->Process(); server.server_manager->Process(); timeout_manager.CheckTimeouts(); }); diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 87e269854..c9dad9e42 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -71,7 +71,7 @@ void ServerManager::Process() } } - list::iterator iter = world_servers.begin(); + auto iter = world_servers.begin(); while (iter != world_servers.end()) { if ((*iter)->Process() == false) { Log.Out(Logs::General, Logs::World_Server, "World server %s had a fatal error and had to be removed from the login.", (*iter)->GetLongName().c_str()); @@ -86,7 +86,7 @@ void ServerManager::Process() void ServerManager::ProcessDisconnect() { - list::iterator iter = world_servers.begin(); + auto iter = world_servers.begin(); while (iter != world_servers.end()) { EmuTCPConnection *connection = (*iter)->GetConnection(); if (!connection->Connected()) { @@ -105,7 +105,7 @@ void ServerManager::ProcessDisconnect() WorldServer* ServerManager::GetServerByAddress(unsigned int address) { - list::iterator iter = world_servers.begin(); + auto iter = world_servers.begin(); while (iter != world_servers.end()) { if ((*iter)->GetConnection()->GetrIP() == address) { return (*iter); @@ -120,24 +120,23 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c) { unsigned int packet_size = sizeof(ServerListHeader_Struct); unsigned int server_count = 0; - in_addr in; - in.s_addr = c->GetConnection()->GetRemoteIP(); - string client_ip = inet_ntoa(in); + std::string client_ip = c->GetConnection()->RemoteEndpoint(); - list::iterator iter = world_servers.begin(); + auto iter = world_servers.begin(); while (iter != world_servers.end()) { if ((*iter)->IsAuthorized() == false) { ++iter; continue; } + in_addr in; in.s_addr = (*iter)->GetConnection()->GetrIP(); - string world_ip = inet_ntoa(in); + std::string world_ip = inet_ntoa(in); if (world_ip.compare(client_ip) == 0) { packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; } - else if (client_ip.find(server.options.GetLocalNetwork()) != string::npos) { + else if (client_ip.find(server.options.GetLocalNetwork()) != std::string::npos) { packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; } else { @@ -171,13 +170,14 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c) continue; } + in_addr in; in.s_addr = (*iter)->GetConnection()->GetrIP(); - string world_ip = inet_ntoa(in); + std::string world_ip = inet_ntoa(in); if (world_ip.compare(client_ip) == 0) { memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size()); data_pointer += ((*iter)->GetLocalIP().size() + 1); } - else if (client_ip.find(server.options.GetLocalNetwork()) != string::npos) { + else if (client_ip.find(server.options.GetLocalNetwork()) != std::string::npos) { memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size()); data_pointer += ((*iter)->GetLocalIP().size() + 1); } @@ -239,7 +239,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c) void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id) { - list::iterator iter = world_servers.begin(); + auto iter = world_servers.begin(); bool found = false; while (iter != world_servers.end()) { if ((*iter)->GetRuntimeID() == server_id) { @@ -263,9 +263,9 @@ void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int } } -bool ServerManager::ServerExists(string l_name, string s_name, WorldServer *ignore) +bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldServer *ignore) { - list::iterator iter = world_servers.begin(); + auto iter = world_servers.begin(); while (iter != world_servers.end()) { if ((*iter) == ignore) { ++iter; @@ -281,9 +281,9 @@ bool ServerManager::ServerExists(string l_name, string s_name, WorldServer *igno return false; } -void ServerManager::DestroyServerByName(string l_name, string s_name, WorldServer *ignore) +void ServerManager::DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore) { - list::iterator iter = world_servers.begin(); + auto iter = world_servers.begin(); while (iter != world_servers.end()) { if ((*iter) == ignore) { ++iter; diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 8e912e285..7f9c18792 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -158,7 +158,9 @@ bool WorldServer::Process() if(utwr->response > 0) { per->Allowed = 1; - SendClientAuth(c->GetConnection()->GetRemoteIP(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); + + std::string remote_ip = c->GetConnection()->RemoteEndpoint(); + SendClientAuth((unsigned int)inet_addr(remote_ip.c_str()), c->GetAccountName(), c->GetKey(), c->GetAccountID()); } switch(utwr->response) @@ -215,9 +217,9 @@ bool WorldServer::Process() if(is_server_trusted) { Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); - string name; - string password; - string email; + std::string name; + std::string password; + std::string email; name.assign(lsau->useraccount); password.assign(lsau->userpassword); email.assign(lsau->useremail); @@ -372,10 +374,10 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) unsigned int s_id = 0; unsigned int s_list_type = 0; unsigned int s_trusted = 0; - string s_desc; - string s_list_desc; - string s_acct_name; - string s_acct_pass; + std::string s_desc; + std::string s_list_desc; + std::string s_acct_name; + std::string s_acct_pass; if(server.db->GetWorldRegistration(long_name, short_name, s_id, s_desc, s_list_type, s_trusted, s_list_desc, s_acct_name, s_acct_pass)) { if(s_acct_name.size() == 0 || s_acct_pass.size() == 0) @@ -424,10 +426,10 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) unsigned int server_id = 0; unsigned int server_list_type = 0; unsigned int is_server_trusted = 0; - string server_description; - string server_list_description; - string server_account_name; - string server_account_password; + std::string server_description; + std::string server_list_description; + std::string server_account_name; + std::string server_account_password; if(server.db->GetWorldRegistration( @@ -493,7 +495,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) in_addr in; in.s_addr = connection->GetrIP(); - server.db->UpdateWorldRegistration(GetRuntimeID(), long_name, string(inet_ntoa(in))); + server.db->UpdateWorldRegistration(GetRuntimeID(), long_name, std::string(inet_ntoa(in))); if(is_server_authorized) { @@ -508,7 +510,7 @@ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) server_status = s->status; } -void WorldServer::SendClientAuth(unsigned int ip, string account, string key, unsigned int account_id) +void WorldServer::SendClientAuth(unsigned int ip, std::string account, std::string key, unsigned int account_id) { ServerPacket *outapp = new ServerPacket(ServerOP_LSClientAuth, sizeof(ClientAuth_Struct)); ClientAuth_Struct* client_auth = (ClientAuth_Struct*)outapp->pBuffer; @@ -522,14 +524,14 @@ void WorldServer::SendClientAuth(unsigned int ip, string account, string key, un in_addr in; in.s_addr = ip; connection->GetrIP(); - string client_address(inet_ntoa(in)); + std::string client_address(inet_ntoa(in)); in.s_addr = connection->GetrIP(); - string world_address(inet_ntoa(in)); + std::string world_address(inet_ntoa(in)); if (client_address.compare(world_address) == 0) { client_auth->local = 1; } - else if (client_address.find(server.options.GetLocalNetwork()) != string::npos) { + else if (client_address.find(server.options.GetLocalNetwork()) != std::string::npos) { client_auth->local = 1; } else { diff --git a/zone/client.h b/zone/client.h index df7c1fce3..472fda02d 100644 --- a/zone/client.h +++ b/zone/client.h @@ -64,7 +64,6 @@ namespace EQEmu #undef max #endif -#include #include #include #include diff --git a/zone/zone.cpp b/zone/zone.cpp index 35b2d52bb..d973a2157 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -16,7 +16,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include