#include "game/debug_config.hpp" #include #include #include #include #include #include "external/fkyaml_node.hpp" #include "utils/log.hpp" namespace DebugConfig { namespace { auto readFile(const std::string& path) -> std::string { std::ifstream file(path); if (!file) { return {}; } std::stringstream buffer; buffer << file.rdbuf(); return buffer.str(); } auto fromName(const std::string& name) -> StartScene { if (name == "LOGO") { return StartScene::LOGO; } if (name == "TITLE") { return StartScene::TITLE; } if (name == "INTRO") { return StartScene::INTRO; } if (name == "GAME") { return StartScene::GAME; } return StartScene::GAME; } auto isKnown(const std::string& name) -> bool { return name == "LOGO" || name == "TITLE" || name == "INTRO" || name == "GAME"; } auto playersFromName(const std::string& name) -> StartingPlayers { if (name == "P1") { return StartingPlayers::P1; } if (name == "P2") { return StartingPlayers::P2; } if (name == "BOTH") { return StartingPlayers::BOTH; } return StartingPlayers::BOTH; } auto isKnownPlayers(const std::string& name) -> bool { return name == "P1" || name == "P2" || name == "BOTH"; } } // namespace auto parseStartScene(const std::string& yaml_content) -> StartScene { if (yaml_content.empty()) { return StartScene::GAME; } try { auto yaml = fkyaml::node::deserialize(yaml_content); if (!yaml.contains("start_scene")) { return StartScene::GAME; } const auto RAW = yaml["start_scene"].get_value(); if (!isKnown(RAW)) { Log::warn("debug.yaml", "start_scene \"{}\" invàlid, arrancant a GAME", RAW); return StartScene::GAME; } return fromName(RAW); } catch (const std::exception& e) { Log::error("debug.yaml", "error parsejant: {} — arrancant a GAME", e.what()); return StartScene::GAME; } } auto resolveStartScene(const std::string& file_path) -> StartScene { std::error_code error; if (!std::filesystem::exists(file_path, error)) { // Silenciós: la no-existència és el cas per defecte en una màquina // neta, no un error. L'usuari crea el fitxer quan el necessita. return StartScene::GAME; } const auto CONTENT = readFile(file_path); if (CONTENT.empty()) { Log::warn("debug.yaml", "fitxer buit a {}, arrancant a GAME", file_path); return StartScene::GAME; } return parseStartScene(CONTENT); } auto parseStartingPlayers(const std::string& yaml_content) -> StartingPlayers { if (yaml_content.empty()) { return StartingPlayers::BOTH; } try { auto yaml = fkyaml::node::deserialize(yaml_content); if (!yaml.contains("starting_players")) { return StartingPlayers::BOTH; } const auto RAW = yaml["starting_players"].get_value(); if (!isKnownPlayers(RAW)) { Log::warn("debug.yaml", "starting_players \"{}\" invàlid, arrancant amb BOTH", RAW); return StartingPlayers::BOTH; } return playersFromName(RAW); } catch (const std::exception& e) { Log::error("debug.yaml", "error parsejant starting_players: {} — arrancant amb BOTH", e.what()); return StartingPlayers::BOTH; } } auto resolveStartingPlayers(const std::string& file_path) -> StartingPlayers { std::error_code error; if (!std::filesystem::exists(file_path, error)) { return StartingPlayers::BOTH; } const auto CONTENT = readFile(file_path); if (CONTENT.empty()) { return StartingPlayers::BOTH; } return parseStartingPlayers(CONTENT); } auto parseStartingLevel(const std::string& yaml_content) -> std::optional { if (yaml_content.empty()) { return std::nullopt; } try { auto yaml = fkyaml::node::deserialize(yaml_content); if (!yaml.contains("starting_level")) { return std::nullopt; } const auto& sl = yaml["starting_level"]; if (!sl.contains("pyramid") || !sl.contains("room")) { Log::warn("debug.yaml", "starting_level necessita els camps `pyramid` i `room` — ignorat"); return std::nullopt; } return StartingLevel{ .pyramid = sl["pyramid"].get_value(), .room = sl["room"].get_value(), }; } catch (const std::exception& e) { Log::error("debug.yaml", "error parsejant starting_level: {} — ignorat", e.what()); return std::nullopt; } } auto resolveStartingLevel(const std::string& file_path) -> std::optional { std::error_code error; if (!std::filesystem::exists(file_path, error)) { return std::nullopt; } const auto CONTENT = readFile(file_path); if (CONTENT.empty()) { return std::nullopt; } return parseStartingLevel(CONTENT); } auto toString(StartScene scene) -> const char* { switch (scene) { case StartScene::LOGO: return "LOGO"; case StartScene::TITLE: return "TITLE"; case StartScene::INTRO: return "INTRO"; case StartScene::GAME: return "GAME"; } return "GAME"; } auto toString(StartingPlayers players) -> const char* { switch (players) { case StartingPlayers::P1: return "P1"; case StartingPlayers::P2: return "P2"; case StartingPlayers::BOTH: return "BOTH"; } return "BOTH"; } void createDefaultIfMissing(const std::string& file_path) { std::error_code error; if (std::filesystem::exists(file_path, error)) { return; } std::ofstream file(file_path); if (!file) { Log::error("debug.yaml", "no s'ha pogut crear {}", file_path); return; } file << "# debug.yaml — ajust personal de dev (no versionat).\n"; file << "# start_scene: LOGO | TITLE | INTRO | GAME\n"; file << "# starting_players: P1 | P2 | BOTH\n"; file << "# starting_level (opcional): { pyramid: N, room: M } — salta a la sala\n"; file << "# corresponent del levels.yaml. Sense la\n"; file << "# clau, comença a la primera (P1-R1).\n"; file << "start_scene: GAME\n"; file << "starting_players: BOTH\n"; Log::info("debug.yaml", "creat a {} amb start_scene=GAME starting_players=BOTH", file_path); } } // namespace DebugConfig