using System; using System.IO; namespace RobotNet10.RobotApp.Xloc; public static class XlocPaths { private static string GetHomeDir() { // systemd/Docker services thường chạy với HOME=/root hoặc thiếu HOME var home = Environment.GetEnvironmentVariable("HOME"); if (!string.IsNullOrWhiteSpace(home)) return home; return Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); } public static string GetXdgDataHome() { // XDG_DATA_HOME mặc định là $HOME/.local/share var xdg = Environment.GetEnvironmentVariable("XDG_DATA_HOME"); if (!string.IsNullOrWhiteSpace(xdg)) return xdg; return Path.Combine(GetHomeDir(), ".local", "share"); } public static string GetMapsDirectory() { return Path.Combine(GetXdgDataHome(), "xloc", "resources", "maps"); } /// /// Resolve a map folder name (e.g. "map_20260307_103646") into a pbstream file path. /// If is already an absolute existing file, returns it as-is. /// public static string? ResolvePbstreamPath(string mapFilePathOrName) { if (string.IsNullOrWhiteSpace(mapFilePathOrName)) return null; // If caller already provided an absolute pbstream path, just validate it. if (Path.IsPathRooted(mapFilePathOrName) && File.Exists(mapFilePathOrName)) return mapFilePathOrName; // Otherwise treat it as a map folder name under the configured maps directory. var mapsDir = GetMapsDirectory(); var mapName = Path.GetFileName(mapFilePathOrName.TrimEnd(Path.DirectorySeparatorChar, '/')); if (string.IsNullOrWhiteSpace(mapName)) return null; var mapFolder = Path.Combine(mapsDir, mapName); if (!Directory.Exists(mapFolder)) return null; // Prefer canonical name: map.pbstream, then fall back to any *.pbstream. var canonical = Path.Combine(mapFolder, "map.pbstream"); if (File.Exists(canonical)) return canonical; var pbstreams = Directory.GetFiles(mapFolder, "*.pbstream", SearchOption.TopDirectoryOnly); return pbstreams.Length > 0 ? pbstreams[0] : null; } }