summary refs log tree commit diff stats
path: root/tools/validator/validator.cpp
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2025-08-16 14:52:24 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2025-08-16 14:52:24 -0400
commitc88f4184eaa48efbdc69e76eb3c8a4a206434ad3 (patch)
treec1da4c419d90debafdd7f71347fe5f3194ff13ee /tools/validator/validator.cpp
parentac600120eb923e99c534f5c405f7f529c1b25bcf (diff)
downloadlingo2-archipelago-c88f4184eaa48efbdc69e76eb3c8a4a206434ad3.tar.gz
lingo2-archipelago-c88f4184eaa48efbdc69e76eb3c8a4a206434ad3.tar.bz2
lingo2-archipelago-c88f4184eaa48efbdc69e76eb3c8a4a206434ad3.zip
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).
Diffstat (limited to 'tools/validator/validator.cpp')
-rw-r--r--tools/validator/validator.cpp250
1 files changed, 250 insertions, 0 deletions
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 @@
1#include "validator.h"
2
3#include <iostream>
4
5#include "proto/human.pb.h"
6#include "structs.h"
7#include "util/identifiers.h"
8
9namespace com::fourisland::lingo2_archipelago {
10namespace {
11
12void ValidateRoom(const RoomIdentifier& room_identifier,
13 const RoomInfo& room_info) {
14 if (room_info.definitions.empty()) {
15 std::cout << "Room " << room_identifier.ShortDebugString()
16 << " has no definition, but was referenced:" << std::endl;
17
18 for (const DoorIdentifier& door_identifier :
19 room_info.doors_referenced_by) {
20 std::cout << " DOOR " << door_identifier.ShortDebugString()
21 << std::endl;
22 }
23
24 for (const PanelIdentifier& panel_identifier :
25 room_info.panels_referenced_by) {
26 std::cout << " PANEL " << panel_identifier.ShortDebugString()
27 << std::endl;
28 }
29
30 for (const HumanConnection& connection :
31 room_info.connections_referenced_by) {
32 std::cout << " CONNECTION " << connection.ShortDebugString()
33 << std::endl;
34 }
35 } else if (room_info.definitions.size() > 1) {
36 std::cout << "Room " << room_identifier.ShortDebugString()
37 << " was defined multiple times." << std::endl;
38 }
39}
40
41void ValidateDoor(const DoorIdentifier& door_identifier,
42 const DoorInfo& door_info) {
43 if (door_info.definitions.empty()) {
44 std::cout << "Door " << door_identifier.ShortDebugString()
45 << " has no definition, but was referenced:" << std::endl;
46
47 for (const DoorIdentifier& other_door_identifier :
48 door_info.doors_referenced_by) {
49 std::cout << " DOOR " << other_door_identifier.ShortDebugString()
50 << std::endl;
51 }
52
53 for (const PanelIdentifier& panel_identifier :
54 door_info.panels_referenced_by) {
55 std::cout << " PANEL " << panel_identifier.ShortDebugString()
56 << std::endl;
57 }
58
59 for (const PaintingIdentifier& painting_identifier :
60 door_info.paintings_referenced_by) {
61 std::cout << " PAINTING " << painting_identifier.ShortDebugString()
62 << std::endl;
63 }
64
65 for (const PortIdentifier& port_identifier :
66 door_info.ports_referenced_by) {
67 std::cout << " PORT " << port_identifier.ShortDebugString()
68 << std::endl;
69 }
70
71 for (const HumanConnection& connection :
72 door_info.connections_referenced_by) {
73 std::cout << " CONNECTION " << connection.ShortDebugString()
74 << std::endl;
75 }
76 } else if (door_info.definitions.size() > 1) {
77 std::cout << "Door " << door_identifier.ShortDebugString()
78 << " was defined multiple times." << std::endl;
79 }
80
81 if (door_info.malformed_identifiers.HasAny()) {
82 std::cout << "Door " << door_identifier.ShortDebugString()
83 << " has malformed identifiers:" << std::endl;
84
85 for (const PaintingIdentifier& painting_identifier :
86 door_info.malformed_identifiers.paintings) {
87 std::cout << " PAINTING " << painting_identifier.ShortDebugString()
88 << std::endl;
89 }
90
91 for (const PanelIdentifier& panel_identifier :
92 door_info.malformed_identifiers.panels) {
93 std::cout << " PANEL " << panel_identifier.ShortDebugString()
94 << std::endl;
95 }
96
97 for (const KeyholderIdentifier& keyholder_identifier :
98 door_info.malformed_identifiers.keyholders) {
99 std::cout << " KEYHOLDER " << keyholder_identifier.ShortDebugString()
100 << std::endl;
101 }
102 }
103}
104
105void ValidatePort(const PortIdentifier& port_identifier,
106 const PortInfo& port_info) {
107 if (port_info.definitions.empty()) {
108 std::cout << "Port " << port_identifier.ShortDebugString()
109 << " has no definition, but was referenced:" << std::endl;
110
111 for (const HumanConnection& connection :
112 port_info.connections_referenced_by) {
113 std::cout << " CONNECTION " << connection.ShortDebugString()
114 << std::endl;
115 }
116 } else if (port_info.definitions.size() > 1) {
117 std::cout << "Port " << port_identifier.ShortDebugString()
118 << " was defined multiple times." << std::endl;
119 }
120}
121
122void ValidatePainting(const PaintingIdentifier& painting_identifier,
123 const PaintingInfo& painting_info) {
124 if (painting_info.definitions.empty()) {
125 std::cout << "Painting " << painting_identifier.ShortDebugString()
126 << " has no definition, but was referenced:" << std::endl;
127
128 for (const DoorIdentifier& door_identifier :
129 painting_info.doors_referenced_by) {
130 std::cout << " DOOR " << door_identifier.ShortDebugString()
131 << std::endl;
132 }
133
134 for (const HumanConnection& connection :
135 painting_info.connections_referenced_by) {
136 std::cout << " CONNECTION " << connection.ShortDebugString()
137 << std::endl;
138 }
139 } else if (painting_info.definitions.size() > 1) {
140 std::cout << "Painting " << painting_identifier.ShortDebugString()
141 << " was defined multiple times." << std::endl;
142 }
143}
144
145void ValidatePanel(const PanelIdentifier& panel_identifier,
146 const PanelInfo& panel_info) {
147 if (panel_info.definitions.empty()) {
148 std::cout << "Panel " << panel_identifier.ShortDebugString()
149 << " has no definition, but was referenced:" << std::endl;
150
151 for (const DoorIdentifier& door_identifier :
152 panel_info.doors_referenced_by) {
153 std::cout << " DOOR " << door_identifier.ShortDebugString()
154 << std::endl;
155 }
156
157 for (const HumanConnection& connection :
158 panel_info.connections_referenced_by) {
159 std::cout << " CONNECTION " << connection.ShortDebugString()
160 << std::endl;
161 }
162 } else if (panel_info.definitions.size() > 1) {
163 std::cout << "Panel " << panel_identifier.ShortDebugString()
164 << " was defined multiple times." << std::endl;
165 }
166
167 for (const auto& [answer, proxy_info] : panel_info.proxies) {
168 if (proxy_info.definitions.empty()) {
169 std::cout << "Panel " << panel_identifier.ShortDebugString()
170 << " with answer \"" << answer
171 << "\" has no definition, but was referenced:" << std::endl;
172
173 for (const DoorIdentifier& door_identifier :
174 proxy_info.doors_referenced_by) {
175 std::cout << " DOOR " << door_identifier.ShortDebugString()
176 << std::endl;
177 }
178
179 for (const HumanConnection& connection :
180 proxy_info.connections_referenced_by) {
181 std::cout << " CONNECTION " << connection.ShortDebugString()
182 << std::endl;
183 }
184 } else if (proxy_info.definitions.size() > 1) {
185 std::cout << "Panel " << panel_identifier.ShortDebugString()
186 << " with answer \"" << answer
187 << "\" was defined multiple times." << std::endl;
188 }
189 }
190}
191
192void ValidateKeyholder(const KeyholderIdentifier& keyholder_identifier,
193 const KeyholderInfo& keyholder_info) {
194 if (keyholder_info.definitions.empty()) {
195 std::cout << "Keyholder " << keyholder_identifier.ShortDebugString()
196 << " has no definition, but was referenced:" << std::endl;
197
198 for (const DoorIdentifier& door_identifier :
199 keyholder_info.doors_referenced_by) {
200 std::cout << " DOOR " << door_identifier.ShortDebugString()
201 << std::endl;
202 }
203 } else if (keyholder_info.definitions.size() > 1) {
204 std::cout << "Keyholder " << keyholder_identifier.ShortDebugString()
205 << " was defined multiple times." << std::endl;
206 }
207}
208
209void ValidateLetter(const LetterIdentifier& letter_identifier,
210 const LetterInfo& letter_info) {
211 std::string letter_name = std::string(1, std::get<0>(letter_identifier)) +
212 (std::get<1>(letter_identifier) ? "2" : "1");
213
214 if (letter_info.defined_in.size() > 1) {
215 std::cout << "Letter " << letter_name
216 << " was defined in multiple places:" << std::endl;
217
218 for (const RoomIdentifier& room_identifier : letter_info.defined_in) {
219 std::cout << " " << room_identifier.ShortDebugString() << std::endl;
220 }
221 }
222}
223
224} // namespace
225
226void ValidateCollectedInfo(const CollectedInfo& info) {
227 for (const auto& [room_identifier, room_info] : info.rooms) {
228 ValidateRoom(room_identifier, room_info);
229 }
230 for (const auto& [door_identifier, door_info] : info.doors) {
231 ValidateDoor(door_identifier, door_info);
232 }
233 for (const auto& [port_identifier, port_info] : info.ports) {
234 ValidatePort(port_identifier, port_info);
235 }
236 for (const auto& [painting_identifier, painting_info] : info.paintings) {
237 ValidatePainting(painting_identifier, painting_info);
238 }
239 for (const auto& [panel_identifier, panel_info] : info.panels) {
240 ValidatePanel(panel_identifier, panel_info);
241 }
242 for (const auto& [keyholder_identifier, keyholder_info] : info.keyholders) {
243 ValidateKeyholder(keyholder_identifier, keyholder_info);
244 }
245 for (const auto& [letter_identifier, letter_info] : info.letters) {
246 ValidateLetter(letter_identifier, letter_info);
247 }
248}
249
250} // namespace com::fourisland::lingo2_archipelago