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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "client.h"
#include "login_server.h" #include "login_server.h"
#include "../common/misc_functions.h" #include "../common/misc_functions.h"
@ -25,6 +28,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
extern LoginServer server; extern LoginServer server;
/**
* @param c
* @param v
*/
Client::Client(std::shared_ptr<EQStreamInterface> c, LSClientVersion v) Client::Client(std::shared_ptr<EQStreamInterface> c, LSClientVersion v)
{ {
connection = c; connection = c;
@ -38,15 +45,12 @@ Client::Client(std::shared_ptr<EQStreamInterface> c, LSClientVersion v)
bool Client::Process() bool Client::Process()
{ {
EQApplicationPacket *app = connection->PopPacket(); EQApplicationPacket *app = connection->PopPacket();
while (app) while (app) {
{ if (server.options.IsTraceOn()) {
if (server.options.IsTraceOn())
{
Log(Logs::General, Logs::Login_Server, "Application packet received from client (size %u)", app->Size()); 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); DumpPacket(app);
} }
@ -56,52 +60,42 @@ bool Client::Process()
continue; continue;
} }
switch (app->GetOpcode()) switch (app->GetOpcode()) {
{ case OP_SessionReady: {
case OP_SessionReady: if (server.options.IsTraceOn()) {
{
if (server.options.IsTraceOn())
{
Log(Logs::General, Logs::Login_Server, "Session ready received from client."); Log(Logs::General, Logs::Login_Server, "Session ready received from client.");
} }
Handle_SessionReady((const char *) app->pBuffer, app->Size()); Handle_SessionReady((const char *) app->pBuffer, app->Size());
break; break;
} }
case OP_Login: case OP_Login: {
{ if (app->Size() < 20) {
if (app->Size() < 20)
{
Log(Logs::General, Logs::Error, "Login received but it is too small, discarding."); Log(Logs::General, Logs::Error, "Login received but it is too small, discarding.");
break; break;
} }
if (server.options.IsTraceOn()) if (server.options.IsTraceOn()) {
{
Log(Logs::General, Logs::Login_Server, "Login received from client."); Log(Logs::General, Logs::Login_Server, "Login received from client.");
} }
Handle_Login((const char *) app->pBuffer, app->Size()); Handle_Login((const char *) app->pBuffer, app->Size());
break; break;
} }
case OP_ServerListRequest: case OP_ServerListRequest: {
{
if (app->Size() < 4) { if (app->Size() < 4) {
Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding."); Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding.");
break; break;
} }
if (server.options.IsTraceOn()) if (server.options.IsTraceOn()) {
{
Log(Logs::General, Logs::Login_Server, "Server list request received from client."); Log(Logs::General, Logs::Login_Server, "Server list request received from client.");
} }
SendServerListPacket(*(uint32_t *) app->pBuffer); SendServerListPacket(*(uint32_t *) app->pBuffer);
break; break;
} }
case OP_PlayEverquestRequest: case OP_PlayEverquestRequest: {
{ if (app->Size() < sizeof(PlayEverquestRequest_Struct)) {
if (app->Size() < sizeof(PlayEverquestRequest_Struct))
{
Log(Logs::General, Logs::Error, "Play received but it is too small, discarding."); Log(Logs::General, Logs::Error, "Play received but it is too small, discarding.");
break; break;
} }
@ -109,8 +103,7 @@ bool Client::Process()
Handle_Play((const char *) app->pBuffer); Handle_Play((const char *) app->pBuffer);
break; break;
} }
default: default: {
{
if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) { if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) {
char dump[64]; char dump[64];
app->build_header_dump(dump); app->build_header_dump(dump);
@ -126,16 +119,20 @@ bool Client::Process()
return true; return true;
} }
/**
* Sends our reply to session ready packet
*
* @param data
* @param size
*/
void Client::Handle_SessionReady(const char *data, unsigned int 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."); Log(Logs::General, Logs::Error, "Session ready received again after already being received.");
return; return;
} }
if (size < sizeof(unsigned int)) if (size < sizeof(unsigned int)) {
{
Log(Logs::General, Logs::Error, "Session ready was too small."); Log(Logs::General, Logs::Error, "Session ready was too small.");
return; return;
} }
@ -145,23 +142,20 @@ void Client::Handle_SessionReady(const char* data, unsigned int size)
/** /**
* The packets are mostly the same but slightly different between the two versions. * 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); EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 17);
outapp->pBuffer[0] = 0x02; outapp->pBuffer[0] = 0x02;
outapp->pBuffer[10] = 0x01; outapp->pBuffer[10] = 0x01;
outapp->pBuffer[11] = 0x65; outapp->pBuffer[11] = 0x65;
if (server.options.IsDumpOutPacketsOn()) if (server.options.IsDumpOutPacketsOn()) {
{
DumpPacket(outapp); DumpPacket(outapp);
} }
connection->QueuePacket(outapp); connection->QueuePacket(outapp);
delete outapp; delete outapp;
} }
else else {
{
const char *msg = "ChatMessage"; const char *msg = "ChatMessage";
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 16 + strlen(msg)); EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 16 + strlen(msg));
outapp->pBuffer[0] = 0x02; outapp->pBuffer[0] = 0x02;
@ -169,8 +163,7 @@ void Client::Handle_SessionReady(const char* data, unsigned int size)
outapp->pBuffer[11] = 0x65; 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); DumpPacket(outapp);
} }
@ -179,6 +172,12 @@ void Client::Handle_SessionReady(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) void Client::Handle_Login(const char *data, unsigned int size)
{ {
if (status != cs_waiting_for_login) { if (status != cs_waiting_for_login) {
@ -187,12 +186,18 @@ void Client::Handle_Login(const char* data, unsigned int size)
} }
if ((size - 12) % 8 != 0) { 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; return;
} }
if (size < sizeof(LoginLoginRequest_Struct)) { 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; return;
} }
@ -229,7 +234,13 @@ void Client::Handle_Login(const char* data, unsigned int size)
if (outbuffer[0] == 0 && outbuffer[1] == 0) { if (outbuffer[0] == 0 && outbuffer[1] == 0) {
if (server.options.IsTokenLoginAllowed()) { if (server.options.IsTokenLoginAllowed()) {
cred = (&outbuffer[2 + user.length()]); cred = (&outbuffer[2 + user.length()]);
result = server.db->GetLoginTokenDataFromToken(cred, connection->GetRemoteAddr(), db_account_id, db_loginserver, user); result = server.db->GetLoginTokenDataFromToken(
cred,
connection->GetRemoteAddr(),
db_account_id,
db_loginserver,
user
);
} }
} }
else { else {
@ -243,7 +254,8 @@ void Client::Handle_Login(const char* data, unsigned int size)
ParseAccountString(user, user, db_loginserver); 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; status = cs_creating_account;
AttemptLoginAccountCreation(user, cred, db_loginserver); AttemptLoginAccountCreation(user, cred, db_loginserver);
return; return;
@ -263,10 +275,14 @@ void Client::Handle_Login(const char* data, unsigned int size)
} }
} }
/**
* 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) 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."); Log(Logs::General, Logs::Error, "Client sent a play request when they were not logged in, discarding.");
return; return;
} }
@ -275,9 +291,12 @@ void Client::Handle_Play(const char* data)
unsigned int server_id_in = (unsigned int) play->ServerNumber; unsigned int server_id_in = (unsigned int) play->ServerNumber;
unsigned int sequence_in = (unsigned int) play->Sequence; unsigned int sequence_in = (unsigned int) play->Sequence;
if (server.options.IsTraceOn()) if (server.options.IsTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Login_Server, "Play received from client, server number %u sequence %u.", server_id_in, sequence_in); 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;
@ -286,12 +305,14 @@ void Client::Handle_Play(const char* data)
server.server_manager->SendUserToWorldRequest(server_id_in, account_id, loginserver_name); server.server_manager->SendUserToWorldRequest(server_id_in, account_id, loginserver_name);
} }
/**
* @param seq
*/
void Client::SendServerListPacket(uint32 seq) void Client::SendServerListPacket(uint32 seq)
{ {
EQApplicationPacket *outapp = server.server_manager->CreateServerListPacket(this, seq); EQApplicationPacket *outapp = server.server_manager->CreateServerListPacket(this, seq);
if (server.options.IsDumpOutPacketsOn()) if (server.options.IsDumpOutPacketsOn()) {
{
DumpPacket(outapp); DumpPacket(outapp);
} }
@ -301,8 +322,7 @@ void Client::SendServerListPacket(uint32 seq)
void Client::SendPlayResponse(EQApplicationPacket *outapp) 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()); 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); // server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size);
} }
@ -313,8 +333,7 @@ void Client::GenerateKey()
{ {
key.clear(); key.clear();
int count = 0; int count = 0;
while (count < 10) while (count < 10) {
{
static const char key_selection[] = static const char key_selection[] =
{ {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
@ -329,7 +348,11 @@ void Client::GenerateKey()
} }
} }
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 (loginserver == "eqemu") {
if (!server.options.CanAutoLinkAccounts()) { if (!server.options.CanAutoLinkAccounts()) {
@ -353,19 +376,39 @@ void Client::AttemptLoginAccountCreation(const std::string &user, const std::str
auto address = addr_components[0]; auto address = addr_components[0];
auto port = std::stoi(addr_components[1]); auto port = std::stoi(addr_components[1]);
EQ::Net::DNSLookup(address, port, false, [=](const std::string &addr) { EQ::Net::DNSLookup(
address, port, false, [=](const std::string &addr) {
if (addr.empty()) { if (addr.empty()) {
DoFailedLogin(); DoFailedLogin();
return; return;
} }
login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager()); login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
login_connection_manager->OnNewConnection(std::bind(&Client::LoginOnNewConnection, this, std::placeholders::_1)); login_connection_manager->OnNewConnection(
login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); std::bind(
login_connection_manager->OnPacketRecv(std::bind(&Client::LoginOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2)); &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->Connect(addr, port);
}); }
);
} }
else { else {
if (!server.options.CanAutoCreateAccounts()) { if (!server.options.CanAutoCreateAccounts()) {
@ -399,7 +442,21 @@ void Client::DoFailedLogin()
status = cs_failed_to_login; 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(); auto mode = server.options.GetEncryptionMode();
if (eqcrypt_verify_hash(user, cred, hash, mode)) { 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; 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) void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver)
{ {
stored_user.clear(); stored_user.clear();
@ -509,6 +571,10 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const
status = cs_logged_in; status = cs_logged_in;
} }
/**
* @param user
* @param pass
*/
void Client::CreateLocalAccount(const std::string &user, const std::string &pass) void Client::CreateLocalAccount(const std::string &user, const std::string &pass)
{ {
auto mode = server.options.GetEncryptionMode(); auto mode = server.options.GetEncryptionMode();
@ -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) void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id)
{ {
auto mode = server.options.GetEncryptionMode(); 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) void Client::LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
{ {
login_connection = 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) { if (to == EQ::Net::StatusConnected) {
LoginSendSessionReady(); LoginSendSessionReady();
@ -553,10 +636,23 @@ 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
)
{ {
} }
/**
* @param conn
* @param p
*/
void Client::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p) void Client::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
{ {
auto opcode = p.GetUInt16(0); auto opcode = p.GetUInt16(0);
@ -617,7 +713,14 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet & p)
EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size); 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) { if (response_error > 101) {
DoFailedLogin(); 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_CLIENT_H
#define EQEMU_CLIENT_H #define EQEMU_CLIENT_H
@ -24,19 +27,15 @@
#include "../common/eq_stream_intf.h" #include "../common/eq_stream_intf.h"
#include "../common/net/dns.h" #include "../common/net/dns.h"
#include "../common/net/daybreak_connection.h" #include "../common/net/daybreak_connection.h"
#include "login_structures.h" #include "login_structures.h"
#include <memory> #include <memory>
enum LSClientVersion enum LSClientVersion {
{
cv_titanium, cv_titanium,
cv_sod cv_sod
}; };
enum LSClientStatus enum LSClientStatus {
{
cs_not_sent_session_ready, cs_not_sent_session_ready,
cs_waiting_for_login, cs_waiting_for_login,
cs_creating_account, cs_creating_account,
@ -45,94 +44,128 @@ enum LSClientStatus
}; };
/** /**
* Client class, controls a single client and it's * Client class, controls a single client and it's connection to the login server
* connection to the login server.
*/ */
class Client class Client {
{
public: 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); Client(std::shared_ptr<EQStreamInterface> c, LSClientVersion v);
/** /**
* Destructor. * Destructor
*/ */
~Client() {} ~Client() {}
/** /**
* Processes the client's connection and does various actions. * Processes the client's connection and does various actions
*
* @return
*/ */
bool Process(); bool Process();
/** /**
* Sends our reply to session ready packet. * Sends our reply to session ready packet
*
* @param data
* @param size
*/ */
void Handle_SessionReady(const char *data, unsigned int size); void Handle_SessionReady(const char *data, unsigned int size);
/** /**
* Verifies login and send a reply. * Verifies login and send a reply
*
* @param data
* @param size
*/ */
void Handle_Login(const char *data, unsigned int 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. * Sends a packet to the requested server to see if the client is allowed or not
*
* @param data
*/ */
void Handle_Play(const char *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); 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); 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(); void GenerateKey();
/** /**
* Gets the account id of this client. * Gets the account id of this client
*
* @return
*/ */
unsigned int GetAccountID() const { return account_id; } 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; } 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; } 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; } 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; } 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; } 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; } 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); void AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver);
@ -142,23 +175,23 @@ public:
void DoFailedLogin(); void DoFailedLogin();
/** /**
* Verifies a login hash, will also attempt to update a login hash if needed. * 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); 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); 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); 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); void CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id);
private: private:
@ -181,8 +214,16 @@ private:
std::string stored_user; std::string stored_user;
std::string stored_pass; std::string stored_pass;
void LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection); 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 LoginOnStatusChange(
void LoginOnStatusChangeIgnored(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); 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 LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
void LoginSendSessionReady(); void LoginSendSessionReady();
void LoginSendLogin(); void LoginSendLogin();

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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "client_manager.h"
#include "login_server.h" #include "login_server.h"
@ -30,58 +33,69 @@ ClientManager::ClientManager()
EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false); EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false);
titanium_stream = new EQ::Net::EQStreamManager(titanium_opts); titanium_stream = new EQ::Net::EQStreamManager(titanium_opts);
titanium_ops = new RegularOpcodeManager; titanium_ops = new RegularOpcodeManager;
if (!titanium_ops->LoadOpcodes(server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str())) 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.", 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()); server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str());
run_server = false; run_server = false;
} }
titanium_stream->OnNewConnection([this](std::shared_ptr<EQ::Net::EQStream> stream) { titanium_stream->OnNewConnection(
LogF(Logs::General, Logs::Login_Server, "New Titanium client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort()); [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); stream->SetOpcodeManager(&titanium_ops);
Client *c = new Client(stream, cv_titanium); Client *c = new Client(stream, cv_titanium);
clients.push_back(c); 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); EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false);
sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_stream = new EQ::Net::EQStreamManager(sod_opts);
sod_ops = new RegularOpcodeManager; sod_ops = new RegularOpcodeManager;
if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) 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.", 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()); server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str());
run_server = false; run_server = false;
} }
sod_stream->OnNewConnection([this](std::shared_ptr<EQ::Net::EQStream> stream) { sod_stream->OnNewConnection(
LogF(Logs::General, Logs::Login_Server, "New SoD client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort()); [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); stream->SetOpcodeManager(&sod_ops);
Client *c = new Client(stream, cv_sod); Client *c = new Client(stream, cv_sod);
clients.push_back(c); clients.push_back(c);
}); }
);
} }
ClientManager::~ClientManager() ClientManager::~ClientManager()
{ {
if (titanium_stream) if (titanium_stream) {
{
delete titanium_stream; delete titanium_stream;
} }
if (titanium_ops) if (titanium_ops) {
{
delete titanium_ops; delete titanium_ops;
} }
if (sod_stream) if (sod_stream) {
{
delete sod_stream; delete sod_stream;
} }
if (sod_ops) if (sod_ops) {
{
delete sod_ops; delete sod_ops;
} }
} }
@ -91,16 +105,13 @@ void ClientManager::Process()
ProcessDisconnect(); ProcessDisconnect();
auto iter = clients.begin(); auto iter = clients.begin();
while (iter != clients.end()) while (iter != clients.end()) {
{ if ((*iter)->Process() == false) {
if ((*iter)->Process() == false)
{
Log(Logs::General, Logs::Debug, "Client had a fatal error and had to be removed from the login."); Log(Logs::General, Logs::Debug, "Client had a fatal error and had to be removed from the login.");
delete (*iter); delete (*iter);
iter = clients.erase(iter); iter = clients.erase(iter);
} }
else else {
{
++iter; ++iter;
} }
} }
@ -109,17 +120,14 @@ void ClientManager::Process()
void ClientManager::ProcessDisconnect() void ClientManager::ProcessDisconnect()
{ {
auto iter = clients.begin(); auto iter = clients.begin();
while (iter != clients.end()) while (iter != clients.end()) {
{
std::shared_ptr<EQStreamInterface> c = (*iter)->GetConnection(); 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."); Log(Logs::General, Logs::Login_Server, "Client disconnected from the server, removing client.");
delete (*iter); delete (*iter);
iter = clients.erase(iter); iter = clients.erase(iter);
} }
else else {
{
++iter; ++iter;
} }
} }
@ -128,16 +136,15 @@ void ClientManager::ProcessDisconnect()
void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver) void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver)
{ {
auto iter = clients.begin(); auto iter = clients.begin();
while (iter != clients.end()) while (iter != clients.end()) {
{ if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) {
if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) Log(Logs::General,
{ Logs::Login_Server,
Log(Logs::General, Logs::Login_Server, "Client attempting to log in and existing client already logged in, removing existing client."); "Client attempting to log in and existing client already logged in, removing existing client.");
delete (*iter); delete (*iter);
iter = clients.erase(iter); iter = clients.erase(iter);
} }
else else {
{
++iter; ++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) Client *ClientManager::GetClient(unsigned int account_id, const std::string &loginserver)
{ {
auto iter = clients.begin(); auto iter = clients.begin();
while (iter != clients.end()) while (iter != clients.end()) {
{ if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) {
if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0)
{
return (*iter); return (*iter);
} }
++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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_CLIENTMANAGER_H
#define EQEMU_CLIENTMANAGER_H #define EQEMU_CLIENTMANAGER_H
@ -27,16 +30,15 @@
/** /**
* Client manager class, holds all the client objects and does basic processing. * Client manager class, holds all the client objects and does basic processing.
*/ */
class ClientManager class ClientManager {
{
public: public:
/** /**
* Constructor, sets up the stream factories and opcode managers. * Constructor: sets up the stream factories and opcode managers
*/ */
ClientManager(); ClientManager();
/** /**
* Destructor, shuts down the streams and opcode managers. * Destructor: shuts down the streams and opcode managers
*/ */
~ClientManager(); ~ClientManager();
@ -46,18 +48,25 @@ public:
void Process(); 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); 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); Client *GetClient(unsigned int account_id, const std::string &loginserver);
private: private:
/** /**
* Processes disconnected clients, removes them if necessary. * Processes disconnected clients, removes them if necessary
*/ */
void ProcessDisconnect(); void ProcessDisconnect();

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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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/global_define.h"
#include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys.h"
#include "config.h" #include "config.h"
/** /**
* Retrieves the variable we want from our title or theme * Retrieves the variable we want from our title or theme
* First gets the map from the title * First gets the map from the title, then gets the argument from the map we got from 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::string Config::GetVariable(std::string title, std::string parameter)
{ {
std::map<std::string, std::map<std::string, std::string> >::iterator iter = vars.find(title); 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); 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; return arg_iter->second;
} }
} }
@ -41,49 +45,43 @@ std::string Config::GetVariable(std::string title, std::string parameter)
/** /**
* Opens a file and passes it to the tokenizer * Opens a file and passes it to the tokenizer
* Then it parses the tokens returned and puts them into titles and variables. * Then it parses the tokens returned and puts them into titles and variables
*
* @param file_name
*/ */
void Config::Parse(const char *file_name) void Config::Parse(const char *file_name)
{ {
if(file_name == nullptr) if (file_name == nullptr) {
{
Log(Logs::General, Logs::Error, "Config::Parse(), file_name passed was null."); Log(Logs::General, Logs::Error, "Config::Parse(), file_name passed was null.");
return; return;
} }
vars.clear(); vars.clear();
FILE *input = fopen(file_name, "r"); FILE *input = fopen(file_name, "r");
if(input) if (input) {
{
std::list<std::string> tokens; std::list<std::string> tokens;
Tokenize(input, tokens); Tokenize(input, tokens);
char mode = 0; char mode = 0;
std::string title, param, arg; std::string title, param, arg;
std::list<std::string>::iterator iter = tokens.begin(); std::list<std::string>::iterator iter = tokens.begin();
while(iter != tokens.end()) while (iter != tokens.end()) {
{ if ((*iter).compare("[") == 0) {
if((*iter).compare("[") == 0)
{
title.clear(); title.clear();
bool first = true; bool first = true;
++iter; ++iter;
if(iter == tokens.end()) if (iter == tokens.end()) {
{
Log(Logs::General, Logs::Error, "Config::Parse(), EOF before title done parsing."); Log(Logs::General, Logs::Error, "Config::Parse(), EOF before title done parsing.");
fclose(input); fclose(input);
vars.clear(); vars.clear();
return; return;
} }
while((*iter).compare("]") != 0 && iter != tokens.end()) while ((*iter).compare("]") != 0 && iter != tokens.end()) {
{ if (!first) {
if(!first)
{
title += " "; title += " ";
} }
else else {
{
first = false; first = false;
} }
@ -93,34 +91,28 @@ void Config::Parse(const char *file_name)
++iter; ++iter;
} }
if(mode == 0) if (mode == 0) {
{
param = (*iter); param = (*iter);
mode++; mode++;
} }
else if(mode == 1) else if (mode == 1) {
{
mode++; mode++;
if((*iter).compare("=") != 0) if ((*iter).compare("=") != 0) {
{
Log(Logs::General, Logs::Error, "Config::Parse(), invalid parse token where = should be."); Log(Logs::General, Logs::Error, "Config::Parse(), invalid parse token where = should be.");
fclose(input); fclose(input);
vars.clear(); vars.clear();
return; return;
} }
} }
else else {
{
arg = (*iter); arg = (*iter);
mode = 0; mode = 0;
std::map<std::string, std::map<std::string, std::string> >::iterator map_iter = vars.find(title); 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; 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; std::map<std::string, std::string> var_map;
var_map[param] = arg; var_map[param] = arg;
vars[title] = var_map; vars[title] = var_map;
@ -130,28 +122,27 @@ void Config::Parse(const char *file_name)
} }
fclose(input); fclose(input);
} }
else else {
{
Log(Logs::General, Logs::Error, "Config::Parse(), file was unable to be opened for parsing."); Log(Logs::General, Logs::Error, "Config::Parse(), file was unable to be opened for parsing.");
} }
} }
/** /**
* Pretty basic lexical analyzer * Pretty basic lexical analyzer
* Breaks up the input character stream into tokens and puts them into the list provided. * Breaks up the input character stream into tokens and puts them into the list provided
* Ignores # as a line comment * Ignores # as a line comment
*
* @param input
* @param tokens
*/ */
void Config::Tokenize(FILE *input, std::list<std::string> &tokens) void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
{ {
auto c = fgetc(input); auto c = fgetc(input);
std::string lexeme; std::string lexeme;
while(c != EOF) while (c != EOF) {
{ if (isspace(c)) {
if(isspace(c)) if (lexeme.size() > 0) {
{
if(lexeme.size() > 0)
{
tokens.push_back(lexeme); tokens.push_back(lexeme);
lexeme.clear(); lexeme.clear();
} }
@ -159,35 +150,28 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
continue; continue;
} }
if(isalnum(c)) if (isalnum(c)) {
{
lexeme += c; lexeme += c;
c = fgetc(input); c = fgetc(input);
continue; continue;
} }
switch(c) switch (c) {
{ case '#': {
case '#': if (lexeme.size() > 0) {
{
if(lexeme.size() > 0)
{
tokens.push_back(lexeme); tokens.push_back(lexeme);
lexeme.clear(); lexeme.clear();
} }
while(c != '\n' && c != EOF) while (c != '\n' && c != EOF) {
{
c = fgetc(input); c = fgetc(input);
} }
break; break;
} }
case '[': case '[':
case ']': case ']':
case '=': case '=': {
{ if (lexeme.size() > 0) {
if(lexeme.size() > 0)
{
tokens.push_back(lexeme); tokens.push_back(lexeme);
lexeme.clear(); lexeme.clear();
} }
@ -197,8 +181,7 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
lexeme.clear(); lexeme.clear();
break; break;
} }
default: default: {
{
lexeme += c; lexeme += c;
} }
} }
@ -206,8 +189,7 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
c = fgetc(input); c = fgetc(input);
} }
if(lexeme.size() > 0) if (lexeme.size() > 0) {
{
tokens.push_back(lexeme); 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_CONFIG_H
#define 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_DATABASE_H
#define EQEMU_DATABASE_H #define EQEMU_DATABASE_H
@ -25,57 +28,109 @@
/** /**
* Base database class, intended to be extended. * Base database class, intended to be extended.
*/ */
class Database class Database {
{
public: public:
Database() : user(""), pass(""), host(""), port(""), name("") {} Database() : user(""), pass(""), host(""), port(""), name("") {}
virtual ~Database() {} virtual ~Database() {}
/**
* Returns true if the database successfully connected.
*/
virtual bool IsConnected() { return false; } virtual bool IsConnected() { return false; }
/** /**
* Retrieves the login data (password hash and account id) from the account name provided * Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure
* Needed for client login procedure. *
* Returns true if the record was found, false otherwise. * @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 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. * Retrieves the world registration from the long and short names provided
* Needed for world login procedure. * Needed for world login procedure
* Returns true if the record was found, false otherwise. * 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, virtual bool GetWorldRegistration(
unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password) { return false; } 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; }
/**
* Updates the ip address of the client with account id = id
*/
virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) {} virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) {}
/** /**
* Updates or creates the login server account with info from world server * 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) {} 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 * 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) {} 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; } virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { return false; }
protected: protected:

View File

@ -18,7 +18,6 @@
* *
*/ */
#include "../common/global_define.h" #include "../common/global_define.h"
#include "database.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/des.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/md5.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 #pragma once
#include <string> #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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMUCAPI__H
#define 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_LOGINSERVER_H
#define EQEMU_LOGINSERVER_H #define EQEMU_LOGINSERVER_H
@ -27,8 +30,7 @@
#include "client_manager.h" #include "client_manager.h"
/** /**
* Login server struct, contains every variable for the server that needs to exist * Login server struct, contains every variable for the server that needs to exist outside the scope of main()
* outside the scope of main().
*/ */
struct LoginServer struct LoginServer
{ {

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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_LOGINSTRUCTURES_H
#define EQEMU_LOGINSTRUCTURES_H #define EQEMU_LOGINSTRUCTURES_H
@ -47,8 +50,7 @@ struct LoginAccepted_Struct {
char encrypt[80]; char encrypt[80];
}; };
struct LoginFailedAttempts_Struct struct LoginFailedAttempts_Struct {
{
char message; //0x01 char message; //0x01
char unknown2[7]; //0x00 char unknown2[7]; //0x00
uint32 lsid; uint32 lsid;
@ -86,8 +88,7 @@ struct ServerListHeader_Struct {
uint32 NumberOfServers; uint32 NumberOfServers;
}; };
struct PlayEverquestRequest_Struct struct PlayEverquestRequest_Struct {
{
uint16 Sequence; uint16 Sequence;
uint32 Unknown1; uint32 Unknown1;
uint32 Unknown2; uint32 Unknown2;
@ -106,7 +107,8 @@ struct PlayEverquestResponse_Struct {
static const unsigned char FailedLoginResponseData[] = { static const unsigned char FailedLoginResponseData[] = {
0xf6, 0x85, 0x9c, 0x23, 0x57, 0x7e, 0x3e, 0x55, 0xb3, 0x4c, 0xf8, 0xc8, 0xcb, 0x77, 0xd5, 0x16, 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, 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() #pragma pack()

View File

@ -80,11 +80,13 @@ int main()
) )
); );
#ifdef ENABLE_SECURITY #ifdef ENABLE_SECURITY
server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 13)); server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 13));
#else #else
server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 6)); server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 6));
#endif #endif
server.options.AllowUnregistered(server.config.GetVariableBool("security", "unregistered_allowed", true)); server.options.AllowUnregistered(server.config.GetVariableBool("security", "unregistered_allowed", true));
server.options.AllowTokenLogin(server.config.GetVariableBool("security", "allow_token_login", false)); server.options.AllowTokenLogin(server.config.GetVariableBool("security", "allow_token_login", false));
server.options.AllowPasswordLogin(server.config.GetVariableBool("security", "allow_password_login", true)); server.options.AllowPasswordLogin(server.config.GetVariableBool("security", "allow_password_login", true));
@ -93,33 +95,36 @@ int main()
"security", "security",
"update_insecure_passwords", "update_insecure_passwords",
true true
)); )
);
server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts")); server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts"));
server.options.WorldRegistrationTable( server.options.WorldRegistrationTable(
server.config.GetVariableString( server.config.GetVariableString(
"schema", "schema",
"world_registration_table", "world_registration_table",
"tblWorldServerRegistration" "tblWorldServerRegistration"
)); )
);
server.options.WorldAdminRegistrationTable( server.options.WorldAdminRegistrationTable(
server.config.GetVariableString( server.config.GetVariableString(
"schema", "schema",
"world_admin_registration_table", "world_admin_registration_table",
"tblServerAdminRegistration" "tblServerAdminRegistration"
)); )
);
server.options.WorldServerTypeTable( server.options.WorldServerTypeTable(
server.config.GetVariableString( server.config.GetVariableString(
"schema", "schema",
"world_server_type_table", "world_server_type_table",
"tblServerListType" "tblServerListType"
)); )
);
/** /**
* mysql connect * mysql connect
*/ */
if (server.config.GetVariableString("database", "subsystem", "MySQL").compare("MySQL") == 0) {
Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); Log(Logs::General, Logs::Login_Server, "MySQL Database Init.");
server.db = (Database *) new DatabaseMySQL( server.db = (Database *) new DatabaseMySQL(
server.config.GetVariableString("database", "user", "root"), server.config.GetVariableString("database", "user", "root"),
server.config.GetVariableString("database", "password", ""), server.config.GetVariableString("database", "password", ""),
@ -127,10 +132,10 @@ int main()
server.config.GetVariableString("database", "port", "3306"), server.config.GetVariableString("database", "port", "3306"),
server.config.GetVariableString("database", "db", "peq") 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) { if (!server.db) {
Log(Logs::General, Logs::Error, "Database Initialization Failure."); Log(Logs::General, Logs::Error, "Database Initialization Failure.");
@ -143,7 +148,7 @@ int main()
*/ */
Log(Logs::General, Logs::Login_Server, "Server Manager Initialize."); Log(Logs::General, Logs::Login_Server, "Server Manager Initialize.");
server.server_manager = new ServerManager(); server.server_manager = new ServerManager();
if (!server.server_manager) if (!server.server_manager) {
Log(Logs::General, Logs::Error, "Server Manager Failed to Start."); Log(Logs::General, Logs::Error, "Server Manager Failed to Start.");
Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); Log(Logs::General, Logs::Login_Server, "Database System Shutdown.");
delete server.db; 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_OPTIONS_H
#define EQEMU_OPTIONS_H #define EQEMU_OPTIONS_H
@ -22,11 +25,11 @@
* Collects options on one object, because having a bunch of global variables floating around is * Collects options on one object, because having a bunch of global variables floating around is
* really ugly and just a little dangerous. * really ugly and just a little dangerous.
*/ */
class Options class Options {
{
public: public:
/** /**
* Constructor, sets the default options. * Constructor: Default options
*/ */
Options() : Options() :
allow_unregistered(true), allow_unregistered(true),

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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "server_manager.h"
#include "login_server.h" #include "login_server.h"
#include "login_structures.h" #include "login_structures.h"
@ -36,15 +39,23 @@ ServerManager::ServerManager()
opts.ipv6 = false; opts.ipv6 = false;
server_connection->Listen(opts); server_connection->Listen(opts);
server_connection->OnConnectionIdentified("World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) { server_connection->OnConnectionIdentified(
LogF(Logs::General, Logs::Login_Server, "New world server connection from {0}:{1}", c->Handle()->RemoteIP(), c->Handle()->RemotePort()); "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(); auto iter = world_servers.begin();
while (iter != world_servers.end()) { while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 && if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 &&
(*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) { (*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) {
LogF(Logs::General, Logs::Login_Server, "World server already existed for {0}:{1}, removing existing connection.", LogF(Logs::General,
c->Handle()->RemoteIP(), c->Handle()->RemotePort()); Logs::Login_Server,
"World server already existed for {0}:{1}, removing existing connection.",
c->Handle()->RemoteIP(),
c->Handle()->RemotePort());
world_servers.erase(iter); world_servers.erase(iter);
break; break;
@ -54,20 +65,26 @@ ServerManager::ServerManager()
} }
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) { server_connection->OnConnectionRemoved(
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
auto iter = world_servers.begin(); auto iter = world_servers.begin();
while (iter != world_servers.end()) { while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) { if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) {
LogF(Logs::General, Logs::World_Server, "World server {0} has been disconnected, removing.", (*iter)->GetLongName().c_str()); LogF(Logs::General,
Logs::World_Server,
"World server {0} has been disconnected, removing.",
(*iter)->GetLongName().c_str());
world_servers.erase(iter); world_servers.erase(iter);
return; return;
} }
++iter; ++iter;
} }
}); }
);
} }
ServerManager::~ServerManager() ServerManager::~ServerManager()
@ -79,7 +96,8 @@ WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port
{ {
auto iter = world_servers.begin(); auto iter = world_servers.begin();
while (iter != world_servers.end()) { while (iter != world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr && (*iter)->GetConnection()->Handle()->RemotePort()) { if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr &&
(*iter)->GetConnection()->Handle()->RemotePort()) {
return (*iter).get(); return (*iter).get();
} }
++iter; ++iter;
@ -207,7 +225,11 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
return outapp; 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; bool found = false;
@ -230,7 +252,10 @@ void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int
} }
if (!found && server.options.IsTraceOn()) { 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_SERVERMANAGER_H
#define EQEMU_SERVERMANAGER_H #define EQEMU_SERVERMANAGER_H
@ -27,13 +30,13 @@
#include <list> #include <list>
/** /**
* Server manager class, deals with management of the world servers. * Server manager class, deals with management of the world servers
*/ */
class ServerManager class ServerManager {
{
public: public:
/** /**
* Constructor, sets up the TCP server and starts listening. * Constructor, sets up the TCP server and starts listening
*/ */
ServerManager(); ServerManager();
@ -43,29 +46,55 @@ public:
~ServerManager(); ~ServerManager();
/** /**
* Sends a request to world to see if the client is banned or suspended. * 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); 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); 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); 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); void DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore = nullptr);
private: private:
/** /**
* Retrieves a server(if exists) by ip address * Retrieves a server(if exists) by ip address
* Useful utility for the reconnect process. * Useful utility for the reconnect process
*
* @param address
* @param port
* @return
*/ */
WorldServer *GetServerByAddress(const std::string &address, int port); WorldServer *GetServerByAddress(const std::string &address, int port);

View File

@ -1,25 +1,27 @@
/* 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "world_server.h"
#include "login_server.h" #include "login_server.h"
#include "login_structures.h" #include "login_structures.h"
#include "config.h" #include "config.h"
#include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys.h"
extern LoginServer server; extern LoginServer server;
@ -37,11 +39,35 @@ WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
is_server_trusted = false; is_server_trusted = false;
is_server_logged_in = false; is_server_logged_in = false;
c->OnMessage(ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2)); c->OnMessage(
c->OnMessage(ServerOP_LSStatus, std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2)); ServerOP_NewLSInfo,
c->OnMessage(ServerOP_UsertoWorldRespLeg, std::bind(&WorldServer::ProcessUsertoWorldRespLeg, this, std::placeholders::_1, std::placeholders::_2)); std::bind(&WorldServer::ProcessNewLSInfo, 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_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() WorldServer::~WorldServer()
@ -63,26 +89,27 @@ void WorldServer::Reset()
void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p)
{ {
if (server.options.IsWorldTraceOn()) if (server.options.IsWorldTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); 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); DumpPacket(opcode, p);
} }
if (p.Length() < sizeof(ServerNewLSInfo_Struct)) if (p.Length() < sizeof(ServerNewLSInfo_Struct)) {
{ Log(Logs::General, Logs::Error,
Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, " "Received application packet from server that had opcode ServerOP_NewLSInfo, "
"but was too small. Discarded to avoid buffer overrun."); "but was too small. Discarded to avoid buffer overrun.");
return; return;
} }
if (server.options.IsWorldTraceOn()) if (server.options.IsWorldTraceOn()) {
{ Log(Logs::General, Logs::Netcode, "New Login Info Received.");
Log(Logs::General, Logs::Netcode, "New Login Info Recieved.");
} }
ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) p.Data(); ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) p.Data();
@ -91,26 +118,27 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p)
void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p)
{ {
if (server.options.IsWorldTraceOn()) if (server.options.IsWorldTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); 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); DumpPacket(opcode, p);
} }
if (p.Length() < sizeof(ServerLSStatus_Struct)) if (p.Length() < sizeof(ServerLSStatus_Struct)) {
{ Log(Logs::General,
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_LSStatus, " Logs::Error,
"but was too small. Discarded to avoid buffer overrun."); "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun");
return; return;
} }
if (server.options.IsWorldTraceOn()) if (server.options.IsWorldTraceOn()) {
{ Log(Logs::General, Logs::Netcode, "World Server Status Received.");
Log(Logs::General, Logs::Netcode, "World Server Status Recieved.");
} }
ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) p.Data(); ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) p.Data();
@ -119,19 +147,22 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p)
void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p) void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p)
{ {
if (server.options.IsWorldTraceOn()) if (server.options.IsWorldTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); 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); DumpPacket(opcode, p);
} }
if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) {
{ Log(Logs::General,
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " Logs::Error,
"Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
"but was too small. Discarded to avoid buffer overrun."); "but was too small. Discarded to avoid buffer overrun.");
return; return;
} }
@ -139,18 +170,22 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
//I don't use world trace for this and here is why: //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 //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. //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."); 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); 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"); Client *c = server.client_manager->GetClient(utwr->lsaccountid, "eqemu");
if (c) if (c) {
{ Log(Logs::General,
Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); Logs::Debug,
EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); "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; PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
per->Sequence = c->GetPlaySequence(); per->Sequence = c->GetPlaySequence();
per->ServerNumber = c->GetPlayServerID(); per->ServerNumber = c->GetPlayServerID();
@ -158,14 +193,17 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
if (utwr->response > 0) if (utwr->response > 0) {
{
per->Allowed = 1; 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) switch (utwr->response) {
{
case 1: case 1:
per->Message = 101; per->Message = 101;
break; break;
@ -183,42 +221,50 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
break; break;
} }
if (server.options.IsTraceOn()) if (server.options.IsTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", Logs::Netcode,
per->Allowed, per->Sequence, per->ServerNumber, per->Message); "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()); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
} }
if (server.options.IsDumpOutPacketsOn()) if (server.options.IsDumpOutPacketsOn()) {
{
DumpPacket(outapp); DumpPacket(outapp);
} }
c->SendPlayResponse(outapp); c->SendPlayResponse(outapp);
delete outapp; delete outapp;
} }
else else {
{ Log(Logs::General,
Log(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); 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) void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p)
{ {
if (server.options.IsWorldTraceOn()) if (server.options.IsWorldTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); 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); DumpPacket(opcode, p);
} }
if (p.Length() < sizeof(UsertoWorldResponse_Struct)) if (p.Length() < sizeof(UsertoWorldResponse_Struct)) {
{ Log(Logs::General,
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " Logs::Error,
"Received application packet from server that had opcode ServerOP_UsertoWorldResp, "
"but was too small. Discarded to avoid buffer overrun."); "but was too small. Discarded to avoid buffer overrun.");
return; return;
} }
@ -226,18 +272,22 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet
//I don't use world trace for this and here is why: //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 //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. //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."); 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); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid);
Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login); Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login);
if (c) if (c) {
{ Log(Logs::General,
Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); Logs::Debug,
EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); "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; PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
per->Sequence = c->GetPlaySequence(); per->Sequence = c->GetPlaySequence();
per->ServerNumber = c->GetPlayServerID(); per->ServerNumber = c->GetPlayServerID();
@ -245,14 +295,17 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet
Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
if (utwr->response > 0) if (utwr->response > 0) {
{
per->Allowed = 1; 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) switch (utwr->response) {
{
case 1: case 1:
per->Message = 101; per->Message = 101;
break; break;
@ -270,50 +323,61 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet
break; break;
} }
if (server.options.IsTraceOn()) if (server.options.IsTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", Logs::Netcode,
per->Allowed, per->Sequence, per->ServerNumber, per->Message); "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()); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
} }
if (server.options.IsDumpOutPacketsOn()) if (server.options.IsDumpOutPacketsOn()) {
{
DumpPacket(outapp); DumpPacket(outapp);
} }
c->SendPlayResponse(outapp); c->SendPlayResponse(outapp);
delete outapp; delete outapp;
} }
else else {
{ Log(Logs::General,
Log(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); 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) void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p)
{ {
if (server.options.IsWorldTraceOn()) if (server.options.IsWorldTraceOn()) {
{ Log(Logs::General,
Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); 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); DumpPacket(opcode, p);
} }
if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) {
{ Log(Logs::General,
Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerLSAccountUpdate_Struct, " Logs::Error,
"Received application packet from server that had opcode ServerLSAccountUpdate_Struct, "
"but was too small. Discarded to avoid buffer overrun."); "but was too small. Discarded to avoid buffer overrun.");
return; return;
} }
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str());
ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) p.Data(); ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) p.Data();
if (is_server_trusted) if (is_server_trusted) {
{
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount);
std::string name; std::string name;
std::string password; std::string password;
@ -327,104 +391,91 @@ 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) if (is_server_logged_in) {
{ Log(Logs::General,
Log(Logs::General, Logs::Error, "WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); Logs::Error,
"WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting.");
return; return;
} }
if (strlen(i->account) <= 30) if (strlen(i->account) <= 30) {
{
account_name = i->account; account_name = i->account;
} }
else else {
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account name was too long."); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account name was too long.");
return; return;
} }
if (strlen(i->password) <= 30) if (strlen(i->password) <= 30) {
{
account_password = i->password; account_password = i->password;
} }
else else {
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account password was too long."); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account password was too long.");
return; return;
} }
if (strlen(i->name) <= 200) if (strlen(i->name) <= 200) {
{
long_name = i->name; long_name = i->name;
} }
else else {
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, long name was too long."); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, long name was too long.");
return; return;
} }
if (strlen(i->shortname) <= 50) if (strlen(i->shortname) <= 50) {
{
short_name = i->shortname; short_name = i->shortname;
} }
else else {
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, short name was too long."); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, short name was too long.");
return; return;
} }
if (strlen(i->local_address) <= 125) if (strlen(i->local_address) <= 125) {
{ if (strlen(i->local_address) == 0) {
if (strlen(i->local_address) == 0)
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was null, defaulting to localhost"); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was null, defaulting to localhost");
local_ip = "127.0.0.1"; local_ip = "127.0.0.1";
} }
else else {
{
local_ip = i->local_address; local_ip = i->local_address;
} }
} }
else else {
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was too long."); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was too long.");
return; return;
} }
if (strlen(i->remote_address) <= 125) if (strlen(i->remote_address) <= 125) {
{ if (strlen(i->remote_address) == 0) {
if (strlen(i->remote_address) == 0)
{
remote_ip = GetConnection()->Handle()->RemoteIP(); 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; remote_ip = i->remote_address;
} }
} }
else else {
{
remote_ip = GetConnection()->Handle()->RemoteIP(); 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; version = i->serverversion;
} }
else else {
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, server version was too long."); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, server version was too long.");
return; return;
} }
if (strlen(i->protocolversion) <= 25) if (strlen(i->protocolversion) <= 25) {
{
protocol = i->protocolversion; protocol = i->protocolversion;
} }
else else {
{
Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, protocol version was too long."); Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, protocol version was too long.");
return; return;
} }
@ -432,27 +483,25 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
server_type = i->servertype; server_type = i->servertype;
is_server_logged_in = true; is_server_logged_in = true;
if (server.options.IsRejectingDuplicateServers()) if (server.options.IsRejectingDuplicateServers()) {
{ if (server.server_manager->ServerExists(long_name, short_name, this)) {
if (server.server_manager->ServerExists(long_name, short_name, this)) Log(Logs::General,
{ Logs::Error,
Log(Logs::General, Logs::Error, "World tried to login but there already exists a server that has that name."); "World tried to login but there already exists a server that has that name.");
return; return;
} }
} }
else else {
{ if (server.server_manager->ServerExists(long_name, short_name, this)) {
if (server.server_manager->ServerExists(long_name, short_name, this)) Log(Logs::General,
{ Logs::Error,
Log(Logs::General, Logs::Error, "World tried to login but there already exists a server that has that name."); "World tried to login but there already exists a server that has that name.");
server.server_manager->DestroyServerByName(long_name, short_name, this); server.server_manager->DestroyServerByName(long_name, short_name, this);
} }
} }
if (!server.options.IsUnregisteredAllowed()) if (!server.options.IsUnregisteredAllowed()) {
{ if (account_name.size() > 0 && account_password.size() > 0) {
if (account_name.size() > 0 && account_password.size() > 0)
{
unsigned int s_id = 0; unsigned int s_id = 0;
unsigned int s_list_type = 0; unsigned int s_list_type = 0;
unsigned int s_trusted = 0; unsigned int s_trusted = 0;
@ -460,19 +509,29 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
std::string s_list_desc; std::string s_list_desc;
std::string s_acct_name; std::string s_acct_name;
std::string s_acct_pass; 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 (server.db->GetWorldRegistration(
{ long_name,
if (s_acct_name.size() == 0 || s_acct_pass.size() == 0) short_name,
{ s_id,
Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged into account that had no user/password requirement.", s_desc,
long_name.c_str(), short_name.c_str()); 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; is_server_authorized = true;
SetRuntimeID(s_id); SetRuntimeID(s_id);
server_list_id = s_list_type; 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.", Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.",
long_name.c_str(), short_name.c_str()); long_name.c_str(), short_name.c_str());
is_server_authorized = true; is_server_authorized = true;
@ -488,20 +547,30 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
} }
} }
else { 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" Log(Logs::General,
" registered servers are allowed.", long_name.c_str(), short_name.c_str()); 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; return;
} }
} }
else { 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.", Log(Logs::General,
long_name.c_str(), short_name.c_str()); 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; return;
} }
} }
else { else {
Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but only registered servers are allowed.", Log(Logs::General,
long_name.c_str(), short_name.c_str()); 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; return;
} }
} }
@ -524,11 +593,12 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
is_server_trusted, is_server_trusted,
server_list_description, server_list_description,
server_account_name, server_account_name,
server_account_password)) server_account_password
{ )) {
if (account_name.size() > 0 && account_password.size() > 0) { 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.", Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.",
long_name.c_str(), short_name.c_str()); long_name.c_str(), short_name.c_str());
is_server_authorized = true; is_server_authorized = true;
@ -543,31 +613,50 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
connection->Send(ServerOP_LSAccountUpdate, outapp); connection->Send(ServerOP_LSAccountUpdate, outapp);
} }
} }
/**
* this is the first of two cases where we should deny access even if unregistered is allowed
*/
else { else {
// this is the first of two cases where we should deny access even if unregistered is allowed Log(Logs::General,
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.", Logs::World_Server,
long_name.c_str(), short_name.c_str()); "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 { 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) { 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,
Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but this server requires a password.", Logs::World_Server,
long_name.c_str(), short_name.c_str()); "Server %s(%s) did not attempt to log in but this server requires a password.",
long_name.c_str(),
short_name.c_str());
} }
else { else {
Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but unregistered servers are allowed.", Log(Logs::General,
long_name.c_str(), short_name.c_str()); 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; is_server_authorized = true;
SetRuntimeID(server_id); SetRuntimeID(server_id);
server_list_id = 3; server_list_id = 3;
} }
} }
} }
else else {
{ Log(Logs::General,
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.", Logs::World_Server,
long_name.c_str(), short_name.c_str()); "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)) { if (server.db->CreateWorldRegistration(long_name, short_name, server_id)) {
is_server_authorized = true; is_server_authorized = true;
SetRuntimeID(server_id); SetRuntimeID(server_id);
@ -579,6 +668,9 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
server.db->UpdateWorldRegistration(GetRuntimeID(), long_name, GetConnection()->Handle()->RemoteIP()); server.db->UpdateWorldRegistration(GetRuntimeID(), long_name, GetConnection()->Handle()->RemoteIP());
} }
/**
* @param s
*/
void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s)
{ {
players_online = s->num_players; players_online = s->num_players;
@ -586,7 +678,20 @@ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s)
server_status = s->status; 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; EQ::Net::DynamicPacket outapp;
ClientAuth_Struct client_auth; ClientAuth_Struct client_auth;
@ -614,8 +719,7 @@ void WorldServer::SendClientAuth(std::string ip, std::string account, std::strin
outapp.PutSerialize(0, client_auth); outapp.PutSerialize(0, client_auth);
connection->Send(ServerOP_LSClientAuth, outapp); connection->Send(ServerOP_LSClientAuth, outapp);
if (server.options.IsDumpInPacketsOn()) if (server.options.IsDumpInPacketsOn()) {
{
DumpPacket(ServerOP_LSClientAuth, outapp); 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 * This program is free software; you can redistribute it and/or modify
the Free Software Foundation; version 2 of the License. * 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 * This program is distributed in the hope that it will be useful,
are required to give you total support for your newly bought product; * but WITHOUT ANY WARRANTY except by those people which sell it, which
without even the implied warranty of MERCHANTABILITY or FITNESS FOR * are required to give you total support for your newly bought product;
A PARTICULAR PURPOSE. See the GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef EQEMU_WORLDSERVER_H
#define EQEMU_WORLDSERVER_H #define EQEMU_WORLDSERVER_H
@ -31,13 +34,10 @@
class WorldServer class WorldServer
{ {
public: public:
/**
* Constructor, sets our connection to c.
*/
WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c); WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c);
/** /**
* Destructor, frees our connection if it exists. * Destructor, frees our connection if it exists
*/ */
~WorldServer(); ~WorldServer();
@ -50,86 +50,62 @@ public:
* Accesses connection, it is intentional that this is not const (trust me). * Accesses connection, it is intentional that this is not const (trust me).
*/ */
std::shared_ptr<EQ::Net::ServertalkServerConnection> GetConnection() { return connection; } 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; } 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; } unsigned int GetRuntimeID() const { return runtime_id; }
/**
* Sets the runtime id of this server.
*/
void SetRuntimeID(unsigned int id) { runtime_id = id; } void SetRuntimeID(unsigned int id) { runtime_id = id; }
/**
* Gets the long name of the server.
*/
std::string GetLongName() const { return long_name; } std::string GetLongName() const { return long_name; }
/**
* Gets the short name of the server.
*/
std::string GetShortName() const { return short_name; } 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; } bool IsAuthorized() const { return is_server_authorized; }
/**
* Gets the local ip of the server.
*/
std::string GetLocalIP() const { return local_ip; } std::string GetLocalIP() const { return local_ip; }
/**
* Gets the remote ip of the server.
*/
std::string GetRemoteIP() const { return remote_ip; } 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; } unsigned int GetServerListID() const { return server_list_id; }
/**
* Gets the status of the server.
*/
int GetStatus() const { return server_status; } int GetStatus() const { return server_status; }
/**
* Gets the number of zones online on the server.
*/
unsigned int GetZonesBooted() const { return zones_booted; } unsigned int GetZonesBooted() const { return zones_booted; }
/**
* Gets the number of players on the server.
*/
unsigned int GetPlayersOnline() const { return players_online; } 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); 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); 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); void SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name);
private: private:
/** /**
* Packet processing functions: * Packet processing functions
*
* @param opcode
* @param p
*/ */
void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p); void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p);
void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p); void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p);