namespace OmniNX.DesktopInstaller.Services; public sealed class ExtrasService { private readonly ConfigIniService _config = new(); public (bool needRam, bool needHekateAms) DetectExtras(string driveRoot) { var extras = PathUtils.ToDrivePath(driveRoot, "extras"); var needRam = File.Exists(Path.Combine(extras, "hekate_8gb.bin")) || File.Exists(Path.Combine(extras, "hekate-pro_8gb.bin")); var needHekateAms = Directory.Exists(Path.Combine(extras, "hekate-ams-pro")); return (needRam, needHekateAms); } public void ApplyExtras( string driveRoot, bool use8GbRam, bool useHekateAmsPro, IProgress? progress = null) { _config.MigrateLegacyRamConfig(driveRoot); var extras = PathUtils.ToDrivePath(driveRoot, "extras"); if (!Directory.Exists(extras)) return; var (needRam, needHekateAms) = DetectExtras(driveRoot); if (!needRam && !needHekateAms) return; progress?.Report("Saving RAM / Hekate-AMS selection to config.ini..."); _config.WriteExtras(driveRoot, needRam, use8GbRam, needHekateAms, useHekateAmsPro); if (useHekateAmsPro && needHekateAms) { progress?.Report("Installing Hekate-Pro / Atmosphere-Pro..."); ApplyHekateAmsPro(extras, driveRoot, progress); } else if (needHekateAms) { progress?.Report("Keeping standard Hekate / Atmosphere."); } if (needRam) { progress?.Report("Applying RAM payload setting..."); Apply8GbPayload(extras, driveRoot, use8GbRam, useHekateAmsPro); } progress?.Report("Removing extras/..."); PathUtils.DeletePath(extras); } private static void ApplyHekateAmsPro(string extrasDir, string driveRoot, IProgress? progress) { var src = Path.Combine(extrasDir, "hekate-ams-pro"); if (!Directory.Exists(src)) return; foreach (var entry in Directory.GetFileSystemEntries(src)) { var name = Path.GetFileName(entry); var dst = Path.Combine(PathUtils.NormalizeDriveRoot(driveRoot), name); if (Directory.Exists(entry)) PathUtils.CopyDirectory(entry, dst); else PathUtils.CopyFile(entry, dst); progress?.Report($" Copied: {name}"); } } private static void Apply8GbPayload(string extrasDir, string driveRoot, bool use8Gb, bool usePro) { var hekate8 = Path.Combine(extrasDir, "hekate_8gb.bin"); var hekatePro8 = Path.Combine(extrasDir, "hekate-pro_8gb.bin"); if (!use8Gb) { if (File.Exists(hekate8)) File.Delete(hekate8); if (File.Exists(hekatePro8)) File.Delete(hekatePro8); return; } var src = usePro ? hekatePro8 : hekate8; if (!File.Exists(src)) return; var payloadDst = PathUtils.ToDrivePath(driveRoot, "payload.bin"); var updateDst = PathUtils.ToDrivePath(driveRoot, @"bootloader\update.bin"); PathUtils.CopyFile(src, payloadDst); PathUtils.CopyFile(src, updateDst); if (File.Exists(hekate8)) File.Delete(hekate8); if (File.Exists(hekatePro8)) File.Delete(hekatePro8); } }