Working on login / world connection mostly there, fixed a few crashes with encryption on 0 length packets

This commit is contained in:
KimLS 2016-10-29 23:23:04 -07:00
parent 0b8b41d91f
commit f3e2af7e42
19 changed files with 441 additions and 412 deletions

View File

@ -17,8 +17,8 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode));
archive(zero,
opcode);
}
};
@ -34,11 +34,11 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(protocol_version),
CEREAL_NVP(connect_code),
CEREAL_NVP(max_packet_size));
archive(zero,
opcode,
protocol_version,
connect_code,
max_packet_size);
}
};
@ -57,14 +57,14 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(connect_code),
CEREAL_NVP(encode_key),
CEREAL_NVP(crc_bytes),
CEREAL_NVP(encode_pass1),
CEREAL_NVP(encode_pass2),
CEREAL_NVP(max_packet_size));
archive(zero,
opcode,
connect_code,
encode_key,
crc_bytes,
encode_pass1,
encode_pass2,
max_packet_size);
}
};
@ -78,9 +78,9 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(connect_code));
archive(zero,
opcode,
connect_code);
}
};
@ -94,9 +94,9 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(sequence));
archive(zero,
opcode,
sequence);
}
};
@ -109,8 +109,8 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(reliable),
CEREAL_NVP(total_size));
archive(reliable,
total_size);
}
};
@ -131,16 +131,16 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(timestamp),
CEREAL_NVP(stat_ping),
CEREAL_NVP(avg_ping),
CEREAL_NVP(min_ping),
CEREAL_NVP(max_ping),
CEREAL_NVP(last_ping),
CEREAL_NVP(packets_sent),
CEREAL_NVP(packets_recv));
archive(zero,
opcode,
timestamp,
stat_ping,
avg_ping,
min_ping,
max_ping,
last_ping,
packets_sent,
packets_recv);
}
};
@ -159,14 +159,14 @@ namespace EQ
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(timestamp),
CEREAL_NVP(our_timestamp),
CEREAL_NVP(client_sent),
CEREAL_NVP(client_recv),
CEREAL_NVP(server_sent),
CEREAL_NVP(server_recv));
archive(zero,
opcode,
timestamp,
our_timestamp,
client_sent,
client_recv,
server_sent,
server_recv);
}
};
}

View File

@ -26,11 +26,7 @@ namespace EQ {
template<typename T>
T GetSerialize(size_t offset) const
{
if (T::size() > (Length() - offset)) {
throw std::out_of_range("Packet::GetSerialize(), packet not large enough to cast to type.");
}
{
T ret;
Util::MemoryStreamReader reader(((char*)Data() + offset), Length());
cereal::BinaryInputArchive input(reader);

View File

@ -19,20 +19,23 @@ EQ::Net::ServertalkClient::~ServertalkClient()
{
}
void EQ::Net::ServertalkClient::Send(uint16_t opcode, EQ::Net::Packet & p)
void EQ::Net::ServertalkClient::Send(uint16_t opcode, EQ::Net::Packet &p)
{
EQ::Net::WritablePacket out;
#ifdef ENABLE_SECURITY
if (m_encrypted) {
if (p.Length() == 0) {
p.PutUInt8(0, 0);
}
out.PutUInt32(0, p.Length() + crypto_secretbox_MACBYTES);
out.PutUInt16(4, opcode);
unsigned char *cipher = new unsigned char[p.Length() + crypto_secretbox_MACBYTES];
crypto_box_easy_afternm(cipher, (unsigned char*)p.Data(), p.Length(), m_nonce_ours, m_shared_key);
std::unique_ptr<unsigned char[]> cipher(new unsigned char[p.Length() + crypto_secretbox_MACBYTES]);
crypto_box_easy_afternm(&cipher[0], (unsigned char*)p.Data(), p.Length(), m_nonce_ours, m_shared_key);
(*(uint64_t*)&m_nonce_ours[0])++;
out.PutData(6, cipher, p.Length() + crypto_secretbox_MACBYTES);
delete[] cipher;
out.PutData(6, &cipher[0], p.Length() + crypto_secretbox_MACBYTES);
}
else {
out.PutUInt32(0, p.Length());

View File

@ -22,8 +22,13 @@ void EQ::Net::ServertalkServerConnection::Send(uint16_t opcode, EQ::Net::Packet
EQ::Net::WritablePacket out;
#ifdef ENABLE_SECURITY
if (m_encrypted) {
if (p.Length() == 0) {
p.PutUInt8(0, 0);
}
out.PutUInt32(0, p.Length() + crypto_secretbox_MACBYTES);
out.PutUInt16(4, opcode);
std::unique_ptr<unsigned char[]> cipher(new unsigned char[p.Length() + crypto_secretbox_MACBYTES]);
crypto_box_easy_afternm(&cipher[0], (unsigned char*)p.Data(), p.Length(), m_nonce_ours, m_shared_key);

View File

@ -152,6 +152,15 @@ void DumpPacket(const ServerPacket* pack, bool iShowInfo) {
DumpPacketHex(pack->pBuffer, pack->size);
}
void DumpPacket(uint16 opcode, const EQ::Net::Packet &p, bool iShowInfo) {
if (iShowInfo) {
std::cout << "Dumping ServerPacket: 0x" << std::hex << std::setfill('0') << std::setw(4) << opcode << std::dec;
std::cout << " size:" << p.Length() << std::endl;
}
std::cout << p.ToString() << std::endl;
}
void DumpPacketBin(const ServerPacket* pack) {
DumpPacketBin(pack->pBuffer, pack->size);
}

View File

@ -18,7 +18,8 @@
#ifndef PACKET_DUMP_H
#define PACKET_DUMP_H
#include "../common/types.h"
#include "types.h"
#include "net/packet.h"
class ServerPacket;
@ -28,6 +29,7 @@ std::string DumpPacketHexToString(const uchar* buf, uint32 size, uint32 cols = 1
void DumpPacketBin(const void* data, uint32 len);
void DumpPacket(const uchar* buf, uint32 size);
void DumpPacket(const ServerPacket* pack, bool iShowInfo = false);
void DumpPacket(uint16 opcode, const EQ::Net::Packet &p, bool iShowInfo = false);
void DumpPacketBin(const ServerPacket* pack);
void DumpPacketBin(uint32 data);
void DumpPacketBin(uint16 data);

View File

@ -4,6 +4,8 @@
#include "../common/types.h"
#include "../common/packet_functions.h"
#include "../common/eq_packet_structs.h"
#include <cereal/cereal.hpp>
#include <cereal/types/string.hpp>
#define SERVER_TIMEOUT 45000 // how often keepalive gets sent
#define INTERSERVER_TIMER 10000
@ -524,14 +526,21 @@ struct ServerLSPlayerZoneChange_Struct {
uint32 from; // 0 = world
uint32 to; // 0 = world
};
struct ClientAuth_Struct {
uint32 lsaccount_id; // ID# in login server's db
char name[30]; // username in login server's db
char key[30]; // the Key the client will present
uint8 lsadmin; // login server admin level
int16 worldadmin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it
char ip[64];
uint8 local; // 1 if the client is from the local network
int lsaccount_id; // ID# in login server's db
std::string name; // username in login server's db
std::string key; // the Key the client will present
int lsadmin; // login server admin level
int worldadmin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it
std::string ip;
int local; // 1 if the client is from the local network
template <class Archive>
void serialize(Archive &ar)
{
ar(lsaccount_id, name, key, lsadmin, worldadmin, ip, local);
}
};
struct ServerSystemwideMessage {

View File

@ -187,13 +187,13 @@ void Client::Handle_Login(const char* data, unsigned int size)
status = cs_logged_in;
string entered_username;
string entered_password_hash_result;
std::string entered_username;
std::string entered_password_hash_result;
char *login_packet_buffer = nullptr;
unsigned int db_account_id = 0;
string db_account_password_hash;
std::string db_account_password_hash;
#ifdef WIN32
login_packet_buffer = server.eq_crypto->DecryptUsernamePassword(data, size, server.options.GetEncryptionMode());
@ -255,7 +255,7 @@ void Client::Handle_Login(const char* data, unsigned int size)
in_addr in;
in.s_addr = connection->GetRemoteIP();
server.db->UpdateLSAccountData(db_account_id, string(inet_ntoa(in)));
server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in)));
GenerateKey();
account_id = db_account_id;

View File

@ -28,8 +28,6 @@
#include <memory>
#include "../common/eq_stream_intf.h"
using namespace std;
enum LSClientVersion
{
cv_titanium,
@ -109,12 +107,12 @@ public:
/**
* Gets the account name of this client.
*/
string GetAccountName() const { return account_name; }
std::string GetAccountName() const { return account_name; }
/**
* Gets the key generated at login for this client.
*/
string GetKey() const { return key; }
std::string GetKey() const { return key; }
/**
* Gets the server selected to be played on for this client.
@ -137,11 +135,11 @@ private:
LSClientVersion version;
LSClientStatus status;
string account_name;
std::string account_name;
unsigned int account_id;
unsigned int play_server_id;
unsigned int play_sequence_id;
string key;
std::string key;
};
#endif

View File

@ -90,7 +90,7 @@ void ClientManager::Process()
{
ProcessDisconnect();
list<Client*>::iterator iter = clients.begin();
auto iter = clients.begin();
while(iter != clients.end())
{
if((*iter)->Process() == false)
@ -108,7 +108,7 @@ void ClientManager::Process()
void ClientManager::ProcessDisconnect()
{
list<Client*>::iterator iter = clients.begin();
auto iter = clients.begin();
while(iter != clients.end())
{
std::shared_ptr<EQStreamInterface> c = (*iter)->GetConnection();
@ -127,7 +127,7 @@ void ClientManager::ProcessDisconnect()
void ClientManager::UpdateServerList()
{
list<Client*>::iterator iter = clients.begin();
auto iter = clients.begin();
while(iter != clients.end())
{
(*iter)->SendServerListPacket();
@ -137,7 +137,7 @@ void ClientManager::UpdateServerList()
void ClientManager::RemoveExistingClient(unsigned int account_id)
{
list<Client*>::iterator iter = clients.begin();
auto iter = clients.begin();
while(iter != clients.end())
{
if((*iter)->GetAccountID() == account_id)
@ -157,7 +157,7 @@ Client *ClientManager::GetClient(unsigned int account_id)
{
Client *cur = nullptr;
int count = 0;
list<Client*>::iterator iter = clients.begin();
auto iter = clients.begin();
while(iter != clients.end())
{
if((*iter)->GetAccountID() == account_id)

View File

@ -24,8 +24,6 @@
#include "client.h"
#include <list>
using namespace std;
/**
* Client manager class, holds all the client objects and does basic processing.
*/
@ -68,7 +66,7 @@ private:
*/
void ProcessDisconnect();
list<Client*> clients;
std::list<Client*> clients;
OpcodeManager *titanium_ops;
EQ::Net::EQStreamManager *titanium_stream;
OpcodeManager *sod_ops;

View File

@ -26,7 +26,7 @@
extern EQEmuLogSys Log;
extern LoginServer server;
DatabaseMySQL::DatabaseMySQL(string user, string pass, string host, string port, string name)
DatabaseMySQL::DatabaseMySQL(std::string user, std::string pass, std::string host, std::string port, std::string name)
{
this->user = user;
this->pass = pass;
@ -59,7 +59,7 @@ DatabaseMySQL::~DatabaseMySQL()
}
}
bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, unsigned int &id)
bool DatabaseMySQL::GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id)
{
if (!database)
{
@ -68,7 +68,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, u
MYSQL_RES *res;
MYSQL_ROW row;
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() << " WHERE AccountName = '";
query << name;
query << "'";
@ -97,7 +97,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(string name, string &password, u
}
bool DatabaseMySQL::CreateLoginData(string name, string &password, unsigned int &id)
bool DatabaseMySQL::CreateLoginData(std::string name, std::string &password, unsigned int &id)
{
if (!database) {
return false;
@ -105,7 +105,7 @@ bool DatabaseMySQL::CreateLoginData(string name, string &password, unsigned int
MYSQL_RES *result;
MYSQL_ROW row;
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "INSERT INTO " << server.options.GetAccountTable() << " (AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) ";
query << " VALUES('" << name << "', '" << password << "', 'local_creation', NOW(), '127.0.0.1'); ";
@ -123,8 +123,8 @@ bool DatabaseMySQL::CreateLoginData(string name, string &password, unsigned int
return false;
}
bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, unsigned int &id, string &desc, unsigned int &list_id,
unsigned int &trusted, string &list_desc, string &account, string &password)
bool DatabaseMySQL::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)
{
if (!database)
{
@ -137,7 +137,7 @@ bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, un
unsigned long length;
length = mysql_real_escape_string(database, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length());
escaped_short_name[length + 1] = 0;
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "SELECT ifnull(WSR.ServerID,999999) AS ServerID, WSR.ServerTagDescription, ifnull(WSR.ServerTrusted,0) AS ServerTrusted, ifnull(SLT.ServerListTypeID,3) AS ServerListTypeID, ";
query << "SLT.ServerListTypeDescription, ifnull(WSR.ServerAdminID,0) AS ServerAdminID FROM " << server.options.GetWorldRegistrationTable();
query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID";
@ -166,7 +166,7 @@ bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, un
if (db_account_id > 0)
{
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "SELECT AccountName, AccountPassword FROM " << server.options.GetWorldAdminRegistrationTable();
query << " WHERE ServerAdminID = " << db_account_id;
@ -199,14 +199,14 @@ bool DatabaseMySQL::GetWorldRegistration(string long_name, string short_name, un
return false;
}
void DatabaseMySQL::UpdateLSAccountData(unsigned int id, string ip_address)
void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address)
{
if (!database)
{
return;
}
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "UPDATE " << server.options.GetAccountTable() << " SET LastIPAddress = '";
query << ip_address;
query << "', LastLoginDate = now() where LoginServerID = ";
@ -218,14 +218,14 @@ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, string ip_address)
}
}
void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, string name, string password, string email)
void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email)
{
if (!database)
{
return;
}
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "REPLACE " << server.options.GetAccountTable() << " SET LoginServerID = ";
query << id << ", AccountName = '" << name << "', AccountPassword = sha('";
query << password << "'), AccountCreateDate = now(), AccountEmail = '" << email;
@ -237,7 +237,7 @@ void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, string name, string pas
}
}
void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, string long_name, string ip_address)
void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address)
{
if (!database)
{
@ -248,7 +248,7 @@ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, string long_name, s
unsigned long length;
length = mysql_real_escape_string(database, escaped_long_name, long_name.substr(0, 100).c_str(), long_name.substr(0, 100).length());
escaped_long_name[length + 1] = 0;
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "UPDATE " << server.options.GetWorldRegistrationTable() << " SET ServerLastLoginDate = now(), ServerLastIPAddr = '";
query << ip_address;
query << "', ServerLongName = '";
@ -262,7 +262,7 @@ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, string long_name, s
}
}
bool DatabaseMySQL::CreateWorldRegistration(string long_name, string short_name, unsigned int &id)
bool DatabaseMySQL::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id)
{
if (!database)
{
@ -278,7 +278,7 @@ bool DatabaseMySQL::CreateWorldRegistration(string long_name, string short_name,
escaped_long_name[length + 1] = 0;
length = mysql_real_escape_string(database, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length());
escaped_short_name[length + 1] = 0;
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "SELECT ifnull(max(ServerID),0) FROM " << server.options.GetWorldRegistrationTable();
if (mysql_query(database, query.str().c_str()) != 0)
@ -295,7 +295,7 @@ bool DatabaseMySQL::CreateWorldRegistration(string long_name, string short_name,
id = atoi(row[0]) + 1;
mysql_free_result(res);
stringstream query(stringstream::in | stringstream::out);
std::stringstream query(std::stringstream::in | std::stringstream::out);
query << "INSERT INTO " << server.options.GetWorldRegistrationTable() << " SET ServerID = " << id;
query << ", ServerLongName = '" << escaped_long_name << "', ServerShortName = '" << escaped_short_name;
query << "', ServerListTypeID = 3, ServerAdminID = 0, ServerTrusted = 0, ServerTagDescription = ''";

View File

@ -26,8 +26,6 @@
#include <stdlib.h>
#include <libpq-fe.h>
using namespace std;
/**
* PostgreSQL Database class
*/
@ -42,7 +40,7 @@ public:
/**
* Constructor, tries to set our database to connect to the supplied options.
*/
DatabasePostgreSQL(string user, string pass, string host, string port, string name);
DatabasePostgreSQL(std::string user, std::string pass, std::string host, std::string port, std::string name);
/**
* Destructor, frees our database if needed.
@ -59,32 +57,32 @@ public:
* Needed for client login procedure.
* Returns true if the record was found, false otherwise.
*/
virtual bool GetLoginDataFromAccountName(string name, string &password, unsigned int &id);
virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id);
/**
* Retrieves the world registration from the long and short names provided.
* Needed for world login procedure.
* Returns true if the record was found, false otherwise.
*/
virtual bool GetWorldRegistration(string long_name, string short_name, unsigned int &id, string &desc, unsigned int &list_id,
unsigned int &trusted, string &list_desc, string &account, string &password);
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);
/**
* Updates the ip address of the client with account id = id
*/
virtual void UpdateLSAccountData(unsigned int id, string ip_address);
virtual void UpdateLSAccountData(unsigned int id, std::string ip_address);
/**
* Updates the ip address of the world with account id = id
*/
virtual void UpdateWorldRegistration(unsigned int id, string long_name, string ip_address);
virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address);
/**
* Creates new world registration for unregistered servers and returns new id
*/
virtual bool CreateWorldRegistration(string long_name, string short_name, unsigned int &id);
virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id);
protected:
string user, pass, host, port, name;
std::string user, pass, host, port, name;
PGconn *db;
};

View File

@ -89,7 +89,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c)
unsigned int server_count = 0;
in_addr in;
in.s_addr = c->GetConnection()->GetRemoteIP();
string client_ip = inet_ntoa(in);
std::string client_ip = inet_ntoa(in);
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
@ -103,7 +103,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c)
if (world_ip.compare(client_ip) == 0) {
packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24;
}
else if (client_ip.find(server.options.GetLocalNetwork()) != string::npos) {
else if (client_ip.find(server.options.GetLocalNetwork()) != std::string::npos) {
packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24;
}
else {
@ -142,7 +142,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c)
memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size());
data_pointer += ((*iter)->GetLocalIP().size() + 1);
}
else if (client_ip.find(server.options.GetLocalNetwork()) != string::npos) {
else if (client_ip.find(server.options.GetLocalNetwork()) != std::string::npos) {
memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size());
data_pointer += ((*iter)->GetLocalIP().size() + 1);
}
@ -228,7 +228,7 @@ void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int
}
}
bool ServerManager::ServerExists(string l_name, string s_name, WorldServer *ignore)
bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldServer *ignore)
{
auto iter = world_servers.begin();
while (iter != world_servers.end()) {
@ -246,7 +246,7 @@ bool ServerManager::ServerExists(string l_name, string s_name, WorldServer *igno
return false;
}
void ServerManager::DestroyServerByName(string l_name, string s_name, WorldServer *ignore)
void ServerManager::DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore)
{
auto iter = world_servers.begin();
while (iter != world_servers.end()) {

View File

@ -38,10 +38,10 @@ WorldServer::WorldServer(std::shared_ptr<EQ::Net::ServertalkServerConnection> c)
is_server_trusted = false;
is_server_logged_in = false;
c->OnMessage(ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
c->OnMessage(ServerOP_LSStatus, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
c->OnMessage(ServerOP_UsertoWorldResp, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
c->OnMessage(ServerOP_LSAccountUpdate, std::bind(&WorldServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
c->OnMessage(ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2));
c->OnMessage(ServerOP_LSStatus, std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2));
c->OnMessage(ServerOP_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()
@ -61,161 +61,180 @@ void WorldServer::Reset()
is_server_logged_in = false;
}
void WorldServer::ProcessPacket(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.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
}
if(server.options.IsDumpInPacketsOn())
if (server.options.IsDumpInPacketsOn())
{
Log.OutF(Logs::General, Logs::Login_Server, "{0}", p.ToString());
DumpPacket(opcode, p);
}
switch(opcode)
if (p.Length() < sizeof(ServerNewLSInfo_Struct))
{
case ServerOP_NewLSInfo:
Log.Out(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, "
"but was too small. Discarded to avoid buffer overrun.");
return;
}
if (server.options.IsWorldTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "New Login Info Recieved.");
}
ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)p.Data();
Handle_NewLSInfo(info);
}
void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p)
{
if (server.options.IsWorldTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(ServerLSStatus_Struct))
{
Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_LSStatus, "
"but was too small. Discarded to avoid buffer overrun.");
return;
}
if (server.options.IsWorldTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "World Server Status Recieved.");
}
ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)p.Data();
Handle_LSStatus(ls_status);
}
void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p)
{
if (server.options.IsWorldTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(UsertoWorldResponse_Struct))
{
Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, "
"but was too small. Discarded to avoid buffer overrun.");
return;
}
//I don't use world trace for this and here is why:
//Because this is a part of the client login procedure it makes tracking client errors
//While keeping world server spam with multiple servers connected almost impossible.
if (server.options.IsTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "User-To-World Response received.");
}
UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)p.Data();
Log.Out(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid);
Client *c = server.client_manager->GetClient(utwr->lsaccountid);
if (c)
{
Log.Out(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str());
EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct));
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer;
per->Sequence = c->GetPlaySequence();
per->ServerNumber = c->GetPlayServerID();
Log.Out(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
if (utwr->response > 0)
{
if(p.Length() < sizeof(ServerNewLSInfo_Struct))
{
Log.Out(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, "
"but was too small. Discarded to avoid buffer overrun.");
break;
}
if(server.options.IsWorldTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "New Login Info Recieved.");
}
ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)p.Data();
Handle_NewLSInfo(info);
per->Allowed = 1;
SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID());
}
switch (utwr->response)
{
case 1:
per->Message = 101;
break;
case 0:
per->Message = 326;
break;
case -1:
per->Message = 337;
break;
case -2:
per->Message = 338;
break;
case -3:
per->Message = 303;
break;
}
case ServerOP_LSStatus:
if (server.options.IsTraceOn())
{
if(p.Length() < sizeof(ServerLSStatus_Struct))
{
Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_LSStatus, "
"but was too small. Discarded to avoid buffer overrun.");
break;
}
if(server.options.IsWorldTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "World Server Status Recieved.");
}
ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)p.Data();
Handle_LSStatus(ls_status);
break;
Log.Out(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u",
per->Allowed, per->Sequence, per->ServerNumber, per->Message);
Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
}
case ServerOP_UsertoWorldResp:
if (server.options.IsDumpOutPacketsOn())
{
if(p.Length() < sizeof(UsertoWorldResponse_Struct))
{
Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, "
"but was too small. Discarded to avoid buffer overrun.");
break;
}
//I don't use world trace for this and here is why:
//Because this is a part of the client login procedure it makes tracking client errors
//While keeping world server spam with multiple servers connected almost impossible.
if(server.options.IsTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "User-To-World Response received.");
}
UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)p.Data();
Log.Out(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid);
Client *c = server.client_manager->GetClient(utwr->lsaccountid);
if(c)
{
Log.Out(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str());
EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct));
PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer;
per->Sequence = c->GetPlaySequence();
per->ServerNumber = c->GetPlayServerID();
Log.Out(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID());
Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
if(utwr->response > 0)
{
per->Allowed = 1;
SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID());
}
switch(utwr->response)
{
case 1:
per->Message = 101;
break;
case 0:
per->Message = 326;
break;
case -1:
per->Message = 337;
break;
case -2:
per->Message = 338;
break;
case -3:
per->Message = 303;
break;
}
if(server.options.IsTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u",
per->Allowed, per->Sequence, per->ServerNumber, per->Message);
Log.Out(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str());
}
if(server.options.IsDumpOutPacketsOn())
{
DumpPacket(outapp);
}
c->SendPlayResponse(outapp);
delete outapp;
}
else
{
Log.Out(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid);
}
break;
}
case ServerOP_LSAccountUpdate:
{
if(p.Length() < sizeof(ServerLSAccountUpdate_Struct))
{
Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerLSAccountUpdate_Struct, "
"but was too small. Discarded to avoid buffer overrun.");
break;
}
Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str());
ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)p.Data();
if(is_server_trusted)
{
Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount);
string name;
string password;
string email;
name.assign(lsau->useraccount);
password.assign(lsau->userpassword);
email.assign(lsau->useremail);
server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email);
}
break;
}
default:
{
Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had an unknown operation code 0x%.4X.", opcode);
DumpPacket(outapp);
}
c->SendPlayResponse(outapp);
delete outapp;
}
else
{
Log.Out(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid);
}
}
void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p)
{
if (server.options.IsWorldTraceOn())
{
Log.Out(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length());
}
if (server.options.IsDumpInPacketsOn())
{
DumpPacket(opcode, p);
}
if (p.Length() < sizeof(ServerLSAccountUpdate_Struct))
{
Log.Out(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerLSAccountUpdate_Struct, "
"but was too small. Discarded to avoid buffer overrun.");
return;
}
Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str());
ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)p.Data();
if (is_server_trusted)
{
Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount);
std::string name;
std::string password;
std::string email;
name.assign(lsau->useraccount);
password.assign(lsau->userpassword);
email.assign(lsau->useremail);
server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email);
}
}
@ -289,7 +308,6 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
{
if(strlen(i->remote_address) == 0)
{
in_addr in;
remote_ip = GetConnection()->Handle()->RemoteIP();
Log.Out(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.", remote_ip.c_str());
}
@ -300,7 +318,6 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
}
else
{
in_addr in;
remote_ip = GetConnection()->Handle()->RemoteIP();
Log.Out(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", remote_ip.c_str());
}
@ -352,10 +369,10 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
unsigned int s_id = 0;
unsigned int s_list_type = 0;
unsigned int s_trusted = 0;
string s_desc;
string s_list_desc;
string s_acct_name;
string s_acct_pass;
std::string s_desc;
std::string s_list_desc;
std::string s_acct_name;
std::string s_acct_pass;
if(server.db->GetWorldRegistration(long_name, short_name, s_id, s_desc, s_list_type, s_trusted, s_list_desc, s_acct_name, s_acct_pass))
{
if(s_acct_name.size() == 0 || s_acct_pass.size() == 0)
@ -378,8 +395,9 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
if(s_trusted) {
Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
is_server_trusted = true;
ServerPacket *outapp = new ServerPacket(ServerOP_LSAccountUpdate, 0);
connection->SendPacket(outapp);
EQ::Net::WritablePacket outapp;
connection->Send(ServerOP_LSAccountUpdate, outapp);
}
}
else {
@ -404,10 +422,10 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
unsigned int server_id = 0;
unsigned int server_list_type = 0;
unsigned int is_server_trusted = 0;
string server_description;
string server_list_description;
string server_account_name;
string server_account_password;
std::string server_description;
std::string server_list_description;
std::string server_account_name;
std::string server_account_password;
if(server.db->GetWorldRegistration(
@ -434,8 +452,8 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i)
if(is_server_trusted) {
Log.Out(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world");
is_server_trusted = true;
ServerPacket *outapp = new ServerPacket(ServerOP_LSAccountUpdate, 0);
connection->SendPacket(outapp);
EQ::Net::WritablePacket outapp;
connection->Send(ServerOP_LSAccountUpdate, outapp);
}
}
else {
@ -486,37 +504,36 @@ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s)
server_status = s->status;
}
void WorldServer::SendClientAuth(std::string ip, string account, string key, unsigned int account_id)
void WorldServer::SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id)
{
ServerPacket *outapp = new ServerPacket(ServerOP_LSClientAuth, sizeof(ClientAuth_Struct));
ClientAuth_Struct* client_auth = (ClientAuth_Struct*)outapp->pBuffer;
client_auth->lsaccount_id = account_id;
strncpy(client_auth->name, account.c_str(), account.size() > 30 ? 30 : account.size());
strncpy(client_auth->key, key.c_str(), 10);
client_auth->lsadmin = 0;
client_auth->worldadmin = 0;
strcpy(client_auth->ip, ip.c_str());
string client_address(ip);
string world_address(connection->Handle()->RemoteIP());
EQ::Net::WritablePacket outapp;
ClientAuth_Struct client_auth;
client_auth.lsaccount_id = account_id;
client_auth.name = account;
client_auth.key = key;
client_auth.lsadmin = 0;
client_auth.worldadmin = 0;
client_auth.ip = ip;
std::string client_address(ip);
std::string world_address(connection->Handle()->RemoteIP());
if (client_address.compare(world_address) == 0) {
client_auth->local = 1;
client_auth.local = 1;
}
else if (client_address.find(server.options.GetLocalNetwork()) != string::npos) {
client_auth->local = 1;
else if (client_address.find(server.options.GetLocalNetwork()) != std::string::npos) {
client_auth.local = 1;
}
else {
client_auth->local = 0;
client_auth.local = 0;
}
connection->SendPacket(outapp);
outapp.PutSerialize(0, client_auth);
connection->Send(ServerOP_LSClientAuth, outapp);
if (server.options.IsDumpInPacketsOn())
{
DumpPacket(outapp);
DumpPacket(ServerOP_LSClientAuth, outapp);
}
delete outapp;
}

View File

@ -46,11 +46,6 @@ public:
*/
void Reset();
/**
* Does processing of all the packets in for this world.
*/
void ProcessPacket(uint16_t opcode, const EQ::Net::Packet &p);
/**
* Accesses connection, it is intentional that this is not const (trust me).
*/
@ -133,6 +128,14 @@ public:
private:
/**
* Packet processing functions:
*/
void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p);
void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p);
void ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p);
void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p);
std::shared_ptr<EQ::Net::ServertalkServerConnection> connection;
unsigned int zones_booted;
unsigned int players_online;

View File

@ -53,95 +53,102 @@ LoginServer::LoginServer(const char* iAddress, uint16 iPort, const char* Account
LoginServer::~LoginServer() {
}
void LoginServer::ProcessPacket(uint16_t opcode, EQ::Net::Packet &p) {
const WorldConfig *Config=WorldConfig::get();
void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) {
const WorldConfig *Config = WorldConfig::get();
Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode);
/************ Get all packets from packet manager out queue and process them ************/
Log.Out(Logs::Detail, Logs::World_Server,"Recevied ServerPacket from LS OpCode 0x04x", opcode);
UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data();
uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid);
int16 status = database.CheckStatus(id);
switch(opcode) {
case ServerOP_UsertoWorldReq: {
UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data();
uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid);
int16 status = database.CheckStatus(id);
auto outpack = new ServerPacket;
outpack->opcode = ServerOP_UsertoWorldResp;
outpack->size = sizeof(UsertoWorldResponse_Struct);
outpack->pBuffer = new uchar[outpack->size];
memset(outpack->pBuffer, 0, outpack->size);
UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*)outpack->pBuffer;
utwrs->lsaccountid = utwr->lsaccountid;
utwrs->ToID = utwr->FromID;
auto outpack = new ServerPacket;
outpack->opcode = ServerOP_UsertoWorldResp;
outpack->size = sizeof(UsertoWorldResponse_Struct);
outpack->pBuffer = new uchar[outpack->size];
memset(outpack->pBuffer, 0, outpack->size);
UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*) outpack->pBuffer;
utwrs->lsaccountid = utwr->lsaccountid;
utwrs->ToID = utwr->FromID;
if(Config->Locked == true)
{
if((status == 0 || status < 100) && (status != -2 || status != -1))
utwrs->response = 0;
if(status >= 100)
utwrs->response = 1;
}
else {
utwrs->response = 1;
}
int32 x = Config->MaxClients;
if( (int32)numplayers >= x && x != -1 && x != 255 && status < 80)
utwrs->response = -3;
if(status == -1)
utwrs->response = -1;
if(status == -2)
utwrs->response = -2;
utwrs->worldid = utwr->worldid;
SendPacket(outpack);
delete outpack;
break;
}
case ServerOP_LSClientAuth: {
ClientAuth_Struct* slsca = (ClientAuth_Struct*)p.Data();
if (RuleI(World, AccountSessionLimit) >= 0) {
// Enforce the limit on the number of characters on the same account that can be
// online at the same time.
client_list.EnforceSessionLimit(slsca->lsaccount_id);
}
client_list.CLEAdd(slsca->lsaccount_id, slsca->name, slsca->key, slsca->worldadmin, inet_addr(slsca->ip), slsca->local);
break;
}
case ServerOP_LSFatalError: {
Log.Out(Logs::Detail, Logs::World_Server, "Login server responded with FatalError.");
if (p.Length() > 1) {
Log.Out(Logs::Detail, Logs::World_Server, " %s", (const char*)p.Data());
}
break;
}
case ServerOP_SystemwideMessage: {
ServerSystemwideMessage* swm = (ServerSystemwideMessage*)p.Data();
zoneserver_list.SendEmoteMessageRaw(0, 0, 0, swm->type, swm->message);
break;
}
case ServerOP_LSRemoteAddr: {
if (!Config->WorldAddress.length()) {
WorldConfig::SetWorldAddress((char *)p.Data());
Log.Out(Logs::Detail, Logs::World_Server, "Loginserver provided %s as world address", (const char*)p.Data());
}
break;
}
case ServerOP_LSAccountUpdate: {
Log.Out(Logs::Detail, Logs::World_Server, "Received ServerOP_LSAccountUpdate packet from loginserver");
CanAccountUpdate = true;
break;
}
default:
{
Log.Out(Logs::Detail, Logs::World_Server, "Unknown LSOpCode: 0x%04x size=%d",(int)opcode, p.Length());
Log.OutF(Logs::General, Logs::Login_Server, "{0}", p.ToString());
break;
}
if (Config->Locked == true)
{
if ((status == 0 || status < 100) && (status != -2 || status != -1))
utwrs->response = 0;
if (status >= 100)
utwrs->response = 1;
}
else {
utwrs->response = 1;
}
int32 x = Config->MaxClients;
if ((int32)numplayers >= x && x != -1 && x != 255 && status < 80)
utwrs->response = -3;
if (status == -1)
utwrs->response = -1;
if (status == -2)
utwrs->response = -2;
utwrs->worldid = utwr->worldid;
SendPacket(outpack);
delete outpack;
}
void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) {
const WorldConfig *Config = WorldConfig::get();
Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode);
try {
auto slsca = p.GetSerialize<ClientAuth_Struct>(0);
if (RuleI(World, AccountSessionLimit) >= 0) {
// Enforce the limit on the number of characters on the same account that can be
// online at the same time.
client_list.EnforceSessionLimit(slsca.lsaccount_id);
}
client_list.CLEAdd(slsca.lsaccount_id, slsca.name.c_str(), slsca.key.c_str(), slsca.worldadmin, inet_addr(slsca.ip.c_str()), slsca.local);
}
catch (std::exception &ex) {
Log.OutF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what());
}
}
void LoginServer::ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p) {
const WorldConfig *Config = WorldConfig::get();
Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode);
Log.Out(Logs::Detail, Logs::World_Server, "Login server responded with FatalError.");
if (p.Length() > 1) {
Log.Out(Logs::Detail, Logs::World_Server, " %s", (const char*)p.Data());
}
}
void LoginServer::ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p) {
const WorldConfig *Config = WorldConfig::get();
Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode);
ServerSystemwideMessage* swm = (ServerSystemwideMessage*)p.Data();
zoneserver_list.SendEmoteMessageRaw(0, 0, 0, swm->type, swm->message);
}
void LoginServer::ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p) {
const WorldConfig *Config = WorldConfig::get();
Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode);
if (!Config->WorldAddress.length()) {
WorldConfig::SetWorldAddress((char *)p.Data());
Log.Out(Logs::Detail, Logs::World_Server, "Loginserver provided %s as world address", (const char*)p.Data());
}
}
void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p) {
const WorldConfig *Config = WorldConfig::get();
Log.Out(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode);
Log.Out(Logs::Detail, Logs::World_Server, "Received ServerOP_LSAccountUpdate packet from loginserver");
CanAccountUpdate = true;
}
bool LoginServer::Connect() {
@ -189,12 +196,12 @@ bool LoginServer::Connect() {
}
});
client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSRemoteAddr, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSAccountUpdate, std::bind(&LoginServer::ProcessPacket, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessUsertoWorldReq, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessLSClientAuth, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessLSFatalError, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessSystemwideMessage, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSRemoteAddr, std::bind(&LoginServer::ProcessLSRemoteAddr, this, std::placeholders::_1, std::placeholders::_2));
client->OnMessage(ServerOP_LSAccountUpdate, std::bind(&LoginServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2));
}
void LoginServer::SendInfo() {
const WorldConfig *Config=WorldConfig::get();

View File

@ -33,7 +33,6 @@ public:
LoginServer(const char*, uint16, const char*, const char*);
~LoginServer();
void ProcessPacket(uint16_t opcode, EQ::Net::Packet &p);
bool Connect();
void SendInfo();
@ -47,6 +46,13 @@ public:
bool CanUpdate() { return CanAccountUpdate; }
private:
void ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p);
void ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p);
void ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p);
void ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p);
void ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p);
void ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p);
bool minilogin;
std::unique_ptr<EQ::Net::ServertalkClient> client;
std::unique_ptr<EQ::Timer> statusupdate_timer;

View File

@ -415,28 +415,6 @@ int main(int argc, char** argv) {
Log.OutF(Logs::Detail, Logs::World_Server, "New connection from IP {0}:{1}", stream->RemoteEndpoint(), ntohs(stream->GetRemotePort()));
});
EQ::Net::ServertalkServer server;
EQ::Net::ServertalkServerOptions stopts;
stopts.port = 5999;
stopts.credentials = "User:Root;Password:1234567890";
stopts.encrypted = true;
server.Listen(stopts);
server.OnConnectionIdentified("QueryServ", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> conn) {
Log.Out(Logs::General, Logs::Debug, "New QueryServ Connection....");
EQ::Net::WritablePacket out;
out.PutCString(0, "Hello");
conn->Send(1, out);
conn->OnMessage(2, [&](uint16_t opcode, EQ::Net::Packet &p) {
Log.OutF(Logs::General, Logs::Debug, "Server got message of type {0}\n{1}", opcode, p.ToString());
});
});
server.OnConnectionRemoved("QueryServ", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> conn) {
Log.Out(Logs::General, Logs::Debug, "Lost QueryServ connection.");
});
while(RunLoops) {
Timer::SetCurrentTime();
eqs = nullptr;