From c88f4184eaa48efbdc69e76eb3c8a4a206434ad3 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 16 Aug 2025 14:52:24 -0400 Subject: Started writing a data validator Currently, it can check whether identifiers point to non-existent objects, or whether multiple objects share the same identifier. It can also determine whether an identifier is underspecified (e.g. a door doesn't specify a room, or a global connection doesn't specify a map). --- tools/validator/validator.cpp | 250 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 tools/validator/validator.cpp (limited to 'tools/validator/validator.cpp') diff --git a/tools/validator/validator.cpp b/tools/validator/validator.cpp new file mode 100644 index 0000000..3381ed2 --- /dev/null +++ b/tools/validator/validator.cpp @@ -0,0 +1,250 @@ +#include "validator.h" + +#include + +#include "proto/human.pb.h" +#include "structs.h" +#include "util/identifiers.h" + +namespace com::fourisland::lingo2_archipelago { +namespace { + +void ValidateRoom(const RoomIdentifier& room_identifier, + const RoomInfo& room_info) { + if (room_info.definitions.empty()) { + std::cout << "Room " << room_identifier.ShortDebugString() + << " has no definition, but was referenced:" << std::endl; + + for (const DoorIdentifier& door_identifier : + room_info.doors_referenced_by) { + std::cout << " DOOR " << door_identifier.ShortDebugString() + << std::endl; + } + + for (const PanelIdentifier& panel_identifier : + room_info.panels_referenced_by) { + std::cout << " PANEL " << panel_identifier.ShortDebugString() + << std::endl; + } + + for (const HumanConnection& connection : + room_info.connections_referenced_by) { + std::cout << " CONNECTION " << connection.ShortDebugString() + << std::endl; + } + } else if (room_info.definitions.size() > 1) { + std::cout << "Room " << room_identifier.ShortDebugString() + << " was defined multiple times." << std::endl; + } +} + +void ValidateDoor(const DoorIdentifier& door_identifier, + const DoorInfo& door_info) { + if (door_info.definitions.empty()) { + std::cout << "Door " << door_identifier.ShortDebugString() + << " has no definition, but was referenced:" << std::endl; + + for (const DoorIdentifier& other_door_identifier : + door_info.doors_referenced_by) { + std::cout << " DOOR " << other_door_identifier.ShortDebugString() + << std::endl; + } + + for (const PanelIdentifier& panel_identifier : + door_info.panels_referenced_by) { + std::cout << " PANEL " << panel_identifier.ShortDebugString() + << std::endl; + } + + for (const PaintingIdentifier& painting_identifier : + door_info.paintings_referenced_by) { + std::cout << " PAINTING " << painting_identifier.ShortDebugString() + << std::endl; + } + + for (const PortIdentifier& port_identifier : + door_info.ports_referenced_by) { + std::cout << " PORT " << port_identifier.ShortDebugString() + << std::endl; + } + + for (const HumanConnection& connection : + door_info.connections_referenced_by) { + std::cout << " CONNECTION " << connection.ShortDebugString() + << std::endl; + } + } else if (door_info.definitions.size() > 1) { + std::cout << "Door " << door_identifier.ShortDebugString() + << " was defined multiple times." << std::endl; + } + + if (door_info.malformed_identifiers.HasAny()) { + std::cout << "Door " << door_identifier.ShortDebugString() + << " has malformed identifiers:" << std::endl; + + for (const PaintingIdentifier& painting_identifier : + door_info.malformed_identifiers.paintings) { + std::cout << " PAINTING " << painting_identifier.ShortDebugString() + << std::endl; + } + + for (const PanelIdentifier& panel_identifier : + door_info.malformed_identifiers.panels) { + std::cout << " PANEL " << panel_identifier.ShortDebugString() + << std::endl; + } + + for (const KeyholderIdentifier& keyholder_identifier : + door_info.malformed_identifiers.keyholders) { + std::cout << " KEYHOLDER " << keyholder_identifier.ShortDebugString() + << std::endl; + } + } +} + +void ValidatePort(const PortIdentifier& port_identifier, + const PortInfo& port_info) { + if (port_info.definitions.empty()) { + std::cout << "Port " << port_identifier.ShortDebugString() + << " has no definition, but was referenced:" << std::endl; + + for (const HumanConnection& connection : + port_info.connections_referenced_by) { + std::cout << " CONNECTION " << connection.ShortDebugString() + << std::endl; + } + } else if (port_info.definitions.size() > 1) { + std::cout << "Port " << port_identifier.ShortDebugString() + << " was defined multiple times." << std::endl; + } +} + +void ValidatePainting(const PaintingIdentifier& painting_identifier, + const PaintingInfo& painting_info) { + if (painting_info.definitions.empty()) { + std::cout << "Painting " << painting_identifier.ShortDebugString() + << " has no definition, but was referenced:" << std::endl; + + for (const DoorIdentifier& door_identifier : + painting_info.doors_referenced_by) { + std::cout << " DOOR " << door_identifier.ShortDebugString() + << std::endl; + } + + for (const HumanConnection& connection : + painting_info.connections_referenced_by) { + std::cout << " CONNECTION " << connection.ShortDebugString() + << std::endl; + } + } else if (painting_info.definitions.size() > 1) { + std::cout << "Painting " << painting_identifier.ShortDebugString() + << " was defined multiple times." << std::endl; + } +} + +void ValidatePanel(const PanelIdentifier& panel_identifier, + const PanelInfo& panel_info) { + if (panel_info.definitions.empty()) { + std::cout << "Panel " << panel_identifier.ShortDebugString() + << " has no definition, but was referenced:" << std::endl; + + for (const DoorIdentifier& door_identifier : + panel_info.doors_referenced_by) { + std::cout << " DOOR " << door_identifier.ShortDebugString() + << std::endl; + } + + for (const HumanConnection& connection : + panel_info.connections_referenced_by) { + std::cout << " CONNECTION " << connection.ShortDebugString() + << std::endl; + } + } else if (panel_info.definitions.size() > 1) { + std::cout << "Panel " << panel_identifier.ShortDebugString() + << " was defined multiple times." << std::endl; + } + + for (const auto& [answer, proxy_info] : panel_info.proxies) { + if (proxy_info.definitions.empty()) { + std::cout << "Panel " << panel_identifier.ShortDebugString() + << " with answer \"" << answer + << "\" has no definition, but was referenced:" << std::endl; + + for (const DoorIdentifier& door_identifier : + proxy_info.doors_referenced_by) { + std::cout << " DOOR " << door_identifier.ShortDebugString() + << std::endl; + } + + for (const HumanConnection& connection : + proxy_info.connections_referenced_by) { + std::cout << " CONNECTION " << connection.ShortDebugString() + << std::endl; + } + } else if (proxy_info.definitions.size() > 1) { + std::cout << "Panel " << panel_identifier.ShortDebugString() + << " with answer \"" << answer + << "\" was defined multiple times." << std::endl; + } + } +} + +void ValidateKeyholder(const KeyholderIdentifier& keyholder_identifier, + const KeyholderInfo& keyholder_info) { + if (keyholder_info.definitions.empty()) { + std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() + << " has no definition, but was referenced:" << std::endl; + + for (const DoorIdentifier& door_identifier : + keyholder_info.doors_referenced_by) { + std::cout << " DOOR " << door_identifier.ShortDebugString() + << std::endl; + } + } else if (keyholder_info.definitions.size() > 1) { + std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() + << " was defined multiple times." << std::endl; + } +} + +void ValidateLetter(const LetterIdentifier& letter_identifier, + const LetterInfo& letter_info) { + std::string letter_name = std::string(1, std::get<0>(letter_identifier)) + + (std::get<1>(letter_identifier) ? "2" : "1"); + + if (letter_info.defined_in.size() > 1) { + std::cout << "Letter " << letter_name + << " was defined in multiple places:" << std::endl; + + for (const RoomIdentifier& room_identifier : letter_info.defined_in) { + std::cout << " " << room_identifier.ShortDebugString() << std::endl; + } + } +} + +} // namespace + +void ValidateCollectedInfo(const CollectedInfo& info) { + for (const auto& [room_identifier, room_info] : info.rooms) { + ValidateRoom(room_identifier, room_info); + } + for (const auto& [door_identifier, door_info] : info.doors) { + ValidateDoor(door_identifier, door_info); + } + for (const auto& [port_identifier, port_info] : info.ports) { + ValidatePort(port_identifier, port_info); + } + for (const auto& [painting_identifier, painting_info] : info.paintings) { + ValidatePainting(painting_identifier, painting_info); + } + for (const auto& [panel_identifier, panel_info] : info.panels) { + ValidatePanel(panel_identifier, panel_info); + } + for (const auto& [keyholder_identifier, keyholder_info] : info.keyholders) { + ValidateKeyholder(keyholder_identifier, keyholder_info); + } + for (const auto& [letter_identifier, letter_info] : info.letters) { + ValidateLetter(letter_identifier, letter_info); + } +} + +} // namespace com::fourisland::lingo2_archipelago -- cgit 1.4.1