feat(zone): read zone files of every version the client reads

Zone files older than version 30 were refused. The client reads them
(1.10.64):
- LuzFile::ReadLUZFile reads a version below 20 as 20;
- LuzReader::ReadScenes reads a scene of a version 20-29 file as a bare
  u32 SceneTable ID, with no file name;
- ZoneLoader::ReadZoneFile takes those scenes in SceneTable ID order,
  looks each one up in the CDClient SceneTable and, when there is a
  row, makes it a scene with the next index (0, 1, ...; -1 past 255) as
  its ID and the row's sceneName as its file; a scene with no row is
  left out.

ZoneFile now reads these files (FileFormatVersion::Oldest = 20 for
anything older), keeps the SceneTable ID on ZoneScene::sceneTableID,
and ZoneFile::ResolveSceneTable does the lookup the client does; the
world looks the names up in the CDClient SceneTable.

The only such file on disk (version 20) now reads.

Check in game: nothing to check on live worlds (all are version 36+).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 05:10:07 -05:00
parent 00b62edfa0
commit d4fc595e2d
4 changed files with 75 additions and 10 deletions

View File

@@ -12,6 +12,7 @@
#include "AssetManager.h"
#include "CDClientManager.h"
#include "CDZoneTableTable.h"
#include "CDClientDatabase.h"
#include "Spawner.h"
#include "dZoneManager.h"
#include "dpWorld.h"
@@ -56,6 +57,14 @@ void Zone::LoadZoneIntoMemory() {
// The file itself is read by ZoneFile (dCommon), which the dashboard uses too
ZoneFile zoneFile;
zoneFile.Read(file);
// The oldest files name their scenes by SceneTable ID
zoneFile.ResolveSceneTable([](uint32_t sceneTableID) -> std::optional<std::string> {
auto query = CDClientDatabase::CreatePreppedStmt("SELECT sceneName FROM SceneTable WHERE sceneID = ?;");
query.bind(1, static_cast<int32_t>(sceneTableID));
auto result = query.execQuery();
if (result.eof() || result.fieldIsNull("sceneName")) return std::nullopt;
return std::string(result.getStringField("sceneName"));
});
m_FileFormatVersion = zoneFile.fileFormatVersion;
m_WorldID = zoneFile.worldID;
if (static_cast<LWOMAPID>(m_WorldID) != m_ZoneID.GetMapID()) LOG("WorldID: %i doesn't match MapID %i! Is this intended?", m_WorldID, m_ZoneID.GetMapID());