Legacy connection wip

This commit is contained in:
KimLS
2016-11-07 21:03:06 -08:00
parent 3e38055f20
commit f07b5d9032
26 changed files with 384 additions and 170 deletions
+6
View File
@@ -72,11 +72,13 @@ SET(common_sources
worldconn.cpp
xml_parser.cpp
platform.cpp
event/event_loop.cpp
net/crc32.cpp
net/daybreak_connection.cpp
net/eqstream.cpp
net/packet.cpp
net/servertalk_client_connection.cpp
net/servertalk_legacy_client_connection.cpp
net/servertalk_server.cpp
net/servertalk_server_connection.cpp
net/tcp_connection.cpp
@@ -224,6 +226,7 @@ SET(common_headers
net/eqstream.h
net/packet.h
net/servertalk_client_connection.h
net/servertalk_legacy_client_connection.h
net/servertalk_common.h
net/servertalk_server.h
net/servertalk_server_connection.h
@@ -286,6 +289,7 @@ SET(common_headers
SOURCE_GROUP(Event FILES
event/background_task.h
event/event_loop.cpp
event/event_loop.h
event/timer.h
)
@@ -306,6 +310,8 @@ SOURCE_GROUP(Net FILES
net/packet.h
net/servertalk_client_connection.cpp
net/servertalk_client_connection.h
net/servertalk_legacy_client_connection.cpp
net/servertalk_legacy_client_connection.h
net/servertalk_common.h
net/servertalk_server.cpp
net/servertalk_server.h
-2
View File
@@ -1534,8 +1534,6 @@ uint32 Database::GetGroupID(const char* name){
if (results.RowCount() == 0)
{
// Commenting this out until logging levels can prevent this from going to console
//Log.Out(Logs::General, Logs::None,, "Character not in a group: %s", name);
return 0;
}
+12
View File
@@ -66,6 +66,10 @@ void EQEmuConfig::do_world(TiXmlElement *ele)
if (text) {
LoginPort = atoi(text);
}
text = ParseTextBlock(sub_ele, "legacy", true);
if (text) {
LoginLegacy = atoi(text) > 0 ? true : false;
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
LoginAccount = text;
@@ -89,6 +93,10 @@ void EQEmuConfig::do_world(TiXmlElement *ele)
if (text) {
loginconfig->LoginPort = atoi(text);
}
text = ParseTextBlock(sub_ele, "legacy", true);
if (text) {
loginconfig->LoginLegacy = atoi(text) > 0 ? true : false;
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
loginconfig->LoginAccount = text;
@@ -370,6 +378,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
if (var_name == "LoginPort") {
return (itoa(LoginPort));
}
if (var_name == "LoginLegacy") {
return (itoa(LoginLegacy ? 1 : 0));
}
if (var_name == "Locked") {
return (Locked ? "true" : "false");
}
@@ -495,6 +506,7 @@ void EQEmuConfig::Dump() const
std::cout << "LoginAccount = " << LoginAccount << std::endl;
std::cout << "LoginPassword = " << LoginPassword << std::endl;
std::cout << "LoginPort = " << LoginPort << std::endl;
std::cout << "LoginLegacy = " << LoginLegacy << std::endl;
std::cout << "Locked = " << Locked << std::endl;
std::cout << "WorldTCPPort = " << WorldTCPPort << std::endl;
std::cout << "WorldIP = " << WorldIP << std::endl;
+4 -1
View File
@@ -26,6 +26,7 @@ struct LoginConfig {
std::string LoginAccount;
std::string LoginPassword;
uint16 LoginPort;
bool LoginLegacy;
};
class EQEmuConfig : public XMLParser
@@ -42,6 +43,7 @@ class EQEmuConfig : public XMLParser
std::string LoginAccount;
std::string LoginPassword;
uint16 LoginPort;
bool LoginLegacy;
uint32 LoginCount;
LinkedList<LoginConfig*> loginlist;
bool Locked;
@@ -127,8 +129,9 @@ class EQEmuConfig : public XMLParser
#include "eqemu_config_elements.h"
// Set sane defaults
// Login server
LoginHost = "eqemulator.net";
LoginHost = "login.eqemulator.net";
LoginPort = 5998;
LoginLegacy = true;
// World
Locked = false;
WorldTCPPort = 9000;
View File
+36 -45
View File
@@ -19,7 +19,6 @@ EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConn
m_attached = nullptr;
m_options = opts;
memset(&m_timer, 0, sizeof(uv_timer_t));
memset(&m_resend_timer, 0, sizeof(uv_timer_t));
memset(&m_socket, 0, sizeof(uv_udp_t));
Attach(EQ::EventLoop::Get().Handle());
@@ -34,19 +33,15 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
{
if (!m_attached) {
uv_timer_init(loop, &m_timer);
uv_timer_init(loop, &m_resend_timer);
m_timer.data = this;
m_resend_timer.data = this;
auto update_rate = (uint64_t)(1000.0 / m_options.tic_rate_hertz);
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
c->Process();
}, 2, 2);
uv_timer_start(&m_resend_timer, [](uv_timer_t *handle) {
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
c->ProcessResend();
}, 5, 5);
}, update_rate, update_rate);
uv_udp_init(loop, &m_socket);
m_socket.data = this;
@@ -187,12 +182,12 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
try {
auto connection = FindConnectionByEndpoint(endpoint, port);
if (connection) {
ReadOnlyPacket p((void*)data, size);
StaticPacket p((void*)data, size);
connection->ProcessPacket(p);
}
else {
if (data[0] == 0 && data[1] == OP_SessionRequest) {
ReadOnlyPacket p((void*)data, size);
StaticPacket p((void*)data, size);
auto request = p.GetSerialize<DaybreakConnect>(0);
connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, request, endpoint, port));
@@ -232,7 +227,7 @@ void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr,
header.opcode = OP_SessionDisconnect;
header.connect_code = 0;
WritablePacket out;
DynamicPacket out;
out.PutSerialize(0, header);
uv_udp_send_t *send_req = new uv_udp_send_t;
@@ -270,6 +265,9 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
m_buffered_packets_length = 0;
m_resend_delay = m_owner->m_options.resend_delay_ms;
m_rolling_ping = 100;
m_combined.reset(new char[512]);
m_combined[0] = 0;
m_combined[1] = OP_Combined;
m_last_session_stats = Clock::now();
}
@@ -304,7 +302,7 @@ void EQ::Net::DaybreakConnection::Close()
disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code);
WritablePacket out;
DynamicPacket out;
out.PutSerialize(0, disconnect);
InternalSend(out);
@@ -328,7 +326,7 @@ void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream)
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliable)
{
if (*(char*)p.Data() == 0) {
WritablePacket packet;
DynamicPacket packet;
packet.PutUInt8(0, 0);
packet.PutPacket(1, p);
InternalQueuePacket(packet, stream, reliable);
@@ -395,7 +393,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
return;
}
EQ::Net::WritablePacket temp;
EQ::Net::DynamicPacket temp;
temp.PutPacket(0, p);
temp.Resize(temp.Length() - m_crc_bytes);
@@ -412,7 +410,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
}
}
ProcessDecodedPacket(ReadOnlyPacket(temp.Data(), temp.Length()));
ProcessDecodedPacket(StaticPacket(temp.Data(), temp.Length()));
}
else {
ProcessDecodedPacket(p);
@@ -454,7 +452,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac
auto s = &m_streams[stream];
auto iter = s->packet_queue.find(seq);
if (iter == s->packet_queue.end()) {
WritablePacket *out = new WritablePacket();
DynamicPacket *out = new DynamicPacket();
out->PutPacket(0, p);
s->packet_queue.insert(std::make_pair(seq, out));
@@ -480,7 +478,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
return;
}
ProcessDecodedPacket(ReadOnlyPacket(current, subpacket_length));
ProcessDecodedPacket(StaticPacket(current, subpacket_length));
current += subpacket_length;
}
break;
@@ -525,7 +523,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
current += 1;
}
ProcessDecodedPacket(ReadOnlyPacket(current, subpacket_length));
ProcessDecodedPacket(StaticPacket(current, subpacket_length));
current += subpacket_length;
}
}
@@ -548,7 +546,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
reply.max_packet_size = HostToNetwork(m_max_packet_size);
reply.encode_pass1 = m_encode_passes[0];
reply.encode_pass2 = m_encode_passes[1];
WritablePacket p;
DynamicPacket p;
p.PutSerialize(0, reply);
InternalSend(p);
}
@@ -578,7 +576,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
RemoveFromQueue(stream_id, sequence);
SendAck(stream_id, stream->sequence_in);
stream->sequence_in++;
ReadOnlyPacket next((char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
StaticPacket next((char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
ProcessDecodedPacket(next);
}
@@ -670,7 +668,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code);
WritablePacket out;
DynamicPacket out;
out.PutSerialize(0, disconnect);
InternalSend(out);
}
@@ -683,7 +681,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
{
auto self = m_self.lock();
if (m_owner->m_on_packet_recv && self) {
m_owner->m_on_packet_recv(self, ReadOnlyPacket((char*)p.Data() + 1, p.Length() - 1));
m_owner->m_on_packet_recv(self, StaticPacket((char*)p.Data() + 1, p.Length() - 1));
}
break;
}
@@ -700,7 +698,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
response.client_recv = request.packets_recv;
response.server_sent = EQ::Net::HostToNetwork(m_stats.sent_packets);
response.server_recv = EQ::Net::HostToNetwork(m_stats.recv_packets);
WritablePacket out;
DynamicPacket out;
out.PutSerialize(0, response);
InternalSend(out);
break;
@@ -1023,7 +1021,7 @@ void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
ack.opcode = OP_Ack + stream_id;
ack.sequence = HostToNetwork(seq);
WritablePacket p;
DynamicPacket p;
p.PutSerialize(0, ack);
InternalBufferedSend(p);
@@ -1036,7 +1034,7 @@ void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
ack.opcode = OP_OutOfOrderAck + stream_id;
ack.sequence = HostToNetwork(seq);
WritablePacket p;
DynamicPacket p;
p.PutSerialize(0, ack);
InternalBufferedSend(p);
@@ -1076,7 +1074,7 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
FlushBuffer();
}
WritablePacket copy;
DynamicPacket copy;
copy.PutPacket(0, p);
m_buffered_packets.push_back(copy);
m_buffered_packets_length += p.Length();
@@ -1095,7 +1093,7 @@ void EQ::Net::DaybreakConnection::SendConnect()
connect.connect_code = (uint32_t)HostToNetwork(m_connect_code);
connect.max_packet_size = HostToNetwork((uint32_t)m_owner->m_options.max_packet_size);
WritablePacket p;
DynamicPacket p;
p.PutSerialize(0, connect);
InternalSend(p);
@@ -1107,7 +1105,7 @@ void EQ::Net::DaybreakConnection::SendKeepAlive()
keep_alive.zero = 0;
keep_alive.opcode = OP_KeepAlive;
WritablePacket p;
DynamicPacket p;
p.PutSerialize(0, keep_alive);
InternalSend(p);
@@ -1123,7 +1121,7 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p)
};
if (PacketCanBeEncoded(p)) {
WritablePacket out;
DynamicPacket out;
out.PutPacket(0, p);
for (int i = 0; i < 2; ++i) {
@@ -1210,7 +1208,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
size_t used = 0;
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size();
WritablePacket first_packet;
DynamicPacket first_packet;
first_packet.PutSerialize(0, first_header);
first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
used += sublen;
@@ -1227,7 +1225,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
while (used < length) {
auto left = length - used;
WritablePacket packet;
DynamicPacket packet;
DaybreakReliableHeader header;
header.zero = 0;
header.opcode = OP_Fragment + stream_id;
@@ -1255,7 +1253,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
}
}
else {
WritablePacket packet;
DynamicPacket packet;
DaybreakReliableHeader header;
header.zero = 0;
header.opcode = OP_Packet + stream_id;
@@ -1282,22 +1280,15 @@ void EQ::Net::DaybreakConnection::FlushBuffer()
}
if (m_buffered_packets.size() > 1) {
WritablePacket out;
DaybreakHeader header;
header.zero = 0;
header.opcode = OP_Combined;
size_t offset = 0;
out.PutSerialize(offset, header);
offset += DaybreakHeader::size();
StaticPacket out(m_combined.get(), 512);
size_t length = 2;
for (auto &p : m_buffered_packets) {
out.PutUInt8(offset, (uint8_t)p.Length());
offset += 1;
out.PutPacket(offset, p);
offset += p.Length();
out.PutUInt8(length, (uint8_t)p.Length());
out.PutPacket(length + 1, p);
length += (1 + p.Length());
}
out.Resize(length);
InternalSend(out);
}
else {
+11 -9
View File
@@ -140,8 +140,9 @@ namespace EQ
Timestamp m_last_recv;
DbProtocolStatus m_status;
Timestamp m_hold_time;
std::list<WritablePacket> m_buffered_packets;
std::list<DynamicPacket> m_buffered_packets;
size_t m_buffered_packets_length;
std::unique_ptr<char[]> m_combined;
Timestamp m_last_stats;
DaybreakConnectionStats m_stats;
Timestamp m_last_session_stats;
@@ -150,7 +151,7 @@ namespace EQ
struct DaybreakSentPacket
{
WritablePacket packet;
DynamicPacket packet;
Timestamp last_sent;
Timestamp first_sent;
size_t times_resent;
@@ -169,7 +170,7 @@ namespace EQ
uint16_t sequence_out;
std::map<uint16_t, Packet*> packet_queue;
WritablePacket fragment_packet;
DynamicPacket fragment_packet;
uint32_t fragment_current_bytes;
uint32_t fragment_total_bytes;
@@ -216,12 +217,12 @@ namespace EQ
{
DaybreakConnectionManagerOptions() {
max_connection_count = 0;
keepalive_delay_ms = 0;
resend_delay_ms = 10;
resend_delay_factor = 1.25;
stats_delay_ms = 0;
keepalive_delay_ms = 9000;
resend_delay_ms = 25;
resend_delay_factor = 1.5;
stats_delay_ms = 9000;
connect_delay_ms = 1000;
stale_connection_ms = 135000;
stale_connection_ms = 30000;
crc_length = 2;
max_packet_size = 512;
encode_passes[0] = DaybreakEncodeType::EncodeNone;
@@ -231,6 +232,7 @@ namespace EQ
hold_length_ms = 50;
simulated_in_packet_loss = 0;
simulated_out_packet_loss = 0;
tic_rate_hertz = 20.0;
}
size_t max_packet_size;
@@ -246,6 +248,7 @@ namespace EQ
size_t hold_length_ms;
size_t simulated_in_packet_loss;
size_t simulated_out_packet_loss;
double tic_rate_hertz;
DaybreakEncodeType encode_passes[2];
int port;
};
@@ -269,7 +272,6 @@ namespace EQ
EQEmu::Random m_rand;
uv_timer_t m_timer;
uv_timer_t m_resend_timer;
uv_udp_t m_socket;
uv_loop_t *m_attached;
DaybreakConnectionManagerOptions m_options;
+2 -2
View File
@@ -42,7 +42,7 @@ void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnec
auto iter = m_streams.find(connection);
if (iter != m_streams.end()) {
auto &stream = iter->second;
std::unique_ptr<EQ::Net::Packet> t(new EQ::Net::WritablePacket());
std::unique_ptr<EQ::Net::Packet> t(new EQ::Net::DynamicPacket());
t->PutPacket(0, p);
stream->m_packet_queue.push_back(std::move(t));
@@ -73,7 +73,7 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
opcode = (*m_opcode_manager)->EmuToEQ(p->GetOpcode());
}
EQ::Net::WritablePacket out;
EQ::Net::DynamicPacket out;
switch (m_owner->m_options.opcode_size) {
case 1:
out.PutUInt8(0, opcode);
+9
View File
@@ -334,3 +334,12 @@ std::string EQ::Net::Packet::ToString(size_t line_length) const
return ret;
}
bool EQ::Net::StaticPacket::Resize(size_t new_size)
{
if (new_size > m_max_data_length) {
return false;
}
m_data_length = new_size;
}
+20 -17
View File
@@ -13,7 +13,7 @@ namespace EQ {
class Packet
{
public:
Packet() { }
Packet() : m_stream(std::ios::out | std::ios::binary) { }
virtual ~Packet() { }
virtual const void *Data() const = 0;
@@ -36,11 +36,11 @@ namespace EQ {
template<typename T>
void PutSerialize(size_t offset, const T &value) {
std::stringstream buffer(std::ios::in | std::ios::out | std::ios::binary);
cereal::BinaryOutputArchive output(buffer);
m_stream.clear();
cereal::BinaryOutputArchive output(m_stream);
output(value);
auto str = buffer.str();
auto &str = m_stream.str();
if (Length() < offset + str.length()) {
if (!Resize(offset + str.length())) {
throw std::out_of_range("Packet::PutSerialize(), could not resize packet and would of written past the end.");
@@ -80,38 +80,41 @@ namespace EQ {
std::string ToString() const;
std::string ToString(size_t line_length) const;
protected:
std::stringstream m_stream;
};
class ReadOnlyPacket : public Packet
class StaticPacket : public Packet
{
public:
ReadOnlyPacket(void *data, size_t size) { m_data = data; m_data_length = size; }
virtual ~ReadOnlyPacket() { }
ReadOnlyPacket(const ReadOnlyPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; }
ReadOnlyPacket& operator=(const ReadOnlyPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; return *this; }
ReadOnlyPacket(ReadOnlyPacket &&o) { m_data = o.m_data; m_data_length = o.m_data_length; }
StaticPacket(void *data, size_t size) { m_data = data; m_data_length = size; m_max_data_length = size; }
virtual ~StaticPacket() { }
StaticPacket(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; }
StaticPacket& operator=(const StaticPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; return *this; }
StaticPacket(StaticPacket &&o) { m_data = o.m_data; m_data_length = o.m_data_length; }
virtual const void *Data() const { return m_data; }
virtual void *Data() { return m_data; }
virtual size_t Length() const { return m_data_length; }
virtual size_t Length() { return m_data_length; }
virtual bool Clear() { return false; }
virtual bool Resize(size_t new_size) { return false; }
virtual bool Resize(size_t new_size);
virtual void Reserve(size_t new_size) { }
protected:
void *m_data;
size_t m_data_length;
size_t m_max_data_length;
};
class WritablePacket : public Packet
class DynamicPacket : public Packet
{
public:
WritablePacket() { }
virtual ~WritablePacket() { }
WritablePacket(WritablePacket &&o) { m_data = std::move(o.m_data); }
WritablePacket(const WritablePacket &o) { m_data = o.m_data; }
WritablePacket& operator=(const WritablePacket &o) { m_data = o.m_data; return *this; }
DynamicPacket() { }
virtual ~DynamicPacket() { }
DynamicPacket(DynamicPacket &&o) { m_data = std::move(o.m_data); }
DynamicPacket(const DynamicPacket &o) { m_data = o.m_data; }
DynamicPacket& operator=(const DynamicPacket &o) { m_data = o.m_data; return *this; }
virtual const void *Data() const { return &m_data[0]; }
virtual void *Data() { return &m_data[0]; }
+9 -9
View File
@@ -21,7 +21,7 @@ EQ::Net::ServertalkClient::~ServertalkClient()
void EQ::Net::ServertalkClient::Send(uint16_t opcode, EQ::Net::Packet &p)
{
EQ::Net::WritablePacket out;
EQ::Net::DynamicPacket out;
#ifdef ENABLE_SECURITY
if (m_encrypted) {
if (p.Length() == 0) {
@@ -52,7 +52,7 @@ void EQ::Net::ServertalkClient::Send(uint16_t opcode, EQ::Net::Packet &p)
void EQ::Net::ServertalkClient::SendPacket(ServerPacket *p)
{
EQ::Net::ReadOnlyPacket pout(p->pBuffer, p->size);
EQ::Net::StaticPacket pout(p->pBuffer, p->size);
Send(p->opcode, pout);
}
@@ -99,7 +99,7 @@ void EQ::Net::ServertalkClient::ProcessData(EQ::Net::TCPConnection *c, const uns
void EQ::Net::ServertalkClient::SendHello()
{
EQ::Net::WritablePacket p;
EQ::Net::DynamicPacket p;
InternalSend(ServertalkClientHello, p);
}
@@ -108,7 +108,7 @@ void EQ::Net::ServertalkClient::InternalSend(ServertalkPacketType type, EQ::Net:
if (!m_connection)
return;
EQ::Net::WritablePacket out;
EQ::Net::DynamicPacket out;
out.PutUInt32(0, (uint32_t)p.Length());
out.PutUInt8(4, (uint8_t)type);
if (p.Length() > 0) {
@@ -145,7 +145,7 @@ void EQ::Net::ServertalkClient::ProcessReadBuffer()
}
if (length == 0) {
EQ::Net::WritablePacket p;
EQ::Net::DynamicPacket p;
switch (type) {
case ServertalkServerHello:
ProcessHello(p);
@@ -156,7 +156,7 @@ void EQ::Net::ServertalkClient::ProcessReadBuffer()
}
}
else {
EQ::Net::ReadOnlyPacket p(&m_buffer[current + 5], length);
EQ::Net::StaticPacket p(&m_buffer[current + 5], length);
switch (type) {
case ServertalkServerHello:
ProcessHello(p);
@@ -272,7 +272,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p)
return;
}
EQ::Net::ReadOnlyPacket decrypted_packet(&decrypted_text[0], message_len);
EQ::Net::StaticPacket decrypted_packet(&decrypted_text[0], message_len);
(*(uint64_t*)&m_nonce_theirs[0])++;
@@ -283,7 +283,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p)
}
else {
size_t message_len = length;
EQ::Net::ReadOnlyPacket packet(&data[0], message_len);
EQ::Net::StaticPacket packet(&data[0], message_len);
auto cb = m_message_callbacks.find(opcode);
if (cb != m_message_callbacks.end()) {
@@ -309,7 +309,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p)
void EQ::Net::ServertalkClient::SendHandshake(bool downgrade)
{
EQ::Net::WritablePacket handshake;
EQ::Net::DynamicPacket handshake;
#ifdef ENABLE_SECURITY
if (m_encrypted) {
crypto_box_keypair(m_public_key_ours, m_private_key_ours);
@@ -0,0 +1,145 @@
#include "servertalk_legacy_client_connection.h"
#include "dns.h"
#include "../eqemu_logsys.h"
EQ::Net::ServertalkLegacyClient::ServertalkLegacyClient(const std::string &addr, int port, bool ipv6)
: m_timer(std::unique_ptr<EQ::Timer>(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkLegacyClient::Connect, this))))
{
m_port = port;
m_ipv6 = ipv6;
m_connecting = false;
DNSLookup(addr, port, false, [this](const std::string &address) {
m_addr = address;
});
}
EQ::Net::ServertalkLegacyClient::~ServertalkLegacyClient()
{
}
void EQ::Net::ServertalkLegacyClient::Send(uint16_t opcode, EQ::Net::Packet &p)
{
EQ::Net::DynamicPacket out;
out.PutUInt16(0, opcode);
out.PutUInt16(2, p.Length());
out.PutPacket(4, p);
InternalSend(ServertalkMessage, out);
}
void EQ::Net::ServertalkLegacyClient::SendPacket(ServerPacket *p)
{
EQ::Net::StaticPacket pout(p->pBuffer, p->size);
Send(p->opcode, pout);
}
void EQ::Net::ServertalkLegacyClient::OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb)
{
m_message_callbacks.insert(std::make_pair(opcode, cb));
}
void EQ::Net::ServertalkLegacyClient::Connect()
{
if (m_addr.length() == 0 || m_port == 0 || m_connection || m_connecting) {
return;
}
m_connecting = true;
EQ::Net::TCPConnection::Connect(m_addr, m_port, false, [this](std::shared_ptr<EQ::Net::TCPConnection> connection) {
if (connection == nullptr) {
Log.OutF(Logs::General, Logs::TCP_Connection, "Error connecting to {0}:{1}, attempting to reconnect...", m_addr, m_port);
m_connecting = false;
return;
}
Log.OutF(Logs::General, Logs::TCP_Connection, "Connected to {0}:{1}", m_addr, m_port);
m_connection = connection;
m_connection->OnDisconnect([this](EQ::Net::TCPConnection *c) {
Log.OutF(Logs::General, Logs::TCP_Connection, "Connection lost to {0}:{1}, attempting to reconnect...", m_addr, m_port);
m_connection.reset();
});
m_connection->OnRead(std::bind(&EQ::Net::ServertalkLegacyClient::ProcessData, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_connection->Start();
m_connecting = false;
if (m_on_connect_cb) {
m_on_connect_cb(this);
}
});
}
void EQ::Net::ServertalkLegacyClient::ProcessData(EQ::Net::TCPConnection *c, const unsigned char *data, size_t length)
{
m_buffer.insert(m_buffer.end(), (const char*)data, (const char*)data + length);
ProcessReadBuffer();
}
void EQ::Net::ServertalkLegacyClient::InternalSend(ServertalkPacketType type, EQ::Net::Packet &p)
{
if (!m_connection)
return;
EQ::Net::DynamicPacket out;
out.PutUInt32(0, (uint32_t)p.Length());
out.PutUInt8(4, (uint8_t)type);
if (p.Length() > 0) {
out.PutPacket(5, p);
}
m_connection->Write((const char*)out.Data(), out.Length());
}
void EQ::Net::ServertalkLegacyClient::ProcessReadBuffer()
{
size_t current = 0;
size_t total = m_buffer.size();
while (current < total) {
auto left = total - current;
/*
//header:
//uint16 opcode;
//uint16 length;
*/
uint16_t length = 0;
uint16_t opcode = 0;
if (left < 4) {
break;
}
opcode = *(uint16_t*)&m_buffer[current];
length = *(uint16_t*)&m_buffer[current + 2] - 4;
if (current + 4 + length > total) {
break;
}
if (length == 0) {
EQ::Net::DynamicPacket p;
auto cb = m_message_callbacks.find(opcode);
if (cb != m_message_callbacks.end()) {
cb->second(opcode, p);
}
}
else {
EQ::Net::StaticPacket p(&m_buffer[current + 4], length);
auto cb = m_message_callbacks.find(opcode);
if (cb != m_message_callbacks.end()) {
cb->second(opcode, p);
}
}
current += length + 4;
}
if (current == total) {
m_buffer.clear();
}
else {
m_buffer.erase(m_buffer.begin(), m_buffer.begin() + current);
}
}
@@ -0,0 +1,43 @@
#pragma once
#include "tcp_connection.h"
#include "../event/timer.h"
#include "servertalk_common.h"
#include "packet.h"
namespace EQ
{
namespace Net
{
class ServertalkLegacyClient
{
public:
ServertalkLegacyClient(const std::string &addr, int port, bool ipv6);
~ServertalkLegacyClient();
void Send(uint16_t opcode, EQ::Net::Packet &p);
void SendPacket(ServerPacket *p);
void OnConnect(std::function<void(ServertalkLegacyClient*)> cb) { m_on_connect_cb = cb; }
void OnMessage(uint16_t opcode, std::function<void(uint16_t, EQ::Net::Packet&)> cb);
bool Connected() const { return m_connecting != true; }
std::shared_ptr<EQ::Net::TCPConnection> Handle() { return m_connection; }
private:
void Connect();
void ProcessData(EQ::Net::TCPConnection *c, const unsigned char *data, size_t length);
void InternalSend(ServertalkPacketType type, EQ::Net::Packet &p);
void ProcessReadBuffer();
std::unique_ptr<EQ::Timer> m_timer;
std::string m_addr;
bool m_connecting;
int m_port;
bool m_ipv6;
std::shared_ptr<EQ::Net::TCPConnection> m_connection;
std::vector<char> m_buffer;
std::unordered_map<uint16_t, std::function<void(uint16_t, EQ::Net::Packet&)>> m_message_callbacks;
std::function<void(ServertalkLegacyClient*)> m_on_connect_cb;
};
}
}
+8 -8
View File
@@ -19,7 +19,7 @@ EQ::Net::ServertalkServerConnection::~ServertalkServerConnection()
void EQ::Net::ServertalkServerConnection::Send(uint16_t opcode, EQ::Net::Packet & p)
{
EQ::Net::WritablePacket out;
EQ::Net::DynamicPacket out;
#ifdef ENABLE_SECURITY
if (m_encrypted) {
if (p.Length() == 0) {
@@ -50,7 +50,7 @@ void EQ::Net::ServertalkServerConnection::Send(uint16_t opcode, EQ::Net::Packet
void EQ::Net::ServertalkServerConnection::SendPacket(ServerPacket * p)
{
EQ::Net::ReadOnlyPacket pout(p->pBuffer, p->size);
EQ::Net::StaticPacket pout(p->pBuffer, p->size);
Send(p->opcode, pout);
}
@@ -92,7 +92,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
}
if (length == 0) {
EQ::Net::WritablePacket p;
EQ::Net::DynamicPacket p;
switch (type) {
case ServertalkClientHello:
{
@@ -108,7 +108,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
}
}
else {
EQ::Net::ReadOnlyPacket p(&m_buffer[current + 5], length);
EQ::Net::StaticPacket p(&m_buffer[current + 5], length);
switch (type) {
case ServertalkClientHello:
{
@@ -145,7 +145,7 @@ void EQ::Net::ServertalkServerConnection::OnDisconnect(TCPConnection *c)
void EQ::Net::ServertalkServerConnection::SendHello()
{
EQ::Net::WritablePacket hello;
EQ::Net::DynamicPacket hello;
#ifdef ENABLE_SECURITY
memset(m_public_key_ours, 0, crypto_box_PUBLICKEYBYTES);
@@ -178,7 +178,7 @@ void EQ::Net::ServertalkServerConnection::InternalSend(ServertalkPacketType type
if (!m_connection)
return;
EQ::Net::WritablePacket out;
EQ::Net::DynamicPacket out;
out.PutUInt32(0, (uint32_t)p.Length());
out.PutUInt8(4, (uint8_t)type);
if (p.Length() > 0) {
@@ -290,7 +290,7 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
return;
}
EQ::Net::ReadOnlyPacket decrypted_packet(&decrypted_text[0], message_len);
EQ::Net::StaticPacket decrypted_packet(&decrypted_text[0], message_len);
(*(uint64_t*)&m_nonce_theirs[0])++;
@@ -301,7 +301,7 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
}
else {
size_t message_len = length;
EQ::Net::ReadOnlyPacket packet(&data[0], message_len);
EQ::Net::StaticPacket packet(&data[0], message_len);
auto cb = m_message_callbacks.find(opcode);
if (cb != m_message_callbacks.end()) {