diff options
Diffstat (limited to 'tools/datapacker/main.cpp')
-rw-r--r-- | tools/datapacker/main.cpp | 196 |
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 | ||
4 | void 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 | |||
17 | namespace com::fourisland::lingo2_archipelago { | ||
18 | namespace { | ||
19 | |||
20 | template <typename T> | ||
21 | T 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 | ||
32 | class 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 | |||
8 | int main(int argc, char** argv) { | 195 | int 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 | } |