summary refs log tree commit diff stats
path: root/tools/assign_ids
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2025-08-07 17:18:47 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2025-08-07 17:18:47 -0400
commitc0c5431800d0306d01814e9902566c9b4fc9220b (patch)
tree50d206c31bb7f535c3f2ca0b8d0f735c5a61f9a5 /tools/assign_ids
parentc9da387ede51f207825b63d9f13036a7b661d4b3 (diff)
downloadlingo2-archipelago-proto.tar.gz
lingo2-archipelago-proto.tar.bz2
lingo2-archipelago-proto.zip
Assign AP IDs to doors and panels proto
Diffstat (limited to 'tools/assign_ids')
-rw-r--r--tools/assign_ids/CMakeLists.txt9
-rw-r--r--tools/assign_ids/main.cpp172
2 files changed, 181 insertions, 0 deletions
diff --git a/tools/assign_ids/CMakeLists.txt b/tools/assign_ids/CMakeLists.txt new file mode 100644 index 0000000..0a9f62d --- /dev/null +++ b/tools/assign_ids/CMakeLists.txt
@@ -0,0 +1,9 @@
1find_package(Protobuf REQUIRED)
2
3add_executable(assign_ids
4 main.cpp
5)
6set_property(TARGET assign_ids PROPERTY CXX_STANDARD 20)
7set_property(TARGET assign_ids PROPERTY CXX_STANDARD_REQUIRED ON)
8target_include_directories(assign_ids PUBLIC ${CMAKE_BINARY_DIR})
9target_link_libraries(assign_ids PUBLIC protos protobuf::libprotobuf)
diff --git a/tools/assign_ids/main.cpp b/tools/assign_ids/main.cpp new file mode 100644 index 0000000..1824c6f --- /dev/null +++ b/tools/assign_ids/main.cpp
@@ -0,0 +1,172 @@
1#include <google/protobuf/message.h>
2#include <google/protobuf/text_format.h>
3
4#include <cstdint>
5#include <fstream>
6#include <iostream>
7#include <map>
8#include <sstream>
9#include <string>
10
11#include "proto/human.pb.h"
12
13namespace com::fourisland::lingo2_archipelago {
14namespace {
15
16template <typename T>
17T ReadMessageFromFile(const std::string& path) {
18 std::cout << "Processing " << path << std::endl;
19
20 std::ifstream file(path);
21 std::stringstream buffer;
22 buffer << file.rdbuf();
23
24 T message;
25 google::protobuf::TextFormat::ParseFromString(buffer.str(), &message);
26
27 return message;
28}
29
30class AssignIds {
31 public:
32 AssignIds(const std::string& mapdir) : mapdir_(mapdir) {}
33
34 void Run() {
35 std::filesystem::path datadir_path = mapdir_;
36 std::filesystem::path ids_path = datadir_path / "ids.txtpb";
37
38 ReadIds(ids_path);
39
40 ProcessMaps(datadir_path);
41
42 WriteIds(ids_path);
43 }
44
45 void ReadIds(std::filesystem::path path) {
46 id_mappings_ = ReadMessageFromFile<IdMappings>(path.string());
47
48 for (const auto& [_, map] : id_mappings_.maps()) {
49 for (const auto& [_, id] : map.doors()) {
50 if (id > next_id_) {
51 next_id_ = id;
52 }
53 }
54
55 for (const auto& [_, room] : map.rooms()) {
56 for (const auto& [_, id] : room.panels()) {
57 if (id > next_id_) {
58 next_id_ = id;
59 }
60 }
61 }
62 }
63
64 next_id_++;
65 }
66
67 void WriteIds(std::filesystem::path path) {
68 std::string output;
69 google::protobuf::TextFormat::PrintToString(id_mappings_, &output);
70
71 {
72 std::ofstream outputfile(path.string());
73 outputfile << output;
74 }
75 }
76
77 void ProcessMaps(std::filesystem::path path) {
78 std::filesystem::path maps_dir = path / "maps";
79 for (auto const& dir_entry :
80 std::filesystem::directory_iterator(maps_dir)) {
81 ProcessMap(dir_entry.path());
82 }
83 }
84
85 void ProcessMap(std::filesystem::path path) {
86 std::string map_name = path.filename();
87
88 ProcessDoorsFile(path / "doors.txtpb", map_name);
89 ProcessRooms(path / "rooms", map_name);
90 }
91
92 void ProcessDoorsFile(std::filesystem::path path,
93 const std::string& current_map_name) {
94 if (!std::filesystem::exists(path)) {
95 return;
96 }
97
98 auto doors = ReadMessageFromFile<HumanDoors>(path.string());
99
100 for (const HumanDoor& door : doors.doors()) {
101 ProcessDoor(door, current_map_name);
102 }
103 }
104
105 void ProcessDoor(const HumanDoor& h_door,
106 const std::string& current_map_name) {
107 if (!id_mappings_.maps().contains(current_map_name) ||
108 !id_mappings_.maps()
109 .at(current_map_name)
110 .doors()
111 .contains(h_door.name())) {
112 auto& maps = *id_mappings_.mutable_maps();
113 auto& doors = *maps[current_map_name].mutable_doors();
114 doors[h_door.name()] = next_id_++;
115 }
116 }
117
118 void ProcessRooms(std::filesystem::path path,
119 const std::string& current_map_name) {
120 for (auto const& dir_entry : std::filesystem::directory_iterator(path)) {
121 auto room = ReadMessageFromFile<HumanRoom>(dir_entry.path().string());
122 ProcessRoom(room, current_map_name);
123 }
124 }
125
126 void ProcessRoom(const HumanRoom& h_room,
127 const std::string& current_map_name) {
128 for (const HumanPanel& h_panel : h_room.panels()) {
129 if (!id_mappings_.maps().contains(current_map_name) ||
130 !id_mappings_.maps()
131 .at(current_map_name)
132 .rooms()
133 .contains(h_room.name()) ||
134 !id_mappings_.maps()
135 .at(current_map_name)
136 .rooms()
137 .at(h_room.name())
138 .panels()
139 .contains(h_panel.name())) {
140 auto& maps = *id_mappings_.mutable_maps();
141 auto& rooms = *maps[current_map_name].mutable_rooms();
142 auto& panels = *rooms[h_room.name()].mutable_panels();
143 panels[h_panel.name()] = next_id_++;
144 }
145 }
146 }
147
148 private:
149 std::string mapdir_;
150
151 uint64_t next_id_ = 0;
152
153 IdMappings id_mappings_;
154};
155
156} // namespace
157} // namespace com::fourisland::lingo2_archipelago
158
159int main(int argc, char** argv) {
160 if (argc != 2) {
161 std::cout << "Incorrect argument count." << std::endl;
162 std::cout << "Usage: assign_ids [path to map directory]" << std::endl;
163 return 1;
164 }
165
166 std::string mapdir = argv[1];
167
168 com::fourisland::lingo2_archipelago::AssignIds assign_ids(mapdir);
169 assign_ids.Run();
170
171 return 0;
172} \ No newline at end of file