From d1f332657391d70176d52addd8844d0cf7cc2fc5 Mon Sep 17 00:00:00 2001 From: Corey Sotiropoulos Date: Sat, 25 Jan 2025 21:05:51 -0500 Subject: [PATCH] Fix send_parse and other update/packet issues Use a copy of the PacketList in case there are any issues while sending. Pop packets from PacketList only after finished sending. Fix an issue with players using the wrong update packet. --- src/map/entities/charentity.cpp | 10 ++++++++++ src/map/entities/charentity.h | 1 + src/map/map.cpp | 12 +++++++----- src/map/packet_guard.cpp | 2 +- src/map/zone_entities.cpp | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/map/entities/charentity.cpp b/src/map/entities/charentity.cpp index 0bb1e478ac4..43a3d5387c8 100644 --- a/src/map/entities/charentity.cpp +++ b/src/map/entities/charentity.cpp @@ -401,6 +401,16 @@ auto CCharEntity::getPacketList() const -> const std::deque std::deque> +{ + std::deque> PacketListCopy; + for (const auto& packet : PacketList) + { + PacketListCopy.emplace_back(std::make_unique(packet)); + } + return PacketListCopy; +} + void CCharEntity::clearPacketList() { while (!PacketList.empty()) diff --git a/src/map/entities/charentity.h b/src/map/entities/charentity.h index 031c2259ef3..3e1b13756f4 100644 --- a/src/map/entities/charentity.h +++ b/src/map/entities/charentity.h @@ -416,6 +416,7 @@ class CCharEntity : public CBattleEntity uint8 GetGender(); auto getPacketList() const -> const std::deque>&; + auto getPacketListCopy() -> std::deque>; // Return a COPY of packet list void clearPacketList(); template diff --git a/src/map/map.cpp b/src/map/map.cpp index 48842b675af..a88b070c57a 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1049,13 +1049,14 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da { do { - *buffsize = FFXI_HEADER_SIZE; - auto& packetList = PChar->getPacketList(); - packets = 0; + *buffsize = FFXI_HEADER_SIZE; + auto packetList = PChar->getPacketListCopy(); + packets = 0; - while (!PChar->isPacketListEmpty() && *buffsize + packetList.front()->getSize() < MAX_BUFFER_SIZE && static_cast(packets) < PacketCount) + while (!packetList.empty() && *buffsize + packetList.front()->getSize() < MAX_BUFFER_SIZE && static_cast(packets) < PacketCount) { - PSmallPacket = PChar->popPacket(); + PSmallPacket = std::move(packetList.front()); + packetList.pop_front(); PSmallPacket->setSequence(map_session_data->server_packet_id); auto type = PSmallPacket->getType(); @@ -1130,6 +1131,7 @@ int32 send_parse(int8* buff, size_t* buffsize, sockaddr_in* from, map_session_da } } } while (PacketSize == static_cast(-1)); + PChar->erasePackets(packets); TotalPacketsSentPerTick += packets; TracyZoneString(fmt::format("Sending {} packets", packets)); diff --git a/src/map/packet_guard.cpp b/src/map/packet_guard.cpp index cf4e426c99f..82ea37856a4 100644 --- a/src/map/packet_guard.cpp +++ b/src/map/packet_guard.cpp @@ -104,7 +104,7 @@ namespace PacketGuard { // Count packets in queue std::map packetCounterMap; - for (auto& entry : PChar->getPacketList()) + for (auto& entry : PChar->getPacketListCopy()) { auto packetStr = fmt::format("0x{:4X}", entry->getType()); packetCounterMap[packetStr]++; diff --git a/src/map/zone_entities.cpp b/src/map/zone_entities.cpp index ee24112dc9a..f6ff658126b 100644 --- a/src/map/zone_entities.cpp +++ b/src/map/zone_entities.cpp @@ -163,7 +163,7 @@ void CZoneEntities::TryAddToNearbySpawnLists(CBaseEntity* PEntity) case TYPE_PC: { PCurrentChar->SpawnPCList[PEntity->id] = PEntity; - PCurrentChar->updateEntityPacket(PEntity, ENTITY_SPAWN, UPDATE_ALL_CHAR); + PCurrentChar->updateCharPacket(static_cast(PEntity), ENTITY_SPAWN, UPDATE_ALL_CHAR); break; } case TYPE_NPC: