More loginserver refactorings and cleanup

This commit is contained in:
Akkadius 2019-07-05 02:33:31 -05:00
parent 8b582730a8
commit b41e58fd10
8 changed files with 328 additions and 232 deletions

View File

@ -157,6 +157,11 @@ namespace Logs {
}; };
} }
#define Error(message, ...) do {\
if (LogSys.log_settings[Logs::Error].is_category_enabled == 1)\
OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\ #define Log(debug_level, log_category, message, ...) do {\
if (LogSys.log_settings[log_category].is_category_enabled == 1)\ if (LogSys.log_settings[log_category].is_category_enabled == 1)\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\

View File

@ -258,11 +258,8 @@ bool Database::CreateLoginDataWithID(
); );
auto results = QueryDatabase(query); auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
return true; return results.Success();
} }
/** /**
@ -309,9 +306,7 @@ void Database::UpdateLoginHash(
const std::string &hash const std::string &hash
) )
{ {
LogF( LogLoginserverDetail(
Logs::Detail,
Logs::Login_Server,
"name [{0}] loginserver [{1}] hash [{2}]", "name [{0}] loginserver [{1}] hash [{2}]",
name, name,
loginserver, loginserver,

View File

@ -23,15 +23,26 @@
#include <openssl/md5.h> #include <openssl/md5.h>
#include <cstring> #include <cstring>
#include <string> #include <string>
#ifdef ENABLE_SECURITY #ifdef ENABLE_SECURITY
#include <sodium.h> #include <sodium.h>
#endif #endif
#include "encryption.h" #include "encryption.h"
const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buffer_out, bool enc) { /**
* @param buffer_in
* @param buffer_in_sz
* @param buffer_out
* @param enc
* @return
*/
const char *eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char *buffer_out, bool enc)
{
DES_key_schedule k; DES_key_schedule k;
DES_cblock v; DES_cblock v;
memset(&k, 0, sizeof(DES_key_schedule)); memset(&k, 0, sizeof(DES_key_schedule));
memset(&v, 0, sizeof(DES_cblock)); memset(&v, 0, sizeof(DES_cblock));
@ -40,16 +51,21 @@ const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buff
return nullptr; return nullptr;
} }
DES_ncbc_encrypt((const unsigned char*)buffer_in, (unsigned char*)buffer_out, (long)buffer_in_sz, &k, &v, enc); DES_ncbc_encrypt((const unsigned char *) buffer_in, (unsigned char *) buffer_out, (long) buffer_in_sz, &k, &v, enc);
return buffer_out; return buffer_out;
} }
std::string eqcrypt_md5(const std::string &msg) { /**
std::string ret; * @param msg
* @return
*/
std::string eqcrypt_md5(const std::string &msg)
{
std::string ret;
unsigned char md5_digest[16]; unsigned char md5_digest[16];
char tmp[4]; char tmp[4];
MD5((const unsigned char*)msg.c_str(), msg.length(), md5_digest); MD5((const unsigned char *) msg.c_str(), msg.length(), md5_digest);
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
sprintf(&tmp[0], "%02x", md5_digest[i]); sprintf(&tmp[0], "%02x", md5_digest[i]);
@ -60,12 +76,17 @@ std::string eqcrypt_md5(const std::string &msg) {
return ret; return ret;
} }
std::string eqcrypt_sha1(const std::string &msg) { /**
std::string ret; * @param msg
* @return
*/
std::string eqcrypt_sha1(const std::string &msg)
{
std::string ret;
unsigned char sha_digest[20]; unsigned char sha_digest[20];
char tmp[4]; char tmp[4];
SHA1((const unsigned char*)msg.c_str(), msg.length(), sha_digest); SHA1((const unsigned char *) msg.c_str(), msg.length(), sha_digest);
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
sprintf(&tmp[0], "%02x", sha_digest[i]); sprintf(&tmp[0], "%02x", sha_digest[i]);
@ -76,12 +97,17 @@ std::string eqcrypt_sha1(const std::string &msg) {
return ret; return ret;
} }
std::string eqcrypt_sha512(const std::string &msg) { /**
std::string ret; * @param msg
* @return
*/
std::string eqcrypt_sha512(const std::string &msg)
{
std::string ret;
unsigned char sha_digest[64]; unsigned char sha_digest[64];
char tmp[4]; char tmp[4];
SHA512((const unsigned char*)msg.c_str(), msg.length(), sha_digest); SHA512((const unsigned char *) msg.c_str(), msg.length(), sha_digest);
for (int i = 0; i < 64; ++i) { for (int i = 0; i < 64; ++i) {
sprintf(&tmp[0], "%02x", sha_digest[i]); sprintf(&tmp[0], "%02x", sha_digest[i]);
@ -94,23 +120,39 @@ std::string eqcrypt_sha512(const std::string &msg) {
#ifdef ENABLE_SECURITY #ifdef ENABLE_SECURITY
/**
* @param msg
* @return
*/
std::string eqcrypt_argon2(const std::string &msg) std::string eqcrypt_argon2(const std::string &msg)
{ {
char buffer[crypto_pwhash_STRBYTES]; char buffer[crypto_pwhash_STRBYTES];
if (crypto_pwhash_str(&buffer[0], &msg[0], msg.length(), crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE) != 0) { if (crypto_pwhash_str(
&buffer[0],
&msg[0],
msg.length(),
crypto_pwhash_OPSLIMIT_INTERACTIVE,
crypto_pwhash_MEMLIMIT_INTERACTIVE
) != 0) {
return ""; return "";
} }
return buffer; return buffer;
} }
/**
* @param msg
* @return
*/
std::string eqcrypt_scrypt(const std::string &msg) std::string eqcrypt_scrypt(const std::string &msg)
{ {
char buffer[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; char buffer[crypto_pwhash_scryptsalsa208sha256_STRBYTES];
if (crypto_pwhash_scryptsalsa208sha256_str(&buffer[0], &msg[0], msg.length(), if (crypto_pwhash_scryptsalsa208sha256_str(
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { &buffer[0], &msg[0], msg.length(),
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE
) != 0) {
return ""; return "";
} }
@ -119,60 +161,72 @@ std::string eqcrypt_scrypt(const std::string &msg)
#endif #endif
std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode) { /**
switch (mode) * @param username
{ * @param password
case EncryptionModeMD5: * @param mode
return eqcrypt_md5(password); * @return
case EncryptionModeMD5PassUser: */
return eqcrypt_md5(password + ":" + username); std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode)
case EncryptionModeMD5UserPass: {
return eqcrypt_md5(username + ":" + password); switch (mode) {
case EncryptionModeMD5Triple: case EncryptionModeMD5:
return eqcrypt_md5(eqcrypt_md5(username) + eqcrypt_md5(password)); return eqcrypt_md5(password);
case EncryptionModeSHA: case EncryptionModeMD5PassUser:
return eqcrypt_sha1(password); return eqcrypt_md5(password + ":" + username);
case EncryptionModeSHAPassUser: case EncryptionModeMD5UserPass:
return eqcrypt_sha1(password + ":" + username); return eqcrypt_md5(username + ":" + password);
case EncryptionModeSHAUserPass: case EncryptionModeMD5Triple:
return eqcrypt_sha1(username + ":" + password); return eqcrypt_md5(eqcrypt_md5(username) + eqcrypt_md5(password));
case EncryptionModeSHATriple: case EncryptionModeSHA:
return eqcrypt_sha1(eqcrypt_sha1(username) + eqcrypt_sha1(password)); return eqcrypt_sha1(password);
case EncryptionModeSHA512: case EncryptionModeSHAPassUser:
return eqcrypt_sha512(password); return eqcrypt_sha1(password + ":" + username);
case EncryptionModeSHA512PassUser: case EncryptionModeSHAUserPass:
return eqcrypt_sha512(password + ":" + username); return eqcrypt_sha1(username + ":" + password);
case EncryptionModeSHA512UserPass: case EncryptionModeSHATriple:
return eqcrypt_sha512(username + ":" + password); return eqcrypt_sha1(eqcrypt_sha1(username) + eqcrypt_sha1(password));
case EncryptionModeSHA512Triple: case EncryptionModeSHA512:
return eqcrypt_sha512(eqcrypt_sha512(username) + eqcrypt_sha512(password)); return eqcrypt_sha512(password);
case EncryptionModeSHA512PassUser:
return eqcrypt_sha512(password + ":" + username);
case EncryptionModeSHA512UserPass:
return eqcrypt_sha512(username + ":" + password);
case EncryptionModeSHA512Triple:
return eqcrypt_sha512(eqcrypt_sha512(username) + eqcrypt_sha512(password));
#ifdef ENABLE_SECURITY #ifdef ENABLE_SECURITY
case EncryptionModeArgon2: case EncryptionModeArgon2:
return eqcrypt_argon2(password); return eqcrypt_argon2(password);
case EncryptionModeSCrypt: case EncryptionModeSCrypt:
return eqcrypt_scrypt(password); return eqcrypt_scrypt(password);
#endif #endif
//todo bcrypt? pbkdf2? //todo bcrypt? pbkdf2?
default: default:
return ""; return "";
break; break;
} }
} }
bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode) { /**
switch (mode) * @param username
{ * @param password
* @param pwhash
* @param mode
* @return
*/
bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode)
{
switch (mode) {
#ifdef ENABLE_SECURITY #ifdef ENABLE_SECURITY
case 13: case 13:
return crypto_pwhash_str_verify(&pwhash[0], &password[0], password.length()) == 0; return crypto_pwhash_str_verify(&pwhash[0], &password[0], password.length()) == 0;
case 14: case 14:
return crypto_pwhash_scryptsalsa208sha256_str_verify(&pwhash[0], &password[0], password.length()) == 0; return crypto_pwhash_scryptsalsa208sha256_str_verify(&pwhash[0], &password[0], password.length()) == 0;
#endif #endif
default: default: {
{ auto hash = eqcrypt_hash(username, password, mode);
auto hash = eqcrypt_hash(username, password, mode); return hash.compare(pwhash) == 0;
return hash.compare(pwhash) == 0; }
}
} }
return false; return false;

View File

@ -26,6 +26,7 @@
#include "../common/platform.h" #include "../common/platform.h"
#include "../common/crash.h" #include "../common/crash.h"
#include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys.h"
#include "../common/eqemu_logsys_fmt.h"
#include "login_server.h" #include "login_server.h"
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
@ -58,10 +59,10 @@ int main()
LogSys.log_settings[Logs::Login_Server].log_to_console = Logs::Detail; LogSys.log_settings[Logs::Login_Server].log_to_console = Logs::Detail;
Log(Logs::General, Logs::Login_Server, "Logging System Init."); LogLoginserver("Logging System Init");
server.config = EQ::JsonConfigFile::Load("login.json"); server.config = EQ::JsonConfigFile::Load("login.json");
Log(Logs::General, Logs::Login_Server, "Config System Init."); LogLoginserver("Config System Init");
server.options.Trace(server.config.GetVariableBool("general", "trace", false)); server.options.Trace(server.config.GetVariableBool("general", "trace", false));
server.options.WorldTrace(server.config.GetVariableBool("general", "world_trace", false)); server.options.WorldTrace(server.config.GetVariableBool("general", "world_trace", false));
@ -131,7 +132,7 @@ int main()
/** /**
* mysql connect * mysql connect
*/ */
Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); LogLoginserver("MySQL Database Init");
server.db = new Database( server.db = new Database(
server.config.GetVariableString("database", "user", "root"), server.config.GetVariableString("database", "user", "root"),
@ -145,19 +146,19 @@ int main()
* make sure our database got created okay, otherwise cleanup and exit * make sure our database got created okay, otherwise cleanup and exit
*/ */
if (!server.db) { if (!server.db) {
Log(Logs::General, Logs::Error, "Database Initialization Failure."); Error("Database Initialization Failure");
Log(Logs::General, Logs::Login_Server, "Log System Shutdown."); LogLoginserver("Log System Shutdown");
return 1; return 1;
} }
/** /**
* create server manager * create server manager
*/ */
Log(Logs::General, Logs::Login_Server, "Server Manager Initialize."); LogLoginserver("Server Manager Init");
server.server_manager = new ServerManager(); server.server_manager = new ServerManager();
if (!server.server_manager) { if (!server.server_manager) {
Log(Logs::General, Logs::Error, "Server Manager Failed to Start."); Error("Server Manager Failed to Start");
Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); LogLoginserver("Database System Shutdown");
delete server.db; delete server.db;
return 1; return 1;
} }
@ -165,14 +166,14 @@ int main()
/** /**
* create client manager * create client manager
*/ */
Log(Logs::General, Logs::Login_Server, "Client Manager Initialize."); LogLoginserver("Client Manager Init");
server.client_manager = new ClientManager(); server.client_manager = new ClientManager();
if (!server.client_manager) { if (!server.client_manager) {
Log(Logs::General, Logs::Error, "Client Manager Failed to Start."); Error("Client Manager Failed to Start");
Log(Logs::General, Logs::Login_Server, "Server Manager Shutdown."); LogLoginserver("Server Manager Shutdown");
delete server.server_manager; delete server.server_manager;
Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); LogLoginserver("Database System Shutdown");
delete server.db; delete server.db;
return 1; return 1;
} }
@ -185,14 +186,10 @@ int main()
#endif #endif
#endif #endif
Log(Logs::General, Logs::Login_Server, "Server Started."); LogLoginserver("Server Started");
if (LogSys.log_settings[Logs::Login_Server].log_to_console == 1) { if (LogSys.log_settings[Logs::Login_Server].log_to_console == 1) {
Log( LogLoginserver("Loginserver logging set to level [1] for more debugging, enable detail [3]");
Logs::General,
Logs::Login_Server,
"Loginserver logging set to level [1] for more debugging, enable detail [3]"
);
} }
while (run_server) { while (run_server) {
@ -202,13 +199,13 @@ int main()
Sleep(5); Sleep(5);
} }
Log(Logs::General, Logs::Login_Server, "Server Shutdown."); LogLoginserver("Server Shutdown");
Log(Logs::General, Logs::Login_Server, "Client Manager Shutdown."); LogLoginserver("Client Manager Shutdown");
delete server.client_manager; delete server.client_manager;
Log(Logs::General, Logs::Login_Server, "Server Manager Shutdown."); LogLoginserver("Server Manager Shutdown");
delete server.server_manager; delete server.server_manager;
Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); LogLoginserver("Database System Shutdown");
delete server.db; delete server.db;
return 0; return 0;
} }

View File

@ -39,23 +39,27 @@ ServerManager::ServerManager()
opts.ipv6 = false; opts.ipv6 = false;
server_connection->Listen(opts); server_connection->Listen(opts);
LogLoginserver("Loginserver now listening on port [{0}]", listen_port);
server_connection->OnConnectionIdentified( server_connection->OnConnectionIdentified(
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) { "World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> world_connection) {
LogF(Logs::General, LogLoginserver(
Logs::Login_Server, "New world server connection from {0}:{1}",
"New world server connection from {0}:{1}", world_connection->Handle()->RemoteIP(),
c->Handle()->RemoteIP(), world_connection->Handle()->RemotePort()
c->Handle()->RemotePort()); );
auto iter = world_servers.begin(); auto iter = world_servers.begin();
while (iter != world_servers.end()) { while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 && if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(world_connection->Handle()->RemoteIP()) ==
(*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) { 0 &&
LogF(Logs::General, (*iter)->GetConnection()->Handle()->RemotePort() == world_connection->Handle()->RemotePort()) {
Logs::Login_Server,
"World server already existed for {0}:{1}, removing existing connection.", LogLoginserver(
c->Handle()->RemoteIP(), "World server already existed for {0}:{1}, removing existing connection.",
c->Handle()->RemotePort()); world_connection->Handle()->RemoteIP(),
world_connection->Handle()->RemotePort()
);
world_servers.erase(iter); world_servers.erase(iter);
break; break;
@ -64,7 +68,7 @@ ServerManager::ServerManager()
++iter; ++iter;
} }
world_servers.push_back(std::unique_ptr<WorldServer>(new WorldServer(c))); world_servers.push_back(std::unique_ptr<WorldServer>(new WorldServer(world_connection)));
} }
); );
@ -87,16 +91,18 @@ ServerManager::ServerManager()
); );
} }
ServerManager::~ServerManager() ServerManager::~ServerManager() = default;
{
} /**
* @param ip_address
WorldServer *ServerManager::GetServerByAddress(const std::string &addr, int port) * @param port
* @return
*/
WorldServer *ServerManager::GetServerByAddress(const std::string &ip_address, int port)
{ {
auto iter = world_servers.begin(); auto iter = world_servers.begin();
while (iter != world_servers.end()) { while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr && if ((*iter)->GetConnection()->Handle()->RemoteIP() == ip_address &&
(*iter)->GetConnection()->Handle()->RemotePort()) { (*iter)->GetConnection()->Handle()->RemotePort()) {
return (*iter).get(); return (*iter).get();
} }
@ -106,12 +112,17 @@ WorldServer *ServerManager::GetServerByAddress(const std::string &addr, int port
return nullptr; return nullptr;
} }
EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq) /**
* @param client
* @param sequence
* @return
*/
EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint32 sequence)
{ {
unsigned int packet_size = sizeof(ServerListHeader_Struct); unsigned int packet_size = sizeof(ServerListHeader_Struct);
unsigned int server_count = 0; unsigned int server_count = 0;
in_addr in; in_addr in;
in.s_addr = c->GetConnection()->GetRemoteIP(); in.s_addr = client->GetConnection()->GetRemoteIP();
std::string client_ip = inet_ntoa(in); std::string client_ip = inet_ntoa(in);
auto iter = world_servers.begin(); auto iter = world_servers.begin();
@ -139,7 +150,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size); EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size);
ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer; ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer;
server_list->Unknown1 = seq; server_list->Unknown1 = sequence;
server_list->Unknown2 = 0x00000000; server_list->Unknown2 = 0x00000000;
server_list->Unknown3 = 0x01650000; server_list->Unknown3 = 0x01650000;
@ -225,6 +236,11 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
return outapp; return outapp;
} }
/**
* @param server_id
* @param client_account_id
* @param client_loginserver
*/
void ServerManager::SendUserToWorldRequest( void ServerManager::SendUserToWorldRequest(
unsigned int server_id, unsigned int server_id,
unsigned int client_account_id, unsigned int client_account_id,
@ -259,7 +275,17 @@ void ServerManager::SendUserToWorldRequest(
} }
} }
bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldServer *ignore) /**
* @param server_long_name
* @param server_short_name
* @param ignore
* @return
*/
bool ServerManager::ServerExists(
std::string server_long_name,
std::string server_short_name,
WorldServer *ignore
)
{ {
auto iter = world_servers.begin(); auto iter = world_servers.begin();
while (iter != world_servers.end()) { while (iter != world_servers.end()) {
@ -268,7 +294,7 @@ bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldSe
continue; continue;
} }
if ((*iter)->GetLongName().compare(l_name) == 0 && (*iter)->GetShortName().compare(s_name) == 0) { if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_name) == 0) {
return true; return true;
} }
@ -277,7 +303,16 @@ bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldSe
return false; return false;
} }
void ServerManager::DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore) /**
* @param server_long_name
* @param server_short_name
* @param ignore
*/
void ServerManager::DestroyServerByName(
std::string server_long_name,
std::string server_short_name,
WorldServer *ignore
)
{ {
auto iter = world_servers.begin(); auto iter = world_servers.begin();
while (iter != world_servers.end()) { while (iter != world_servers.end()) {
@ -286,7 +321,7 @@ void ServerManager::DestroyServerByName(std::string l_name, std::string s_name,
continue; continue;
} }
if ((*iter)->GetLongName().compare(l_name) == 0 && (*iter)->GetShortName().compare(s_name) == 0) { if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_name) == 0) {
(*iter)->GetConnection()->Handle()->Disconnect(); (*iter)->GetConnection()->Handle()->Disconnect();
iter = world_servers.erase(iter); iter = world_servers.erase(iter);
continue; continue;

View File

@ -61,30 +61,30 @@ public:
/** /**
* Creates a server list packet for the client * Creates a server list packet for the client
* *
* @param c * @param client
* @param seq * @param sequence
* @return * @return
*/ */
EQApplicationPacket *CreateServerListPacket(Client *c, uint32 seq); EQApplicationPacket *CreateServerListPacket(Client *client, uint32 sequence);
/** /**
* Checks to see if there is a server exists with this name, ignoring option * Checks to see if there is a server exists with this name, ignoring option
* *
* @param l_name * @param server_long_name
* @param s_name * @param server_short_name
* @param ignore * @param ignore
* @return * @return
*/ */
bool ServerExists(std::string l_name, std::string s_name, WorldServer *ignore = nullptr); bool ServerExists(std::string server_long_name, std::string server_short_name, WorldServer *ignore = nullptr);
/** /**
* Destroys a server with this name, ignoring option * Destroys a server with this name, ignoring option
* *
* @param l_name * @param server_long_name
* @param s_name * @param server_short_name
* @param ignore * @param ignore
*/ */
void DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore = nullptr); void DestroyServerByName(std::string server_long_name, std::string server_short_name, WorldServer *ignore = nullptr);
private: private:
@ -92,11 +92,11 @@ private:
* Retrieves a server(if exists) by ip address * Retrieves a server(if exists) by ip address
* Useful utility for the reconnect process * Useful utility for the reconnect process
* *
* @param address * @param ip_address
* @param port * @param port
* @return * @return
*/ */
WorldServer *GetServerByAddress(const std::string &address, int port); WorldServer *GetServerByAddress(const std::string &ip_address, int port);
std::unique_ptr<EQ::Net::ServertalkServer> server_connection; std::unique_ptr<EQ::Net::ServertalkServer> server_connection;
std::list<std::unique_ptr<WorldServer>> world_servers; std::list<std::unique_ptr<WorldServer>> world_servers;

View File

@ -27,9 +27,12 @@
extern LoginServer server; extern LoginServer server;
WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c) /**
* @param worldserver_connection
*/
WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> worldserver_connection)
{ {
connection = c; connection = worldserver_connection;
zones_booted = 0; zones_booted = 0;
players_online = 0; players_online = 0;
server_status = 0; server_status = 0;
@ -40,17 +43,17 @@ WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
is_server_trusted = false; is_server_trusted = false;
is_server_logged_in = false; is_server_logged_in = false;
c->OnMessage( worldserver_connection->OnMessage(
ServerOP_NewLSInfo, ServerOP_NewLSInfo,
std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2) std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2)
); );
c->OnMessage( worldserver_connection->OnMessage(
ServerOP_LSStatus, ServerOP_LSStatus,
std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2) std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2)
); );
c->OnMessage( worldserver_connection->OnMessage(
ServerOP_UsertoWorldRespLeg, ServerOP_UsertoWorldRespLeg,
std::bind( std::bind(
&WorldServer::ProcessUsertoWorldRespLeg, &WorldServer::ProcessUsertoWorldRespLeg,
@ -60,49 +63,50 @@ WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
) )
); );
c->OnMessage( worldserver_connection->OnMessage(
ServerOP_UsertoWorldResp, ServerOP_UsertoWorldResp,
std::bind(&WorldServer::ProcessUsertoWorldResp, this, std::placeholders::_1, std::placeholders::_2) std::bind(&WorldServer::ProcessUserToWorldResponse, this, std::placeholders::_1, std::placeholders::_2)
); );
c->OnMessage( worldserver_connection->OnMessage(
ServerOP_LSAccountUpdate, ServerOP_LSAccountUpdate,
std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2) std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)
); );
} }
WorldServer::~WorldServer() WorldServer::~WorldServer() = default;
{
}
void WorldServer::Reset() void WorldServer::Reset()
{ {
zones_booted = 0;
players_online = 0;
server_status = 0;
runtime_id; runtime_id;
zones_booted = 0;
players_online = 0;
server_status = 0;
server_list_id = 0; server_list_id = 0;
server_type = 0; server_type = 0;
is_server_authorized = false; is_server_authorized = false;
is_server_logged_in = false; is_server_logged_in = false;
} }
void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) /**
* @param opcode
* @param packet
*/
void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet)
{ {
if (server.options.IsWorldTraceOn()) { if (server.options.IsWorldTraceOn()) {
Log(Logs::General, Log(Logs::General,
Logs::Netcode, Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)", "Application packet received from server: 0x%.4X, (size %u)",
opcode, opcode,
p.Length()); packet.Length());
} }
if (server.options.IsDumpInPacketsOn()) { if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p); DumpPacket(opcode, packet);
} }
if (p.Length() < sizeof(ServerNewLSInfo_Struct)) { if (packet.Length() < sizeof(ServerNewLSInfo_Struct)) {
Log(Logs::General, Logs::Error, Log(Logs::General, Logs::Error,
"Received application packet from server that had opcode ServerOP_NewLSInfo, " "Received application packet from server that had opcode ServerOP_NewLSInfo, "
"but was too small. Discarded to avoid buffer overrun."); "but was too small. Discarded to avoid buffer overrun.");
@ -110,7 +114,7 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p)
} }
ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) p.Data(); ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) packet.Data();
LogF( LogF(
Logs::General, Logs::General,
@ -139,21 +143,25 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p)
Handle_NewLSInfo(info); Handle_NewLSInfo(info);
} }
void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) /**
* @param opcode
* @param packet
*/
void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet)
{ {
Log( Log(
Logs::Detail, Logs::Detail,
Logs::Netcode, Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)", "Application packet received from server: 0x%.4X, (size %u)",
opcode, opcode,
p.Length() packet.Length()
); );
if (server.options.IsDumpInPacketsOn()) { if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p); DumpPacket(opcode, packet);
} }
if (p.Length() < sizeof(ServerLSStatus_Struct)) { if (packet.Length() < sizeof(ServerLSStatus_Struct)) {
Log( Log(
Logs::General, Logs::General,
Logs::Error, Logs::Error,
@ -163,11 +171,9 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p)
return; return;
} }
ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) p.Data(); ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) packet.Data();
LogF( LogLoginserverDetail(
Logs::Detail,
Logs::Login_Server,
"World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]",
this->GetLongName(), this->GetLongName(),
ls_status->status, ls_status->status,
@ -178,21 +184,25 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p)
Handle_LSStatus(ls_status); Handle_LSStatus(ls_status);
} }
void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p) /**
* @param opcode
* @param packet
*/
void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &packet)
{ {
if (server.options.IsWorldTraceOn()) { if (server.options.IsWorldTraceOn()) {
Log(Logs::General, Log(Logs::General,
Logs::Netcode, Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)", "Application packet received from server: 0x%.4X, (size %u)",
opcode, opcode,
p.Length()); packet.Length());
} }
if (server.options.IsDumpInPacketsOn()) { if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p); DumpPacket(opcode, packet);
} }
if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) { if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) {
Log(Logs::General, Log(Logs::General,
Logs::Error, Logs::Error,
"Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
@ -207,7 +217,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
Log(Logs::General, Logs::Netcode, "User-To-World Response received."); Log(Logs::General, Logs::Netcode, "User-To-World Response received.");
} }
UsertoWorldResponseLegacy_Struct *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) p.Data(); UsertoWorldResponseLegacy_Struct *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data();
Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid);
Client *c = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu"); Client *c = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu");
if (c) { if (c) {
@ -276,28 +286,32 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
delete outapp; delete outapp;
} }
else { else {
Log(Logs::General, Error(
Logs::Error, "Received User-To-World Response for {0} but could not find the client referenced!",
"Received User-To-World Response for %u but could not find the client referenced!.", user_to_world_response->lsaccountid
user_to_world_response->lsaccountid); );
} }
} }
void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p) /**
* @param opcode
* @param packet
*/
void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet)
{ {
if (server.options.IsWorldTraceOn()) { if (server.options.IsWorldTraceOn()) {
Log(Logs::General, Log(Logs::General,
Logs::Netcode, Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)", "Application packet received from server: 0x%.4X, (size %u)",
opcode, opcode,
p.Length()); packet.Length());
} }
if (server.options.IsDumpInPacketsOn()) { if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p); DumpPacket(opcode, packet);
} }
if (p.Length() < sizeof(UsertoWorldResponse_Struct)) { if (packet.Length() < sizeof(UsertoWorldResponse_Struct)) {
Log(Logs::General, Log(Logs::General,
Logs::Error, Logs::Error,
"Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
@ -312,7 +326,7 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet
Log(Logs::General, Logs::Netcode, "User-To-World Response received."); Log(Logs::General, Logs::Netcode, "User-To-World Response received.");
} }
UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct *) p.Data(); UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct *) packet.Data();
Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid);
Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login); Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login);
if (c) { if (c) {
@ -387,23 +401,23 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet
/** /**
* @param opcode * @param opcode
* @param p * @param packet
*/ */
void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p) void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet)
{ {
if (server.options.IsWorldTraceOn()) { if (server.options.IsWorldTraceOn()) {
Log(Logs::General, Log(Logs::General,
Logs::Netcode, Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)", "Application packet received from server: 0x%.4X, (size %u)",
opcode, opcode,
p.Length()); packet.Length());
} }
if (server.options.IsDumpInPacketsOn()) { if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p); DumpPacket(opcode, packet);
} }
if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) { if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) {
Log(Logs::General, Log(Logs::General,
Logs::Error, Logs::Error,
"Received application packet from server that had opcode ServerLSAccountUpdate_Struct, " "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, "
@ -412,7 +426,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
} }
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str());
ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) p.Data(); ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) packet.Data();
if (is_server_trusted) { if (is_server_trusted) {
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount);
std::string name = ""; std::string name = "";
@ -429,74 +443,70 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
} }
} }
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_packet)
{ {
if (is_server_logged_in) { if (is_server_logged_in) {
Log(Logs::General, Error("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting.");
Logs::Error,
"WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting.");
return; return;
} }
if (strlen(i->account) <= 30) { if (strlen(new_worldserver_info_packet->account) <= 30) {
account_name = i->account; account_name = new_worldserver_info_packet->account;
} }
else { else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account name was too long."); Error("Handle_NewLSInfo error, account name was too long.");
return; return;
} }
if (strlen(i->password) <= 30) { if (strlen(new_worldserver_info_packet->password) <= 30) {
account_password = i->password; account_password = new_worldserver_info_packet->password;
} }
else { else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account password was too long."); Error("Handle_NewLSInfo error, account password was too long.");
return; return;
} }
if (strlen(i->name) <= 200) { if (strlen(new_worldserver_info_packet->name) <= 200) {
long_name = i->name; long_name = new_worldserver_info_packet->name;
} }
else { else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, long name was too long."); Error("Handle_NewLSInfo error, long name was too long.");
return; return;
} }
if (strlen(i->shortname) <= 50) { if (strlen(new_worldserver_info_packet->shortname) <= 50) {
short_name = i->shortname; short_name = new_worldserver_info_packet->shortname;
} }
else { else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, short name was too long."); Error("Handle_NewLSInfo error, short name was too long.");
return; return;
} }
if (strlen(i->local_address) <= 125) { if (strlen(new_worldserver_info_packet->local_address) <= 125) {
if (strlen(i->local_address) == 0) { if (strlen(new_worldserver_info_packet->local_address) == 0) {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was null, defaulting to localhost"); Error("Handle_NewLSInfo error, local address was null, defaulting to localhost");
local_ip = "127.0.0.1"; local_ip = "127.0.0.1";
} }
else { else {
local_ip = i->local_address; local_ip = new_worldserver_info_packet->local_address;
} }
} }
else { else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was too long."); Error("Handle_NewLSInfo error, local address was too long.");
return; return;
} }
if (strlen(i->remote_address) <= 125) { if (strlen(new_worldserver_info_packet->remote_address) <= 125) {
if (strlen(i->remote_address) == 0) { if (strlen(new_worldserver_info_packet->remote_address) == 0) {
remote_ip = GetConnection()->Handle()->RemoteIP(); remote_ip = GetConnection()->Handle()->RemoteIP();
Log( Error(
Logs::General,
Logs::Error,
"Remote address was null, defaulting to stream address %s.", "Remote address was null, defaulting to stream address %s.",
remote_ip.c_str() remote_ip.c_str()
); );
} }
else { else {
remote_ip = i->remote_address; remote_ip = new_worldserver_info_packet->remote_address;
} }
} }
else { else {
@ -510,23 +520,23 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i)
); );
} }
if (strlen(i->serverversion) <= 64) { if (strlen(new_worldserver_info_packet->serverversion) <= 64) {
version = i->serverversion; version = new_worldserver_info_packet->serverversion;
} }
else { else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, server version was too long."); Error("Handle_NewLSInfo error, server version was too long.");
return; return;
} }
if (strlen(i->protocolversion) <= 25) { if (strlen(new_worldserver_info_packet->protocolversion) <= 25) {
protocol = i->protocolversion; protocol = new_worldserver_info_packet->protocolversion;
} }
else { else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, protocol version was too long."); Error("Handle_NewLSInfo error, protocol version was too long.");
return; return;
} }
server_type = i->servertype; server_type = new_worldserver_info_packet->servertype;
is_server_logged_in = true; is_server_logged_in = true;
if (server.options.IsRejectingDuplicateServers()) { if (server.options.IsRejectingDuplicateServers()) {
@ -715,13 +725,13 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i)
} }
/** /**
* @param s * @param server_login_status
*/ */
void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *server_login_status)
{ {
players_online = s->num_players; players_online = server_login_status->num_players;
zones_booted = s->num_zones; zones_booted = server_login_status->num_zones;
server_status = s->status; server_status = server_login_status->status;
} }
/** /**
@ -752,8 +762,8 @@ void WorldServer::SendClientAuth(
client_auth.ip = inet_addr(ip.c_str()); client_auth.ip = inet_addr(ip.c_str());
strncpy(client_auth.lsname, &loginserver_name[0], 64); strncpy(client_auth.lsname, &loginserver_name[0], 64);
const std::string& client_address(ip); const std::string &client_address(ip);
std::string world_address(connection->Handle()->RemoteIP()); std::string world_address(connection->Handle()->RemoteIP());
if (client_address.compare(world_address) == 0) { if (client_address.compare(world_address) == 0) {
client_auth.local = 1; client_auth.local = 1;

View File

@ -34,7 +34,7 @@
class WorldServer class WorldServer
{ {
public: public:
WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c); WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> worldserver_connection);
/** /**
* Destructor, frees our connection if it exists * Destructor, frees our connection if it exists
@ -77,16 +77,16 @@ public:
/** /**
* Takes the info struct we received from world and processes it * Takes the info struct we received from world and processes it
* *
* @param i * @param new_worldserver_info_packet
*/ */
void Handle_NewLSInfo(ServerNewLSInfo_Struct* i); void Handle_NewLSInfo(ServerNewLSInfo_Struct* new_worldserver_info_packet);
/** /**
* Takes the status struct we received from world and processes it * Takes the status struct we received from world and processes it
* *
* @param s * @param server_login_status
*/ */
void Handle_LSStatus(ServerLSStatus_Struct *s); void Handle_LSStatus(ServerLSStatus_Struct *server_login_status);
/** /**
* Informs world that there is a client incoming with the following data. * Informs world that there is a client incoming with the following data.
@ -105,13 +105,13 @@ private:
* Packet processing functions * Packet processing functions
* *
* @param opcode * @param opcode
* @param p * @param packet
*/ */
void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p); void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet);
void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p); void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet);
void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p); void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &packet);
void ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p); void ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet);
void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p); void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet);
std::shared_ptr<EQ::Net::ServertalkServerConnection> connection; std::shared_ptr<EQ::Net::ServertalkServerConnection> connection;
unsigned int zones_booted; unsigned int zones_booted;