private void listInstalledMods_SelectedIndexChanged(object sender, EventArgs e)// Populate mod details pane { if (listInstalledMods.SelectedIndex >= 0) { var mods = manager.GetInstalledMods(); ModEntry selectedMod = mods[listInstalledMods.SelectedIndex]; modDescription.ShowModInfo(selectedMod); } }
private void labelModWebsite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) //inspired by Nexus Mod Manager, the version number doubles as a link to the webpage. { var mods = manager.GetInstalledMods(); ModEntry selectedMod = mods[listInstalledMods.SelectedIndex]; try { Process.Start(selectedMod.Website); } catch { } }
private void RefreshInstalledMods(bool resetSelection = false) { var mods = SettingsManager.GetInstalledMods(); listInstalledMods.Items.Clear(); if (mods.Count > 0) { panelModDetails.Visible = true; labelNoMods.Visible = false; foreach (ModEntry mod in mods) { listInstalledMods.Items.Add(mod.Name); } if (resetSelection) { if (listInstalledMods.Items.Count > 0) { listInstalledMods.SelectedIndex = 0; } else { listInstalledMods.SelectedIndex = -1; } } } else { panelModDetails.Visible = false; labelNoMods.Visible = true; } }
private void listInstalledMods_SelectedIndexChanged(object sender, EventArgs e) { // Populate mod details pane if (listInstalledMods.SelectedIndex >= 0) { var mods = SettingsManager.GetInstalledMods(); ModEntry selectedMod = mods[listInstalledMods.SelectedIndex]; labelModName.Text = selectedMod.Name; labelModVersion.Text = selectedMod.Version; labelModAuthor.Text = "by " + selectedMod.Author; labelModAuthor.Left = labelModName.Left + labelModName.Width + 4; labelModWebsite.Text = selectedMod.Website; textDescription.Text = selectedMod.Description; } }
private void buttonUninstallMod_Click(object sender, EventArgs e) { if (!(listInstalledMods.SelectedIndex >= 0)) { return; } // Get selected mod var mods = SettingsManager.GetInstalledMods(); ModEntry mod = mods[listInstalledMods.SelectedIndex]; if (!(MessageBox.Show(String.Format("{0} will be uninstalled.", mod.Name), "SnakeBite", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)) { return; } ProcessUninstallMod(mod); // Update installed mod list RefreshInstalledMods(true); }
public static bool CheckConflicts(string ModFile) { //Morbid: Conflict check has been reworked as of 0.9.0. CheckConflicts is now split into PreinstallManager.FilterModValidity and PreinstallManager.FilterModConflicts. // CheckConflicts is only used for command-line installation. ModEntry metaData = Tools.ReadMetaData(ModFile); if (metaData == null) { return(false); } // check version conflicts var SBVersion = ModManager.GetSBVersion(); var MGSVersion = ModManager.GetMGSVersion(); Version modSBVersion = new Version(); Version modMGSVersion = new Version(); try { modSBVersion = metaData.SBVersion.AsVersion(); modMGSVersion = metaData.MGSVersion.AsVersion(); } catch { MessageBox.Show(String.Format("The selected version of {0} was created with an older version of SnakeBite and is no longer compatible, please download the latest version and try again.", metaData.Name), "Mod update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } // Check if mod requires SB update if (modSBVersion > SBVersion) { MessageBox.Show(String.Format("{0} requires SnakeBite version {1} or newer. Please follow the link on the Settings page to get the latest version.", metaData.Name, metaData.SBVersion), "Update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } if (modSBVersion < new Version(0, 8, 0, 0)) // 0.8.0.0 { MessageBox.Show(String.Format("The selected version of {0} was created with an older version of SnakeBite and is no longer compatible, please download the latest version and try again.", metaData.Name), "Mod update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } // Check MGS version compatibility if (MGSVersion != modMGSVersion && modMGSVersion != new Version(0, 0, 0, 0)) { if (MGSVersion > modMGSVersion && modMGSVersion > new Version(0, 0, 0, 0)) { var contInstall = MessageBox.Show(String.Format("{0} appears to be for an older version of MGSV. It is recommended that you at least check for an updated version before installing.\n\nContinue installation?", metaData.Name), "Game version mismatch", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (contInstall == DialogResult.No) { return(false); } } if (MGSVersion < modMGSVersion) { MessageBox.Show(String.Format("{0} requires MGSV version {1}, but your installation is version {2}. Please update MGSV and try again.", metaData.Name, modMGSVersion, MGSVersion), "Update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } } //end of validity checks Debug.LogLine(String.Format("[Mod] Checking conflicts for {0}", metaData.Name)); int confCounter = 0; // search installed mods for conflicts SettingsManager manager = new SettingsManager(GameDir); var mods = manager.GetInstalledMods(); List <string> conflictingMods = new List <string>(); int confIndex = -1; foreach (ModEntry mod in mods) // iterate through installed mods { foreach (ModFileEntry fileEntry in metaData.ModFileEntries) // iterate external files from new mod { ModFileEntry conflicts = mod.ModFileEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FilePath, fileEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in 00.dat: {1}", mod.Name, conflicts.FilePath)); confCounter++; } } foreach (ModQarEntry qarEntry in metaData.ModQarEntries) // iterate qar files from new mod { if (qarEntry.FilePath.Contains(".fpk")) { continue; } ModQarEntry conflicts = mod.ModQarEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FilePath, qarEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in 00.dat: {1}", mod.Name, conflicts.FilePath)); confCounter++; } } foreach (ModFpkEntry fpkEntry in metaData.ModFpkEntries) // iterate fpk files from new mod { ModFpkEntry conflicts = mod.ModFpkEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FpkFile, fpkEntry.FpkFile) && Tools.CompareHashes(entry.FilePath, fpkEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in {2}: {1}", mod.Name, conflicts.FilePath, Path.GetFileName(conflicts.FpkFile))); confCounter++; } } } // if the mod conflicts, display message if (conflictingMods.Count > 0) { Debug.LogLine(String.Format("[Mod] Found {0} conflicts", confCounter)); string msgboxtext = "The selected mod conflicts with these mods:\n"; foreach (string Conflict in conflictingMods) { msgboxtext += Conflict + "\n"; } msgboxtext += "\nMore information regarding the conflicts has been output to the logfile."; MessageBox.Show(msgboxtext, "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } Debug.LogLine("[Mod] No conflicts found"); bool sysConflict = false; // check for system file conflicts var gameData = manager.GetGameData(); foreach (ModQarEntry gameQarFile in gameData.GameQarEntries.FindAll(entry => entry.SourceType == FileSource.System)) { if (metaData.ModQarEntries.Count(entry => Tools.ToQarPath(entry.FilePath) == Tools.ToQarPath(gameQarFile.FilePath)) > 0) { sysConflict = true; } } foreach (ModFpkEntry gameFpkFile in gameData.GameFpkEntries.FindAll(entry => entry.SourceType == FileSource.System)) { if (metaData.ModFpkEntries.Count(entry => entry.FilePath == gameFpkFile.FilePath && entry.FpkFile == gameFpkFile.FpkFile) > 0) { sysConflict = true; } } if (sysConflict) { //tex TODO: figure out what it's actually checking and how this can be corrupted string msgboxtext = "The selected mod conflicts with existing MGSV system files,\n"; msgboxtext += "or the snakebite.xml base entries has become corrupt.\n"; msgboxtext += "Please use the Restore Original Game Files option in Snakebite settings and re-run snakebite\n"; MessageBox.Show(msgboxtext, "SnakeBite", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } return(true); }
public static void FilterModConflicts(List <string> ModFiles)//checks if the mods in the list conflict with installed mods or with the game files { // asks user for input if a conflict is found. //return a list of mods that the user has OK'd int confCounter; int confIndex; SettingsManager manager = new SettingsManager(GameDir); var mods = manager.GetInstalledMods(); List <string> conflictingMods; ModEntry metaData; formModConflict conflictForm = new formModConflict(); // search installed mods for conflicts for (int i = ModFiles.Count() - 1; i >= 0; i--) { metaData = Tools.ReadMetaData(ModFiles[i]); confCounter = 0; confIndex = -1; conflictingMods = new List <string>(); Debug.LogLine(String.Format("[Mod] Checking conflicts for {0}", metaData.Name)); foreach (ModEntry mod in mods) // iterate through installed mods [Morbid: TODO iterate pftxs files as well] { foreach (ModFileEntry fileEntry in metaData.ModFileEntries) // iterate external files from new mod { ModFileEntry conflicts = mod.ModFileEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FilePath, fileEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in 00.dat: {1}", mod.Name, conflicts.FilePath)); confCounter++; } } foreach (ModQarEntry qarEntry in metaData.ModQarEntries) // iterate qar files from new mod { if (qarEntry.FilePath.Contains(".fpk")) { continue; } ModQarEntry conflicts = mod.ModQarEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FilePath, qarEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in 00.dat: {1}", mod.Name, conflicts.FilePath)); confCounter++; } } foreach (ModFpkEntry fpkEntry in metaData.ModFpkEntries) // iterate fpk files from new mod { ModFpkEntry conflicts = mod.ModFpkEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FpkFile, fpkEntry.FpkFile) && Tools.CompareHashes(entry.FilePath, fpkEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in {2}: {1}", mod.Name, conflicts.FilePath, Path.GetFileName(conflicts.FpkFile))); confCounter++; } } } // if the mod conflicts, prompt user for resolution if (conflictingMods.Count > 0) { Debug.LogLine(String.Format("[Mod] Found {0} conflicts", confCounter)); string msgboxtext = String.Format("\"{0}\" conflicts with the following pre-existing mods:\n\n", Tools.ReadMetaData(ModFiles[i]).Name); foreach (string Conflict in conflictingMods) { msgboxtext += String.Format("\"{0}\"\n", Conflict); } msgboxtext += "\n\nMore information regarding these conflicts can be found in the Debug Logs."; DialogResult userInput = conflictForm.ShowDialog(msgboxtext); if (userInput == DialogResult.Cancel) { ModFiles.RemoveAt(i); continue; } } Debug.LogLine("[Mod] No conflicts found"); bool sysConflict = false; // check for system file conflicts var gameData = manager.GetGameData(); foreach (ModQarEntry gameQarFile in gameData.GameQarEntries.FindAll(entry => entry.SourceType == FileSource.System)) { if (metaData.ModQarEntries.Count(entry => Tools.ToQarPath(entry.FilePath) == Tools.ToQarPath(gameQarFile.FilePath)) > 0) { sysConflict = true; } } foreach (ModFpkEntry gameFpkFile in gameData.GameFpkEntries.FindAll(entry => entry.SourceType == FileSource.System)) { if (metaData.ModFpkEntries.Count(entry => entry.FilePath == gameFpkFile.FilePath && entry.FpkFile == gameFpkFile.FpkFile) > 0) { sysConflict = true; } } if (sysConflict) { //tex TODO: figure out what it's actually checking and how this can be corrupted string msgboxtext = String.Format("\"{0}\" conflicts with existing MGSV system files,\n", Tools.ReadMetaData(ModFiles[i]).Name); msgboxtext += "or the snakebite.xml base entries has become corrupt.\n"; msgboxtext += "Please use the Restore Original Game Files option in Snakebite settings and re-run snakebite\n"; DialogResult userInput = conflictForm.ShowDialog(msgboxtext); if (userInput == DialogResult.Cancel) { ModFiles.RemoveAt(i); continue; } } } }
private static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); SettingsManager.DisableConflictCheck = false; if (Properties.Settings.Default.LastSBVersion == null || new Version(Properties.Settings.Default.LastSBVersion) < ModManager.GetSBVersion()) { Properties.Settings.Default.Upgrade(); } Properties.Settings.Default.LastSBVersion = ModManager.GetSBVersion().ToString(); Properties.Settings.Default.Save(); Debug.Clear(); Debug.LogLine(String.Format( "SnakeBite {0}\n" + "{1}\n" + "-------------------------", ModManager.GetSBVersion(), Environment.OSVersion.VersionString)); // Delete old settings file if (File.Exists(ModManager.GameDir + "\\sbmods.xml")) { Debug.LogLine("Settings v0.7 or less detected, removing"); File.Delete(ModManager.GameDir + "\\sbmods.xml"); MessageBox.Show("Due to fundamental changes from version 0.8 onwards, your settings have been reset. Please re-verify or restore the game files and run the setup wizard before continuing.", "Version Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } bool showSetupWizard = false; if (!SettingsManager.SettingsExist() || !SettingsManager.ValidInstallPath) { showSetupWizard = true; } // Show wizard on first run, if folder is invalid or settings out of date while (showSetupWizard) { // show setup wizard Debug.LogLine("Showing setup wizard"); SetupWizard.SetupWizard setupWizard = new SetupWizard.SetupWizard(); var wizResult = setupWizard.ShowDialog(); if (wizResult == DialogResult.Cancel) { return; } if (wizResult == DialogResult.OK) { showSetupWizard = false; } } string InitLog = String.Format( "MGS Install Folder: {0}\n" + "MGS Version: {1}\n" + "-------------------------", Properties.Settings.Default.InstallPath, ModManager.GetMGSVersion()); Debug.LogLine(InitLog, Debug.LogLevel.Basic); // Process Command Line args // TODO: test all command line args // Uninstall SnakeBite if (args.Length == 1) { if (args[0] == "-completeuninstall") { Debug.LogLine("Complete uninstall"); // Restore backup and remove settings SettingsManager.DeleteSettings(); BackupManager.RestoreOriginals(); return; } } // Parse command line arguments bool doCmdLine = false; // Process command line args? bool closeApp = false; // Close app after? bool install = false; // Install = true, uninstall = false bool ignoreConflicts = false; // Bypass conflict check bool resetDatHash = false; // Rehash dat file string installFile = String.Empty; if (args.Length > 0) { foreach (string arg in args) { switch (arg.ToLower()) { case "-i": install = true; break; case "-u": install = false; break; case "-c": ignoreConflicts = true; break; case "-d": resetDatHash = true; break; case "-x": closeApp = true; break; default: installFile = arg; doCmdLine = true; break; } } } // Update dat hash in settings if (resetDatHash) { Debug.LogLine("Resetting dat hash"); SettingsManager.UpdateDatHash(); } var checkDat = SettingsManager.ValidateDatHash(); if (!checkDat) { MessageBox.Show("Game archive has been modified. The setup wizard will now run.", "Game data hash mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error); SetupWizard.SetupWizard setupWizard = new SetupWizard.SetupWizard(); setupWizard.ShowDialog(); } if (doCmdLine) { Debug.LogLine("Doing cmd line args"); formMods ModForm = new formMods(); ModForm.Show(); ModForm.Hide(); if (install) { // install ModForm.ProcessInstallMod(installFile, ignoreConflicts); // install mod } else { // uninstall var mods = SettingsManager.GetInstalledMods(); ModEntry mod = mods.FirstOrDefault(entry => entry.Name == installFile); // select mod if (mod != null) { ModForm.ProcessUninstallMod(mod); // uninstall mod } } ModForm.Dispose(); if (closeApp) { return; } } //Application.Run(new formMain()); Application.Run(new formLauncher()); }
private static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); ICSharpCode.SharpZipLib.Zip.ZipConstants.DefaultCodePage = 437; SettingsManager manager = new SettingsManager(GamePaths.SnakeBiteSettings); bool updateQarFilenames = false; if (Properties.Settings.Default.LastSBVersion == null || new Version(Properties.Settings.Default.LastSBVersion) < ModManager.GetSBVersion()) { if (Properties.Settings.Default.LastSBVersion != null) { updateQarFilenames = true; } Properties.Settings.Default.Upgrade(); } Properties.Settings.Default.LastSBVersion = ModManager.GetSBVersion().ToString(); Properties.Settings.Default.Save(); Debug.Clear(); Debug.LogLine(String.Format( "SnakeBite {0}\n" + "{1}\n" + "-------------------------", ModManager.GetSBVersion(), Environment.OSVersion.VersionString)); // Delete old settings file if (File.Exists(GamePaths.GameDir + "\\sbmods.xml")) { Debug.LogLine("Settings v0.7 or less detected, removing"); File.Delete(GamePaths.GameDir + "\\sbmods.xml"); MessageBox.Show("Due to fundamental changes from version 0.8 onwards, your settings have been reset. Please re-verify or restore the game files and run the setup wizard before continuing.", "Version Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } bool showSetupWizard = true; if (manager.SettingsExist() && manager.ValidInstallPath) { showSetupWizard = false; } // Show wizard on first run, if folder is invalid or settings out of date while (showSetupWizard) { // show setup wizard Debug.LogLine("[Setup] Starting Setup Wizard"); try { SetupWizard.SetupWizard setupWizard = new SetupWizard.SetupWizard(); var wizResult = setupWizard.ShowDialog(); if (wizResult == DialogResult.Cancel) { return; } if (wizResult == DialogResult.OK) { showSetupWizard = false; } } catch (Exception e) { Debug.LogLine("[Setup] Setup Wizard error: " + e.ToString()); } } manager = new SettingsManager(GamePaths.SnakeBiteSettings); string InitLog = String.Format( "MGS Install Folder: {0}\n" + "MGS Version: {1}\n" + "-------------------------", Properties.Settings.Default.InstallPath, ModManager.GetMGSVersion()); Debug.LogLine(InitLog, Debug.LogLevel.Basic); // Process Command Line args // Uninstall SnakeBite if (args.Length == 1) { if (args[0] == "-completeuninstall") { Debug.LogLine("Complete uninstall"); // Restore backup and remove settings manager.DeleteSettings(); BackupManager.RestoreOriginals(); return; } } // Parse command line arguments bool doCmdLine = false; // Process command line args? bool closeApp = false; // Close app after? bool install = false; // Install = true, uninstall = false bool resetDatHash = false; // Rehash dat file bool skipConflictChecks = false; bool skipCleanup = false; // Skip CleanupDatabase string installFile = String.Empty; if (args.Length > 0) { foreach (string arg in args) { switch (arg.ToLower()) { case "-i": install = true; break; case "-u": install = false; break; case "-d": resetDatHash = true; break; case "-x": closeApp = true; break; case "-s": skipCleanup = true; break; case "-c": skipConflictChecks = true; break; default: installFile = arg; doCmdLine = true; break; } } } // Update dat hash in settings if (resetDatHash) { Debug.LogLine("Resetting dat hash"); manager.UpdateDatHash(); } if (ModManager.GetMGSVersion() > SettingsManager.IntendedGameVersion) { var contSB = MessageBox.Show("Due to a recent game update, this version of SnakeBite is outdated, and some features will not function properly.\n\nIt is highly recommended that you do not continue, and update to the latest version of Snakebite when it becomes available.\n\nWould you still like to continue? ", "Game Version Update", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (contSB == DialogResult.No) { return; } } if (!File.Exists(GamePaths.ZeroPath) || !File.Exists(GamePaths.OnePath)) { MessageBox.Show(string.Format("Critical Error: SnakeBite could not locate critical game data! \n\n({0})\nand/or\n({1}).\n\nRestore your game files with backups, MGSVPreset files, or revalidating through Steam!", GamePaths.ZeroPath, GamePaths.OnePath), "Archive(s) Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { try { bool checkDat = false; if (updateQarFilenames) { manager.updateQarFileNames(); } checkDat = manager.ValidateDatHash(); if (!checkDat || manager.IsVanilla0001DatHash()) { if (manager.IsVanilla0001DatHash() || manager.IsVanilla0001Size()) { MessageBox.Show("Fresh 00.dat/01.dat detected. The setup wizard will now run.", "Game data hash mismatch", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("Game archive has been modified. The setup wizard will now run.", "Game data hash mismatch", MessageBoxButtons.OK, MessageBoxIcon.Information); } SetupWizard.SetupWizard setupWizard = new SetupWizard.SetupWizard(); setupWizard.ShowDialog(); } else if (!BackupManager.c7t7Exist()) // chunk7 and/or texture7 are missing, despite the dathash validating. { MessageBox.Show("To continue, SnakeBite must build a_chunk7.dat and a_texture7.dat from your current archives. The setup wizard will now run.", "Setup required", MessageBoxButtons.OK, MessageBoxIcon.Information); SetupWizard.SetupWizard setupWizard = new SetupWizard.SetupWizard(); setupWizard.ShowDialog(); } } catch (InvalidOperationException e) { if (File.Exists(GamePaths.OnePath) && File.Exists(GamePaths.ZeroPath)) { if (manager.IsVanilla0001Size()) { File.Delete(GamePaths.SnakeBiteSettings); SetupWizard.SetupWizard setupWizard = new SetupWizard.SetupWizard(); setupWizard.ShowDialog(); } } MessageBox.Show(string.Format("Critical Error: SnakeBite could not read settings data! \n\n({0})\n\nRestore your game files with backups, MGSVPreset files, or revalidating through Steam!", GamePaths.SnakeBiteSettings), "Failed To Read Settings", MessageBoxButtons.OK, MessageBoxIcon.Error); Debug.LogLine("Error: ValidateDatHash failed: " + e); } } if (doCmdLine) { Debug.LogLine("Doing cmd line args"); formMods ModForm = new formMods(); ModForm.Show(); ModForm.Hide(); if (install) { ModForm.ProcessInstallMod(installFile, skipConflictChecks, skipCleanup); // install mod } else { // uninstall var mods = manager.GetInstalledMods(); ModEntry mod = mods.FirstOrDefault(entry => entry.Name == installFile); // select mod if (mod != null) { ModForm.ProcessUninstallMod(mod, skipCleanup); // uninstall mod } } ModForm.Dispose(); if (closeApp) { return; } } if (Properties.Settings.Default.SkipLauncher) { Application.Run(new formMods()); } else { Application.Run(new formLauncher()); } }
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
/// <summary> /// Checks 00.dat files, indcluding fpk contents and adds the different mod entry types (if missing) to database (snakebite.xml) /// Slows down as number of fpks increase /// </summary> public static void CleanupDatabase() { Debug.LogLine("[Cleanup] Database cleanup started", Debug.LogLevel.Basic); // Retrieve installation data SettingsManager manager = new SettingsManager(SnakeBiteSettings); var mods = manager.GetInstalledMods(); var game = manager.GetGameData(); var zeroFiles = GzsLib.ListArchiveContents<QarFile>(ZeroPath); //Should only happen if user manually mods 00.dat Debug.LogLine("[Cleanup] Removing duplicate file entries", Debug.LogLevel.Debug); // Remove duplicate file entries var cleanFiles = zeroFiles.ToList(); foreach (string file in zeroFiles) { while (cleanFiles.Count(entry => entry == file) > 1) { cleanFiles.Remove(file); Debug.LogLine(String.Format("[Cleanup] Found duplicate file in 00.dat: {0}", file), Debug.LogLevel.Debug); } } Debug.LogLine("[Cleanup] Examining FPK archives", Debug.LogLevel.Debug); var GameFpks = game.GameFpkEntries.ToList(); // Search for FPKs in game data var fpkFiles = cleanFiles.FindAll(entry => entry.EndsWith(".fpk") || entry.EndsWith(".fpkd")); foreach (string fpkFile in fpkFiles) { string fpkName = Path.GetFileName(fpkFile); // Extract FPK from archive Debug.LogLine(String.Format("[Cleanup] Examining {0}", fpkName)); GzsLib.ExtractFile<QarFile>(ZeroPath, fpkFile, fpkName); // Read FPK contents var fpkContent = GzsLib.ListArchiveContents<FpkFile>(fpkName); // Add contents to game FPK list foreach (var c in fpkContent) { if (GameFpks.Count(entry => Tools.CompareNames(entry.FilePath, c) && Tools.CompareHashes(entry.FpkFile, fpkFile)) == 0) { GameFpks.Add(new ModFpkEntry() { FpkFile = fpkFile, FilePath = c }); } } try { File.Delete(fpkName); } catch { Console.WriteLine("[Uninstall] Could not delete: " + fpkName); } } Debug.LogLine("[Cleanup] Checking installed mods", Debug.LogLevel.Debug); Debug.LogLine("[Cleanup] Removing all installed mod data from game data list", Debug.LogLevel.Debug); foreach (var mod in mods) { foreach (var qarEntry in mod.ModQarEntries) { cleanFiles.RemoveAll(file => Tools.CompareHashes(file, qarEntry.FilePath)); } foreach (var fpkEntry in mod.ModFpkEntries) { GameFpks.RemoveAll(fpk => Tools.CompareHashes(fpk.FpkFile, fpkEntry.FpkFile) && Tools.ToQarPath(fpk.FilePath) == Tools.ToQarPath(fpkEntry.FilePath)); } } Debug.LogLine("[Cleanup] Checking mod QAR files against game files", Debug.LogLevel.Debug); foreach (var s in cleanFiles) { if (game.GameQarEntries.Count(entry => Tools.CompareHashes(entry.FilePath, s)) == 0) { Debug.LogLine($"[Cleanup] Adding missing {s}", Debug.LogLevel.Debug); game.GameQarEntries.Add(new ModQarEntry() { FilePath = Tools.ToQarPath(s), SourceType = FileSource.System, Hash = Tools.NameToHash(s) }); } } game.GameFpkEntries = GameFpks; manager.SetGameData(game); }
public static bool CheckConflicts(string ModFile, bool ignoreConflicts = false) { var metaData = Tools.ReadMetaData(ModFile); if (metaData == null) { return(false); } if (!SettingsManager.DisableConflictCheck && !ignoreConflicts) { // check version conflicts var SBVersion = ModManager.GetSBVersion(); var MGSVersion = ModManager.GetMGSVersion(); Version modSBVersion = new Version(); Version modMGSVersion = new Version(); try { modSBVersion = metaData.SBVersion.AsVersion(); modMGSVersion = metaData.MGSVersion.AsVersion(); } catch { MessageBox.Show(String.Format("The selected version of {0} was created with an older version of SnakeBite and is no longer compatible, please download the latest version and try again.", metaData.Name), "Mod update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } // Check if mod requires SB update if (modSBVersion > SBVersion) { MessageBox.Show(String.Format("{0} requires a newer version of SnakeBite. Please follow the link on the Settings page to get the latest version.", metaData.Name), "Update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } if (modSBVersion < new Version(0, 8, 0, 0)) // 0.8.0.0 { MessageBox.Show(String.Format("The selected version of {0} was created with an older version of SnakeBite and is no longer compatible, please download the latest version and try again.", metaData.Name), "Mod update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } // Check MGS version compatibility if (MGSVersion != modMGSVersion && modMGSVersion != new Version(0, 0, 0, 0)) { if (MGSVersion > modMGSVersion && modMGSVersion > new Version(0, 0, 0, 0)) { var contInstall = MessageBox.Show(String.Format("{0} appears to be for an older version of MGSV. It is recommended that you at least check for an updated version before installing.\n\nContinue installation?", metaData.Name, modMGSVersion, MGSVersion), "Game version mismatch", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (contInstall == DialogResult.No) { return(false); } } if (MGSVersion < modMGSVersion) { MessageBox.Show(String.Format("{0} requires MGSV version {1}, but your installation is version {2}. Please update MGSV and try again.", metaData.Name, modMGSVersion, MGSVersion), "Update required", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } } Debug.LogLine(String.Format("[Mod] Checking conflicts for {0}", metaData.Name)); int confCounter = 0; // search installed mods for conflicts var mods = SettingsManager.GetInstalledMods(); List <string> conflictingMods = new List <string>(); int confIndex = -1; foreach (ModEntry mod in mods) // iterate through installed mods { foreach (ModQarEntry qarEntry in metaData.ModQarEntries) // iterate qar files from new mod { if (qarEntry.FilePath.Contains(".fpk")) { continue; } ModQarEntry conflicts = mod.ModQarEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FilePath, qarEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in 00.dat: {1}", mod.Name, conflicts.FilePath)); confCounter++; } } foreach (ModFpkEntry fpkEntry in metaData.ModFpkEntries) // iterate fpk files from new mod { ModFpkEntry conflicts = mod.ModFpkEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FpkFile, fpkEntry.FpkFile) && Tools.CompareHashes(entry.FilePath, fpkEntry.FilePath)); if (conflicts != null) { if (confIndex == -1) { confIndex = mods.IndexOf(mod); } if (!conflictingMods.Contains(mod.Name)) { conflictingMods.Add(mod.Name); } Debug.LogLine(String.Format("[{0}] Conflict in {2}: {1}", mod.Name, conflicts.FilePath, Path.GetFileName(conflicts.FpkFile))); confCounter++; } } } // if the mod conflicts, display message if (conflictingMods.Count > 0) { Debug.LogLine(String.Format("[Mod] Found {0} conflicts", confCounter)); string msgboxtext = "The selected mod conflicts with these mods:\n"; foreach (string Conflict in conflictingMods) { msgboxtext += Conflict + "\n"; } msgboxtext += "\nMore information regarding the conflicts has been output to the logfile. Double click the version number shown in the Launcher to view the current logfile."; MessageBox.Show(msgboxtext, "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } Debug.LogLine("[Mod] No conflicts found"); bool sysConflict = false; // check for system file conflicts var gameData = SettingsManager.GetGameData(); foreach (ModQarEntry gameQarFile in gameData.GameQarEntries.FindAll(entry => entry.SourceType == FileSource.System)) { if (metaData.ModQarEntries.Count(entry => Tools.ToQarPath(entry.FilePath) == Tools.ToQarPath(gameQarFile.FilePath)) > 0) { sysConflict = true; } } foreach (ModFpkEntry gameFpkFile in gameData.GameFpkEntries.FindAll(entry => entry.SourceType == FileSource.System)) { if (metaData.ModFpkEntries.Count(entry => entry.FilePath == gameFpkFile.FilePath && entry.FpkFile == gameFpkFile.FpkFile) > 0) { sysConflict = true; } } if (sysConflict) { MessageBox.Show("The selected mod conflicts with existing MGSV system files.", "SnakeBite", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } DialogResult confirmInstall = MessageBox.Show(String.Format("You are about to install {0}, continue?", metaData.Name), "SnakeBite", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (confirmInstall == DialogResult.No) { return(false); } } return(true); }