summary refs log tree commit diff stats
path: root/tools/validator
diff options
context:
space:
mode:
Diffstat (limited to 'tools/validator')
-rw-r--r--tools/validator/CMakeLists.txt1
-rw-r--r--tools/validator/godot_processor.cpp76
-rw-r--r--tools/validator/godot_processor.h14
-rw-r--r--tools/validator/human_processor.cpp15
-rw-r--r--tools/validator/main.cpp11
-rw-r--r--tools/validator/structs.h1
-rw-r--r--tools/validator/validator.cpp8
7 files changed, 122 insertions, 4 deletions
diff --git a/tools/validator/CMakeLists.txt b/tools/validator/CMakeLists.txt index 0ad58c2..967b890 100644 --- a/tools/validator/CMakeLists.txt +++ b/tools/validator/CMakeLists.txt
@@ -1,6 +1,7 @@
1find_package(Protobuf REQUIRED) 1find_package(Protobuf REQUIRED)
2 2
3add_executable(validator 3add_executable(validator
4 godot_processor.cpp
4 human_processor.cpp 5 human_processor.cpp
5 main.cpp 6 main.cpp
6 validator.cpp 7 validator.cpp
diff --git a/tools/validator/godot_processor.cpp b/tools/validator/godot_processor.cpp new file mode 100644 index 0000000..f345cff --- /dev/null +++ b/tools/validator/godot_processor.cpp
@@ -0,0 +1,76 @@
1#include "godot_processor.h"
2
3#include <filesystem>
4#include <iostream>
5#include <memory>
6#include <set>
7
8#include "structs.h"
9#include "util/godot_scene.h"
10
11namespace com::fourisland::lingo2_archipelago {
12
13namespace {
14
15static const std::set<std::string> kImportantNodeTypes = {
16 "res://objects/nodes/panel.tscn", "res://objects/nodes/worldport.tscn",
17 "res://objects/nodes/keyHolder.tscn",
18 "res://objects/nodes/collectable.tscn"};
19
20class GodotProcessor {
21 public:
22 GodotProcessor(const std::string& repodir, CollectedInfo& info)
23 : repodir_(repodir), info_(info) {}
24
25 void Run() {
26 for (auto& [map_name, map_info] : info_.maps) {
27 ProcessMap(map_name, map_info);
28 }
29 }
30
31 void ProcessMap(const std::string& map_name, MapInfo& map_info) {
32 std::filesystem::path scene_path = std::filesystem::path(repodir_) /
33 "objects" / "scenes" /
34 (map_name + ".tscn");
35 std::string scene_path_str = scene_path.string();
36 std::cout << "Processing " << scene_path_str << std::endl;
37
38 std::unique_ptr<GodotScene> scene =
39 ReadGodotSceneFromFile(scene_path_str);
40
41 ProcessMapNode(*scene, scene->GetRoot(), map_info);
42 }
43
44 void ProcessMapNode(const GodotScene& scene, const GodotNode& node,
45 MapInfo& map_info) {
46 if (std::holds_alternative<GodotExtResourceRef>(node.GetInstanceType())) {
47 const GodotExtResourceRef& ext_resource_ref =
48 std::get<GodotExtResourceRef>(node.GetInstanceType());
49 const GodotExtResource* ext_resource =
50 scene.GetExtResource(ext_resource_ref.id);
51
52 if (ext_resource != nullptr &&
53 (kImportantNodeTypes.count(ext_resource->path) ||
54 ext_resource->path.starts_with("res://objects/meshes/paintings/"))) {
55 map_info.game_nodes[node.GetPath()].defined = true;
56 }
57 }
58
59 for (const auto& [child_name, child_node] : node.GetChildren()) {
60 ProcessMapNode(scene, *child_node, map_info);
61 }
62 }
63
64 private:
65 std::string repodir_;
66 CollectedInfo& info_;
67};
68
69} // namespace
70
71void ProcessGodotData(const std::string& repodir, CollectedInfo& info) {
72 GodotProcessor godot_processor(repodir, info);
73 godot_processor.Run();
74}
75
76} // namespace com::fourisland::lingo2_archipelago
diff --git a/tools/validator/godot_processor.h b/tools/validator/godot_processor.h new file mode 100644 index 0000000..97bcea6 --- /dev/null +++ b/tools/validator/godot_processor.h
@@ -0,0 +1,14 @@
1#ifndef TOOLS_VALIDATOR_GODOT_PROCESSOR_H_
2#define TOOLS_VALIDATOR_GODOT_PROCESSOR_H_
3
4#include <string>
5
6namespace com::fourisland::lingo2_archipelago {
7
8struct CollectedInfo;
9
10void ProcessGodotData(const std::string& repodir, CollectedInfo& info);
11
12} // namespace com::fourisland::lingo2_archipelago
13
14#endif /* TOOLS_VALIDATOR_GODOT_PROCESSOR_H_ */
diff --git a/tools/validator/human_processor.cpp b/tools/validator/human_processor.cpp index 0846bb8..af40980 100644 --- a/tools/validator/human_processor.cpp +++ b/tools/validator/human_processor.cpp
@@ -55,11 +55,26 @@ class HumanProcessor {
55 void ProcessMap(std::filesystem::path path) { 55 void ProcessMap(std::filesystem::path path) {
56 std::string map_name = path.filename().string(); 56 std::string map_name = path.filename().string();
57 57
58 ProcessMetadataFile(path / "metadata.txtpb", map_name);
58 ProcessConnectionsFile(path / "connections.txtpb", map_name); 59 ProcessConnectionsFile(path / "connections.txtpb", map_name);
59 ProcessDoorsFile(path / "doors.txtpb", map_name); 60 ProcessDoorsFile(path / "doors.txtpb", map_name);
60 ProcessRooms(path / "rooms", map_name); 61 ProcessRooms(path / "rooms", map_name);
61 } 62 }
62 63
64 void ProcessMetadataFile(std::filesystem::path path,
65 const std::string& current_map_name) {
66 if (!std::filesystem::exists(path)) {
67 return;
68 }
69
70 MapInfo& map_info = info_.maps[current_map_name];
71
72 auto metadata = ReadMessageFromFile<HumanMap>(path.string());
73 for (const std::string& path : metadata.excluded_nodes()) {
74 map_info.game_nodes[path].uses++;
75 }
76 }
77
63 void ProcessRooms(std::filesystem::path path, 78 void ProcessRooms(std::filesystem::path path,
64 const std::string& current_map_name) { 79 const std::string& current_map_name) {
65 for (auto const& dir_entry : std::filesystem::directory_iterator(path)) { 80 for (auto const& dir_entry : std::filesystem::directory_iterator(path)) {
diff --git a/tools/validator/main.cpp b/tools/validator/main.cpp index af9842b..1a72e9a 100644 --- a/tools/validator/main.cpp +++ b/tools/validator/main.cpp
@@ -1,3 +1,4 @@
1#include "godot_processor.h"
1#include "human_processor.h" 2#include "human_processor.h"
2#include "structs.h" 3#include "structs.h"
3#include "validator.h" 4#include "validator.h"
@@ -5,10 +6,11 @@
5namespace com::fourisland::lingo2_archipelago { 6namespace com::fourisland::lingo2_archipelago {
6namespace { 7namespace {
7 8
8void Run(const std::string& mapdir) { 9void Run(const std::string& mapdir, const std::string& repodir) {
9 CollectedInfo info; 10 CollectedInfo info;
10 11
11 ProcessHumanData(mapdir, info); 12 ProcessHumanData(mapdir, info);
13 ProcessGodotData(repodir, info);
12 14
13 ValidateCollectedInfo(info); 15 ValidateCollectedInfo(info);
14} 16}
@@ -17,15 +19,16 @@ void Run(const std::string& mapdir) {
17} // namespace com::fourisland::lingo2_archipelago 19} // namespace com::fourisland::lingo2_archipelago
18 20
19int main(int argc, char** argv) { 21int main(int argc, char** argv) {
20 if (argc != 2) { 22 if (argc != 3) {
21 std::cout << "Incorrect argument count." << std::endl; 23 std::cout << "Incorrect argument count." << std::endl;
22 std::cout << "Usage: validator [path to map directory]" << std::endl; 24 std::cout << "Usage: validator [path to map directory] [path to Lingo 2 repository]" << std::endl;
23 return 1; 25 return 1;
24 } 26 }
25 27
26 std::string mapdir = argv[1]; 28 std::string mapdir = argv[1];
29 std::string repodir = argv[2];
27 30
28 com::fourisland::lingo2_archipelago::Run(mapdir); 31 com::fourisland::lingo2_archipelago::Run(mapdir, repodir);
29 32
30 return 0; 33 return 0;
31} 34}
diff --git a/tools/validator/structs.h b/tools/validator/structs.h index 1b61f77..406dc0c 100644 --- a/tools/validator/structs.h +++ b/tools/validator/structs.h
@@ -21,6 +21,7 @@ struct MalformedIdentifiers {
21}; 21};
22 22
23struct GameNodeInfo { 23struct GameNodeInfo {
24 bool defined = false;
24 int uses = 0; 25 int uses = 0;
25}; 26};
26 27
diff --git a/tools/validator/validator.cpp b/tools/validator/validator.cpp index f2ec280..6d01b7c 100644 --- a/tools/validator/validator.cpp +++ b/tools/validator/validator.cpp
@@ -14,6 +14,14 @@ void ValidateMap(const std::string& map_name, const MapInfo& map_info) {
14 if (node_info.uses > 1) { 14 if (node_info.uses > 1) {
15 std::cout << "Map " << map_name << " node " << node_path 15 std::cout << "Map " << map_name << " node " << node_path
16 << " is used in multiple places." << std::endl; 16 << " is used in multiple places." << std::endl;
17 } else if (node_info.uses == 0) {
18 std::cout << "Map " << map_name << " node " << node_path
19 << " is not used." << std::endl;
20 }
21
22 if (!node_info.defined) {
23 std::cout << "Map " << map_name << " node " << node_path
24 << " is not defined in the game file." << std::endl;
17 } 25 }
18 } 26 }
19} 27}