diff --git a/SabreTools.Helper/Data/Build.cs b/SabreTools.Helper/Data/Build.cs index d05b82e3..d126630b 100644 --- a/SabreTools.Helper/Data/Build.cs +++ b/SabreTools.Helper/Data/Build.cs @@ -144,9 +144,11 @@ namespace SabreTools.Helper helptext.Add(" -hs, --hash-split Split a DAT or folder by best-available hashes"); helptext.Add(" -out= Output directory"); helptext.Add(" -st, --stats Get statistics on all input DATs"); + helptext.Add(" -bc, --baddump-col Add baddump stats to output"); helptext.Add(" -csv, --csv Output in Comma-Separated Value format"); helptext.Add(" -f=, --filename= Set the filename for the output"); helptext.Add(" -html, --html Output in HTML format"); + helptext.Add(" -nc, --nodump-col Add nodump stats to output"); helptext.Add(" -si, --single Show individual statistics"); helptext.Add(" -tsv, --tsv Output in Tab-Separated Value format"); helptext.Add(" -ts, --type-split Split a DAT or folder by file types (rom/disk)"); diff --git a/SabreTools.Helper/Objects/Dat/DatFile.cs b/SabreTools.Helper/Objects/Dat/DatFile.cs index 5dc64ca5..6f4a35ba 100644 --- a/SabreTools.Helper/Objects/Dat/DatFile.cs +++ b/SabreTools.Helper/Objects/Dat/DatFile.cs @@ -56,7 +56,8 @@ namespace SabreTools.Helper private long _crcCount; private long _md5Count; private long _sha1Count; - private long _itemStatusCount; + private long _baddumpCount; + private long _nodumpCount; #endregion @@ -257,10 +258,15 @@ namespace SabreTools.Helper get { return _sha1Count; } set { _sha1Count = value; } } + public long BaddumpCount + { + get { return _baddumpCount; } + set { _baddumpCount = value; } + } public long NodumpCount { - get { return _itemStatusCount; } - set { _itemStatusCount = value; } + get { return _nodumpCount; } + set { _nodumpCount = value; } } #endregion @@ -329,7 +335,7 @@ namespace SabreTools.Helper _crcCount = 0; _md5Count = 0; _sha1Count = 0; - _itemStatusCount = 0; + _nodumpCount = 0; } /// @@ -379,7 +385,7 @@ namespace SabreTools.Helper _crcCount = 0; _md5Count = 0; _sha1Count = 0; - _itemStatusCount = 0; + _nodumpCount = 0; } #endregion @@ -508,6 +514,7 @@ namespace SabreTools.Helper CRCCount = this.CRCCount, MD5Count = this.MD5Count, SHA1Count = this.SHA1Count, + BaddumpCount = this.BaddumpCount, NodumpCount = this.NodumpCount, }; } @@ -2888,6 +2895,7 @@ namespace SabreTools.Helper TotalSize += 0; MD5Count += (String.IsNullOrEmpty(((Disk)item).MD5) ? 0 : 1); SHA1Count += (String.IsNullOrEmpty(((Disk)item).SHA1) ? 0 : 1); + BaddumpCount += (((Disk)item).ItemStatus == ItemStatus.BadDump ? 1 : 0); NodumpCount += (((Disk)item).ItemStatus == ItemStatus.Nodump ? 1 : 0); break; case ItemType.Rom: @@ -2899,6 +2907,7 @@ namespace SabreTools.Helper CRCCount += (String.IsNullOrEmpty(((Rom)item).CRC) ? 0 : 1); MD5Count += (String.IsNullOrEmpty(((Rom)item).MD5) ? 0 : 1); SHA1Count += (String.IsNullOrEmpty(((Rom)item).SHA1) ? 0 : 1); + BaddumpCount += (((Rom)item).ItemStatus == ItemStatus.BadDump ? 1 : 0); NodumpCount += (((Rom)item).ItemStatus == ItemStatus.Nodump ? 1 : 0); break; default: @@ -4311,6 +4320,7 @@ namespace SabreTools.Helper CRCCount = 0; MD5Count = 0; SHA1Count = 0; + BaddumpCount = 0; NodumpCount = 0; // If we have a blank Dat in any way, return @@ -4330,6 +4340,18 @@ namespace SabreTools.Helper CRCCount += (String.IsNullOrEmpty(rom.CRC) ? 0 : 1); MD5Count += (String.IsNullOrEmpty(rom.MD5) ? 0 : 1); SHA1Count += (String.IsNullOrEmpty(rom.SHA1) ? 0 : 1); + BaddumpCount += (rom.Type == ItemType.Disk + ? (((Disk)rom).ItemStatus == ItemStatus.BadDump ? 1 : 0) + : (rom.Type == ItemType.Rom + ? (((Rom)rom).ItemStatus == ItemStatus.BadDump ? 1 : 0) + : 0) + ); + NodumpCount += (rom.Type == ItemType.Disk + ? (((Disk)rom).ItemStatus == ItemStatus.Nodump ? 1 : 0) + : (rom.Type == ItemType.Rom + ? (((Rom)rom).ItemStatus == ItemStatus.Nodump ? 1 : 0) + : 0) + ); } } } @@ -4342,7 +4364,9 @@ namespace SabreTools.Helper /// Logger object for file and console writing /// True if numbers should be recalculated for the DAT, false otherwise (default) /// Number of games to use, -1 means recalculate games (default) - public void OutputStats(StreamWriter sw, StatOutputFormat statOutputFormat, Logger logger, bool recalculate = false, long game = -1) + /// True if baddumps should be included in output, false otherwise (default) + /// True if nodumps should be included in output, false otherwise (default) + public void OutputStats(StreamWriter sw, StatOutputFormat statOutputFormat, Logger logger, bool recalculate = false, long game = -1, bool baddumpCol = false, bool nodumpCol = false) { // If we're supposed to recalculate the statistics, do so if (recalculate) @@ -4357,7 +4381,7 @@ namespace SabreTools.Helper } // Log the results to screen - logger.User(@"For '" + FileName + @"': + string results = @"For '" + FileName + @"': -------------------------------------------------- Uncompressed size: " + Style.GetBytesReadable(TotalSize) + @" Games found: " + (game == -1 ? Files.Count : game) + @" @@ -4365,10 +4389,18 @@ namespace SabreTools.Helper Disks found: " + DiskCount + @" Roms with CRC: " + CRCCount + @" Roms with MD5: " + MD5Count + @" - Roms with SHA-1: " + SHA1Count + @" - Roms with Nodump status: " + NodumpCount + @" + Roms with SHA-1: " + SHA1Count + "\n"; -"); + if (baddumpCol) + { + results += " Roms with BadDump status: " + BaddumpCount + "\n"; + } + if (nodumpCol) + { + results += " Roms with Nodump status: " + NodumpCount + "\n"; + } + + logger.User(results); // Now write it out to file as well string line = ""; @@ -4382,8 +4414,18 @@ namespace SabreTools.Helper + "\"" + DiskCount + "\"," + "\"" + CRCCount + "\"," + "\"" + MD5Count + "\"," - + "\"" + SHA1Count + "\"," - + "\"" + NodumpCount + "\"\n"; + + "\"" + SHA1Count + "\""; + + if (baddumpCol) + { + line += ",\"" + BaddumpCount + "\""; + } + if (nodumpCol) + { + line += ",\"" + NodumpCount + "\""; + } + + line += "\n"; break; case StatOutputFormat.HTML: line = "\t\t\t" + HttpUtility.HtmlEncode(FileName) + "" @@ -4393,9 +4435,18 @@ namespace SabreTools.Helper + "" + DiskCount + "" + "" + CRCCount + "" + "" + MD5Count + "" - + "" + SHA1Count + "" - + "" + NodumpCount + "" - + "\n"; + + "" + SHA1Count + ""; + + if (baddumpCol) + { + line += "" + BaddumpCount + ""; + } + if (nodumpCol) + { + line += "" + NodumpCount + ""; + } + + line += "\n"; break; case StatOutputFormat.None: default: @@ -4407,10 +4458,16 @@ namespace SabreTools.Helper Disks found: " + DiskCount + @" Roms with CRC: " + CRCCount + @" Roms with MD5: " + MD5Count + @" - Roms with SHA-1: " + SHA1Count + @" - Roms with Nodump status: " + NodumpCount + @" + Roms with SHA-1: " + SHA1Count + "\n"; -"; + if (baddumpCol) + { + line += " Roms with BadDump status: " + BaddumpCount + "\n"; + } + if (nodumpCol) + { + line += " Roms with Nodump status: " + NodumpCount + "\n"; + } break; case StatOutputFormat.TSV: line = "\"" + FileName + "\"\t" @@ -4420,8 +4477,18 @@ namespace SabreTools.Helper + "\"" + DiskCount + "\"\t" + "\"" + CRCCount + "\"\t" + "\"" + MD5Count + "\"\t" - + "\"" + SHA1Count + "\"\t" - + "\"" + NodumpCount + "\"\n"; + + "\"" + SHA1Count + "\""; + + if (baddumpCol) + { + line += "\t\"" + BaddumpCount + "\""; + } + if (nodumpCol) + { + line += "\t\"" + NodumpCount + "\""; + } + + line += "\n"; break; } @@ -5093,9 +5160,12 @@ namespace SabreTools.Helper /// List of input files and folders /// Name of the output file /// True if single DAT stats are output, false otherwise + /// True if baddumps should be included in output, false otherwise + /// True if nodumps should be included in output, false otherwise /// Set the statistics output format to use /// Logger object for file and console output - public static void OutputStats(List inputs, string reportName, bool single, StatOutputFormat statOutputFormat, Logger logger) + public static void OutputStats(List inputs, string reportName, bool single, bool baddumpCol, + bool nodumpCol, StatOutputFormat statOutputFormat, Logger logger) { reportName += OutputStatsGetExtension(statOutputFormat); StreamWriter sw = new StreamWriter(File.Open(reportName, FileMode.Create, FileAccess.Write)); @@ -5122,7 +5192,7 @@ namespace SabreTools.Helper .ToList(); // Write the header, if any - OutputStatsWriteHeader(sw, statOutputFormat); + OutputStatsWriteHeader(sw, statOutputFormat, baddumpCol, nodumpCol); // Init all total variables long totalSize = 0; @@ -5132,6 +5202,7 @@ namespace SabreTools.Helper long totalCRC = 0; long totalMD5 = 0; long totalSHA1 = 0; + long totalBaddump = 0; long totalNodump = 0; // Init directory-level variables @@ -5143,6 +5214,7 @@ namespace SabreTools.Helper long dirCRC = 0; long dirMD5 = 0; long dirSHA1 = 0; + long dirBaddump = 0; long dirNodump = 0; // Now process each of the input files @@ -5155,7 +5227,7 @@ namespace SabreTools.Helper if (lastdir != null && thisdir != lastdir) { // Output separator if needed - OutputStatsWriteMidSeparator(sw, statOutputFormat); + OutputStatsWriteMidSeparator(sw, statOutputFormat, baddumpCol, nodumpCol); DatFile lastdirdat = new DatFile { @@ -5166,15 +5238,16 @@ namespace SabreTools.Helper CRCCount = dirCRC, MD5Count = dirMD5, SHA1Count = dirSHA1, + BaddumpCount = dirBaddump, NodumpCount = dirNodump, }; - lastdirdat.OutputStats(sw, statOutputFormat, logger, game: dirGame); + lastdirdat.OutputStats(sw, statOutputFormat, logger, game: dirGame, baddumpCol: baddumpCol, nodumpCol: nodumpCol); // Write the mid-footer, if any OutputStatsWriteMidFooter(sw, statOutputFormat); // Write the header, if any - OutputStatsWriteHeader(sw, statOutputFormat); + OutputStatsWriteHeader(sw, statOutputFormat, baddumpCol, nodumpCol); // Reset the directory stats dirSize = 0; @@ -5184,6 +5257,7 @@ namespace SabreTools.Helper dirCRC = 0; dirMD5 = 0; dirSHA1 = 0; + dirBaddump = 0; dirNodump = 0; } @@ -5197,7 +5271,7 @@ namespace SabreTools.Helper logger.User("Adding stats for file '" + filename + "'\n", false); if (single) { - datdata.OutputStats(sw, statOutputFormat, logger); + datdata.OutputStats(sw, statOutputFormat, logger, baddumpCol: baddumpCol, nodumpCol: nodumpCol); } // Add single DAT stats to dir @@ -5208,6 +5282,7 @@ namespace SabreTools.Helper dirCRC += datdata.CRCCount; dirMD5 += datdata.MD5Count; dirSHA1 += datdata.SHA1Count; + dirBaddump += datdata.BaddumpCount; dirNodump += datdata.NodumpCount; // Add single DAT stats to totals @@ -5218,6 +5293,7 @@ namespace SabreTools.Helper totalCRC += datdata.CRCCount; totalMD5 += datdata.MD5Count; totalSHA1 += datdata.SHA1Count; + totalBaddump += datdata.BaddumpCount; totalNodump += datdata.NodumpCount; // Make sure to assign the new directory @@ -5225,26 +5301,30 @@ namespace SabreTools.Helper } // Output the directory stats one last time - OutputStatsWriteMidSeparator(sw, statOutputFormat); + OutputStatsWriteMidSeparator(sw, statOutputFormat, baddumpCol, nodumpCol); - DatFile dirdat = new DatFile + if (single) { - FileName = lastdir, - TotalSize = dirSize, - RomCount = dirRom, - DiskCount = dirDisk, - CRCCount = dirCRC, - MD5Count = dirMD5, - SHA1Count = dirSHA1, - NodumpCount = dirNodump, - }; - dirdat.OutputStats(sw, statOutputFormat, logger, game: dirGame); + DatFile dirdat = new DatFile + { + FileName = lastdir, + TotalSize = dirSize, + RomCount = dirRom, + DiskCount = dirDisk, + CRCCount = dirCRC, + MD5Count = dirMD5, + SHA1Count = dirSHA1, + BaddumpCount = dirBaddump, + NodumpCount = dirNodump, + }; + dirdat.OutputStats(sw, statOutputFormat, logger, game: dirGame, baddumpCol: baddumpCol, nodumpCol: nodumpCol); + } // Write the mid-footer, if any OutputStatsWriteMidFooter(sw, statOutputFormat); // Write the header, if any - OutputStatsWriteHeader(sw, statOutputFormat); + OutputStatsWriteHeader(sw, statOutputFormat, baddumpCol, nodumpCol); // Reset the directory stats dirSize = 0; @@ -5266,6 +5346,7 @@ namespace SabreTools.Helper CRCCount = totalCRC, MD5Count = totalMD5, SHA1Count = totalSHA1, + BaddumpCount = totalBaddump, NodumpCount = totalNodump, }; totaldata.OutputStats(sw, statOutputFormat, logger, game: totalGame); @@ -5312,13 +5393,16 @@ Please check the log folder if the stats scrolled offscreen", false); /// /// StreamWriter representing the output /// StatOutputFormat representing output format - private static void OutputStatsWriteHeader(StreamWriter sw, StatOutputFormat statOutputFormat) + /// True if baddumps should be included in output, false otherwise + /// True if nodumps should be included in output, false otherwise + private static void OutputStatsWriteHeader(StreamWriter sw, StatOutputFormat statOutputFormat, bool baddumpCol, bool nodumpCol) { string head = ""; switch (statOutputFormat) { case StatOutputFormat.CSV: - head = "\"File Name\",\"Total Size\",\"Games\",\"Roms\",\"Disks\",\"# with CRC\",\"# with MD5\",\"# with SHA-1\",\"Nodumps\"\n"; + head = "\"File Name\",\"Total Size\",\"Games\",\"Roms\",\"Disks\",\"# with CRC\",\"# with MD5\",\"# with SHA-1\"" + + (baddumpCol ? ",\"BadDumps\"" : "") + (nodumpCol ? ",\"Nodumps\"" : "") + "\n"; break; case StatOutputFormat.HTML: head = @" @@ -5329,13 +5413,14 @@ Please check the log folder if the stats scrolled offscreen", false); " -+ "\n"; ++ "" + (baddumpCol ? "" : "") + (nodumpCol ? "" : "") + "\n"; break; case StatOutputFormat.None: default: break; case StatOutputFormat.TSV: - head = "\"File Name\"\t\"Total Size\"\t\"Games\"\t\"Roms\"\t\"Disks\"\t\"# with CRC\"\t\"# with MD5\"\t\"# with SHA-1\"\t\"Nodumps\"\n"; + head = "\"File Name\"\t\"Total Size\"\t\"Games\"\t\"Roms\"\t\"Disks\"\t\"# with CRC\"\t\"# with MD5\"\t\"# with SHA-1\"" + + (baddumpCol ? "\t\"BadDumps\"" : "") + (nodumpCol ? "\t\"Nodumps\"" : "") + "\n"; break; } sw.Write(head); @@ -5346,7 +5431,9 @@ Please check the log folder if the stats scrolled offscreen", false); /// /// StreamWriter representing the output /// StatOutputFormat representing output format - private static void OutputStatsWriteMidSeparator(StreamWriter sw, StatOutputFormat statOutputFormat) + /// True if baddumps should be included in output, false otherwise + /// True if nodumps should be included in output, false otherwise + private static void OutputStatsWriteMidSeparator(StreamWriter sw, StatOutputFormat statOutputFormat, bool baddumpCol, bool nodumpCol) { string mid = ""; switch (statOutputFormat) @@ -5354,7 +5441,14 @@ Please check the log folder if the stats scrolled offscreen", false); case StatOutputFormat.CSV: break; case StatOutputFormat.HTML: - mid = "\n"; + mid = "\n"; break; case StatOutputFormat.None: default: diff --git a/SabreTools.Helper/README.1ST b/SabreTools.Helper/README.1ST index 00e9b2ed..ffdbbea1 100644 --- a/SabreTools.Helper/README.1ST +++ b/SabreTools.Helper/README.1ST @@ -322,6 +322,9 @@ Options: - Roms that include a SHA-1 - Roms with Nodump status + -bc, --baddump-col Add statistics for baddumps to output + Add a new column or field for counting the number of baddumps in the DAT + -csv, --csv Write all statistics to CSV Output all rom information in standardized CSV format @@ -331,6 +334,9 @@ Options: -html, --html Write all statistics to HTML This will output by default the combined statistics for all input DAT files. + -nc, --nodump-col Add statistics for nodumps to output + Add a new column or field for counting the number of nodumps in the DAT + -si, --single Show individual statistics Optionally, the statistics for each of the individual input DATs can be output as well. This can be useful to show where the size or amount of files found diff --git a/SabreTools/Partials/SabreTools_Inits.cs b/SabreTools/Partials/SabreTools_Inits.cs index 3a259f63..913e9484 100644 --- a/SabreTools/Partials/SabreTools_Inits.cs +++ b/SabreTools/Partials/SabreTools_Inits.cs @@ -283,11 +283,14 @@ namespace SabreTools /// Wrap getting statistics on a DAT or folder of DATs /// /// List of inputs to be used + /// Name of the file to output to, blank for default /// True to show individual DAT statistics, false otherwise + /// True if baddumps should be included in output, false otherwise + /// True if nodumps should be included in output, false otherwise /// Set the statistics output format to use - private static void InitStats(List inputs, string filename, bool single, StatOutputFormat statOutputFormat) + private static void InitStats(List inputs, string filename, bool single, bool baddumpCol, bool nodumpCol, StatOutputFormat statOutputFormat) { - DatFile.OutputStats(inputs, (String.IsNullOrEmpty(filename) ? "report" : filename), single, statOutputFormat, _logger); + DatFile.OutputStats(inputs, (String.IsNullOrEmpty(filename) ? "report" : filename), single, baddumpCol, nodumpCol, statOutputFormat, _logger); } /// diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs index ac8e9f09..fa052638 100644 --- a/SabreTools/SabreTools.cs +++ b/SabreTools/SabreTools.cs @@ -51,6 +51,7 @@ namespace SabreTools addBlanks = false, addDate = false, archivesAsFiles = false, + baddumpColumn = false, bare = false, clean = false, copyFiles = false, @@ -64,6 +65,7 @@ namespace SabreTools headerer = false, inplace = false, merge = false, + nodumpColumn = false, noMD5 = false, noSHA1 = false, quotes = false, @@ -148,6 +150,10 @@ namespace SabreTools case "--bare": bare = true; break; + case "-bc": + case "--baddump-col": + baddumpColumn = true; + break; case "-c": case "--cascade": cascade = true; @@ -226,6 +232,10 @@ namespace SabreTools case "--merge": merge = true; break; + case "-nc": + case "--nodump-col": + nodumpColumn = true; + break; case "-nm": case "--noMD5": noMD5 = true; @@ -574,7 +584,7 @@ namespace SabreTools // Get statistics on input files else if (stats) { - InitStats(inputs, filename, single, statOutputFormat); + InitStats(inputs, filename, single, baddumpColumn, nodumpColumn, statOutputFormat); } // Split a DAT by item type
File NameTotal SizeGamesRomsDisks# with CRC# with MD5# with SHA-1Nodumps
# with MD5# with SHA-1BaddumpsNodumps