From c0c5431800d0306d01814e9902566c9b4fc9220b Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Thu, 7 Aug 2025 17:18:47 -0400 Subject: Assign AP IDs to doors and panels --- tools/assign_ids/CMakeLists.txt | 9 +++ tools/assign_ids/main.cpp | 172 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 tools/assign_ids/CMakeLists.txt create mode 100644 tools/assign_ids/main.cpp (limited to 'tools/assign_ids') 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 @@ +find_package(Protobuf REQUIRED) + +add_executable(assign_ids + main.cpp +) +set_property(TARGET assign_ids PROPERTY CXX_STANDARD 20) +set_property(TARGET assign_ids PROPERTY CXX_STANDARD_REQUIRED ON) +target_include_directories(assign_ids PUBLIC ${CMAKE_BINARY_DIR}) +target_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 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "proto/human.pb.h" + +namespace com::fourisland::lingo2_archipelago { +namespace { + +template +T ReadMessageFromFile(const std::string& path) { + std::cout << "Processing " << path << std::endl; + + std::ifstream file(path); + std::stringstream buffer; + buffer << file.rdbuf(); + + T message; + google::protobuf::TextFormat::ParseFromString(buffer.str(), &message); + + return message; +} + +class AssignIds { + public: + AssignIds(const std::string& mapdir) : mapdir_(mapdir) {} + + void Run() { + std::filesystem::path datadir_path = mapdir_; + std::filesystem::path ids_path = datadir_path / "ids.txtpb"; + + ReadIds(ids_path); + + ProcessMaps(datadir_path); + + WriteIds(ids_path); + } + + void ReadIds(std::filesystem::path path) { + id_mappings_ = ReadMessageFromFile(path.string()); + + for (const auto& [_, map] : id_mappings_.maps()) { + for (const auto& [_, id] : map.doors()) { + if (id > next_id_) { + next_id_ = id; + } + } + + for (const auto& [_, room] : map.rooms()) { + for (const auto& [_, id] : room.panels()) { + if (id > next_id_) { + next_id_ = id; + } + } + } + } + + next_id_++; + } + + void WriteIds(std::filesystem::path path) { + std::string output; + google::protobuf::TextFormat::PrintToString(id_mappings_, &output); + + { + std::ofstream outputfile(path.string()); + outputfile << output; + } + } + + void ProcessMaps(std::filesystem::path path) { + std::filesystem::path maps_dir = path / "maps"; + for (auto const& dir_entry : + std::filesystem::directory_iterator(maps_dir)) { + ProcessMap(dir_entry.path()); + } + } + + void ProcessMap(std::filesystem::path path) { + std::string map_name = path.filename(); + + ProcessDoorsFile(path / "doors.txtpb", map_name); + ProcessRooms(path / "rooms", map_name); + } + + void ProcessDoorsFile(std::filesystem::path path, + const std::string& current_map_name) { + if (!std::filesystem::exists(path)) { + return; + } + + auto doors = ReadMessageFromFile(path.string()); + + for (const HumanDoor& door : doors.doors()) { + ProcessDoor(door, current_map_name); + } + } + + void ProcessDoor(const HumanDoor& h_door, + const std::string& current_map_name) { + if (!id_mappings_.maps().contains(current_map_name) || + !id_mappings_.maps() + .at(current_map_name) + .doors() + .contains(h_door.name())) { + auto& maps = *id_mappings_.mutable_maps(); + auto& doors = *maps[current_map_name].mutable_doors(); + doors[h_door.name()] = next_id_++; + } + } + + void ProcessRooms(std::filesystem::path path, + const std::string& current_map_name) { + for (auto const& dir_entry : std::filesystem::directory_iterator(path)) { + auto room = ReadMessageFromFile(dir_entry.path().string()); + ProcessRoom(room, current_map_name); + } + } + + void ProcessRoom(const HumanRoom& h_room, + const std::string& current_map_name) { + for (const HumanPanel& h_panel : h_room.panels()) { + if (!id_mappings_.maps().contains(current_map_name) || + !id_mappings_.maps() + .at(current_map_name) + .rooms() + .contains(h_room.name()) || + !id_mappings_.maps() + .at(current_map_name) + .rooms() + .at(h_room.name()) + .panels() + .contains(h_panel.name())) { + auto& maps = *id_mappings_.mutable_maps(); + auto& rooms = *maps[current_map_name].mutable_rooms(); + auto& panels = *rooms[h_room.name()].mutable_panels(); + panels[h_panel.name()] = next_id_++; + } + } + } + + private: + std::string mapdir_; + + uint64_t next_id_ = 0; + + IdMappings id_mappings_; +}; + +} // namespace +} // namespace com::fourisland::lingo2_archipelago + +int main(int argc, char** argv) { + if (argc != 2) { + std::cout << "Incorrect argument count." << std::endl; + std::cout << "Usage: assign_ids [path to map directory]" << std::endl; + return 1; + } + + std::string mapdir = argv[1]; + + com::fourisland::lingo2_archipelago::AssignIds assign_ids(mapdir); + assign_ids.Run(); + + return 0; +} \ No newline at end of file -- cgit 1.4.1