Files
DarkflameServer/dDashboardServer/routes/ReportRoutes.h
Aaron Kimbrell 17689cd663 feat: build a zone's 3D data on worker threads
Opening a zone the first time built its terrain, scene objects and manifests
and ran ImageMagick on the web thread, stalling the dashboard for seconds.

- Workers: the shared pool plus Workers::Reply (answer at once when built,
  else from a worker via Web::Defer).
- terrain_chunks/terrain_layers/scene/paths/scenery/flairs (world3d, property
  and showcase routes) and terrain textures go through it; results are built
  once in OnceCaches, the .raw is read once per zone for chunks, layers and
  flairs, deflated bodies are cached thread-safely.
- ImageMagick conversions are deduplicated and written under a temporary name.
- Workers don't query the CDClient, read settings or call mongoose: ZoneTable,
  render components, flairs, object names, LOT kinds and terrain texture names
  are read at startup; client_location is read once; base64 is plain C++.
- Logger writes one line at a time (mutex; localtime's buffer is shared).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:30:51 -05:00

68 lines
2.9 KiB
C++

#pragma once
// Economy reports: coin/U-score/item flows, transfers between players, item tracing and duplicate scans
void RegisterReportRoutes();
#include "json.hpp"
#include <functional>
#include <string>
/**
* Scan every character and unclaimed mail for duplicated object ids in the background; the result is also what the
* Duplicates tab shows. done runs on the main thread. Returns false if a scan is already running.
*/
bool StartDuplicateScan(std::function<void(const nlohmann::json& scan, const std::string& error)> done);
#include <cstdint>
#include <optional>
// A zone's terrain as the map reports use it (heights quantized to 16 bits, base64), cached; nullopt without a client
std::optional<std::string> ZoneTerrainJson(uint32_t zoneId);
#include "Raw.h"
/**
* The zone data below is built on the dashboard's worker threads too, so it is thread safe: results are built once
* (OnceCache) and the CDClient tables it needs are read at startup by PreloadZoneData (workers never query the
* CDClient). The ...Ready functions say whether a result is built, so a route can answer it at once.
*/
void PreloadZoneData();
bool ZoneTerrainJsonReady(uint32_t zoneId);
bool ZoneTerrainChunksReady(uint32_t zoneId);
bool ZoneTerrainLayersReady(uint32_t zoneId);
bool TerrainTextureReady(uint32_t textureId);
// A zone's .luz file (relative to res/maps) from ZoneTable
std::optional<std::string> ZoneLuzPath(uint32_t zoneId);
#include <memory>
// ZoneRaw, shared: the last few zones read are kept, and a zone asked for by several threads at once is read once
std::shared_ptr<const Raw::Raw> ZoneRawShared(uint32_t zoneId);
// A zone's terrain file (.raw) read whole, as its .luz names it; nullopt without client files or when it's damaged
std::optional<Raw::Raw> ZoneRaw(uint32_t zoneId);
// Every terrain chunk of a zone as the client draws it (heights, textures, color and blend maps); nullopt without files
std::optional<std::string> ZoneTerrainChunksJson(uint32_t zoneId);
/**
* The rest of a zone's terrain file, for the 3D world view's terrain layers: per chunk (in ZoneTerrainChunksJson's
* order) the scene of each terrain cell, plus the scenes found with their names from the .luz, the game's scene colors
* and their share of the terrain. Cached; nullopt without files.
*/
std::optional<std::string> ZoneTerrainLayersJson(uint32_t zoneId);
// A terrain texture (mapTextureResource ID) as a PNG
std::optional<std::string> TerrainTextureFile(uint32_t textureId);
// A zone's property build areas (outline and height limit) from its .luz; nullopt without client files
std::optional<nlohmann::json> ZonePropertyAreasJson(uint32_t zoneId);
// Where a player can be put in a zone: [{name, lot, x, y, z}] from its scene files; nullopt without client files
std::optional<nlohmann::json> ZoneSpawnPointsJson(uint32_t zoneId);
// Economy source id (as a string) -> name, for labelling flows
nlohmann::json EconomySourceNames();