fix(terrain): read terrain files before version 32 as the client does

The client reads a terrain chunk of a file older than version 32
(1.10.64):
- its color map as width x width BGRA pixels, keeping the
  (width - 1) x (width - 1) before the last row and column, as RGBA
  (RAWReadColorandLightMaps); the reader kept all the pixels as
  written;
- its texture blend map's pixels as BGRA, kept as RGBA (0x0103aaf0);
- before version 31 no scene map, only a byte: the client's scene map is
  all scene 0 (RAWReadSceneMap); the reader had none.

A chunk of width or height 0, which the client reads (no heights, no
color map), no longer fails the whole file.

Live terrain files are version 32, so they read as before.

Check in game: nothing to check (no live terrain changes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 06:43:29 -05:00
parent 71b7f19ec8
commit 93c7b1948f
2 changed files with 51 additions and 11 deletions

View File

@@ -84,6 +84,36 @@ TEST(RawTerrainTests, ReadsEveryLayer) {
EXPECT_FLOAT_EQ(raw.maxBoundsX, 6.0f);
}
// Before version 32: a shader ID, a width x width BGRA color map the client keeps (width - 1) x (width - 1) of as RGBA,
// a BGRA texture map, no light or blend maps, a (width x width) scene map in version 31 and none (all scene 0) before
TEST(RawTerrainTests, ReadsOlderVersions) {
for (const uint16_t version : { 30, 31 }) {
RawWriter w;
w.Put<uint16_t>(version).Put<uint8_t>(0).Put<uint32_t>(1).Put<uint32_t>(1).Put<uint32_t>(1);
w.Put<uint32_t>(0).Put<uint32_t>(3).Put<uint32_t>(3).Put(0.0f).Put(0.0f);
w.Put<uint32_t>(7);
for (uint32_t texture : { 10u, 11u, 12u, 13u }) w.Put(texture);
w.Put(1.0f);
for (int i = 0; i < 9; i++) w.Put(0.0f);
for (int i = 0; i < 9; i++) w.Put<uint8_t>(1).Put<uint8_t>(2).Put<uint8_t>(3).Put<uint8_t>(static_cast<uint8_t>(i)); // BGRA
w.Put<uint32_t>(1).Put<uint8_t>(1).Put<uint8_t>(2).Put<uint8_t>(3).Put<uint8_t>(4);
w.Put<uint32_t>(0); // no flairs
if (version == 31) for (int i = 0; i < 9; i++) w.Put<uint8_t>(static_cast<uint8_t>(i));
else w.Put<uint8_t>(0);
Raw::Raw raw;
ASSERT_TRUE(Read(w.data, raw)) << version;
const auto& chunk = raw.chunks.at(0);
EXPECT_EQ(chunk.shaderId, 7u);
EXPECT_EQ(chunk.colorMapResolution, 2u);
// Rows 0-1, columns 0-1 of the 3 x 3, as RGBA
EXPECT_EQ(chunk.colorMap, (std::vector<uint8_t>{ 3, 2, 1, 0, 3, 2, 1, 1, 3, 2, 1, 3, 3, 2, 1, 4 }));
EXPECT_EQ(chunk.textureMap, (std::vector<uint8_t>{ 3, 2, 1, 4 }));
if (version == 31) EXPECT_EQ(chunk.sceneMap, (std::vector<uint8_t>{ 0, 1, 3, 4 }));
else EXPECT_EQ(chunk.sceneMap, (std::vector<uint8_t>(4, 0)));
}
}
TEST(RawTerrainTests, RejectsDamagedFiles) {
const auto raw = SampleRaw();
for (const size_t length : { size_t{ 0 }, size_t{ 2 }, size_t{ 20 }, raw.size() / 2, raw.size() - 1 }) {