From 942d0ff8adaff675b2140ed7c78bdb116e80f5c7 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 29 Sep 2026 04:27:45 -0500 Subject: [PATCH] fix(zone): PrePreAlpha zone files have no zone name or description The client reads a zone's name and description only when the file is newer than version 30 (LuzFile::ReadLUZFile, 1.10.64: revision > 0x1e); a version 30 file ends at its terrain file's name. The reader read both strings for every version, so version 30 files ran off their end. The four version 30 zones of the alpha leak (scale_TEST_ASSETS, Gnarled_assetsMIKET, dennis_gnarled_forest_02/_03-ninja) now read. Some of them have a stray name string after the terrain file's name, which the client does not read either. Every newer file reads the same as before. Check in game: nothing to check on live worlds (none is version 30). Co-Authored-By: Claude Opus 5.5 --- dCommon/ZoneFile.cpp | 7 +++++-- tests/dCommonTests/ZoneFileTests.cpp | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/dCommon/ZoneFile.cpp b/dCommon/ZoneFile.cpp index 3efdf63a8..9c9e10535 100644 --- a/dCommon/ZoneFile.cpp +++ b/dCommon/ZoneFile.cpp @@ -42,8 +42,11 @@ void ZoneFile::ReadHeader(std::istream& file) { //Read generic zone info: BinaryIO::ReadString(file, zoneRawPath, BinaryIO::ReadType::String); - BinaryIO::ReadString(file, zoneName, BinaryIO::ReadType::String); - BinaryIO::ReadString(file, zoneDesc, BinaryIO::ReadType::String); + // PrePreAlpha files have no name or description (LuzFile::ReadLUZFile) + if (fileFormatVersion > FileFormatVersion::PrePreAlpha) { + BinaryIO::ReadString(file, zoneName, BinaryIO::ReadType::String); + BinaryIO::ReadString(file, zoneDesc, BinaryIO::ReadType::String); + } } void ZoneFile::Read(std::istream& file) { diff --git a/tests/dCommonTests/ZoneFileTests.cpp b/tests/dCommonTests/ZoneFileTests.cpp index 739efd7fb..f83f5b11e 100644 --- a/tests/dCommonTests/ZoneFileTests.cpp +++ b/tests/dCommonTests/ZoneFileTests.cpp @@ -148,6 +148,22 @@ TEST(ZoneFileTests, VersionsBeforePrePreAlphaThrow) { EXPECT_TRUE(zone.scenes.empty()); } +// A PrePreAlpha (30) file ends at its terrain file's name: no zone name, description, transitions or paths +TEST(ZoneFileTests, PrePreAlphaHasNoZoneName) { + ZoneBytes w; + w.Put(30).Put(72).Put(1).Text("scale.lvl"); // version, world, one scene: only its file + w.Put(0).Text("scale.raw"); + std::istringstream stream(w.data); + ZoneFile zone; + zone.Read(stream); + EXPECT_FALSE(stream.fail()); + ASSERT_EQ(zone.scenes.size(), 1u); + EXPECT_EQ(zone.scenes[0].filename, "scale.lvl"); + EXPECT_EQ(zone.zoneRawPath, "scale.raw"); + EXPECT_TRUE(zone.zoneName.empty()); + EXPECT_TRUE(zone.zoneDesc.empty()); +} + TEST(ZoneFileTests, ShortFilesThrowOrFail) { const auto zone = SampleZone(); for (const size_t length : { size_t{ 3 }, size_t{ 40 }, zone.size() / 2, zone.size() - 1 }) {