From 1cd8e53b2f17d3c33ab69b6afc2658440691eeb5 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 13 Mar 2026 02:38:53 -0700 Subject: [PATCH] fix: handle SPLINEFLAG_ANIMATION in UPDATE_OBJECT legacy spline layout When SPLINEFLAG_ANIMATION (0x00400000) is set, AzerothCore inserts 5 bytes (uint8 animationType + int32 animTime) between durationModNext and verticalAccel in the SMSG_UPDATE_OBJECT MoveSpline block. The parser was not accounting for these bytes, causing verticalAccel, effectStartTime, and pointCount to be read from the wrong offset. This produced garbage pointCount values (e.g. 3322451254) triggering the "Spline pointCount invalid (legacy+compact)" fallback path and breaking UPDATE_OBJECT parsing for animated-spline entities, causing all subsequent update blocks in the same packet to be dropped. --- src/game/world_packets.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/game/world_packets.cpp b/src/game/world_packets.cpp index e183ff16..48ac2cfe 100644 --- a/src/game/world_packets.cpp +++ b/src/game/world_packets.cpp @@ -1031,6 +1031,7 @@ bool UpdateObjectParser::parseMovementBlock(network::Packet& packet, UpdateBlock // Legacy UPDATE_OBJECT spline layout used by many servers: // timePassed, duration, splineId, durationMod, durationModNext, + // [ANIMATION: animType(1)+animTime(4) if SPLINEFLAG_ANIMATION(0x00400000)], // verticalAccel, effectStartTime, pointCount, points, splineMode, endPoint. const size_t legacyStart = packet.getReadPos(); if (!bytesAvailable(12 + 8 + 8 + 4)) return false; @@ -1039,6 +1040,12 @@ bool UpdateObjectParser::parseMovementBlock(network::Packet& packet, UpdateBlock /*uint32_t splineId =*/ packet.readUInt32(); /*float durationMod =*/ packet.readFloat(); /*float durationModNext =*/ packet.readFloat(); + // Animation flag inserts 5 bytes (uint8 type + int32 time) before verticalAccel + if (splineFlags & 0x00400000) { // SPLINEFLAG_ANIMATION + if (!bytesAvailable(5)) return false; + packet.readUInt8(); // animationType + packet.readUInt32(); // animTime + } /*float verticalAccel =*/ packet.readFloat(); /*uint32_t effectStartTime =*/ packet.readUInt32(); uint32_t pointCount = packet.readUInt32();