summary refs log tree commit diff stats
path: root/tools/datapacker/main.cpp
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2025-08-07 13:34:42 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2025-08-07 13:34:42 -0400
commite9d9da34e86a1e5f0de155bf9086d3e5ff6b2da0 (patch)
tree432e1177f11e7e2b5e0d6400fad977def7d31129 /tools/datapacker/main.cpp
parent1eacf01378d4dff3aed73fffcc42e0352b93835e (diff)
downloadlingo2-archipelago-e9d9da34e86a1e5f0de155bf9086d3e5ff6b2da0.tar.gz
lingo2-archipelago-e9d9da34e86a1e5f0de155bf9086d3e5ff6b2da0.tar.bz2
lingo2-archipelago-e9d9da34e86a1e5f0de155bf9086d3e5ff6b2da0.zip
Protobuf works! Parsing connections
Diffstat (limited to 'tools/datapacker/main.cpp')
-rw-r--r--tools/datapacker/main.cpp196
1 files changed, 193 insertions, 3 deletions
diff --git a/tools/datapacker/main.cpp b/tools/datapacker/main.cpp index fd0ace6..b2ec068 100644 --- a/tools/datapacker/main.cpp +++ b/tools/datapacker/main.cpp
@@ -1,21 +1,211 @@
1#include <google/protobuf/message.h>
2#include <google/protobuf/text_format.h>
3
4#include <cstdint>
5#include <filesystem>
6#include <fstream>
1#include <iostream> 7#include <iostream>
8#include <map>
9#include <optional>
10#include <sstream>
2#include <string> 11#include <string>
3 12
4void Run(const std::string& mapdir, const std::string& outputpath) { 13#include "container.h"
14#include "proto/data.pb.h"
15#include "proto/human.pb.h"
16
17namespace com::fourisland::lingo2_archipelago {
18namespace {
19
20template <typename T>
21T ReadMessageFromFile(const std::string& path) {
22 std::ifstream file(path);
23 std::stringstream buffer;
24 buffer << file.rdbuf();
5 25
26 T message;
27 google::protobuf::TextFormat::ParseFromString(buffer.str(), &message);
28
29 return message;
6} 30}
7 31
32class DataPacker {
33 public:
34 DataPacker(const std::string& mapdir, const std::string& outputpath)
35 : mapdir_(mapdir), outputpath_(outputpath) {}
36
37 void Run() {
38 std::filesystem::path datadir_path = mapdir_;
39
40 ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt);
41
42 {
43 std::ofstream outputfile(outputpath_);
44 container_.all_objects().SerializeToOstream(&outputfile);
45 }
46
47 std::string output;
48 google::protobuf::TextFormat::PrintToString(container_.all_objects(),
49 &output);
50 std::cout << output << std::endl;
51 }
52
53 private:
54 void ProcessConnectionsFile(std::filesystem::path path,
55 std::optional<std::string> current_map_name) {
56 if (!std::filesystem::exists(path)) {
57 return;
58 }
59
60 auto connections = ReadMessageFromFile<HumanConnections>(path.string());
61
62 for (const HumanConnection& connection : connections.connections()) {
63 ProcessConnection(connection, current_map_name);
64 }
65 }
66
67 void ProcessConnection(const HumanConnection& human_connection,
68 const std::optional<std::string>& current_map_name) {
69 Connection f_connection;
70
71 if (human_connection.has_from_room()) {
72 f_connection.set_from_room(container_.FindOrAddRoom(
73 std::nullopt, human_connection.from_room(), current_map_name));
74 } else if (human_connection.has_from()) {
75 ProcessSingleConnection(human_connection.from(), current_map_name,
76 f_connection);
77 }
78
79 Connection r_connection;
80 r_connection.set_to_room(f_connection.from_room());
81
82 if (human_connection.has_to_room()) {
83 r_connection.set_to_room(container_.FindOrAddRoom(
84 std::nullopt, human_connection.to_room(), current_map_name));
85 } else if (human_connection.has_to()) {
86 ProcessSingleConnection(human_connection.to(), current_map_name,
87 r_connection);
88 }
89
90 f_connection.set_to_room(r_connection.from_room());
91
92 if (human_connection.has_door()) {
93 std::optional<std::string> map_name =
94 human_connection.door().has_map()
95 ? std::optional<std::string>(human_connection.door().map())
96 : std::nullopt;
97 uint64_t door_id = container_.FindOrAddDoor(
98 map_name, human_connection.door().name(), current_map_name);
99 f_connection.set_required_door(door_id);
100 r_connection.set_required_door(door_id);
101 }
102
103 container_.AddConnection(f_connection);
104 if (!human_connection.oneway()) {
105 container_.AddConnection(r_connection);
106 }
107 }
108
109 void ProcessSingleConnection(
110 const HumanConnection::Endpoint& endpoint,
111 const std::optional<std::string>& current_map_name,
112 Connection& connection) {
113 if (endpoint.has_room()) {
114 std::optional<std::string> map_name =
115 endpoint.room().has_map()
116 ? std::optional<std::string>(endpoint.room().map())
117 : std::nullopt;
118 connection.set_from_room(container_.FindOrAddRoom(
119 map_name, endpoint.room().name(), current_map_name));
120 } else if (endpoint.has_painting()) {
121 std::optional<std::string> map_name =
122 endpoint.painting().has_map()
123 ? std::optional<std::string>(endpoint.painting().map())
124 : std::nullopt;
125
126 std::string room_name;
127 if (!endpoint.painting().has_room()) {
128 std::cout << "Missing room name for painting "
129 << endpoint.painting().name() << std::endl;
130 room_name = "default";
131 } else {
132 room_name = endpoint.painting().room();
133 }
134
135 connection.set_from_room(
136 container_.FindOrAddRoom(map_name, room_name, current_map_name));
137 connection.set_painting(container_.FindOrAddPainting(
138 map_name, room_name, endpoint.painting().name(), current_map_name,
139 std::nullopt));
140 } else if (endpoint.has_port()) {
141 std::optional<std::string> map_name =
142 endpoint.port().has_map()
143 ? std::optional<std::string>(endpoint.port().map())
144 : std::nullopt;
145
146 std::string room_name;
147 if (!endpoint.port().has_room()) {
148 std::cout << "Missing room name for port " << endpoint.port().name()
149 << std::endl;
150 room_name = "default";
151 } else {
152 room_name = endpoint.port().room();
153 }
154
155 connection.set_from_room(
156 container_.FindOrAddRoom(map_name, room_name, current_map_name));
157 connection.set_port(
158 container_.FindOrAddPort(map_name, room_name, endpoint.port().name(),
159 current_map_name, std::nullopt));
160 } else if (endpoint.has_panel()) {
161 std::optional<std::string> map_name =
162 endpoint.panel().has_map()
163 ? std::optional<std::string>(endpoint.panel().map())
164 : std::nullopt;
165
166 std::string room_name;
167 if (!endpoint.panel().has_room()) {
168 std::cout << "Missing room name for panel " << endpoint.panel().name()
169 << std::endl;
170 room_name = "default";
171 } else {
172 room_name = endpoint.panel().room();
173 }
174
175 connection.set_from_room(
176 container_.FindOrAddRoom(map_name, room_name, current_map_name));
177 connection.mutable_panel()->set_panel(container_.FindOrAddPanel(
178 map_name, room_name, endpoint.panel().name(), current_map_name,
179 std::nullopt));
180 if (endpoint.panel().has_answer()) {
181 connection.mutable_panel()->set_answer(endpoint.panel().answer());
182 }
183 }
184 }
185
186 std::string mapdir_;
187 std::string outputpath_;
188
189 Container container_;
190};
191
192} // namespace
193} // namespace com::fourisland::lingo2_archipelago
194
8int main(int argc, char** argv) { 195int main(int argc, char** argv) {
9 if (argc != 3) { 196 if (argc != 3) {
10 std::cout << "Incorrect argument count." << std::endl; 197 std::cout << "Incorrect argument count." << std::endl;
11 std::cout << "Usage: datapacker [path to map directory] [output file]" << std::endl; 198 std::cout << "Usage: datapacker [path to map directory] [output file]"
199 << std::endl;
12 return 1; 200 return 1;
13 } 201 }
14 202
15 std::string mapdir = argv[1]; 203 std::string mapdir = argv[1];
16 std::string outputpath = argv[2]; 204 std::string outputpath = argv[2];
17 205
18 Run(mapdir, outputpath); 206 com::fourisland::lingo2_archipelago::DataPacker data_packer(mapdir,
207 outputpath);
208 data_packer.Run();
19 209
20 return 0; 210 return 0;
21} 211}