feat(zone): read version 1-2 paths

Paths before version 3 are laid out differently (LevelPath::FromBuffer,
1.10.64: pathVersion < 3):
- the type is a u8-length wide string, "platform" for a moving platform
  and anything else ("npc") for a movement path, instead of a u32;
- the flags and behavior u32s follow as in later versions;
- every waypoint, whatever the path's type, has a rotation, lock player
  byte, speed and wait time and then its name/value pairs.

The reader treated the type name's first bytes as the type and misread
everything after it. The LUP group zones of the 0.179.12
client (lup_group_1b, _2a, _6a) now read with all their paths; one of
them read before with a garbage type on a waypoint-less path. Every
other zone reads the same as before (no live zone has a path older than
version 3).

Check in game: nothing to check on live worlds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 04:31:47 -05:00
parent 20f784e262
commit 0d2fcc7dff
2 changed files with 59 additions and 1 deletions

View File

@@ -176,7 +176,12 @@ void ZoneFile::ReadPath(std::istream& file) {
BinaryIO::ReadString<uint8_t>(file, path.pathName, BinaryIO::ReadType::WideString);
BinaryIO::BinaryRead(file, path.pathType);
if (path.pathVersion < 3) {
// Before version 3 the type is a name, "platform" or "npc" (LevelPath::FromBuffer)
std::string typeName;
BinaryIO::ReadString<uint8_t>(file, typeName, BinaryIO::ReadType::WideString);
path.pathType = typeName == "platform" ? PathType::MovingPlatform : PathType::Movement;
} else BinaryIO::BinaryRead(file, path.pathType);
BinaryIO::BinaryRead(file, path.flags);
BinaryIO::BinaryRead(file, path.pathBehavior);
@@ -236,6 +241,19 @@ void ZoneFile::ReadPath(std::istream& file) {
BinaryIO::BinaryRead(file, waypoint.position.y);
BinaryIO::BinaryRead(file, waypoint.position.z);
if (path.pathVersion < 3) {
// Before version 3 every waypoint has a moving platform's data and then name/value pairs, whatever its path's type
BinaryIO::BinaryRead(file, waypoint.rotation.w);
BinaryIO::BinaryRead(file, waypoint.rotation.x);
BinaryIO::BinaryRead(file, waypoint.rotation.y);
BinaryIO::BinaryRead(file, waypoint.rotation.z);
BinaryIO::BinaryRead(file, waypoint.movingPlatform.lockPlayer);
BinaryIO::BinaryRead(file, waypoint.speed);
BinaryIO::BinaryRead(file, waypoint.movingPlatform.wait);
ReadLdfConfig(file, path.pathType, waypoint);
path.pathWaypoints.push_back(waypoint);
continue;
}
if (path.pathType == PathType::Spawner || path.pathType == PathType::MovingPlatform || path.pathType == PathType::Race || path.pathType == PathType::Camera || path.pathType == PathType::Rail) {
BinaryIO::BinaryRead(file, waypoint.rotation.w);