More loginserver refactorings and cleanup

This commit is contained in:
Akkadius 2019-07-05 02:49:55 -05:00
parent b41e58fd10
commit 2c922876a9
7 changed files with 129 additions and 91 deletions

View File

@ -30,7 +30,9 @@ extern bool run_server;
ClientManager::ClientManager() ClientManager::ClientManager()
{ {
int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998);
EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false); EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false);
titanium_stream = new EQ::Net::EQStreamManager(titanium_opts); titanium_stream = new EQ::Net::EQStreamManager(titanium_opts);
titanium_ops = new RegularOpcodeManager; titanium_ops = new RegularOpcodeManager;
if (!titanium_ops->LoadOpcodes( if (!titanium_ops->LoadOpcodes(
@ -39,8 +41,12 @@ ClientManager::ClientManager()
"opcodes", "opcodes",
"login_opcodes.conf" "login_opcodes.conf"
).c_str())) { ).c_str())) {
Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for Titanium file %s.",
server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str()); Error(
"ClientManager fatal error: couldn't load opcodes for Titanium file [{0}]",
server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf")
);
run_server = false; run_server = false;
} }
@ -58,6 +64,7 @@ ClientManager::ClientManager()
); );
int sod_port = server.config.GetVariableInt("SoD", "port", 5999); int sod_port = server.config.GetVariableInt("SoD", "port", 5999);
EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false); EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false);
sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_stream = new EQ::Net::EQStreamManager(sod_opts);
sod_ops = new RegularOpcodeManager; sod_ops = new RegularOpcodeManager;
@ -69,11 +76,12 @@ ClientManager::ClientManager()
sod_stream->OnNewConnection( sod_stream->OnNewConnection(
[this](std::shared_ptr<EQ::Net::EQStream> stream) { [this](std::shared_ptr<EQ::Net::EQStream> stream) {
LogF(Logs::General, LogLoginserver(
Logs::Login_Server,
"New SoD client connection from {0}:{1}", "New SoD client connection from {0}:{1}",
stream->GetRemoteIP(), stream->GetRemoteIP(),
stream->GetRemotePort()); stream->GetRemotePort()
);
stream->SetOpcodeManager(&sod_ops); stream->SetOpcodeManager(&sod_ops);
Client *c = new Client(stream, cv_sod); Client *c = new Client(stream, cv_sod);
clients.push_back(c); clients.push_back(c);
@ -133,6 +141,10 @@ void ClientManager::ProcessDisconnect()
} }
} }
/**
* @param account_id
* @param loginserver
*/
void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver) void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver)
{ {
auto iter = clients.begin(); auto iter = clients.begin();
@ -150,6 +162,11 @@ void ClientManager::RemoveExistingClient(unsigned int account_id, const std::str
} }
} }
/**
* @param account_id
* @param loginserver
* @return
*/
Client *ClientManager::GetClient(unsigned int account_id, const std::string &loginserver) Client *ClientManager::GetClient(unsigned int account_id, const std::string &loginserver)
{ {
auto iter = clients.begin(); auto iter = clients.begin();

View File

@ -20,6 +20,7 @@
#include "../common/global_define.h" #include "../common/global_define.h"
#include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys.h"
#include "../common/eqemu_logsys_fmt.h"
#include "config.h" #include "config.h"
/** /**
@ -52,7 +53,7 @@ std::string Config::GetVariable(std::string title, std::string parameter)
void Config::Parse(const char *file_name) void Config::Parse(const char *file_name)
{ {
if (file_name == nullptr) { if (file_name == nullptr) {
Log(Logs::General, Logs::Error, "Config::Parse(), file_name passed was null."); Error("Config::Parse(), file_name passed was null");
return; return;
} }
@ -64,6 +65,7 @@ void Config::Parse(const char *file_name)
char mode = 0; char mode = 0;
std::string title, param, arg; std::string title, param, arg;
std::list<std::string>::iterator iter = tokens.begin(); std::list<std::string>::iterator iter = tokens.begin();
while (iter != tokens.end()) { while (iter != tokens.end()) {
if ((*iter).compare("[") == 0) { if ((*iter).compare("[") == 0) {
@ -71,7 +73,7 @@ void Config::Parse(const char *file_name)
bool first = true; bool first = true;
++iter; ++iter;
if (iter == tokens.end()) { if (iter == tokens.end()) {
Log(Logs::General, Logs::Error, "Config::Parse(), EOF before title done parsing."); Error("Config::Parse(), EOF before title done parsing");
fclose(input); fclose(input);
vars.clear(); vars.clear();
return; return;
@ -98,7 +100,7 @@ void Config::Parse(const char *file_name)
else if (mode == 1) { else if (mode == 1) {
mode++; mode++;
if ((*iter).compare("=") != 0) { if ((*iter).compare("=") != 0) {
Log(Logs::General, Logs::Error, "Config::Parse(), invalid parse token where = should be."); Error("Config::Parse(), invalid parse token where = should be");
fclose(input); fclose(input);
vars.clear(); vars.clear();
return; return;
@ -123,7 +125,7 @@ void Config::Parse(const char *file_name)
fclose(input); fclose(input);
} }
else { else {
Log(Logs::General, Logs::Error, "Config::Parse(), file was unable to be opened for parsing."); Error("Config::Parse(), file was unable to be opened for parsing");
} }
} }

View File

@ -41,7 +41,7 @@ public:
Database *db; Database *db;
Options options; Options options;
ServerManager *server_manager; ServerManager *server_manager;
ClientManager *client_manager; ClientManager *client_manager{};
}; };
#endif #endif

View File

@ -196,7 +196,7 @@ int main()
Timer::SetCurrentTime(); Timer::SetCurrentTime();
server.client_manager->Process(); server.client_manager->Process();
EQ::EventLoop::Get().Process(); EQ::EventLoop::Get().Process();
Sleep(5); Sleep(50);
} }
LogLoginserver("Server Shutdown"); LogLoginserver("Server Shutdown");

View File

@ -148,8 +148,9 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3
++iter; ++iter;
} }
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size); auto *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size);
ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer; auto *server_list = (ServerListHeader_Struct *) outapp->pBuffer;
server_list->Unknown1 = sequence; server_list->Unknown1 = sequence;
server_list->Unknown2 = 0x00000000; server_list->Unknown2 = 0x00000000;
server_list->Unknown3 = 0x01650000; server_list->Unknown3 = 0x01650000;
@ -253,10 +254,11 @@ void ServerManager::SendUserToWorldRequest(
if ((*iter)->GetRuntimeID() == server_id) { if ((*iter)->GetRuntimeID() == server_id) {
EQ::Net::DynamicPacket outapp; EQ::Net::DynamicPacket outapp;
outapp.Resize(sizeof(UsertoWorldRequest_Struct)); outapp.Resize(sizeof(UsertoWorldRequest_Struct));
UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct *) outapp.Data();
utwr->worldid = server_id; auto *user_to_world_request = (UsertoWorldRequest_Struct *) outapp.Data();
utwr->lsaccountid = client_account_id; user_to_world_request->worldid = server_id;
strncpy(utwr->login, &client_loginserver[0], 64); user_to_world_request->lsaccountid = client_account_id;
strncpy(user_to_world_request->login, &client_loginserver[0], 64);
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp); (*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
found = true; found = true;
@ -294,7 +296,8 @@ bool ServerManager::ServerExists(
continue; continue;
} }
if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_name) == 0) { if ((*iter)->GetLongName().compare(server_long_name) == 0 &&
(*iter)->GetShortName().compare(server_short_name) == 0) {
return true; return true;
} }
@ -321,7 +324,8 @@ void ServerManager::DestroyServerByName(
continue; continue;
} }
if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_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

@ -162,16 +162,14 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet
} }
if (packet.Length() < sizeof(ServerLSStatus_Struct)) { if (packet.Length() < sizeof(ServerLSStatus_Struct)) {
Log( Error(
Logs::General,
Logs::Error,
"Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun" "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun"
); );
return; return;
} }
ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) packet.Data(); auto *ls_status = (ServerLSStatus_Struct *) packet.Data();
LogLoginserverDetail( LogLoginserverDetail(
"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}]",
@ -203,10 +201,10 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
} }
if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) { if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) {
Log(Logs::General, Error(
Logs::Error,
"Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
"but was too small. Discarded to avoid buffer overrun."); "but was too small. Discarded to avoid buffer overrun"
);
return; return;
} }
@ -217,7 +215,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 *) packet.Data(); auto *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) {
@ -229,12 +227,12 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
c->GetAccountName().c_str() c->GetAccountName().c_str()
); );
EQApplicationPacket *outapp = new EQApplicationPacket( auto *outapp = new EQApplicationPacket(
OP_PlayEverquestResponse, OP_PlayEverquestResponse,
sizeof(PlayEverquestResponse_Struct) sizeof(PlayEverquestResponse_Struct)
); );
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
per->Sequence = c->GetPlaySequence(); per->Sequence = c->GetPlaySequence();
per->ServerNumber = c->GetPlayServerID(); per->ServerNumber = c->GetPlayServerID();
@ -326,36 +324,49 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
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 *) packet.Data(); auto user_to_world_response = (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.", user_to_world_response->lsaccountid);
Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login); Client *client = server.client_manager->GetClient(
if (c) { user_to_world_response->lsaccountid,
user_to_world_response->login
);
if (client) {
Log(Logs::General, Log(Logs::General,
Logs::Debug, Logs::Debug,
"Found client with user id of %u and account name of %s.", "Found client with user id of %u and account name of %s.",
utwr->lsaccountid, user_to_world_response->lsaccountid,
c->GetAccountName().c_str()); client->GetAccountName().c_str()
EQApplicationPacket *outapp = new EQApplicationPacket( );
auto *outapp = new EQApplicationPacket(
OP_PlayEverquestResponse, OP_PlayEverquestResponse,
sizeof(PlayEverquestResponse_Struct)); sizeof(PlayEverquestResponse_Struct)
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; );
per->Sequence = c->GetPlaySequence();
per->ServerNumber = c->GetPlayServerID(); auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); per->Sequence = client->GetPlaySequence();
per->ServerNumber = client->GetPlayServerID();
Log(Logs::General,
Logs::Debug,
"Found sequence and play of %u %u",
client->GetPlaySequence(),
client->GetPlayServerID()
);
Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
if (utwr->response > 0) { if (user_to_world_response->response > 0) {
per->Allowed = 1; per->Allowed = 1;
SendClientAuth( SendClientAuth(
c->GetConnection()->GetRemoteAddr(), client->GetConnection()->GetRemoteAddr(),
c->GetAccountName(), client->GetAccountName(),
c->GetKey(), client->GetKey(),
c->GetAccountID(), client->GetAccountID(),
c->GetLoginServerName()); client->GetLoginServerName()
);
} }
switch (utwr->response) { switch (user_to_world_response->response) {
case 1: case 1:
per->Message = 101; per->Message = 101;
break; break;
@ -388,14 +399,12 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
DumpPacket(outapp); DumpPacket(outapp);
} }
c->SendPlayResponse(outapp); client->SendPlayResponse(outapp);
delete outapp; delete outapp;
} }
else { else {
Log(Logs::General, Error("Received User-To-World Response for {0} but could not find the client referenced!.",
Logs::Error, user_to_world_response->lsaccountid);
"Received User-To-World Response for %u but could not find the client referenced!.",
utwr->lsaccountid);
} }
} }
@ -418,77 +427,83 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
} }
if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) { if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) {
Log(Logs::General, Error(
Logs::Error,
"Received application packet from server that had opcode ServerLSAccountUpdate_Struct, " "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, "
"but was too small. Discarded to avoid buffer overrun."); "but was too small. Discarded to avoid buffer overrun"
);
return; return;
} }
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 *) packet.Data();
auto *loginserver_update = (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", loginserver_update->useraccount);
std::string name = ""; std::string name = "";
std::string password = ""; std::string password = "";
std::string email = ""; std::string email = "";
name.assign(lsau->useraccount); name.assign(loginserver_update->useraccount);
password.assign(lsau->userpassword); password.assign(loginserver_update->userpassword);
if (lsau->useremail) { if (loginserver_update->useremail) {
email.assign(lsau->useremail); email.assign(loginserver_update->useremail);
} }
server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email); server.db->UpdateLSAccountInfo(loginserver_update->useraccountid, name, password, email);
} }
} }
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_packet) /**
*
* @param new_world_server_info_packet
*/
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info_packet)
{ {
if (is_server_logged_in) { if (is_server_logged_in) {
Error("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); Error("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting.");
return; return;
} }
if (strlen(new_worldserver_info_packet->account) <= 30) { if (strlen(new_world_server_info_packet->account) <= 30) {
account_name = new_worldserver_info_packet->account; account_name = new_world_server_info_packet->account;
} }
else { else {
Error("Handle_NewLSInfo error, account name was too long."); Error("Handle_NewLSInfo error, account name was too long.");
return; return;
} }
if (strlen(new_worldserver_info_packet->password) <= 30) { if (strlen(new_world_server_info_packet->password) <= 30) {
account_password = new_worldserver_info_packet->password; account_password = new_world_server_info_packet->password;
} }
else { else {
Error("Handle_NewLSInfo error, account password was too long."); Error("Handle_NewLSInfo error, account password was too long.");
return; return;
} }
if (strlen(new_worldserver_info_packet->name) <= 200) { if (strlen(new_world_server_info_packet->name) <= 200) {
long_name = new_worldserver_info_packet->name; long_name = new_world_server_info_packet->name;
} }
else { else {
Error("Handle_NewLSInfo error, long name was too long."); Error("Handle_NewLSInfo error, long name was too long.");
return; return;
} }
if (strlen(new_worldserver_info_packet->shortname) <= 50) { if (strlen(new_world_server_info_packet->shortname) <= 50) {
short_name = new_worldserver_info_packet->shortname; short_name = new_world_server_info_packet->shortname;
} }
else { else {
Error("Handle_NewLSInfo error, short name was too long."); Error("Handle_NewLSInfo error, short name was too long.");
return; return;
} }
if (strlen(new_worldserver_info_packet->local_address) <= 125) { if (strlen(new_world_server_info_packet->local_address) <= 125) {
if (strlen(new_worldserver_info_packet->local_address) == 0) { if (strlen(new_world_server_info_packet->local_address) == 0) {
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 = new_worldserver_info_packet->local_address; local_ip = new_world_server_info_packet->local_address;
} }
} }
else { else {
@ -497,8 +512,8 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_
return; return;
} }
if (strlen(new_worldserver_info_packet->remote_address) <= 125) { if (strlen(new_world_server_info_packet->remote_address) <= 125) {
if (strlen(new_worldserver_info_packet->remote_address) == 0) { if (strlen(new_world_server_info_packet->remote_address) == 0) {
remote_ip = GetConnection()->Handle()->RemoteIP(); remote_ip = GetConnection()->Handle()->RemoteIP();
Error( Error(
"Remote address was null, defaulting to stream address %s.", "Remote address was null, defaulting to stream address %s.",
@ -506,7 +521,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_
); );
} }
else { else {
remote_ip = new_worldserver_info_packet->remote_address; remote_ip = new_world_server_info_packet->remote_address;
} }
} }
else { else {
@ -520,23 +535,23 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_
); );
} }
if (strlen(new_worldserver_info_packet->serverversion) <= 64) { if (strlen(new_world_server_info_packet->serverversion) <= 64) {
version = new_worldserver_info_packet->serverversion; version = new_world_server_info_packet->serverversion;
} }
else { else {
Error("Handle_NewLSInfo error, server version was too long."); Error("Handle_NewLSInfo error, server version was too long.");
return; return;
} }
if (strlen(new_worldserver_info_packet->protocolversion) <= 25) { if (strlen(new_world_server_info_packet->protocolversion) <= 25) {
protocol = new_worldserver_info_packet->protocolversion; protocol = new_world_server_info_packet->protocolversion;
} }
else { else {
Error("Handle_NewLSInfo error, protocol version was too long."); Error("Handle_NewLSInfo error, protocol version was too long.");
return; return;
} }
server_type = new_worldserver_info_packet->servertype; server_type = new_world_server_info_packet->servertype;
is_server_logged_in = true; is_server_logged_in = true;
if (server.options.IsRejectingDuplicateServers()) { if (server.options.IsRejectingDuplicateServers()) {

View File

@ -77,9 +77,9 @@ public:
/** /**
* Takes the info struct we received from world and processes it * Takes the info struct we received from world and processes it
* *
* @param new_worldserver_info_packet * @param new_world_server_info_packet
*/ */
void Handle_NewLSInfo(ServerNewLSInfo_Struct* new_worldserver_info_packet); void Handle_NewLSInfo(ServerNewLSInfo_Struct* new_world_server_info_packet);
/** /**
* Takes the status struct we received from world and processes it * Takes the status struct we received from world and processes it