#include #include #include #include #include #include #include #include #include #include #include #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::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 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); ProcessMaps(datadir_path); ProcessIdsFile(datadir_path / "ids.txtpb"); { 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 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(); ProcessConnectionsFile(path / "connections.txtpb", map_name); ProcessDoorsFile(path / "doors.txtpb", map_name); ProcessRooms(path / "rooms", map_name); } 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) { uint64_t room_id = container_.FindOrAddRoom(current_map_name, h_room.name(), std::nullopt); Room& room = *container_.all_objects().mutable_rooms(room_id); room.set_display_name(h_room.display_name()); for (const HumanPanel& h_panel : h_room.panels()) { room.add_panels(ProcessPanel(h_panel, current_map_name, room.name())); } for (const HumanPainting& h_painting : h_room.paintings()) { room.add_paintings( ProcessPainting(h_painting, current_map_name, room.name())); } for (const HumanPort& h_port : h_room.ports()) { room.add_ports(ProcessPort(h_port, current_map_name, room.name())); } std::copy( h_room.letters().begin(), h_room.letters().end(), google::protobuf::RepeatedFieldBackInserter(room.mutable_letters())); } uint64_t ProcessPanel(const HumanPanel& h_panel, const std::string& current_map_name, const std::string& current_room_name) { uint64_t panel_id = container_.FindOrAddPanel(current_map_name, current_room_name, h_panel.name(), std::nullopt, std::nullopt); Panel& panel = *container_.all_objects().mutable_panels(panel_id); panel.set_path(h_panel.path()); panel.set_clue(h_panel.clue()); panel.set_answer(h_panel.answer()); std::copy( h_panel.symbols().begin(), h_panel.symbols().end(), google::protobuf::RepeatedFieldBackInserter(panel.mutable_symbols())); std::copy( h_panel.proxies().begin(), h_panel.proxies().end(), google::protobuf::RepeatedFieldBackInserter(panel.mutable_proxies())); if (h_panel.has_required_door()) { std::optional map_name = h_panel.required_door().has_map() ? std::optional(h_panel.required_door().map()) : std::nullopt; panel.set_required_door(container_.FindOrAddDoor( map_name, h_panel.required_door().name(), current_map_name)); } return panel_id; } uint64_t ProcessPainting(const HumanPainting& h_painting, const std::string& current_map_name, const std::string& current_room_name) { uint64_t painting_id = container_.FindOrAddPainting( current_map_name, current_room_name, h_painting.name(), std::nullopt, std::nullopt); Painting& painting = *container_.all_objects().mutable_paintings(painting_id); painting.set_path(h_painting.path()); painting.set_display_name(h_painting.display_name()); painting.set_orientation(h_painting.orientation()); if (h_painting.has_flipped()) { painting.set_flipped(h_painting.flipped());
name: "Last Room"
panels {
  name: "BLEAT"
  path: "Panels/Ending/panel"
  clue: "bleat"
  answer: "goat"
  symbols: SOUND
}
panels {
  name: "JARGON"
  path: "Panels/Ending/panel2"
  clue: "jargon"
  answer: "lingo"
  symbols: SUN
}
panels {
  name: "JARGON BLEAT"
  path: "Panels/Ending/panel3"
  clue: ""
  answer: "gloat"
  symbols: EVAL
  symbols: LINGO
}
panels {
  name: "BRAG"
  path: "Panels/Ending/panel4"
  clue: "brag"
  answer: "gloat"
  symbols: SUN
}
= 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()); } } } void ProcessIdsFile(std::filesystem::path path) { auto ids = ReadMessageFromFile(path.string()); for (const auto& [map_name, map] : ids.maps()) { for (const auto& [door_name, ap_id] : map.doors()) { uint64_t door_id = container_.FindOrAddDoor(map_name, door_name, std::nullopt); container_.all_objects().mutable_doors(door_id)->set_ap_id(ap_id); } for (const auto& [room_name, room] : map.rooms()) { for (const auto& [panel_name, ap_id] : room.panels()) { uint64_t panel_id = container_.FindOrAddPanel( map_name, room_name, panel_name, std::nullopt, std::nullopt); container_.all_objects().mutable_panels(panel_id)->set_ap_id(ap_id); } } } auto& specials = *container_.all_objects().mutable_special_ids(); for (const auto& [tag, id] : ids.special()) { specials[tag] = id; } } 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; return 1; } std::string mapdir = argv[1]; std::string outputpath = argv[2]; com::fourisland::lingo2_archipelago::DataPacker data_packer(mapdir, outputpath); data_packer.Run(); return 0; }