mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-03 11:12:25 +00:00
Tons of cleanup / formatting
This commit is contained in:
parent
9e0f440106
commit
217c9751a8
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "login_server.h"
|
#include "login_server.h"
|
||||||
#include "../common/misc_functions.h"
|
#include "../common/misc_functions.h"
|
||||||
@ -25,28 +28,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
extern LoginServer server;
|
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;
|
||||||
version = v;
|
version = v;
|
||||||
status = cs_not_sent_session_ready;
|
status = cs_not_sent_session_ready;
|
||||||
account_id = 0;
|
account_id = 0;
|
||||||
play_server_id = 0;
|
play_server_id = 0;
|
||||||
play_sequence_id = 0;
|
play_sequence_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,67 +60,56 @@ bool Client::Process()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (app->GetOpcode())
|
switch (app->GetOpcode()) {
|
||||||
{
|
case OP_SessionReady: {
|
||||||
case OP_SessionReady:
|
if (server.options.IsTraceOn()) {
|
||||||
{
|
Log(Logs::General, Logs::Login_Server, "Session ready received from client.");
|
||||||
if (server.options.IsTraceOn())
|
}
|
||||||
{
|
Handle_SessionReady((const char *) app->pBuffer, app->Size());
|
||||||
Log(Logs::General, Logs::Login_Server, "Session ready received from client.");
|
|
||||||
}
|
|
||||||
Handle_SessionReady((const char*)app->pBuffer, app->Size());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case OP_Login:
|
|
||||||
{
|
|
||||||
if (app->Size() < 20)
|
|
||||||
{
|
|
||||||
Log(Logs::General, Logs::Error, "Login received but it is too small, discarding.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_Login: {
|
||||||
|
if (app->Size() < 20) {
|
||||||
|
Log(Logs::General, Logs::Error, "Login received but it is too small, discarding.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (server.options.IsTraceOn())
|
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;
|
|
||||||
}
|
|
||||||
case OP_ServerListRequest:
|
|
||||||
{
|
|
||||||
if (app->Size() < 4) {
|
|
||||||
Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_ServerListRequest: {
|
||||||
|
if (app->Size() < 4) {
|
||||||
|
Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (server.options.IsTraceOn())
|
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;
|
|
||||||
}
|
|
||||||
case OP_PlayEverquestRequest:
|
|
||||||
{
|
|
||||||
if (app->Size() < sizeof(PlayEverquestRequest_Struct))
|
|
||||||
{
|
|
||||||
Log(Logs::General, Logs::Error, "Play received but it is too small, discarding.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_PlayEverquestRequest: {
|
||||||
|
if (app->Size() < sizeof(PlayEverquestRequest_Struct)) {
|
||||||
|
Log(Logs::General, Logs::Error, "Play received but it is too small, discarding.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Handle_Play((const char*)app->pBuffer);
|
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);
|
Log(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump);
|
||||||
Log(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete app;
|
delete app;
|
||||||
@ -126,16 +119,20 @@ bool Client::Process()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_SessionReady(const char* data, unsigned int size)
|
/**
|
||||||
|
* Sends our reply to session ready packet
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
void Client::Handle_SessionReady(const char *data, unsigned int size)
|
||||||
{
|
{
|
||||||
if (status != cs_not_sent_session_ready)
|
if (status != cs_not_sent_session_ready) {
|
||||||
{
|
|
||||||
Log(Logs::General, Logs::Error, "Session ready received again after already being received.");
|
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,32 +142,28 @@ void Client::Handle_SessionReady(const char* data, unsigned int size)
|
|||||||
/**
|
/**
|
||||||
* The packets are mostly the same but slightly different between the two versions.
|
* 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;
|
||||||
outapp->pBuffer[10] = 0x01;
|
outapp->pBuffer[10] = 0x01;
|
||||||
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,7 +172,13 @@ void Client::Handle_SessionReady(const char* data, unsigned int size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_Login(const char* data, unsigned int size)
|
/**
|
||||||
|
* Verifies login and send a reply
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
void Client::Handle_Login(const char *data, unsigned int size)
|
||||||
{
|
{
|
||||||
if (status != cs_waiting_for_login) {
|
if (status != cs_waiting_for_login) {
|
||||||
Log(Logs::General, Logs::Error, "Login received after already having logged in.");
|
Log(Logs::General, Logs::Error, "Login received after already having logged in.");
|
||||||
@ -187,20 +186,26 @@ void Client::Handle_Login(const char* data, unsigned int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((size - 12) % 8 != 0) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *login_packet_buffer = nullptr;
|
char *login_packet_buffer = nullptr;
|
||||||
|
|
||||||
unsigned int db_account_id = 0;
|
unsigned int db_account_id = 0;
|
||||||
std::string db_loginserver = "eqemu";
|
std::string db_loginserver = "eqemu";
|
||||||
std::string db_account_password_hash;
|
std::string db_account_password_hash;
|
||||||
|
|
||||||
std::string outbuffer;
|
std::string outbuffer;
|
||||||
outbuffer.resize(size - 12);
|
outbuffer.resize(size - 12);
|
||||||
@ -228,22 +233,29 @@ void Client::Handle_Login(const char* data, unsigned int size)
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
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 {
|
||||||
if (server.options.IsPasswordLoginAllowed()) {
|
if (server.options.IsPasswordLoginAllowed()) {
|
||||||
cred = (&outbuffer[1 + user.length()]);
|
cred = (&outbuffer[1 + user.length()]);
|
||||||
auto components = SplitString(user, '.');
|
auto components = SplitString(user, '.');
|
||||||
if (components.size() == 2) {
|
if (components.size() == 2) {
|
||||||
db_loginserver = components[0];
|
db_loginserver = components[0];
|
||||||
user = components[1];
|
user = components[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
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,35 +275,44 @@ void Client::Handle_Login(const char* data, unsigned int size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Handle_Play(const char* data)
|
/**
|
||||||
|
* Sends a packet to the requested server to see if the client is allowed or not
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
void Client::Handle_Play(const char *data)
|
||||||
{
|
{
|
||||||
if (status != cs_logged_in)
|
if (status != cs_logged_in) {
|
||||||
{
|
|
||||||
Log(Logs::General, Logs::Error, "Client sent a play request when they were not logged in, discarding.");
|
Log(Logs::General, Logs::Error, "Client sent a play request when they were not logged in, discarding.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlayEverquestRequest_Struct *play = (const PlayEverquestRequest_Struct*)data;
|
const PlayEverquestRequest_Struct *play = (const PlayEverquestRequest_Struct *) 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;
|
||||||
play_sequence_id = sequence_in;
|
play_sequence_id = sequence_in;
|
||||||
play_server_id = server_id_in;
|
play_server_id = server_id_in;
|
||||||
server.server_manager->SendUserToWorldRequest(server_id_in, account_id, loginserver_name);
|
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,23 +333,26 @@ 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',
|
||||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||||
'Y', 'Z', '0', '1', '2', '3', '4', '5',
|
'Y', 'Z', '0', '1', '2', '3', '4', '5',
|
||||||
'6', '7', '8', '9'
|
'6', '7', '8', '9'
|
||||||
};
|
};
|
||||||
|
|
||||||
key.append((const char*)&key_selection[random.Int(0, 35)], 1);
|
key.append((const char *) &key_selection[random.Int(0, 35)], 1);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver)
|
void Client::AttemptLoginAccountCreation(
|
||||||
|
const std::string &user,
|
||||||
|
const std::string &pass,
|
||||||
|
const std::string &loginserver
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (loginserver == "eqemu") {
|
if (loginserver == "eqemu") {
|
||||||
if (!server.options.CanAutoLinkAccounts()) {
|
if (!server.options.CanAutoLinkAccounts()) {
|
||||||
@ -341,7 +364,7 @@ void Client::AttemptLoginAccountCreation(const std::string &user, const std::str
|
|||||||
DoFailedLogin();
|
DoFailedLogin();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto addr_components = SplitString(server.options.GetEQEmuLoginServerAddress(), ':');
|
auto addr_components = SplitString(server.options.GetEQEmuLoginServerAddress(), ':');
|
||||||
if (addr_components.size() != 2) {
|
if (addr_components.size() != 2) {
|
||||||
DoFailedLogin();
|
DoFailedLogin();
|
||||||
@ -350,22 +373,42 @@ void Client::AttemptLoginAccountCreation(const std::string &user, const std::str
|
|||||||
|
|
||||||
stored_user = user;
|
stored_user = user;
|
||||||
stored_pass = pass;
|
stored_pass = pass;
|
||||||
|
|
||||||
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(
|
||||||
if (addr.empty()) {
|
address, port, false, [=](const std::string &addr) {
|
||||||
DoFailedLogin();
|
if (addr.empty()) {
|
||||||
return;
|
DoFailedLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||||
|
login_connection_manager->OnNewConnection(
|
||||||
|
std::bind(
|
||||||
|
&Client::LoginOnNewConnection,
|
||||||
|
this,
|
||||||
|
std::placeholders::_1
|
||||||
|
));
|
||||||
|
login_connection_manager->OnConnectionStateChange(
|
||||||
|
std::bind(
|
||||||
|
&Client::LoginOnStatusChange,
|
||||||
|
this,
|
||||||
|
std::placeholders::_1,
|
||||||
|
std::placeholders::_2,
|
||||||
|
std::placeholders::_3
|
||||||
|
));
|
||||||
|
login_connection_manager->OnPacketRecv(
|
||||||
|
std::bind(
|
||||||
|
&Client::LoginOnPacketRecv,
|
||||||
|
this,
|
||||||
|
std::placeholders::_1,
|
||||||
|
std::placeholders::_2
|
||||||
|
));
|
||||||
|
|
||||||
|
login_connection_manager->Connect(addr, port);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
|
||||||
login_connection_manager->OnNewConnection(std::bind(&Client::LoginOnNewConnection, this, std::placeholders::_1));
|
|
||||||
login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
|
||||||
login_connection_manager->OnPacketRecv(std::bind(&Client::LoginOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
|
||||||
|
|
||||||
login_connection_manager->Connect(addr, port);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!server.options.CanAutoCreateAccounts()) {
|
if (!server.options.CanAutoCreateAccounts()) {
|
||||||
@ -382,8 +425,8 @@ void Client::DoFailedLogin()
|
|||||||
stored_user.clear();
|
stored_user.clear();
|
||||||
stored_pass.clear();
|
stored_pass.clear();
|
||||||
|
|
||||||
EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
|
EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
|
||||||
LoginLoginFailed_Struct* llas = (LoginLoginFailed_Struct *)outapp.pBuffer;
|
LoginLoginFailed_Struct *llas = (LoginLoginFailed_Struct *) outapp.pBuffer;
|
||||||
llas->unknown1 = llrs.unknown1;
|
llas->unknown1 = llrs.unknown1;
|
||||||
llas->unknown2 = llrs.unknown2;
|
llas->unknown2 = llrs.unknown2;
|
||||||
llas->unknown3 = llrs.unknown3;
|
llas->unknown3 = llrs.unknown3;
|
||||||
@ -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();
|
||||||
@ -456,43 +518,43 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const
|
|||||||
server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in)));
|
server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in)));
|
||||||
GenerateKey();
|
GenerateKey();
|
||||||
|
|
||||||
account_id = db_account_id;
|
account_id = db_account_id;
|
||||||
account_name = user;
|
account_name = user;
|
||||||
loginserver_name = db_loginserver;
|
loginserver_name = db_loginserver;
|
||||||
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80);
|
||||||
LoginAccepted_Struct* login_accepted = (LoginAccepted_Struct *)outapp->pBuffer;
|
LoginAccepted_Struct *login_accepted = (LoginAccepted_Struct *) outapp->pBuffer;
|
||||||
login_accepted->unknown1 = llrs.unknown1;
|
login_accepted->unknown1 = llrs.unknown1;
|
||||||
login_accepted->unknown2 = llrs.unknown2;
|
login_accepted->unknown2 = llrs.unknown2;
|
||||||
login_accepted->unknown3 = llrs.unknown3;
|
login_accepted->unknown3 = llrs.unknown3;
|
||||||
login_accepted->unknown4 = llrs.unknown4;
|
login_accepted->unknown4 = llrs.unknown4;
|
||||||
login_accepted->unknown5 = llrs.unknown5;
|
login_accepted->unknown5 = llrs.unknown5;
|
||||||
|
|
||||||
LoginFailedAttempts_Struct * login_failed_attempts = new LoginFailedAttempts_Struct;
|
LoginFailedAttempts_Struct *login_failed_attempts = new LoginFailedAttempts_Struct;
|
||||||
memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct));
|
memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct));
|
||||||
|
|
||||||
login_failed_attempts->failed_attempts = 0;
|
login_failed_attempts->failed_attempts = 0;
|
||||||
login_failed_attempts->message = 0x01;
|
login_failed_attempts->message = 0x01;
|
||||||
login_failed_attempts->lsid = db_account_id;
|
login_failed_attempts->lsid = db_account_id;
|
||||||
login_failed_attempts->unknown3[3] = 0x03;
|
login_failed_attempts->unknown3[3] = 0x03;
|
||||||
login_failed_attempts->unknown4[3] = 0x02;
|
login_failed_attempts->unknown4[3] = 0x02;
|
||||||
login_failed_attempts->unknown5[0] = 0xe7;
|
login_failed_attempts->unknown5[0] = 0xe7;
|
||||||
login_failed_attempts->unknown5[1] = 0x03;
|
login_failed_attempts->unknown5[1] = 0x03;
|
||||||
login_failed_attempts->unknown6[0] = 0xff;
|
login_failed_attempts->unknown6[0] = 0xff;
|
||||||
login_failed_attempts->unknown6[1] = 0xff;
|
login_failed_attempts->unknown6[1] = 0xff;
|
||||||
login_failed_attempts->unknown6[2] = 0xff;
|
login_failed_attempts->unknown6[2] = 0xff;
|
||||||
login_failed_attempts->unknown6[3] = 0xff;
|
login_failed_attempts->unknown6[3] = 0xff;
|
||||||
login_failed_attempts->unknown7[0] = 0xa0;
|
login_failed_attempts->unknown7[0] = 0xa0;
|
||||||
login_failed_attempts->unknown7[1] = 0x05;
|
login_failed_attempts->unknown7[1] = 0x05;
|
||||||
login_failed_attempts->unknown8[3] = 0x02;
|
login_failed_attempts->unknown8[3] = 0x02;
|
||||||
login_failed_attempts->unknown9[0] = 0xff;
|
login_failed_attempts->unknown9[0] = 0xff;
|
||||||
login_failed_attempts->unknown9[1] = 0x03;
|
login_failed_attempts->unknown9[1] = 0x03;
|
||||||
login_failed_attempts->unknown11[0] = 0x63;
|
login_failed_attempts->unknown11[0] = 0x63;
|
||||||
login_failed_attempts->unknown12[0] = 0x01;
|
login_failed_attempts->unknown12[0] = 0x01;
|
||||||
memcpy(login_failed_attempts->key, key.c_str(), key.size());
|
memcpy(login_failed_attempts->key, key.c_str(), key.size());
|
||||||
|
|
||||||
char encrypted_buffer[80] = { 0 };
|
char encrypted_buffer[80] = {0};
|
||||||
auto rc = eqcrypt_block((const char*)login_failed_attempts, 75, encrypted_buffer, 1);
|
auto rc = eqcrypt_block((const char *) login_failed_attempts, 75, encrypted_buffer, 1);
|
||||||
if (rc == nullptr) {
|
if (rc == nullptr) {
|
||||||
LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block");
|
LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block");
|
||||||
}
|
}
|
||||||
@ -509,13 +571,17 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const
|
|||||||
status = cs_logged_in;
|
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();
|
||||||
auto hash = eqcrypt_hash(user, pass, mode);
|
auto hash = eqcrypt_hash(user, pass, mode);
|
||||||
|
|
||||||
unsigned int db_id = 0;
|
unsigned int db_id = 0;
|
||||||
std::string db_login = server.options.GetDefaultLoginServerName();
|
std::string db_login = server.options.GetDefaultLoginServerName();
|
||||||
if (!server.db->CreateLoginData(user, hash, db_login, db_id)) {
|
if (!server.db->CreateLoginData(user, hash, db_login, db_id)) {
|
||||||
DoFailedLogin();
|
DoFailedLogin();
|
||||||
}
|
}
|
||||||
@ -524,6 +590,11 @@ void Client::CreateLocalAccount(const std::string &user, const std::string &pass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param user
|
||||||
|
* @param pass
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id)
|
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,20 +636,33 @@ void Client::LoginOnStatusChange(std::shared_ptr<EQ::Net::DaybreakConnection> co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::LoginOnStatusChangeIgnored(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
/**
|
||||||
|
* @param conn
|
||||||
|
* @param from
|
||||||
|
* @param to
|
||||||
|
*/
|
||||||
|
void Client::LoginOnStatusChangeIgnored(
|
||||||
|
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||||
|
EQ::Net::DbProtocolStatus from,
|
||||||
|
EQ::Net::DbProtocolStatus to
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
|
/**
|
||||||
|
* @param conn
|
||||||
|
* @param p
|
||||||
|
*/
|
||||||
|
void Client::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
|
||||||
{
|
{
|
||||||
auto opcode = p.GetUInt16(0);
|
auto opcode = p.GetUInt16(0);
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0x0017: //OP_ChatMessage
|
case 0x0017: //OP_ChatMessage
|
||||||
LoginSendLogin();
|
LoginSendLogin();
|
||||||
break;
|
break;
|
||||||
case 0x0018:
|
case 0x0018:
|
||||||
LoginProcessLoginResponse(p);
|
LoginProcessLoginResponse(p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,7 +677,7 @@ void Client::LoginSendSessionReady()
|
|||||||
|
|
||||||
void Client::LoginSendLogin()
|
void Client::LoginSendLogin()
|
||||||
{
|
{
|
||||||
size_t buffer_len = stored_user.length() + stored_pass.length() + 2;
|
size_t buffer_len = stored_user.length() + stored_pass.length() + 2;
|
||||||
std::unique_ptr<char[]> buffer(new char[buffer_len]);
|
std::unique_ptr<char[]> buffer(new char[buffer_len]);
|
||||||
|
|
||||||
strcpy(&buffer[0], stored_user.c_str());
|
strcpy(&buffer[0], stored_user.c_str());
|
||||||
@ -598,26 +694,33 @@ void Client::LoginSendLogin()
|
|||||||
p.PutUInt16(0, 2); //OP_Login
|
p.PutUInt16(0, 2); //OP_Login
|
||||||
p.PutUInt32(2, 3);
|
p.PutUInt32(2, 3);
|
||||||
|
|
||||||
eqcrypt_block(&buffer[0], buffer_len, (char*)p.Data() + 12, true);
|
eqcrypt_block(&buffer[0], buffer_len, (char *) p.Data() + 12, true);
|
||||||
|
|
||||||
login_connection->QueuePacket(p);
|
login_connection->QueuePacket(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::LoginProcessLoginResponse(const EQ::Net::Packet & p)
|
void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p)
|
||||||
{
|
{
|
||||||
auto encrypt_size = p.Length() - 12;
|
auto encrypt_size = p.Length() - 12;
|
||||||
if (encrypt_size % 8 > 0) {
|
if (encrypt_size % 8 > 0) {
|
||||||
encrypt_size = (encrypt_size / 8) * 8;
|
encrypt_size = (encrypt_size / 8) * 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<char[]> decrypted(new char[encrypt_size]);
|
std::unique_ptr<char[]> decrypted(new char[encrypt_size]);
|
||||||
|
|
||||||
eqcrypt_block((char*)p.Data() + 12, encrypt_size, &decrypted[0], false);
|
eqcrypt_block((char *) p.Data() + 12, encrypt_size, &decrypted[0], false);
|
||||||
|
|
||||||
EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size);
|
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();
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_CLIENT_H
|
#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,144 +44,186 @@ 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
|
||||||
*/
|
*
|
||||||
void Handle_SessionReady(const char* data, unsigned int size);
|
* @param data
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
void Handle_SessionReady(const char *data, unsigned int size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies login and send a reply.
|
* Verifies login and send a reply
|
||||||
*/
|
*
|
||||||
void Handle_Login(const char* data, unsigned int size);
|
* @param data
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
void Handle_Login(const char *data, unsigned int size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a packet to the requested server to see if the client is allowed or not.
|
* Sends a packet to the requested server to see if the client is allowed or not
|
||||||
*/
|
*
|
||||||
void Handle_Play(const char* data);
|
* @param data
|
||||||
|
*/
|
||||||
|
void Handle_Play(const char *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a server list packet to the client.
|
* Sends a server list packet to the client
|
||||||
*/
|
*
|
||||||
|
* @param seq
|
||||||
|
*/
|
||||||
void SendServerListPacket(uint32 seq);
|
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does a failed login
|
* Does a failed login
|
||||||
*/
|
*/
|
||||||
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
|
||||||
*/
|
*
|
||||||
bool VerifyLoginHash(const std::string &user, const std::string &loginserver, const std::string &cred, const std::string &hash);
|
* @param user
|
||||||
|
* @param loginserver
|
||||||
|
* @param cred
|
||||||
|
* @param hash
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool VerifyLoginHash(
|
||||||
|
const std::string &user,
|
||||||
|
const std::string &loginserver,
|
||||||
|
const std::string &cred,
|
||||||
|
const std::string &hash
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* Does a successful login
|
|
||||||
*/
|
|
||||||
void DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver);
|
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:
|
||||||
EQEmu::Random random;
|
EQEmu::Random random;
|
||||||
std::shared_ptr<EQStreamInterface> connection;
|
std::shared_ptr<EQStreamInterface> connection;
|
||||||
LSClientVersion version;
|
LSClientVersion version;
|
||||||
LSClientStatus status;
|
LSClientStatus status;
|
||||||
|
|
||||||
std::string account_name;
|
std::string account_name;
|
||||||
unsigned int account_id;
|
unsigned int account_id;
|
||||||
std::string loginserver_name;
|
std::string loginserver_name;
|
||||||
unsigned int play_server_id;
|
unsigned int play_server_id;
|
||||||
unsigned int play_sequence_id;
|
unsigned int play_sequence_id;
|
||||||
std::string key;
|
std::string key;
|
||||||
|
|
||||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> login_connection_manager;
|
std::unique_ptr<EQ::Net::DaybreakConnectionManager> login_connection_manager;
|
||||||
std::shared_ptr<EQ::Net::DaybreakConnection> login_connection;
|
std::shared_ptr<EQ::Net::DaybreakConnection> login_connection;
|
||||||
LoginLoginRequest_Struct llrs;
|
LoginLoginRequest_Struct llrs;
|
||||||
|
|
||||||
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();
|
||||||
|
|||||||
@ -1,87 +1,101 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "client_manager.h"
|
#include "client_manager.h"
|
||||||
#include "login_server.h"
|
#include "login_server.h"
|
||||||
|
|
||||||
extern LoginServer server;
|
extern LoginServer server;
|
||||||
extern bool run_server;
|
extern bool run_server;
|
||||||
|
|
||||||
#include "../common/eqemu_logsys.h"
|
#include "../common/eqemu_logsys.h"
|
||||||
#include "../common/eqemu_logsys_fmt.h"
|
#include "../common/eqemu_logsys_fmt.h"
|
||||||
|
|
||||||
ClientManager::ClientManager()
|
ClientManager::ClientManager()
|
||||||
{
|
{
|
||||||
int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998);
|
int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998);
|
||||||
EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false);
|
EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false);
|
||||||
titanium_stream = new EQ::Net::EQStreamManager(titanium_opts);
|
titanium_stream = new EQ::Net::EQStreamManager(titanium_opts);
|
||||||
titanium_ops = new RegularOpcodeManager;
|
titanium_ops = new RegularOpcodeManager;
|
||||||
if (!titanium_ops->LoadOpcodes(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) {
|
||||||
stream->SetOpcodeManager(&titanium_ops);
|
LogF(Logs::General,
|
||||||
Client *c = new Client(stream, cv_titanium);
|
Logs::Login_Server,
|
||||||
clients.push_back(c);
|
"New Titanium client connection from {0}:{1}",
|
||||||
});
|
stream->GetRemoteIP(),
|
||||||
|
stream->GetRemotePort());
|
||||||
|
stream->SetOpcodeManager(&titanium_ops);
|
||||||
|
Client *c = new Client(stream, cv_titanium);
|
||||||
|
clients.push_back(c);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
int sod_port = server.config.GetVariableInt("SoD", "port", 5999);
|
int sod_port = server.config.GetVariableInt("SoD", "port", 5999);
|
||||||
EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false);
|
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) {
|
||||||
stream->SetOpcodeManager(&sod_ops);
|
LogF(Logs::General,
|
||||||
Client *c = new Client(stream, cv_sod);
|
Logs::Login_Server,
|
||||||
clients.push_back(c);
|
"New SoD client connection from {0}:{1}",
|
||||||
});
|
stream->GetRemoteIP(),
|
||||||
|
stream->GetRemotePort());
|
||||||
|
stream->SetOpcodeManager(&sod_ops);
|
||||||
|
Client *c = new Client(stream, cv_sod);
|
||||||
|
clients.push_back(c);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientManager::~ClientManager()
|
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;
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_CLIENTMANAGER_H
|
#ifndef EQEMU_CLIENTMANAGER_H
|
||||||
#define EQEMU_CLIENTMANAGER_H
|
#define EQEMU_CLIENTMANAGER_H
|
||||||
|
|
||||||
@ -27,44 +30,50 @@
|
|||||||
/**
|
/**
|
||||||
* 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();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes every client in the internal list, removes them if necessary.
|
* Processes every client in the internal list, removes them if necessary.
|
||||||
*/
|
*/
|
||||||
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();
|
||||||
|
|
||||||
std::list<Client*> clients;
|
std::list<Client *> clients;
|
||||||
OpcodeManager *titanium_ops;
|
OpcodeManager *titanium_ops;
|
||||||
EQ::Net::EQStreamManager *titanium_stream;
|
EQ::Net::EQStreamManager *titanium_stream;
|
||||||
OpcodeManager *sod_ops;
|
OpcodeManager *sod_ops;
|
||||||
EQ::Net::EQStreamManager *sod_stream;
|
EQ::Net::EQStreamManager *sod_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,41 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "../common/global_define.h"
|
#include "../common/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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,50 +44,44 @@ 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,65 +91,58 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_CONFIG_H
|
#ifndef EQEMU_CONFIG_H
|
||||||
#define EQEMU_CONFIG_H
|
#define EQEMU_CONFIG_H
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_DATABASE_H
|
#ifndef EQEMU_DATABASE_H
|
||||||
#define EQEMU_DATABASE_H
|
#define EQEMU_DATABASE_H
|
||||||
|
|
||||||
@ -25,58 +28,110 @@
|
|||||||
/**
|
/**
|
||||||
* 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
|
||||||
virtual bool GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id) { return false; }
|
* @param password
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual bool GetLoginDataFromAccountInfo(
|
||||||
|
const std::string &name,
|
||||||
|
const std::string &loginserver,
|
||||||
|
std::string &password,
|
||||||
|
unsigned int &id
|
||||||
|
) { return false; }
|
||||||
|
|
||||||
virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) { return false; }
|
virtual bool GetLoginTokenDataFromToken(
|
||||||
|
const std::string &token,
|
||||||
|
const std::string &ip,
|
||||||
|
unsigned int &db_account_id,
|
||||||
|
std::string &db_loginserver,
|
||||||
|
std::string &user
|
||||||
|
) { return false; }
|
||||||
|
|
||||||
virtual bool CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id) { return false; }
|
virtual bool CreateLoginData(
|
||||||
|
const std::string &name,
|
||||||
|
const std::string &password,
|
||||||
|
const std::string &loginserver,
|
||||||
|
unsigned int &id
|
||||||
|
) { return false; }
|
||||||
|
|
||||||
virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id) { return false; }
|
virtual bool CreateLoginDataWithID(
|
||||||
|
const std::string &name,
|
||||||
|
const std::string &password,
|
||||||
|
const std::string &loginserver,
|
||||||
|
unsigned int id
|
||||||
|
) { return false; }
|
||||||
|
|
||||||
virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) { }
|
virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the world registration from the long and short names provided.
|
* 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
|
||||||
*/
|
*
|
||||||
virtual bool GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id,
|
* @param long_name
|
||||||
unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password) { return false; }
|
* @param short_name
|
||||||
|
* @param id
|
||||||
|
* @param desc
|
||||||
|
* @param list_id
|
||||||
|
* @param trusted
|
||||||
|
* @param list_desc
|
||||||
|
* @param account
|
||||||
|
* @param password
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual bool GetWorldRegistration(
|
||||||
|
std::string long_name,
|
||||||
|
std::string short_name,
|
||||||
|
unsigned int &id,
|
||||||
|
std::string &desc,
|
||||||
|
unsigned int &list_id,
|
||||||
|
unsigned int &trusted,
|
||||||
|
std::string &list_desc,
|
||||||
|
std::string &account,
|
||||||
|
std::string &password
|
||||||
|
) { return false; }
|
||||||
|
|
||||||
|
virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the ip address of the client with account id = id
|
* Updates or creates the login server account with info from world server
|
||||||
*/
|
*
|
||||||
virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) { }
|
* @param id
|
||||||
|
* @param name
|
||||||
|
* @param password
|
||||||
|
* @param email
|
||||||
|
*/
|
||||||
|
virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates or creates the login server account with info from world server
|
* Updates the ip address of the world with account id = id
|
||||||
*/
|
*
|
||||||
virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) { }
|
* @param id
|
||||||
|
* @param long_name
|
||||||
|
* @param ip_address
|
||||||
|
*/
|
||||||
|
virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the ip address of the world with account id = id
|
* Creates new world registration for unregistered servers and returns new id
|
||||||
*/
|
*
|
||||||
virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { }
|
* @param long_name
|
||||||
|
* @param short_name
|
||||||
/**
|
* @param id
|
||||||
* Creates new world registration for unregistered servers and returns new 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:
|
||||||
std::string user, pass, host, port, name;
|
std::string user, pass, host, port, name;
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "../common/global_define.h"
|
#include "../common/global_define.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMUCAPI__H
|
#ifndef EQEMUCAPI__H
|
||||||
#define EQEMUCAPI__H
|
#define EQEMUCAPI__H
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_LOGINSERVER_H
|
#ifndef EQEMU_LOGINSERVER_H
|
||||||
#define EQEMU_LOGINSERVER_H
|
#define EQEMU_LOGINSERVER_H
|
||||||
|
|
||||||
@ -27,9 +30,8 @@
|
|||||||
#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
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -1,32 +1,35 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_LOGINSTRUCTURES_H
|
#ifndef EQEMU_LOGINSTRUCTURES_H
|
||||||
#define EQEMU_LOGINSTRUCTURES_H
|
#define EQEMU_LOGINSTRUCTURES_H
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
struct LoginChatMessage_Struct {
|
struct LoginChatMessage_Struct {
|
||||||
short Unknown0;
|
short Unknown0;
|
||||||
uint32 Unknown1;
|
uint32 Unknown1;
|
||||||
uint32 Unknown2;
|
uint32 Unknown2;
|
||||||
uint32 Unknown3;
|
uint32 Unknown3;
|
||||||
uint8 Unknown4;
|
uint8 Unknown4;
|
||||||
char ChatMessage[1];
|
char ChatMessage[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoginLoginRequest_Struct {
|
struct LoginLoginRequest_Struct {
|
||||||
@ -35,7 +38,7 @@ struct LoginLoginRequest_Struct {
|
|||||||
short unknown3;
|
short unknown3;
|
||||||
short unknown4;
|
short unknown4;
|
||||||
short unknown5;
|
short unknown5;
|
||||||
char unknown6[16];
|
char unknown6[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoginAccepted_Struct {
|
struct LoginAccepted_Struct {
|
||||||
@ -44,28 +47,27 @@ struct LoginAccepted_Struct {
|
|||||||
short unknown3;
|
short unknown3;
|
||||||
short unknown4;
|
short unknown4;
|
||||||
short unknown5;
|
short unknown5;
|
||||||
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;
|
||||||
char key[11]; //10 char + null term;
|
char key[11]; //10 char + null term;
|
||||||
uint32 failed_attempts;
|
uint32 failed_attempts;
|
||||||
char unknown3[4]; //0x00, 0x00, 0x00, 0x03
|
char unknown3[4]; //0x00, 0x00, 0x00, 0x03
|
||||||
char unknown4[4]; //0x00, 0x00, 0x00, 0x02
|
char unknown4[4]; //0x00, 0x00, 0x00, 0x02
|
||||||
char unknown5[4]; //0xe7, 0x03, 0x00, 0x00
|
char unknown5[4]; //0xe7, 0x03, 0x00, 0x00
|
||||||
char unknown6[4]; //0xff, 0xff, 0xff, 0xff
|
char unknown6[4]; //0xff, 0xff, 0xff, 0xff
|
||||||
char unknown7[4]; //0xa0, 0x05, 0x00, 0x00
|
char unknown7[4]; //0xa0, 0x05, 0x00, 0x00
|
||||||
char unknown8[4]; //0x00, 0x00, 0x00, 0x02
|
char unknown8[4]; //0x00, 0x00, 0x00, 0x02
|
||||||
char unknown9[4]; //0xff, 0x03, 0x00, 0x00
|
char unknown9[4]; //0xff, 0x03, 0x00, 0x00
|
||||||
char unknown10[4]; //0x00, 0x00, 0x00, 0x00
|
char unknown10[4]; //0x00, 0x00, 0x00, 0x00
|
||||||
char unknown11[4]; //0x63, 0x00, 0x00, 0x00
|
char unknown11[4]; //0x63, 0x00, 0x00, 0x00
|
||||||
char unknown12[4]; //0x01, 0x00, 0x00, 0x00
|
char unknown12[4]; //0x01, 0x00, 0x00, 0x00
|
||||||
char unknown13[4]; //0x00, 0x00, 0x00, 0x00
|
char unknown13[4]; //0x00, 0x00, 0x00, 0x00
|
||||||
char unknown14[4]; //0x00, 0x00, 0x00, 0x00
|
char unknown14[4]; //0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoginLoginFailed_Struct {
|
struct LoginLoginFailed_Struct {
|
||||||
@ -74,7 +76,7 @@ struct LoginLoginFailed_Struct {
|
|||||||
short unknown3;
|
short unknown3;
|
||||||
short unknown4;
|
short unknown4;
|
||||||
short unknown5;
|
short unknown5;
|
||||||
char unknown6[74];
|
char unknown6[74];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerListHeader_Struct {
|
struct ServerListHeader_Struct {
|
||||||
@ -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;
|
||||||
@ -95,18 +96,19 @@ struct PlayEverquestRequest_Struct
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PlayEverquestResponse_Struct {
|
struct PlayEverquestResponse_Struct {
|
||||||
uint8 Sequence;
|
uint8 Sequence;
|
||||||
uint8 Unknown1[9];
|
uint8 Unknown1[9];
|
||||||
uint8 Allowed;
|
uint8 Allowed;
|
||||||
uint16 Message;
|
uint16 Message;
|
||||||
uint8 Unknown2[3];
|
uint8 Unknown2[3];
|
||||||
uint32 ServerNumber;
|
uint32 ServerNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
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()
|
||||||
|
|||||||
@ -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,44 +95,47 @@ 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", ""),
|
||||||
server.config.GetVariableString("database", "host", "localhost"),
|
server.config.GetVariableString("database", "host", "localhost"),
|
||||||
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;
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_OPTIONS_H
|
#ifndef EQEMU_OPTIONS_H
|
||||||
#define EQEMU_OPTIONS_H
|
#define EQEMU_OPTIONS_H
|
||||||
|
|
||||||
@ -22,12 +25,12 @@
|
|||||||
* Collects options on one object, because having a bunch of global variables floating around is
|
* 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),
|
||||||
trace(false),
|
trace(false),
|
||||||
@ -38,7 +41,7 @@ public:
|
|||||||
reject_duplicate_servers(false),
|
reject_duplicate_servers(false),
|
||||||
allow_password_login(true),
|
allow_password_login(true),
|
||||||
allow_token_login(false),
|
allow_token_login(false),
|
||||||
auto_create_accounts(false) { }
|
auto_create_accounts(false) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets allow_unregistered.
|
* Sets allow_unregistered.
|
||||||
@ -182,18 +185,18 @@ public:
|
|||||||
inline bool IsUpdatingInsecurePasswords() const { return update_insecure_passwords; }
|
inline bool IsUpdatingInsecurePasswords() const { return update_insecure_passwords; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool allow_unregistered;
|
bool allow_unregistered;
|
||||||
bool trace;
|
bool trace;
|
||||||
bool world_trace;
|
bool world_trace;
|
||||||
bool dump_in_packets;
|
bool dump_in_packets;
|
||||||
bool dump_out_packets;
|
bool dump_out_packets;
|
||||||
bool reject_duplicate_servers;
|
bool reject_duplicate_servers;
|
||||||
bool allow_token_login;
|
bool allow_token_login;
|
||||||
bool allow_password_login;
|
bool allow_password_login;
|
||||||
bool auto_create_accounts;
|
bool auto_create_accounts;
|
||||||
bool auto_link_accounts;
|
bool auto_link_accounts;
|
||||||
bool update_insecure_passwords;
|
bool update_insecure_passwords;
|
||||||
int encryption_mode;
|
int encryption_mode;
|
||||||
std::string local_network;
|
std::string local_network;
|
||||||
std::string account_table;
|
std::string account_table;
|
||||||
std::string world_registration_table;
|
std::string world_registration_table;
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "server_manager.h"
|
#include "server_manager.h"
|
||||||
#include "login_server.h"
|
#include "login_server.h"
|
||||||
#include "login_structures.h"
|
#include "login_structures.h"
|
||||||
@ -24,7 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../common/eqemu_logsys_fmt.h"
|
#include "../common/eqemu_logsys_fmt.h"
|
||||||
|
|
||||||
extern LoginServer server;
|
extern LoginServer server;
|
||||||
extern bool run_server;
|
extern bool run_server;
|
||||||
|
|
||||||
ServerManager::ServerManager()
|
ServerManager::ServerManager()
|
||||||
{
|
{
|
||||||
@ -36,38 +39,52 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
++iter;
|
world_servers.push_back(std::unique_ptr<WorldServer>(new WorldServer(c)));
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
world_servers.push_back(std::unique_ptr<WorldServer>(new WorldServer(c)));
|
server_connection->OnConnectionRemoved(
|
||||||
});
|
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
|
||||||
|
auto iter = world_servers.begin();
|
||||||
|
while (iter != world_servers.end()) {
|
||||||
|
if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) {
|
||||||
|
LogF(Logs::General,
|
||||||
|
Logs::World_Server,
|
||||||
|
"World server {0} has been disconnected, removing.",
|
||||||
|
(*iter)->GetLongName().c_str());
|
||||||
|
world_servers.erase(iter);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
server_connection->OnConnectionRemoved("World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
|
++iter;
|
||||||
auto iter = world_servers.begin();
|
|
||||||
while (iter != world_servers.end()) {
|
|
||||||
if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) {
|
|
||||||
LogF(Logs::General, Logs::World_Server, "World server {0} has been disconnected, removing.", (*iter)->GetLongName().c_str());
|
|
||||||
world_servers.erase(iter);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerManager::~ServerManager()
|
ServerManager::~ServerManager()
|
||||||
@ -75,11 +92,12 @@ ServerManager::~ServerManager()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port)
|
WorldServer *ServerManager::GetServerByAddress(const std::string &addr, int port)
|
||||||
{
|
{
|
||||||
auto iter = world_servers.begin();
|
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;
|
||||||
@ -90,9 +108,9 @@ WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port
|
|||||||
|
|
||||||
EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq)
|
EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq)
|
||||||
{
|
{
|
||||||
unsigned int packet_size = sizeof(ServerListHeader_Struct);
|
unsigned int packet_size = sizeof(ServerListHeader_Struct);
|
||||||
unsigned int server_count = 0;
|
unsigned int server_count = 0;
|
||||||
in_addr in;
|
in_addr in;
|
||||||
in.s_addr = c->GetConnection()->GetRemoteIP();
|
in.s_addr = c->GetConnection()->GetRemoteIP();
|
||||||
std::string client_ip = inet_ntoa(in);
|
std::string client_ip = inet_ntoa(in);
|
||||||
|
|
||||||
@ -119,8 +137,8 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
|
|||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size);
|
||||||
ServerListHeader_Struct *server_list = (ServerListHeader_Struct*)outapp->pBuffer;
|
ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer;
|
||||||
server_list->Unknown1 = seq;
|
server_list->Unknown1 = seq;
|
||||||
server_list->Unknown2 = 0x00000000;
|
server_list->Unknown2 = 0x00000000;
|
||||||
server_list->Unknown3 = 0x01650000;
|
server_list->Unknown3 = 0x01650000;
|
||||||
@ -129,7 +147,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
|
|||||||
* Not sure what this is but it should be noted setting it to
|
* Not sure what this is but it should be noted setting it to
|
||||||
* 0xFFFFFFFF crashes the client so: don't do that.
|
* 0xFFFFFFFF crashes the client so: don't do that.
|
||||||
*/
|
*/
|
||||||
server_list->Unknown4 = 0x00000000;
|
server_list->Unknown4 = 0x00000000;
|
||||||
server_list->NumberOfServers = server_count;
|
server_list->NumberOfServers = server_count;
|
||||||
|
|
||||||
unsigned char *data_pointer = outapp->pBuffer;
|
unsigned char *data_pointer = outapp->pBuffer;
|
||||||
@ -157,22 +175,22 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch ((*iter)->GetServerListID()) {
|
switch ((*iter)->GetServerListID()) {
|
||||||
case 1: {
|
case 1: {
|
||||||
*(unsigned int*)data_pointer = 0x00000030;
|
*(unsigned int *) data_pointer = 0x00000030;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
*(unsigned int*)data_pointer = 0x00000009;
|
*(unsigned int *) data_pointer = 0x00000009;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
*(unsigned int*)data_pointer = 0x00000001;
|
*(unsigned int *) data_pointer = 0x00000001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data_pointer += 4;
|
data_pointer += 4;
|
||||||
|
|
||||||
*(unsigned int*)data_pointer = (*iter)->GetRuntimeID();
|
*(unsigned int *) data_pointer = (*iter)->GetRuntimeID();
|
||||||
data_pointer += 4;
|
data_pointer += 4;
|
||||||
|
|
||||||
memcpy(data_pointer, (*iter)->GetLongName().c_str(), (*iter)->GetLongName().size());
|
memcpy(data_pointer, (*iter)->GetLongName().c_str(), (*iter)->GetLongName().size());
|
||||||
@ -187,18 +205,18 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq
|
|||||||
// 0 = Up, 1 = Down, 2 = Up, 3 = down, 4 = locked, 5 = locked(down)
|
// 0 = Up, 1 = Down, 2 = Up, 3 = down, 4 = locked, 5 = locked(down)
|
||||||
if ((*iter)->GetStatus() < 0) {
|
if ((*iter)->GetStatus() < 0) {
|
||||||
if ((*iter)->GetZonesBooted() == 0) {
|
if ((*iter)->GetZonesBooted() == 0) {
|
||||||
*(uint32*)data_pointer = 0x01;
|
*(uint32 *) data_pointer = 0x01;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*(uint32*)data_pointer = 0x04;
|
*(uint32 *) data_pointer = 0x04;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*(uint32*)data_pointer = 0x02;
|
*(uint32 *) data_pointer = 0x02;
|
||||||
}
|
}
|
||||||
data_pointer += 4;
|
data_pointer += 4;
|
||||||
|
|
||||||
*(uint32*)data_pointer = (*iter)->GetPlayersOnline();
|
*(uint32 *) data_pointer = (*iter)->GetPlayersOnline();
|
||||||
data_pointer += 4;
|
data_pointer += 4;
|
||||||
|
|
||||||
++iter;
|
++iter;
|
||||||
@ -207,16 +225,20 @@ 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;
|
||||||
while (iter != world_servers.end()) {
|
while (iter != world_servers.end()) {
|
||||||
if ((*iter)->GetRuntimeID() == server_id) {
|
if ((*iter)->GetRuntimeID() == server_id) {
|
||||||
EQ::Net::DynamicPacket outapp;
|
EQ::Net::DynamicPacket outapp;
|
||||||
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
|
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
|
||||||
UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp.Data();
|
UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct *) outapp.Data();
|
||||||
utwr->worldid = server_id;
|
utwr->worldid = server_id;
|
||||||
utwr->lsaccountid = client_account_id;
|
utwr->lsaccountid = client_account_id;
|
||||||
strncpy(utwr->login, &client_loginserver[0], 64);
|
strncpy(utwr->login, &client_loginserver[0], 64);
|
||||||
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
|
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_SERVERMANAGER_H
|
#ifndef EQEMU_SERVERMANAGER_H
|
||||||
#define EQEMU_SERVERMANAGER_H
|
#define EQEMU_SERVERMANAGER_H
|
||||||
|
|
||||||
@ -27,14 +30,14 @@
|
|||||||
#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,34 +46,60 @@ 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
|
||||||
*/
|
*
|
||||||
void SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id, const std::string &client_loginserver);
|
* @param server_id
|
||||||
|
* @param client_account_id
|
||||||
|
* @param client_loginserver
|
||||||
|
*/
|
||||||
|
void SendUserToWorldRequest(
|
||||||
|
unsigned int server_id,
|
||||||
|
unsigned int client_account_id,
|
||||||
|
const std::string &client_loginserver
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a server list packet for the client.
|
* Creates a server list packet for the client
|
||||||
*/
|
*
|
||||||
|
* @param c
|
||||||
|
* @param seq
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
EQApplicationPacket *CreateServerListPacket(Client *c, uint32 seq);
|
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
|
||||||
*/
|
*
|
||||||
WorldServer* GetServerByAddress(const std::string &address, int port);
|
* @param address
|
||||||
|
* @param port
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
WorldServer *GetServerByAddress(const std::string &address, int port);
|
||||||
|
|
||||||
std::unique_ptr<EQ::Net::ServertalkServer> server_connection;
|
std::unique_ptr<EQ::Net::ServertalkServer> server_connection;
|
||||||
std::list<std::unique_ptr<WorldServer>> world_servers;
|
std::list<std::unique_ptr<WorldServer>> world_servers;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,47 +1,73 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#include "world_server.h"
|
#include "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;
|
||||||
|
|
||||||
WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
|
WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
|
||||||
{
|
{
|
||||||
connection = c;
|
connection = c;
|
||||||
zones_booted = 0;
|
zones_booted = 0;
|
||||||
players_online = 0;
|
players_online = 0;
|
||||||
server_status = 0;
|
server_status = 0;
|
||||||
runtime_id = 0;
|
runtime_id = 0;
|
||||||
server_list_id = 0;
|
server_list_id = 0;
|
||||||
server_type = 0;
|
server_type = 0;
|
||||||
is_server_authorized = false;
|
is_server_authorized = false;
|
||||||
is_server_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()
|
||||||
@ -51,87 +77,92 @@ WorldServer::~WorldServer()
|
|||||||
|
|
||||||
void WorldServer::Reset()
|
void WorldServer::Reset()
|
||||||
{
|
{
|
||||||
zones_booted = 0;
|
zones_booted = 0;
|
||||||
players_online = 0;
|
players_online = 0;
|
||||||
server_status = 0;
|
server_status = 0;
|
||||||
runtime_id;
|
runtime_id;
|
||||||
server_list_id = 0;
|
server_list_id = 0;
|
||||||
server_type = 0;
|
server_type = 0;
|
||||||
is_server_authorized = false;
|
is_server_authorized = false;
|
||||||
is_server_logged_in = false;
|
is_server_logged_in = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p)
|
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();
|
||||||
Handle_NewLSInfo(info);
|
Handle_NewLSInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
Handle_LSStatus(ls_status);
|
Handle_LSStatus(ls_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
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,86 +170,101 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack
|
|||||||
//I don't use world trace for this and here is why:
|
//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.",
|
||||||
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer;
|
utwr->lsaccountid,
|
||||||
per->Sequence = c->GetPlaySequence();
|
c->GetAccountName().c_str());
|
||||||
|
EQApplicationPacket *outapp = new EQApplicationPacket(
|
||||||
|
OP_PlayEverquestResponse,
|
||||||
|
sizeof(PlayEverquestResponse_Struct));
|
||||||
|
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
|
||||||
|
per->Sequence = c->GetPlaySequence();
|
||||||
per->ServerNumber = c->GetPlayServerID();
|
per->ServerNumber = c->GetPlayServerID();
|
||||||
Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
|
Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
|
||||||
|
|
||||||
Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
|
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;
|
case 0:
|
||||||
case 0:
|
per->Message = 326;
|
||||||
per->Message = 326;
|
break;
|
||||||
break;
|
case -1:
|
||||||
case -1:
|
per->Message = 337;
|
||||||
per->Message = 337;
|
break;
|
||||||
break;
|
case -2:
|
||||||
case -2:
|
per->Message = 338;
|
||||||
per->Message = 338;
|
break;
|
||||||
break;
|
case -3:
|
||||||
case -3:
|
per->Message = 303;
|
||||||
per->Message = 303;
|
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,94 +272,112 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet
|
|||||||
//I don't use world trace for this and here is why:
|
//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.",
|
||||||
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer;
|
utwr->lsaccountid,
|
||||||
per->Sequence = c->GetPlaySequence();
|
c->GetAccountName().c_str());
|
||||||
|
EQApplicationPacket *outapp = new EQApplicationPacket(
|
||||||
|
OP_PlayEverquestResponse,
|
||||||
|
sizeof(PlayEverquestResponse_Struct));
|
||||||
|
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
|
||||||
|
per->Sequence = c->GetPlaySequence();
|
||||||
per->ServerNumber = c->GetPlayServerID();
|
per->ServerNumber = c->GetPlayServerID();
|
||||||
Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
|
Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
|
||||||
|
|
||||||
Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
|
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;
|
case 0:
|
||||||
case 0:
|
per->Message = 326;
|
||||||
per->Message = 326;
|
break;
|
||||||
break;
|
case -1:
|
||||||
case -1:
|
per->Message = 337;
|
||||||
per->Message = 337;
|
break;
|
||||||
break;
|
case -2:
|
||||||
case -2:
|
per->Message = 338;
|
||||||
per->Message = 338;
|
break;
|
||||||
break;
|
case -3:
|
||||||
case -3:
|
per->Message = 303;
|
||||||
per->Message = 303;
|
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;
|
||||||
@ -325,160 +389,155 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
|
void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i)
|
||||||
{
|
{
|
||||||
if (is_server_logged_in)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
std::string s_desc;
|
std::string s_desc;
|
||||||
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;
|
||||||
SetRuntimeID(s_id);
|
SetRuntimeID(s_id);
|
||||||
server_list_id = s_list_type;
|
server_list_id = s_list_type;
|
||||||
desc = s_desc;
|
desc = s_desc;
|
||||||
if (s_trusted) {
|
if (s_trusted) {
|
||||||
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
|
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
|
||||||
is_server_trusted = true;
|
is_server_trusted = true;
|
||||||
@ -488,31 +547,41 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned int server_id = 0;
|
unsigned int server_id = 0;
|
||||||
unsigned int server_list_type = 0;
|
unsigned int server_list_type = 0;
|
||||||
unsigned int is_server_trusted = 0;
|
unsigned int is_server_trusted = 0;
|
||||||
std::string server_description;
|
std::string server_description;
|
||||||
std::string server_list_description;
|
std::string server_list_description;
|
||||||
std::string server_account_name;
|
std::string server_account_name;
|
||||||
std::string server_account_password;
|
std::string server_account_password;
|
||||||
|
|
||||||
|
|
||||||
if (server.db->GetWorldRegistration(
|
if (server.db->GetWorldRegistration(
|
||||||
@ -524,17 +593,18 @@ 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;
|
||||||
SetRuntimeID(server_id);
|
SetRuntimeID(server_id);
|
||||||
server_list_id = server_list_type;
|
server_list_id = server_list_type;
|
||||||
desc = server_description;
|
desc = server_description;
|
||||||
|
|
||||||
if (is_server_trusted) {
|
if (is_server_trusted) {
|
||||||
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
|
Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
|
||||||
@ -543,31 +613,50 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
|
|||||||
connection->Send(ServerOP_LSAccountUpdate, outapp);
|
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,23 +668,39 @@ 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;
|
||||||
zones_booted = s->num_zones;
|
zones_booted = s->num_zones;
|
||||||
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;
|
||||||
client_auth.lsaccount_id = account_id;
|
client_auth.lsaccount_id = account_id;
|
||||||
strncpy(client_auth.name, account.c_str(), 30);
|
strncpy(client_auth.name, account.c_str(), 30);
|
||||||
strncpy(client_auth.key, key.c_str(), 30);
|
strncpy(client_auth.key, key.c_str(), 30);
|
||||||
client_auth.lsadmin = 0;
|
client_auth.lsadmin = 0;
|
||||||
client_auth.worldadmin = 0;
|
client_auth.worldadmin = 0;
|
||||||
client_auth.ip = inet_addr(ip.c_str());
|
client_auth.ip = inet_addr(ip.c_str());
|
||||||
strncpy(client_auth.lsname, &loginserver_name[0], 64);
|
strncpy(client_auth.lsname, &loginserver_name[0], 64);
|
||||||
|
|
||||||
std::string client_address(ip);
|
std::string client_address(ip);
|
||||||
@ -614,8 +719,7 @@ void WorldServer::SendClientAuth(std::string ip, std::string account, std::strin
|
|||||||
outapp.PutSerialize(0, client_auth);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,23 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
/**
|
||||||
Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net)
|
* EQEmulator: Everquest Server Emulator
|
||||||
|
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
* are required to give you total support for your newly bought product;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
||||||
are required to give you total support for your newly bought product;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
#ifndef EQEMU_WORLDSERVER_H
|
#ifndef EQEMU_WORLDSERVER_H
|
||||||
#define EQEMU_WORLDSERVER_H
|
#define EQEMU_WORLDSERVER_H
|
||||||
|
|
||||||
@ -31,106 +34,79 @@
|
|||||||
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();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the basic stats of this server.
|
* Resets the basic stats of this server.
|
||||||
*/
|
*/
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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);
|
||||||
void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p);
|
void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user