Пример #1
0
        private static void Main(string[] args)
        {
            const string errorMsg0 = "Can't access {0} path, please specify it on the xml settings...";

            if (string.IsNullOrEmpty(Settings.FO2Path) || !Directory.Exists(Settings.FO2Path))
            {
                ShowError(string.Format(errorMsg0, "FlatOut 2"));
                return;
            }

            if (string.IsNullOrEmpty(Settings.PatchFilePath) || !File.Exists(Settings.PatchFilePath))
            {
                ShowError(string.Format(errorMsg0, "patch"));
                return;
            }

            if (string.IsNullOrEmpty(Settings.BFS2PackPath) || !File.Exists(Settings.BFS2PackPath))
            {
                ShowError(string.Format(errorMsg0, "BFS2Pack"));
                return;
            }

            if (Path.GetExtension(Settings.BFS2PackPath).ToLowerInvariant() != ".exe")
            {
                ShowError("BFS2Pack isn't a executable...");
                return;
            }

            if (!Directory.Exists(TempFolder))
            {
                Directory.CreateDirectory(TempFolder);
            }

            if (!Directory.Exists(DataFolder))
            {
                ShowError("Can't access data folder, please check that FO2 contains one...");
                return;
            }

            string[] lines = File.ReadAllLines(Settings.PatchFilePath);

            var bfsFiles   = lines.Select(line => Path.Combine(Path.GetDirectoryName(Settings.PatchFilePath), line));
            var bfsFolders = bfsFiles.Select(line => GetActualTempFolder(TempFolder, line));
            var bfsDict    = bfsFolders.Select(folder => new { Folder = folder, Files = GetFolderFiles(folder), ConflictingFiles = GetConflictingFiles(folder) })
                             .ToDictionary(t => t.Folder + "\\", t => new Tuple <List <string>, List <string> >(t.Files, t.ConflictingFiles));
            var _allFiles = bfsFolders.Select(file => GetFolderFiles(file, false).AsEnumerable()).Select(x => x).Distinct().ToList();

            string origJson = Path.Combine(TempFolder, "origFiles.json");

            if (!File.Exists(origJson))
            {
                AllOrigFiles = new HashSet <string>(GetFolderFiles(DataFolder, false));
                File.WriteAllText(origJson, JsonConvert.SerializeObject(AllOrigFiles, Formatting.Indented));
            }
            else
            {
                AllOrigFiles = JsonConvert.DeserializeObject <HashSet <string> >(File.ReadAllText(origJson));
            }

            CarIds = new HashSet <int>(AllOrigFiles.Where(file => file.ToLowerInvariant().Contains(CarHandle))
                                       .Select(file => GetCarIdFromPath(file, CarHandle)));

            string dictJson = Path.Combine(TempFolder, "dict.json");

            File.WriteAllText(dictJson, JsonConvert.SerializeObject(bfsDict, Formatting.Indented));

            string allFilesJson = Path.Combine(TempFolder, "files.json");

            File.WriteAllText(allFilesJson, JsonConvert.SerializeObject(_allFiles, Formatting.Indented));

            Console.Write("Do you wish to make a restore? [y/N]: ");
            if (Console.ReadLine().ToLowerInvariant() == "y")
            {
                const string backupString = ".backup0";

                var allFiles      = Directory.GetFiles(DataFolder, "*.*", SearchOption.AllDirectories);
                var _allDataFiles = bfsFolders.Select(file => DataFolder + "\\" + GetFolderFiles(file).AsEnumerable()).Select(x => x).Distinct().ToList();

                var backupFiles = allFiles
                                  .Where(file => Path.GetExtension(file)?.ToLowerInvariant() == backupString);

                var jsonFiles = allFiles
                                .Where(file => Path.GetExtension(file)?.ToLowerInvariant() == ".json");

                int index      = 0;
                int totalCount = backupFiles.Count() + jsonFiles.Count();

                foreach (var backupFile in backupFiles)
                {
                    if (!File.Exists(backupFile))
                    {
                        Console.WriteLine($"[{GetPerc(index, totalCount)}] File doesn't exists! ({backupFile})", Color.Red);

                        ++index;
                        continue;
                    }

                    string origFile = backupFile.Replace(backupString, string.Empty);

                    if (File.Exists(origFile))
                    {
                        File.Delete(origFile);
                    }
                    else
                    {
                        Console.WriteLine($"[{GetPerc(index, totalCount)}] Couldn't delete modified file '{origFile}'...", Color.Yellow);
                    }

                    File.Move(backupFile, origFile);
                    ++index;
                }

                foreach (var jsonFile in jsonFiles)
                {
                    Console.WriteLine($"[{GetPerc(index, totalCount)}] Deleted json file: {jsonFile}...", PromptColor);

                    File.Delete(jsonFile);
                    ++index;
                }

                // Delete rest of files
                var aBackupFiles = allFiles
                                   .Where(file => Path.GetExtension(file)?.ToLowerInvariant().Contains(".backup") == true);

                int aIndex      = 0;
                int aTotalCount = aBackupFiles.Count();

                foreach (var aBackupFile in aBackupFiles)
                {
                    Console.WriteLine($"[{GetPerc(aIndex, aTotalCount)}] Deleted backup file: {aBackupFile}...", PromptColor);

                    File.Delete(aBackupFile);
                    ++index;
                }

                foreach (var moddedFile in _allDataFiles)
                {
                    if (AllOrigFiles.Contains(moddedFile))
                    {
                        continue;
                    }

                    Console.WriteLine($"Deleted modded file: {moddedFile}...", PromptColor);
                    File.Delete(moddedFile);
                }
            }
            WriteSeparator();
            {
                int   index      = 0;
                int   totalCount = bfsFiles.Count();
                float delta      = 1f / totalCount;

                foreach (var bfsFile in bfsFiles)
                {
                    if (!File.Exists(bfsFile) || Path.GetExtension(bfsFile).ToLowerInvariant() != ".bfs")
                    {
                        ++index;
                        continue;
                    }

                    string actualTempPath = GetActualTempFolder(TempFolder, bfsFile) + "\\";

                    if (!Directory.Exists(actualTempPath))
                    {
                        Directory.CreateDirectory(actualTempPath);
                        CreateProcess(Settings.BFS2PackPath, $"x {bfsFile} -v", actualTempPath);
                    }

                    var inFiles = bfsDict[actualTempPath].Item1;

                    const string backupFilename = "backup-database.json";
                    const string backupSufix    = "backup";

                    Dictionary <string, List <Tuple <int, string> > > currentDictionary;

                    int subindex = 0;

                    foreach (var inFile in inFiles)
                    {
                        string realFile = Path.Combine(actualTempPath, inFile);
                        string replFile = Path.Combine(Settings.FO2Path, inFile);

                        bool diffMD5 = CalculateMD5(realFile) != CalculateMD5(replFile);

                        if (!diffMD5)
                        {
                            Console.WriteLine($"Skipping same file... ({realFile} => {replFile})", Color.Yellow);

                            ++subindex;
                            continue;
                        }

                        bool exists = File.Exists(replFile) && diffMD5;
                        if (exists)
                        {
                            string folder   = Path.GetDirectoryName(replFile);
                            string database = Path.Combine(folder, backupFilename);

                            // Get number of ocurrences
                            int ocurrences = Directory
                                             .GetFiles(folder, $"{Path.GetFileNameWithoutExtension(replFile)}.*", SearchOption.TopDirectoryOnly)
                                             .Count(file => Path.GetExtension(file).ToLowerInvariant().Contains(".backup"));

                            // Based on the number of backups then create *.backup(XX) files... *.backup0 will be always the original file
                            File.Move(replFile, replFile + $".{backupSufix}{ocurrences}");

                            string fileName = Path.GetFileName(replFile);

                            // Load current dictionary...
                            currentDictionary =
                                File.Exists(database) ? JsonConvert.DeserializeObject <Dictionary <string, List <Tuple <int, string> > > >(
                                    File.ReadAllText(database)) : new Dictionary <string, List <Tuple <int, string> > >();

                            bool save = false;

                            // Map the ocurrence with the folder where it comes from...
                            if (!currentDictionary.ContainsKey(fileName))
                            {
                                var list = new List <Tuple <int, string> >(); // ocurrences = 0, in this scope
                                list.Add(new Tuple <int, string>(ocurrences, actualTempPath));

                                currentDictionary.Add(fileName, list);
                                save = true;
                            }
                            else
                            {
                                var list = currentDictionary[fileName];
                                if (list.Count < ocurrences)
                                {
                                    list.Add(new Tuple <int, string>(ocurrences, actualTempPath));
                                    save = true;
                                }
                            }

                            // If any changes made...
                            if (save)
                            {
                                File.WriteAllText(database,
                                                  JsonConvert.SerializeObject(currentDictionary, Formatting.Indented));
                            }
                        }

                        if (!File.Exists(realFile))
                        {
                            Console.WriteLine($"Can't find file '{realFile}'...", Color.Yellow);
                            continue;
                        }

                        string resolvedFile = ResolveCarConflict(replFile, realFile);
                        string replFolder   = Path.GetDirectoryName(resolvedFile);

                        if (!Directory.Exists(replFolder))
                        {
                            Directory.CreateDirectory(replFolder);
                        }

                        File.Copy(realFile, resolvedFile);

                        string subPerc = GetPerc(subindex, inFiles.Count, out float subPercValue);
                        string perc    = $"[{(float)index / totalCount + delta * subPercValue:F2} %]"; // GetPerc(index, totalCount);

                        Console.WriteLine($"[{subPerc} (Total: {perc})] Moving file {subindex}: {Path.GetFileName(realFile)}...{(exists ? " [REPLACING...]" : string.Empty)}");

                        ++subindex;
                    }

                    ++index;
                    WriteSeparator();
                }
            }

            Console.WriteLine($"{bfsDict.Values.Sum(v => v.Item2.Count)} total intersections...");
            Console.WriteLine("Completed!", Color.LimeGreen);
            AnyKeyToExit();
        }
Пример #2
0
        private static string ResolveCarConflict(string fileName, string fromFileName)
        {
            const string idGroupName = "ID";
            string       carHandle0  = $@"car_(?<{idGroupName}>(\d+))";
            string       carHandle1  = $@"car(?<{idGroupName}>(\d+))";

            bool match0 = Regex.IsMatch(fromFileName, carHandle0);
            bool match1 = Regex.IsMatch(fromFileName, carHandle1);

            // !fileName.ToLowerInvariant().Contains(carHandle) || !fileName.All(char.IsDigit)
            if (!(match0 || match1))
            {
                return(fileName);
            }

            int id = -1;

            if (match0)
            {
                id = int.Parse(Regex.Match(fromFileName, carHandle0).Groups[idGroupName].Value);
            }
            else if (match1)
            {
                id = int.Parse(Regex.Match(fromFileName, carHandle1).Groups[idGroupName].Value);
            }

            if (id == -1)
            {
                return(fileName);
            }

            // Has conflict?
            if (AllOrigFiles.Any(file => file.Contains(GetDataSubString(file, DataLiteral))))
            {
                int freeId;

                bool containsId   = MappedConflicts.ContainsKey(id);
                bool containsPath = MappedConflictsPath.ContainsKey(fileName);

                if (!containsId || !containsPath)
                {
                    freeId = CarIds.Min() + 1;
                    CarIds.Add(freeId);

                    MappedConflicts.Add(id, freeId);
                    MappedConflictsPath.Add(fileName, freeId);
                }
                else if (!containsId && containsPath)
                {
                    // TODO
                }
                else if (containsId && !containsPath)
                {
                    // TODO
                }
                else
                {
                    freeId = MappedConflicts[id];
                }

                return(fileName.Replace(id.ToString(), freeId.ToString()));
            }

            return(fileName);
        }