From f3e2af7e42cdfe8c97d24bb3a57eeebe0cf61bc6 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 29 Oct 2016 23:23:04 -0700 Subject: [PATCH] Working on login / world connection mostly there, fixed a few crashes with encryption on 0 length packets --- common/net/daybreak_structs.h | 82 ++--- common/net/packet.h | 6 +- common/net/servertalk_client_connection.cpp | 15 +- common/net/servertalk_server_connection.cpp | 5 + common/packet_dump.cpp | 9 + common/packet_dump.h | 4 +- common/servertalk.h | 23 +- loginserver/client.cpp | 8 +- loginserver/client.h | 10 +- loginserver/client_manager.cpp | 10 +- loginserver/client_manager.h | 4 +- loginserver/database_mysql.cpp | 36 +- loginserver/database_postgresql.h | 18 +- loginserver/server_manager.cpp | 10 +- loginserver/world_server.cpp | 381 ++++++++++---------- loginserver/world_server.h | 13 +- world/login_server.cpp | 189 +++++----- world/login_server.h | 8 +- world/net.cpp | 22 -- 19 files changed, 441 insertions(+), 412 deletions(-) diff --git a/common/net/daybreak_structs.h b/common/net/daybreak_structs.h index 36e97a246..b03ed18bb 100644 --- a/common/net/daybreak_structs.h +++ b/common/net/daybreak_structs.h @@ -17,8 +17,8 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(zero), - CEREAL_NVP(opcode)); + archive(zero, + opcode); } }; @@ -34,11 +34,11 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(zero), - CEREAL_NVP(opcode), - CEREAL_NVP(protocol_version), - CEREAL_NVP(connect_code), - CEREAL_NVP(max_packet_size)); + archive(zero, + opcode, + protocol_version, + connect_code, + max_packet_size); } }; @@ -57,14 +57,14 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(zero), - CEREAL_NVP(opcode), - CEREAL_NVP(connect_code), - CEREAL_NVP(encode_key), - CEREAL_NVP(crc_bytes), - CEREAL_NVP(encode_pass1), - CEREAL_NVP(encode_pass2), - CEREAL_NVP(max_packet_size)); + archive(zero, + opcode, + connect_code, + encode_key, + crc_bytes, + encode_pass1, + encode_pass2, + max_packet_size); } }; @@ -78,9 +78,9 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(zero), - CEREAL_NVP(opcode), - CEREAL_NVP(connect_code)); + archive(zero, + opcode, + connect_code); } }; @@ -94,9 +94,9 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(zero), - CEREAL_NVP(opcode), - CEREAL_NVP(sequence)); + archive(zero, + opcode, + sequence); } }; @@ -109,8 +109,8 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(reliable), - CEREAL_NVP(total_size)); + archive(reliable, + total_size); } }; @@ -131,16 +131,16 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(zero), - CEREAL_NVP(opcode), - CEREAL_NVP(timestamp), - CEREAL_NVP(stat_ping), - CEREAL_NVP(avg_ping), - CEREAL_NVP(min_ping), - CEREAL_NVP(max_ping), - CEREAL_NVP(last_ping), - CEREAL_NVP(packets_sent), - CEREAL_NVP(packets_recv)); + archive(zero, + opcode, + timestamp, + stat_ping, + avg_ping, + min_ping, + max_ping, + last_ping, + packets_sent, + packets_recv); } }; @@ -159,14 +159,14 @@ namespace EQ template void serialize(Archive & archive) { - archive(CEREAL_NVP(zero), - CEREAL_NVP(opcode), - CEREAL_NVP(timestamp), - CEREAL_NVP(our_timestamp), - CEREAL_NVP(client_sent), - CEREAL_NVP(client_recv), - CEREAL_NVP(server_sent), - CEREAL_NVP(server_recv)); + archive(zero, + opcode, + timestamp, + our_timestamp, + client_sent, + client_recv, + server_sent, + server_recv); } }; } diff --git a/common/net/packet.h b/common/net/packet.h index 43b36d71b..a3275b48e 100644 --- a/common/net/packet.h +++ b/common/net/packet.h @@ -26,11 +26,7 @@ namespace EQ { template T GetSerialize(size_t offset) const - { - if (T::size() > (Length() - offset)) { - throw std::out_of_range("Packet::GetSerialize(), packet not large enough to cast to type."); - } - + { T ret; Util::MemoryStreamReader reader(((char*)Data() + offset), Length()); cereal::BinaryInputArchive input(reader); diff --git a/common/net/servertalk_client_connection.cpp b/common/net/servertalk_client_connection.cpp index e3fe67817..ac3ddb7b4 100644 --- a/common/net/servertalk_client_connection.cpp +++ b/common/net/servertalk_client_connection.cpp @@ -19,20 +19,23 @@ EQ::Net::ServertalkClient::~ServertalkClient() { } -void EQ::Net::ServertalkClient::Send(uint16_t opcode, EQ::Net::Packet & p) +void EQ::Net::ServertalkClient::Send(uint16_t opcode, EQ::Net::Packet &p) { EQ::Net::WritablePacket out; #ifdef ENABLE_SECURITY if (m_encrypted) { + if (p.Length() == 0) { + p.PutUInt8(0, 0); + } + out.PutUInt32(0, p.Length() + crypto_secretbox_MACBYTES); out.PutUInt16(4, opcode); - unsigned char *cipher = new unsigned char[p.Length() + crypto_secretbox_MACBYTES]; - crypto_box_easy_afternm(cipher, (unsigned char*)p.Data(), p.Length(), m_nonce_ours, m_shared_key); + std::unique_ptr cipher(new unsigned char[p.Length() + crypto_secretbox_MACBYTES]); + + crypto_box_easy_afternm(&cipher[0], (unsigned char*)p.Data(), p.Length(), m_nonce_ours, m_shared_key); (*(uint64_t*)&m_nonce_ours[0])++; - out.PutData(6, cipher, p.Length() + crypto_secretbox_MACBYTES); - - delete[] cipher; + out.PutData(6, &cipher[0], p.Length() + crypto_secretbox_MACBYTES); } else { out.PutUInt32(0, p.Length()); diff --git a/common/net/servertalk_server_connection.cpp b/common/net/servertalk_server_connection.cpp index 98fbc07b3..7f900955d 100644 --- a/common/net/servertalk_server_connection.cpp +++ b/common/net/servertalk_server_connection.cpp @@ -22,8 +22,13 @@ void EQ::Net::ServertalkServerConnection::Send(uint16_t opcode, EQ::Net::Packet EQ::Net::WritablePacket out; #ifdef ENABLE_SECURITY if (m_encrypted) { + if (p.Length() == 0) { + p.PutUInt8(0, 0); + } + out.PutUInt32(0, p.Length() + crypto_secretbox_MACBYTES); out.PutUInt16(4, opcode); + std::unique_ptr cipher(new unsigned char[p.Length() + crypto_secretbox_MACBYTES]); crypto_box_easy_afternm(&cipher[0], (unsigned char*)p.Data(), p.Length(), m_nonce_ours, m_shared_key); diff --git a/common/packet_dump.cpp b/common/packet_dump.cpp index 1e28c2616..a4ecba781 100644 --- a/common/packet_dump.cpp +++ b/common/packet_dump.cpp @@ -152,6 +152,15 @@ void DumpPacket(const ServerPacket* pack, bool iShowInfo) { DumpPacketHex(pack->pBuffer, pack->size); } +void DumpPacket(uint16 opcode, const EQ::Net::Packet &p, bool iShowInfo) { + if (iShowInfo) { + std::cout << "Dumping ServerPacket: 0x" << std::hex << std::setfill('0') << std::setw(4) << opcode << std::dec; + std::cout << " size:" << p.Length() << std::endl; + } + + std::cout << p.ToString() << std::endl; +} + void DumpPacketBin(const ServerPacket* pack) { DumpPacketBin(pack->pBuffer, pack->size); } diff --git a/common/packet_dump.h b/common/packet_dump.h index db6e485a4..dd0058bb1 100644 --- a/common/packet_dump.h +++ b/common/packet_dump.h @@ -18,7 +18,8 @@ #ifndef PACKET_DUMP_H #define PACKET_DUMP_H -#include "../common/types.h" +#include "types.h" +#include "net/packet.h" class ServerPacket; @@ -28,6 +29,7 @@ std::string DumpPacketHexToString(const uchar* buf, uint32 size, uint32 cols = 1 void DumpPacketBin(const void* data, uint32 len); void DumpPacket(const uchar* buf, uint32 size); void DumpPacket(const ServerPacket* pack, bool iShowInfo = false); +void DumpPacket(uint16 opcode, const EQ::Net::Packet &p, bool iShowInfo = false); void DumpPacketBin(const ServerPacket* pack); void DumpPacketBin(uint32 data); void DumpPacketBin(uint16 data); diff --git a/common/servertalk.h b/common/servertalk.h index 7de9491b7..c7805e55c 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -4,6 +4,8 @@ #include "../common/types.h" #include "../common/packet_functions.h" #include "../common/eq_packet_structs.h" +#include +#include #define SERVER_TIMEOUT 45000 // how often keepalive gets sent #define INTERSERVER_TIMER 10000 @@ -524,14 +526,21 @@ struct ServerLSPlayerZoneChange_Struct { uint32 from; // 0 = world uint32 to; // 0 = world }; + struct ClientAuth_Struct { - uint32 lsaccount_id; // ID# in login server's db - char name[30]; // username in login server's db - char key[30]; // the Key the client will present - uint8 lsadmin; // login server admin level - int16 worldadmin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it - char ip[64]; - uint8 local; // 1 if the client is from the local network + int lsaccount_id; // ID# in login server's db + std::string name; // username in login server's db + std::string key; // the Key the client will present + int lsadmin; // login server admin level + int worldadmin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it + std::string ip; + int local; // 1 if the client is from the local network + + template + void serialize(Archive &ar) + { + ar(lsaccount_id, name, key, lsadmin, worldadmin, ip, local); + } }; struct ServerSystemwideMessage { diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 4e1449e91..b3535490a 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -187,13 +187,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()); @@ -255,7 +255,7 @@ void Client::Handle_Login(const char* data, unsigned int size) in_addr in; in.s_addr = connection->GetRemoteIP(); - server.db->UpdateLSAccountData(db_account_id, string(inet_ntoa(in))); + server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); GenerateKey(); account_id = db_account_id; diff --git a/loginserver/client.h b/loginserver/client.h index bc08f6fb7..e60de7f56 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -28,8 +28,6 @@ #include #include "../common/eq_stream_intf.h" -using namespace std; - enum LSClientVersion { cv_titanium, @@ -109,12 +107,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. @@ -137,11 +135,11 @@ private: 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 9b1906bd9..fa16365d3 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -90,7 +90,7 @@ void ClientManager::Process() { ProcessDisconnect(); - list::iterator iter = clients.begin(); + auto iter = clients.begin(); while(iter != clients.end()) { if((*iter)->Process() == false) @@ -108,7 +108,7 @@ void ClientManager::Process() void ClientManager::ProcessDisconnect() { - list::iterator iter = clients.begin(); + auto iter = clients.begin(); while(iter != clients.end()) { std::shared_ptr c = (*iter)->GetConnection(); @@ -127,7 +127,7 @@ void ClientManager::ProcessDisconnect() void ClientManager::UpdateServerList() { - list::iterator iter = clients.begin(); + auto iter = clients.begin(); while(iter != clients.end()) { (*iter)->SendServerListPacket(); @@ -137,7 +137,7 @@ 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) @@ -157,7 +157,7 @@ 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) diff --git a/loginserver/client_manager.h b/loginserver/client_manager.h index 839124d75..04d276861 100644 --- a/loginserver/client_manager.h +++ b/loginserver/client_manager.h @@ -24,8 +24,6 @@ #include "client.h" #include -using namespace std; - /** * Client manager class, holds all the client objects and does basic processing. */ @@ -68,7 +66,7 @@ private: */ void ProcessDisconnect(); - list clients; + std::list clients; OpcodeManager *titanium_ops; EQ::Net::EQStreamManager *titanium_stream; OpcodeManager *sod_ops; 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/database_postgresql.h b/loginserver/database_postgresql.h index 0dfbe53aa..0cd5c3ee8 100644 --- a/loginserver/database_postgresql.h +++ b/loginserver/database_postgresql.h @@ -26,8 +26,6 @@ #include #include -using namespace std; - /** * PostgreSQL Database class */ @@ -42,7 +40,7 @@ public: /** * Constructor, tries to set our database to connect to the supplied options. */ - DatabasePostgreSQL(string user, string pass, string host, string port, string name); + DatabasePostgreSQL(std::string user, std::string pass, std::string host, std::string port, std::string name); /** * Destructor, frees our database if needed. @@ -59,32 +57,32 @@ public: * Needed for client login procedure. * Returns true if the record was found, false otherwise. */ - virtual bool GetLoginDataFromAccountName(string name, string &password, unsigned int &id); + virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id); /** * Retrieves the world registration from the long and short names provided. * Needed for world login procedure. * Returns true if the record was found, false otherwise. */ - virtual bool 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); + virtual bool 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); /** * Updates the ip address of the client with account id = id */ - virtual void UpdateLSAccountData(unsigned int id, string ip_address); + virtual void UpdateLSAccountData(unsigned int id, std::string ip_address); /** * Updates the ip address of the world with account id = id */ - virtual void UpdateWorldRegistration(unsigned int id, string long_name, string ip_address); + virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); /** * Creates new world registration for unregistered servers and returns new id */ - virtual bool CreateWorldRegistration(string long_name, string short_name, unsigned int &id); + virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); protected: - string user, pass, host, port, name; + std::string user, pass, host, port, name; PGconn *db; }; diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 54c86f937..189eb663f 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -89,7 +89,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c) unsigned int server_count = 0; in_addr in; in.s_addr = c->GetConnection()->GetRemoteIP(); - string client_ip = inet_ntoa(in); + std::string client_ip = inet_ntoa(in); auto iter = world_servers.begin(); while (iter != world_servers.end()) { @@ -103,7 +103,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c) 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 { @@ -142,7 +142,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c) 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); } @@ -228,7 +228,7 @@ 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) { auto iter = world_servers.begin(); while (iter != world_servers.end()) { @@ -246,7 +246,7 @@ 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) { auto iter = world_servers.begin(); while (iter != world_servers.end()) { diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index bcf036815..9421cce5f 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -38,10 +38,10 @@ WorldServer::WorldServer(std::shared_ptr c) is_server_trusted = false; is_server_logged_in = false; - c->OnMessage(ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - c->OnMessage(ServerOP_LSStatus, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - c->OnMessage(ServerOP_UsertoWorldResp, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - c->OnMessage(ServerOP_LSAccountUpdate, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); + c->OnMessage(ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2)); + c->OnMessage(ServerOP_LSStatus, std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2)); + c->OnMessage(ServerOP_UsertoWorldResp, std::bind(&WorldServer::ProcessUsertoWorldResp, this, std::placeholders::_1, std::placeholders::_2)); + c->OnMessage(ServerOP_LSAccountUpdate, std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)); } WorldServer::~WorldServer() @@ -61,161 +61,180 @@ void WorldServer::Reset() is_server_logged_in = false; } -void WorldServer::ProcessPacket(uint16_t opcode, const EQ::Net::Packet &p) +void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) { - if(server.options.IsWorldTraceOn()) + if (server.options.IsWorldTraceOn()) { Log.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); } - - if(server.options.IsDumpInPacketsOn()) + + if (server.options.IsDumpInPacketsOn()) { - Log.OutF(Logs::General, Logs::Login_Server, "{0}", p.ToString()); + DumpPacket(opcode, p); } - - switch(opcode) + + if (p.Length() < sizeof(ServerNewLSInfo_Struct)) { - case ServerOP_NewLSInfo: + Log.Out(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, " + "but was too small. Discarded to avoid buffer overrun."); + return; + } + + if (server.options.IsWorldTraceOn()) + { + Log.Out(Logs::General, Logs::Netcode, "New Login Info Recieved."); + } + + ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)p.Data(); + Handle_NewLSInfo(info); +} + +void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) +{ + if (server.options.IsWorldTraceOn()) + { + Log.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + } + + if (server.options.IsDumpInPacketsOn()) + { + DumpPacket(opcode, p); + } + + if (p.Length() < sizeof(ServerLSStatus_Struct)) + { + Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_LSStatus, " + "but was too small. Discarded to avoid buffer overrun."); + return; + } + + if (server.options.IsWorldTraceOn()) + { + Log.Out(Logs::General, Logs::Netcode, "World Server Status Recieved."); + } + + ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)p.Data(); + Handle_LSStatus(ls_status); +} + +void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p) +{ + if (server.options.IsWorldTraceOn()) + { + Log.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + } + + if (server.options.IsDumpInPacketsOn()) + { + DumpPacket(opcode, p); + } + + if (p.Length() < sizeof(UsertoWorldResponse_Struct)) + { + Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " + "but was too small. Discarded to avoid buffer overrun."); + return; + } + + //I don't use world trace for this and here is why: + //Because this is a part of the client login procedure it makes tracking client errors + //While keeping world server spam with multiple servers connected almost impossible. + if (server.options.IsTraceOn()) + { + Log.Out(Logs::General, Logs::Netcode, "User-To-World Response received."); + } + + UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)p.Data(); + Log.Out(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); + Client *c = server.client_manager->GetClient(utwr->lsaccountid); + if (c) + { + Log.Out(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); + EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); + PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer; + per->Sequence = c->GetPlaySequence(); + per->ServerNumber = c->GetPlayServerID(); + Log.Out(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); + + Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); + + if (utwr->response > 0) { - if(p.Length() < sizeof(ServerNewLSInfo_Struct)) - { - Log.Out(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, " - "but was too small. Discarded to avoid buffer overrun."); - break; - } - - if(server.options.IsWorldTraceOn()) - { - Log.Out(Logs::General, Logs::Netcode, "New Login Info Recieved."); - } - - ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)p.Data(); - Handle_NewLSInfo(info); + per->Allowed = 1; + SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); + } + + switch (utwr->response) + { + case 1: + per->Message = 101; + break; + case 0: + per->Message = 326; + break; + case -1: + per->Message = 337; + break; + case -2: + per->Message = 338; + break; + case -3: + per->Message = 303; break; } - case ServerOP_LSStatus: + + if (server.options.IsTraceOn()) { - if(p.Length() < sizeof(ServerLSStatus_Struct)) - { - Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_LSStatus, " - "but was too small. Discarded to avoid buffer overrun."); - break; - } - - if(server.options.IsWorldTraceOn()) - { - Log.Out(Logs::General, Logs::Netcode, "World Server Status Recieved."); - } - - ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)p.Data(); - Handle_LSStatus(ls_status); - break; + Log.Out(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", + per->Allowed, per->Sequence, per->ServerNumber, per->Message); + Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); } - case ServerOP_UsertoWorldResp: + + if (server.options.IsDumpOutPacketsOn()) { - if(p.Length() < sizeof(UsertoWorldResponse_Struct)) - { - Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " - "but was too small. Discarded to avoid buffer overrun."); - break; - } - - //I don't use world trace for this and here is why: - //Because this is a part of the client login procedure it makes tracking client errors - //While keeping world server spam with multiple servers connected almost impossible. - if(server.options.IsTraceOn()) - { - Log.Out(Logs::General, Logs::Netcode, "User-To-World Response received."); - } - - UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)p.Data(); - Log.Out(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); - Client *c = server.client_manager->GetClient(utwr->lsaccountid); - if(c) - { - Log.Out(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); - EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); - PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer; - per->Sequence = c->GetPlaySequence(); - per->ServerNumber = c->GetPlayServerID(); - Log.Out(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); - - Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); - - if(utwr->response > 0) - { - per->Allowed = 1; - SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); - } - - switch(utwr->response) - { - case 1: - per->Message = 101; - break; - case 0: - per->Message = 326; - break; - case -1: - per->Message = 337; - break; - case -2: - per->Message = 338; - break; - case -3: - per->Message = 303; - break; - } - - if(server.options.IsTraceOn()) - { - Log.Out(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", - per->Allowed, per->Sequence, per->ServerNumber, per->Message); - Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); - } - - if(server.options.IsDumpOutPacketsOn()) - { - DumpPacket(outapp); - } - - c->SendPlayResponse(outapp); - delete outapp; - } - else - { - Log.Out(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); - } - break; - } - case ServerOP_LSAccountUpdate: - { - if(p.Length() < sizeof(ServerLSAccountUpdate_Struct)) - { - Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerLSAccountUpdate_Struct, " - "but was too small. Discarded to avoid buffer overrun."); - break; - } - - Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); - ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)p.Data(); - if(is_server_trusted) - { - Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); - string name; - string password; - string email; - name.assign(lsau->useraccount); - password.assign(lsau->userpassword); - email.assign(lsau->useremail); - server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email); - } - break; - } - default: - { - Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had an unknown operation code 0x%.4X.", opcode); + DumpPacket(outapp); } + + c->SendPlayResponse(outapp); + delete outapp; + } + else + { + Log.Out(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); + } +} + +void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p) +{ + if (server.options.IsWorldTraceOn()) + { + Log.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + } + + if (server.options.IsDumpInPacketsOn()) + { + DumpPacket(opcode, p); + } + + if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) + { + Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerLSAccountUpdate_Struct, " + "but was too small. Discarded to avoid buffer overrun."); + return; + } + + Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); + ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)p.Data(); + if (is_server_trusted) + { + Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); + std::string name; + std::string password; + std::string email; + name.assign(lsau->useraccount); + password.assign(lsau->userpassword); + email.assign(lsau->useremail); + server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email); } } @@ -289,7 +308,6 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) { if(strlen(i->remote_address) == 0) { - in_addr in; remote_ip = GetConnection()->Handle()->RemoteIP(); Log.Out(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.", remote_ip.c_str()); } @@ -300,7 +318,6 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) } else { - in_addr in; remote_ip = GetConnection()->Handle()->RemoteIP(); Log.Out(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", remote_ip.c_str()); } @@ -352,10 +369,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) @@ -378,8 +395,9 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) if(s_trusted) { Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world"); is_server_trusted = true; - ServerPacket *outapp = new ServerPacket(ServerOP_LSAccountUpdate, 0); - connection->SendPacket(outapp); + + EQ::Net::WritablePacket outapp; + connection->Send(ServerOP_LSAccountUpdate, outapp); } } else { @@ -404,10 +422,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( @@ -434,8 +452,8 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) if(is_server_trusted) { Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world"); is_server_trusted = true; - ServerPacket *outapp = new ServerPacket(ServerOP_LSAccountUpdate, 0); - connection->SendPacket(outapp); + EQ::Net::WritablePacket outapp; + connection->Send(ServerOP_LSAccountUpdate, outapp); } } else { @@ -486,37 +504,36 @@ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) server_status = s->status; } -void WorldServer::SendClientAuth(std::string ip, string account, string key, unsigned int account_id) +void WorldServer::SendClientAuth(std::string 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; - - client_auth->lsaccount_id = account_id; - strncpy(client_auth->name, account.c_str(), account.size() > 30 ? 30 : account.size()); - strncpy(client_auth->key, key.c_str(), 10); - client_auth->lsadmin = 0; - client_auth->worldadmin = 0; - strcpy(client_auth->ip, ip.c_str()); - - string client_address(ip); - string world_address(connection->Handle()->RemoteIP()); - + EQ::Net::WritablePacket outapp; + ClientAuth_Struct client_auth; + client_auth.lsaccount_id = account_id; + client_auth.name = account; + client_auth.key = key; + client_auth.lsadmin = 0; + client_auth.worldadmin = 0; + client_auth.ip = ip; + + std::string client_address(ip); + std::string world_address(connection->Handle()->RemoteIP()); + if (client_address.compare(world_address) == 0) { - client_auth->local = 1; + client_auth.local = 1; } - else if (client_address.find(server.options.GetLocalNetwork()) != string::npos) { - client_auth->local = 1; + else if (client_address.find(server.options.GetLocalNetwork()) != std::string::npos) { + client_auth.local = 1; } else { - client_auth->local = 0; + client_auth.local = 0; } - - connection->SendPacket(outapp); - + + outapp.PutSerialize(0, client_auth); + connection->Send(ServerOP_LSClientAuth, outapp); + if (server.options.IsDumpInPacketsOn()) { - DumpPacket(outapp); + DumpPacket(ServerOP_LSClientAuth, outapp); } - delete outapp; } diff --git a/loginserver/world_server.h b/loginserver/world_server.h index 8ee00fbba..bce7b27eb 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -46,11 +46,6 @@ public: */ void Reset(); - /** - * Does processing of all the packets in for this world. - */ - void ProcessPacket(uint16_t opcode, const EQ::Net::Packet &p); - /** * Accesses connection, it is intentional that this is not const (trust me). */ @@ -133,6 +128,14 @@ public: private: + /** + * Packet processing functions: + */ + void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p); + void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p); + void ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p); + void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p); + std::shared_ptr connection; unsigned int zones_booted; unsigned int players_online; diff --git a/world/login_server.cpp b/world/login_server.cpp index f2cd9bd4e..e4d151564 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -53,95 +53,102 @@ LoginServer::LoginServer(const char* iAddress, uint16 iPort, const char* Account LoginServer::~LoginServer() { } -void LoginServer::ProcessPacket(uint16_t opcode, EQ::Net::Packet &p) { - const WorldConfig *Config=WorldConfig::get(); +void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); - /************ Get all packets from packet manager out queue and process them ************/ - Log.Out(Logs::Detail, Logs::World_Server,"Recevied ServerPacket from LS OpCode 0x04x", opcode); + UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data(); + uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid); + int16 status = database.CheckStatus(id); - switch(opcode) { - case ServerOP_UsertoWorldReq: { - UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data(); - uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid); - int16 status = database.CheckStatus(id); + auto outpack = new ServerPacket; + outpack->opcode = ServerOP_UsertoWorldResp; + outpack->size = sizeof(UsertoWorldResponse_Struct); + outpack->pBuffer = new uchar[outpack->size]; + memset(outpack->pBuffer, 0, outpack->size); + UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*)outpack->pBuffer; + utwrs->lsaccountid = utwr->lsaccountid; + utwrs->ToID = utwr->FromID; - auto outpack = new ServerPacket; - outpack->opcode = ServerOP_UsertoWorldResp; - outpack->size = sizeof(UsertoWorldResponse_Struct); - outpack->pBuffer = new uchar[outpack->size]; - memset(outpack->pBuffer, 0, outpack->size); - UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*) outpack->pBuffer; - utwrs->lsaccountid = utwr->lsaccountid; - utwrs->ToID = utwr->FromID; - - if(Config->Locked == true) - { - if((status == 0 || status < 100) && (status != -2 || status != -1)) - utwrs->response = 0; - if(status >= 100) - utwrs->response = 1; - } - else { - utwrs->response = 1; - } - - int32 x = Config->MaxClients; - if( (int32)numplayers >= x && x != -1 && x != 255 && status < 80) - utwrs->response = -3; - - if(status == -1) - utwrs->response = -1; - if(status == -2) - utwrs->response = -2; - - utwrs->worldid = utwr->worldid; - SendPacket(outpack); - delete outpack; - break; - } - case ServerOP_LSClientAuth: { - ClientAuth_Struct* slsca = (ClientAuth_Struct*)p.Data(); - - if (RuleI(World, AccountSessionLimit) >= 0) { - // Enforce the limit on the number of characters on the same account that can be - // online at the same time. - client_list.EnforceSessionLimit(slsca->lsaccount_id); - } - - client_list.CLEAdd(slsca->lsaccount_id, slsca->name, slsca->key, slsca->worldadmin, inet_addr(slsca->ip), slsca->local); - break; - } - case ServerOP_LSFatalError: { - Log.Out(Logs::Detail, Logs::World_Server, "Login server responded with FatalError."); - if (p.Length() > 1) { - Log.Out(Logs::Detail, Logs::World_Server, " %s", (const char*)p.Data()); - } - break; - } - case ServerOP_SystemwideMessage: { - ServerSystemwideMessage* swm = (ServerSystemwideMessage*)p.Data(); - zoneserver_list.SendEmoteMessageRaw(0, 0, 0, swm->type, swm->message); - break; - } - case ServerOP_LSRemoteAddr: { - if (!Config->WorldAddress.length()) { - WorldConfig::SetWorldAddress((char *)p.Data()); - Log.Out(Logs::Detail, Logs::World_Server, "Loginserver provided %s as world address", (const char*)p.Data()); - } - break; - } - case ServerOP_LSAccountUpdate: { - Log.Out(Logs::Detail, Logs::World_Server, "Received ServerOP_LSAccountUpdate packet from loginserver"); - CanAccountUpdate = true; - break; - } - default: - { - Log.Out(Logs::Detail, Logs::World_Server, "Unknown LSOpCode: 0x%04x size=%d",(int)opcode, p.Length()); - Log.OutF(Logs::General, Logs::Login_Server, "{0}", p.ToString()); - break; - } + if (Config->Locked == true) + { + if ((status == 0 || status < 100) && (status != -2 || status != -1)) + utwrs->response = 0; + if (status >= 100) + utwrs->response = 1; } + else { + utwrs->response = 1; + } + + int32 x = Config->MaxClients; + if ((int32)numplayers >= x && x != -1 && x != 255 && status < 80) + utwrs->response = -3; + + if (status == -1) + utwrs->response = -1; + if (status == -2) + utwrs->response = -2; + + utwrs->worldid = utwr->worldid; + SendPacket(outpack); + delete outpack; +} + +void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + + try { + auto slsca = p.GetSerialize(0); + + if (RuleI(World, AccountSessionLimit) >= 0) { + // Enforce the limit on the number of characters on the same account that can be + // online at the same time. + client_list.EnforceSessionLimit(slsca.lsaccount_id); + } + + client_list.CLEAdd(slsca.lsaccount_id, slsca.name.c_str(), slsca.key.c_str(), slsca.worldadmin, inet_addr(slsca.ip.c_str()), slsca.local); + } + catch (std::exception &ex) { + Log.OutF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what()); + } +} + +void LoginServer::ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + + Log.Out(Logs::Detail, Logs::World_Server, "Login server responded with FatalError."); + if (p.Length() > 1) { + Log.Out(Logs::Detail, Logs::World_Server, " %s", (const char*)p.Data()); + } +} + +void LoginServer::ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + + ServerSystemwideMessage* swm = (ServerSystemwideMessage*)p.Data(); + zoneserver_list.SendEmoteMessageRaw(0, 0, 0, swm->type, swm->message); +} + +void LoginServer::ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + + if (!Config->WorldAddress.length()) { + WorldConfig::SetWorldAddress((char *)p.Data()); + Log.Out(Logs::Detail, Logs::World_Server, "Loginserver provided %s as world address", (const char*)p.Data()); + } +} + +void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + + Log.Out(Logs::Detail, Logs::World_Server, "Received ServerOP_LSAccountUpdate packet from loginserver"); + CanAccountUpdate = true; } bool LoginServer::Connect() { @@ -189,12 +196,12 @@ bool LoginServer::Connect() { } }); - client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSRemoteAddr, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSAccountUpdate, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2)); + client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessUsertoWorldReq, this, std::placeholders::_1, std::placeholders::_2)); + client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessLSClientAuth, this, std::placeholders::_1, std::placeholders::_2)); + client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessLSFatalError, this, std::placeholders::_1, std::placeholders::_2)); + client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessSystemwideMessage, this, std::placeholders::_1, std::placeholders::_2)); + client->OnMessage(ServerOP_LSRemoteAddr, std::bind(&LoginServer::ProcessLSRemoteAddr, this, std::placeholders::_1, std::placeholders::_2)); + client->OnMessage(ServerOP_LSAccountUpdate, std::bind(&LoginServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)); } void LoginServer::SendInfo() { const WorldConfig *Config=WorldConfig::get(); diff --git a/world/login_server.h b/world/login_server.h index 31438b4d8..f4ec04033 100644 --- a/world/login_server.h +++ b/world/login_server.h @@ -33,7 +33,6 @@ public: LoginServer(const char*, uint16, const char*, const char*); ~LoginServer(); - void ProcessPacket(uint16_t opcode, EQ::Net::Packet &p); bool Connect(); void SendInfo(); @@ -47,6 +46,13 @@ public: bool CanUpdate() { return CanAccountUpdate; } private: + void ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p); + void ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p); + void ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p); + void ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p); + void ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p); + void ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p); + bool minilogin; std::unique_ptr client; std::unique_ptr statusupdate_timer; diff --git a/world/net.cpp b/world/net.cpp index 714ddd1be..a5a2c3e5e 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -415,28 +415,6 @@ int main(int argc, char** argv) { Log.OutF(Logs::Detail, Logs::World_Server, "New connection from IP {0}:{1}", stream->RemoteEndpoint(), ntohs(stream->GetRemotePort())); }); - EQ::Net::ServertalkServer server; - EQ::Net::ServertalkServerOptions stopts; - stopts.port = 5999; - stopts.credentials = "User:Root;Password:1234567890"; - stopts.encrypted = true; - server.Listen(stopts); - - server.OnConnectionIdentified("QueryServ", [](std::shared_ptr conn) { - Log.Out(Logs::General, Logs::Debug, "New QueryServ Connection...."); - EQ::Net::WritablePacket out; - out.PutCString(0, "Hello"); - conn->Send(1, out); - - conn->OnMessage(2, [&](uint16_t opcode, EQ::Net::Packet &p) { - Log.OutF(Logs::General, Logs::Debug, "Server got message of type {0}\n{1}", opcode, p.ToString()); - }); - }); - - server.OnConnectionRemoved("QueryServ", [](std::shared_ptr conn) { - Log.Out(Logs::General, Logs::Debug, "Lost QueryServ connection."); - }); - while(RunLoops) { Timer::SetCurrentTime(); eqs = nullptr;