mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
fix(zone): zone files older than version 30 are refused
Before version 30 (PrePreAlpha) a zone file's scene is only a u32 scene ID, with no scene file name (LuzReader::ReadScenes, 1.10.64: revision < 30 reads the ID alone; LuzFile::ReadLUZFile treats anything below 20 as 20). The reader read a file name and then an ID for those versions, which is not the format, and the world could not load such a zone's scenes anyway. Reading one now throws a runtime_error that says why, before anything else is read. No zone file of any client on disk is older than 30 except an unnamed editor stub (a res/.luz, version 20). Check in game: every world loads as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <istream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "BinaryIO.h"
|
||||
#include "Game.h"
|
||||
@@ -10,6 +12,10 @@
|
||||
|
||||
void ZoneFile::ReadHeader(std::istream& file) {
|
||||
BinaryIO::BinaryRead(file, fileFormatVersion);
|
||||
// Before PrePreAlpha a scene is only its ID, with no file to load it from (LuzReader::ReadScenes)
|
||||
if (fileFormatVersion < FileFormatVersion::PrePreAlpha) {
|
||||
throw std::runtime_error("Zone file version " + std::to_string(static_cast<uint32_t>(fileFormatVersion)) + " is older than " + std::to_string(static_cast<uint32_t>(FileFormatVersion::PrePreAlpha)) + ": its scenes have no files");
|
||||
}
|
||||
|
||||
if (fileFormatVersion >= FileFormatVersion::Alpha) BinaryIO::BinaryRead(file, mapRevision);
|
||||
|
||||
@@ -68,10 +74,8 @@ void ZoneFile::ReadScene(std::istream& file) {
|
||||
|
||||
BinaryIO::ReadString<uint8_t>(file, scene.filename, BinaryIO::ReadType::String);
|
||||
|
||||
if (fileFormatVersion >= FileFormatVersion::LatePreAlpha || fileFormatVersion < FileFormatVersion::PrePreAlpha) {
|
||||
BinaryIO::BinaryRead(file, scene.id);
|
||||
}
|
||||
if (fileFormatVersion >= FileFormatVersion::LatePreAlpha) {
|
||||
BinaryIO::BinaryRead(file, scene.id);
|
||||
BinaryIO::BinaryRead(file, scene.sceneType);
|
||||
|
||||
BinaryIO::ReadString<uint8_t>(file, scene.name, BinaryIO::ReadType::String);
|
||||
|
||||
@@ -138,6 +138,16 @@ TEST(ZoneFileTests, LateAlphaSceneCountIsAU32) {
|
||||
EXPECT_EQ(zone.zoneRawPath, "zone.raw");
|
||||
}
|
||||
|
||||
// Before version 30 a scene is only an ID, with no file to load
|
||||
TEST(ZoneFileTests, VersionsBeforePrePreAlphaThrow) {
|
||||
ZoneBytes w;
|
||||
w.Put<uint32_t>(20).Put<uint32_t>(53).Put<uint8_t>(1).Put<uint32_t>(53).Put<uint8_t>(0).Text(".raw");
|
||||
std::istringstream stream(w.data);
|
||||
ZoneFile zone;
|
||||
EXPECT_THROW(zone.Read(stream), std::runtime_error);
|
||||
EXPECT_TRUE(zone.scenes.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 }) {
|
||||
|
||||
Reference in New Issue
Block a user