diff --git a/SabreTools/Features/Update.cs b/SabreTools/Features/Update.cs index 99499370..7cf94608 100644 --- a/SabreTools/Features/Update.cs +++ b/SabreTools/Features/Update.cs @@ -103,43 +103,7 @@ namespace SabreTools.Features : $".{Modifiers.ReplaceExtension}"; // If we're in a non-replacement special update mode and the names aren't set, set defaults - if (updateMode != 0 -#if NET20 || NET35 - && !(((updateMode & UpdateMode.DiffAgainst) != 0) || ((updateMode & UpdateMode.BaseReplace) != 0))) -#else - && !(updateMode.HasFlag(UpdateMode.DiffAgainst) || updateMode.HasFlag(UpdateMode.BaseReplace))) -#endif - { - // Get the values that will be used - if (string.IsNullOrEmpty(Header!.GetStringFieldValue(Models.Metadata.Header.DateKey))) - Header.SetFieldValue(Models.Metadata.Header.DateKey, DateTime.Now.ToString("yyyy-MM-dd")); - - if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.NameKey))) - { - Header.SetFieldValue(Models.Metadata.Header.NameKey, (updateMode != 0 ? "DiffDAT" : "MergeDAT") - + (Header.GetStringFieldValue(Models.Metadata.Header.TypeKey) == "SuperDAT" ? "-SuperDAT" : string.Empty) - + (Cleaner!.DedupeRoms != DedupeType.None ? "-deduped" : string.Empty)); - } - - if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey))) - { - Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, (updateMode != 0 ? "DiffDAT" : "MergeDAT") - + (Header.GetStringFieldValue(Models.Metadata.Header.TypeKey) == "SuperDAT" ? "-SuperDAT" : string.Empty) - + (Cleaner!.DedupeRoms != DedupeType.None ? " - deduped" : string.Empty)); - - if (!GetBoolean(features, NoAutomaticDateValue)) - Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, $"{Header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey)} ({Header.GetStringFieldValue(Models.Metadata.Header.DateKey)})"); - } - - if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.CategoryKey)) && updateMode != 0) - Header.SetFieldValue(Models.Metadata.Header.CategoryKey, "DiffDAT"); - - if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.AuthorKey))) - Header.SetFieldValue(Models.Metadata.Header.AuthorKey, $"SabreTools {Globals.Version}"); - - if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.CommentKey))) - Header.SetFieldValue(Models.Metadata.Header.CommentKey, $"Generated by SabreTools {Globals.Version}"); - } + SetDefaultHeaderValues(updateMode, GetBoolean(features, NoAutomaticDateValue)); // If no update fields are set, default to Names if (updateItemFieldNames == null || updateItemFieldNames.Count == 0) @@ -158,52 +122,7 @@ namespace SabreTools.Features // If we're in standard update mode, run through all of the inputs if (updateMode == UpdateMode.None) { - // Loop through each input and update -#if NET452_OR_GREATER || NETCOREAPP - Parallel.ForEach(inputPaths, Core.Globals.ParallelOptions, inputPath => -#elif NET40_OR_GREATER - Parallel.ForEach(inputPaths, inputPath => -#else - foreach (var inputPath in inputPaths) -#endif - { - // Create a new base DatFile - DatFile datFile = DatFileTool.CreateDatFile(Header!, Modifiers); - _logger.User($"Processing '{Path.GetFileName(inputPath.CurrentPath)}'"); - - // Check the current format - DatFormat currentFormat = datFile.Header.GetFieldValue(DatHeader.DatFormatKey); -#if NET20 || NET35 - bool isSeparatedFile = (currentFormat & DatFormat.CSV) != 0 - || (currentFormat & DatFormat.SSV) != 0 - || (currentFormat & DatFormat.TSV) != 0; -#else - bool isSeparatedFile = currentFormat.HasFlag(DatFormat.CSV) - || currentFormat.HasFlag(DatFormat.SSV) - || currentFormat.HasFlag(DatFormat.TSV); -#endif - - Parser.ParseInto(datFile, inputPath.CurrentPath, keep: true, keepext: isSeparatedFile); - - // Perform additional processing steps - Extras!.ApplyExtras(datFile); - Extras!.ApplyExtrasDB(datFile); - Splitter!.ApplySplitting(datFile, useTags: false); - datFile.ExecuteFilters(FilterRunner!); - Cleaner!.ApplyCleaning(datFile); - Remover!.ApplyRemovals(datFile); - - // Get the correct output path - string realOutDir = inputPath.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue))!; - - // Try to output the file, overwriting only if it's not in the current directory - Writer.Write(datFile, realOutDir, overwrite: GetBoolean(features, InplaceValue)); -#if NET40_OR_GREATER || NETCOREAPP - }); -#else - } -#endif - + StandardUpdate(inputPaths, GetBoolean(features, InplaceValue)); return true; } @@ -231,23 +150,10 @@ namespace SabreTools.Features DatFile userInputDat = DatFileTool.CreateDatFile(Header!, Modifiers); // Populate using the correct set - List datHeaders; -#if NET20 || NET35 - if ((updateMode & UpdateMode.DiffAgainst) != 0 || (updateMode & UpdateMode.BaseReplace) != 0) -#else - if (updateMode.HasFlag(UpdateMode.DiffAgainst) || updateMode.HasFlag(UpdateMode.BaseReplace)) -#endif - datHeaders = DatFileTool.PopulateUserData(userInputDat, basePaths); - else - datHeaders = DatFileTool.PopulateUserData(userInputDat, inputPaths); + List datHeaders = GetDatHeaders(updateMode, inputPaths, basePaths, userInputDat); // Perform additional processing steps - Extras!.ApplyExtras(userInputDat); - Extras!.ApplyExtrasDB(userInputDat); - Splitter!.ApplySplitting(userInputDat, useTags: false); - userInputDat.ExecuteFilters(FilterRunner!); - Cleaner!.ApplyCleaning(userInputDat); - Remover!.ApplyRemovals(userInputDat); + AdditionalProcessing(userInputDat); // Output only DatItems that are duplicated across inputs #if NET20 || NET35 @@ -330,16 +236,20 @@ namespace SabreTools.Features for (int j = 0; j < datHeaders.Count; j++) #endif { - // If we're outputting to the runtime folder, rename - if (!GetBoolean(features, InplaceValue) && OutputDir == Environment.CurrentDirectory) - { - string innerpost = $" ({j} - {inputPaths[j].GetNormalizedFileName(true)} Only)"; + // Skip renaming if not outputting to the runtime folder + if (GetBoolean(features, InplaceValue) || OutputDir != Environment.CurrentDirectory) +#if NET40_OR_GREATER || NETCOREAPP + return; +#else + continue; +#endif - datHeaders[j] = userInputDat.Header; - datHeaders[j].SetFieldValue(DatHeader.FileNameKey, datHeaders[j].GetStringFieldValue(DatHeader.FileNameKey) + innerpost); - datHeaders[j].SetFieldValue(Models.Metadata.Header.NameKey, datHeaders[j].GetStringFieldValue(Models.Metadata.Header.NameKey) + innerpost); - datHeaders[j].SetFieldValue(Models.Metadata.Header.DescriptionKey, datHeaders[j].GetStringFieldValue(Models.Metadata.Header.DescriptionKey) + innerpost); - } + // Update the naming for the header + string innerpost = $" ({j} - {inputPaths[j].GetNormalizedFileName(true)} Only)"; + datHeaders[j] = userInputDat.Header; + datHeaders[j].SetFieldValue(DatHeader.FileNameKey, datHeaders[j].GetStringFieldValue(DatHeader.FileNameKey) + innerpost); + datHeaders[j].SetFieldValue(Models.Metadata.Header.NameKey, datHeaders[j].GetStringFieldValue(Models.Metadata.Header.NameKey) + innerpost); + datHeaders[j].SetFieldValue(Models.Metadata.Header.DescriptionKey, datHeaders[j].GetStringFieldValue(Models.Metadata.Header.DescriptionKey) + innerpost); #if NET40_OR_GREATER || NETCOREAPP }); #else @@ -395,12 +305,7 @@ namespace SabreTools.Features Parser.ParseInto(repDat, inputPath.CurrentPath, indexId: 1, keep: true); // Perform additional processing steps - Extras.ApplyExtras(repDat); - Extras.ApplyExtrasDB(repDat); - Splitter.ApplySplitting(repDat, useTags: false); - repDat.ExecuteFilters(FilterRunner!); - Cleaner.ApplyCleaning(repDat); - Remover.ApplyRemovals(repDat); + AdditionalProcessing(repDat); // Now replace the fields from the base DatFile Diffing.Against(userInputDat, repDat, GetBoolean(Features, ByGameValue)); @@ -436,12 +341,7 @@ namespace SabreTools.Features Parser.ParseInto(repDat, inputPath.CurrentPath, indexId: 1, keep: true); // Perform additional processing steps - Extras.ApplyExtras(repDat); - Extras.ApplyExtrasDB(repDat); - Splitter.ApplySplitting(repDat, useTags: false); - repDat.ExecuteFilters(FilterRunner!); - Cleaner.ApplyCleaning(repDat); - Remover.ApplyRemovals(repDat); + AdditionalProcessing(repDat); // Now replace the fields from the base DatFile Replacer.BaseReplace( @@ -482,5 +382,148 @@ namespace SabreTools.Features return true; } + + /// + /// Set default header values for non-specialized update types + /// + /// Update mode that is currently being run + /// True if date should be omitted from the description, false otherwise + private void SetDefaultHeaderValues(UpdateMode updateMode, bool noAutomaticDate) + { + // Skip running if a required object is null + if (Header == null || Cleaner == null) + return; + + // Skip running for diff against and base replacement +#if NET20 || NET35 + if ((updateMode & UpdateMode.DiffAgainst) != 0) + return; + if ((updateMode & UpdateMode.BaseReplace) != 0) + return; +#else + if (updateMode.HasFlag(UpdateMode.DiffAgainst)) + return; + if (updateMode.HasFlag(UpdateMode.BaseReplace)) + return; +#endif + + // Date + if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.DateKey))) + Header.SetFieldValue(Models.Metadata.Header.DateKey, DateTime.Now.ToString("yyyy-MM-dd")); + + // Name + if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.NameKey))) + { + Header.SetFieldValue(Models.Metadata.Header.NameKey, (updateMode != 0 ? "DiffDAT" : "MergeDAT") + + (Header.GetStringFieldValue(Models.Metadata.Header.TypeKey) == "SuperDAT" ? "-SuperDAT" : string.Empty) + + (Cleaner.DedupeRoms != DedupeType.None ? "-deduped" : string.Empty)); + } + + // Description + if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey))) + { + Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, (updateMode != 0 ? "DiffDAT" : "MergeDAT") + + (Header.GetStringFieldValue(Models.Metadata.Header.TypeKey) == "SuperDAT" ? "-SuperDAT" : string.Empty) + + (Cleaner!.DedupeRoms != DedupeType.None ? " - deduped" : string.Empty)); + + if (!noAutomaticDate) + Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, $"{Header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey)} ({Header.GetStringFieldValue(Models.Metadata.Header.DateKey)})"); + } + + // Category + if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.CategoryKey)) && updateMode != 0) + Header.SetFieldValue(Models.Metadata.Header.CategoryKey, "DiffDAT"); + + // Author + if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.AuthorKey))) + Header.SetFieldValue(Models.Metadata.Header.AuthorKey, $"SabreTools {Globals.Version}"); + + // Comment + if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.CommentKey))) + Header.SetFieldValue(Models.Metadata.Header.CommentKey, $"Generated by SabreTools {Globals.Version}"); + } + + /// + /// Perform standard processing and cleaning + /// + /// Set of input paths to process + /// True to output to the input folder, false otherwise + private void StandardUpdate(List inputPaths, bool inplace) + { + // Loop through each input and update +#if NET452_OR_GREATER || NETCOREAPP + Parallel.ForEach(inputPaths, Core.Globals.ParallelOptions, inputPath => +#elif NET40_OR_GREATER + Parallel.ForEach(inputPaths, inputPath => +#else + foreach (var inputPath in inputPaths) +#endif + { + // Create a new base DatFile + DatFile datFile = DatFileTool.CreateDatFile(Header!, Modifiers!); + _logger.User($"Processing '{Path.GetFileName(inputPath.CurrentPath)}'"); + + // Check the current format + DatFormat currentFormat = datFile.Header.GetFieldValue(DatHeader.DatFormatKey); +#if NET20 || NET35 + bool isSeparatedFile = (currentFormat & DatFormat.CSV) != 0 + || (currentFormat & DatFormat.SSV) != 0 + || (currentFormat & DatFormat.TSV) != 0; +#else + bool isSeparatedFile = currentFormat.HasFlag(DatFormat.CSV) + || currentFormat.HasFlag(DatFormat.SSV) + || currentFormat.HasFlag(DatFormat.TSV); +#endif + + Parser.ParseInto(datFile, inputPath.CurrentPath, keep: true, keepext: isSeparatedFile); + + // Perform additional processing steps + AdditionalProcessing(datFile); + + // Get the correct output path + string realOutDir = inputPath.GetOutputPath(OutputDir, inplace)!; + + // Try to output the file, overwriting only if it's not in the current directory + Writer.Write(datFile, realOutDir, overwrite: inplace); +#if NET40_OR_GREATER || NETCOREAPP + }); +#else + } +#endif + } + + /// + /// Get the DatHeader values appopriate for the update mode + /// + /// Update mode that is currently being run + /// Set of input paths + /// Set of base paths + /// DatFile to parse into + /// List of DatHeader values representing the parsed files + private static List GetDatHeaders(UpdateMode updateMode, List inputPaths, List basePaths, DatFile userInputDat) + { +#if NET20 || NET35 + if ((updateMode & UpdateMode.DiffAgainst) != 0 || (updateMode & UpdateMode.BaseReplace) != 0) +#else + if (updateMode.HasFlag(UpdateMode.DiffAgainst) || updateMode.HasFlag(UpdateMode.BaseReplace)) +#endif + return DatFileTool.PopulateUserData(userInputDat, basePaths); + else + return DatFileTool.PopulateUserData(userInputDat, inputPaths); + } + + /// + /// Perform additional processing on a given DatFile + /// + /// DatFile to process + private void AdditionalProcessing(DatFile datFile) + { + Extras!.ApplyExtras(datFile); + Extras!.ApplyExtrasDB(datFile); + Splitter!.ApplySplitting(datFile, useTags: false); + datFile.ExecuteFilters(FilterRunner!); + Cleaner!.ApplyCleaning(datFile); + Remover!.ApplyRemovals(datFile); + } } }