Tons of cleanup / formatting

This commit is contained in:
Akkadius 2019-07-03 02:50:16 -05:00
parent 9e0f440106
commit 217c9751a8
19 changed files with 1515 additions and 1129 deletions

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "client.h"
#include "login_server.h"
#include "../common/misc_functions.h"
@ -25,28 +28,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
extern LoginServer server;
/**
* @param c
* @param v
*/
Client::Client(std::shared_ptr<EQStreamInterface> c, LSClientVersion v)
{
connection = c;
version = v;
status = cs_not_sent_session_ready;
account_id = 0;
play_server_id = 0;
connection = c;
version = v;
status = cs_not_sent_session_ready;
account_id = 0;
play_server_id = 0;
play_sequence_id = 0;
}
bool Client::Process()
{
EQApplicationPacket *app = connection->PopPacket();
while (app)
{
if (server.options.IsTraceOn())
{
while (app) {
if (server.options.IsTraceOn()) {
Log(Logs::General, Logs::Login_Server, "Application packet received from client (size %u)", app->Size());
}
if (server.options.IsDumpInPacketsOn())
{
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(app);
}
@ -56,67 +60,56 @@ bool Client::Process()
continue;
}
switch (app->GetOpcode())
{
case OP_SessionReady:
{
if (server.options.IsTraceOn())
{
Log(Logs::General, Logs::Login_Server, "Session ready received from client.");
}
Handle_SessionReady((const char*)app->pBuffer, app->Size());
break;
}
case OP_Login:
{
if (app->Size() < 20)
{
Log(Logs::General, Logs::Error, "Login received but it is too small, discarding.");
switch (app->GetOpcode()) {
case OP_SessionReady: {
if (server.options.IsTraceOn()) {
Log(Logs::General, Logs::Login_Server, "Session ready received from client.");
}
Handle_SessionReady((const char *) app->pBuffer, app->Size());
break;
}
case OP_Login: {
if (app->Size() < 20) {
Log(Logs::General, Logs::Error, "Login received but it is too small, discarding.");
break;
}
if (server.options.IsTraceOn())
{
Log(Logs::General, Logs::Login_Server, "Login received from client.");
}
if (server.options.IsTraceOn()) {
Log(Logs::General, Logs::Login_Server, "Login received from client.");
}
Handle_Login((const char*)app->pBuffer, app->Size());
break;
}
case OP_ServerListRequest:
{
if (app->Size() < 4) {
Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding.");
Handle_Login((const char *) app->pBuffer, app->Size());
break;
}
case OP_ServerListRequest: {
if (app->Size() < 4) {
Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding.");
break;
}
if (server.options.IsTraceOn())
{
Log(Logs::General, Logs::Login_Server, "Server list request received from client.");
}
if (server.options.IsTraceOn()) {
Log(Logs::General, Logs::Login_Server, "Server list request received from client.");
}
SendServerListPacket(*(uint32_t*)app->pBuffer);
break;
}
case OP_PlayEverquestRequest:
{
if (app->Size() < sizeof(PlayEverquestRequest_Struct))
{
Log(Logs::General, Logs::Error, "Play received but it is too small, discarding.");
SendServerListPacket(*(uint32_t *) app->pBuffer);
break;
}
case OP_PlayEverquestRequest: {
if (app->Size() < sizeof(PlayEverquestRequest_Struct)) {
Log(Logs::General, Logs::Error, "Play received but it is too small, discarding.");
break;
}
Handle_Play((const char*)app->pBuffer);
break;
}
default:
{
if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) {
char dump[64];
app->build_header_dump(dump);
Log(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump);
Handle_Play((const char *) app->pBuffer);
break;
}
default: {
if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) {
char dump[64];
app->build_header_dump(dump);
Log(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump);
}
}
}
}
delete app;
@ -126,16 +119,20 @@ bool Client::Process()
return true;
}
void Client::Handle_SessionReady(const char* data, unsigned int size)
/**
* Sends our reply to session ready packet
*
* @param data
* @param size
*/
void Client::Handle_SessionReady(const char *data, unsigned int size)
{
if (status != cs_not_sent_session_ready)
{
if (status != cs_not_sent_session_ready) {
Log(Logs::General, Logs::Error, "Session ready received again after already being received.");
return;
}
if (size < sizeof(unsigned int))
{
if (size < sizeof(unsigned int)) {
Log(Logs::General, Logs::Error, "Session ready was too small.");
return;
}
@ -145,32 +142,28 @@ void Client::Handle_SessionReady(const char* data, unsigned int size)
/**
* The packets are mostly the same but slightly different between the two versions.
*/
if (version == cv_sod)
{
if (version == cv_sod) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 17);
outapp->pBuffer[0] = 0x02;
outapp->pBuffer[0] = 0x02;
outapp->pBuffer[10] = 0x01;
outapp->pBuffer[11] = 0x65;
if (server.options.IsDumpOutPacketsOn())
{
if (server.options.IsDumpOutPacketsOn()) {
DumpPacket(outapp);
}
connection->QueuePacket(outapp);
delete outapp;
}
else
{
const char *msg = "ChatMessage";
else {
const char *msg = "ChatMessage";
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 16 + strlen(msg));
outapp->pBuffer[0] = 0x02;
outapp->pBuffer[0] = 0x02;
outapp->pBuffer[10] = 0x01;
outapp->pBuffer[11] = 0x65;
strcpy((char*)(outapp->pBuffer + 15), msg);
strcpy((char *) (outapp->pBuffer + 15), msg);
if (server.options.IsDumpOutPacketsOn())
{
if (server.options.IsDumpOutPacketsOn()) {
DumpPacket(outapp);
}
@ -179,7 +172,13 @@ void Client::Handle_SessionReady(const char* data, unsigned int size)
}
}
void Client::Handle_Login(const char* data, unsigned int size)
/**
* Verifies login and send a reply
*
* @param data
* @param size
*/
void Client::Handle_Login(const char *data, unsigned int size)
{
if (status != cs_waiting_for_login) {
Log(Logs::General, Logs::Error, "Login received after already having logged in.");
@ -187,20 +186,26 @@ void Client::Handle_Login(const char* data, unsigned int size)
}
if ((size - 12) % 8 != 0) {
Log(Logs::General, Logs::Error, "Login received packet of size: %u, this would cause a block corruption, discarding.", size);
Log(Logs::General,
Logs::Error,
"Login received packet of size: %u, this would cause a block corruption, discarding.",
size);
return;
}
if (size < sizeof(LoginLoginRequest_Struct)) {
Log(Logs::General, Logs::Error, "Login received packet of size: %u, this would cause a buffer overflow, discarding.", size);
Log(Logs::General,
Logs::Error,
"Login received packet of size: %u, this would cause a buffer overflow, discarding.",
size);
return;
}
char *login_packet_buffer = nullptr;
unsigned int db_account_id = 0;
std::string db_loginserver = "eqemu";
std::string db_account_password_hash;
unsigned int db_account_id = 0;
std::string db_loginserver = "eqemu";
std::string db_account_password_hash;
std::string outbuffer;
outbuffer.resize(size - 12);
@ -228,22 +233,29 @@ void Client::Handle_Login(const char* data, unsigned int size)
bool result = false;
if (outbuffer[0] == 0 && outbuffer[1] == 0) {
if (server.options.IsTokenLoginAllowed()) {
cred = (&outbuffer[2 + user.length()]);
result = server.db->GetLoginTokenDataFromToken(cred, connection->GetRemoteAddr(), db_account_id, db_loginserver, user);
cred = (&outbuffer[2 + user.length()]);
result = server.db->GetLoginTokenDataFromToken(
cred,
connection->GetRemoteAddr(),
db_account_id,
db_loginserver,
user
);
}
}
else {
if (server.options.IsPasswordLoginAllowed()) {
cred = (&outbuffer[1 + user.length()]);
cred = (&outbuffer[1 + user.length()]);
auto components = SplitString(user, '.');
if (components.size() == 2) {
db_loginserver = components[0];
user = components[1];
user = components[1];
}
ParseAccountString(user, user, db_loginserver);
if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) == false) {
if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) ==
false) {
status = cs_creating_account;
AttemptLoginAccountCreation(user, cred, db_loginserver);
return;
@ -263,35 +275,44 @@ void Client::Handle_Login(const char* data, unsigned int size)
}
}
void Client::Handle_Play(const char* data)
/**
* Sends a packet to the requested server to see if the client is allowed or not
*
* @param data
*/
void Client::Handle_Play(const char *data)
{
if (status != cs_logged_in)
{
if (status != cs_logged_in) {
Log(Logs::General, Logs::Error, "Client sent a play request when they were not logged in, discarding.");
return;
}
const PlayEverquestRequest_Struct *play = (const PlayEverquestRequest_Struct*)data;
unsigned int server_id_in = (unsigned int)play->ServerNumber;
unsigned int sequence_in = (unsigned int)play->Sequence;
const PlayEverquestRequest_Struct *play = (const PlayEverquestRequest_Struct *) data;
unsigned int server_id_in = (unsigned int) play->ServerNumber;
unsigned int sequence_in = (unsigned int) play->Sequence;
if (server.options.IsTraceOn())
{
Log(Logs::General, Logs::Login_Server, "Play received from client, server number %u sequence %u.", server_id_in, sequence_in);
if (server.options.IsTraceOn()) {
Log(Logs::General,
Logs::Login_Server,
"Play received from client, server number %u sequence %u.",
server_id_in,
sequence_in);
}
this->play_server_id = (unsigned int)play->ServerNumber;
this->play_server_id = (unsigned int) play->ServerNumber;
play_sequence_id = sequence_in;
play_server_id = server_id_in;
play_server_id = server_id_in;
server.server_manager->SendUserToWorldRequest(server_id_in, account_id, loginserver_name);
}
/**
* @param seq
*/
void Client::SendServerListPacket(uint32 seq)
{
EQApplicationPacket *outapp = server.server_manager->CreateServerListPacket(this, seq);
if (server.options.IsDumpOutPacketsOn())
{
if (server.options.IsDumpOutPacketsOn()) {
DumpPacket(outapp);
}
@ -301,8 +322,7 @@ void Client::SendServerListPacket(uint32 seq)
void Client::SendPlayResponse(EQApplicationPacket *outapp)
{
if (server.options.IsTraceOn())
{
if (server.options.IsTraceOn()) {
Log(Logs::General, Logs::Netcode, "Sending play response for %s.", GetAccountName().c_str());
// server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size);
}
@ -313,23 +333,26 @@ void Client::GenerateKey()
{
key.clear();
int count = 0;
while (count < 10)
{
while (count < 10) {
static const char key_selection[] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9'
};
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9'
};
key.append((const char*)&key_selection[random.Int(0, 35)], 1);
key.append((const char *) &key_selection[random.Int(0, 35)], 1);
count++;
}
}
void Client::AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver)
void Client::AttemptLoginAccountCreation(
const std::string &user,
const std::string &pass,
const std::string &loginserver
)
{
if (loginserver == "eqemu") {
if (!server.options.CanAutoLinkAccounts()) {
@ -341,7 +364,7 @@ void Client::AttemptLoginAccountCreation(const std::string &user, const std::str
DoFailedLogin();
return;
}
auto addr_components = SplitString(server.options.GetEQEmuLoginServerAddress(), ':');
if (addr_components.size() != 2) {
DoFailedLogin();
@ -350,22 +373,42 @@ void Client::AttemptLoginAccountCreation(const std::string &user, const std::str
stored_user = user;
stored_pass = pass;
auto address = addr_components[0];
auto port = std::stoi(addr_components[1]);
EQ::Net::DNSLookup(address, port, false, [=](const std::string &addr) {
if (addr.empty()) {
DoFailedLogin();
return;
auto port = std::stoi(addr_components[1]);
EQ::Net::DNSLookup(
address, port, false, [=](const std::string &addr) {
if (addr.empty()) {
DoFailedLogin();
return;
}
login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
login_connection_manager->OnNewConnection(
std::bind(
&Client::LoginOnNewConnection,
this,
std::placeholders::_1
));
login_connection_manager->OnConnectionStateChange(
std::bind(
&Client::LoginOnStatusChange,
this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3
));
login_connection_manager->OnPacketRecv(
std::bind(
&Client::LoginOnPacketRecv,
this,
std::placeholders::_1,
std::placeholders::_2
));
login_connection_manager->Connect(addr, port);
}
login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
login_connection_manager->OnNewConnection(std::bind(&Client::LoginOnNewConnection, this, std::placeholders::_1));
login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
login_connection_manager->OnPacketRecv(std::bind(&Client::LoginOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
login_connection_manager->Connect(addr, port);
});
);
}
else {
if (!server.options.CanAutoCreateAccounts()) {
@ -382,8 +425,8 @@ void Client::DoFailedLogin()
stored_user.clear();
stored_pass.clear();
EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
LoginLoginFailed_Struct* llas = (LoginLoginFailed_Struct *)outapp.pBuffer;
EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
LoginLoginFailed_Struct *llas = (LoginLoginFailed_Struct *) outapp.pBuffer;
llas->unknown1 = llrs.unknown1;
llas->unknown2 = llrs.unknown2;
llas->unknown3 = llrs.unknown3;
@ -399,7 +442,21 @@ void Client::DoFailedLogin()
status = cs_failed_to_login;
}
bool Client::VerifyLoginHash(const std::string &user, const std::string &loginserver, const std::string &cred, const std::string &hash)
/**
* Verifies a login hash, will also attempt to update a login hash if needed
*
* @param user
* @param loginserver
* @param cred
* @param hash
* @return
*/
bool Client::VerifyLoginHash(
const std::string &user,
const std::string &loginserver,
const std::string &cred,
const std::string &hash
)
{
auto mode = server.options.GetEncryptionMode();
if (eqcrypt_verify_hash(user, cred, hash, mode)) {
@ -443,6 +500,11 @@ bool Client::VerifyLoginHash(const std::string &user, const std::string &loginse
return false;
}
/**
* @param user
* @param db_account_id
* @param db_loginserver
*/
void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver)
{
stored_user.clear();
@ -456,43 +518,43 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const
server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in)));
GenerateKey();
account_id = db_account_id;
account_name = user;
account_id = db_account_id;
account_name = user;
loginserver_name = db_loginserver;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80);
LoginAccepted_Struct* login_accepted = (LoginAccepted_Struct *)outapp->pBuffer;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80);
LoginAccepted_Struct *login_accepted = (LoginAccepted_Struct *) outapp->pBuffer;
login_accepted->unknown1 = llrs.unknown1;
login_accepted->unknown2 = llrs.unknown2;
login_accepted->unknown3 = llrs.unknown3;
login_accepted->unknown4 = llrs.unknown4;
login_accepted->unknown5 = llrs.unknown5;
LoginFailedAttempts_Struct * login_failed_attempts = new LoginFailedAttempts_Struct;
LoginFailedAttempts_Struct *login_failed_attempts = new LoginFailedAttempts_Struct;
memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct));
login_failed_attempts->failed_attempts = 0;
login_failed_attempts->message = 0x01;
login_failed_attempts->lsid = db_account_id;
login_failed_attempts->unknown3[3] = 0x03;
login_failed_attempts->unknown4[3] = 0x02;
login_failed_attempts->unknown5[0] = 0xe7;
login_failed_attempts->unknown5[1] = 0x03;
login_failed_attempts->unknown6[0] = 0xff;
login_failed_attempts->unknown6[1] = 0xff;
login_failed_attempts->unknown6[2] = 0xff;
login_failed_attempts->unknown6[3] = 0xff;
login_failed_attempts->unknown7[0] = 0xa0;
login_failed_attempts->unknown7[1] = 0x05;
login_failed_attempts->unknown8[3] = 0x02;
login_failed_attempts->unknown9[0] = 0xff;
login_failed_attempts->unknown9[1] = 0x03;
login_failed_attempts->message = 0x01;
login_failed_attempts->lsid = db_account_id;
login_failed_attempts->unknown3[3] = 0x03;
login_failed_attempts->unknown4[3] = 0x02;
login_failed_attempts->unknown5[0] = 0xe7;
login_failed_attempts->unknown5[1] = 0x03;
login_failed_attempts->unknown6[0] = 0xff;
login_failed_attempts->unknown6[1] = 0xff;
login_failed_attempts->unknown6[2] = 0xff;
login_failed_attempts->unknown6[3] = 0xff;
login_failed_attempts->unknown7[0] = 0xa0;
login_failed_attempts->unknown7[1] = 0x05;
login_failed_attempts->unknown8[3] = 0x02;
login_failed_attempts->unknown9[0] = 0xff;
login_failed_attempts->unknown9[1] = 0x03;
login_failed_attempts->unknown11[0] = 0x63;
login_failed_attempts->unknown12[0] = 0x01;
memcpy(login_failed_attempts->key, key.c_str(), key.size());
char encrypted_buffer[80] = { 0 };
auto rc = eqcrypt_block((const char*)login_failed_attempts, 75, encrypted_buffer, 1);
char encrypted_buffer[80] = {0};
auto rc = eqcrypt_block((const char *) login_failed_attempts, 75, encrypted_buffer, 1);
if (rc == nullptr) {
LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block");
}
@ -509,13 +571,17 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const
status = cs_logged_in;
}
/**
* @param user
* @param pass
*/
void Client::CreateLocalAccount(const std::string &user, const std::string &pass)
{
auto mode = server.options.GetEncryptionMode();
auto hash = eqcrypt_hash(user, pass, mode);
unsigned int db_id = 0;
std::string db_login = server.options.GetDefaultLoginServerName();
unsigned int db_id = 0;
std::string db_login = server.options.GetDefaultLoginServerName();
if (!server.db->CreateLoginData(user, hash, db_login, db_id)) {
DoFailedLogin();
}
@ -524,6 +590,11 @@ void Client::CreateLocalAccount(const std::string &user, const std::string &pass
}
}
/**
* @param user
* @param pass
* @param id
*/
void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id)
{
auto mode = server.options.GetEncryptionMode();
@ -537,12 +608,24 @@ void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass
}
}
/**
* @param connection
*/
void Client::LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
{
login_connection = connection;
}
void Client::LoginOnStatusChange(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
/**
* @param conn
* @param from
* @param to
*/
void Client::LoginOnStatusChange(
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
EQ::Net::DbProtocolStatus from,
EQ::Net::DbProtocolStatus to
)
{
if (to == EQ::Net::StatusConnected) {
LoginSendSessionReady();
@ -553,20 +636,33 @@ void Client::LoginOnStatusChange(std::shared_ptr<EQ::Net::DaybreakConnection> co
}
}
void Client::LoginOnStatusChangeIgnored(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
/**
* @param conn
* @param from
* @param to
*/
void Client::LoginOnStatusChangeIgnored(
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
EQ::Net::DbProtocolStatus from,
EQ::Net::DbProtocolStatus to
)
{
}
void Client::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
/**
* @param conn
* @param p
*/
void Client::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
{
auto opcode = p.GetUInt16(0);
switch (opcode) {
case 0x0017: //OP_ChatMessage
LoginSendLogin();
break;
case 0x0018:
LoginProcessLoginResponse(p);
break;
case 0x0017: //OP_ChatMessage
LoginSendLogin();
break;
case 0x0018:
LoginProcessLoginResponse(p);
break;
}
}
@ -581,7 +677,7 @@ void Client::LoginSendSessionReady()
void Client::LoginSendLogin()
{
size_t buffer_len = stored_user.length() + stored_pass.length() + 2;
size_t buffer_len = stored_user.length() + stored_pass.length() + 2;
std::unique_ptr<char[]> buffer(new char[buffer_len]);
strcpy(&buffer[0], stored_user.c_str());
@ -598,26 +694,33 @@ void Client::LoginSendLogin()
p.PutUInt16(0, 2); //OP_Login
p.PutUInt32(2, 3);
eqcrypt_block(&buffer[0], buffer_len, (char*)p.Data() + 12, true);
eqcrypt_block(&buffer[0], buffer_len, (char *) p.Data() + 12, true);
login_connection->QueuePacket(p);
}
void Client::LoginProcessLoginResponse(const EQ::Net::Packet & p)
void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p)
{
auto encrypt_size = p.Length() - 12;
auto encrypt_size = p.Length() - 12;
if (encrypt_size % 8 > 0) {
encrypt_size = (encrypt_size / 8) * 8;
}
std::unique_ptr<char[]> decrypted(new char[encrypt_size]);
eqcrypt_block((char*)p.Data() + 12, encrypt_size, &decrypted[0], false);
eqcrypt_block((char *) p.Data() + 12, encrypt_size, &decrypted[0], false);
EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size);
auto response_error = sp.GetUInt16(1);
auto response_error = sp.GetUInt16(1);
login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChangeIgnored, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
login_connection_manager->OnConnectionStateChange(
std::bind(
&Client::LoginOnStatusChangeIgnored,
this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3
));
if (response_error > 101) {
DoFailedLogin();

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_CLIENT_H
#define EQEMU_CLIENT_H
@ -24,19 +27,15 @@
#include "../common/eq_stream_intf.h"
#include "../common/net/dns.h"
#include "../common/net/daybreak_connection.h"
#include "login_structures.h"
#include <memory>
enum LSClientVersion
{
enum LSClientVersion {
cv_titanium,
cv_sod
};
enum LSClientStatus
{
enum LSClientStatus {
cs_not_sent_session_ready,
cs_waiting_for_login,
cs_creating_account,
@ -45,144 +44,186 @@ enum LSClientStatus
};
/**
* Client class, controls a single client and it's
* connection to the login server.
*/
class Client
{
* Client class, controls a single client and it's connection to the login server
*/
class Client {
public:
/**
* Constructor, sets our connection to c and version to v
*/
* Constructor, sets our connection to c and version to v
*
* @param c
* @param v
*/
Client(std::shared_ptr<EQStreamInterface> c, LSClientVersion v);
/**
* Destructor.
*/
~Client() { }
* Destructor
*/
~Client() {}
/**
* Processes the client's connection and does various actions.
*/
* Processes the client's connection and does various actions
*
* @return
*/
bool Process();
/**
* Sends our reply to session ready packet.
*/
void Handle_SessionReady(const char* data, unsigned int size);
* Sends our reply to session ready packet
*
* @param data
* @param size
*/
void Handle_SessionReady(const char *data, unsigned int size);
/**
* Verifies login and send a reply.
*/
void Handle_Login(const char* data, unsigned int size);
* Verifies login and send a reply
*
* @param data
* @param size
*/
void Handle_Login(const char *data, unsigned int size);
/**
* Sends a packet to the requested server to see if the client is allowed or not.
*/
void Handle_Play(const char* data);
* Sends a packet to the requested server to see if the client is allowed or not
*
* @param data
*/
void Handle_Play(const char *data);
/**
* Sends a server list packet to the client.
*/
* Sends a server list packet to the client
*
* @param seq
*/
void SendServerListPacket(uint32 seq);
/**
* Sends the input packet to the client and clears our play response states.
*/
* Sends the input packet to the client and clears our play response states
*
* @param outapp
*/
void SendPlayResponse(EQApplicationPacket *outapp);
/**
* Generates a random login key for the client during login.
*/
* Generates a random login key for the client during login
*/
void GenerateKey();
/**
* Gets the account id of this client.
*/
* Gets the account id of this client
*
* @return
*/
unsigned int GetAccountID() const { return account_id; }
/**
* Gets the loginserver name of this client.
*/
* Gets the loginserver name of this client
*
* @return
*/
std::string GetLoginServerName() const { return loginserver_name; }
/**
* Gets the account name of this client.
*/
* Gets the account name of this client
*
* @return
*/
std::string GetAccountName() const { return account_name; }
/**
* Gets the key generated at login for this client.
*/
* Gets the key generated at login for this client
*
* @return
*/
std::string GetKey() const { return key; }
/**
* Gets the server selected to be played on for this client.
*/
* Gets the server selected to be played on for this client
*
* @return
*/
unsigned int GetPlayServerID() const { return play_server_id; }
/**
* Gets the play sequence state for this client.
*/
* Gets the play sequence state for this client
*
* @return
*/
unsigned int GetPlaySequence() const { return play_sequence_id; }
/**
* Gets the connection for this client.
*/
* Gets the connection for this client
*
* @return
*/
std::shared_ptr<EQStreamInterface> GetConnection() { return connection; }
/**
* Attempts to create a login account
*/
* Attempts to create a login account
*
* @param user
* @param pass
* @param loginserver
*/
void AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver);
/**
* Does a failed login
*/
* Does a failed login
*/
void DoFailedLogin();
/**
* Verifies a login hash, will also attempt to update a login hash if needed.
*/
bool VerifyLoginHash(const std::string &user, const std::string &loginserver, const std::string &cred, const std::string &hash);
* Verifies a login hash, will also attempt to update a login hash if needed
*
* @param user
* @param loginserver
* @param cred
* @param hash
* @return
*/
bool VerifyLoginHash(
const std::string &user,
const std::string &loginserver,
const std::string &cred,
const std::string &hash
);
/**
* Does a successful login
*/
void DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver);
/**
* Creates a local account
*/
void CreateLocalAccount(const std::string &user, const std::string &pass);
/**
* Creates an eqemu account
*/
void CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id);
private:
EQEmu::Random random;
EQEmu::Random random;
std::shared_ptr<EQStreamInterface> connection;
LSClientVersion version;
LSClientStatus status;
LSClientVersion version;
LSClientStatus status;
std::string account_name;
std::string account_name;
unsigned int account_id;
std::string loginserver_name;
std::string loginserver_name;
unsigned int play_server_id;
unsigned int play_sequence_id;
std::string key;
std::string key;
std::unique_ptr<EQ::Net::DaybreakConnectionManager> login_connection_manager;
std::shared_ptr<EQ::Net::DaybreakConnection> login_connection;
LoginLoginRequest_Struct llrs;
std::shared_ptr<EQ::Net::DaybreakConnection> login_connection;
LoginLoginRequest_Struct llrs;
std::string stored_user;
std::string stored_pass;
void LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
void LoginOnStatusChange(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
void LoginOnStatusChangeIgnored(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
void LoginOnStatusChange(
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
EQ::Net::DbProtocolStatus from,
EQ::Net::DbProtocolStatus to
);
void LoginOnStatusChangeIgnored(
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
EQ::Net::DbProtocolStatus from,
EQ::Net::DbProtocolStatus to
);
void LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
void LoginSendSessionReady();
void LoginSendLogin();

View File

@ -1,87 +1,101 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "client_manager.h"
#include "login_server.h"
extern LoginServer server;
extern bool run_server;
extern bool run_server;
#include "../common/eqemu_logsys.h"
#include "../common/eqemu_logsys_fmt.h"
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);
titanium_stream = new EQ::Net::EQStreamManager(titanium_opts);
titanium_ops = new RegularOpcodeManager;
if (!titanium_ops->LoadOpcodes(server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str()))
{
titanium_ops = new RegularOpcodeManager;
if (!titanium_ops->LoadOpcodes(
server.config.GetVariableString(
"Titanium",
"opcodes",
"login_opcodes.conf"
).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());
run_server = false;
}
titanium_stream->OnNewConnection([this](std::shared_ptr<EQ::Net::EQStream> stream) {
LogF(Logs::General, Logs::Login_Server, "New Titanium client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort());
stream->SetOpcodeManager(&titanium_ops);
Client *c = new Client(stream, cv_titanium);
clients.push_back(c);
});
titanium_stream->OnNewConnection(
[this](std::shared_ptr<EQ::Net::EQStream> stream) {
LogF(Logs::General,
Logs::Login_Server,
"New Titanium client connection from {0}:{1}",
stream->GetRemoteIP(),
stream->GetRemotePort());
stream->SetOpcodeManager(&titanium_ops);
Client *c = new Client(stream, cv_titanium);
clients.push_back(c);
}
);
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);
sod_stream = new EQ::Net::EQStreamManager(sod_opts);
sod_ops = new RegularOpcodeManager;
if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str()))
{
sod_ops = new RegularOpcodeManager;
if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) {
Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for SoD file %s.",
server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str());
run_server = false;
}
sod_stream->OnNewConnection([this](std::shared_ptr<EQ::Net::EQStream> stream) {
LogF(Logs::General, Logs::Login_Server, "New SoD client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort());
stream->SetOpcodeManager(&sod_ops);
Client *c = new Client(stream, cv_sod);
clients.push_back(c);
});
sod_stream->OnNewConnection(
[this](std::shared_ptr<EQ::Net::EQStream> stream) {
LogF(Logs::General,
Logs::Login_Server,
"New SoD client connection from {0}:{1}",
stream->GetRemoteIP(),
stream->GetRemotePort());
stream->SetOpcodeManager(&sod_ops);
Client *c = new Client(stream, cv_sod);
clients.push_back(c);
}
);
}
ClientManager::~ClientManager()
{
if (titanium_stream)
{
if (titanium_stream) {
delete titanium_stream;
}
if (titanium_ops)
{
if (titanium_ops) {
delete titanium_ops;
}
if (sod_stream)
{
if (sod_stream) {
delete sod_stream;
}
if (sod_ops)
{
if (sod_ops) {
delete sod_ops;
}
}
@ -91,16 +105,13 @@ void ClientManager::Process()
ProcessDisconnect();
auto iter = clients.begin();
while (iter != clients.end())
{
if ((*iter)->Process() == false)
{
while (iter != clients.end()) {
if ((*iter)->Process() == false) {
Log(Logs::General, Logs::Debug, "Client had a fatal error and had to be removed from the login.");
delete (*iter);
iter = clients.erase(iter);
}
else
{
else {
++iter;
}
}
@ -109,17 +120,14 @@ void ClientManager::Process()
void ClientManager::ProcessDisconnect()
{
auto iter = clients.begin();
while (iter != clients.end())
{
while (iter != clients.end()) {
std::shared_ptr<EQStreamInterface> c = (*iter)->GetConnection();
if (c->CheckState(CLOSED))
{
if (c->CheckState(CLOSED)) {
Log(Logs::General, Logs::Login_Server, "Client disconnected from the server, removing client.");
delete (*iter);
iter = clients.erase(iter);
}
else
{
else {
++iter;
}
}
@ -128,16 +136,15 @@ void ClientManager::ProcessDisconnect()
void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver)
{
auto iter = clients.begin();
while (iter != clients.end())
{
if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0)
{
Log(Logs::General, Logs::Login_Server, "Client attempting to log in and existing client already logged in, removing existing client.");
while (iter != clients.end()) {
if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) {
Log(Logs::General,
Logs::Login_Server,
"Client attempting to log in and existing client already logged in, removing existing client.");
delete (*iter);
iter = clients.erase(iter);
}
else
{
else {
++iter;
}
}
@ -146,10 +153,8 @@ void ClientManager::RemoveExistingClient(unsigned int account_id, const std::str
Client *ClientManager::GetClient(unsigned int account_id, const std::string &loginserver)
{
auto iter = clients.begin();
while (iter != clients.end())
{
if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0)
{
while (iter != clients.end()) {
if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) {
return (*iter);
}
++iter;

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_CLIENTMANAGER_H
#define EQEMU_CLIENTMANAGER_H
@ -27,44 +30,50 @@
/**
* Client manager class, holds all the client objects and does basic processing.
*/
class ClientManager
{
class ClientManager {
public:
/**
* Constructor, sets up the stream factories and opcode managers.
*/
* Constructor: sets up the stream factories and opcode managers
*/
ClientManager();
/**
* Destructor, shuts down the streams and opcode managers.
*/
* Destructor: shuts down the streams and opcode managers
*/
~ClientManager();
/**
* Processes every client in the internal list, removes them if necessary.
*/
* Processes every client in the internal list, removes them if necessary.
*/
void Process();
/**
* Removes a client with a certain account id.
*/
* Removes a client with a certain account id
*
* @param account_id
* @param loginserver
*/
void RemoveExistingClient(unsigned int account_id, const std::string &loginserver);
/**
* Gets a client (if exists) by their account id.
*/
* Gets a client (if exists) by their account id
*
* @param account_id
* @param loginserver
* @return
*/
Client *GetClient(unsigned int account_id, const std::string &loginserver);
private:
/**
* Processes disconnected clients, removes them if necessary.
*/
* Processes disconnected clients, removes them if necessary
*/
void ProcessDisconnect();
std::list<Client*> clients;
OpcodeManager *titanium_ops;
std::list<Client *> clients;
OpcodeManager *titanium_ops;
EQ::Net::EQStreamManager *titanium_stream;
OpcodeManager *sod_ops;
OpcodeManager *sod_ops;
EQ::Net::EQStreamManager *sod_stream;
};

View File

@ -1,37 +1,41 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/global_define.h"
#include "../common/eqemu_logsys.h"
#include "config.h"
/**
* Retrieves the variable we want from our title or theme
* First gets the map from the title
* Then gets the argument from the map we got from title
*/
* Retrieves the variable we want from our title or theme
* First gets the map from the title, then gets the argument from the map we got from title
*
* @param title
* @param parameter
* @return
*/
std::string Config::GetVariable(std::string title, std::string parameter)
{
std::map<std::string, std::map<std::string, std::string> >::iterator iter = vars.find(title);
if(iter != vars.end())
{
if (iter != vars.end()) {
std::map<std::string, std::string>::iterator arg_iter = iter->second.find(parameter);
if(arg_iter != iter->second.end())
{
if (arg_iter != iter->second.end()) {
return arg_iter->second;
}
}
@ -40,50 +44,44 @@ std::string Config::GetVariable(std::string title, std::string parameter)
}
/**
* Opens a file and passes it to the tokenizer
* Then it parses the tokens returned and puts them into titles and variables.
*/
* Opens a file and passes it to the tokenizer
* Then it parses the tokens returned and puts them into titles and variables
*
* @param 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.");
return;
}
vars.clear();
FILE *input = fopen(file_name, "r");
if(input)
{
if (input) {
std::list<std::string> tokens;
Tokenize(input, tokens);
char mode = 0;
std::string title, param, arg;
char mode = 0;
std::string title, param, arg;
std::list<std::string>::iterator iter = tokens.begin();
while(iter != tokens.end())
{
if((*iter).compare("[") == 0)
{
while (iter != tokens.end()) {
if ((*iter).compare("[") == 0) {
title.clear();
bool first = true;
++iter;
if(iter == tokens.end())
{
if (iter == tokens.end()) {
Log(Logs::General, Logs::Error, "Config::Parse(), EOF before title done parsing.");
fclose(input);
vars.clear();
return;
}
while((*iter).compare("]") != 0 && iter != tokens.end())
{
if(!first)
{
while ((*iter).compare("]") != 0 && iter != tokens.end()) {
if (!first) {
title += " ";
}
else
{
else {
first = false;
}
@ -93,65 +91,58 @@ void Config::Parse(const char *file_name)
++iter;
}
if(mode == 0)
{
if (mode == 0) {
param = (*iter);
mode++;
}
else if(mode == 1)
{
else if (mode == 1) {
mode++;
if((*iter).compare("=") != 0)
{
if ((*iter).compare("=") != 0) {
Log(Logs::General, Logs::Error, "Config::Parse(), invalid parse token where = should be.");
fclose(input);
vars.clear();
return;
}
}
else
{
arg = (*iter);
else {
arg = (*iter);
mode = 0;
std::map<std::string, std::map<std::string, std::string> >::iterator map_iter = vars.find(title);
if(map_iter != vars.end())
{
if (map_iter != vars.end()) {
map_iter->second[param] = arg;
vars[title] = map_iter->second;
vars[title] = map_iter->second;
}
else
{
else {
std::map<std::string, std::string> var_map;
var_map[param] = arg;
vars[title] = var_map;
vars[title] = var_map;
}
}
++iter;
}
fclose(input);
}
else
{
else {
Log(Logs::General, Logs::Error, "Config::Parse(), file was unable to be opened for parsing.");
}
}
/**
* Pretty basic lexical analyzer
* Breaks up the input character stream into tokens and puts them into the list provided.
* Ignores # as a line comment
*/
* Pretty basic lexical analyzer
* Breaks up the input character stream into tokens and puts them into the list provided
* Ignores # as a line comment
*
* @param input
* @param tokens
*/
void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
{
auto c = fgetc(input);
auto c = fgetc(input);
std::string lexeme;
while(c != EOF)
{
if(isspace(c))
{
if(lexeme.size() > 0)
{
while (c != EOF) {
if (isspace(c)) {
if (lexeme.size() > 0) {
tokens.push_back(lexeme);
lexeme.clear();
}
@ -159,35 +150,28 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
continue;
}
if(isalnum(c))
{
if (isalnum(c)) {
lexeme += c;
c = fgetc(input);
continue;
}
switch(c)
{
case '#':
{
if(lexeme.size() > 0)
{
switch (c) {
case '#': {
if (lexeme.size() > 0) {
tokens.push_back(lexeme);
lexeme.clear();
}
while(c != '\n' && c != EOF)
{
while (c != '\n' && c != EOF) {
c = fgetc(input);
}
break;
}
case '[':
case ']':
case '=':
{
if(lexeme.size() > 0)
{
case '[':
case ']':
case '=': {
if (lexeme.size() > 0) {
tokens.push_back(lexeme);
lexeme.clear();
}
@ -197,8 +181,7 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
lexeme.clear();
break;
}
default:
{
default: {
lexeme += c;
}
}
@ -206,8 +189,7 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
c = fgetc(input);
}
if(lexeme.size() > 0)
{
if (lexeme.size() > 0) {
tokens.push_back(lexeme);
}
}

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_CONFIG_H
#define EQEMU_CONFIG_H

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_DATABASE_H
#define EQEMU_DATABASE_H
@ -25,58 +28,110 @@
/**
* Base database class, intended to be extended.
*/
class Database
{
class Database {
public:
Database() : user(""), pass(""), host(""), port(""), name("") { }
virtual ~Database() { }
Database() : user(""), pass(""), host(""), port(""), name("") {}
virtual ~Database() {}
/**
* Returns true if the database successfully connected.
*/
virtual bool IsConnected() { return false; }
/**
* Retrieves the login data (password hash and account id) from the account name provided
* Needed for client login procedure.
* Returns true if the record was found, false otherwise.
*/
virtual bool GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id) { return false; }
* Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure
*
* @param name
* @param loginserver
* @param password
* @param id
* @return
*/
virtual bool GetLoginDataFromAccountInfo(
const std::string &name,
const std::string &loginserver,
std::string &password,
unsigned int &id
) { return false; }
virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) { return false; }
virtual bool GetLoginTokenDataFromToken(
const std::string &token,
const std::string &ip,
unsigned int &db_account_id,
std::string &db_loginserver,
std::string &user
) { return false; }
virtual bool CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id) { return false; }
virtual bool CreateLoginData(
const std::string &name,
const std::string &password,
const std::string &loginserver,
unsigned int &id
) { return false; }
virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id) { return false; }
virtual bool CreateLoginDataWithID(
const std::string &name,
const std::string &password,
const std::string &loginserver,
unsigned int id
) { return false; }
virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) { }
virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) {}
/**
* 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(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) { return false; }
* 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
*
* @param long_name
* @param short_name
* @param id
* @param desc
* @param list_id
* @param trusted
* @param list_desc
* @param account
* @param password
* @return
*/
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
) { return false; }
virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) {}
/**
* Updates the ip address of the client with account id = id
*/
virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) { }
* Updates or creates the login server account with info from world server
*
* @param id
* @param name
* @param password
* @param email
*/
virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) {}
/**
* Updates or creates the login server account with info from world server
*/
virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) { }
* Updates the ip address of the world with account id = id
*
* @param id
* @param long_name
* @param ip_address
*/
virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) {}
/**
* Updates the ip address of the world with account id = id
*/
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
*/
* Creates new world registration for unregistered servers and returns new id
*
* @param long_name
* @param short_name
* @param id
* @return
*/
virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { return false; }
protected:
std::string user, pass, host, port, name;

View File

@ -18,7 +18,6 @@
*
*/
#include "../common/global_define.h"
#include "database.h"

View File

@ -1,3 +1,23 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <openssl/des.h>
#include <openssl/sha.h>
#include <openssl/md5.h>

View File

@ -1,3 +1,23 @@
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#pragma once
#include <string>

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMUCAPI__H
#define EQEMUCAPI__H

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_LOGINSERVER_H
#define EQEMU_LOGINSERVER_H
@ -27,9 +30,8 @@
#include "client_manager.h"
/**
* Login server struct, contains every variable for the server that needs to exist
* outside the scope of main().
*/
* Login server struct, contains every variable for the server that needs to exist outside the scope of main()
*/
struct LoginServer
{
public:

View File

@ -1,32 +1,35 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_LOGINSTRUCTURES_H
#define EQEMU_LOGINSTRUCTURES_H
#pragma pack(1)
struct LoginChatMessage_Struct {
short Unknown0;
short Unknown0;
uint32 Unknown1;
uint32 Unknown2;
uint32 Unknown3;
uint8 Unknown4;
char ChatMessage[1];
uint8 Unknown4;
char ChatMessage[1];
};
struct LoginLoginRequest_Struct {
@ -35,7 +38,7 @@ struct LoginLoginRequest_Struct {
short unknown3;
short unknown4;
short unknown5;
char unknown6[16];
char unknown6[16];
};
struct LoginAccepted_Struct {
@ -44,28 +47,27 @@ struct LoginAccepted_Struct {
short unknown3;
short unknown4;
short unknown5;
char encrypt[80];
char encrypt[80];
};
struct LoginFailedAttempts_Struct
{
char message; //0x01
char unknown2[7]; //0x00
struct LoginFailedAttempts_Struct {
char message; //0x01
char unknown2[7]; //0x00
uint32 lsid;
char key[11]; //10 char + null term;
char key[11]; //10 char + null term;
uint32 failed_attempts;
char unknown3[4]; //0x00, 0x00, 0x00, 0x03
char unknown4[4]; //0x00, 0x00, 0x00, 0x02
char unknown5[4]; //0xe7, 0x03, 0x00, 0x00
char unknown6[4]; //0xff, 0xff, 0xff, 0xff
char unknown7[4]; //0xa0, 0x05, 0x00, 0x00
char unknown8[4]; //0x00, 0x00, 0x00, 0x02
char unknown9[4]; //0xff, 0x03, 0x00, 0x00
char unknown10[4]; //0x00, 0x00, 0x00, 0x00
char unknown11[4]; //0x63, 0x00, 0x00, 0x00
char unknown12[4]; //0x01, 0x00, 0x00, 0x00
char unknown13[4]; //0x00, 0x00, 0x00, 0x00
char unknown14[4]; //0x00, 0x00, 0x00, 0x00
char unknown3[4]; //0x00, 0x00, 0x00, 0x03
char unknown4[4]; //0x00, 0x00, 0x00, 0x02
char unknown5[4]; //0xe7, 0x03, 0x00, 0x00
char unknown6[4]; //0xff, 0xff, 0xff, 0xff
char unknown7[4]; //0xa0, 0x05, 0x00, 0x00
char unknown8[4]; //0x00, 0x00, 0x00, 0x02
char unknown9[4]; //0xff, 0x03, 0x00, 0x00
char unknown10[4]; //0x00, 0x00, 0x00, 0x00
char unknown11[4]; //0x63, 0x00, 0x00, 0x00
char unknown12[4]; //0x01, 0x00, 0x00, 0x00
char unknown13[4]; //0x00, 0x00, 0x00, 0x00
char unknown14[4]; //0x00, 0x00, 0x00, 0x00
};
struct LoginLoginFailed_Struct {
@ -74,7 +76,7 @@ struct LoginLoginFailed_Struct {
short unknown3;
short unknown4;
short unknown5;
char unknown6[74];
char unknown6[74];
};
struct ServerListHeader_Struct {
@ -86,8 +88,7 @@ struct ServerListHeader_Struct {
uint32 NumberOfServers;
};
struct PlayEverquestRequest_Struct
{
struct PlayEverquestRequest_Struct {
uint16 Sequence;
uint32 Unknown1;
uint32 Unknown2;
@ -95,18 +96,19 @@ struct PlayEverquestRequest_Struct
};
struct PlayEverquestResponse_Struct {
uint8 Sequence;
uint8 Unknown1[9];
uint8 Allowed;
uint8 Sequence;
uint8 Unknown1[9];
uint8 Allowed;
uint16 Message;
uint8 Unknown2[3];
uint8 Unknown2[3];
uint32 ServerNumber;
};
static const unsigned char FailedLoginResponseData[] = {
0xf6, 0x85, 0x9c, 0x23, 0x57, 0x7e, 0x3e, 0x55, 0xb3, 0x4c, 0xf8, 0xc8, 0xcb, 0x77, 0xd5, 0x16,
0x09, 0x7a, 0x63, 0xdc, 0x57, 0x7e, 0x3e, 0x55, 0xb3, 0x4c, 0xf8, 0xc8, 0xcb, 0x77, 0xd5, 0x16,
0x09, 0x7a, 0x63, 0xdc, 0x57, 0x7e, 0x3e, 0x55, 0xb3 };
0x09, 0x7a, 0x63, 0xdc, 0x57, 0x7e, 0x3e, 0x55, 0xb3
};
#pragma pack()

View File

@ -80,11 +80,13 @@ int main()
)
);
#ifdef ENABLE_SECURITY
server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 13));
#else
server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 6));
#endif
server.options.AllowUnregistered(server.config.GetVariableBool("security", "unregistered_allowed", true));
server.options.AllowTokenLogin(server.config.GetVariableBool("security", "allow_token_login", false));
server.options.AllowPasswordLogin(server.config.GetVariableBool("security", "allow_password_login", true));
@ -93,44 +95,47 @@ int main()
"security",
"update_insecure_passwords",
true
));
)
);
server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts"));
server.options.WorldRegistrationTable(
server.config.GetVariableString(
"schema",
"world_registration_table",
"tblWorldServerRegistration"
));
)
);
server.options.WorldAdminRegistrationTable(
server.config.GetVariableString(
"schema",
"world_admin_registration_table",
"tblServerAdminRegistration"
));
)
);
server.options.WorldServerTypeTable(
server.config.GetVariableString(
"schema",
"world_server_type_table",
"tblServerListType"
));
)
);
/**
* mysql connect
*/
if (server.config.GetVariableString("database", "subsystem", "MySQL").compare("MySQL") == 0) {
Log(Logs::General, Logs::Login_Server, "MySQL Database Init.");
server.db = (Database *) new DatabaseMySQL(
server.config.GetVariableString("database", "user", "root"),
server.config.GetVariableString("database", "password", ""),
server.config.GetVariableString("database", "host", "localhost"),
server.config.GetVariableString("database", "port", "3306"),
server.config.GetVariableString("database", "db", "peq")
);
}
Log(Logs::General, Logs::Login_Server, "MySQL Database Init.");
server.db = (Database *) new DatabaseMySQL(
server.config.GetVariableString("database", "user", "root"),
server.config.GetVariableString("database", "password", ""),
server.config.GetVariableString("database", "host", "localhost"),
server.config.GetVariableString("database", "port", "3306"),
server.config.GetVariableString("database", "db", "peq")
);
/**
* 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) {
Log(Logs::General, Logs::Error, "Database Initialization Failure.");
@ -143,7 +148,7 @@ int main()
*/
Log(Logs::General, Logs::Login_Server, "Server Manager Initialize.");
server.server_manager = new ServerManager();
if (!server.server_manager)
if (!server.server_manager) {
Log(Logs::General, Logs::Error, "Server Manager Failed to Start.");
Log(Logs::General, Logs::Login_Server, "Database System Shutdown.");
delete server.db;

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_OPTIONS_H
#define EQEMU_OPTIONS_H
@ -22,12 +25,12 @@
* Collects options on one object, because having a bunch of global variables floating around is
* really ugly and just a little dangerous.
*/
class Options
{
class Options {
public:
/**
* Constructor, sets the default options.
*/
* Constructor: Default options
*/
Options() :
allow_unregistered(true),
trace(false),
@ -38,7 +41,7 @@ public:
reject_duplicate_servers(false),
allow_password_login(true),
allow_token_login(false),
auto_create_accounts(false) { }
auto_create_accounts(false) {}
/**
* Sets allow_unregistered.
@ -182,18 +185,18 @@ public:
inline bool IsUpdatingInsecurePasswords() const { return update_insecure_passwords; }
private:
bool allow_unregistered;
bool trace;
bool world_trace;
bool dump_in_packets;
bool dump_out_packets;
bool reject_duplicate_servers;
bool allow_token_login;
bool allow_password_login;
bool auto_create_accounts;
bool auto_link_accounts;
bool update_insecure_passwords;
int encryption_mode;
bool allow_unregistered;
bool trace;
bool world_trace;
bool dump_in_packets;
bool dump_out_packets;
bool reject_duplicate_servers;
bool allow_token_login;
bool allow_password_login;
bool auto_create_accounts;
bool auto_link_accounts;
bool update_insecure_passwords;
int encryption_mode;
std::string local_network;
std::string account_table;
std::string world_registration_table;

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "server_manager.h"
#include "login_server.h"
#include "login_structures.h"
@ -24,7 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/eqemu_logsys_fmt.h"
extern LoginServer server;
extern bool run_server;
extern bool run_server;
ServerManager::ServerManager()
{
@ -36,38 +39,52 @@ ServerManager::ServerManager()
opts.ipv6 = false;
server_connection->Listen(opts);
server_connection->OnConnectionIdentified("World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
LogF(Logs::General, Logs::Login_Server, "New world server connection from {0}:{1}", c->Handle()->RemoteIP(), c->Handle()->RemotePort());
server_connection->OnConnectionIdentified(
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
LogF(Logs::General,
Logs::Login_Server,
"New world server connection from {0}:{1}",
c->Handle()->RemoteIP(),
c->Handle()->RemotePort());
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 &&
(*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) {
LogF(Logs::General, Logs::Login_Server, "World server already existed for {0}:{1}, removing existing connection.",
c->Handle()->RemoteIP(), c->Handle()->RemotePort());
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 &&
(*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) {
LogF(Logs::General,
Logs::Login_Server,
"World server already existed for {0}:{1}, removing existing connection.",
c->Handle()->RemoteIP(),
c->Handle()->RemotePort());
world_servers.erase(iter);
break;
world_servers.erase(iter);
break;
}
++iter;
}
++iter;
world_servers.push_back(std::unique_ptr<WorldServer>(new WorldServer(c)));
}
);
world_servers.push_back(std::unique_ptr<WorldServer>(new WorldServer(c)));
});
server_connection->OnConnectionRemoved(
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) {
LogF(Logs::General,
Logs::World_Server,
"World server {0} has been disconnected, removing.",
(*iter)->GetLongName().c_str());
world_servers.erase(iter);
return;
}
server_connection->OnConnectionRemoved("World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) {
LogF(Logs::General, Logs::World_Server, "World server {0} has been disconnected, removing.", (*iter)->GetLongName().c_str());
world_servers.erase(iter);
return;
++iter;
}
++iter;
}
});
);
}
ServerManager::~ServerManager()
@ -75,11 +92,12 @@ ServerManager::~ServerManager()
}
WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port)
WorldServer *ServerManager::GetServerByAddress(const std::string &addr, int port)
{
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr && (*iter)->GetConnection()->Handle()->RemotePort()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr &&
(*iter)->GetConnection()->Handle()->RemotePort()) {
return (*iter).get();
}
++iter;
@ -90,9 +108,9 @@ WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port
EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq)
{
unsigned int packet_size = sizeof(ServerListHeader_Struct);
unsigned int packet_size = sizeof(ServerListHeader_Struct);
unsigned int server_count = 0;
in_addr in;
in_addr in;
in.s_addr = c->GetConnection()->GetRemoteIP();
std::string client_ip = inet_ntoa(in);
@ -119,8 +137,8 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
++iter;
}
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size);
ServerListHeader_Struct *server_list = (ServerListHeader_Struct*)outapp->pBuffer;
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size);
ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer;
server_list->Unknown1 = seq;
server_list->Unknown2 = 0x00000000;
server_list->Unknown3 = 0x01650000;
@ -129,7 +147,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
* Not sure what this is but it should be noted setting it to
* 0xFFFFFFFF crashes the client so: don't do that.
*/
server_list->Unknown4 = 0x00000000;
server_list->Unknown4 = 0x00000000;
server_list->NumberOfServers = server_count;
unsigned char *data_pointer = outapp->pBuffer;
@ -157,22 +175,22 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
}
switch ((*iter)->GetServerListID()) {
case 1: {
*(unsigned int*)data_pointer = 0x00000030;
break;
}
case 2: {
*(unsigned int*)data_pointer = 0x00000009;
break;
}
default: {
*(unsigned int*)data_pointer = 0x00000001;
}
case 1: {
*(unsigned int *) data_pointer = 0x00000030;
break;
}
case 2: {
*(unsigned int *) data_pointer = 0x00000009;
break;
}
default: {
*(unsigned int *) data_pointer = 0x00000001;
}
}
data_pointer += 4;
*(unsigned int*)data_pointer = (*iter)->GetRuntimeID();
*(unsigned int *) data_pointer = (*iter)->GetRuntimeID();
data_pointer += 4;
memcpy(data_pointer, (*iter)->GetLongName().c_str(), (*iter)->GetLongName().size());
@ -187,18 +205,18 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
// 0 = Up, 1 = Down, 2 = Up, 3 = down, 4 = locked, 5 = locked(down)
if ((*iter)->GetStatus() < 0) {
if ((*iter)->GetZonesBooted() == 0) {
*(uint32*)data_pointer = 0x01;
*(uint32 *) data_pointer = 0x01;
}
else {
*(uint32*)data_pointer = 0x04;
*(uint32 *) data_pointer = 0x04;
}
}
else {
*(uint32*)data_pointer = 0x02;
*(uint32 *) data_pointer = 0x02;
}
data_pointer += 4;
*(uint32*)data_pointer = (*iter)->GetPlayersOnline();
*(uint32 *) data_pointer = (*iter)->GetPlayersOnline();
data_pointer += 4;
++iter;
@ -207,16 +225,20 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
return outapp;
}
void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id, const std::string &client_loginserver)
void ServerManager::SendUserToWorldRequest(
unsigned int server_id,
unsigned int client_account_id,
const std::string &client_loginserver
)
{
auto iter = world_servers.begin();
auto iter = world_servers.begin();
bool found = false;
while (iter != world_servers.end()) {
if ((*iter)->GetRuntimeID() == server_id) {
EQ::Net::DynamicPacket outapp;
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp.Data();
utwr->worldid = server_id;
UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct *) outapp.Data();
utwr->worldid = server_id;
utwr->lsaccountid = client_account_id;
strncpy(utwr->login, &client_loginserver[0], 64);
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
@ -230,7 +252,10 @@ void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int
}
if (!found && server.options.IsTraceOn()) {
Log(Logs::General, Logs::Error, "Client requested a user to world but supplied an invalid id of %u.", server_id);
Log(Logs::General,
Logs::Error,
"Client requested a user to world but supplied an invalid id of %u.",
server_id);
}
}

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_SERVERMANAGER_H
#define EQEMU_SERVERMANAGER_H
@ -27,14 +30,14 @@
#include <list>
/**
* Server manager class, deals with management of the world servers.
*/
class ServerManager
{
* Server manager class, deals with management of the world servers
*/
class ServerManager {
public:
/**
* Constructor, sets up the TCP server and starts listening.
*/
* Constructor, sets up the TCP server and starts listening
*/
ServerManager();
/**
@ -43,34 +46,60 @@ public:
~ServerManager();
/**
* Sends a request to world to see if the client is banned or suspended.
*/
void SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id, const std::string &client_loginserver);
* Sends a request to world to see if the client is banned or suspended
*
* @param server_id
* @param client_account_id
* @param client_loginserver
*/
void SendUserToWorldRequest(
unsigned int server_id,
unsigned int client_account_id,
const std::string &client_loginserver
);
/**
* Creates a server list packet for the client.
*/
* Creates a server list packet for the client
*
* @param c
* @param seq
* @return
*/
EQApplicationPacket *CreateServerListPacket(Client *c, uint32 seq);
/**
* 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 s_name
* @param ignore
* @return
*/
bool ServerExists(std::string l_name, std::string s_name, WorldServer *ignore = nullptr);
/**
* Destroys a server with this name, ignoring option.
*/
* Destroys a server with this name, ignoring option
*
* @param l_name
* @param s_name
* @param ignore
*/
void DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore = nullptr);
private:
/**
* Retrieves a server(if exists) by ip address
* Useful utility for the reconnect process.
*/
WorldServer* GetServerByAddress(const std::string &address, int port);
* Retrieves a server(if exists) by ip address
* Useful utility for the reconnect process
*
* @param address
* @param port
* @return
*/
WorldServer *GetServerByAddress(const std::string &address, int port);
std::unique_ptr<EQ::Net::ServertalkServer> server_connection;
std::list<std::unique_ptr<WorldServer>> world_servers;
std::list<std::unique_ptr<WorldServer>> world_servers;
};
#endif

View File

@ -1,47 +1,73 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "world_server.h"
#include "login_server.h"
#include "login_structures.h"
#include "config.h"
#include "../common/eqemu_logsys.h"
extern LoginServer server;
WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
{
connection = c;
zones_booted = 0;
players_online = 0;
server_status = 0;
runtime_id = 0;
server_list_id = 0;
server_type = 0;
connection = c;
zones_booted = 0;
players_online = 0;
server_status = 0;
runtime_id = 0;
server_list_id = 0;
server_type = 0;
is_server_authorized = false;
is_server_trusted = false;
is_server_logged_in = false;
is_server_trusted = false;
is_server_logged_in = false;
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_UsertoWorldRespLeg, std::bind(&WorldServer::ProcessUsertoWorldRespLeg, 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));
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_UsertoWorldRespLeg,
std::bind(
&WorldServer::ProcessUsertoWorldRespLeg,
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()
@ -51,87 +77,92 @@ WorldServer::~WorldServer()
void WorldServer::Reset()
{
zones_booted = 0;
zones_booted = 0;
players_online = 0;
server_status = 0;
server_status = 0;
runtime_id;
server_list_id = 0;
server_type = 0;
server_list_id = 0;
server_type = 0;
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)
{
if (server.options.IsWorldTraceOn())
{
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
if (server.options.IsWorldTraceOn()) {
Log(Logs::General,
Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)",
opcode,
p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(ServerNewLSInfo_Struct))
{
Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, "
if (p.Length() < sizeof(ServerNewLSInfo_Struct)) {
Log(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(Logs::General, Logs::Netcode, "New Login Info Recieved.");
if (server.options.IsWorldTraceOn()) {
Log(Logs::General, Logs::Netcode, "New Login Info Received.");
}
ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)p.Data();
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(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
if (server.options.IsWorldTraceOn()) {
Log(Logs::General,
Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)",
opcode,
p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(ServerLSStatus_Struct))
{
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_LSStatus, "
"but was too small. Discarded to avoid buffer overrun.");
if (p.Length() < sizeof(ServerLSStatus_Struct)) {
Log(Logs::General,
Logs::Error,
"Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun");
return;
}
if (server.options.IsWorldTraceOn())
{
Log(Logs::General, Logs::Netcode, "World Server Status Recieved.");
if (server.options.IsWorldTraceOn()) {
Log(Logs::General, Logs::Netcode, "World Server Status Received.");
}
ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)p.Data();
ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) p.Data();
Handle_LSStatus(ls_status);
}
void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p)
{
if (server.options.IsWorldTraceOn())
{
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
if (server.options.IsWorldTraceOn()) {
Log(Logs::General,
Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)",
opcode,
p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct))
{
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, "
if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) {
Log(Logs::General,
Logs::Error,
"Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
"but was too small. Discarded to avoid buffer overrun.");
return;
}
@ -139,86 +170,101 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
//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())
{
if (server.options.IsTraceOn()) {
Log(Logs::General, Logs::Netcode, "User-To-World Response received.");
}
UsertoWorldResponseLegacy_Struct *utwr = (UsertoWorldResponseLegacy_Struct*)p.Data();
UsertoWorldResponseLegacy_Struct *utwr = (UsertoWorldResponseLegacy_Struct *) p.Data();
Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid);
Client *c = server.client_manager->GetClient(utwr->lsaccountid, "eqemu");
if (c)
{
Log(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();
if (c) {
Log(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(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
if (utwr->response > 0)
{
if (utwr->response > 0) {
per->Allowed = 1;
SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetLoginServerName());
SendClientAuth(
c->GetConnection()->GetRemoteAddr(),
c->GetAccountName(),
c->GetKey(),
c->GetAccountID(),
c->GetLoginServerName());
}
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;
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(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);
if (server.options.IsTraceOn()) {
Log(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(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
}
if (server.options.IsDumpOutPacketsOn())
{
if (server.options.IsDumpOutPacketsOn()) {
DumpPacket(outapp);
}
c->SendPlayResponse(outapp);
delete outapp;
}
else
{
Log(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid);
else {
Log(Logs::General,
Logs::Error,
"Received User-To-World Response for %u but could not find the client referenced!.",
utwr->lsaccountid);
}
}
void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p)
{
if (server.options.IsWorldTraceOn())
{
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
if (server.options.IsWorldTraceOn()) {
Log(Logs::General,
Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)",
opcode,
p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(UsertoWorldResponse_Struct))
{
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, "
if (p.Length() < sizeof(UsertoWorldResponse_Struct)) {
Log(Logs::General,
Logs::Error,
"Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
"but was too small. Discarded to avoid buffer overrun.");
return;
}
@ -226,94 +272,112 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet
//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())
{
if (server.options.IsTraceOn()) {
Log(Logs::General, Logs::Netcode, "User-To-World Response received.");
}
UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)p.Data();
UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct *) p.Data();
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);
if (c)
{
Log(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();
if (c) {
Log(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(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
if (utwr->response > 0)
{
if (utwr->response > 0) {
per->Allowed = 1;
SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetLoginServerName());
SendClientAuth(
c->GetConnection()->GetRemoteAddr(),
c->GetAccountName(),
c->GetKey(),
c->GetAccountID(),
c->GetLoginServerName());
}
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;
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(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);
if (server.options.IsTraceOn()) {
Log(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(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
}
if (server.options.IsDumpOutPacketsOn())
{
if (server.options.IsDumpOutPacketsOn()) {
DumpPacket(outapp);
}
c->SendPlayResponse(outapp);
delete outapp;
}
else
{
Log(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid);
else {
Log(Logs::General,
Logs::Error,
"Received User-To-World Response for %u but could not find the client referenced!.",
utwr->lsaccountid);
}
}
/**
* @param opcode
* @param p
*/
void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p)
{
if (server.options.IsWorldTraceOn())
{
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
if (server.options.IsWorldTraceOn()) {
Log(Logs::General,
Logs::Netcode,
"Application packet received from server: 0x%.4X, (size %u)",
opcode,
p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(ServerLSAccountUpdate_Struct))
{
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerLSAccountUpdate_Struct, "
if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) {
Log(Logs::General,
Logs::Error,
"Received application packet from server that had opcode ServerLSAccountUpdate_Struct, "
"but was too small. Discarded to avoid buffer overrun.");
return;
}
Log(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)
{
ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) p.Data();
if (is_server_trusted) {
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount);
std::string name;
std::string password;
@ -325,160 +389,155 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
}
}
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i)
{
if (is_server_logged_in)
{
Log(Logs::General, Logs::Error, "WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting.");
if (is_server_logged_in) {
Log(Logs::General,
Logs::Error,
"WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting.");
return;
}
if (strlen(i->account) <= 30)
{
if (strlen(i->account) <= 30) {
account_name = i->account;
}
else
{
else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account name was too long.");
return;
}
if (strlen(i->password) <= 30)
{
if (strlen(i->password) <= 30) {
account_password = i->password;
}
else
{
else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account password was too long.");
return;
}
if (strlen(i->name) <= 200)
{
if (strlen(i->name) <= 200) {
long_name = i->name;
}
else
{
else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, long name was too long.");
return;
}
if (strlen(i->shortname) <= 50)
{
if (strlen(i->shortname) <= 50) {
short_name = i->shortname;
}
else
{
else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, short name was too long.");
return;
}
if (strlen(i->local_address) <= 125)
{
if (strlen(i->local_address) == 0)
{
if (strlen(i->local_address) <= 125) {
if (strlen(i->local_address) == 0) {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was null, defaulting to localhost");
local_ip = "127.0.0.1";
}
else
{
else {
local_ip = i->local_address;
}
}
else
{
else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was too long.");
return;
}
if (strlen(i->remote_address) <= 125)
{
if (strlen(i->remote_address) == 0)
{
if (strlen(i->remote_address) <= 125) {
if (strlen(i->remote_address) == 0) {
remote_ip = GetConnection()->Handle()->RemoteIP();
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.", remote_ip.c_str());
Log(Logs::General,
Logs::Error,
"Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.",
remote_ip.c_str());
}
else
{
else {
remote_ip = i->remote_address;
}
}
else
{
else {
remote_ip = GetConnection()->Handle()->RemoteIP();
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", remote_ip.c_str());
Log(Logs::General,
Logs::Error,
"Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.",
remote_ip.c_str());
}
if (strlen(i->serverversion) <= 64)
{
if (strlen(i->serverversion) <= 64) {
version = i->serverversion;
}
else
{
else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, server version was too long.");
return;
}
if (strlen(i->protocolversion) <= 25)
{
if (strlen(i->protocolversion) <= 25) {
protocol = i->protocolversion;
}
else
{
else {
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, protocol version was too long.");
return;
}
server_type = i->servertype;
server_type = i->servertype;
is_server_logged_in = true;
if (server.options.IsRejectingDuplicateServers())
{
if (server.server_manager->ServerExists(long_name, short_name, this))
{
Log(Logs::General, Logs::Error, "World tried to login but there already exists a server that has that name.");
if (server.options.IsRejectingDuplicateServers()) {
if (server.server_manager->ServerExists(long_name, short_name, this)) {
Log(Logs::General,
Logs::Error,
"World tried to login but there already exists a server that has that name.");
return;
}
}
else
{
if (server.server_manager->ServerExists(long_name, short_name, this))
{
Log(Logs::General, Logs::Error, "World tried to login but there already exists a server that has that name.");
else {
if (server.server_manager->ServerExists(long_name, short_name, this)) {
Log(Logs::General,
Logs::Error,
"World tried to login but there already exists a server that has that name.");
server.server_manager->DestroyServerByName(long_name, short_name, this);
}
}
if (!server.options.IsUnregisteredAllowed())
{
if (account_name.size() > 0 && account_password.size() > 0)
{
unsigned int s_id = 0;
if (!server.options.IsUnregisteredAllowed()) {
if (account_name.size() > 0 && account_password.size() > 0) {
unsigned int s_id = 0;
unsigned int s_list_type = 0;
unsigned int s_trusted = 0;
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)
{
Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged into account that had no user/password requirement.",
long_name.c_str(), short_name.c_str());
unsigned int s_trusted = 0;
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) {
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) successfully logged into account that had no user/password requirement.",
long_name.c_str(),
short_name.c_str());
is_server_authorized = true;
SetRuntimeID(s_id);
server_list_id = s_list_type;
desc = s_desc;
desc = s_desc;
}
else if (s_acct_name.compare(account_name) == 0 && s_acct_pass.compare(account_password) == 0)
{
else if (s_acct_name.compare(account_name) == 0 && s_acct_pass.compare(account_password) == 0) {
Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.",
long_name.c_str(), short_name.c_str());
is_server_authorized = true;
SetRuntimeID(s_id);
server_list_id = s_list_type;
desc = s_desc;
desc = s_desc;
if (s_trusted) {
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
is_server_trusted = true;
@ -488,31 +547,41 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
}
}
else {
Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but account and password did not match the entry in the database, and only"
" registered servers are allowed.", long_name.c_str(), short_name.c_str());
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) attempted to log in but account and password did not match the entry in the database, and only"
" registered servers are allowed.",
long_name.c_str(),
short_name.c_str());
return;
}
}
else {
Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but database couldn't find an entry and only registered servers are allowed.",
long_name.c_str(), short_name.c_str());
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) attempted to log in but database couldn't find an entry and only registered servers are allowed.",
long_name.c_str(),
short_name.c_str());
return;
}
}
else {
Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but only registered servers are allowed.",
long_name.c_str(), short_name.c_str());
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) did not attempt to log in but only registered servers are allowed.",
long_name.c_str(),
short_name.c_str());
return;
}
}
else {
unsigned int server_id = 0;
unsigned int server_list_type = 0;
unsigned int server_id = 0;
unsigned int server_list_type = 0;
unsigned int is_server_trusted = 0;
std::string server_description;
std::string server_list_description;
std::string server_account_name;
std::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(
@ -524,17 +593,18 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
is_server_trusted,
server_list_description,
server_account_name,
server_account_password))
{
server_account_password
)) {
if (account_name.size() > 0 && account_password.size() > 0) {
if (server_account_name.compare(account_name) == 0 && server_account_password.compare(account_password) == 0) {
if (server_account_name.compare(account_name) == 0 &&
server_account_password.compare(account_password) == 0) {
Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.",
long_name.c_str(), short_name.c_str());
is_server_authorized = true;
SetRuntimeID(server_id);
server_list_id = server_list_type;
desc = server_description;
desc = server_description;
if (is_server_trusted) {
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
@ -543,31 +613,50 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
connection->Send(ServerOP_LSAccountUpdate, outapp);
}
}
/**
* this is the first of two cases where we should deny access even if unregistered is allowed
*/
else {
// this is the first of two cases where we should deny access even if unregistered is allowed
Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but account and password did not match the entry in the database.",
long_name.c_str(), short_name.c_str());
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) attempted to log in but account and password did not match the entry in the database.",
long_name.c_str(),
short_name.c_str());
}
}
else {
/**
* this is the second of two cases where we should deny access even if unregistered is allowed
*/
if (server_account_name.size() > 0 || server_account_password.size() > 0) {
// this is the second of two cases where we should deny access even if unregistered is allowed
Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but this server requires a password.",
long_name.c_str(), short_name.c_str());
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) did not attempt to log in but this server requires a password.",
long_name.c_str(),
short_name.c_str());
}
else {
Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but unregistered servers are allowed.",
long_name.c_str(), short_name.c_str());
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) did not attempt to log in but unregistered servers are allowed.",
long_name.c_str(),
short_name.c_str());
is_server_authorized = true;
SetRuntimeID(server_id);
server_list_id = 3;
}
}
}
else
{
Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but database couldn't find an entry but unregistered servers are allowed.",
long_name.c_str(), short_name.c_str());
else {
Log(Logs::General,
Logs::World_Server,
"Server %s(%s) attempted to log in but database couldn't find an entry but unregistered servers are allowed.",
long_name.c_str(),
short_name.c_str());
if (server.db->CreateWorldRegistration(long_name, short_name, server_id)) {
is_server_authorized = true;
SetRuntimeID(server_id);
@ -579,23 +668,39 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
server.db->UpdateWorldRegistration(GetRuntimeID(), long_name, GetConnection()->Handle()->RemoteIP());
}
/**
* @param s
*/
void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s)
{
players_online = s->num_players;
zones_booted = s->num_zones;
server_status = s->status;
zones_booted = s->num_zones;
server_status = s->status;
}
void WorldServer::SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name)
/**
* @param ip
* @param account
* @param key
* @param account_id
* @param loginserver_name
*/
void WorldServer::SendClientAuth(
std::string ip,
std::string account,
std::string key,
unsigned int account_id,
const std::string &loginserver_name
)
{
EQ::Net::DynamicPacket outapp;
ClientAuth_Struct client_auth;
ClientAuth_Struct client_auth;
client_auth.lsaccount_id = account_id;
strncpy(client_auth.name, account.c_str(), 30);
strncpy(client_auth.key, key.c_str(), 30);
client_auth.lsadmin = 0;
client_auth.lsadmin = 0;
client_auth.worldadmin = 0;
client_auth.ip = inet_addr(ip.c_str());
client_auth.ip = inet_addr(ip.c_str());
strncpy(client_auth.lsname, &loginserver_name[0], 64);
std::string client_address(ip);
@ -614,8 +719,7 @@ void WorldServer::SendClientAuth(std::string ip, std::string account, std::strin
outapp.PutSerialize(0, client_auth);
connection->Send(ServerOP_LSClientAuth, outapp);
if (server.options.IsDumpInPacketsOn())
{
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(ServerOP_LSClientAuth, outapp);
}
}

View File

@ -1,20 +1,23 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
/**
* EQEmulator: Everquest Server Emulator
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY except by those people which sell it, which
* are required to give you total support for your newly bought product;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EQEMU_WORLDSERVER_H
#define EQEMU_WORLDSERVER_H
@ -31,106 +34,79 @@
class WorldServer
{
public:
/**
* Constructor, sets our connection to c.
*/
WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c);
/**
* Destructor, frees our connection if it exists.
*/
* Destructor, frees our connection if it exists
*/
~WorldServer();
/**
* Resets the basic stats of this server.
*/
* Resets the basic stats of this server.
*/
void Reset();
/**
* Accesses connection, it is intentional that this is not const (trust me).
*/
std::shared_ptr<EQ::Net::ServertalkServerConnection> GetConnection() { return connection; }
/**
* Sets the connection to c.
*/
void SetConnection(std::shared_ptr<EQ::Net::ServertalkServerConnection> c) { connection = c; }
/**
* Gets the runtime id of this server.
*/
unsigned int GetRuntimeID() const { return runtime_id; }
/**
* Sets the runtime id of this server.
*/
void SetRuntimeID(unsigned int id) { runtime_id = id; }
/**
* Gets the long name of the server.
*/
std::string GetLongName() const { return long_name; }
/**
* Gets the short name of the server.
*/
std::string GetShortName() const { return short_name; }
/**
* Gets whether the server is authorized to show up on the server list or not.
*/
* Gets whether the server is authorized to show up on the server list or not
* @return
*/
bool IsAuthorized() const { return is_server_authorized; }
/**
* Gets the local ip of the server.
*/
std::string GetLocalIP() const { return local_ip; }
/**
* Gets the remote ip of the server.
*/
std::string GetRemoteIP() const { return remote_ip; }
/**
* Gets what kind of server this server is (legends, preferred, normal)
*/
* Gets what kind of server this server is (legends, preferred, normal)
*
* @return
*/
unsigned int GetServerListID() const { return server_list_id; }
/**
* Gets the status of the server.
*/
int GetStatus() const { return server_status; }
/**
* Gets the number of zones online on the server.
*/
unsigned int GetZonesBooted() const { return zones_booted; }
/**
* Gets the number of players on the server.
*/
unsigned int GetPlayersOnline() const { return players_online; }
/**
* Takes the info struct we received from world and processes it.
*/
* Takes the info struct we received from world and processes it
*
* @param i
*/
void Handle_NewLSInfo(ServerNewLSInfo_Struct* i);
/**
* Takes the status struct we received from world and processes it.
*/
* Takes the status struct we received from world and processes it
*
* @param s
*/
void Handle_LSStatus(ServerLSStatus_Struct *s);
/**
* Informs world that there is a client incoming with the following data.
*/
* Informs world that there is a client incoming with the following data.
*
* @param ip
* @param account
* @param key
* @param account_id
* @param loginserver_name
*/
void SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name);
private:
/**
* Packet processing functions:
*/
* Packet processing functions
*
* @param opcode
* @param p
*/
void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p);
void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p);
void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p);