Exemple #1
0
 private static void ValidateModEntries(ref ModEntry modEntry)
 {
     Debug.LogLine("[ValidateModEntries] Validating qar entries", Debug.LogLevel.Basic);
     for (int i = modEntry.ModQarEntries.Count - 1; i >= 0; i--)
     {
         ModQarEntry qarEntry = modEntry.ModQarEntries[i];
         if (!GzsLib.IsExtensionValidForArchive(qarEntry.FilePath, ".dat"))
         {
             Debug.LogLine($"[ValidateModEntries] Found invalid file entry {qarEntry.FilePath} for archive {qarEntry.SourceName}", Debug.LogLevel.Basic);
             modEntry.ModQarEntries.RemoveAt(i);
         }
     }
     Debug.LogLine("[ValidateModEntries] Validating fpk entries", Debug.LogLevel.Basic);
     for (int i = modEntry.ModFpkEntries.Count - 1; i >= 0; i--)
     {
         ModFpkEntry fpkEntry = modEntry.ModFpkEntries[i];
         if (!GzsLib.IsExtensionValidForArchive(fpkEntry.FilePath, fpkEntry.FpkFile))
         {
             Debug.LogLine($"[ValidateModEntries] Found invalid file entry {fpkEntry.FilePath} for archive {fpkEntry.FpkFile}", Debug.LogLevel.Basic);
             modEntry.ModFpkEntries.RemoveAt(i);
         }
     }
 }
        public static bool hasConflict(ModEntry mod1, ModEntry mod2)
        {
            foreach (ModQarEntry qarEntry in mod1.ModQarEntries) // iterate qar files from new mod
            {
                if (qarEntry.FilePath.EndsWith(".fpk") || qarEntry.FilePath.EndsWith(".fpkd"))
                {
                    continue;
                }
                ModQarEntry conflicts = mod2.ModQarEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FilePath, qarEntry.FilePath));
                if (conflicts != null)
                {
                    Debug.LogLine(String.Format("[PreinstallCheck] Conflict found between {0} and {1}: {2}", mod1.Name, mod2.Name, conflicts.FilePath), Debug.LogLevel.Basic);
                    return(true);
                }
            }

            foreach (ModFpkEntry fpkEntry in mod1.ModFpkEntries) // iterate fpk files from new mod
            {
                ModFpkEntry conflicts = mod2.ModFpkEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FpkFile, fpkEntry.FpkFile) &&
                                                                          Tools.CompareHashes(entry.FilePath, fpkEntry.FilePath));
                if (conflicts != null)
                {
                    return(true);
                }
            }

            foreach (ModFileEntry fileEntry in mod1.ModFileEntries) // iterate external files from new mod
            {
                ModFileEntry conflicts = mod2.ModFileEntries.FirstOrDefault(entry => Tools.CompareHashes(entry.FilePath, fileEntry.FilePath));
                if (conflicts != null)
                {
                    return(true);
                }
            }
            return(false);
        }
        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;
                    }
                }
            }
        }
Exemple #5
0
        private static void UnmergePackFiles(List <ModQarEntry> partialEditQarEntries, List <ModFpkEntry> partialRemoveFpkEntries)
        {
            GameData           gameData = SBBuildManager.GetGameData();
            List <ModFpkEntry> addedRepairFpkEntries = new List <ModFpkEntry>();

            foreach (ModQarEntry partialEditQarEntry in partialEditQarEntries)
            {
                // create a list of fpk filepaths that need to be modified for the specific qar file (either restored to vanilla or removed from the pack)
                List <string> fpkPathsForThisQar = partialRemoveFpkEntries.Where(entry => entry.FpkFile == partialEditQarEntry.FilePath).Select(fpkEntry => Tools.ToWinPath(fpkEntry.FilePath)).ToList();
                var           fpkReferences      = new List <string>();//tex references in fpk that need to be preserved/transfered to the rebuilt fpk

                // pull the vanilla qar file from the game archive, send to _gameFpk folder
                string winQarEntryPath = Tools.ToWinPath(partialEditQarEntry.FilePath);
                string gameQarPath     = Path.Combine("_gameFpk", winQarEntryPath);
                if (partialEditQarEntry.SourceName != null)
                {
                    string vanillaArchivePath = Path.Combine(GameDir, "master\\" + partialEditQarEntry.SourceName);
                    //Debug.LogLine(string.Format("Pulling {0} from {1}", partialRemoveQarEntry.FilePath, partialRemoveQarEntry.SourceName));
                    GzsLib.ExtractFileByHash <QarFile>(vanillaArchivePath, partialEditQarEntry.Hash, gameQarPath);
                    fpkReferences = GzsLib.GetFpkReferences(gameQarPath);
                }
                // pull the modded qar file from _working0 (assumed to already exist when the uninstall process reads 00.dat), send to _build folder
                string        workingZeroQarPath = Path.Combine("_working0", winQarEntryPath);
                List <string> moddedFpkFiles     = GzsLib.ExtractArchive <FpkFile>(workingZeroQarPath, "_build");

                // split the fpk paths for this Qar into two categories:
                List <string> repairFilePathList = new List <string>(); // files that need to be repaired (aka overwritten by a vanilla file)
                if (partialEditQarEntry.SourceName != null)
                {
                    repairFilePathList = GzsLib.ListArchiveContents <FpkFile>(gameQarPath).Intersect(fpkPathsForThisQar).ToList();
                }
                List <string> removeFilePathList = fpkPathsForThisQar.Except(repairFilePathList).ToList(); // files that need to be removed (i.e. files that were non-native to the vanilla Qar)

                foreach (string repairFilePath in repairFilePathList)
                {
                    string fpkBuildPath = Path.Combine("_build", repairFilePath);
                    Debug.LogLine(string.Format("[Unmerge Fpk] Extracting repair file: {0}", repairFilePath), Debug.LogLevel.Basic);
                    GzsLib.ExtractFile <FpkFile>(gameQarPath, repairFilePath, fpkBuildPath); // overwrites modded fpk files
                    ModFpkEntry repairEntry = new ModFpkEntry
                    {
                        FpkFile    = partialEditQarEntry.FilePath,
                        FilePath   = repairFilePath, // this will be a window path
                        SourceType = FileSource.Merged,
                        SourceName = partialEditQarEntry.SourceName
                    };
                    gameData.GameFpkEntries.Add(repairEntry);
                    addedRepairFpkEntries.Add(repairEntry);
                }

                var buildFiles = moddedFpkFiles.Except(removeFilePathList).ToList();
                //tex refs werent grabbed from vanilla (or there weren't any in there in that case we're probably doubling the work lol)
                if (fpkReferences.Count == 0)
                {
                    fpkReferences = GzsLib.GetFpkReferences(workingZeroQarPath);
                }
                GzsLib.WriteFpkArchive(workingZeroQarPath, "_build", buildFiles, fpkReferences); // writes the pack back to _working folder (leaving out the non-native fpk files)
                foreach (string removeFilePath in removeFilePathList)
                {
                    int indexToRemove = gameData.GameFpkEntries.FindIndex(entry => entry.FilePath == removeFilePath);
                    if (indexToRemove >= 0)
                    {
                        gameData.GameFpkEntries.RemoveAt(indexToRemove);
                    }
                }
            }

            List <ModEntry> installedMods = SBBuildManager.GetInstalledMods();

            foreach (ModEntry installedMod in installedMods)
            {
                List <string> qarPathsFound = new List <string>();
                foreach (ModFpkEntry addedRepairEntry in addedRepairFpkEntries)
                {
                    if (installedMod.ModQarEntries.FirstOrDefault(entry => entry.FilePath == addedRepairEntry.FpkFile) == null)
                    {
                        continue;
                    }

                    //Debug.LogLine(string.Format("checking {0} for {1} of {2}", installedMod.Name, addedRepairEntry.FilePath, addedRepairEntry.FpkFile));
                    if (installedMod.ModFpkEntries.RemoveAll(entry => entry.FilePath == Tools.ToQarPath(addedRepairEntry.FilePath) && entry.FpkFile == addedRepairEntry.FpkFile) > 0)
                    {
                        //Debug.LogLine(string.Format("found {0} of {1} in {2}", addedRepairEntry.FilePath, addedRepairEntry.FpkFile, installedMod.Name));
                        if (!qarPathsFound.Contains(addedRepairEntry.FpkFile))
                        {
                            qarPathsFound.Add(addedRepairEntry.FpkFile);
                        }
                    }
                }

                foreach (string qarPathFound in qarPathsFound)
                {
                    if (installedMod.ModFpkEntries.FirstOrDefault(entry => entry.FpkFile == qarPathFound) == null) //when the duplicate fpk file(s) were removed, there was nothing left in the modded qar.
                    {
                        //Debug.LogLine(string.Format("Removing {0} from {1}", qarPathFound, installedMod.Name));
                        installedMod.ModQarEntries.RemoveAll(entry => entry.FilePath == qarPathFound); // filters the qar file out of the list
                    }
                }
            }
            SBBuildManager.SetInstalledMods(installedMods);
            SBBuildManager.SetGameData(gameData);
        }
Exemple #6
0
        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);
        }