[Loginserver] Code Cleanup and Tweaks (#1653)

* if for whatever reason the world server is not sending an address, use the local address it sends

* Log when world is sending loginserver info

* Force legacy mode when login host is login.eqemulator.net to avoid misconfigurations at least until things change

* Add human IP translation to log messages

* Sanitize world server name

* Code cleanup and renaming member variables

* More cleanup

* Remove this->

* Validation constants

* Key worldserver lookups by both longname and shortname both

* Update allowed character list

* Fix short_name API response field; add world_id to response

* Shorten receiver verbosity

* Remove unnecessary member variables from database and rename database to m_database

* Adjust MAX_SERVER_VERSION_LENGTH

* Fix indents
This commit is contained in:
Chris Miles 2021-10-30 19:09:42 -05:00 committed by GitHub
parent 119c3d14b7
commit d87db648c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 496 additions and 870 deletions

View File

@ -44,6 +44,12 @@ void EQEmuConfig::parse_config()
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") { LoginLegacy = true; }
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
// at least today, this is wrong a majority of the time
// remove this if eqemulator ever upgrades its loginserver
if (LoginHost.find("login.eqemulator.net") != std::string::npos) {
LoginLegacy = true;
}
}
else {
char str[32];
@ -62,12 +68,19 @@ void EQEmuConfig::parse_config()
loginconfig->LoginLegacy = false;
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") { loginconfig->LoginLegacy = true; }
// at least today, this is wrong a majority of the time
// remove this if eqemulator ever upgrades its loginserver
if (loginconfig->LoginHost.find("login.eqemulator.net") != std::string::npos) {
loginconfig->LoginLegacy = true;
}
loginlist.Insert(loginconfig);
} while (LoginCount < 100);
}
//<locked> from xml converts to json as locked: "", so i default to "false".
//<locked> from xml converts to json as locked: "", so i default to "false".
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
Locked = false;
if (_root["server"]["world"].get("locked", "false").asString() == "true") { Locked = true; }

View File

@ -605,3 +605,31 @@ std::string FormatName(const std::string& char_name)
}
return formatted;
}
bool IsAllowedWorldServerCharacterList(char c)
{
const char *valid_characters = ":[](){}.!@#$%^&*-=+<>/\\|'\"";
if (strchr(valid_characters, c)) {
return true;
}
return false;
}
void SanitizeWorldServerName(char *name)
{
std::string server_long_name = name;
server_long_name.erase(
std::remove_if(
server_long_name.begin(),
server_long_name.end(),
[](char c) {
return !(std::isalpha(c) || std::isalnum(c) || std::isspace(c) || IsAllowedWorldServerCharacterList(c));
}
), server_long_name.end()
);
server_long_name = trim(server_long_name);
strcpy(name, server_long_name.c_str());
}

View File

@ -208,6 +208,7 @@ void RemoveApostrophes(std::string &s);
std::string convert2digit(int n, std::string suffix);
std::string numberToWords(unsigned long long int n);
std::string FormatName(const std::string& char_name);
void SanitizeWorldServerName(char *name);
template<typename InputIterator, typename OutputIterator>
auto CleanMobName(InputIterator first, InputIterator last, OutputIterator result)

View File

@ -1,23 +1,3 @@
/**
* 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 "account_management.h"
#include "login_server.h"
#include "../common/event/task_scheduler.h"
@ -416,4 +396,4 @@ uint32 AccountManagement::CheckExternalLoginserverUserCredentials(
);
return res.get();
}
}

View File

@ -1,22 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_ACCOUNT_MANAGEMENT_H
#define EQEMU_ACCOUNT_MANAGEMENT_H

View File

@ -1,23 +1,3 @@
/**
* 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 "client.h"
#include "login_server.h"
#include "../common/misc_functions.h"
@ -33,17 +13,17 @@ extern LoginServer server;
*/
Client::Client(std::shared_ptr<EQStreamInterface> c, LSClientVersion v)
{
connection = c;
version = v;
status = cs_not_sent_session_ready;
account_id = 0;
play_server_id = 0;
play_sequence_id = 0;
m_connection = c;
m_client_version = v;
m_client_status = cs_not_sent_session_ready;
m_account_id = 0;
m_play_server_id = 0;
m_play_sequence_id = 0;
}
bool Client::Process()
{
EQApplicationPacket *app = connection->PopPacket();
EQApplicationPacket *app = m_connection->PopPacket();
while (app) {
if (server.options.IsTraceOn()) {
LogDebug("Application packet received from client (size {0})", app->Size());
@ -53,9 +33,9 @@ bool Client::Process()
DumpPacket(app);
}
if (status == cs_failed_to_login) {
if (m_client_status == cs_failed_to_login) {
delete app;
app = connection->PopPacket();
app = m_connection->PopPacket();
continue;
}
@ -112,7 +92,7 @@ bool Client::Process()
}
delete app;
app = connection->PopPacket();
app = m_connection->PopPacket();
}
return true;
@ -126,7 +106,7 @@ bool Client::Process()
*/
void Client::Handle_SessionReady(const char *data, unsigned int size)
{
if (status != cs_not_sent_session_ready) {
if (m_client_status != cs_not_sent_session_ready) {
LogError("Session ready received again after already being received");
return;
}
@ -136,12 +116,12 @@ void Client::Handle_SessionReady(const char *data, unsigned int size)
return;
}
status = cs_waiting_for_login;
m_client_status = cs_waiting_for_login;
/**
* The packets are mostly the same but slightly different between the two versions
*/
if (version == cv_sod) {
if (m_client_version == cv_sod) {
auto *outapp = new EQApplicationPacket(OP_ChatMessage, 17);
outapp->pBuffer[0] = 0x02;
outapp->pBuffer[10] = 0x01;
@ -151,7 +131,7 @@ void Client::Handle_SessionReady(const char *data, unsigned int size)
DumpPacket(outapp);
}
connection->QueuePacket(outapp);
m_connection->QueuePacket(outapp);
delete outapp;
}
else {
@ -166,7 +146,7 @@ void Client::Handle_SessionReady(const char *data, unsigned int size)
DumpPacket(outapp);
}
connection->QueuePacket(outapp);
m_connection->QueuePacket(outapp);
delete outapp;
}
}
@ -179,7 +159,7 @@ void Client::Handle_SessionReady(const char *data, unsigned int size)
*/
void Client::Handle_Login(const char *data, unsigned int size)
{
if (status != cs_waiting_for_login) {
if (m_client_status != cs_waiting_for_login) {
LogError("Login received after already having logged in");
return;
}
@ -228,7 +208,7 @@ void Client::Handle_Login(const char *data, unsigned int size)
return;
}
memcpy(&llrs, data, sizeof(LoginLoginRequest_Struct));
memcpy(&m_llrs, data, sizeof(LoginLoginRequest_Struct));
bool result = false;
if (outbuffer[0] == 0 && outbuffer[1] == 0) {
@ -236,7 +216,7 @@ void Client::Handle_Login(const char *data, unsigned int size)
cred = (&outbuffer[2 + user.length()]);
result = server.db->GetLoginTokenDataFromToken(
cred,
connection->GetRemoteAddr(),
m_connection->GetRemoteAddr(),
db_account_id,
db_loginserver,
user
@ -267,7 +247,7 @@ void Client::Handle_Login(const char *data, unsigned int size)
LogDebug("[VerifyLoginHash] Success [{0}]", (result ? "true" : "false"));
}
else {
status = cs_creating_account;
m_client_status = cs_creating_account;
AttemptLoginAccountCreation(user, cred, db_loginserver);
return;
@ -305,7 +285,7 @@ void Client::Handle_Login(const char *data, unsigned int size)
*/
void Client::Handle_Play(const char *data)
{
if (status != cs_logged_in) {
if (m_client_status != cs_logged_in) {
LogError("Client sent a play request when they were not logged in, discarding");
return;
}
@ -323,10 +303,10 @@ void Client::Handle_Play(const char *data)
);
}
this->play_server_id = (unsigned int) play->ServerNumber;
play_sequence_id = sequence_in;
play_server_id = server_id_in;
server.server_manager->SendUserToWorldRequest(server_id_in, account_id, loginserver_name);
m_play_server_id = (unsigned int) play->ServerNumber;
m_play_sequence_id = sequence_in;
m_play_server_id = server_id_in;
server.server_manager->SendUserToWorldRequest(server_id_in, m_account_id, m_loginserver_name);
}
/**
@ -340,7 +320,7 @@ void Client::SendServerListPacket(uint32 seq)
DumpPacket(outapp);
}
connection->QueuePacket(outapp);
m_connection->QueuePacket(outapp);
delete outapp;
}
@ -350,12 +330,12 @@ void Client::SendPlayResponse(EQApplicationPacket *outapp)
LogDebug("Sending play response for {0}", GetAccountName());
// server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size);
}
connection->QueuePacket(outapp);
m_connection->QueuePacket(outapp);
}
void Client::GenerateKey()
{
key.clear();
m_key.clear();
int count = 0;
while (count < 10) {
static const char key_selection[] =
@ -367,7 +347,7 @@ void Client::GenerateKey()
'6', '7', '8', '9'
};
key.append((const char *) &key_selection[random.Int(0, 35)], 1);
m_key.append((const char *) &key_selection[m_random.Int(0, 35)], 1);
count++;
}
}
@ -383,6 +363,8 @@ void Client::AttemptLoginAccountCreation(
const std::string &loginserver
)
{
LogInfo("[AttemptLoginAccountCreation] user [{}] loginserver [{}]", user, loginserver);
#ifdef LSPX
if (loginserver == "eqemu") {
LogInfo("Attempting login account creation via '{0}'", loginserver);
@ -404,8 +386,8 @@ void Client::AttemptLoginAccountCreation(
return;
}
stored_user = user;
stored_pass = pass;
m_stored_user = user;
m_stored_pass = pass;
auto address = addr_components[0];
auto port = std::stoi(addr_components[1]);
@ -416,15 +398,15 @@ void Client::AttemptLoginAccountCreation(
return;
}
login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
login_connection_manager->OnNewConnection(
m_login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
m_login_connection_manager->OnNewConnection(
std::bind(
&Client::LoginOnNewConnection,
this,
std::placeholders::_1
)
);
login_connection_manager->OnConnectionStateChange(
m_login_connection_manager->OnConnectionStateChange(
std::bind(
&Client::LoginOnStatusChange,
this,
@ -433,7 +415,7 @@ void Client::AttemptLoginAccountCreation(
std::placeholders::_3
)
);
login_connection_manager->OnPacketRecv(
m_login_connection_manager->OnPacketRecv(
std::bind(
&Client::LoginOnPacketRecv,
this,
@ -442,7 +424,7 @@ void Client::AttemptLoginAccountCreation(
)
);
login_connection_manager->Connect(addr, port);
m_login_connection_manager->Connect(addr, port);
}
);
@ -461,17 +443,17 @@ void Client::AttemptLoginAccountCreation(
void Client::DoFailedLogin()
{
stored_user.clear();
stored_pass.clear();
m_stored_user.clear();
m_stored_pass.clear();
EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct));
auto *login_failed = (LoginLoginFailed_Struct *) outapp.pBuffer;
login_failed->unknown1 = llrs.unknown1;
login_failed->unknown2 = llrs.unknown2;
login_failed->unknown3 = llrs.unknown3;
login_failed->unknown4 = llrs.unknown4;
login_failed->unknown5 = llrs.unknown5;
login_failed->unknown1 = m_llrs.unknown1;
login_failed->unknown2 = m_llrs.unknown2;
login_failed->unknown3 = m_llrs.unknown3;
login_failed->unknown4 = m_llrs.unknown4;
login_failed->unknown5 = m_llrs.unknown5;
memcpy(login_failed->unknown6, FailedLoginResponseData, sizeof(FailedLoginResponseData));
@ -479,8 +461,8 @@ void Client::DoFailedLogin()
DumpPacket(&outapp);
}
connection->QueuePacket(&outapp);
status = cs_failed_to_login;
m_connection->QueuePacket(&outapp);
m_client_status = cs_failed_to_login;
}
/**
@ -576,28 +558,28 @@ void Client::DoSuccessfulLogin(
const std::string &db_loginserver
)
{
stored_user.clear();
stored_pass.clear();
m_stored_user.clear();
m_stored_pass.clear();
server.client_manager->RemoveExistingClient(db_account_id, db_loginserver);
in_addr in{};
in.s_addr = connection->GetRemoteIP();
in.s_addr = m_connection->GetRemoteIP();
server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in)));
GenerateKey();
account_id = db_account_id;
account_name = in_account_name;
loginserver_name = db_loginserver;
m_account_id = db_account_id;
m_account_name = in_account_name;
m_loginserver_name = db_loginserver;
auto *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80);
auto *login_accepted = (LoginAccepted_Struct *) outapp->pBuffer;
login_accepted->unknown1 = llrs.unknown1;
login_accepted->unknown2 = llrs.unknown2;
login_accepted->unknown3 = llrs.unknown3;
login_accepted->unknown4 = llrs.unknown4;
login_accepted->unknown5 = llrs.unknown5;
login_accepted->unknown1 = m_llrs.unknown1;
login_accepted->unknown2 = m_llrs.unknown2;
login_accepted->unknown3 = m_llrs.unknown3;
login_accepted->unknown4 = m_llrs.unknown4;
login_accepted->unknown5 = m_llrs.unknown5;
auto *login_failed_attempts = new LoginFailedAttempts_Struct;
memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct));
@ -620,7 +602,7 @@ void Client::DoSuccessfulLogin(
login_failed_attempts->unknown9[1] = 0x03;
login_failed_attempts->unknown11[0] = 0x63;
login_failed_attempts->unknown12[0] = 0x01;
memcpy(login_failed_attempts->key, key.c_str(), key.size());
memcpy(login_failed_attempts->key, m_key.c_str(), m_key.size());
char encrypted_buffer[80] = {0};
auto rc = eqcrypt_block((const char *) login_failed_attempts, 75, encrypted_buffer, 1);
@ -634,10 +616,10 @@ void Client::DoSuccessfulLogin(
DumpPacket(outapp);
}
connection->QueuePacket(outapp);
m_connection->QueuePacket(outapp);
delete outapp;
status = cs_logged_in;
m_client_status = cs_logged_in;
}
/**
@ -689,7 +671,7 @@ void Client::CreateEQEmuAccount(
*/
void Client::LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
{
login_connection = connection;
m_login_connection = connection;
}
/**
@ -751,16 +733,16 @@ void Client::LoginSendSessionReady()
p.PutUInt16(0, 1); //OP_SessionReady
p.PutUInt32(2, 2);
login_connection->QueuePacket(p);
m_login_connection->QueuePacket(p);
}
void Client::LoginSendLogin()
{
size_t buffer_len = stored_user.length() + stored_pass.length() + 2;
size_t buffer_len = m_stored_user.length() + m_stored_pass.length() + 2;
std::unique_ptr<char[]> buffer(new char[buffer_len]);
strcpy(&buffer[0], stored_user.c_str());
strcpy(&buffer[stored_user.length() + 1], stored_pass.c_str());
strcpy(&buffer[0], m_stored_user.c_str());
strcpy(&buffer[m_stored_user.length() + 1], m_stored_pass.c_str());
size_t encrypted_len = buffer_len;
@ -775,7 +757,7 @@ void Client::LoginSendLogin()
eqcrypt_block(&buffer[0], buffer_len, (char *) p.Data() + 12, true);
login_connection->QueuePacket(p);
m_login_connection->QueuePacket(p);
}
/**
@ -796,7 +778,7 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p)
EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size);
auto response_error = sp.GetUInt16(1);
login_connection_manager->OnConnectionStateChange(
m_login_connection_manager->OnConnectionStateChange(
std::bind(
&Client::LoginOnStatusChangeIgnored,
this,
@ -809,18 +791,18 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p)
if (response_error > 101) {
LogDebug("response [{0}] failed login", response_error);
DoFailedLogin();
login_connection->Close();
m_login_connection->Close();
}
else {
LogDebug(
"response [{0}] login succeeded user [{1}]",
response_error,
stored_user
"response [{0}] login succeeded user [{1}]",
response_error,
m_stored_user
);
auto m_dbid = sp.GetUInt32(8);
CreateEQEmuAccount(stored_user, stored_pass, m_dbid);
login_connection->Close();
CreateEQEmuAccount(m_stored_user, m_stored_pass, m_dbid);
m_login_connection->Close();
}
}

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_CLIENT_H
#define EQEMU_CLIENT_H
@ -116,49 +96,49 @@ public:
*
* @return
*/
unsigned int GetAccountID() const { return account_id; }
unsigned int GetAccountID() const { return m_account_id; }
/**
* Gets the loginserver name of this client
*
* @return
*/
std::string GetLoginServerName() const { return loginserver_name; }
std::string GetLoginServerName() const { return m_loginserver_name; }
/**
* Gets the account name of this client
*
* @return
*/
std::string GetAccountName() const { return account_name; }
std::string GetAccountName() const { return m_account_name; }
/**
* Gets the key generated at login for this client
*
* @return
*/
std::string GetKey() const { return key; }
std::string GetKey() const { return m_key; }
/**
* 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 m_play_server_id; }
/**
* Gets the play sequence state for this client
*
* @return
*/
unsigned int GetPlaySequence() const { return play_sequence_id; }
unsigned int GetPlaySequence() const { return m_play_sequence_id; }
/**
* Gets the connection for this client
*
* @return
*/
std::shared_ptr<EQStreamInterface> GetConnection() { return connection; }
std::shared_ptr<EQStreamInterface> GetConnection() { return m_connection; }
/**
* Attempts to create a login account
@ -195,24 +175,24 @@ public:
void CreateEQEmuAccount(const std::string &in_account_name, const std::string &in_account_password, unsigned int loginserver_account_id);
private:
EQ::Random random;
std::shared_ptr<EQStreamInterface> connection;
LSClientVersion version;
LSClientStatus status;
EQ::Random m_random;
std::shared_ptr<EQStreamInterface> m_connection;
LSClientVersion m_client_version;
LSClientStatus m_client_status;
std::string account_name;
unsigned int account_id;
std::string loginserver_name;
unsigned int play_server_id;
unsigned int play_sequence_id;
std::string key;
std::string m_account_name;
unsigned int m_account_id;
std::string m_loginserver_name;
unsigned int m_play_server_id;
unsigned int m_play_sequence_id;
std::string m_key;
std::unique_ptr<EQ::Net::DaybreakConnectionManager> login_connection_manager;
std::shared_ptr<EQ::Net::DaybreakConnection> login_connection;
LoginLoginRequest_Struct llrs;
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_login_connection_manager;
std::shared_ptr<EQ::Net::DaybreakConnection> m_login_connection;
LoginLoginRequest_Struct m_llrs;
std::string stored_user;
std::string stored_pass;
std::string m_stored_user;
std::string m_stored_pass;
void LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
void LoginOnStatusChange(
std::shared_ptr<EQ::Net::DaybreakConnection> conn,

View File

@ -1,23 +1,3 @@
/**
* 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 "client_manager.h"
#include "login_server.h"
@ -25,6 +5,7 @@ extern LoginServer server;
extern bool run_server;
#include "../common/eqemu_logsys.h"
#include "../common/misc.h"
ClientManager::ClientManager()
{
@ -52,8 +33,8 @@ ClientManager::ClientManager()
titanium_stream->OnNewConnection(
[this](std::shared_ptr<EQ::Net::EQStream> stream) {
LogInfo(
"New Titanium client connection from {0}:{1}",
stream->GetRemoteIP(),
"New Titanium client connection from [{0}:{1}]",
long2ip(stream->GetRemoteIP()),
stream->GetRemotePort()
);
@ -87,13 +68,13 @@ ClientManager::ClientManager()
sod_stream->OnNewConnection(
[this](std::shared_ptr<EQ::Net::EQStream> stream) {
LogInfo(
"New SoD client connection from {0}:{1}",
stream->GetRemoteIP(),
"New SoD+ client connection from [{0}:{1}]",
long2ip(stream->GetRemoteIP()),
stream->GetRemotePort()
);
stream->SetOpcodeManager(&sod_ops);
Client *c = new Client(stream, cv_sod);
auto *c = new Client(stream, cv_sod);
clients.push_back(c);
}
);

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_CLIENTMANAGER_H
#define EQEMU_CLIENTMANAGER_H

View File

@ -1,23 +1,3 @@
/**
* 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 "../common/global_define.h"
#include "database.h"
@ -45,11 +25,6 @@ Database::Database(
std::string name
)
{
this->user = user;
this->pass = pass;
this->host = host;
this->name = name;
uint32 errnum = 0;
char errbuf[MYSQL_ERRMSG_SIZE];
if (!Open(
@ -75,8 +50,8 @@ Database::Database(
*/
Database::~Database()
{
if (database) {
mysql_close(database);
if (m_database) {
mysql_close(m_database);
}
}
@ -355,11 +330,13 @@ void Database::UpdateLoginserverAccountPasswordHash(
/**
* @param short_name
* @param long_name
* @param login_world_server_admin_id
* @return
*/
Database::DbWorldRegistration Database::GetWorldRegistration(
const std::string &short_name,
const std::string &long_name,
uint32 login_world_server_admin_id
)
{
@ -375,45 +352,46 @@ Database::DbWorldRegistration Database::GetWorldRegistration(
" login_world_servers AS WSR\n"
" JOIN login_server_list_types AS SLT ON WSR.login_server_list_type_id = SLT.id\n"
"WHERE\n"
" WSR.short_name = '{0}' AND WSR.login_server_admin_id = {1} LIMIT 1",
" WSR.short_name = '{}' AND WSR.long_name = '{}' AND WSR.login_server_admin_id = {} LIMIT 1",
EscapeString(short_name),
EscapeString(long_name),
login_world_server_admin_id
);
Database::DbWorldRegistration world_registration{};
Database::DbWorldRegistration r{};
auto results = QueryDatabase(query);
if (!results.Success() || results.RowCount() != 1) {
return world_registration;
return r;
}
auto row = results.begin();
world_registration.loaded = true;
world_registration.server_id = std::stoi(row[0]);
world_registration.server_description = row[1];
world_registration.server_list_type = std::stoi(row[3]);
world_registration.is_server_trusted = std::stoi(row[2]) > 0;
world_registration.server_list_description = row[4];
world_registration.server_admin_id = std::stoi(row[5]);
r.loaded = true;
r.server_id = std::stoi(row[0]);
r.server_description = row[1];
r.server_list_type = std::stoi(row[3]);
r.is_server_trusted = std::stoi(row[2]) > 0;
r.server_list_description = row[4];
r.server_admin_id = std::stoi(row[5]);
if (world_registration.server_admin_id <= 0) {
return world_registration;
if (r.server_admin_id <= 0) {
return r;
}
auto world_registration_query = fmt::format(
"SELECT account_name, account_password FROM login_server_admins WHERE id = {0} LIMIT 1",
world_registration.server_admin_id
r.server_admin_id
);
auto world_registration_results = QueryDatabase(world_registration_query);
if (world_registration_results.Success() && world_registration_results.RowCount() == 1) {
auto world_registration_row = world_registration_results.begin();
world_registration.server_admin_account_name = world_registration_row[0];
world_registration.server_admin_account_password = world_registration_row[1];
r.server_admin_account_name = world_registration_row[0];
r.server_admin_account_password = world_registration_row[1];
}
return world_registration;
return r;
}
/**
@ -665,21 +643,21 @@ Database::DbLoginServerAdmin Database::GetLoginServerAdmin(const std::string &ac
auto results = QueryDatabase(query);
Database::DbLoginServerAdmin login_server_admin{};
Database::DbLoginServerAdmin r{};
if (results.RowCount() == 1) {
auto row = results.begin();
login_server_admin.loaded = true;
login_server_admin.id = std::stoi(row[0]);
login_server_admin.account_name = row[1];
login_server_admin.account_password = row[2];
login_server_admin.first_name = row[3];
login_server_admin.last_name = row[4];
login_server_admin.email = row[5];
login_server_admin.registration_date = row[7];
login_server_admin.registration_ip_address = row[8];
r.loaded = true;
r.id = std::stoi(row[0]);
r.account_name = row[1];
r.account_password = row[2];
r.first_name = row[3];
r.last_name = row[4];
r.email = row[5];
r.registration_date = row[7];
r.registration_ip_address = row[8];
}
return login_server_admin;
return r;
}
/**
@ -701,20 +679,20 @@ Database::DbLoginServerAccount Database::GetLoginServerAccountByAccountName(
auto results = QueryDatabase(query);
Database::DbLoginServerAccount login_server_account{};
Database::DbLoginServerAccount r{};
if (results.RowCount() == 1) {
auto row = results.begin();
login_server_account.loaded = true;
login_server_account.id = std::stoi(row[0]);
login_server_account.account_name = row[1];
login_server_account.account_password = row[2];
login_server_account.account_email = row[3];
login_server_account.source_loginserver = row[4];
login_server_account.last_ip_address = row[5];
login_server_account.last_login_date = row[6];
login_server_account.created_at = row[7];
login_server_account.updated_at = row[8];
r.loaded = true;
r.id = std::stoi(row[0]);
r.account_name = row[1];
r.account_password = row[2];
r.account_email = row[3];
r.source_loginserver = row[4];
r.last_ip_address = row[5];
r.last_login_date = row[6];
r.created_at = row[7];
r.updated_at = row[8];
}
return login_server_account;
return r;
}

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_DATABASEMYSQL_H
#define EQEMU_DATABASEMYSQL_H
@ -32,7 +12,7 @@
class Database : public DBcore {
public:
Database() { database = nullptr; }
Database() { m_database = nullptr; }
/**
* Constructor, tries to set our database to connect to the supplied options.
@ -49,7 +29,7 @@ public:
* Destructor, frees our database if needed.
*/
~Database();
bool IsConnected() { return (database != nullptr); }
bool IsConnected() { return (m_database != nullptr); }
/**
* Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure.
@ -158,11 +138,13 @@ public:
* Returns true if the record was found, false otherwise
*
* @param short_name
* @param long_name
* @param login_world_server_admin_id
* @return
*/
Database::DbWorldRegistration GetWorldRegistration(
const std::string &short_name,
const std::string &long_name,
uint32 login_world_server_admin_id
);
@ -298,8 +280,7 @@ public:
);
protected:
std::string user, pass, host, port, name;
MYSQL *database{};
MYSQL *m_database{};
};
#endif

View File

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

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMUCAPI__H
#define EQEMUCAPI__H

View File

@ -1,29 +1,7 @@
#include <utility>
/**
* 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
*
*/
#ifndef EQEMU_LOGINSERVER_H
#define EQEMU_LOGINSERVER_H
#include <utility>
#include "../common/json_config.h"
#include "database.h"
#include "encryption.h"

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_LOGINSTRUCTURES_H
#define EQEMU_LOGINSTRUCTURES_H

View File

@ -1,23 +1,3 @@
/**
* 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 <iostream>
#include <random>
#include "loginserver_command_handler.h"

View File

@ -1,23 +1,3 @@
/**
* 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 "iostream"
#include "../common/cli/eqemu_command_handler.h"

View File

@ -1,23 +1,3 @@
/**
* 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 "loginserver_webserver.h"
#include "server_manager.h"
#include "login_server.h"
@ -48,17 +28,18 @@ namespace LoginserverWebserver {
}
Json::Value response;
auto iter = server.server_manager->getWorldServers().begin();
auto iter = server.server_manager->getWorldServers().begin();
while (iter != server.server_manager->getWorldServers().end()) {
Json::Value row;
row["server_long_name"] = (*iter)->GetServerLongName();
row["server_short_name"] = (*iter)->GetServerLongName();
row["server_list_id"] = (*iter)->GetServerListID();
row["server_status"] = (*iter)->GetStatus();
row["zones_booted"] = (*iter)->GetZonesBooted();
row["local_ip"] = (*iter)->GetLocalIP();
row["remote_ip"] = (*iter)->GetRemoteIP();
row["players_online"] = (*iter)->GetPlayersOnline();
row["server_long_name"] = (*iter)->GetServerLongName();
row["server_short_name"] = (*iter)->GetServerShortName();
row["server_list_type_id"] = (*iter)->GetServerListID();
row["server_status"] = (*iter)->GetStatus();
row["zones_booted"] = (*iter)->GetZonesBooted();
row["local_ip"] = (*iter)->GetLocalIP();
row["remote_ip"] = (*iter)->GetRemoteIP();
row["players_online"] = (*iter)->GetPlayersOnline();
row["world_id"] = (*iter)->GetServerId();
response.append(row);
++iter;
}

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_LOGINSERVER_WEBSERVER_H
#define EQEMU_LOGINSERVER_WEBSERVER_H

View File

@ -1,23 +1,3 @@
/**
* 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 "../common/global_define.h"
#include "../common/types.h"
#include "../common/opcodemgr.h"

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_OPTIONS_H
#define EQEMU_OPTIONS_H

View File

@ -1,23 +1,3 @@
/**
* 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 "server_manager.h"
#include "login_server.h"
#include "login_structures.h"
@ -33,15 +13,15 @@ ServerManager::ServerManager()
{
int listen_port = server.config.GetVariableInt("general", "listen_port", 5998);
server_connection = std::make_unique<EQ::Net::ServertalkServer>();
m_server_connection = std::make_unique<EQ::Net::ServertalkServer>();
EQ::Net::ServertalkServerOptions opts;
opts.port = listen_port;
opts.ipv6 = false;
server_connection->Listen(opts);
opts.ipv6 = false;
m_server_connection->Listen(opts);
LogInfo("Loginserver now listening on port [{0}]", listen_port);
server_connection->OnConnectionIdentified(
m_server_connection->OnConnectionIdentified(
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> world_connection) {
LogInfo(
"New World Server connection from {0}:{1}",
@ -49,8 +29,8 @@ ServerManager::ServerManager()
world_connection->Handle()->RemotePort()
);
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
auto iter = m_world_servers.begin();
while (iter != m_world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(world_connection->Handle()->RemoteIP()) ==
0 &&
(*iter)->GetConnection()->Handle()->RemotePort() == world_connection->Handle()->RemotePort()) {
@ -61,27 +41,27 @@ ServerManager::ServerManager()
world_connection->Handle()->RemotePort()
);
world_servers.erase(iter);
m_world_servers.erase(iter);
break;
}
++iter;
}
world_servers.push_back(std::make_unique<WorldServer>(world_connection));
m_world_servers.push_back(std::make_unique<WorldServer>(world_connection));
}
);
server_connection->OnConnectionRemoved(
m_server_connection->OnConnectionRemoved(
"World", [this](std::shared_ptr<EQ::Net::ServertalkServerConnection> c) {
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
auto iter = m_world_servers.begin();
while (iter != m_world_servers.end()) {
if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) {
LogInfo(
"World server {0} has been disconnected, removing.",
(*iter)->GetServerLongName()
);
world_servers.erase(iter);
m_world_servers.erase(iter);
return;
}
@ -100,8 +80,8 @@ ServerManager::~ServerManager() = default;
*/
WorldServer *ServerManager::GetServerByAddress(const std::string &ip_address, int port)
{
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
auto iter = m_world_servers.begin();
while (iter != m_world_servers.end()) {
if ((*iter)->GetConnection()->Handle()->RemoteIP() == ip_address &&
(*iter)->GetConnection()->Handle()->RemotePort()) {
return (*iter).get();
@ -127,8 +107,8 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3
LogDebug("ServerManager::CreateServerListPacket via client address [{0}]", client_ip);
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
auto iter = m_world_servers.begin();
while (iter != m_world_servers.end()) {
if (!(*iter)->IsAuthorized()) {
LogDebug(
"ServerManager::CreateServerListPacket | Server [{0}] via IP [{1}] is not authorized to be listed",
@ -195,8 +175,8 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3
unsigned char *data_pointer = outapp->pBuffer;
data_pointer += sizeof(ServerListHeader_Struct);
iter = world_servers.begin();
while (iter != world_servers.end()) {
iter = m_world_servers.begin();
while (iter != m_world_servers.end()) {
if (!(*iter)->IsAuthorized()) {
++iter;
continue;
@ -278,9 +258,9 @@ void ServerManager::SendUserToWorldRequest(
const std::string &client_loginserver
)
{
auto iter = world_servers.begin();
auto iter = m_world_servers.begin();
bool found = false;
while (iter != world_servers.end()) {
while (iter != m_world_servers.end()) {
if ((*iter)->GetServerId() == server_id) {
EQ::Net::DynamicPacket outapp;
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
@ -316,8 +296,8 @@ bool ServerManager::ServerExists(
WorldServer *ignore
)
{
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
auto iter = m_world_servers.begin();
while (iter != m_world_servers.end()) {
if ((*iter).get() == ignore) {
++iter;
continue;
@ -343,8 +323,8 @@ void ServerManager::DestroyServerByName(
WorldServer *ignore
)
{
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
auto iter = m_world_servers.begin();
while (iter != m_world_servers.end()) {
if ((*iter).get() == ignore) {
++iter;
continue;
@ -353,7 +333,7 @@ void ServerManager::DestroyServerByName(
if ((*iter)->GetServerLongName().compare(server_long_name) == 0 &&
(*iter)->GetServerShortName().compare(server_short_name) == 0) {
(*iter)->GetConnection()->Handle()->Disconnect();
iter = world_servers.erase(iter);
iter = m_world_servers.erase(iter);
continue;
}
@ -366,5 +346,5 @@ void ServerManager::DestroyServerByName(
*/
const std::list<std::unique_ptr<WorldServer>> &ServerManager::getWorldServers() const
{
return world_servers;
return m_world_servers;
}

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_SERVERMANAGER_H
#define EQEMU_SERVERMANAGER_H
@ -103,8 +83,8 @@ private:
*/
WorldServer *GetServerByAddress(const std::string &ip_address, int port);
std::unique_ptr<EQ::Net::ServertalkServer> server_connection;
std::list<std::unique_ptr<WorldServer>> world_servers;
std::unique_ptr<EQ::Net::ServertalkServer> m_server_connection;
std::list<std::unique_ptr<WorldServer>> m_world_servers;
};

View File

@ -1,28 +1,8 @@
/**
* 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 "world_server.h"
#include "login_server.h"
#include "login_structures.h"
#include "../common/eqemu_logsys.h"
#include "../common/ip_util.h"
#include "../common/string_util.h"
extern LoginServer server;
@ -31,16 +11,16 @@ extern LoginServer server;
*/
WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> worldserver_connection)
{
connection = worldserver_connection;
zones_booted = 0;
players_online = 0;
server_status = 0;
server_id = 0;
server_list_type_id = 0;
server_process_type = 0;
is_server_authorized = false;
is_server_trusted = false;
is_server_logged_in = false;
m_connection = worldserver_connection;
m_zones_booted = 0;
m_players_online = 0;
m_server_status = 0;
m_server_id = 0;
m_server_list_type_id = 0;
m_server_process_type = 0;
m_is_server_authorized = false;
m_is_server_trusted = false;
m_is_server_logged_in = false;
worldserver_connection->OnMessage(
ServerOP_NewLSInfo,
@ -72,21 +52,25 @@ WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> wo
std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)
);
m_keepalive = std::make_unique<EQ::Timer>(1000, true, std::bind(&WorldServer::OnKeepAlive, this, std::placeholders::_1));
m_keepalive = std::make_unique<EQ::Timer>(
1000,
true,
std::bind(&WorldServer::OnKeepAlive, this, std::placeholders::_1)
);
}
WorldServer::~WorldServer() = default;
void WorldServer::Reset()
{
server_id;
zones_booted = 0;
players_online = 0;
server_status = 0;
server_list_type_id = 0;
server_process_type = 0;
is_server_authorized = false;
is_server_logged_in = false;
m_server_id;
m_zones_booted = 0;
m_players_online = 0;
m_server_status = 0;
m_server_list_type_id = 0;
m_server_process_type = 0;
m_is_server_authorized = false;
m_is_server_logged_in = false;
}
/**
@ -116,9 +100,15 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packe
return;
}
auto *info = (ServerNewLSInfo_Struct *) packet.Data();
// if for whatever reason the world server is not sending an address, use the local address it sends
std::string remote_ip_addr = info->remote_ip_address;
std::string local_ip_addr = info->local_ip_address;
if (remote_ip_addr.empty() && !local_ip_addr.empty() && local_ip_addr != "127.0.0.1") {
strcpy(info->remote_ip_address, local_ip_addr.c_str());
}
LogInfo(
"New World Server Info | name [{0}] shortname [{1}] remote_address [{2}] local_address [{3}] account [{4}] password [{5}] server_type [{6}]",
info->server_long_name,
@ -443,7 +433,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
}
if (server.options.IsWorldTraceOn()) {
LogDebug("ServerOP_LSAccountUpdate packet received from [{0}]", short_name);
LogDebug("ServerOP_LSAccountUpdate packet received from [{0}]", m_short_name);
}
auto *loginserver_update = (ServerLSAccountUpdate_Struct *) packet.Data();
@ -486,6 +476,8 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info
return;
}
SanitizeWorldServerName(new_world_server_info_packet->server_long_name);
SetAccountPassword(new_world_server_info_packet->account_password)
->SetLongName(new_world_server_info_packet->server_long_name)
->SetShortName(new_world_server_info_packet->server_short_name)
@ -506,8 +498,8 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info
else {
if (server.server_manager->ServerExists(GetServerLongName(), GetServerShortName(), this)) {
LogInfo("World tried to login but there already exists a server that has that name, destroying [{}]",
long_name);
server.server_manager->DestroyServerByName(long_name, short_name, this);
m_long_name);
server.server_manager->DestroyServerByName(m_long_name, m_short_name, this);
}
}
@ -551,6 +543,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info
Database::DbWorldRegistration
world_registration = server.db->GetWorldRegistration(
GetServerShortName(),
GetServerLongName(),
world_server_admin_id
);
@ -619,7 +612,7 @@ void WorldServer::SendClientAuth(
strncpy(client_auth.loginserver_name, &loginserver_name[0], 64);
const std::string &client_address(ip);
std::string world_address(connection->Handle()->RemoteIP());
std::string world_address(m_connection->Handle()->RemoteIP());
if (client_address == world_address) {
client_auth.is_client_from_local_network = 1;
@ -655,13 +648,22 @@ void WorldServer::SendClientAuth(
);
outapp.PutSerialize(0, client_auth);
connection->Send(ServerOP_LSClientAuth, outapp);
m_connection->Send(ServerOP_LSClientAuth, outapp);
if (server.options.IsDumpInPacketsOn()) {
DumpPacket(ServerOP_LSClientAuth, outapp);
}
}
constexpr static int MAX_ACCOUNT_NAME_LENGTH = 30;
constexpr static int MAX_ACCOUNT_PASSWORD_LENGTH = 30;
constexpr static int MAX_SERVER_LONG_NAME_LENGTH = 200;
constexpr static int MAX_SERVER_SHORT_NAME_LENGTH = 50;
constexpr static int MAX_SERVER_LOCAL_ADDRESS_LENGTH = 125;
constexpr static int MAX_SERVER_REMOTE_ADDRESS_LENGTH = 125;
constexpr static int MAX_SERVER_VERSION_LENGTH = 64;
constexpr static int MAX_SERVER_PROTOCOL_VERSION = 25;
/**
* @param new_world_server_info_packet
* @return
@ -670,41 +672,32 @@ bool WorldServer::HandleNewLoginserverInfoValidation(
ServerNewLSInfo_Struct *new_world_server_info_packet
)
{
const int max_account_name_length = 30;
const int max_account_password_length = 30;
const int max_server_long_name_length = 200;
const int max_server_short_name_length = 50;
const int max_server_local_address_length = 125;
const int max_server_remote_address_length = 125;
const int max_server_version_length = 64;
const int max_server_protocol_version = 25;
if (strlen(new_world_server_info_packet->account_name) >= max_account_name_length) {
LogError("Handle_NewLSInfo error [account_name] was too long | max [{0}]", max_account_name_length);
if (strlen(new_world_server_info_packet->account_name) >= MAX_ACCOUNT_NAME_LENGTH) {
LogError("Handle_NewLSInfo error [account_name] was too long | max [{0}]", MAX_ACCOUNT_NAME_LENGTH);
return false;
}
else if (strlen(new_world_server_info_packet->account_password) >= max_account_password_length) {
LogError("Handle_NewLSInfo error [account_password] was too long | max [{0}]", max_account_password_length);
else if (strlen(new_world_server_info_packet->account_password) >= MAX_ACCOUNT_PASSWORD_LENGTH) {
LogError("Handle_NewLSInfo error [account_password] was too long | max [{0}]", MAX_ACCOUNT_PASSWORD_LENGTH);
return false;
}
else if (strlen(new_world_server_info_packet->server_long_name) >= max_server_long_name_length) {
LogError("Handle_NewLSInfo error [server_long_name] was too long | max [{0}]", max_server_long_name_length);
else if (strlen(new_world_server_info_packet->server_long_name) >= MAX_SERVER_LONG_NAME_LENGTH) {
LogError("Handle_NewLSInfo error [server_long_name] was too long | max [{0}]", MAX_SERVER_LONG_NAME_LENGTH);
return false;
}
else if (strlen(new_world_server_info_packet->server_short_name) >= max_server_short_name_length) {
LogError("Handle_NewLSInfo error [server_short_name] was too long | max [{0}]", max_server_short_name_length);
else if (strlen(new_world_server_info_packet->server_short_name) >= MAX_SERVER_SHORT_NAME_LENGTH) {
LogError("Handle_NewLSInfo error [server_short_name] was too long | max [{0}]", MAX_SERVER_SHORT_NAME_LENGTH);
return false;
}
else if (strlen(new_world_server_info_packet->server_version) >= max_server_short_name_length) {
LogError("Handle_NewLSInfo error [server_version] was too long | max [{0}]", max_server_version_length);
else if (strlen(new_world_server_info_packet->server_version) >= MAX_SERVER_VERSION_LENGTH) {
LogError("Handle_NewLSInfo error [server_version] was too long | max [{0}]", MAX_SERVER_VERSION_LENGTH);
return false;
}
else if (strlen(new_world_server_info_packet->protocol_version) >= max_server_protocol_version) {
LogError("Handle_NewLSInfo error [protocol_version] was too long | max [{0}]", max_server_protocol_version);
else if (strlen(new_world_server_info_packet->protocol_version) >= MAX_SERVER_PROTOCOL_VERSION) {
LogError("Handle_NewLSInfo error [protocol_version] was too long | max [{0}]", MAX_SERVER_PROTOCOL_VERSION);
return false;
}
if (strlen(new_world_server_info_packet->local_ip_address) <= max_server_local_address_length) {
if (strlen(new_world_server_info_packet->local_ip_address) <= MAX_SERVER_LOCAL_ADDRESS_LENGTH) {
if (strlen(new_world_server_info_packet->local_ip_address) == 0) {
LogError("Handle_NewLSInfo error, local address was null, defaulting to localhost");
SetLocalIp("127.0.0.1");
@ -714,17 +707,17 @@ bool WorldServer::HandleNewLoginserverInfoValidation(
}
}
else {
LogError("Handle_NewLSInfo error, local address was too long | max [{0}]", max_server_local_address_length);
LogError("Handle_NewLSInfo error, local address was too long | max [{0}]", MAX_SERVER_LOCAL_ADDRESS_LENGTH);
return false;
}
if (strlen(new_world_server_info_packet->remote_ip_address) <= max_server_remote_address_length) {
if (strlen(new_world_server_info_packet->remote_ip_address) <= MAX_SERVER_REMOTE_ADDRESS_LENGTH) {
if (strlen(new_world_server_info_packet->remote_ip_address) == 0) {
SetRemoteIp(GetConnection()->Handle()->RemoteIP());
LogWarning(
"Remote address was null, defaulting to stream address [{0}]",
remote_ip_address
m_remote_ip_address
);
}
else {
@ -736,7 +729,7 @@ bool WorldServer::HandleNewLoginserverInfoValidation(
LogWarning(
"Handle_NewLSInfo remote address was too long, defaulting to stream address [{0}]",
remote_ip_address
m_remote_ip_address
);
}
@ -796,7 +789,7 @@ bool WorldServer::HandleNewLoginserverRegisteredOnly(
if (IsServerTrusted()) {
LogDebug("WorldServer::HandleNewLoginserverRegisteredOnly | ServerOP_LSAccountUpdate sent to world");
EQ::Net::DynamicPacket outapp;
connection->Send(ServerOP_LSAccountUpdate, outapp);
m_connection->Send(ServerOP_LSAccountUpdate, outapp);
}
}
else {
@ -847,6 +840,8 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed(
->SetIsServerTrusted(world_registration.is_server_trusted)
->SetServerListTypeId(world_registration.server_list_type);
SetIsServerAuthorized(true);
bool does_world_server_pass_authentication_check = (
world_registration.server_admin_account_name == GetAccountName() &&
WorldServer::ValidateWorldServerAdminLogin(
@ -864,7 +859,7 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed(
if (does_world_server_have_non_empty_credentials) {
if (does_world_server_pass_authentication_check) {
SetIsServerAuthorized(true);
SetIsServerLoggedIn(true);
LogInfo(
"Server long_name [{0}] short_name [{1}] successfully logged in",
@ -875,16 +870,13 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed(
if (IsServerTrusted()) {
LogDebug("WorldServer::HandleNewLoginserverRegisteredOnly | ServerOP_LSAccountUpdate sent to world");
EQ::Net::DynamicPacket outapp;
connection->Send(ServerOP_LSAccountUpdate, outapp);
m_connection->Send(ServerOP_LSAccountUpdate, outapp);
}
}
else {
/**
* this is the first of two cases where we should deny access even if unregistered is allowed
*/
// server is authorized to be on the loginserver list but didn't pass login check
LogInfo(
"Server long_name [{0}] short_name [{1}] attempted to log in but account and password did not match the entry in the database.",
"Server long_name [{0}] short_name [{1}] attempted to log in but account and password did not match the entry in the database. Unregistered still allowed",
GetServerLongName(),
GetServerShortName()
);
@ -892,9 +884,7 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed(
}
else {
/**
* this is the second of two cases where we should deny access even if unregistered is allowed
*/
// server is authorized to be on the loginserver list but didn't pass login check
if (!GetAccountName().empty() || !GetAccountPassword().empty()) {
LogInfo(
"Server [{0}] [{1}] did not login but this server required a password to login",
@ -903,7 +893,6 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed(
);
}
else {
SetIsServerAuthorized(true);
LogInfo(
"Server [{0}] [{1}] did not login but unregistered servers are allowed",
GetServerLongName(),
@ -939,14 +928,12 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed(
}
}
/**
* Auto create a registration
*/
// Auto create a registration
if (!server.db->CreateWorldRegistration(
GetServerLongName(),
GetServerShortName(),
GetRemoteIp(),
server_id,
m_server_id,
server_admin_id
)) {
return false;
@ -1044,7 +1031,7 @@ bool WorldServer::ValidateWorldServerAdminLogin(
*/
WorldServer *WorldServer::SetServerListTypeId(unsigned int in_server_list_id)
{
server_list_type_id = in_server_list_id;
m_server_list_type_id = in_server_list_id;
return this;
}
@ -1054,7 +1041,7 @@ WorldServer *WorldServer::SetServerListTypeId(unsigned int in_server_list_id)
*/
const std::string &WorldServer::GetServerDescription() const
{
return server_description;
return m_server_description;
}
/**
@ -1062,7 +1049,7 @@ const std::string &WorldServer::GetServerDescription() const
*/
WorldServer *WorldServer::SetServerDescription(const std::string &in_server_description)
{
WorldServer::server_description = in_server_description;
WorldServer::m_server_description = in_server_description;
return this;
}
@ -1072,7 +1059,7 @@ WorldServer *WorldServer::SetServerDescription(const std::string &in_server_desc
*/
bool WorldServer::IsServerAuthorized() const
{
return is_server_authorized;
return m_is_server_authorized;
}
/**
@ -1080,7 +1067,7 @@ bool WorldServer::IsServerAuthorized() const
*/
WorldServer *WorldServer::SetIsServerAuthorized(bool in_is_server_authorized)
{
WorldServer::is_server_authorized = in_is_server_authorized;
WorldServer::m_is_server_authorized = in_is_server_authorized;
return this;
}
@ -1090,7 +1077,7 @@ WorldServer *WorldServer::SetIsServerAuthorized(bool in_is_server_authorized)
*/
bool WorldServer::IsServerLoggedIn() const
{
return is_server_logged_in;
return m_is_server_logged_in;
}
/**
@ -1098,7 +1085,7 @@ bool WorldServer::IsServerLoggedIn() const
*/
WorldServer *WorldServer::SetIsServerLoggedIn(bool in_is_server_logged_in)
{
WorldServer::is_server_logged_in = in_is_server_logged_in;
WorldServer::m_is_server_logged_in = in_is_server_logged_in;
return this;
}
@ -1108,7 +1095,7 @@ WorldServer *WorldServer::SetIsServerLoggedIn(bool in_is_server_logged_in)
*/
bool WorldServer::IsServerTrusted() const
{
return is_server_trusted;
return m_is_server_trusted;
}
/**
@ -1116,7 +1103,7 @@ bool WorldServer::IsServerTrusted() const
*/
WorldServer *WorldServer::SetIsServerTrusted(bool in_is_server_trusted)
{
WorldServer::is_server_trusted = in_is_server_trusted;
WorldServer::m_is_server_trusted = in_is_server_trusted;
return this;
}
@ -1126,7 +1113,7 @@ WorldServer *WorldServer::SetIsServerTrusted(bool in_is_server_trusted)
*/
WorldServer *WorldServer::SetZonesBooted(unsigned int in_zones_booted)
{
WorldServer::zones_booted = in_zones_booted;
WorldServer::m_zones_booted = in_zones_booted;
return this;
}
@ -1136,7 +1123,7 @@ WorldServer *WorldServer::SetZonesBooted(unsigned int in_zones_booted)
*/
WorldServer *WorldServer::SetPlayersOnline(unsigned int in_players_online)
{
WorldServer::players_online = in_players_online;
WorldServer::m_players_online = in_players_online;
return this;
}
@ -1146,7 +1133,7 @@ WorldServer *WorldServer::SetPlayersOnline(unsigned int in_players_online)
*/
WorldServer *WorldServer::SetServerStatus(int in_server_status)
{
WorldServer::server_status = in_server_status;
WorldServer::m_server_status = in_server_status;
return this;
}
@ -1156,7 +1143,7 @@ WorldServer *WorldServer::SetServerStatus(int in_server_status)
*/
WorldServer *WorldServer::SetServerProcessType(unsigned int in_server_process_type)
{
WorldServer::server_process_type = in_server_process_type;
WorldServer::m_server_process_type = in_server_process_type;
return this;
}
@ -1166,7 +1153,7 @@ WorldServer *WorldServer::SetServerProcessType(unsigned int in_server_process_ty
*/
WorldServer *WorldServer::SetLongName(const std::string &in_long_name)
{
WorldServer::long_name = in_long_name;
WorldServer::m_long_name = in_long_name;
return this;
}
@ -1176,7 +1163,7 @@ WorldServer *WorldServer::SetLongName(const std::string &in_long_name)
*/
WorldServer *WorldServer::SetShortName(const std::string &in_short_name)
{
WorldServer::short_name = in_short_name;
WorldServer::m_short_name = in_short_name;
return this;
}
@ -1186,7 +1173,7 @@ WorldServer *WorldServer::SetShortName(const std::string &in_short_name)
*/
WorldServer *WorldServer::SetAccountName(const std::string &in_account_name)
{
WorldServer::account_name = in_account_name;
WorldServer::m_account_name = in_account_name;
return this;
}
@ -1196,7 +1183,7 @@ WorldServer *WorldServer::SetAccountName(const std::string &in_account_name)
*/
WorldServer *WorldServer::SetAccountPassword(const std::string &in_account_password)
{
WorldServer::account_password = in_account_password;
WorldServer::m_account_password = in_account_password;
return this;
}
@ -1206,7 +1193,7 @@ WorldServer *WorldServer::SetAccountPassword(const std::string &in_account_passw
*/
WorldServer *WorldServer::SetRemoteIp(const std::string &in_remote_ip)
{
WorldServer::remote_ip_address = in_remote_ip;
WorldServer::m_remote_ip_address = in_remote_ip;
return this;
}
@ -1216,7 +1203,7 @@ WorldServer *WorldServer::SetRemoteIp(const std::string &in_remote_ip)
*/
WorldServer *WorldServer::SetLocalIp(const std::string &in_local_ip)
{
WorldServer::local_ip = in_local_ip;
WorldServer::m_local_ip = in_local_ip;
return this;
}
@ -1226,7 +1213,7 @@ WorldServer *WorldServer::SetLocalIp(const std::string &in_local_ip)
*/
WorldServer *WorldServer::SetProtocol(const std::string &in_protocol)
{
WorldServer::protocol = in_protocol;
WorldServer::m_protocol = in_protocol;
return this;
}
@ -1236,7 +1223,7 @@ WorldServer *WorldServer::SetProtocol(const std::string &in_protocol)
*/
WorldServer *WorldServer::SetVersion(const std::string &in_version)
{
WorldServer::version = in_version;
WorldServer::m_version = in_version;
return this;
}
@ -1246,7 +1233,7 @@ WorldServer *WorldServer::SetVersion(const std::string &in_version)
*/
int WorldServer::GetServerStatus() const
{
return server_status;
return m_server_status;
}
/**
@ -1254,7 +1241,7 @@ int WorldServer::GetServerStatus() const
*/
unsigned int WorldServer::GetServerListTypeId() const
{
return server_list_type_id;
return m_server_list_type_id;
}
/**
@ -1262,7 +1249,7 @@ unsigned int WorldServer::GetServerListTypeId() const
*/
unsigned int WorldServer::GetServerProcessType() const
{
return server_process_type;
return m_server_process_type;
}
/**
@ -1270,7 +1257,7 @@ unsigned int WorldServer::GetServerProcessType() const
*/
const std::string &WorldServer::GetAccountName() const
{
return account_name;
return m_account_name;
}
/**
@ -1278,7 +1265,7 @@ const std::string &WorldServer::GetAccountName() const
*/
const std::string &WorldServer::GetAccountPassword() const
{
return account_password;
return m_account_password;
}
/**
@ -1286,7 +1273,7 @@ const std::string &WorldServer::GetAccountPassword() const
*/
const std::string &WorldServer::GetRemoteIp() const
{
return remote_ip_address;
return m_remote_ip_address;
}
/**
@ -1294,7 +1281,7 @@ const std::string &WorldServer::GetRemoteIp() const
*/
const std::string &WorldServer::GetLocalIp() const
{
return local_ip;
return m_local_ip;
}
/**
@ -1302,7 +1289,7 @@ const std::string &WorldServer::GetLocalIp() const
*/
const std::string &WorldServer::GetProtocol() const
{
return protocol;
return m_protocol;
}
/**
@ -1310,11 +1297,11 @@ const std::string &WorldServer::GetProtocol() const
*/
const std::string &WorldServer::GetVersion() const
{
return version;
return m_version;
}
void WorldServer::OnKeepAlive(EQ::Timer *t)
{
ServerPacket pack(ServerOP_KeepAlive, 0);
connection->SendPacket(&pack);
m_connection->SendPacket(&pack);
}

View File

@ -1,23 +1,3 @@
/**
* 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
*
*/
#ifndef EQEMU_WORLDSERVER_H
#define EQEMU_WORLDSERVER_H
@ -50,44 +30,44 @@ public:
/**
* Accesses connection, it is intentional that this is not const (trust me).
*/
std::shared_ptr<EQ::Net::ServertalkServerConnection> GetConnection() { return connection; }
void SetConnection(std::shared_ptr<EQ::Net::ServertalkServerConnection> c) { connection = c; }
std::shared_ptr<EQ::Net::ServertalkServerConnection> GetConnection() { return m_connection; }
void SetConnection(std::shared_ptr<EQ::Net::ServertalkServerConnection> c) { m_connection = c; }
/**
* @return
*/
unsigned int GetServerId() const { return server_id; }
unsigned int GetServerId() const { return m_server_id; }
WorldServer *SetServerId(unsigned int id)
{
server_id = id;
m_server_id = id;
return this;
}
/**
* @return
*/
std::string GetServerLongName() const { return long_name; }
std::string GetServerShortName() const { return short_name; }
std::string GetServerLongName() const { return m_long_name; }
std::string GetServerShortName() const { return m_short_name; }
/**
* Gets whether the server is authorized to show up on the server list or not
* @return
*/
bool IsAuthorized() const { return is_server_authorized; }
std::string GetLocalIP() const { return local_ip; }
std::string GetRemoteIP() const { return remote_ip_address; }
bool IsAuthorized() const { return m_is_server_authorized; }
std::string GetLocalIP() const { return m_local_ip; }
std::string GetRemoteIP() const { return m_remote_ip_address; }
/**
* Gets what kind of server this server is (legends, preferred, normal)
*
* @return
*/
unsigned int GetServerListID() const { return server_list_type_id; }
unsigned int GetServerListID() const { return m_server_list_type_id; }
WorldServer *SetServerListTypeId(unsigned int in_server_list_id);
int GetStatus() const { return server_status; }
unsigned int GetZonesBooted() const { return zones_booted; }
unsigned int GetPlayersOnline() const { return players_online; }
int GetStatus() const { return m_server_status; }
unsigned int GetZonesBooted() const { return m_zones_booted; }
unsigned int GetPlayersOnline() const { return m_players_online; }
/**
* Takes the info struct we received from world and processes it
@ -184,27 +164,26 @@ private:
void ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet);
void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet);
std::shared_ptr<EQ::Net::ServertalkServerConnection> connection;
std::shared_ptr<EQ::Net::ServertalkServerConnection> m_connection;
unsigned int zones_booted;
unsigned int players_online;
int server_status;
unsigned int server_id;
unsigned int server_list_type_id;
unsigned int server_process_type;
std::string server_description;
std::string long_name;
std::string short_name;
std::string account_name;
std::string account_password;
std::string remote_ip_address;
std::string local_ip;
std::string protocol;
std::string version;
bool is_server_authorized;
bool is_server_logged_in;
bool is_server_trusted;
unsigned int m_zones_booted;
unsigned int m_players_online;
int m_server_status;
unsigned int m_server_id;
unsigned int m_server_list_type_id;
unsigned int m_server_process_type;
std::string m_server_description;
std::string m_long_name;
std::string m_short_name;
std::string m_account_name;
std::string m_account_password;
std::string m_remote_ip_address;
std::string m_local_ip;
std::string m_protocol;
std::string m_version;
bool m_is_server_authorized;
bool m_is_server_logged_in;
bool m_is_server_trusted;
/**
* Keepalive

View File

@ -46,12 +46,12 @@ extern volatile bool RunLoops;
LoginServer::LoginServer(const char *iAddress, uint16 iPort, const char *Account, const char *Password, bool legacy)
{
strn0cpy(LoginServerAddress, iAddress, 256);
LoginServerPort = iPort;
LoginAccount = Account;
LoginPassword = Password;
CanAccountUpdate = false;
IsLegacy = legacy;
strn0cpy(m_loginserver_address, iAddress, 256);
m_loginserver_port = iPort;
m_login_account = Account;
m_login_password = Password;
m_can_account_update = false;
m_is_legacy = legacy;
Connect();
}
@ -93,7 +93,10 @@ void LoginServer::ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p)
if (Config->Locked) {
if (status < (RuleI(GM, MinStatusToBypassLockedServer))) {
LogDebug("[ProcessUsertoWorldReqLeg] Server locked and status is not high enough for account_id [{0}]", utwr->lsaccountid);
LogDebug(
"[ProcessUsertoWorldReqLeg] Server locked and status is not high enough for account_id [{0}]",
utwr->lsaccountid
);
utwrs->response = UserToWorldStatusWorldUnavail;
SendPacket(&outpack);
return;
@ -171,7 +174,10 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p)
if (Config->Locked == true) {
if (status < (RuleI(GM, MinStatusToBypassLockedServer))) {
LogDebug("[ProcessUsertoWorldReq] Server locked and status is not high enough for account_id [{0}]", utwr->lsaccountid);
LogDebug(
"[ProcessUsertoWorldReq] Server locked and status is not high enough for account_id [{0}]",
utwr->lsaccountid
);
utwrs->response = UserToWorldStatusWorldUnavail;
SendPacket(&outpack);
return;
@ -320,61 +326,63 @@ void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p)
LogNetcode("Received ServerPacket from LS OpCode {:#04x}", opcode);
LogNetcode("Received ServerOP_LSAccountUpdate packet from loginserver");
CanAccountUpdate = true;
m_can_account_update = true;
}
bool LoginServer::Connect()
{
char errbuf[1024];
if ((LoginServerIP = ResolveIP(LoginServerAddress, errbuf)) == 0) {
LogInfo("Unable to resolve [{}] to an IP", LoginServerAddress);
if ((m_loginserver_ip = ResolveIP(m_loginserver_address, errbuf)) == 0) {
LogInfo("Unable to resolve [{}] to an IP", m_loginserver_address);
return false;
}
if (LoginServerIP == 0 || LoginServerPort == 0) {
if (m_loginserver_ip == 0 || m_loginserver_port == 0) {
LogInfo(
"Connect info incomplete, cannot connect: [{0}:{1}]",
LoginServerAddress,
LoginServerPort
m_loginserver_address,
m_loginserver_port
);
return false;
}
if (IsLegacy) {
legacy_client = std::make_unique<EQ::Net::ServertalkLegacyClient>(LoginServerAddress, LoginServerPort, false);
legacy_client->OnConnect(
if (m_is_legacy) {
m_legacy_client = std::make_unique<EQ::Net::ServertalkLegacyClient>(
m_loginserver_address,
m_loginserver_port,
false
);
m_legacy_client->OnConnect(
[this](EQ::Net::ServertalkLegacyClient *client) {
if (client) {
LogInfo(
"Connected to Legacy Loginserver: [{0}:{1}]",
LoginServerAddress,
LoginServerPort
m_loginserver_address,
m_loginserver_port
);
SendInfo();
SendStatus();
zoneserver_list.SendLSZones();
statusupdate_timer = std::make_unique<EQ::Timer>(
LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) {
SendStatus();
}
m_statusupdate_timer = std::make_unique<EQ::Timer>(
LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) {
SendStatus();
}
);
}
else {
LogInfo(
"Could not connect to Legacy Loginserver: [{0}:{1}]",
LoginServerAddress,
LoginServerPort
m_loginserver_address,
m_loginserver_port
);
}
}
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_UsertoWorldReqLeg,
std::bind(
&LoginServer::ProcessUsertoWorldReqLeg,
@ -383,7 +391,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_UsertoWorldReq,
std::bind(
&LoginServer::ProcessUsertoWorldReq,
@ -392,7 +400,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_LSClientAuthLeg,
std::bind(
&LoginServer::ProcessLSClientAuthLegacy,
@ -401,7 +409,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_LSClientAuth,
std::bind(
&LoginServer::ProcessLSClientAuth,
@ -410,7 +418,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_LSFatalError,
std::bind(
&LoginServer::ProcessLSFatalError,
@ -419,7 +427,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_SystemwideMessage,
std::bind(
&LoginServer::ProcessSystemwideMessage,
@ -428,7 +436,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_LSRemoteAddr,
std::bind(
&LoginServer::ProcessLSRemoteAddr,
@ -437,7 +445,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
legacy_client->OnMessage(
m_legacy_client->OnMessage(
ServerOP_LSAccountUpdate,
std::bind(
&LoginServer::ProcessLSAccountUpdate,
@ -448,37 +456,43 @@ bool LoginServer::Connect()
);
}
else {
client = std::make_unique<EQ::Net::ServertalkClient>(LoginServerAddress, LoginServerPort, false, "World", "");
client->OnConnect(
m_client = std::make_unique<EQ::Net::ServertalkClient>(
m_loginserver_address,
m_loginserver_port,
false,
"World",
""
);
m_client->OnConnect(
[this](EQ::Net::ServertalkClient *client) {
if (client) {
LogInfo(
"Connected to Loginserver: [{0}:{1}]",
LoginServerAddress,
LoginServerPort
m_loginserver_address,
m_loginserver_port
);
SendInfo();
SendStatus();
zoneserver_list.SendLSZones();
statusupdate_timer = std::make_unique<EQ::Timer>(
m_statusupdate_timer = std::make_unique<EQ::Timer>(
LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) {
SendStatus();
}
);
LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) {
SendStatus();
}
);
}
else {
LogInfo(
"Could not connect to Loginserver: [{0}:{1}]",
LoginServerAddress,
LoginServerPort
m_loginserver_address,
m_loginserver_port
);
}
}
);
client->OnMessage(
m_client->OnMessage(
ServerOP_UsertoWorldReqLeg,
std::bind(
&LoginServer::ProcessUsertoWorldReqLeg,
@ -487,7 +501,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
client->OnMessage(
m_client->OnMessage(
ServerOP_UsertoWorldReq,
std::bind(
&LoginServer::ProcessUsertoWorldReq,
@ -496,7 +510,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
client->OnMessage(
m_client->OnMessage(
ServerOP_LSClientAuthLeg,
std::bind(
&LoginServer::ProcessLSClientAuthLegacy,
@ -505,7 +519,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
client->OnMessage(
m_client->OnMessage(
ServerOP_LSClientAuth,
std::bind(
&LoginServer::ProcessLSClientAuth,
@ -514,7 +528,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
client->OnMessage(
m_client->OnMessage(
ServerOP_LSFatalError,
std::bind(
&LoginServer::ProcessLSFatalError,
@ -523,7 +537,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
client->OnMessage(
m_client->OnMessage(
ServerOP_SystemwideMessage,
std::bind(
&LoginServer::ProcessSystemwideMessage,
@ -532,7 +546,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
client->OnMessage(
m_client->OnMessage(
ServerOP_LSRemoteAddr,
std::bind(
&LoginServer::ProcessLSRemoteAddr,
@ -541,7 +555,7 @@ bool LoginServer::Connect()
std::placeholders::_2
)
);
client->OnMessage(
m_client->OnMessage(
ServerOP_LSAccountUpdate,
std::bind(
&LoginServer::ProcessLSAccountUpdate,
@ -552,7 +566,10 @@ bool LoginServer::Connect()
);
}
m_keepalive = std::make_unique<EQ::Timer>(1000, true, std::bind(&LoginServer::OnKeepAlive, this, std::placeholders::_1));
m_keepalive = std::make_unique<EQ::Timer>(
1000,
true,
std::bind(&LoginServer::OnKeepAlive, this, std::placeholders::_1));
return true;
}
@ -566,28 +583,44 @@ void LoginServer::SendInfo()
pack->size = sizeof(ServerNewLSInfo_Struct);
pack->pBuffer = new uchar[pack->size];
memset(pack->pBuffer, 0, pack->size);
ServerNewLSInfo_Struct *lsi = (ServerNewLSInfo_Struct *) pack->pBuffer;
strcpy(lsi->protocol_version, EQEMU_PROTOCOL_VERSION);
strcpy(lsi->server_version, LOGIN_VERSION);
strcpy(lsi->server_long_name, Config->LongName.c_str());
strcpy(lsi->server_short_name, Config->ShortName.c_str());
strn0cpy(lsi->account_name, LoginAccount.c_str(), 30);
strn0cpy(lsi->account_password, LoginPassword.c_str(), 30);
auto *l = (ServerNewLSInfo_Struct *) pack->pBuffer;
strcpy(l->protocol_version, EQEMU_PROTOCOL_VERSION);
strcpy(l->server_version, LOGIN_VERSION);
strcpy(l->server_long_name, Config->LongName.c_str());
strcpy(l->server_short_name, Config->ShortName.c_str());
strn0cpy(l->account_name, m_login_account.c_str(), 30);
strn0cpy(l->account_password, m_login_password.c_str(), 30);
if (Config->WorldAddress.length()) {
strcpy(lsi->remote_ip_address, Config->WorldAddress.c_str());
strcpy(l->remote_ip_address, Config->WorldAddress.c_str());
}
if (Config->LocalAddress.length()) {
strcpy(lsi->local_ip_address, Config->LocalAddress.c_str());
strcpy(l->local_ip_address, Config->LocalAddress.c_str());
}
else {
auto local_addr = IsLegacy ? legacy_client->Handle()->LocalIP() : client->Handle()->LocalIP();
strcpy(lsi->local_ip_address, local_addr.c_str());
WorldConfig::SetLocalAddress(lsi->local_ip_address);
auto local_addr = m_is_legacy ? m_legacy_client->Handle()->LocalIP() : m_client->Handle()->LocalIP();
strcpy(l->local_ip_address, local_addr.c_str());
WorldConfig::SetLocalAddress(l->local_ip_address);
}
SanitizeWorldServerName(l->server_long_name);
LogInfo(
"[LoginServer::SendInfo] protocol_version [{}] server_version [{}] long_name [{}] short_name [{}] account_name [{}] remote_ip_address [{}] local_ip [{}]",
l->protocol_version,
l->server_version,
l->server_long_name,
l->server_short_name,
l->account_name,
l->remote_ip_address,
l->local_ip_address
);
SendPacket(pack);
delete pack;
}
void LoginServer::SendStatus()
{
auto pack = new ServerPacket;
@ -618,14 +651,14 @@ void LoginServer::SendStatus()
*/
void LoginServer::SendPacket(ServerPacket *pack)
{
if (IsLegacy) {
if (legacy_client) {
legacy_client->SendPacket(pack);
if (m_is_legacy) {
if (m_legacy_client) {
m_legacy_client->SendPacket(pack);
}
}
else {
if (client) {
client->SendPacket(pack);
if (m_client) {
m_client->SendPacket(pack);
}
}
}
@ -636,11 +669,11 @@ void LoginServer::SendAccountUpdate(ServerPacket *pack)
if (CanUpdate()) {
LogInfo(
"Sending ServerOP_LSAccountUpdate packet to loginserver: [{0}]:[{1}]",
LoginServerAddress,
LoginServerPort
m_loginserver_address,
m_loginserver_port
);
strn0cpy(ls_account_update->worldaccount, LoginAccount.c_str(), 30);
strn0cpy(ls_account_update->worldpassword, LoginPassword.c_str(), 30);
strn0cpy(ls_account_update->worldaccount, m_login_account.c_str(), 30);
strn0cpy(ls_account_update->worldpassword, m_login_password.c_str(), 30);
SendPacket(pack);
}
}

View File

@ -1,20 +1,3 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
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 LOGINSERVER_H
#define LOGINSERVER_H
@ -42,20 +25,20 @@ public:
void SendAccountUpdate(ServerPacket *pack);
bool Connected()
{
if (IsLegacy) {
if (legacy_client) {
return legacy_client->Connected();
if (m_is_legacy) {
if (m_legacy_client) {
return m_legacy_client->Connected();
}
}
else {
if (client) {
return client->Connected();
if (m_client) {
return m_client->Connected();
}
}
return false;
}
bool CanUpdate() { return CanAccountUpdate; }
bool CanUpdate() { return m_can_account_update; }
private:
void ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p);
@ -70,15 +53,15 @@ private:
void OnKeepAlive(EQ::Timer *t);
std::unique_ptr<EQ::Timer> m_keepalive;
std::unique_ptr<EQ::Net::ServertalkClient> client;
std::unique_ptr<EQ::Net::ServertalkLegacyClient> legacy_client;
std::unique_ptr<EQ::Timer> statusupdate_timer;
char LoginServerAddress[256];
uint32 LoginServerIP;
uint16 LoginServerPort;
std::string LoginAccount;
std::string LoginPassword;
bool CanAccountUpdate;
bool IsLegacy;
std::unique_ptr<EQ::Net::ServertalkClient> m_client;
std::unique_ptr<EQ::Net::ServertalkLegacyClient> m_legacy_client;
std::unique_ptr<EQ::Timer> m_statusupdate_timer;
char m_loginserver_address[256];
uint32 m_loginserver_ip;
uint16 m_loginserver_port;
std::string m_login_account;
std::string m_login_password;
bool m_can_account_update;
bool m_is_legacy;
};
#endif