From e9d9da34e86a1e5f0de155bf9086d3e5ff6b2da0 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Thu, 7 Aug 2025 13:34:42 -0400 Subject: Protobuf works! Parsing connections --- tools/datapacker/main.cpp | 196 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 3 deletions(-) (limited to 'tools/datapacker/main.cpp') 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 @@ +#include +#include + +#include +#include +#include #include +#include +#include +#include #include -void Run(const std::string& mapdir, const std::string& outputpath) { +#include "container.h" +#include "proto/data.pb.h" +#include "proto/human.pb.h" + +namespace com::fourisland::lingo2_archipelago { +namespace { + +template +T ReadMessageFromFile(const std::string& path) { + std::ifstream file(path); + std::stringstream buffer; + buffer << file.rdbuf(); + T message; + google::protobuf::TextFormat::ParseFromString(buffer.str(), &message); + + return message; } +class DataPacker { + public: + DataPacker(const std::string& mapdir, const std::string& outputpath) + : mapdir_(mapdir), outputpath_(outputpath) {} + + void Run() { + std::filesystem::path datadir_path = mapdir_; + + ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt); + + { + std::ofstream outputfile(outputpath_); + container_.all_objects().SerializeToOstream(&outputfile); + } + + std::string output; + google::protobuf::TextFormat::PrintToString(container_.all_objects(), + &output); + std::cout << output << std::endl; + } + + private: + void ProcessConnectionsFile(std::filesystem::path path, + std::optional current_map_name) { + if (!std::filesystem::exists(path)) { + return; + } + + auto connections = ReadMessageFromFile(path.string()); + + for (const HumanConnection& connection : connections.connections()) { + ProcessConnection(connection, current_map_name); + } + } + + void ProcessConnection(const HumanConnection& human_connection, + const std::optional& current_map_name) { + Connection f_connection; + + if (human_connection.has_from_room()) { + f_connection.set_from_room(container_.FindOrAddRoom( + std::nullopt, human_connection.from_room(), current_map_name)); + } else if (human_connection.has_from()) { + ProcessSingleConnection(human_connection.from(), current_map_name, + f_connection); + } + + Connection r_connection; + r_connection.set_to_room(f_connection.from_room()); + + if (human_connection.has_to_room()) { + r_connection.set_to_room(container_.FindOrAddRoom( + std::nullopt, human_connection.to_room(), current_map_name)); + } else if (human_connection.has_to()) { + ProcessSingleConnection(human_connection.to(), current_map_name, + r_connection); + } + + f_connection.set_to_room(r_connection.from_room()); + + if (human_connection.has_door()) { + std::optional map_name = + human_connection.door().has_map() + ? std::optional(human_connection.door().map()) + : std::nullopt; + uint64_t door_id = container_.FindOrAddDoor( + map_name, human_connection.door().name(), current_map_name); + f_connection.set_required_door(door_id); + r_connection.set_required_door(door_id); + } + + container_.AddConnection(f_connection); + if (!human_connection.oneway()) { + container_.AddConnection(r_connection); + } + } + + void ProcessSingleConnection( + const HumanConnection::Endpoint& endpoint, + const std::optional& current_map_name, + Connection& connection) { + if (endpoint.has_room()) { + std::optional map_name = + endpoint.room().has_map() + ? std::optional(endpoint.room().map()) + : std::nullopt; + connection.set_from_room(container_.FindOrAddRoom( + map_name, endpoint.room().name(), current_map_name)); + } else if (endpoint.has_painting()) { + std::optional map_name = + endpoint.painting().has_map() + ? std::optional(endpoint.painting().map()) + : std::nullopt; + + std::string room_name; + if (!endpoint.painting().has_room()) { + std::cout << "Missing room name for painting " + << endpoint.painting().name() << std::endl; + room_name = "default"; + } else { + room_name = endpoint.painting().room(); + } + + connection.set_from_room( + container_.FindOrAddRoom(map_name, room_name, current_map_name)); + connection.set_painting(container_.FindOrAddPainting( + map_name, room_name, endpoint.painting().name(), current_map_name, + std::nullopt)); + } else if (endpoint.has_port()) { + std::optional map_name = + endpoint.port().has_map() + ? std::optional(endpoint.port().map()) + : std::nullopt; + + std::string room_name; + if (!endpoint.port().has_room()) { + std::cout << "Missing room name for port " << endpoint.port().name() + << std::endl; + room_name = "default"; + } else { + room_name = endpoint.port().room(); + } + + connection.set_from_room( + container_.FindOrAddRoom(map_name, room_name, current_map_name)); + connection.set_port( + container_.FindOrAddPort(map_name, room_name, endpoint.port().name(), + current_map_name, std::nullopt)); + } else if (endpoint.has_panel()) { + std::optional map_name = + endpoint.panel().has_map() + ? std::optional(endpoint.panel().map()) + : std::nullopt; + + std::string room_name; + if (!endpoint.panel().has_room()) { + std::cout << "Missing room name for panel " << endpoint.panel().name() + << std::endl; + room_name = "default"; + } else { + room_name = endpoint.panel().room(); + } + + connection.set_from_room( + container_.FindOrAddRoom(map_name, room_name, current_map_name)); + connection.mutable_panel()->set_panel(container_.FindOrAddPanel( + map_name, room_name, endpoint.panel().name(), current_map_name, + std::nullopt)); + if (endpoint.panel().has_answer()) { + connection.mutable_panel()->set_answer(endpoint.panel().answer()); + } + } + } + + std::string mapdir_; + std::string outputpath_; + + Container container_; +}; + +} // namespace +} // namespace com::fourisland::lingo2_archipelago + int main(int argc, char** argv) { if (argc != 3) { std::cout << "Incorrect argument count." << std::endl; - std::cout << "Usage: datapacker [path to map directory] [output file]" << std::endl; + std::cout << "Usage: datapacker [path to map directory] [output file]" + << std::endl; return 1; } std::string mapdir = argv[1]; std::string outputpath = argv[2]; - Run(mapdir, outputpath); + com::fourisland::lingo2_archipelago::DataPacker data_packer(mapdir, + outputpath); + data_packer.Run(); return 0; } -- cgit 1.4.1