/// <summary> /// Creates a .MGSVPreset file for the mods that are currently installed /// </summary> public static bool SavePreset(string presetFilePath) { bool success = false; Directory.CreateDirectory("_build\\master\\0"); SettingsManager manager = new SettingsManager(SnakeBiteSettings); string presetName = Path.GetFileName(presetFilePath); Debug.LogLine($"[SavePreset] Saving {presetName}...", Debug.LogLevel.Basic); try { foreach (string gameFile in manager.GetModExternalFiles()) { string sourcePath = Path.Combine(GameDir, Tools.ToWinPath(gameFile)); string DestDir = "_build\\" + Path.GetDirectoryName(gameFile); string fileName = Path.GetFileName(gameFile); Directory.CreateDirectory(DestDir); if (File.Exists(sourcePath)) { Debug.LogLine(string.Format("[SavePreset] Copying to build directory: {0}", gameFile), Debug.LogLevel.Basic); File.Copy(sourcePath, Path.Combine(DestDir, fileName), true); } else { Debug.LogLine(string.Format("[SavePreset] File not found: {0}", sourcePath), Debug.LogLevel.Basic); } } Debug.LogLine("[SavePreset] Copying to build directory: 00.dat", Debug.LogLevel.Basic); File.Copy(ZeroPath, "_build\\master\\0\\00.dat", true); Debug.LogLine("[SavePreset] Copying to build directory: 01.dat", Debug.LogLevel.Basic); File.Copy(OnePath, "_build\\master\\0\\01.dat", true); Debug.LogLine("[SavePreset] Copying to build directory: snakebite.xml", Debug.LogLevel.Basic); File.Copy(SnakeBiteSettings, "_build\\snakebite.xml", true); if (presetFilePath == SavePresetPath + build_ext) { Debug.LogLine($"Note: '{Path.GetFileNameWithoutExtension(presetName)}' can be disabled in the Settings menu to save time during installation and uninstallation.", Debug.LogLevel.Basic); } FastZip zipper = new FastZip(); Debug.LogLine(string.Format("[SavePreset] Writing {0}...", presetName), Debug.LogLevel.Basic); zipper.CreateZip(presetFilePath, "_build", true, "(.*?)"); Debug.LogLine("[SavePreset] Write Complete", Debug.LogLevel.Basic); success = true; } catch (Exception e) { MessageBox.Show("An error has occurred and the preset was not saved.\nException: " + e); } finally { ModManager.CleanupFolders(); } return(success); }
/// <summary> /// overwrites existing mods with the set of mods stored in the .MGSVPreset file /// </summary> public static bool LoadPreset(string presetFilePath) { bool panicMode = (!File.Exists(ZeroPath) || !File.Exists(OnePath) || !File.Exists(SnakeBiteSettings)); bool success = false; ModManager.CleanupFolders(); SettingsManager manager = new SettingsManager(SnakeBiteSettings); List <string> existingExternalFiles = new List <string>(); List <string> fileEntryDirs = new List <string>(); try { existingExternalFiles = manager.GetModExternalFiles(); } catch { panicMode = true; } try { if (!panicMode) { Debug.LogLine("[LoadPreset] Storing backups of existing files...", Debug.LogLevel.Basic); foreach (string gameFile in existingExternalFiles) { string gameFilePath = Path.Combine(GameDir, Tools.ToWinPath(gameFile)); if (File.Exists(gameFilePath)) // only stores backups of managed files { Debug.LogLine(string.Format("[LoadPreset] Storing backup: {0}", gameFile), Debug.LogLevel.Basic); fileEntryDirs.Add(Path.GetDirectoryName(gameFilePath)); if (File.Exists(gameFilePath + build_ext)) { File.Delete(gameFilePath + build_ext); } File.Move(gameFilePath, gameFilePath + build_ext); } } Debug.LogLine("[LoadPreset] Storing backup: 00.dat", Debug.LogLevel.Basic); File.Copy(ZeroPath, ZeroPath + build_ext, true); Debug.LogLine("[LoadPreset] Storing backup: 01.dat", Debug.LogLevel.Basic); File.Copy(OnePath, OnePath + build_ext, true); Debug.LogLine("[LoadPreset] Storing backup: snakebite.xml", Debug.LogLevel.Basic); File.Copy(SnakeBiteSettings, SnakeBiteSettings + build_ext, true); } else { Debug.LogLine("[LoadPreset] Critical file(s) are disfunctional or not found, skipping backup procedure", Debug.LogLevel.Basic); } Debug.LogLine("[LoadPreset] Importing preset files", Debug.LogLevel.Basic); FastZip unzipper = new FastZip(); unzipper.ExtractZip(presetFilePath, GameDir, "(.*?)"); Debug.LogLine("[LoadPreset] Import Complete", Debug.LogLevel.Basic); success = true; } catch (Exception e) { MessageBox.Show("An error has occurred and the preset was not imported.\nException: " + e); if (!panicMode) { Debug.LogLine("[LoadPreset] Restoring backup files", Debug.LogLevel.Basic); File.Copy(ZeroPath + build_ext, ZeroPath, true); File.Copy(OnePath + build_ext, OnePath, true); File.Copy(SnakeBiteSettings + build_ext, SnakeBiteSettings, true); foreach (string gameFile in existingExternalFiles) { string gameFilePath = Path.Combine(GameDir, Tools.ToWinPath(gameFile)); if (File.Exists(gameFilePath + build_ext)) { File.Copy(gameFilePath + build_ext, gameFilePath, true); } } } } finally { if (!panicMode) { Debug.LogLine("[LoadPreset] Removing backup files", Debug.LogLevel.Basic); foreach (string gameFile in existingExternalFiles) { string gameFilePath = Path.Combine(GameDir, Tools.ToWinPath(gameFile)); if (File.Exists(gameFilePath)) { File.Delete(gameFilePath + build_ext); } } foreach (string fileEntryDir in fileEntryDirs) { if (Directory.Exists(fileEntryDir)) { try { if (Directory.GetFiles(fileEntryDir).Length == 0) { Debug.LogLine(String.Format("[SB_Build] deleting empty folder: {0}", fileEntryDir), Debug.LogLevel.All); Directory.Delete(fileEntryDir); } } catch { Debug.LogLine("[Uninstall] Could not delete: " + fileEntryDir); } } } File.Delete(ZeroPath + build_ext); File.Delete(OnePath + build_ext); File.Delete(SnakeBiteSettings + build_ext); } } return(success); }
public static bool UninstallMods(CheckedListBox.CheckedIndexCollection modIndices, bool skipCleanup = false) // Uninstalls mods based on their indices in the list { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Debug.LogLine("[Uninstall] Start", Debug.LogLevel.Basic); // initial cleanup ModManager.ClearBuildFiles(ZeroPath, OnePath, SnakeBiteSettings, SavePresetPath); ModManager.ClearSBGameDir(); ModManager.CleanupFolders(); // backup preset build if (Properties.Settings.Default.AutosaveRevertPreset == true) { PresetManager.SavePreset(SavePresetPath + build_ext); } else { Debug.LogLine("[Uninstall] Skipping RevertChanges.MGSVPreset Save", Debug.LogLevel.Basic); } GzsLib.LoadDictionaries(); File.Copy(SnakeBiteSettings, SnakeBiteSettings + build_ext, true); List <ModEntry> mods = SBBuildManager.GetInstalledMods(); List <ModEntry> selectedMods = new List <ModEntry>(); foreach (int index in modIndices) { ModEntry mod = mods[index]; selectedMods.Add(mod); } List <string> zeroFiles = new List <string>(); bool hasQarZero = ModManager.hasQarZeroFiles(selectedMods); if (hasQarZero) { // if necessary, extracts 00.dat and creates a list of filenames, which is pruned throughout the uninstall process and repacked at the end. zeroFiles = GzsLib.ExtractArchive <QarFile>(ZeroPath, "_working0"); zeroFiles.RemoveAll(file => file.EndsWith("_unknown")); } List <string> oneFiles = null; bool hasFtexs = ModManager.foundLooseFtexs(selectedMods); if (hasFtexs) { // if necessary, extracts 01.dat and creates a list of filenames similar to zeroFiles. only textures are pruned from the list. oneFiles = GzsLib.ExtractArchive <QarFile>(OnePath, "_working1"); oneFiles.RemoveAll(file => file.EndsWith("_unknown")); } //end of qar extraction GameData gameData = SBBuildManager.GetGameData(); ModManager.ValidateGameData(ref gameData, ref zeroFiles); Debug.LogLine("[Uninstall] Building gameFiles lists", Debug.LogLevel.Basic); var baseGameFiles = GzsLib.ReadBaseData(); try { ModManager.PrepGameDirFiles(); // begin uninstall UninstallMods(selectedMods, ref zeroFiles, ref oneFiles); if (hasQarZero) { zeroFiles.Sort(); GzsLib.WriteQarArchive(ZeroPath + build_ext, "_working0", zeroFiles, GzsLib.zeroFlags); } if (hasFtexs) { oneFiles.Sort(); GzsLib.WriteQarArchive(OnePath + build_ext, "_working1", oneFiles, GzsLib.oneFlags); } // end of qar rebuild // overwrite old mod data ModManager.PromoteGameDirFiles(); ModManager.PromoteBuildFiles(ZeroPath, OnePath, SnakeBiteSettings, SavePresetPath); if (!skipCleanup) { ModManager.CleanupFolders(); ModManager.ClearSBGameDir(); } Debug.LogLine("[Uninstall] Uninstall complete", Debug.LogLevel.Basic); stopwatch.Stop(); Debug.LogLine($"[Uninstall] Uninstall took {stopwatch.ElapsedMilliseconds} ms", Debug.LogLevel.Basic); return(true); } catch (Exception e) { Debug.LogLine("[Uninstall] Exception: " + e, Debug.LogLevel.Basic); stopwatch.Stop(); Debug.LogLine($"[Uninstall] Uninstall failed at {stopwatch.ElapsedMilliseconds} ms", Debug.LogLevel.Basic); MessageBox.Show("An error has occurred during the uninstallation process and SnakeBite could not uninstall the selected mod(s).\nException: " + e); // clean up failed files ModManager.ClearBuildFiles(ZeroPath, OnePath, SnakeBiteSettings, SavePresetPath); ModManager.CleanupFolders(); bool restoreRetry = false; do { try { ModManager.RestoreBackupGameDir(SBBuildManager); } catch (Exception f) { Debug.LogLine("[Uninstall] Exception: " + f, Debug.LogLevel.Basic); restoreRetry = DialogResult.Retry == MessageBox.Show("SnakeBite could not restore Game Directory mod files due to the following exception: {f} \nWould you like to retry?", "Exception Occurred", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); } } while (restoreRetry); ModManager.ClearSBGameDir(); return(false); } }//UninstallMod batch
public static bool InstallMods(List <string> ModFiles, bool skipCleanup = false) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Debug.LogLine("[Install] Start", Debug.LogLevel.Basic); ModManager.ClearBuildFiles(ZeroPath, OnePath, SnakeBiteSettings, SavePresetPath); // deletes any leftover sb_build files that might still be in the directory (ie from a mid-process shutdown) ModManager.ClearSBGameDir(); // deletes the game directory sb_build ModManager.CleanupFolders(); // deletes the work folders which contain extracted files from 00/01 if (Properties.Settings.Default.AutosaveRevertPreset == true) { PresetManager.SavePreset(SavePresetPath + build_ext); // creates a backup preset file sb_build } else { Debug.LogLine("[Install] Skipping RevertChanges.MGSVPreset Save", Debug.LogLevel.Basic); } File.Copy(SnakeBiteSettings, SnakeBiteSettings + build_ext, true); // creates a settings sb_build GzsLib.LoadDictionaries(); List <ModEntry> installEntryList = new List <ModEntry>(); foreach (string modFile in ModFiles) { installEntryList.Add(Tools.ReadMetaData(modFile)); } List <string> zeroFiles = new List <string>(); bool hasQarZero = ModManager.hasQarZeroFiles(installEntryList); if (hasQarZero) { zeroFiles = GzsLib.ExtractArchive <QarFile>(ZeroPath, "_working0"); } List <string> oneFiles = null; bool hasFtexs = ModManager.foundLooseFtexs(installEntryList); if (hasFtexs) { oneFiles = GzsLib.ExtractArchive <QarFile>(OnePath, "_working1"); } SettingsManager SBBuildManager = new SettingsManager(SnakeBiteSettings + build_ext); var gameData = SBBuildManager.GetGameData(); ModManager.ValidateGameData(ref gameData, ref zeroFiles); var zeroFilesHashSet = new HashSet <string>(zeroFiles); Debug.LogLine("[Install] Building gameFiles lists", Debug.LogLevel.Basic); var baseGameFiles = GzsLib.ReadBaseData(); var allQarGameFiles = new List <Dictionary <ulong, GameFile> >(); allQarGameFiles.AddRange(baseGameFiles); try { ModManager.PrepGameDirFiles(); List <string> pullFromVanillas; List <string> pullFromMods; Dictionary <string, bool> pathUpdatesExist; Debug.LogLine("[Install] Writing FPK data to Settings", Debug.LogLevel.Basic); AddToSettingsFpk(installEntryList, SBBuildManager, allQarGameFiles, out pullFromVanillas, out pullFromMods, out pathUpdatesExist); InstallMods(ModFiles, SBBuildManager, pullFromVanillas, pullFromMods, ref zeroFilesHashSet, ref oneFiles, pathUpdatesExist); if (hasQarZero) { zeroFiles = zeroFilesHashSet.ToList(); zeroFiles.Sort(); GzsLib.WriteQarArchive(ZeroPath + build_ext, "_working0", zeroFiles, GzsLib.zeroFlags); } if (hasFtexs) { oneFiles.Sort(); GzsLib.WriteQarArchive(OnePath + build_ext, "_working1", oneFiles, GzsLib.oneFlags); } ModManager.PromoteGameDirFiles(); ModManager.PromoteBuildFiles(ZeroPath, OnePath, SnakeBiteSettings, SavePresetPath); if (!skipCleanup) { ModManager.CleanupFolders(); ModManager.ClearSBGameDir(); } stopwatch.Stop(); Debug.LogLine($"[Install] Installation finished in {stopwatch.ElapsedMilliseconds} ms", Debug.LogLevel.Basic); return(true); } catch (Exception e) { stopwatch.Stop(); Debug.LogLine($"[Install] Installation failed at {stopwatch.ElapsedMilliseconds} ms", Debug.LogLevel.Basic); Debug.LogLine("[Install] Exception: " + e, Debug.LogLevel.Basic); MessageBox.Show("An error has occurred during the installation process and SnakeBite could not install the selected mod(s).\nException: " + e, "Mod(s) could not be installed", MessageBoxButtons.OK, MessageBoxIcon.Error); ModManager.ClearBuildFiles(ZeroPath, OnePath, SnakeBiteSettings, SavePresetPath); ModManager.CleanupFolders(); bool restoreRetry = false; do { try { ModManager.RestoreBackupGameDir(SBBuildManager); } catch (Exception f) { Debug.LogLine("[Uninstall] Exception: " + f, Debug.LogLevel.Basic); restoreRetry = DialogResult.Retry == MessageBox.Show("SnakeBite could not restore Game Directory mod files due to the following exception: {f} \nWould you like to retry?", "Exception Occurred", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); } } while (restoreRetry); ModManager.ClearSBGameDir(); return(false); } }