diff --git a/src/game/packet_parsers_classic.cpp b/src/game/packet_parsers_classic.cpp index 5b02127b..f757b931 100644 --- a/src/game/packet_parsers_classic.cpp +++ b/src/game/packet_parsers_classic.cpp @@ -2140,6 +2140,8 @@ bool TurtlePacketParsers::parseUpdateObject(network::Packet& packet, UpdateObjec out.blocks.reserve(out.blockCount); for (uint32_t i = 0; i < out.blockCount; ++i) { if (!packet.hasData()) { + // If we already parsed some blocks, keep them (layout is confirmed valid). + if (!out.blocks.empty()) break; packet.setReadPos(start); return false; } @@ -2147,6 +2149,7 @@ bool TurtlePacketParsers::parseUpdateObject(network::Packet& packet, UpdateObjec const size_t blockStart = packet.getReadPos(); uint8_t updateTypeVal = packet.readUInt8(); if (updateTypeVal > static_cast(UpdateType::NEAR_OBJECTS)) { + if (!out.blocks.empty()) break; packet.setReadPos(start); return false; } @@ -2220,14 +2223,19 @@ bool TurtlePacketParsers::parseUpdateObject(network::Packet& packet, UpdateObjec } if (!ok) { - LOG_WARNING("[Turtle] SMSG_UPDATE_OBJECT block parse failed", - " blockIndex=", i, - " updateType=", updateTypeName(updateType), - " readPos=", packet.getReadPos(), - " blockStart=", blockStart, - " packetSize=", packet.getSize()); - packet.setReadPos(start); - return false; + static int turtleBlockErrors = 0; + if (++turtleBlockErrors <= 5) { + LOG_WARNING("[Turtle] SMSG_UPDATE_OBJECT block parse failed", + " blockIndex=", i, " of ", out.blockCount, + " updateType=", updateTypeName(updateType), + " readPos=", packet.getReadPos(), + " blockStart=", blockStart, + " packetSize=", packet.getSize(), + " (", out.blocks.size(), " blocks kept)"); + } + // Keep successfully parsed blocks instead of discarding all. + // Cannot re-sync within the packet, so stop parsing here. + break; } out.blocks.push_back(std::move(block)); diff --git a/src/game/world_packets.cpp b/src/game/world_packets.cpp index 4867b295..8df1dec0 100644 --- a/src/game/world_packets.cpp +++ b/src/game/world_packets.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -1010,8 +1011,18 @@ bool UpdateObjectParser::parseMovementBlock(network::Packet& packet, UpdateBlock packet.setReadPos(prePointCount); return false; } - packet.readFloat(); packet.readFloat(); packet.readFloat(); // endPoint - LOG_DEBUG(" Spline pointCount=", pc, " compressed=", compressed, " (", tag, ")"); + float epX = packet.readFloat(); + float epY = packet.readFloat(); + float epZ = packet.readFloat(); + // Validate endPoint: garbage bytes rarely produce finite world coords + if (!std::isfinite(epX) || !std::isfinite(epY) || !std::isfinite(epZ) || + std::fabs(epX) > 65000.0f || std::fabs(epY) > 65000.0f || + std::fabs(epZ) > 65000.0f) { + packet.setReadPos(prePointCount); + return false; + } + LOG_DEBUG(" Spline pointCount=", pc, " compressed=", compressed, + " endPt=(", epX, ",", epY, ",", epZ, ") (", tag, ")"); return true; };