mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-22 12:18:27 +00:00
Proof of concept daybreak implementation using login
This commit is contained in:
+19
-7
@@ -77,7 +77,11 @@ SET(common_sources
|
||||
platform.cpp
|
||||
net/crc32.cpp
|
||||
net/daybreak_connection.cpp
|
||||
net/eqstream.cpp
|
||||
net/packet.cpp
|
||||
patch/login_sod.cpp
|
||||
patch/login_titanium.cpp
|
||||
patch/patch.cpp
|
||||
patches/patches.cpp
|
||||
patches/sod.cpp
|
||||
patches/sod_limits.cpp
|
||||
@@ -220,7 +224,11 @@ SET(common_headers
|
||||
net/daybreak_connection.h
|
||||
net/daybreak_structs.h
|
||||
net/endian.h
|
||||
net/eqstream.h
|
||||
net/packet.h
|
||||
patch/login_sod.h
|
||||
patch/login_titanium.h
|
||||
patch/patch.h
|
||||
patches/patches.h
|
||||
patches/sod.h
|
||||
# patches/sod_itemfields.h
|
||||
@@ -275,13 +283,6 @@ SET(common_headers
|
||||
util/memory_stream.h
|
||||
)
|
||||
|
||||
INCLUDE(CheckSymbolExists)
|
||||
IF(WIN32)
|
||||
check_symbol_exists(open io.h HAVE_OPEN)
|
||||
ELSE()
|
||||
check_symbol_exists(open fcntl.h HAVE_OPEN)
|
||||
ENDIF()
|
||||
|
||||
SOURCE_GROUP(Event FILES
|
||||
event/background_task.h
|
||||
event/event_loop.h
|
||||
@@ -295,10 +296,21 @@ SOURCE_GROUP(Net FILES
|
||||
net/daybreak_connection.h
|
||||
net/daybreak_structs.h
|
||||
net/endian.h
|
||||
net/eqstream.h
|
||||
net/eqstream.cpp
|
||||
net/packet.cpp
|
||||
net/packet.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Patch FILES
|
||||
patch/login_sod.cpp
|
||||
patch/login_sod.h
|
||||
patch/login_titanium.cpp
|
||||
patch/login_titanium.h
|
||||
patch/patch.cpp
|
||||
patch/patch.h
|
||||
)
|
||||
|
||||
SOURCE_GROUP(Patches FILES
|
||||
patches/patches.h
|
||||
patches/sod.h
|
||||
|
||||
@@ -79,17 +79,6 @@ struct VarCache_Struct {
|
||||
|
||||
class PTimerList;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#if _MSC_VER > 1700 // greater than 2012 (2013+)
|
||||
# define _ISNAN_(a) std::isnan(a)
|
||||
#else
|
||||
# include <float.h>
|
||||
# define _ISNAN_(a) _isnan(a)
|
||||
#endif
|
||||
#else
|
||||
# define _ISNAN_(a) std::isnan(a)
|
||||
#endif
|
||||
|
||||
class Database : public DBcore {
|
||||
public:
|
||||
Database();
|
||||
|
||||
@@ -1327,7 +1327,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
if (rquery != ""){ results = QueryDatabase(rquery); }
|
||||
|
||||
/* Run Bind Home Convert */
|
||||
if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) {
|
||||
if (pp->binds[4].zoneId < 999 && !std::isnan(pp->binds[4].x) && !std::isnan(pp->binds[4].y) && !std::isnan(pp->binds[4].z) && !std::isnan(pp->binds[4].heading)) {
|
||||
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, 1)",
|
||||
character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading);
|
||||
@@ -1335,7 +1335,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
|
||||
}
|
||||
|
||||
/* Run Bind Convert */
|
||||
if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) {
|
||||
if (pp->binds[0].zoneId < 999 && !std::isnan(pp->binds[0].x) && !std::isnan(pp->binds[0].y) && !std::isnan(pp->binds[0].z) && !std::isnan(pp->binds[0].heading)) {
|
||||
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, 0)",
|
||||
character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "net\eqstream.h"
|
||||
#endif
|
||||
|
||||
//for logsys
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "crc32.h"
|
||||
#include <memory.h>
|
||||
|
||||
unsigned int CRC32Table[256] =
|
||||
unsigned int CRC32EncodeTable[256] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
@@ -74,7 +74,7 @@ int EQ::Crc32(const void * data, int size)
|
||||
int crc = 0xffffffff;
|
||||
auto buffer = (const uint8_t *)data;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32Table[(crc ^ *&buffer[i]) & 0x000000FFL];
|
||||
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL];
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
@@ -84,12 +84,12 @@ int EQ::Crc32(const void * data, int size, int key)
|
||||
{
|
||||
int crc = 0xffffffff;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32Table[(crc ^ ((key >> (i * 8)) & 0xff)) & 0x000000FFL];
|
||||
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ ((key >> (i * 8)) & 0xff)) & 0x000000FFL];
|
||||
}
|
||||
|
||||
auto buffer = (const uint8_t *)data;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32Table[(crc ^ *&buffer[i]) & 0x000000FFL];
|
||||
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL];
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
#include "eqstream.h"
|
||||
#include <eqemu_logsys.h>
|
||||
|
||||
EQ::Net::EQStreamManager::EQStreamManager(EQStreamManagerOptions &options) : m_daybreak(options.daybreak_options)
|
||||
{
|
||||
m_options = options;
|
||||
|
||||
m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
|
||||
m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
EQ::Net::EQStreamManager::~EQStreamManager()
|
||||
{
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
||||
{
|
||||
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
||||
m_streams.insert(std::make_pair(connection, stream));
|
||||
if (m_on_new_connection) {
|
||||
m_on_new_connection(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
||||
{
|
||||
auto iter = m_streams.find(connection);
|
||||
if (iter != m_streams.end()) {
|
||||
if (m_on_connection_state_change) {
|
||||
m_on_connection_state_change(iter->second, from, to);
|
||||
}
|
||||
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_streams.erase(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, Packet &p)
|
||||
{
|
||||
auto iter = m_streams.find(connection);
|
||||
if (iter != m_streams.end()) {
|
||||
auto patch = iter->second->GetRegisteredPatch();
|
||||
if (patch == nullptr && m_possible_patches.size() > 0) {
|
||||
for (auto &pt : m_possible_patches) {
|
||||
auto match = pt->TryIdentityMatch(p);
|
||||
if (match == EQ::Patches::IdentityMatchSuccess) {
|
||||
iter->second->RegisterPatch(pt.get());
|
||||
patch = pt.get();
|
||||
Log.OutF(Logs::General, Logs::Debug, "Identified patch with name {0}", pt->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (patch) {
|
||||
EmuOpcode opcode;
|
||||
EQ::Net::WritablePacket out;
|
||||
patch->Decode(&p, opcode, out);
|
||||
|
||||
if (opcode == OP_Unknown) {
|
||||
Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because the opcode was not found.\n{0}", p.ToString());
|
||||
}
|
||||
else {
|
||||
if (m_on_packet_recv) {
|
||||
m_on_packet_recv(iter->second, opcode, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because we don't have a patch set.\n{0}", p.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EQ::Net::EQStream::EQStream(EQStreamManager *owner, std::shared_ptr<DaybreakConnection> connection)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_connection = connection;
|
||||
m_patch = nullptr;
|
||||
}
|
||||
|
||||
EQ::Net::EQStream::~EQStream()
|
||||
{
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::QueuePacket(EmuOpcode type, Packet &p)
|
||||
{
|
||||
if (m_patch) {
|
||||
EQ::Net::WritablePacket trans;
|
||||
m_patch->Encode(m_connection, type, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::ResetStats()
|
||||
{
|
||||
m_connection->ResetStats();
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::Close()
|
||||
{
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::QueuePacket(EQApplicationPacket *p)
|
||||
{
|
||||
EQ::Net::ReadOnlyPacket out(p->pBuffer, p->size);
|
||||
QueuePacket(p->GetOpcode(), out);
|
||||
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::FastQueuePacket(EQApplicationPacket **p)
|
||||
{
|
||||
QueuePacket(*p);
|
||||
delete *p;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <patch/patch.h>
|
||||
#include <eq_packet.h>
|
||||
#include "daybreak_connection.h"
|
||||
#include <vector>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
struct EQStreamManagerOptions
|
||||
{
|
||||
EQStreamManagerOptions() {
|
||||
compressed = false;
|
||||
}
|
||||
|
||||
DaybreakConnectionManagerOptions daybreak_options;
|
||||
bool compressed;
|
||||
};
|
||||
|
||||
class EQStream;
|
||||
class EQStreamManager
|
||||
{
|
||||
public:
|
||||
EQStreamManager(EQStreamManagerOptions &options);
|
||||
~EQStreamManager();
|
||||
|
||||
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
|
||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||
void OnPacketRecv(std::function<void(std::shared_ptr<EQStream>, EmuOpcode, Packet &)> func) { m_on_packet_recv = func; }
|
||||
|
||||
void RegisterPotentialPatch(EQ::Patches::BasePatch *patch) { m_possible_patches.push_back(std::unique_ptr<EQ::Patches::BasePatch>(patch)); }
|
||||
private:
|
||||
EQStreamManagerOptions m_options;
|
||||
DaybreakConnectionManager m_daybreak;
|
||||
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
|
||||
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||
std::function<void(std::shared_ptr<EQStream>, EmuOpcode, Packet &)> m_on_packet_recv;
|
||||
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
|
||||
std::vector<std::unique_ptr<EQ::Patches::BasePatch>> m_possible_patches;
|
||||
|
||||
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
|
||||
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
||||
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, Packet &p);
|
||||
friend class EQStream;
|
||||
};
|
||||
|
||||
class EQStream
|
||||
{
|
||||
public:
|
||||
EQStream(EQStreamManager *parent, std::shared_ptr<DaybreakConnection> connection);
|
||||
~EQStream();
|
||||
|
||||
const std::string& RemoteEndpoint() const { return m_connection->RemoteEndpoint(); }
|
||||
int RemotePort() const { return m_connection->RemotePort(); }
|
||||
|
||||
void QueuePacket(EmuOpcode type, Packet &p);
|
||||
const DaybreakConnectionStats& GetStats() const { return m_connection->GetStats(); }
|
||||
void ResetStats();
|
||||
size_t GetRollingPing() const { return m_connection->GetRollingPing(); }
|
||||
void Close();
|
||||
void QueuePacket(EQApplicationPacket *p);
|
||||
void FastQueuePacket(EQApplicationPacket **p);
|
||||
|
||||
void RegisterPatch(EQ::Patches::BasePatch *p) { m_patch = p; }
|
||||
EQ::Patches::BasePatch *GetRegisteredPatch() { return m_patch; }
|
||||
private:
|
||||
EQStreamManager *m_owner;
|
||||
std::shared_ptr<DaybreakConnection> m_connection;
|
||||
EQ::Patches::BasePatch *m_patch;
|
||||
friend class EQStreamManager;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "login_sod.h"
|
||||
|
||||
EQ::Patches::LoginSoDPatch::LoginSoDPatch()
|
||||
{
|
||||
m_opcode_manager.reset(new RegularOpcodeManager());
|
||||
if (!m_opcode_manager->LoadOpcodes("login_opcodes_sod.conf")) {
|
||||
m_opcode_manager.release();
|
||||
}
|
||||
|
||||
m_signature.match_message_opcode = 0x01;
|
||||
m_signature.match_message_size = 0;
|
||||
m_message_size = 2;
|
||||
}
|
||||
|
||||
EQ::Patches::LoginSoDPatch::~LoginSoDPatch()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <patch/patch.h>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Patches
|
||||
{
|
||||
class LoginSoDPatch : public BasePatch
|
||||
{
|
||||
public:
|
||||
LoginSoDPatch();
|
||||
virtual ~LoginSoDPatch();
|
||||
virtual std::string GetName() const { return "Login SoD+"; }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "login_titanium.h"
|
||||
|
||||
EQ::Patches::LoginTitaniumPatch::LoginTitaniumPatch()
|
||||
{
|
||||
m_opcode_manager.reset(new RegularOpcodeManager());
|
||||
if (!m_opcode_manager->LoadOpcodes("login_opcodes_titanium.conf")) {
|
||||
m_opcode_manager.release();
|
||||
}
|
||||
|
||||
m_signature.match_message_opcode = 0x01;
|
||||
m_signature.match_message_size = 0;
|
||||
m_message_size = 2;
|
||||
}
|
||||
|
||||
EQ::Patches::LoginTitaniumPatch::~LoginTitaniumPatch()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <patch/patch.h>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Patches
|
||||
{
|
||||
class LoginTitaniumPatch : public BasePatch
|
||||
{
|
||||
public:
|
||||
LoginTitaniumPatch();
|
||||
virtual ~LoginTitaniumPatch();
|
||||
virtual std::string GetName() const { return "Login Titanium"; }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
#include "patch.h"
|
||||
#include <eqemu_logsys.h>
|
||||
|
||||
EQ::Patches::IdentityMatchStatus EQ::Patches::BasePatch::TryIdentityMatch(const EQ::Net::Packet &p) const
|
||||
{
|
||||
if (p.Length() < m_message_size) {
|
||||
return IdentityMatchFailure;
|
||||
}
|
||||
|
||||
int raw_opcode = 0;
|
||||
switch (m_message_size) {
|
||||
case 1:
|
||||
raw_opcode = *(uint8_t*)p.Data();
|
||||
break;
|
||||
case 2:
|
||||
raw_opcode = *(uint16_t*)p.Data();
|
||||
break;
|
||||
default:
|
||||
return IdentityMatchFailure;
|
||||
}
|
||||
|
||||
if (m_signature.match_message_opcode != raw_opcode) {
|
||||
return IdentityMatchFailure;
|
||||
}
|
||||
|
||||
if (m_signature.match_message_size > 0 && m_signature.match_message_size != p.Length() - m_message_size) {
|
||||
return IdentityMatchFailure;
|
||||
}
|
||||
|
||||
return IdentityMatchSuccess;
|
||||
}
|
||||
|
||||
void EQ::Patches::BasePatch::Decode(const EQ::Net::Packet *in, EmuOpcode &opcode, EQ::Net::WritablePacket &out)
|
||||
{
|
||||
int raw_opcode = 0;
|
||||
switch (m_message_size) {
|
||||
case 1:
|
||||
raw_opcode = *(uint8_t*)in->Data();
|
||||
break;
|
||||
case 2:
|
||||
raw_opcode = *(uint16_t*)in->Data();
|
||||
break;
|
||||
default:
|
||||
opcode = OP_Unknown;
|
||||
return;
|
||||
}
|
||||
|
||||
opcode = m_opcode_manager->EQToEmu(raw_opcode);
|
||||
if (opcode == OP_Unknown) {
|
||||
out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
|
||||
return;
|
||||
}
|
||||
|
||||
auto decode_iter = m_decode.find(opcode);
|
||||
if (decode_iter != m_decode.end()) {
|
||||
EQ::Net::ReadOnlyPacket p((uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
|
||||
decode_iter->second(&p, opcode, out);
|
||||
}
|
||||
else {
|
||||
out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Patches::BasePatch::Encode(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *in)
|
||||
{
|
||||
auto encode_iter = m_encode.find(opcode);
|
||||
if (encode_iter != m_encode.end()) {
|
||||
encode_iter->second(connection, opcode, in);
|
||||
}
|
||||
else {
|
||||
SendPacket(connection, opcode, in);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Patches::BasePatch::RegisterDecode(int protocol_number, DecodeStructFunction f)
|
||||
{
|
||||
m_decode.insert(std::make_pair(protocol_number, f));
|
||||
}
|
||||
|
||||
void EQ::Patches::BasePatch::RegisterEncode(EmuOpcode opcode, EncodeStructFunction f)
|
||||
{
|
||||
m_encode.insert(std::make_pair(opcode, f));
|
||||
}
|
||||
|
||||
void EQ::Patches::BasePatch::SendPacket(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *p)
|
||||
{
|
||||
if (!m_opcode_manager) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto raw_opcode = m_opcode_manager->EmuToEQ(opcode);
|
||||
EQ::Net::WritablePacket out;
|
||||
switch (m_message_size) {
|
||||
case 1:
|
||||
out.PutUInt8(0, (uint8_t)raw_opcode);
|
||||
out.PutPacket(1, *p);
|
||||
break;
|
||||
case 2:
|
||||
out.PutUInt16(0, raw_opcode);
|
||||
out.PutPacket(2, *p);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
connection->QueuePacket(out);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <opcodemgr.h>
|
||||
#include <net/packet.h>
|
||||
#include <net/daybreak_connection.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Patches
|
||||
{
|
||||
enum IdentityMatchStatus
|
||||
{
|
||||
IdentityMatchFailure,
|
||||
IdentityMatchSuccess
|
||||
};
|
||||
|
||||
struct Signature
|
||||
{
|
||||
int match_message_opcode;
|
||||
size_t match_message_size;
|
||||
};
|
||||
|
||||
class BasePatch
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(const EQ::Net::Packet*, EmuOpcode&, EQ::Net::WritablePacket&)> DecodeStructFunction;
|
||||
typedef std::function<void(std::shared_ptr<EQ::Net::DaybreakConnection>, EmuOpcode, const EQ::Net::Packet*)> EncodeStructFunction;
|
||||
|
||||
BasePatch() { }
|
||||
virtual ~BasePatch() { }
|
||||
virtual std::string GetName() const = 0;
|
||||
|
||||
IdentityMatchStatus TryIdentityMatch(const EQ::Net::Packet &p) const;
|
||||
|
||||
void Decode(const EQ::Net::Packet *in, EmuOpcode& opcode, EQ::Net::WritablePacket& out);
|
||||
void Encode(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *in);
|
||||
|
||||
void RegisterDecode(int protocol_number, DecodeStructFunction f);
|
||||
void RegisterEncode(EmuOpcode opcode, EncodeStructFunction f);
|
||||
protected:
|
||||
void SendPacket(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *p);
|
||||
|
||||
std::unique_ptr<OpcodeManager> m_opcode_manager;
|
||||
std::map<int, DecodeStructFunction> m_decode;
|
||||
std::map<EmuOpcode, EncodeStructFunction> m_encode;
|
||||
Signature m_signature;
|
||||
int m_message_size;
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user