mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
Working on login / world connection mostly there, fixed a few crashes with encryption on 0 length packets
This commit is contained in:
parent
0b8b41d91f
commit
f3e2af7e42
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 = ''";
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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()) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user