Compare commits

..

3 Commits

Author SHA1 Message Date
KimLS 29bdc86d12 Refactoring streams, will be an ongoing process. 2025-01-28 23:39:51 -08:00
KimLS f2f05479dc Change streams type 2025-01-28 14:43:09 -08:00
KimLS 5e0b388cf9 Connection stream will now be lazy loaded. 2025-01-28 14:11:52 -08:00
9 changed files with 89 additions and 80 deletions
+45 -10
View File
@@ -152,6 +152,9 @@ void EQ::Net::DaybreakConnectionManager::Process()
connection->SendKeepAlive();
}
}
connection->Process();
break;
}
case StatusDisconnecting:
connection->Process();
@@ -435,7 +438,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
return;
}
if (m_encode_passes[0] == EncodeCompression || m_encode_passes[1] == EncodeCompression)
if (m_encode_passes[0] & EncodeCompression || m_encode_passes[1] & EncodeCompression)
{
EQ::Net::DynamicPacket temp;
temp.PutPacket(0, p);
@@ -492,8 +495,10 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
void EQ::Net::DaybreakConnection::ProcessQueue()
{
for (int i = 0; i < 4; ++i) {
auto stream = &m_streams[i];
auto &stream = m_streams[i];
for (;;) {
if (stream == nullptr)
break;
auto iter = stream->packet_queue.find(stream->sequence_in);
if (iter == stream->packet_queue.end()) {
@@ -510,7 +515,11 @@ void EQ::Net::DaybreakConnection::ProcessQueue()
void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
{
auto s = &m_streams[stream];
auto &s = m_streams[stream];
if (s == nullptr) {
return;
}
auto iter = s->packet_queue.find(seq);
if (iter != s->packet_queue.end()) {
auto packet = iter->second;
@@ -521,7 +530,11 @@ void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
{
auto s = &m_streams[stream];
auto &s = m_streams[stream];
if (s == nullptr) {
return;
}
auto iter = s->packet_queue.find(seq);
if (iter == s->packet_queue.end()) {
DynamicPacket *out = new DynamicPacket();
@@ -676,7 +689,10 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Packet;
auto stream = &m_streams[stream_id];
auto &stream = m_streams[stream_id];
if (stream == nullptr) {
stream.reset(new DaybreakReliableStream());
}
auto order = CompareSequence(stream->sequence_in, sequence);
if (order == SequenceFuture) {
@@ -705,7 +721,10 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Fragment;
auto stream = &m_streams[stream_id];
auto &stream = m_streams[stream_id];
if (stream == nullptr) {
stream.reset(new DaybreakReliableStream());
}
auto order = CompareSequence(stream->sequence_in, sequence);
@@ -1099,7 +1118,11 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
auto resends = 0;
auto now = Clock::now();
auto s = &m_streams[stream];
auto &s = m_streams[stream];
if (s == nullptr) {
return;
}
for (auto &entry : s->sent_packets) {
auto time_since_last_send = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.last_sent);
if (entry.second.times_resent == 0) {
@@ -1161,7 +1184,11 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
{
auto now = Clock::now();
auto s = &m_streams[stream];
auto &s = m_streams[stream];
if (s == nullptr) {
return;
}
auto iter = s->sent_packets.begin();
while (iter != s->sent_packets.end()) {
auto order = CompareSequence(seq, iter->first);
@@ -1185,7 +1212,11 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
{
auto now = Clock::now();
auto s = &m_streams[stream];
auto &s = m_streams[stream];
if (s == nullptr) {
return;
}
auto iter = s->sent_packets.find(seq);
if (iter != s->sent_packets.end()) {
uint64_t round_time = (uint64_t)std::chrono::duration_cast<std::chrono::milliseconds>(now - iter->second.last_sent).count();
@@ -1401,7 +1432,11 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
return;
}
auto stream = &m_streams[stream_id];
auto &stream = m_streams[stream_id];
if (stream == nullptr) {
stream.reset(new DaybreakReliableStream());
}
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
size_t length = p.Length();
if (length > max_raw_size) {
+44 -30
View File
@@ -133,6 +133,38 @@ namespace EQ
uint64_t bytes_before_encode;
};
//Refactoring this stuff
struct DaybreakSentPacket
{
DynamicPacket packet;
Timestamp last_sent;
Timestamp first_sent;
size_t times_resent;
size_t resend_delay;
};
class DaybreakReliableStream
{
public:
DaybreakReliableStream() {
sequence_in = 0;
sequence_out = 0;
fragment_current_bytes = 0;
fragment_total_bytes = 0;
}
//private:
uint16_t sequence_in;
uint16_t sequence_out;
std::map<uint16_t, Packet*> packet_queue;
DynamicPacket fragment_packet;
uint32_t fragment_current_bytes;
uint32_t fragment_total_bytes;
std::map<uint16_t, DaybreakSentPacket> sent_packets;
};
class DaybreakConnectionManager;
class DaybreakConnection;
class DaybreakConnection
@@ -181,36 +213,7 @@ namespace EQ
Timestamp m_close_time;
double m_outgoing_budget;
struct DaybreakSentPacket
{
DynamicPacket packet;
Timestamp last_sent;
Timestamp first_sent;
size_t times_resent;
size_t resend_delay;
};
struct DaybreakStream
{
DaybreakStream() {
sequence_in = 0;
sequence_out = 0;
fragment_current_bytes = 0;
fragment_total_bytes = 0;
}
uint16_t sequence_in;
uint16_t sequence_out;
std::map<uint16_t, Packet*> packet_queue;
DynamicPacket fragment_packet;
uint32_t fragment_current_bytes;
uint32_t fragment_total_bytes;
std::map<uint16_t, DaybreakSentPacket> sent_packets;
};
DaybreakStream m_streams[4];
std::unique_ptr<DaybreakReliableStream> m_streams[4];
std::weak_ptr<DaybreakConnection> m_self;
void Process();
@@ -272,6 +275,14 @@ namespace EQ
resend_timeout = 30000;
connection_close_time = 2000;
outgoing_data_rate = 0.0;
//this is emperically based on what the client seems to set for theirs
//this is the max number of packets that can be sent/recv per channel before acks come in
//we'll use this to preallocate some buffers
max_outgoing_packets_per_channel = 400;
max_incoming_packets_per_channel = 400;
//This is the max size of a packet that can be sent or received
max_total_packet_size = 1024 * 1024 * 16;
}
size_t max_packet_size;
@@ -295,6 +306,9 @@ namespace EQ
DaybreakEncodeType encode_passes[2];
int port;
double outgoing_data_rate;
int max_outgoing_packets_per_channel;
int max_incoming_packets_per_channel;
int max_total_packet_size;
};
class DaybreakConnectionManager
-1
View File
@@ -686,7 +686,6 @@ RULE_BOOL(NPC, NPCIgnoreLevelBasedHasteCaps, false, "Ignores hard coded level ba
RULE_INT(NPC, NPCHasteCap, 150, "Haste cap for non-v3(over haste) haste")
RULE_INT(NPC, NPCHastev3Cap, 25, "Haste cap for v3(over haste) haste")
RULE_STRING(NPC, ExcludedFaceTargetRaces, "52,72,73,141,233,328,329,372,376,377,378,379,380,381,382,383,404,422,423,424,425,426,428,429,445,449,460,462,463,500,501,502,503,504,505,506,507,508,509,510,511,513,514,515,516,533,534,535,536,537,538,539,540,541,542,543,544,545,546,550,551,552,553,554,555,556,557,567,573,577,586,589,590,591,592,593,595,596,599,601,616,619,621,628,629,630,633,634,635,636,665,683,684,685,691,692,693,694,702,703,705,706,707,710,711,714,720,2250,2254", "Race IDs excluded from facing target when hailed")
RULE_BOOL(NPC, ResetUnderworldMobsToSpawn, false, "Reset mobs that are under the world back to spawn point if valid. DEFAULT: False")
RULE_CATEGORY_END()
RULE_CATEGORY(Aggro)
-2
View File
@@ -230,7 +230,6 @@ int command_init(void)
command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", AccountStatus::GMLeadAdmin, command_traindisc) ||
command_add("tune", "Calculate statistical values related to combat.", AccountStatus::GMAdmin, command_tune) ||
command_add("undye", "Remove dye from all of your or your target's armor slots", AccountStatus::GMAdmin, command_undye) ||
command_add("underworld", "- Show all mobs under the world", AccountStatus::GMAreas, command_underworld) ||
command_add("unmemspell", "[Spell ID] - Unmemorize a Spell by ID for you or your target", AccountStatus::Guide, command_unmemspell) ||
command_add("unmemspells", " Unmemorize all spells for you or your target", AccountStatus::Guide, command_unmemspells) ||
command_add("unscribespell", "[Spell ID] - Unscribe a spell from your or your target's spell book by Spell ID", AccountStatus::GMCoder, command_unscribespell) ||
@@ -924,7 +923,6 @@ void command_bot(Client *c, const Seperator *sep)
#include "gm_commands/task.cpp"
#include "gm_commands/traindisc.cpp"
#include "gm_commands/tune.cpp"
#include "gm_commands/underworld.cpp"
#include "gm_commands/undye.cpp"
#include "gm_commands/unmemspell.cpp"
#include "gm_commands/unmemspells.cpp"
-1
View File
@@ -183,7 +183,6 @@ void command_task(Client *c, const Seperator *sep);
void command_petname(Client *c, const Seperator *sep);
void command_traindisc(Client *c, const Seperator *sep);
void command_tune(Client *c, const Seperator *sep);
void command_underworld(Client *c, const Seperator *sep);
void command_undye(Client *c, const Seperator *sep);
void command_unmemspell(Client *c, const Seperator *sep);
void command_unmemspells(Client *c, const Seperator *sep);
-17
View File
@@ -5963,20 +5963,3 @@ std::vector<NPC*> EntityList::GetExcludedNPCsByIDs(std::vector<uint32> npc_ids)
return v;
}
void EntityList::GetUnderworldMobs(Client* c) {
float underworld = zone->newzone_data.underworld;
auto it = npc_list.begin();
while (it != npc_list.end()) {
NPC* mob = it->second->CastToNPC();
if (mob->IsTrackable()) {
if (mob->GetZ() <= underworld) {
c->Message(Chat::White, "%s was under the world at %f %f %f. Resetting to spawn point at %f %f %f.",
mob->GetCleanName(), mob->GetX(), mob->GetY(), mob->GetZ(), mob->respawn2->GetX(), mob->respawn2->GetY(), mob->respawn2->GetZ());
mob->Teleport(glm::vec3(mob->respawn2->GetX(), mob->respawn2->GetY(), mob->respawn2->GetZ()));
mob->SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true);
}
}
++it;
}
}
-2
View File
@@ -578,8 +578,6 @@ public:
int MovePlayerCorpsesToGraveyard(bool force_move_from_instance = false);
void GetUnderworldMobs(Client* c);
protected:
friend class Zone;
void Depop(bool StartSpawnTimer = false);
-5
View File
@@ -1,5 +0,0 @@
#include "../client.h"
void command_underworld(Client *c, const Seperator *sep) {
entity_list.GetUnderworldMobs(c);
}
-12
View File
@@ -595,18 +595,6 @@ bool NPC::Process()
spun_timer.Disable();
}
// If mobs are under the world, move them back to spawn point.
if (
RuleB(NPC, ResetUnderworldMobsToSpawn) &&
!IsEngaged() &&
IsTrackable() &&
GetZ() <= zone->newzone_data.underworld &&
respawn2
) {
Teleport(glm::vec3(respawn2->GetX(), respawn2->GetY(), respawn2->GetZ()));
SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true);
}
SpellProcess();
if (swarm_timer.Check()) {