Ejemplo n.º 1
0
        public static bool HasEditCollision(GameModification currentMod, string file, IWriteContent content, FileWriterUtility fileWriter, List <FileModification> modifications, out ModCollision collision)
        {
            var actions = new ActionCollection(file, currentMod.Config.ModID, modifications);

            if (actions.moveAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Edit, FileModificationType.Moved, actions.moveAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.replaceAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Edit, FileModificationType.Replaced, actions.replaceAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.editAction != null && !fileWriter.CanWrite(file, content))
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Edit, FileModificationType.Edited, actions.editAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.deleteAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Edit, FileModificationType.Deleted, actions.deleteAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            collision = null;
            return(false);
        }
Ejemplo n.º 2
0
        private void MoveFile_Internal(string targetPath, string destinationPath, GameModification mod)
        {
            if (IsReservedFile(targetPath))
            {
                modifications.Add(new MoveFileModification(targetPath, destinationPath, true, mod.Config.ModID));
                BackupFile(targetPath);
            }
            else
            {
                modifications.Add(new MoveFileModification(targetPath, destinationPath, false, mod.Config.ModID));
            }

            if (IsReservedFile(destinationPath))
            {
                modifications.Add(new ReplaceFileModification(destinationPath, true, mod.Config.ModID));
                BackupFile(destinationPath);
            }
            else
            {
                modifications.Add(new AddFileModification(destinationPath, false, mod.Config.ModID));
            }

            Directory.CreateDirectory(new FileInfo(destinationPath).DirectoryName);
            File.Move(targetPath, destinationPath, true);
        }
Ejemplo n.º 3
0
        public void CheckFileWriteWithMove()
        {
            var actions = new List <FileModification>()
            {
                new MoveFileModification(exampleFile1, exampleDestination1, false, "Test.Move")
            };

            var fileWriter = new FileWriterUtility();
            var content    = new WriteToFileAction.WriteContent()
            {
                Text = "Test", StartOffset = 12
            };
            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Edit"
                }
            };

            bool hasCollision = ModCollisionTracker.HasEditCollision(mod, exampleFile1, content, fileWriter, actions, out var collision);

            Assert.AreEqual(true, hasCollision);
            Assert.AreEqual(collision.severity, ModCollisionSeverity.Clash);
            Assert.AreEqual(collision.modID, "Test.Move");
            Assert.IsTrue(collision.description.Contains("Attempting to write to a file that has been moved by another mod"), $"Actual: {collision.description}");
        }
Ejemplo n.º 4
0
        private static bool AddModCollision(GameModification mod, ModInstallActionEnum action, FileModificationType collisionReason, string collidingModID, ModCollisionSeverity severity, out ModCollision collision, string suffix = "")
        {
            string collisionReasonDescription = GetCollisionDescription(collisionReason);
            string actionDescription          = GetModificationDescription(action);

            return(AddModCollision(mod, actionDescription, collisionReasonDescription, collidingModID, severity, out collision, suffix: suffix));
        }
Ejemplo n.º 5
0
        public static bool HasReplaceCollision(GameModification currentMod, string file, string replacementFile, List <FileModification> modifications, out ModCollision collision)
        {
            var actions = new ActionCollection(file, currentMod.Config.ModID, modifications);

            if (actions.moveAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Replace, FileModificationType.Moved, actions.moveAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.replaceAction != null && MD5Utility.CalculateMD5Hash(file) != MD5Utility.CalculateMD5Hash(replacementFile))
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Replace, FileModificationType.Replaced, actions.replaceAction.ModID, ModCollisionSeverity.Clash, out collision, suffix: "(with different data)"));
            }

            if (actions.editAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Replace, FileModificationType.Edited, actions.editAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.deleteAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Replace, FileModificationType.Deleted, actions.deleteAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            collision = null;
            return(false);
        }
Ejemplo n.º 6
0
 public GameChangedEventArgs(AvailableGame game,
                             GameModification gameModification)
 {
     Game = game ?? throw new ArgumentNullException(nameof(game));
     if (gameModification == GameModification.Undefined)
     {
         throw new ArgumentOutOfRangeException(nameof(gameModification));
     }
     GameModification = gameModification;
 }
Ejemplo n.º 7
0
 public void AddActions(GameModification mod, ModInstallAction[] actions)
 {
     extractActions.AddRange(actions.Where(a => a.Action.SafeEquals("QuickBMSExtract", ignoreCase: true)).Select(a => new ModAction <QuickBMSExtractAction>(mod, a as QuickBMSExtractAction)));
     decompileActions.AddRange(actions.Where(a => a.Action.SafeEquals("UnluacDecompile", ignoreCase: true)).Select(a => new ModAction <UnluacDecompileAction>(mod, a as UnluacDecompileAction)));
     fileMoveActions.AddRange(actions.Where(a => a.Action.SafeEquals("MoveFile", ignoreCase: true)).Select(a => new ModAction <MoveFileAction>(mod, a as MoveFileAction)));
     bulkFileMoveActions.AddRange(actions.Where(a => a.Action.SafeEquals("MoveFiles", ignoreCase: true)).Select(a => new ModAction <MoveFilesAction>(mod, a as MoveFilesAction)));
     fileDeleteActions.AddRange(actions.Where(a => a.Action.SafeEquals("DeleteFiles", ignoreCase: true)).Select(a => new ModAction <DeleteFilesAction>(mod, a as DeleteFilesAction)));
     fileWriteActions.AddRange(actions.Where(a => a.Action.SafeEquals("WriteToFile", ignoreCase: true)).Select(a => new ModAction <WriteToFileAction>(mod, a as WriteToFileAction)));
     fileReplaceActions.AddRange(actions.Where(a => a.Action.SafeEquals("ReplaceFile", ignoreCase: true)).Select(a => new ModAction <ReplaceFileAction>(mod, a as ReplaceFileAction)));
     bulkFileReplaceActions.AddRange(actions.Where(a => a.Action.SafeEquals("ReplaceFiles", ignoreCase: true)).Select(a => new ModAction <ReplaceFilesAction>(mod, a as ReplaceFilesAction)));
     fileCopyActions.AddRange(actions.Where(a => a.Action.SafeEquals("CopyFile", ignoreCase: true)).Select(a => new ModAction <CopyFileAction>(mod, a as CopyFileAction)));
     bulkFileCopyActions.AddRange(actions.Where(a => a.Action.SafeEquals("CopyFiles", ignoreCase: true)).Select(a => new ModAction <CopyFilesAction>(mod, a as CopyFilesAction)));
 }
Ejemplo n.º 8
0
        private void DeleteFile_Internal(string targetPath, GameModification mod)
        {
            if (IsReservedFile(targetPath))
            {
                modifications.Add(new DeleteFileModification(targetPath, true, mod.Config.ModID));
                BackupFile(targetPath);
            }
            else
            {
                modifications.Add(new DeleteFileModification(targetPath, false, mod.Config.ModID));
            }

            File.Delete(targetPath);
        }
Ejemplo n.º 9
0
 public ModActionCollection CreateFilteredCollection(GameModification mod, bool filterOut = false)
 {
     return(new ModActionCollection()
     {
         extractActions = extractActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         decompileActions = decompileActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         fileMoveActions = fileMoveActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         bulkFileMoveActions = bulkFileMoveActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         fileDeleteActions = fileDeleteActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         fileWriteActions = fileWriteActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         fileReplaceActions = fileReplaceActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         bulkFileReplaceActions = bulkFileReplaceActions.Where(a => Filter(a, mod, filterOut)).ToList(),
         fileCopyActions = fileCopyActions.Where(a => Filter(a, mod, filterOut)).ToList()
     });
 }
Ejemplo n.º 10
0
        public void CheckFileMoveWithMove_SameTarget()
        {
            var actions = new List <FileModification>()
            {
                new MoveFileModification(exampleFile1, exampleDestination1, false, "Test.Move")
            };

            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Move2"
                }
            };
            bool hasCollision = ModCollisionTracker.HasMoveCollision(mod, exampleFile1, exampleDestination1, actions, out var collision);

            Assert.AreEqual(false, hasCollision);
        }
Ejemplo n.º 11
0
        public void CheckFileReplaceWithReplace_SameData()
        {
            var actions = new List <FileModification>()
            {
                new ReplaceFileModification(exampleDestination1, false, "Test.Replace1")
            };

            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Replace2"
                }
            };
            bool hasCollision = ModCollisionTracker.HasReplaceCollision(mod, exampleFile1, exampleDestination3_exampleDestination1, actions, out var collision);

            Assert.AreEqual(false, hasCollision);
        }
Ejemplo n.º 12
0
        public void CheckFileMoveWithAdd_DiffDest()
        {
            var actions = new List <FileModification>()
            {
                new AddFileModification(exampleFile2, false, "Test.Add")
            };

            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Move"
                }
            };
            bool hasCollision = ModCollisionTracker.HasMoveCollision(mod, exampleFile3, exampleFile1, actions, out var collision);

            Assert.AreEqual(false, hasCollision);
        }
Ejemplo n.º 13
0
        public static string ResolvePath(string path, GameModification mod, Configuration config)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(null);
            }

            if (path.StartsWith("[GAME]", StringComparison.InvariantCultureIgnoreCase))
            {
                return(ResolveGamePath(path, config));
            }

            if (path.StartsWith("[MOD]", StringComparison.InvariantCultureIgnoreCase))
            {
                return(ResolveModPath(path, mod));
            }

            throw new Exception("Supplied path must begin with the following: [GAME], [MOD]");
        }
Ejemplo n.º 14
0
        public void CheckFileReplaceWithReplace_DifferentData()
        {
            var actions = new List <FileModification>()
            {
                new ReplaceFileModification(exampleFile1, false, "Test.Replace1")
            };

            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Replace2"
                }
            };
            bool hasCollision = ModCollisionTracker.HasReplaceCollision(mod, exampleFile1, testFile2, actions, out var collision);

            Assert.AreEqual(true, hasCollision);
            Assert.AreEqual(collision.severity, ModCollisionSeverity.Clash);
            Assert.AreEqual(collision.modID, "Test.Replace1");
            Assert.IsTrue(collision.description.Contains("Attempting to replace a file that has been replaced by another mod (with different data)"), $"Actual: {collision.description}");
        }
Ejemplo n.º 15
0
        public void CheckFileReplaceWithMove()
        {
            var actions = new List <FileModification>()
            {
                new MoveFileModification(exampleFile1, "C:\\Example\\ExampleFile.txt", false, "Test.Move")
            };

            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Replace"
                }
            };
            bool hasCollision = ModCollisionTracker.HasReplaceCollision(mod, exampleFile1, exampleFile2, actions, out var collision);

            Assert.AreEqual(true, hasCollision);
            Assert.AreEqual(collision.severity, ModCollisionSeverity.Clash);
            Assert.AreEqual(collision.modID, "Test.Move");
            Assert.IsTrue(collision.description.Contains("Attempting to replace a file that has been moved by another mod"), $"Actual: {collision.description}");
        }
Ejemplo n.º 16
0
        public void CheckFileMoveWithAdd_SameDest()
        {
            var actions = new List <FileModification>()
            {
                new AddFileModification(exampleFile1, false, "Test.Add")
            };

            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Move"
                }
            };
            bool hasCollision = ModCollisionTracker.HasMoveCollision(mod, exampleFile2, exampleFile1, actions, out var collision);

            Assert.AreEqual(true, hasCollision);
            Assert.AreEqual(collision.severity, ModCollisionSeverity.Clash);
            Assert.AreEqual(collision.modID, "Test.Add");
            Assert.IsTrue(collision.description.Contains("Attempting to move a file to a destination that has been modified by another mod (with different data)"), $"Actual: {collision.description}");
        }
Ejemplo n.º 17
0
        public void CheckFileMoveWithWrite()
        {
            var actions = new List <FileModification>()
            {
                new EditFileModification(exampleFile1, false, "Test.Edit")
            };

            var mod = new GameModification()
            {
                Config = new Data.BaseModConfiguration()
                {
                    ModID = "Test.Move2"
                }
            };
            bool hasCollision = ModCollisionTracker.HasMoveCollision(mod, exampleFile1, exampleDestination1, actions, out var collision);

            Assert.AreEqual(true, hasCollision);
            Assert.AreEqual(collision.severity, ModCollisionSeverity.Clash);
            Assert.AreEqual(collision.modID, "Test.Edit");
            Assert.IsTrue(collision.description.Contains("Attempting to move a file that has been written to by another mod"), $"Actual: {collision.description}");
        }
Ejemplo n.º 18
0
        public static bool HasCopyCollision(GameModification currentMod, string file, string destinationPath, List <FileModification> modifications, out ModCollision collision)
        {
            var actions            = new ActionCollection(file, currentMod.Config.ModID, modifications);
            var destinationActions = new ActionCollection(destinationPath, currentMod.Config.ModID, modifications);

            if (actions.moveAction != null && destinationPath != (actions.moveAction as MoveFileModification).DestinationPath)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Copy, FileModificationType.Moved, actions.moveAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.replaceAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Copy, FileModificationType.Replaced, actions.replaceAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.editAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Copy, FileModificationType.Edited, actions.editAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (actions.deleteAction != null)
            {
                return(AddModCollision(currentMod, ModInstallActionEnum.Copy, FileModificationType.Deleted, actions.deleteAction.ModID, ModCollisionSeverity.Clash, out collision));
            }

            if (destinationActions.lastAction != null && !(new[] { FileModificationType.Moved, FileModificationType.Deleted }).Contains(destinationActions.lastAction.Type))
            {
                if (MD5Utility.CalculateMD5Hash(file) != MD5Utility.CalculateMD5Hash(destinationPath))
                {
                    string modPrefix = $"Mod collision detected while installing mod ({currentMod.Config.ModID})";
                    collision = new ModCollision(currentMod.Config.ModID, ModCollisionSeverity.Clash, $"{modPrefix}: Attempting to copy a file to a destination that has been modified by another mod (with different data) (conflicting mod: {destinationActions.lastAction.ModID})");
                    return(true);
                }
            }

            collision = null;
            return(false);
        }
Ejemplo n.º 19
0
        private InstallationStatus ReplaceFile(string replacementFile, string targetFile, GameModification mod)
        {
            if (ModCollisionTracker.HasReplaceCollision(mod, targetFile, replacementFile, modifications, out var collision))
            {
                return(HandleCollision(collision));
            }

            if (!File.Exists(targetFile))
            {
                throw new Exception($"Unable to find target path: {targetFile}");
            }

            CopyFile_Internal(replacementFile, targetFile, mod);
            return(InstallationStatus.Success);
        }
Ejemplo n.º 20
0
        public void AddActionsFromMod(GameModification mod)
        {
            var installActions = (mod.Config.InstallActions ?? new ModInstallAction[] { });

            AddActions(mod, installActions);
        }
Ejemplo n.º 21
0
 public ModAction(GameModification mod, T action)
 {
     this.mod    = mod;
     this.action = action;
 }
Ejemplo n.º 22
0
 public static string ResolveModPath(string path, GameModification mod)
 {
     return(Path.Combine(mod.Config.ModCachePath, path.Substring(5, path.Length - 5).TrimStart('\\').TrimStart('/')));
 }
Ejemplo n.º 23
0
        private InstallationStatus MoveFile(string targetFile, string destinationPath, GameModification mod)
        {
            // Have we already moved this file to the exact same destination?
            if (HasMovedFileToSameDestination(targetFile, destinationPath))
            {
                return(InstallationStatus.Success);
            }

            if (ModCollisionTracker.HasMoveCollision(mod, targetFile, destinationPath, modifications, out var collision))
            {
                return(HandleCollision(collision));
            }

            if (!File.Exists(targetFile))
            {
                throw new Exception($"Unable to find target path: {targetFile}");
            }

            MoveFile_Internal(targetFile, destinationPath, mod);
            return(InstallationStatus.Success);
        }
Ejemplo n.º 24
0
        private static bool AddModCollision(GameModification mod, string actionDescription, string collisionReasonDescription, string collidingModID, ModCollisionSeverity severity, out ModCollision collision, string suffix = "")
        {
            string modPrefix = $"Mod collision detected while installing mod ({mod.Config.ModID})";

            collision = new ModCollision(collidingModID, severity, $"{modPrefix}: Attempting to {actionDescription} that has been {collisionReasonDescription} another mod{(string.IsNullOrEmpty(suffix) ? "" : $" {suffix}")} (conflicting mod: {collidingModID})");
Ejemplo n.º 25
0
 private bool Filter <TAction>(ModAction <TAction> action, GameModification mod, bool filterOut = false)
 {
     return(filterOut ? !action.mod.Equals(mod) : action.mod.Equals(mod));
 }
Ejemplo n.º 26
0
        private InstallationStatus CopyFile(string targetFile, string destinationPath, GameModification mod)
        {
            if (ModCollisionTracker.HasCopyCollision(mod, targetFile, destinationPath, modifications, out var collision))
            {
                return(HandleCollision(collision));
            }

            if (!File.Exists(targetFile))
            {
                throw new Exception($"Unable to find target path: {targetFile}");
            }

            // Copying files occurs near the start, and should not cause conflicts

            CopyFile_Internal(targetFile, destinationPath, mod);
            return(InstallationStatus.Success);
        }