diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs
index cc7239ce..c97998dd 100644
--- a/SabreTools.Library/DatFiles/DatFile.cs
+++ b/SabreTools.Library/DatFiles/DatFile.cs
@@ -1581,8 +1581,9 @@ namespace SabreTools.Library.DatFiles
/// True to allow SL DATs to have game names used instead of descriptions, false otherwise (default)
/// Filter object to be passed to the DatItem level
/// Type of the split that should be performed (split, merged, fully merged)
+ /// True if hashes should be updated along with names, false otherwise [Only for base replacement]
public void DetermineUpdateType(List inputPaths, List basePaths, string outDir, UpdateMode updateMode, bool inplace, bool skip,
- bool bare, bool clean, bool remUnicode, bool descAsName, Filter filter, SplitType splitType)
+ bool bare, bool clean, bool remUnicode, bool descAsName, Filter filter, SplitType splitType, bool updateHashes)
{
// Ensure we only have files in the inputs
List inputFileNames = Utilities.GetOnlyFilesFromInputs(inputPaths, appendparent: true);
@@ -1636,7 +1637,7 @@ namespace SabreTools.Library.DatFiles
else if ((updateMode & UpdateMode.BaseReplace) != 0
|| (updateMode & UpdateMode.ReverseBaseReplace) != 0)
{
- BaseReplace(inputFileNames, baseFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType);
+ BaseReplace(inputFileNames, baseFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType, updateHashes);
}
return;
@@ -1718,8 +1719,9 @@ namespace SabreTools.Library.DatFiles
/// True if we are supposed to trim names to NTFS length, false otherwise
/// True if all games should be replaced by '!', false otherwise
/// String representing root directory to compare against for length calculation
+ /// True if hashes should be updated along with names, false otherwise
public void BaseReplace(List inputFileNames, List baseFileNames, string outDir, bool inplace, bool clean, bool remUnicode,
- bool descAsName, Filter filter, SplitType splitType)
+ bool descAsName, Filter filter, SplitType splitType, bool updateHashes)
{
// First we want to parse all of the base DATs into the input
InternalStopwatch watch = new InternalStopwatch("Populating base DAT for replacement...");
@@ -1769,6 +1771,67 @@ namespace SabreTools.Library.DatFiles
if (dupes.Count > 0)
{
newDatItem.Name = dupes[0].Name;
+
+ // If we're updating hashes too, only replace if the current item doesn't have them
+ if (updateHashes)
+ {
+ if (newDatItem.Type == ItemType.Rom)
+ {
+ Rom newRomItem = (Rom)newDatItem;
+ if (String.IsNullOrEmpty(newRomItem.CRC) && !String.IsNullOrEmpty(((Rom)dupes[0]).CRC))
+ {
+ newRomItem.CRC = ((Rom)dupes[0]).CRC;
+ }
+ if (String.IsNullOrEmpty(newRomItem.MD5) && !String.IsNullOrEmpty(((Rom)dupes[0]).MD5))
+ {
+ newRomItem.MD5 = ((Rom)dupes[0]).MD5;
+ }
+ if (String.IsNullOrEmpty(newRomItem.SHA1) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA1))
+ {
+ newRomItem.SHA1 = ((Rom)dupes[0]).SHA1;
+ }
+ if (String.IsNullOrEmpty(newRomItem.SHA256) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA256))
+ {
+ newRomItem.SHA256 = ((Rom)dupes[0]).SHA256;
+ }
+ if (String.IsNullOrEmpty(newRomItem.SHA384) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA384))
+ {
+ newRomItem.SHA384 = ((Rom)dupes[0]).SHA384;
+ }
+ if (String.IsNullOrEmpty(newRomItem.SHA512) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA512))
+ {
+ newRomItem.SHA512 = ((Rom)dupes[0]).SHA512;
+ }
+
+ newDatItem = (Rom)newRomItem.Clone();
+ }
+ else if (newDatItem.Type == ItemType.Disk)
+ {
+ Disk newDiskItem = (Disk)newDatItem;
+ if (String.IsNullOrEmpty(newDiskItem.MD5) && !String.IsNullOrEmpty(((Rom)dupes[0]).MD5))
+ {
+ newDiskItem.MD5 = ((Rom)dupes[0]).MD5;
+ }
+ if (String.IsNullOrEmpty(newDiskItem.SHA1) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA1))
+ {
+ newDiskItem.SHA1 = ((Rom)dupes[0]).SHA1;
+ }
+ if (String.IsNullOrEmpty(newDiskItem.SHA256) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA256))
+ {
+ newDiskItem.SHA256 = ((Rom)dupes[0]).SHA256;
+ }
+ if (String.IsNullOrEmpty(newDiskItem.SHA384) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA384))
+ {
+ newDiskItem.SHA384 = ((Rom)dupes[0]).SHA384;
+ }
+ if (String.IsNullOrEmpty(newDiskItem.SHA512) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA512))
+ {
+ newDiskItem.SHA512 = ((Rom)dupes[0]).SHA512;
+ }
+
+ newDatItem = (Disk)newDiskItem.Clone();
+ }
+ }
}
newDatItems.Add(newDatItem);
diff --git a/SabreTools.Library/README.1ST b/SabreTools.Library/README.1ST
index 424ae8d2..7eb58ce2 100644
--- a/SabreTools.Library/README.1ST
+++ b/SabreTools.Library/README.1ST
@@ -1154,6 +1154,10 @@ Options:
-bd=, --base-dat= Add a base DAT for replacing
Add a DAT or folder of DATs to the base set to be used in
item name replacement
+
+ -uh, --update-hashes Update hashes along with the names
+ By default, only names are updated during the replacement. This
+ flag also allows updating of missing hashes at the same time.
-gn=, --not-game= Filter by game name
-ngn=, --game-name= Exclude by game name
diff --git a/SabreTools/SabreTools.Help.cs b/SabreTools/SabreTools.Help.cs
index d0d10e63..8fa26fde 100644
--- a/SabreTools/SabreTools.Help.cs
+++ b/SabreTools/SabreTools.Help.cs
@@ -1270,6 +1270,11 @@ namespace SabreTools
"Add a base DAT for replacing",
FeatureType.List,
null));
+ update["base-name"].AddFeature("update-hashes", new Feature(
+ new List() { "-uh", "--update-hashes" },
+ "Update hashes along with the names",
+ FeatureType.Flag,
+ null));
update.AddFeature("reverse-base-name", new Feature(
new List() { "-rbn", "--reverse-base-name" },
"Replace item names from base DATs in reverse",
@@ -1280,6 +1285,11 @@ namespace SabreTools
"Add a base DAT for replacing",
FeatureType.List,
null));
+ update["reverse-base-name"].AddFeature("update-hashes", new Feature(
+ new List() { "-uh", "--update-hashes" },
+ "Update hashes along with the names",
+ FeatureType.Flag,
+ null));
update.AddFeature("game-name", new Feature(
new List() { "-gn", "--game-name" },
"Filter by game name",
diff --git a/SabreTools/SabreTools.Inits.cs b/SabreTools/SabreTools.Inits.cs
index 0cbbf83f..545d067b 100644
--- a/SabreTools/SabreTools.Inits.cs
+++ b/SabreTools/SabreTools.Inits.cs
@@ -233,6 +233,7 @@ namespace SabreTools
/// True to clean the game names to WoD standard, false otherwise (default)
/// True if we should remove non-ASCII characters from output, false otherwise (default)
/// True if descriptions should be used as names, false otherwise (default)
+ /// True if hashes should be updated along with names, false otherwise [Only for base replacement]
private static void InitUpdate(
List inputPaths,
List basePaths,
@@ -254,7 +255,8 @@ namespace SabreTools
string outDir,
bool clean,
bool remUnicode,
- bool descAsName)
+ bool descAsName,
+ bool updateHashes)
{
// Normalize the extensions
datHeader.AddExtension = (datHeader.AddExtension == "" || datHeader.AddExtension.StartsWith(".")
@@ -302,7 +304,7 @@ namespace SabreTools
DatFile userInputDat = new DatFile(datHeader);
userInputDat.DetermineUpdateType(inputPaths, basePaths, outDir, updateMode, inplace, skip, bare, clean,
- remUnicode, descAsName, filter, splitType);
+ remUnicode, descAsName, filter, splitType, updateHashes);
}
///
diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs
index 9d914d3b..60cd7595 100644
--- a/SabreTools/SabreTools.cs
+++ b/SabreTools/SabreTools.cs
@@ -93,7 +93,8 @@ namespace SabreTools
showNodumpColumn = false,
shortname = false,
skip = false,
- updateDat = false;
+ updateDat = false,
+ updateHashes = false;
Hash omitFromScan = Hash.DeepHashes; // TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually
OutputFormat outputFormat = OutputFormat.Folder;
SkipFileType skipFileType = SkipFileType.None;
@@ -487,6 +488,9 @@ namespace SabreTools
case "update-dat":
updateDat = true;
break;
+ case "update-hashes":
+ updateHashes = true;
+ break;
case "exclude-of":
datHeader.ExcludeOf = true;
break;
@@ -716,7 +720,7 @@ namespace SabreTools
case "Update":
VerifyInputs(inputs, feature);
InitUpdate(inputs, basePaths, datHeader, updateMode, inplace, skip, removeDateFromAutomaticName, filter,
- splitType, outDir, cleanGameNames, removeUnicode, descAsName);
+ splitType, outDir, cleanGameNames, removeUnicode, descAsName, updateHashes);
break;
// If we're using the verifier
case "Verify":