mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 18:52:22 +00:00
Change eqstream interface to get rid of some stuff as well as flesh out a few more options plus some rule and performance changes
This commit is contained in:
+43
-1
@@ -19,6 +19,47 @@ typedef enum {
|
||||
class EQApplicationPacket;
|
||||
class OpcodeManager;
|
||||
|
||||
struct EQStreamManagerInterfaceOptions
|
||||
{
|
||||
EQStreamManagerInterfaceOptions() {
|
||||
opcode_size = 2;
|
||||
}
|
||||
|
||||
EQStreamManagerInterfaceOptions(int port, bool encoded, bool compressed) {
|
||||
opcode_size = 2;
|
||||
track_opcode_stats = false;
|
||||
|
||||
//World seems to support both compression and xor zone supports one or the others.
|
||||
//Enforce one or the other in the convienence construct
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//but that might be because it was still a bit buggy when i was testing that.
|
||||
if (compressed) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||
}
|
||||
else if (encoded) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
||||
}
|
||||
|
||||
daybreak_options.port = port;
|
||||
}
|
||||
|
||||
int opcode_size;
|
||||
bool track_opcode_stats;
|
||||
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
|
||||
};
|
||||
|
||||
class EQStreamManagerInterface
|
||||
{
|
||||
public:
|
||||
EQStreamManagerInterface(const EQStreamManagerInterfaceOptions &options) { m_options = options; }
|
||||
virtual ~EQStreamManagerInterface() { };
|
||||
|
||||
const EQStreamManagerInterfaceOptions& GetOptions() const { return m_options; }
|
||||
EQStreamManagerInterfaceOptions& MutateOptions() { return m_options; }
|
||||
protected:
|
||||
EQStreamManagerInterfaceOptions m_options;
|
||||
};
|
||||
|
||||
class EQStreamInterface {
|
||||
public:
|
||||
virtual ~EQStreamInterface() {}
|
||||
@@ -60,8 +101,9 @@ public:
|
||||
virtual EQStreamState GetState() = 0;
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
|
||||
virtual const EQEmu::versions::ClientVersion ClientVersion() const { return EQEmu::versions::ClientVersion::Unknown; }
|
||||
virtual std::shared_ptr<EQ::Net::DaybreakConnection> GetRawConnection() const = 0;
|
||||
virtual Stats GetStats() const = 0;
|
||||
virtual void ResetStats() = 0;
|
||||
virtual EQStreamManagerInterface* GetManager() const = 0;
|
||||
};
|
||||
|
||||
#endif /*EQSTREAMINTF_H_*/
|
||||
|
||||
@@ -90,15 +90,21 @@ void EQStreamProxy::RemoveData() {
|
||||
m_stream->RemoveData();
|
||||
}
|
||||
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> EQStreamProxy::GetRawConnection() const {
|
||||
return m_stream->GetRawConnection();
|
||||
}
|
||||
|
||||
EQStreamInterface::Stats EQStreamProxy::GetStats() const
|
||||
{
|
||||
return m_stream->GetStats();
|
||||
}
|
||||
|
||||
void EQStreamProxy::ResetStats()
|
||||
{
|
||||
m_stream->ResetStats();
|
||||
}
|
||||
|
||||
EQStreamManagerInterface *EQStreamProxy::GetManager() const
|
||||
{
|
||||
return m_stream->GetManager();
|
||||
}
|
||||
|
||||
bool EQStreamProxy::CheckState(EQStreamState state) {
|
||||
if(m_stream)
|
||||
return(m_stream->CheckState(state));
|
||||
|
||||
@@ -31,8 +31,9 @@ public:
|
||||
virtual const EQEmu::versions::ClientVersion ClientVersion() const;
|
||||
virtual EQStreamState GetState();
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm);
|
||||
virtual std::shared_ptr<EQ::Net::DaybreakConnection> GetRawConnection() const;
|
||||
virtual Stats GetStats() const;
|
||||
virtual void ResetStats();
|
||||
virtual EQStreamManagerInterface* GetManager() const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace EQ
|
||||
encode_passes[0] = DaybreakEncodeType::EncodeNone;
|
||||
encode_passes[1] = DaybreakEncodeType::EncodeNone;
|
||||
port = 0;
|
||||
hold_size = 448;
|
||||
hold_size = 512;
|
||||
hold_length_ms = 50;
|
||||
simulated_in_packet_loss = 0;
|
||||
simulated_out_packet_loss = 0;
|
||||
|
||||
+27
-19
@@ -2,10 +2,8 @@
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../eqemu_logsys_fmt.h"
|
||||
|
||||
EQ::Net::EQStreamManager::EQStreamManager(EQStreamManagerOptions &options) : m_daybreak(options.daybreak_options)
|
||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(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));
|
||||
@@ -49,7 +47,7 @@ void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnec
|
||||
}
|
||||
}
|
||||
|
||||
EQ::Net::EQStream::EQStream(EQStreamManager *owner, std::shared_ptr<DaybreakConnection> connection)
|
||||
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<DaybreakConnection> connection)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_connection = connection;
|
||||
@@ -67,14 +65,14 @@ void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req)
|
||||
opcode = p->GetOpcodeBypass();
|
||||
}
|
||||
else {
|
||||
if (m_owner->m_options.track_opcode_stats) {
|
||||
if (m_owner->GetOptions().track_opcode_stats) {
|
||||
m_packet_sent_count[p->GetOpcode()]++; //Wont bother with bypass tracking of these since those are rare for testing anyway
|
||||
}
|
||||
opcode = (*m_opcode_manager)->EmuToEQ(p->GetOpcode());
|
||||
}
|
||||
|
||||
EQ::Net::DynamicPacket out;
|
||||
switch (m_owner->m_options.opcode_size) {
|
||||
switch (m_owner->GetOptions().opcode_size) {
|
||||
case 1:
|
||||
out.PutUInt8(0, opcode);
|
||||
out.PutData(1, p->pBuffer, p->size);
|
||||
@@ -109,7 +107,7 @@ EQApplicationPacket *EQ::Net::EQStream::PopPacket() {
|
||||
auto &p = m_packet_queue.front();
|
||||
|
||||
uint16 opcode = 0;
|
||||
switch (m_owner->m_options.opcode_size) {
|
||||
switch (m_owner->GetOptions().opcode_size) {
|
||||
case 1:
|
||||
opcode = p->GetUInt8(0);
|
||||
break;
|
||||
@@ -119,11 +117,11 @@ EQApplicationPacket *EQ::Net::EQStream::PopPacket() {
|
||||
}
|
||||
|
||||
EmuOpcode emu_op = (*m_opcode_manager)->EQToEmu(opcode);
|
||||
if (m_owner->m_options.track_opcode_stats) {
|
||||
if (m_owner->GetOptions().track_opcode_stats) {
|
||||
m_packet_recv_count[emu_op]++;
|
||||
}
|
||||
|
||||
EQApplicationPacket *ret = new EQApplicationPacket(emu_op, (unsigned char*)p->Data() + m_owner->m_options.opcode_size, p->Length() - m_owner->m_options.opcode_size);
|
||||
EQApplicationPacket *ret = new EQApplicationPacket(emu_op, (unsigned char*)p->Data() + m_owner->GetOptions().opcode_size, p->Length() - m_owner->GetOptions().opcode_size);
|
||||
ret->SetProtocolOpcode(opcode);
|
||||
m_packet_queue.pop_front();
|
||||
return ret;
|
||||
@@ -138,11 +136,11 @@ void EQ::Net::EQStream::Close() {
|
||||
|
||||
std::string EQ::Net::EQStream::GetRemoteAddr() const
|
||||
{
|
||||
return GetRawConnection()->RemoteEndpoint();
|
||||
return m_connection->RemoteEndpoint();
|
||||
}
|
||||
|
||||
uint32 EQ::Net::EQStream::GetRemoteIP() const {
|
||||
return inet_addr(GetRawConnection()->RemoteEndpoint().c_str());
|
||||
return inet_addr(m_connection->RemoteEndpoint().c_str());
|
||||
}
|
||||
|
||||
bool EQ::Net::EQStream::CheckState(EQStreamState state) {
|
||||
@@ -153,8 +151,8 @@ EQStreamInterface::MatchState EQ::Net::EQStream::CheckSignature(const Signature
|
||||
if (!m_packet_queue.empty()) {
|
||||
auto p = m_packet_queue.front().get();
|
||||
uint16 opcode = 0;
|
||||
size_t length = p->Length() - m_owner->m_options.opcode_size;
|
||||
switch (m_owner->m_options.opcode_size) {
|
||||
size_t length = p->Length() - m_owner->GetOptions().opcode_size;
|
||||
switch (m_owner->GetOptions().opcode_size) {
|
||||
case 1:
|
||||
opcode = p->GetUInt8(0);
|
||||
break;
|
||||
@@ -167,8 +165,8 @@ EQStreamInterface::MatchState EQ::Net::EQStream::CheckSignature(const Signature
|
||||
if (m_packet_queue.size() > 1) {
|
||||
p = m_packet_queue[1].get();
|
||||
opcode = 0;
|
||||
length = p->Length() - m_owner->m_options.opcode_size;
|
||||
switch (m_owner->m_options.opcode_size) {
|
||||
length = p->Length() - m_owner->GetOptions().opcode_size;
|
||||
switch (m_owner->GetOptions().opcode_size) {
|
||||
case 1:
|
||||
opcode = p->GetUInt8(0);
|
||||
break;
|
||||
@@ -185,23 +183,23 @@ EQStreamInterface::MatchState EQ::Net::EQStream::CheckSignature(const Signature
|
||||
if (opcode == sig->first_eq_opcode) {
|
||||
if (length == sig->first_length) {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length matched {3}",
|
||||
GetRawConnection()->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length);
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length);
|
||||
return MatchSuccessful;
|
||||
}
|
||||
else if (length == 0) {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} and length is ignored.",
|
||||
GetRawConnection()->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode);
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode);
|
||||
return MatchSuccessful;
|
||||
}
|
||||
else {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode matched {2:#x} but length {3} did not match expected {4}",
|
||||
GetRawConnection()->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length, sig->first_length);
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), sig->first_eq_opcode, length, sig->first_length);
|
||||
return MatchFailed;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogF(Logs::General, Logs::Netcode, "[IDENT_TRACE] {0}:{1}: First opcode {1:#x} did not match expected {2:#x}",
|
||||
GetRawConnection()->RemoteEndpoint(), m_connection->RemotePort(), opcode, sig->first_eq_opcode);
|
||||
m_connection->RemoteEndpoint(), m_connection->RemotePort(), opcode, sig->first_eq_opcode);
|
||||
return MatchFailed;
|
||||
}
|
||||
}
|
||||
@@ -243,3 +241,13 @@ EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::ResetStats()
|
||||
{
|
||||
m_connection->ResetStats();
|
||||
}
|
||||
|
||||
EQStreamManagerInterface *EQ::Net::EQStream::GetManager() const
|
||||
{
|
||||
return m_owner;
|
||||
}
|
||||
|
||||
+6
-38
@@ -12,46 +12,16 @@ namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
struct EQStreamManagerOptions
|
||||
{
|
||||
EQStreamManagerOptions() {
|
||||
opcode_size = 2;
|
||||
}
|
||||
|
||||
EQStreamManagerOptions(int port, bool encoded, bool compressed) {
|
||||
opcode_size = 2;
|
||||
track_opcode_stats = false;
|
||||
|
||||
//World seems to support both compression and xor zone supports one or the others.
|
||||
//Enforce one or the other in the convienence construct
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//but that might be because it was still a bit buggy when i was testing that.
|
||||
if (compressed) {
|
||||
daybreak_options.encode_passes[0] = EncodeCompression;
|
||||
}
|
||||
else if (encoded) {
|
||||
daybreak_options.encode_passes[0] = EncodeXOR;
|
||||
}
|
||||
|
||||
daybreak_options.port = port;
|
||||
}
|
||||
|
||||
int opcode_size;
|
||||
bool track_opcode_stats;
|
||||
DaybreakConnectionManagerOptions daybreak_options;
|
||||
};
|
||||
|
||||
class EQStream;
|
||||
class EQStreamManager
|
||||
class EQStreamManager : public EQStreamManagerInterface
|
||||
{
|
||||
public:
|
||||
EQStreamManager(EQStreamManagerOptions &options);
|
||||
EQStreamManager(const EQStreamManagerInterfaceOptions &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; }
|
||||
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;
|
||||
@@ -66,7 +36,7 @@ namespace EQ
|
||||
class EQStream : public EQStreamInterface
|
||||
{
|
||||
public:
|
||||
EQStream(EQStreamManager *parent, std::shared_ptr<DaybreakConnection> connection);
|
||||
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<DaybreakConnection> connection);
|
||||
~EQStream();
|
||||
|
||||
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
|
||||
@@ -87,13 +57,11 @@ namespace EQ
|
||||
m_opcode_manager = opm;
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<EQ::Net::DaybreakConnection> GetRawConnection() const {
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
virtual Stats GetStats() const;
|
||||
virtual void ResetStats();
|
||||
virtual EQStreamManagerInterface* GetManager() const;
|
||||
private:
|
||||
EQStreamManager *m_owner;
|
||||
EQStreamManagerInterface *m_owner;
|
||||
std::shared_ptr<DaybreakConnection> m_connection;
|
||||
OpcodeManager **m_opcode_manager;
|
||||
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
|
||||
|
||||
+3
-26
@@ -286,35 +286,11 @@ RULE_INT(Map, FindBestZHeightAdjust, 1) // Adds this to the current Z before se
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Pathing)
|
||||
// Some of these rules may benefit by being made into columns in the zone table,
|
||||
// for instance, in dungeons, the min LOS distances could be substantially lowered.
|
||||
RULE_BOOL(Pathing, Aggro, true) // Enable pathing for aggroed mobs.
|
||||
RULE_BOOL(Pathing, AggroReturnToGrid, true) // Enable pathing for aggroed roaming mobs returning to their previous waypoint.
|
||||
RULE_BOOL(Pathing, Guard, true) // Enable pathing for mobs moving to their guard point.
|
||||
RULE_BOOL(Pathing, Find, true) // Enable pathing for FindPerson requests from the client.
|
||||
RULE_BOOL(Pathing, Fear, true) // Enable pathing for fear
|
||||
RULE_REAL(Pathing, ZDiffThresholdNew, 80) // If a mob las LOS to it's target, it will run to it if the Z difference is < this.
|
||||
RULE_INT(Pathing, LOSCheckFrequency, 1000) // A mob will check for LOS to it's target this often (milliseconds).
|
||||
RULE_INT(Pathing, RouteUpdateFrequencyShort, 1000) // How often a new route will be calculated if the target has moved.
|
||||
RULE_INT(Pathing, RouteUpdateFrequencyLong, 5000) // How often a new route will be calculated if the target has moved.
|
||||
// When a path has a path node route and it's target changes position, if it has RouteUpdateFrequencyNodeCount or less nodes to go on it's
|
||||
// current path, it will recalculate it's path based on the RouteUpdateFrequencyShort timer, otherwise it will use the
|
||||
// RouteUpdateFrequencyLong timer.
|
||||
RULE_INT(Pathing, RouteUpdateFrequencyNodeCount, 5)
|
||||
RULE_REAL(Pathing, MinDistanceForLOSCheckShort, 40000) // (NoRoot). While following a path, only check for LOS to target within this distance.
|
||||
RULE_REAL(Pathing, MinDistanceForLOSCheckLong, 1000000) // (NoRoot). Min distance when initially attempting to acquire the target.
|
||||
RULE_INT(Pathing, MinNodesLeftForLOSCheck, 4) // Only check for LOS when we are down to this many path nodes left to run.
|
||||
// This next rule was put in for situations where the mob and it's target may be on different sides of a 'hazard', e.g. a pit
|
||||
// If the mob has LOS to it's target, even though there is a hazard in it's way, it may break off from the node path and run at
|
||||
// the target, only to later detect the hazard and re-acquire a node path. Depending upon the placement of the path nodes, this
|
||||
// can lead to the mob looping. The rule is intended to allow the mob to at least get closer to it's target each time before
|
||||
// checking LOS and trying to head straight for it.
|
||||
RULE_INT(Pathing, MinNodesTraversedForLOSCheck, 3) // Only check for LOS after we have traversed this many path nodes.
|
||||
RULE_INT(Pathing, CullNodesFromStart, 1) // Checks LOS from Start point to second node for this many nodes and removes first node if there is LOS
|
||||
RULE_INT(Pathing, CullNodesFromEnd, 1) // Checks LOS from End point to second to last node for this many nodes and removes last node if there is LOS
|
||||
RULE_REAL(Pathing, CandidateNodeRangeXY, 400) // When searching for path start/end nodes, only nodes within this range will be considered.
|
||||
RULE_REAL(Pathing, CandidateNodeRangeZ, 10) // When searching for path start/end nodes, only nodes within this range will be considered.
|
||||
RULE_REAL(Pathing, NavmeshStepSize, 30.0f)
|
||||
RULE_REAL(Pathing, NavmeshStepSize, 100.0f)
|
||||
RULE_REAL(Pathing, ShortMovementUpdateRange, 130.0f)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Watermap)
|
||||
@@ -710,6 +686,7 @@ RULE_REAL(Network, ResendDelayFactor, 1.5)
|
||||
RULE_INT(Network, ResendDelayMinMS, 100)
|
||||
RULE_INT(Network, ResendDelayMaxMS, 5000)
|
||||
RULE_REAL(Network, ClientDataRate, 0.0) // KB / sec, 0.0 disabled
|
||||
RULE_BOOL(Network, TrackOpcodeStats, false)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(QueryServ)
|
||||
|
||||
Reference in New Issue
Block a user