mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-09 06:13:43 +00:00
The NexusDashboard-parity dashboard (dDashboardServer) and everything built on it on the experimental branch: accounts, characters, properties and moderation tools, permissions shared with in-game slash commands, economy reports, World 3D and property 3D views with client scenery, scheduled events (features, vanity changes, live events, announcements, restarts), vanity files and events, the CDClient browser, the message inspector with saved captures, chat filter tools, community challenges, live ops, the AI moderator helper, and the server-side changes they need. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
2.9 KiB
C++
81 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <exception>
|
|
#include <optional>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "ZoneFile.h"
|
|
|
|
/**
|
|
* Property build areas and scene files from a zone file (.luz), for the 3D views and the rescue page.
|
|
*
|
|
* A property zone has a path of type Property: its waypoints outline where players may build, and it carries the
|
|
* highest point they may build to. The file is read by ZoneFile (dCommon), the same reader the world server's
|
|
* Zone::LoadZoneIntoMemory uses. Pure (bytes in, areas out) so it can be unit tested.
|
|
*/
|
|
namespace ZonePaths {
|
|
struct Point {
|
|
float x{};
|
|
float y{};
|
|
float z{};
|
|
};
|
|
|
|
struct PropertyArea {
|
|
std::string name; // the path's name, e.g. "PropertyPath"
|
|
std::string displayName; // what the property is called when rented
|
|
int32_t areaType{}; // 0: the waypoints outline it, 1: the entire zone, 2: a generated rectangle
|
|
float maxBuildHeight{}; // 0 when the file doesn't say
|
|
std::vector<Point> outline;
|
|
};
|
|
|
|
/**
|
|
* The zone file, or nullopt and error if it ends early. `headerOnly` stops after the scenes and the terrain file's
|
|
* name (ZoneFile::ReadHeader), skipping the scene transitions and paths, which is all most views need.
|
|
*/
|
|
inline std::optional<ZoneFile> Read(const std::string& luz, std::string& error, bool headerOnly = false) {
|
|
std::istringstream stream(luz);
|
|
ZoneFile zone;
|
|
try {
|
|
if (headerOnly) zone.ReadHeader(stream);
|
|
else zone.Read(stream);
|
|
} catch (const std::exception&) {
|
|
stream.setstate(std::ios::failbit);
|
|
}
|
|
if (stream.fail()) {
|
|
error = "The zone file is shorter than expected";
|
|
return std::nullopt;
|
|
}
|
|
return zone;
|
|
}
|
|
|
|
// The start of the zone file: version, spawn point, scenes and the terrain file's name
|
|
inline std::optional<ZoneFile> ReadHeader(const std::string& luz, std::string& error) {
|
|
return Read(luz, error, true);
|
|
}
|
|
|
|
// The zone's scene files (.lvl), relative to the folder the .luz is in; empty if the file can't be read
|
|
inline std::vector<std::string> ReadSceneFiles(const std::string& luz) {
|
|
std::string error;
|
|
const auto zone = ReadHeader(luz, error);
|
|
std::vector<std::string> files;
|
|
if (zone) for (const auto& scene : zone->scenes) files.push_back(scene.filename);
|
|
return files;
|
|
}
|
|
|
|
inline std::optional<std::vector<PropertyArea>> ReadPropertyAreas(const std::string& luz, std::string& error) {
|
|
const auto zone = Read(luz, error);
|
|
if (!zone) return std::nullopt;
|
|
std::vector<PropertyArea> areas;
|
|
for (const auto& path : zone->paths) {
|
|
if (path.pathType != PathType::Property) continue;
|
|
PropertyArea area{ path.pathName, path.property.displayName, static_cast<int32_t>(path.property.pathType), path.property.maxBuildHeight };
|
|
for (const auto& waypoint : path.pathWaypoints) area.outline.push_back({ waypoint.position.x, waypoint.position.y, waypoint.position.z });
|
|
areas.push_back(std::move(area));
|
|
}
|
|
return areas;
|
|
}
|
|
}
|