diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2025-08-16 14:52:24 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2025-08-16 14:52:24 -0400 |
commit | c88f4184eaa48efbdc69e76eb3c8a4a206434ad3 (patch) | |
tree | c1da4c419d90debafdd7f71347fe5f3194ff13ee /tools/validator/validator.cpp | |
parent | ac600120eb923e99c534f5c405f7f529c1b25bcf (diff) | |
download | lingo2-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.cpp | 250 |
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 | |||
9 | namespace com::fourisland::lingo2_archipelago { | ||
10 | namespace { | ||
11 | |||
12 | void 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 | |||
41 | void 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 | |||
105 | void 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 | |||
122 | void 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 | |||
145 | void 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 | |||
192 | void 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 | |||
209 | void 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 | |||
226 | void 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 | ||