Add nullability to the two programs (not enforced)

This commit is contained in:
Matt Nadareski
2024-03-05 20:26:38 -05:00
parent 919973266c
commit 3c0d190dc3
43 changed files with 238 additions and 259 deletions

View File

@@ -29,7 +29,7 @@ Unpacked files will be stored as individual entries. Prior to unpacking a zip
file, the external SHA1 is checked against the DAT index. file, the external SHA1 is checked against the DAT index.
If -only-needed is set, only those files are put in the ROM archive that If -only-needed is set, only those files are put in the ROM archive that
have a current entry in the DAT index."; have a current entry in the DAT index.";
Features = new Dictionary<string, SabreTools.Help.Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -45,7 +45,7 @@ have a current entry in the DAT index.";
AddFeature(NoDbFlag); AddFeature(NoDbFlag);
} }
public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature> features) public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -93,7 +93,10 @@ have a current entry in the DAT index.";
foreach (string key in df.Items.Keys) foreach (string key in df.Items.Keys)
{ {
ConcurrentList<DatItem> datItems = df.Items[key]; ConcurrentList<DatItem>? datItems = df.Items[key];
if (datItems == null)
continue;
foreach (Rom rom in datItems) foreach (Rom rom in datItems)
{ {
// If we care about if the file exists, check the databse first // If we care about if the file exists, check the databse first
@@ -117,7 +120,7 @@ have a current entry in the DAT index.";
if (!string.IsNullOrWhiteSpace(rom.SHA1)) if (!string.IsNullOrWhiteSpace(rom.SHA1))
{ {
sha1query += $" (\"{rom.SHA1}\", \"{_depots.Keys.ToList()[0]}\"),"; sha1query += $" (\"{rom.SHA1}\", \"{_depots!.Keys.ToList()[0]}\"),";
if (!string.IsNullOrWhiteSpace(rom.CRC)) if (!string.IsNullOrWhiteSpace(rom.CRC))
crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),"; crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),";
@@ -144,7 +147,7 @@ have a current entry in the DAT index.";
if (!string.IsNullOrWhiteSpace(rom.SHA1)) if (!string.IsNullOrWhiteSpace(rom.SHA1))
{ {
sha1query += $" (\"{rom.SHA1}\", \"{_depots.Keys.ToList()[0]}\"),"; sha1query += $" (\"{rom.SHA1}\", \"{_depots!.Keys.ToList()[0]}\"),";
if (!string.IsNullOrWhiteSpace(rom.CRC)) if (!string.IsNullOrWhiteSpace(rom.CRC))
crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),"; crcsha1query += $" (\"{rom.CRC}\", \"{rom.SHA1}\"),";
@@ -200,7 +203,7 @@ have a current entry in the DAT index.";
Rebuilder.RebuildGeneric( Rebuilder.RebuildGeneric(
need, need,
onlyDirs, onlyDirs,
outDir: _depots.Keys.ToList()[0], outDir: _depots!.Keys.ToList()[0],
outputFormat: OutputFormat.TorrentGzipRomba, outputFormat: OutputFormat.TorrentGzipRomba,
asFiles: TreatAsFile.NonArchive); asFiles: TreatAsFile.NonArchive);

View File

@@ -411,26 +411,26 @@ Possible values are: Verbose, User, Warning, Error");
#region Settings #region Settings
// General settings // General settings
internal static string _logdir; // Log folder location internal static string? _logdir; // Log folder location
internal static string _tmpdir; // Temp folder location internal static string? _tmpdir; // Temp folder location
internal static string _webdir; // Web frontend location internal static string? _webdir; // Web frontend location
internal static string _baddir; // Fail-to-unpack file folder location internal static string? _baddir; // Fail-to-unpack file folder location
internal static int _verbosity; // Verbosity of the output internal static int _verbosity; // Verbosity of the output
internal static int _cores; // Forced CPU cores internal static int _cores; // Forced CPU cores
// DatRoot settings // DatRoot settings
internal static string _dats; // DatRoot folder location internal static string? _dats; // DatRoot folder location
internal static string _db; // Database name internal static string? _db; // Database name
// Depot settings // Depot settings
internal static Dictionary<string, Tuple<long, bool>> _depots; // Folder location, Max size internal static Dictionary<string, Tuple<long, bool>>? _depots; // Folder location, Max size
// Server settings // Server settings
internal static int _port; // Web server port internal static int _port; // Web server port
// Other internal variables // Other internal variables
internal const string _config = "config.xml"; internal const string _config = "config.xml";
internal static string _connectionString; internal static string? _connectionString;
#endregion #endregion
@@ -447,7 +447,7 @@ Possible values are: Verbose, User, Warning, Error");
#endregion #endregion
public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature> features) public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature?> features)
{ {
LogLevel = GetString(features, LogLevelStringValue).AsEnumValue<LogLevel>(); LogLevel = GetString(features, LogLevelStringValue).AsEnumValue<LogLevel>();
ScriptMode = GetBoolean(features, ScriptValue); ScriptMode = GetBoolean(features, ScriptValue);
@@ -462,8 +462,12 @@ Possible values are: Verbose, User, Warning, Error");
/// </summary> /// </summary>
/// <param name="db">Name of the databse</param> /// <param name="db">Name of the databse</param>
/// <param name="connectionString">Connection string for SQLite</param> /// <param name="connectionString">Connection string for SQLite</param>
public void EnsureDatabase(string db, string connectionString) public void EnsureDatabase(string? db, string? connectionString)
{ {
// Missing database or connection string can't work
if (db == null || connectionString == null)
return;
// Make sure the file exists // Make sure the file exists
if (!System.IO.File.Exists(db)) if (!System.IO.File.Exists(db))
System.IO.File.Create(db); System.IO.File.Create(db);
@@ -559,7 +563,8 @@ CREATE TABLE IF NOT EXISTS dat (
if (lowerCaseDats.Contains(input.ToLowerInvariant())) if (lowerCaseDats.Contains(input.ToLowerInvariant()))
{ {
string fullpath = Path.GetFullPath(datRootDats[lowerCaseDats.IndexOf(input.ToLowerInvariant())]); string fullpath = Path.GetFullPath(datRootDats[lowerCaseDats.IndexOf(input.ToLowerInvariant())]);
string sha1 = TextHelper.ByteArrayToString(BaseFile.GetInfo(fullpath, hashes: [HashType.SHA1]).SHA1); string? sha1 = TextHelper.ByteArrayToString(BaseFile.GetInfo(fullpath, hashes: [HashType.SHA1])?.SHA1);
if (sha1 != null)
foundDats.Add(sha1, fullpath); foundDats.Add(sha1, fullpath);
} }
else else
@@ -787,7 +792,7 @@ CREATE TABLE IF NOT EXISTS dat (
DatFile tempdat = Parser.CreateAndParse(fullpath); DatFile tempdat = Parser.CreateAndParse(fullpath);
// If the Dat wasn't empty, add the information // If the Dat wasn't empty, add the information
SqliteCommand slc = null; SqliteCommand? slc = null;
string crcquery = "INSERT OR IGNORE INTO crc (crc) VALUES"; string crcquery = "INSERT OR IGNORE INTO crc (crc) VALUES";
string md5query = "INSERT OR IGNORE INTO md5 (md5) VALUES"; string md5query = "INSERT OR IGNORE INTO md5 (md5) VALUES";
string sha1query = "INSERT OR IGNORE INTO sha1 (sha1) VALUES"; string sha1query = "INSERT OR IGNORE INTO sha1 (sha1) VALUES";
@@ -798,7 +803,7 @@ CREATE TABLE IF NOT EXISTS dat (
bool hasItems = false; bool hasItems = false;
foreach (string romkey in tempdat.Items.Keys) foreach (string romkey in tempdat.Items.Keys)
{ {
foreach (DatItem datItem in tempdat.Items[romkey]) foreach (DatItem datItem in tempdat.Items[romkey]!)
{ {
logger.Verbose($"Checking and adding file '{datItem.GetName() ?? string.Empty}'"); logger.Verbose($"Checking and adding file '{datItem.GetName() ?? string.Empty}'");

View File

@@ -23,7 +23,7 @@ namespace RombaSharp.Features
LongDescription = @"For each specified DAT file it creates the torrentzip files in the specified LongDescription = @"For each specified DAT file it creates the torrentzip files in the specified
output dir. The files will be placed in the specified location using a folder output dir. The files will be placed in the specified location using a folder
structure according to the original DAT master directory tree structure."; structure according to the original DAT master directory tree structure.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -35,7 +35,7 @@ structure according to the original DAT master directory tree structure.";
AddFeature(SubworkersInt32Input); AddFeature(SubworkersInt32Input);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -43,7 +43,7 @@ structure according to the original DAT master directory tree structure.";
// Get feature flags // Get feature flags
bool copy = GetBoolean(features, CopyValue); bool copy = GetBoolean(features, CopyValue);
string outdat = GetString(features, OutStringValue); string? outdat = GetString(features, OutStringValue);
// Verify the filenames // Verify the filenames
Dictionary<string, string> foundDats = GetValidDats(Inputs); Dictionary<string, string> foundDats = GetValidDats(Inputs);
@@ -67,7 +67,7 @@ structure according to the original DAT master directory tree structure.";
outputFolder.Ensure(create: true); outputFolder.Ensure(create: true);
// Get all online depots // Get all online depots
List<string> onlineDepots = _depots.Where(d => d.Value.Item2).Select(d => d.Key).ToList(); List<string> onlineDepots = _depots!.Where(d => d.Value.Item2).Select(d => d.Key).ToList();
// Now scan all of those depots and rebuild // Now scan all of those depots and rebuild
Rebuilder.RebuildDepot( Rebuilder.RebuildDepot(

View File

@@ -15,13 +15,13 @@ namespace RombaSharp.Features
Description = "Cancels current long-running job"; Description = "Cancels current long-running job";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Cancels current long-running job."; LongDescription = "Cancels current long-running job.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -18,13 +18,13 @@ namespace RombaSharp.Features
Description = "Prints dat stats."; Description = "Prints dat stats.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Print dat stats."; LongDescription = "Print dat stats.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -16,13 +16,13 @@ namespace RombaSharp.Features
Description = "Prints db stats."; Description = "Prints db stats.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Print db stats."; LongDescription = "Print db stats.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -34,22 +34,22 @@ namespace RombaSharp.Features
// Total number of CRCs // Total number of CRCs
string query = "SELECT COUNT(*) FROM crc"; string query = "SELECT COUNT(*) FROM crc";
SqliteCommand slc = new SqliteCommand(query, dbc); SqliteCommand slc = new SqliteCommand(query, dbc);
logger.User($"Total CRCs: {(long)slc.ExecuteScalar()}"); logger.User($"Total CRCs: {(long)slc.ExecuteScalar()!}");
// Total number of MD5s // Total number of MD5s
query = "SELECT COUNT(*) FROM md5"; query = "SELECT COUNT(*) FROM md5";
slc = new SqliteCommand(query, dbc); slc = new SqliteCommand(query, dbc);
logger.User($"Total MD5s: {(long)slc.ExecuteScalar()}"); logger.User($"Total MD5s: {(long)slc.ExecuteScalar()!}");
// Total number of SHA1s // Total number of SHA1s
query = "SELECT COUNT(*) FROM sha1"; query = "SELECT COUNT(*) FROM sha1";
slc = new SqliteCommand(query, dbc); slc = new SqliteCommand(query, dbc);
logger.User($"Total SHA1s: {(long)slc.ExecuteScalar()}"); logger.User($"Total SHA1s: {(long)slc.ExecuteScalar()!}");
// Total number of DATs // Total number of DATs
query = "SELECT COUNT(*) FROM dat"; query = "SELECT COUNT(*) FROM dat";
slc = new SqliteCommand(query, dbc); slc = new SqliteCommand(query, dbc);
logger.User($"Total DATs: {(long)slc.ExecuteScalar()}"); logger.User($"Total DATs: {(long)slc.ExecuteScalar()!}");
slc.Dispose(); slc.Dispose();
dbc.Dispose(); dbc.Dispose();

View File

@@ -20,7 +20,7 @@ namespace RombaSharp.Features
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = @"Creates a DAT file with those entries that are in -new DAT file and not LongDescription = @"Creates a DAT file with those entries that are in -new DAT file and not
in -old DAT file. Ignores those entries in -old that are not in -new."; in -old DAT file. Ignores those entries in -old that are not in -new.";
this.Features = new Dictionary<string, Feature>(); this.Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -32,21 +32,21 @@ in -old DAT file. Ignores those entries in -old that are not in -new.";
AddFeature(DescriptionStringInput); AddFeature(DescriptionStringInput);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
return false; return false;
// Get feature flags // Get feature flags
string name = GetString(features, NameStringValue); string? name = GetString(features, NameStringValue);
string description = GetString(features, DescriptionStringValue); string? description = GetString(features, DescriptionStringValue);
string newdat = GetString(features, NewStringValue); string? newdat = GetString(features, NewStringValue);
string olddat = GetString(features, OldStringValue); string? olddat = GetString(features, OldStringValue);
string outdat = GetString(features, OutStringValue); string? outdat = GetString(features, OutStringValue);
// Ensure the output directory // Ensure the output directory
outdat.Ensure(create: true); outdat = outdat?.Ensure(create: true);
// Check that all required files exist // Check that all required files exist
if (!File.Exists(olddat)) if (!File.Exists(olddat))
@@ -70,7 +70,7 @@ in -old DAT file. Ignores those entries in -old that are not in -new.";
// Diff against the new datfile // Diff against the new datfile
DatFile intDat = Parser.CreateAndParse(newdat); DatFile intDat = Parser.CreateAndParse(newdat);
DatFileTool.DiffAgainst(datfile, intDat, false); DatFileTool.DiffAgainst(datfile, intDat, false);
Writer.Write(intDat, outdat); Writer.Write(intDat, outdat!);
return true; return true;
} }
} }

View File

@@ -20,7 +20,7 @@ namespace RombaSharp.Features
Description = "Creates a DAT file for the specified input directory and saves it to the -out filename."; Description = "Creates a DAT file for the specified input directory and saves it to the -out filename.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Creates a DAT file for the specified input directory and saves it to the -out filename."; LongDescription = "Creates a DAT file for the specified input directory and saves it to the -out filename.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -31,20 +31,20 @@ namespace RombaSharp.Features
AddFeature(DescriptionStringInput); AddFeature(DescriptionStringInput);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
return false; return false;
// Get feature flags // Get feature flags
string name = GetString(features, NameStringValue); string? name = GetString(features, NameStringValue);
string description = GetString(features, DescriptionStringValue); string? description = GetString(features, DescriptionStringValue);
string source = GetString(features, SourceStringValue); string? source = GetString(features, SourceStringValue);
string outdat = GetString(features, OutStringValue); string? outdat = GetString(features, OutStringValue);
// Ensure the output directory // Ensure the output directory
outdat.Ensure(create: true); outdat = outdat?.Ensure(create: true);
// Check that all required directories exist // Check that all required directories exist
if (!Directory.Exists(source)) if (!Directory.Exists(source))
@@ -58,7 +58,7 @@ namespace RombaSharp.Features
datfile.Header.Name = string.IsNullOrWhiteSpace(name) ? "untitled" : name; datfile.Header.Name = string.IsNullOrWhiteSpace(name) ? "untitled" : name;
datfile.Header.Description = description; datfile.Header.Description = description;
DatFromDir.PopulateFromDir(datfile, source, asFiles: TreatAsFile.NonArchive, hashes: [HashType.CRC32, HashType.MD5, HashType.SHA1]); DatFromDir.PopulateFromDir(datfile, source, asFiles: TreatAsFile.NonArchive, hashes: [HashType.CRC32, HashType.MD5, HashType.SHA1]);
Writer.Write(datfile, outdat); Writer.Write(datfile, outdat!);
return true; return true;
} }
} }

View File

@@ -15,7 +15,7 @@ namespace RombaSharp.Features
Description = "Show this help"; Description = "Show this help";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Built-in to most of the programs is a basic help text."; LongDescription = "Built-in to most of the programs is a basic help text.";
Features = new Dictionary<string, Feature>(); Features = [];
} }
public override bool ProcessArgs(string[] args, FeatureSet help) public override bool ProcessArgs(string[] args, FeatureSet help)

View File

@@ -15,7 +15,7 @@ namespace RombaSharp.Features
Description = "Show this detailed help"; Description = "Show this detailed help";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Display a detailed help text to the screen."; LongDescription = "Display a detailed help text to the screen.";
Features = new Dictionary<string, Feature>(); Features = [];
} }
public override bool ProcessArgs(string[] args, FeatureSet help) public override bool ProcessArgs(string[] args, FeatureSet help)

View File

@@ -19,7 +19,7 @@ namespace RombaSharp.Features
Description = "Creates a DAT file with those entries that are in -new DAT."; Description = "Creates a DAT file with those entries that are in -new DAT.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = @"Creates a DAT file with those entries that are in -new DAT files and not in -old DAT files. Ignores those entries in -old that are not in -new."; LongDescription = @"Creates a DAT file with those entries that are in -new DAT files and not in -old DAT files. Ignores those entries in -old that are not in -new.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -29,19 +29,19 @@ namespace RombaSharp.Features
AddFeature(NewStringInput); AddFeature(NewStringInput);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
return false; return false;
// Get feature flags // Get feature flags
string olddat = GetString(features, OldStringValue); string? olddat = GetString(features, OldStringValue);
string outdat = GetString(features, OutStringValue); string? outdat = GetString(features, OutStringValue);
string newdat = GetString(features, NewStringValue); string? newdat = GetString(features, NewStringValue);
// Ensure the output directory // Ensure the output directory
outdat.Ensure(create: true); outdat = outdat?.Ensure(create: true);
// Check that all required files exist // Check that all required files exist
if (!File.Exists(olddat)) if (!File.Exists(olddat))
@@ -62,7 +62,7 @@ namespace RombaSharp.Features
// Diff against the new datfile // Diff against the new datfile
DatFile intDat = Parser.CreateAndParse(newdat); DatFile intDat = Parser.CreateAndParse(newdat);
DatFileTool.DiffAgainst(datfile, intDat, false); DatFileTool.DiffAgainst(datfile, intDat, false);
Writer.Write(intDat, outdat); Writer.Write(intDat, outdat!);
return true; return true;
} }
} }

View File

@@ -18,14 +18,14 @@ namespace RombaSharp.Features
Description = "Exports db to export.csv"; Description = "Exports db to export.csv";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Exports db to standardized export.csv"; LongDescription = "Exports db to standardized export.csv";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
// TODO: Add ability to say which depot the files are found in // TODO: Add ability to say which depot the files are found in
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -15,7 +15,7 @@ namespace RombaSharp.Features
Description = "For each specified DAT file it creates a fix DAT."; Description = "For each specified DAT file it creates a fix DAT.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = @"For each specified DAT file it creates a fix DAT with the missing entries for that DAT. If nothing is missing it doesn't create a fix DAT for that particular DAT."; LongDescription = @"For each specified DAT file it creates a fix DAT with the missing entries for that DAT. If nothing is missing it doesn't create a fix DAT for that particular DAT.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -26,7 +26,7 @@ namespace RombaSharp.Features
AddFeature(SubworkersInt32Input); AddFeature(SubworkersInt32Input);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -37,7 +37,7 @@ namespace RombaSharp.Features
bool fixdatOnly = GetBoolean(features, FixdatOnlyValue); bool fixdatOnly = GetBoolean(features, FixdatOnlyValue);
int subworkers = GetInt32(features, SubworkersInt32Value); int subworkers = GetInt32(features, SubworkersInt32Value);
int workers = GetInt32(features, WorkersInt32Value); int workers = GetInt32(features, WorkersInt32Value);
string outdat = GetString(features, OutStringValue); string? outdat = GetString(features, OutStringValue);
logger.Error("This feature is not yet implemented: fixdat"); logger.Error("This feature is not yet implemented: fixdat");
return true; return true;

View File

@@ -20,13 +20,13 @@ namespace RombaSharp.Features
Description = "Import a database from a formatted CSV file"; Description = "Import a database from a formatted CSV file";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Import a database from a formatted CSV file"; LongDescription = "Import a database from a formatted CSV file";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -46,7 +46,7 @@ namespace RombaSharp.Features
StreamReader sr = new StreamReader(File.OpenRead(input)); StreamReader sr = new StreamReader(File.OpenRead(input));
// The first line should be the hash header // The first line should be the hash header
string line = sr.ReadLine(); string? line = sr.ReadLine();
if (line != "CRC,MD5,SHA-1") // ,Depot if (line != "CRC,MD5,SHA-1") // ,Depot
{ {
logger.Error($"{input} is not a valid export file"); logger.Error($"{input} is not a valid export file");
@@ -63,7 +63,7 @@ namespace RombaSharp.Features
// For each line until we hit a blank line... // For each line until we hit a blank line...
while (!sr.EndOfStream && line != string.Empty) while (!sr.EndOfStream && line != string.Empty)
{ {
line = sr.ReadLine(); line = sr.ReadLine() ?? string.Empty;
string[] hashes = line.Split(','); string[] hashes = line.Split(',');
// Loop through the parsed entries // Loop through the parsed entries

View File

@@ -17,7 +17,7 @@ namespace RombaSharp.Features
Description = "For each specified hash it looks up any available information."; Description = "For each specified hash it looks up any available information.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "For each specified hash it looks up any available information (dat or rom)."; LongDescription = "For each specified hash it looks up any available information (dat or rom).";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -26,7 +26,7 @@ namespace RombaSharp.Features
AddFeature(OutStringInput); AddFeature(OutStringInput);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -34,12 +34,12 @@ namespace RombaSharp.Features
// Get feature flags // Get feature flags
long size = GetInt64(features, SizeInt64Value); long size = GetInt64(features, SizeInt64Value);
string outdat = GetString(features, OutStringValue); string? outdat = GetString(features, OutStringValue);
// First, try to figure out what type of hash each is by length and clean it // First, try to figure out what type of hash each is by length and clean it
List<string> crc = new List<string>(); List<string> crc = [];
List<string> md5 = new List<string>(); List<string> md5 = [];
List<string> sha1 = new List<string>(); List<string> sha1 = [];
foreach (string input in Inputs) foreach (string input in Inputs)
{ {
if (input.Length == Constants.CRCLength) if (input.Length == Constants.CRCLength)

View File

@@ -15,13 +15,13 @@ namespace RombaSharp.Features
Description = "Prints memory stats."; Description = "Prints memory stats.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Print memory stats."; LongDescription = "Print memory stats.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -18,7 +18,7 @@ namespace RombaSharp.Features
Description = "Merges depot"; Description = "Merges depot";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Merges specified depot into current depot."; LongDescription = "Merges specified depot into current depot.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -30,7 +30,7 @@ namespace RombaSharp.Features
} }
// TODO: Add way of specifying "current depot" since that's what Romba relies on // TODO: Add way of specifying "current depot" since that's what Romba relies on
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -40,7 +40,7 @@ namespace RombaSharp.Features
bool onlyNeeded = GetBoolean(features, OnlyNeededValue); bool onlyNeeded = GetBoolean(features, OnlyNeededValue);
bool skipInitialscan = GetBoolean(features, SkipInitialScanValue); bool skipInitialscan = GetBoolean(features, SkipInitialScanValue);
int workers = GetInt32(features, WorkersInt32Value); int workers = GetInt32(features, WorkersInt32Value);
string resume = GetString(features, ResumeStringValue); string? resume = GetString(features, ResumeStringValue);
logger.Error("This feature is not yet implemented: merge"); logger.Error("This feature is not yet implemented: merge");

View File

@@ -20,13 +20,13 @@ namespace RombaSharp.Features
Description = "Create miss and have file"; Description = "Create miss and have file";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "For each specified DAT file, create miss and have file"; LongDescription = "For each specified DAT file, create miss and have file";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -15,13 +15,13 @@ namespace RombaSharp.Features
Description = "Shows progress of the currently running command."; Description = "Shows progress of the currently running command.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Shows progress of the currently running command."; LongDescription = "Shows progress of the currently running command.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -19,7 +19,7 @@ longer associated with any current DATs to the specified backup folder.
The files will be placed in the backup location using The files will be placed in the backup location using
a folder structure according to the original DAT master directory tree a folder structure according to the original DAT master directory tree
structure. It also deletes the specified DATs from the DAT index."; structure. It also deletes the specified DATs from the DAT index.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -31,7 +31,7 @@ structure. It also deletes the specified DATs from the DAT index.";
AddFeature(LogOnlyFlag); AddFeature(LogOnlyFlag);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -40,7 +40,7 @@ structure. It also deletes the specified DATs from the DAT index.";
// Get feature flags // Get feature flags
bool logOnly = GetBoolean(features, LogOnlyValue); bool logOnly = GetBoolean(features, LogOnlyValue);
int workers = GetInt32(features, WorkersInt32Value); int workers = GetInt32(features, WorkersInt32Value);
string backup = GetString(features, BackupStringValue); string? backup = GetString(features, BackupStringValue);
List<string> dats = GetList(features, DatsListStringValue); List<string> dats = GetList(features, DatsListStringValue);
List<string> depot = GetList(features, DepotListStringValue); List<string> depot = GetList(features, DepotListStringValue);

View File

@@ -20,7 +20,7 @@ longer associated with any current DATs to the specified backup folder.
The files will be placed in the backup location using The files will be placed in the backup location using
a folder structure according to the original DAT master directory tree a folder structure according to the original DAT master directory tree
structure. It also deletes the specified DATs from the DAT index."; structure. It also deletes the specified DATs from the DAT index.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -31,7 +31,7 @@ structure. It also deletes the specified DATs from the DAT index.";
AddFeature(LogOnlyFlag); AddFeature(LogOnlyFlag);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -27,7 +27,7 @@ namespace RombaSharp.Features
Detects any changes in the DAT master directory tree and updates the DAT index Detects any changes in the DAT master directory tree and updates the DAT index
accordingly, marking deleted or overwritten dats as orphaned and updating accordingly, marking deleted or overwritten dats as orphaned and updating
contents of any changed dats."; contents of any changed dats.";
Features = new Dictionary<string, SabreTools.Help.Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -36,7 +36,7 @@ contents of any changed dats.";
AddFeature(MissingSha1sStringInput); AddFeature(MissingSha1sStringInput);
} }
public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature> features) public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -44,7 +44,7 @@ contents of any changed dats.";
// Get feature flags // Get feature flags
int workers = GetInt32(features, WorkersInt32Value); int workers = GetInt32(features, WorkersInt32Value);
string missingSha1s = GetString(features, MissingSha1sStringValue); string? missingSha1s = GetString(features, MissingSha1sStringValue);
// Make sure the db is set // Make sure the db is set
if (string.IsNullOrWhiteSpace(_db)) if (string.IsNullOrWhiteSpace(_db))
@@ -112,7 +112,7 @@ contents of any changed dats.";
watch.Start("Adding new DAT information"); watch.Start("Adding new DAT information");
foreach (string key in datroot.Items.Keys) foreach (string key in datroot.Items.Keys)
{ {
foreach (Rom value in datroot.Items[key]) foreach (Rom value in datroot.Items[key]!)
{ {
AddDatToDatabase(value, dbc); AddDatToDatabase(value, dbc);
} }

View File

@@ -24,13 +24,13 @@ namespace RombaSharp.Features
Description = "Rescan a specific depot to get new information"; Description = "Rescan a specific depot to get new information";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Rescan a specific depot to get new information"; LongDescription = "Rescan a specific depot to get new information";
Features = new Dictionary<string, SabreTools.Help.Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature> features) public override bool ProcessFeatures(Dictionary<string, SabreTools.Help.Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -41,7 +41,7 @@ namespace RombaSharp.Features
foreach (string depotname in Inputs) foreach (string depotname in Inputs)
{ {
// Check that it's a valid depot first // Check that it's a valid depot first
if (!_depots.ContainsKey(depotname)) if (!_depots!.ContainsKey(depotname))
{ {
logger.User($"'{depotname}' is not a recognized depot. Please add it to your configuration file and try again"); logger.User($"'{depotname}' is not a recognized depot. Please add it to your configuration file and try again");
return false; return false;
@@ -88,7 +88,10 @@ namespace RombaSharp.Features
IEnumerable<string> keys = depot.Items.Keys; IEnumerable<string> keys = depot.Items.Keys;
foreach (string key in keys) foreach (string key in keys)
{ {
ConcurrentList<DatItem> roms = depot.Items[key]; ConcurrentList<DatItem>? roms = depot.Items[key];
if (roms == null)
continue;
foreach (Rom rom in roms) foreach (Rom rom in roms)
{ {
if (hashes.Contains(rom.SHA1)) if (hashes.Contains(rom.SHA1))

View File

@@ -15,13 +15,13 @@ namespace RombaSharp.Features
Description = "Gracefully shuts down server."; Description = "Gracefully shuts down server.";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Gracefully shuts down server saving all the cached data."; LongDescription = "Gracefully shuts down server saving all the cached data.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -16,13 +16,13 @@ namespace RombaSharp.Features
Description = "Prints version"; Description = "Prints version";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Prints current program version."; LongDescription = "Prints current program version.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -25,7 +25,7 @@ namespace RombaSharp
/// <summary> /// <summary>
/// Help object that determines available functionality /// Help object that determines available functionality
/// </summary> /// </summary>
private static FeatureSet _help; private static FeatureSet? _help;
/// <summary> /// <summary>
/// Logging object /// Logging object
@@ -81,18 +81,18 @@ namespace RombaSharp
featureName = _help.GetFeatureName(featureName); featureName = _help.GetFeatureName(featureName);
// Get the associated feature // Get the associated feature
BaseFeature feature = _help[featureName] as BaseFeature; BaseFeature? feature = _help[featureName] as BaseFeature;
// If we had the help feature first // If we had the help feature first
if (featureName == DisplayHelp.Value || featureName == DisplayHelpDetailed.Value) if (featureName == DisplayHelp.Value || featureName == DisplayHelpDetailed.Value)
{ {
feature.ProcessArgs(args, _help); feature!.ProcessArgs(args, _help);
LoggerImpl.Close(); LoggerImpl.Close();
return; return;
} }
// Now verify that all other flags are valid // Now verify that all other flags are valid
if (!feature.ProcessArgs(args, _help)) if (!feature!.ProcessArgs(args, _help))
{ {
LoggerImpl.Close(); LoggerImpl.Close();
return; return;
@@ -109,7 +109,7 @@ namespace RombaSharp
} }
// Now process the current feature // Now process the current feature
Dictionary<string, Feature> features = _help.GetEnabledFeatures(); Dictionary<string, Feature?> features = _help.GetEnabledFeatures();
bool success = false; bool success = false;
switch (featureName) switch (featureName)
{ {
@@ -224,7 +224,7 @@ namespace RombaSharp
if (inputs.Count == 0) if (inputs.Count == 0)
{ {
logger.Error("This feature requires at least one input"); logger.Error("This feature requires at least one input");
_help.OutputIndividualFeature(feature); _help?.OutputIndividualFeature(feature);
Environment.Exit(0); Environment.Exit(0);
} }
} }

View File

@@ -5,6 +5,7 @@
<TargetFrameworks>net6.0;net8.0</TargetFrameworks> <TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<Authors>Matt Nadareski</Authors> <Authors>Matt Nadareski</Authors>
<Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright> <Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>

View File

@@ -153,7 +153,7 @@ namespace SabreTools.DatTools
public static bool Write( public static bool Write(
List<DatStatistics> stats, List<DatStatistics> stats,
string reportName, string reportName,
string outDir, string? outDir,
bool baddumpCol, bool baddumpCol,
bool nodumpCol, bool nodumpCol,
StatReportFormat statDatFormat, StatReportFormat statDatFormat,
@@ -171,12 +171,12 @@ namespace SabreTools.DatTools
reportName = "report"; reportName = "report";
// Get the proper output directory name // Get the proper output directory name
outDir = outDir.Ensure(); outDir = outDir?.Ensure();
InternalStopwatch watch = new($"Writing out report data to '{outDir}'"); InternalStopwatch watch = new($"Writing out report data to '{outDir}'");
// Get the dictionary of desired output report names // Get the dictionary of desired output report names
Dictionary<StatReportFormat, string> outfiles = CreateOutStatsNames(outDir, statDatFormat, reportName); Dictionary<StatReportFormat, string> outfiles = CreateOutStatsNames(outDir!, statDatFormat, reportName);
try try
{ {

View File

@@ -16,7 +16,7 @@ namespace SabreTools.Help
/// <summary> /// <summary>
/// List of files, directories, and potential wildcard paths /// List of files, directories, and potential wildcard paths
/// </summary> /// </summary>
public List<string> Inputs = new(); public List<string> Inputs = [];
#endregion #endregion
@@ -87,7 +87,7 @@ namespace SabreTools.Help
/// Process and extract variables based on current feature /// Process and extract variables based on current feature
/// </summary> /// </summary>
/// <returns>True if execution was successful, false otherwise</returns> /// <returns>True if execution was successful, false otherwise</returns>
public virtual bool ProcessFeatures(Dictionary<string, Feature> features) => true; public virtual bool ProcessFeatures(Dictionary<string, Feature?> features) => true;
#endregion #endregion
@@ -96,7 +96,7 @@ namespace SabreTools.Help
/// <summary> /// <summary>
/// Get boolean value from nullable feature /// Get boolean value from nullable feature
/// </summary> /// </summary>
protected static bool GetBoolean(Dictionary<string, Feature> features, string key) protected static bool GetBoolean(Dictionary<string, Feature?> features, string key)
{ {
if (!features.ContainsKey(key)) if (!features.ContainsKey(key))
return false; return false;
@@ -107,45 +107,45 @@ namespace SabreTools.Help
/// <summary> /// <summary>
/// Get int value from nullable feature /// Get int value from nullable feature
/// </summary> /// </summary>
protected static int GetInt32(Dictionary<string, Feature> features, string key) protected static int GetInt32(Dictionary<string, Feature?> features, string key)
{ {
if (!features.ContainsKey(key)) if (!features.ContainsKey(key))
return Int32.MinValue; return Int32.MinValue;
return features[key].GetInt32Value(); return features[key]!.GetInt32Value();
} }
/// <summary> /// <summary>
/// Get long value from nullable feature /// Get long value from nullable feature
/// </summary> /// </summary>
protected static long GetInt64(Dictionary<string, Feature> features, string key) protected static long GetInt64(Dictionary<string, Feature?> features, string key)
{ {
if (!features.ContainsKey(key)) if (!features.ContainsKey(key))
return Int64.MinValue; return Int64.MinValue;
return features[key].GetInt64Value(); return features[key]!.GetInt64Value();
} }
/// <summary> /// <summary>
/// Get list value from nullable feature /// Get list value from nullable feature
/// </summary> /// </summary>
protected static List<string> GetList(Dictionary<string, Feature> features, string key) protected static List<string> GetList(Dictionary<string, Feature?> features, string key)
{ {
if (!features.ContainsKey(key)) if (!features.ContainsKey(key))
return []; return [];
return features[key].GetListValue() ?? []; return features[key]!.GetListValue() ?? [];
} }
/// <summary> /// <summary>
/// Get string value from nullable feature /// Get string value from nullable feature
/// </summary> /// </summary>
protected static string? GetString(Dictionary<string, Feature> features, string key) protected static string? GetString(Dictionary<string, Feature?> features, string key)
{ {
if (!features.ContainsKey(key)) if (!features.ContainsKey(key))
return null; return null;
return features[key].GetStringValue(); return features[key]!.GetStringValue();
} }
#endregion #endregion

View File

@@ -1774,28 +1774,23 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Preconfigured Cleaner /// Preconfigured Cleaner
/// </summary> /// </summary>
protected Cleaner Cleaner { get; set; } protected Cleaner? Cleaner { get; set; }
/// <summary> /// <summary>
/// Preconfigured ExtraIni set /// Preconfigured ExtraIni set
/// </summary> /// </summary>
protected ExtraIni Extras { get; set; } protected ExtraIni? Extras { get; set; }
/// <summary>
/// Preconfigured Filter
/// </summary>
protected Filtering.Filter Filter { get; set; }
/// <summary> /// <summary>
/// Preonfigured FilterRunner /// Preonfigured FilterRunner
/// </summary> /// </summary>
protected Filter.FilterRunner FilterRunner { get; set; } protected Filter.FilterRunner? FilterRunner { get; set; }
/// <summary> /// <summary>
/// Pre-configured DatHeader /// Pre-configured DatHeader
/// </summary> /// </summary>
/// <remarks>Public because it's an indicator something went wrong</remarks> /// <remarks>Public because it's an indicator something went wrong</remarks>
public DatHeader Header { get; set; } public DatHeader? Header { get; set; }
/// <summary> /// <summary>
/// Lowest log level for output /// Lowest log level for output
@@ -1805,12 +1800,12 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Output directory /// Output directory
/// </summary> /// </summary>
protected string OutputDir { get; set; } protected string? OutputDir { get; set; }
/// <summary> /// <summary>
/// Pre-configured Remover /// Pre-configured Remover
/// </summary> /// </summary>
protected Remover Remover { get; set; } protected Remover? Remover { get; set; }
/// <summary> /// <summary>
/// Determines if scripting mode is enabled /// Determines if scripting mode is enabled
@@ -1820,7 +1815,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Pre-configured Splitter /// Pre-configured Splitter
/// </summary> /// </summary>
protected Filtering.Splitter Splitter { get; set; } protected Filtering.Splitter? Splitter { get; set; }
#endregion #endregion
@@ -1873,7 +1868,7 @@ Some special strings that can be used:
// Header Filters // Header Filters
AddFeature(ExcludeFieldListInput); AddFeature(ExcludeFieldListInput);
AddFeature(OneGamePerRegionFlag); AddFeature(OneGamePerRegionFlag);
this[OneGamePerRegionFlag].AddFeature(RegionListInput); this[OneGamePerRegionFlag]!.AddFeature(RegionListInput);
AddFeature(OneRomPerGameFlag); AddFeature(OneRomPerGameFlag);
AddFeature(SceneDateStripFlag); AddFeature(SceneDateStripFlag);
} }
@@ -1893,12 +1888,11 @@ Some special strings that can be used:
#endregion #endregion
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// Generic feature flags // Generic feature flags
Cleaner = GetCleaner(features); Cleaner = GetCleaner(features);
Extras = GetExtras(features); Extras = GetExtras(features);
Filter = GetFilter(features);
FilterRunner = GetFilterRunner(features); FilterRunner = GetFilterRunner(features);
Header = GetDatHeader(features); Header = GetDatHeader(features);
LogLevel = GetString(features, LogLevelStringValue).AsEnumValue<LogLevel>(); LogLevel = GetString(features, LogLevelStringValue).AsEnumValue<LogLevel>();
@@ -1923,7 +1917,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get include from scan from feature list /// Get include from scan from feature list
/// </summary> /// </summary>
protected static HashType[] GetIncludeInScan(Dictionary<string, Feature> features) protected static HashType[] GetIncludeInScan(Dictionary<string, Feature?> features)
{ {
List<HashType> includeInScan = []; List<HashType> includeInScan = [];
@@ -1952,7 +1946,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get OutputFormat from feature list /// Get OutputFormat from feature list
/// </summary> /// </summary>
protected static OutputFormat GetOutputFormat(Dictionary<string, Feature> features) protected static OutputFormat GetOutputFormat(Dictionary<string, Feature?> features)
{ {
if (GetBoolean(features, TarValue)) if (GetBoolean(features, TarValue))
return OutputFormat.TapeArchive; return OutputFormat.TapeArchive;
@@ -1981,7 +1975,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get SkipFileType from feature list /// Get SkipFileType from feature list
/// </summary> /// </summary>
protected static SkipFileType GetSkipFileType(Dictionary<string, Feature> features) protected static SkipFileType GetSkipFileType(Dictionary<string, Feature?> features)
{ {
if (GetBoolean(features, SkipArchivesValue)) if (GetBoolean(features, SkipArchivesValue))
return SkipFileType.Archive; return SkipFileType.Archive;
@@ -1994,7 +1988,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get SplittingMode from feature list /// Get SplittingMode from feature list
/// </summary> /// </summary>
protected static SplittingMode GetSplittingMode(Dictionary<string, Feature> features) protected static SplittingMode GetSplittingMode(Dictionary<string, Feature?> features)
{ {
SplittingMode splittingMode = SplittingMode.None; SplittingMode splittingMode = SplittingMode.None;
@@ -2017,7 +2011,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get StatReportFormat from feature list /// Get StatReportFormat from feature list
/// </summary> /// </summary>
protected static StatReportFormat GetStatReportFormat(Dictionary<string, Feature> features) protected static StatReportFormat GetStatReportFormat(Dictionary<string, Feature?> features)
{ {
StatReportFormat statDatFormat = StatReportFormat.None; StatReportFormat statDatFormat = StatReportFormat.None;
@@ -2032,7 +2026,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get TreatAsFiles from feature list /// Get TreatAsFiles from feature list
/// </summary> /// </summary>
protected static TreatAsFile GetTreatAsFiles(Dictionary<string, Feature> features) protected static TreatAsFile GetTreatAsFiles(Dictionary<string, Feature?> features)
{ {
TreatAsFile asFiles = 0x00; TreatAsFile asFiles = 0x00;
if (GetBoolean(features, AaruFormatsAsFilesValue)) if (GetBoolean(features, AaruFormatsAsFilesValue))
@@ -2048,13 +2042,13 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get update Machine fields from feature list /// Get update Machine fields from feature list
/// </summary> /// </summary>
protected static List<string> GetUpdateMachineFields(Dictionary<string, Feature> features) protected static List<string> GetUpdateMachineFields(Dictionary<string, Feature?> features)
{ {
List<string> updateFields = []; List<string> updateFields = [];
foreach (string fieldName in GetList(features, UpdateFieldListValue)) foreach (string fieldName in GetList(features, UpdateFieldListValue))
{ {
(string? itemType, string? key) = SabreTools.Filter.FilterParser.ParseFilterId(fieldName); (string? itemType, string? key) = SabreTools.Filter.FilterParser.ParseFilterId(fieldName);
if (itemType == Models.Metadata.MetadataFile.MachineKey) if (itemType == Models.Metadata.MetadataFile.MachineKey && key != null)
updateFields.Add(key); updateFields.Add(key);
} }
@@ -2064,13 +2058,13 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get update DatItem fields from feature list /// Get update DatItem fields from feature list
/// </summary> /// </summary>
protected static Dictionary<string, List<string>> GetUpdateDatItemFields(Dictionary<string, Feature> features) protected static Dictionary<string, List<string>> GetUpdateDatItemFields(Dictionary<string, Feature?> features)
{ {
Dictionary<string, List<string>> updateFields = []; Dictionary<string, List<string>> updateFields = [];
foreach (string fieldName in GetList(features, UpdateFieldListValue)) foreach (string fieldName in GetList(features, UpdateFieldListValue))
{ {
(string? itemType, string? key) = SabreTools.Filter.FilterParser.ParseFilterId(fieldName); (string? itemType, string? key) = SabreTools.Filter.FilterParser.ParseFilterId(fieldName);
if (itemType != Models.Metadata.MetadataFile.HeaderKey && itemType != Models.Metadata.MetadataFile.MachineKey) if (itemType != null && itemType != Models.Metadata.MetadataFile.HeaderKey && itemType != Models.Metadata.MetadataFile.MachineKey && key != null)
{ {
if (!updateFields.ContainsKey(itemType)) if (!updateFields.ContainsKey(itemType))
updateFields[itemType] = []; updateFields[itemType] = [];
@@ -2085,7 +2079,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get UpdateMode from feature list /// Get UpdateMode from feature list
/// </summary> /// </summary>
protected static UpdateMode GetUpdateMode(Dictionary<string, Feature> features) protected static UpdateMode GetUpdateMode(Dictionary<string, Feature?> features)
{ {
UpdateMode updateMode = UpdateMode.None; UpdateMode updateMode = UpdateMode.None;
@@ -2129,7 +2123,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get Cleaner from feature list /// Get Cleaner from feature list
/// </summary> /// </summary>
private static Cleaner GetCleaner(Dictionary<string, Feature> features) private static Cleaner GetCleaner(Dictionary<string, Feature?> features)
{ {
Cleaner cleaner = new() Cleaner cleaner = new()
{ {
@@ -2153,10 +2147,10 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get DatHeader from feature list /// Get DatHeader from feature list
/// </summary> /// </summary>
private DatHeader GetDatHeader(Dictionary<string, Feature> features) private DatHeader? GetDatHeader(Dictionary<string, Feature?> features)
{ {
// TODO: Sort this by region, like the actual header // TODO: Sort this by region, like the actual header
DatHeader datHeader = new() var datHeader = new DatHeader()
{ {
AddExtension = GetString(features, AddExtensionStringValue), AddExtension = GetString(features, AddExtensionStringValue),
Author = GetString(features, AuthorStringValue), Author = GetString(features, AuthorStringValue),
@@ -2217,7 +2211,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get DedupeType from feature list /// Get DedupeType from feature list
/// </summary> /// </summary>
private static DedupeType GetDedupeType(Dictionary<string, Feature> features) private static DedupeType GetDedupeType(Dictionary<string, Feature?> features)
{ {
if (GetBoolean(features, DedupValue)) if (GetBoolean(features, DedupValue))
return DedupeType.Full; return DedupeType.Full;
@@ -2230,38 +2224,17 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get ExtraIni from feature list /// Get ExtraIni from feature list
/// </summary> /// </summary>
private static ExtraIni GetExtras(Dictionary<string, Feature> features) private static ExtraIni GetExtras(Dictionary<string, Feature?> features)
{ {
ExtraIni extraIni = new(); ExtraIni extraIni = new();
extraIni.PopulateFromList(GetList(features, ExtraIniListValue)); extraIni.PopulateFromList(GetList(features, ExtraIniListValue));
return extraIni; return extraIni;
} }
/// <summary>
/// Get Filter from feature list
/// </summary>
private static Filtering.Filter GetFilter(Dictionary<string, Feature> features)
{
Filtering.Filter filter = new()
{
DatItemFilter = new DatItemFilter(),
MachineFilter = new MachineFilter(),
};
// Populate filters
List<string> filterPairs = GetList(features, FilterListValue);
filter.PopulateFiltersFromList(filterPairs);
// Include 'of" in game filters
filter.MachineFilter.IncludeOfInGame = GetBoolean(features, MatchOfTagsValue);
return filter;
}
/// <summary> /// <summary>
/// Get FilterRunner from feature list /// Get FilterRunner from feature list
/// </summary> /// </summary>
private static Filter.FilterRunner GetFilterRunner(Dictionary<string, Feature> features) private static Filter.FilterRunner GetFilterRunner(Dictionary<string, Feature?> features)
{ {
// Populate filters // Populate filters
List<string> filterPairs = GetList(features, FilterListValue); List<string> filterPairs = GetList(features, FilterListValue);
@@ -2277,7 +2250,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get Remover from feature list /// Get Remover from feature list
/// </summary> /// </summary>
private static Remover GetRemover(Dictionary<string, Feature> features) private static Remover GetRemover(Dictionary<string, Feature?> features)
{ {
Remover remover = new(); Remover remover = new();
@@ -2291,7 +2264,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get Splitter from feature list /// Get Splitter from feature list
/// </summary> /// </summary>
private static Filtering.Splitter GetSplitter(Dictionary<string, Feature> features) private static Filtering.Splitter GetSplitter(Dictionary<string, Feature?> features)
{ {
Filtering.Splitter splitter = new() Filtering.Splitter splitter = new()
{ {
@@ -2303,7 +2276,7 @@ Some special strings that can be used:
/// <summary> /// <summary>
/// Get SplitType from feature list /// Get SplitType from feature list
/// </summary> /// </summary>
private static MergingFlag GetSplitType(Dictionary<string, Feature> features) private static MergingFlag GetSplitType(Dictionary<string, Feature?> features)
{ {
MergingFlag splitType = MergingFlag.None; MergingFlag splitType = MergingFlag.None;
if (GetBoolean(features, DatDeviceNonMergedValue)) if (GetBoolean(features, DatDeviceNonMergedValue))

View File

@@ -38,9 +38,9 @@ namespace SabreTools.Features
AddFeature(ArchivesAsFilesFlag); AddFeature(ArchivesAsFilesFlag);
AddFeature(ChdsAsFilesFlag); AddFeature(ChdsAsFilesFlag);
AddFeature(OutputTypeListInput); AddFeature(OutputTypeListInput);
this[OutputTypeListInput].AddFeature(DeprecatedFlag); this[OutputTypeListInput]!.AddFeature(DeprecatedFlag);
AddFeature(RombaFlag); AddFeature(RombaFlag);
this[RombaFlag].AddFeature(RombaDepthInt32Input); this[RombaFlag]!.AddFeature(RombaDepthInt32Input);
AddFeature(SkipArchivesFlag); AddFeature(SkipArchivesFlag);
AddFeature(SkipFilesFlag); AddFeature(SkipFilesFlag);
AddHeaderFeatures(); AddHeaderFeatures();
@@ -100,8 +100,7 @@ namespace SabreTools.Features
// Perform additional processing steps // Perform additional processing steps
Extras.ApplyExtras(datdata); Extras.ApplyExtras(datdata);
Splitter.ApplySplitting(datdata, useTags: false); Splitter.ApplySplitting(datdata, useTags: false);
Filter.ApplyFilters(datdata); datdata.ExecuteFilters(FilterRunner);
// datdata.ExecuteFilters(FilterRunner); // TODO: Replace Filter.ApplyFilters with this
Cleaner.ApplyCleaning(datdata); Cleaner.ApplyCleaning(datdata);
Remover.ApplyRemovals(datdata); Remover.ApplyRemovals(datdata);

View File

@@ -15,7 +15,7 @@ namespace SabreTools.Features
Description = "Show this help"; Description = "Show this help";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Built-in to most of the programs is a basic help text."; LongDescription = "Built-in to most of the programs is a basic help text.";
Features = new Dictionary<string, Feature>(); Features = [];
} }
public override bool ProcessArgs(string[] args, FeatureSet help) public override bool ProcessArgs(string[] args, FeatureSet help)

View File

@@ -15,7 +15,7 @@ namespace SabreTools.Features
Description = "Show this detailed help"; Description = "Show this detailed help";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Display a detailed help text to the screen."; LongDescription = "Display a detailed help text to the screen.";
Features = new Dictionary<string, Feature>(); Features = [];
} }
public override bool ProcessArgs(string[] args, FeatureSet help) public override bool ProcessArgs(string[] args, FeatureSet help)

View File

@@ -32,7 +32,7 @@ The following systems have headers that this program can work with:
- Nintendo Famicom Disk System - Nintendo Famicom Disk System
- Nintendo Super Famicom / Super Nintendo Entertainment System - Nintendo Super Famicom / Super Nintendo Entertainment System
- Nintendo Super Famicom / Super Nintendo Entertainment System SPC"; - Nintendo Super Famicom / Super Nintendo Entertainment System SPC";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -41,7 +41,7 @@ The following systems have headers that this program can work with:
AddFeature(NoStoreHeaderFlag); AddFeature(NoStoreHeaderFlag);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -31,7 +31,7 @@ The following systems have headers that this program can work with:
- Nintendo Famicom Disk System - Nintendo Famicom Disk System
- Nintendo Super Famicom / Super Nintendo Entertainment System - Nintendo Super Famicom / Super Nintendo Entertainment System
- Nintendo Super Famicom / Super Nintendo Entertainment System SPC"; - Nintendo Super Famicom / Super Nintendo Entertainment System SPC";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -39,7 +39,7 @@ The following systems have headers that this program can work with:
AddFeature(OutputDirStringInput); AddFeature(OutputDirStringInput);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -21,7 +21,7 @@ namespace SabreTools.Features
Description = "Sort inputs by a set of DATs"; Description = "Sort inputs by a set of DATs";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "This feature allows the user to quickly rebuild based on a supplied DAT file(s). By default all files will be rebuilt to uncompressed folders in the output directory."; LongDescription = "This feature allows the user to quickly rebuild based on a supplied DAT file(s). By default all files will be rebuilt to uncompressed folders in the output directory.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -29,7 +29,7 @@ namespace SabreTools.Features
AddFeature(DatListInput); AddFeature(DatListInput);
AddFeature(OutputDirStringInput); AddFeature(OutputDirStringInput);
AddFeature(DepotFlag); AddFeature(DepotFlag);
this[DepotFlag].AddFeature(DepotDepthInt32Input); this[DepotFlag]!.AddFeature(DepotDepthInt32Input);
AddFeature(DeleteFlag); AddFeature(DeleteFlag);
AddFeature(InverseFlag); AddFeature(InverseFlag);
AddFeature(QuickFlag); AddFeature(QuickFlag);
@@ -42,13 +42,13 @@ namespace SabreTools.Features
AddFeature(Torrent7zipFlag); AddFeature(Torrent7zipFlag);
AddFeature(TarFlag); AddFeature(TarFlag);
AddFeature(TorrentGzipFlag); AddFeature(TorrentGzipFlag);
this[TorrentGzipFlag].AddFeature(RombaFlag); this[TorrentGzipFlag]!.AddFeature(RombaFlag);
this[TorrentGzipFlag][RombaFlag].AddFeature(RombaDepthInt32Input); this[TorrentGzipFlag][RombaFlag]!.AddFeature(RombaDepthInt32Input);
//AddFeature(SharedInputs.TorrentLrzipFlag); //AddFeature(SharedInputs.TorrentLrzipFlag);
//AddFeature(SharedInputs.TorrentLz4Flag); //AddFeature(SharedInputs.TorrentLz4Flag);
//AddFeature(SharedInputs.TorrentRarFlag); //AddFeature(SharedInputs.TorrentRarFlag);
//AddFeature(SharedInputs.TorrentXzFlag); //AddFeature(SharedInputs.TorrentXzFlag);
//this[SharedInputs.TorrentXzFlag].AddFeature(SharedInputs.RombaFlag); //this[SharedInputs.TorrentXzFlag]!.AddFeature(SharedInputs.RombaFlag);
AddFeature(TorrentZipFlag); AddFeature(TorrentZipFlag);
//AddFeature(SharedInputs.TorrentZpaqFlag); //AddFeature(SharedInputs.TorrentZpaqFlag);
//AddFeature(SharedInputs.TorrentZstdFlag); //AddFeature(SharedInputs.TorrentZstdFlag);
@@ -58,7 +58,7 @@ namespace SabreTools.Features
AddFeature(UpdateDatFlag); AddFeature(UpdateDatFlag);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -26,20 +26,20 @@ namespace SabreTools.Features
AddCommonFeatures(); AddCommonFeatures();
AddFeature(OutputTypeListInput); AddFeature(OutputTypeListInput);
this[OutputTypeListInput].AddFeature(DeprecatedFlag); this[OutputTypeListInput]!.AddFeature(DeprecatedFlag);
AddFeature(OutputDirStringInput); AddFeature(OutputDirStringInput);
AddFeature(InplaceFlag); AddFeature(InplaceFlag);
AddFeature(ExtensionFlag); AddFeature(ExtensionFlag);
this[ExtensionFlag].AddFeature(ExtaListInput); this[ExtensionFlag]!.AddFeature(ExtaListInput);
this[ExtensionFlag].AddFeature(ExtbListInput); this[ExtensionFlag]!.AddFeature(ExtbListInput);
AddFeature(HashFlag); AddFeature(HashFlag);
AddFeature(LevelFlag); AddFeature(LevelFlag);
this[LevelFlag].AddFeature(ShortFlag); this[LevelFlag]!.AddFeature(ShortFlag);
this[LevelFlag].AddFeature(BaseFlag); this[LevelFlag]!.AddFeature(BaseFlag);
AddFeature(SizeFlag); AddFeature(SizeFlag);
this[SizeFlag].AddFeature(RadixInt64Input); this[SizeFlag]!.AddFeature(RadixInt64Input);
AddFeature(TotalSizeFlag); AddFeature(TotalSizeFlag);
this[TotalSizeFlag].AddFeature(ChunkSizeInt64Input); this[TotalSizeFlag]!.AddFeature(ChunkSizeInt64Input);
AddFeature(TypeFlag); AddFeature(TypeFlag);
} }

View File

@@ -30,7 +30,7 @@ The stats that are outputted are as follows:
- Items that include a SHA-384 - Items that include a SHA-384
- Items that include a SHA-512 - Items that include a SHA-512
- Items with Nodump status"; - Items with Nodump status";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
@@ -43,7 +43,7 @@ The stats that are outputted are as follows:
AddFeature(IndividualFlag); AddFeature(IndividualFlag);
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -29,17 +29,17 @@ namespace SabreTools.Features
// Output Formats // Output Formats
AddFeature(OutputTypeListInput); AddFeature(OutputTypeListInput);
this[OutputTypeListInput].AddFeature(PrefixStringInput); this[OutputTypeListInput]!.AddFeature(PrefixStringInput);
this[OutputTypeListInput].AddFeature(PostfixStringInput); this[OutputTypeListInput]!.AddFeature(PostfixStringInput);
this[OutputTypeListInput].AddFeature(QuotesFlag); this[OutputTypeListInput]!.AddFeature(QuotesFlag);
this[OutputTypeListInput].AddFeature(RomsFlag); this[OutputTypeListInput]!.AddFeature(RomsFlag);
this[OutputTypeListInput].AddFeature(GamePrefixFlag); this[OutputTypeListInput]!.AddFeature(GamePrefixFlag);
this[OutputTypeListInput].AddFeature(AddExtensionStringInput); this[OutputTypeListInput]!.AddFeature(AddExtensionStringInput);
this[OutputTypeListInput].AddFeature(ReplaceExtensionStringInput); this[OutputTypeListInput]!.AddFeature(ReplaceExtensionStringInput);
this[OutputTypeListInput].AddFeature(RemoveExtensionsFlag); this[OutputTypeListInput]!.AddFeature(RemoveExtensionsFlag);
this[OutputTypeListInput].AddFeature(RombaFlag); this[OutputTypeListInput]!.AddFeature(RombaFlag);
this[OutputTypeListInput][RombaFlag].AddFeature(RombaDepthInt32Input); this[OutputTypeListInput][RombaFlag]!.AddFeature(RombaDepthInt32Input);
this[OutputTypeListInput].AddFeature(DeprecatedFlag); this[OutputTypeListInput]!.AddFeature(DeprecatedFlag);
AddHeaderFeatures(); AddHeaderFeatures();
AddFeature(KeepEmptyGamesFlag); AddFeature(KeepEmptyGamesFlag);
@@ -48,35 +48,35 @@ namespace SabreTools.Features
AddFeature(DescriptionAsNameFlag); AddFeature(DescriptionAsNameFlag);
AddInternalSplitFeatures(); AddInternalSplitFeatures();
AddFeature(TrimFlag); AddFeature(TrimFlag);
this[TrimFlag].AddFeature(RootDirStringInput); this[TrimFlag]!.AddFeature(RootDirStringInput);
AddFeature(SingleSetFlag); AddFeature(SingleSetFlag);
AddFeature(DedupFlag); AddFeature(DedupFlag);
AddFeature(GameDedupFlag); AddFeature(GameDedupFlag);
AddFeature(MergeFlag); AddFeature(MergeFlag);
this[MergeFlag].AddFeature(NoAutomaticDateFlag); this[MergeFlag]!.AddFeature(NoAutomaticDateFlag);
AddFeature(DiffAllFlag); AddFeature(DiffAllFlag);
this[DiffAllFlag].AddFeature(NoAutomaticDateFlag); this[DiffAllFlag]!.AddFeature(NoAutomaticDateFlag);
AddFeature(DiffDuplicatesFlag); AddFeature(DiffDuplicatesFlag);
this[DiffDuplicatesFlag].AddFeature(NoAutomaticDateFlag); this[DiffDuplicatesFlag]!.AddFeature(NoAutomaticDateFlag);
AddFeature(DiffIndividualsFlag); AddFeature(DiffIndividualsFlag);
this[DiffIndividualsFlag].AddFeature(NoAutomaticDateFlag); this[DiffIndividualsFlag]!.AddFeature(NoAutomaticDateFlag);
AddFeature(DiffNoDuplicatesFlag); AddFeature(DiffNoDuplicatesFlag);
this[DiffNoDuplicatesFlag].AddFeature(NoAutomaticDateFlag); this[DiffNoDuplicatesFlag]!.AddFeature(NoAutomaticDateFlag);
AddFeature(DiffAgainstFlag); AddFeature(DiffAgainstFlag);
this[DiffAgainstFlag].AddFeature(BaseDatListInput); this[DiffAgainstFlag]!.AddFeature(BaseDatListInput);
this[DiffAgainstFlag].AddFeature(ByGameFlag); this[DiffAgainstFlag]!.AddFeature(ByGameFlag);
AddFeature(BaseReplaceFlag); AddFeature(BaseReplaceFlag);
this[BaseReplaceFlag].AddFeature(BaseDatListInput); this[BaseReplaceFlag]!.AddFeature(BaseDatListInput);
this[BaseReplaceFlag].AddFeature(UpdateFieldListInput); this[BaseReplaceFlag]!.AddFeature(UpdateFieldListInput);
this[BaseReplaceFlag][UpdateFieldListInput].AddFeature(OnlySameFlag); this[BaseReplaceFlag][UpdateFieldListInput]!.AddFeature(OnlySameFlag);
AddFeature(ReverseBaseReplaceFlag); AddFeature(ReverseBaseReplaceFlag);
this[ReverseBaseReplaceFlag].AddFeature(BaseDatListInput); this[ReverseBaseReplaceFlag]!.AddFeature(BaseDatListInput);
this[ReverseBaseReplaceFlag].AddFeature(UpdateFieldListInput); this[ReverseBaseReplaceFlag]!.AddFeature(UpdateFieldListInput);
this[ReverseBaseReplaceFlag][UpdateFieldListInput].AddFeature(OnlySameFlag); this[ReverseBaseReplaceFlag][UpdateFieldListInput]!.AddFeature(OnlySameFlag);
AddFeature(DiffCascadeFlag); AddFeature(DiffCascadeFlag);
this[DiffCascadeFlag].AddFeature(SkipFirstOutputFlag); this[DiffCascadeFlag]!.AddFeature(SkipFirstOutputFlag);
AddFeature(DiffReverseCascadeFlag); AddFeature(DiffReverseCascadeFlag);
this[DiffReverseCascadeFlag].AddFeature(SkipFirstOutputFlag); this[DiffReverseCascadeFlag]!.AddFeature(SkipFirstOutputFlag);
AddFeature(ExtraIniListInput); AddFeature(ExtraIniListInput);
AddFilteringFeatures(); AddFilteringFeatures();
AddFeature(OutputDirStringInput); AddFeature(OutputDirStringInput);
@@ -174,8 +174,7 @@ namespace SabreTools.Features
// Perform additional processing steps // Perform additional processing steps
Extras.ApplyExtras(datFile); Extras.ApplyExtras(datFile);
Splitter.ApplySplitting(datFile, useTags: false); Splitter.ApplySplitting(datFile, useTags: false);
Filter.ApplyFilters(datFile); datFile.ExecuteFilters(FilterRunner);
// datFile.ExecuteFilters(FilterRunner); // TODO: Replace Filter.ApplyFilters with this
Cleaner.ApplyCleaning(datFile); Cleaner.ApplyCleaning(datFile);
Remover.ApplyRemovals(datFile); Remover.ApplyRemovals(datFile);
@@ -218,8 +217,7 @@ namespace SabreTools.Features
// Perform additional processing steps // Perform additional processing steps
Extras.ApplyExtras(userInputDat); Extras.ApplyExtras(userInputDat);
Splitter.ApplySplitting(userInputDat, useTags: false); Splitter.ApplySplitting(userInputDat, useTags: false);
Filter.ApplyFilters(userInputDat); userInputDat.ExecuteFilters(FilterRunner);
// userInputDat.ExecuteFilters(FilterRunner); // TODO: Replace Filter.ApplyFilters with this
Cleaner.ApplyCleaning(userInputDat); Cleaner.ApplyCleaning(userInputDat);
Remover.ApplyRemovals(userInputDat); Remover.ApplyRemovals(userInputDat);
@@ -348,8 +346,7 @@ namespace SabreTools.Features
// Perform additional processing steps // Perform additional processing steps
Extras.ApplyExtras(repDat); Extras.ApplyExtras(repDat);
Splitter.ApplySplitting(repDat, useTags: false); Splitter.ApplySplitting(repDat, useTags: false);
Filter.ApplyFilters(repDat); repDat.ExecuteFilters(FilterRunner);
// repDat.ExecuteFilters(FilterRunner); // TODO: Replace Filter.ApplyFilters with this
Cleaner.ApplyCleaning(repDat); Cleaner.ApplyCleaning(repDat);
Remover.ApplyRemovals(repDat); Remover.ApplyRemovals(repDat);
@@ -385,8 +382,7 @@ namespace SabreTools.Features
// Perform additional processing steps // Perform additional processing steps
Extras.ApplyExtras(repDat); Extras.ApplyExtras(repDat);
Splitter.ApplySplitting(repDat, useTags: false); Splitter.ApplySplitting(repDat, useTags: false);
Filter.ApplyFilters(repDat); repDat.ExecuteFilters(FilterRunner);
// repDat.ExecuteFilters(FilterRunner); // TODO: Replace Filter.ApplyFilters with this
Cleaner.ApplyCleaning(repDat); Cleaner.ApplyCleaning(repDat);
Remover.ApplyRemovals(repDat); Remover.ApplyRemovals(repDat);

View File

@@ -20,14 +20,14 @@ namespace SabreTools.Features
Description = "Verify a folder against DATs"; Description = "Verify a folder against DATs";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "When used, this will use an input DAT or set of DATs to blindly check against an input folder. The base of the folder is considered the base for the combined DATs and games are either the directories or archives within. This will only do a direct verification of the items within and will create a fixdat afterwards for missing files."; LongDescription = "When used, this will use an input DAT or set of DATs to blindly check against an input folder. The base of the folder is considered the base for the combined DATs and games are either the directories or archives within. This will only do a direct verification of the items within and will create a fixdat afterwards for missing files.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
AddFeature(DatListInput); AddFeature(DatListInput);
AddFeature(DepotFlag); AddFeature(DepotFlag);
this[DepotFlag].AddFeature(DepotDepthInt32Input); this[DepotFlag]!.AddFeature(DepotDepthInt32Input);
AddFeature(OutputDirStringInput); AddFeature(OutputDirStringInput);
AddFeature(HashOnlyFlag); AddFeature(HashOnlyFlag);
AddFeature(QuickFlag); AddFeature(QuickFlag);
@@ -40,7 +40,7 @@ namespace SabreTools.Features
AddFilteringFeatures(); AddFilteringFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))
@@ -65,15 +65,14 @@ namespace SabreTools.Features
Parser.ParseInto(datdata, datfile, int.MaxValue, keep: true); Parser.ParseInto(datdata, datfile, int.MaxValue, keep: true);
// Perform additional processing steps // Perform additional processing steps
Extras.ApplyExtras(datdata); Extras!.ApplyExtras(datdata);
Splitter.ApplySplitting(datdata, useTags: true); Splitter!.ApplySplitting(datdata, useTags: true);
Filter.ApplyFilters(datdata); datdata.ExecuteFilters(FilterRunner!);
// datdata.ExecuteFilters(FilterRunner); // TODO: Replace Filter.ApplyFilters with this Cleaner!.ApplyCleaning(datdata);
Cleaner.ApplyCleaning(datdata); Remover!.ApplyRemovals(datdata);
Remover.ApplyRemovals(datdata);
// Set depot information // Set depot information
datdata.Header.InputDepot = Header.InputDepot?.Clone() as DepotInformation; datdata.Header.InputDepot = Header!.InputDepot?.Clone() as DepotInformation;
// If we have overridden the header skipper, set it now // If we have overridden the header skipper, set it now
if (!string.IsNullOrEmpty(Header.HeaderSkipper)) if (!string.IsNullOrEmpty(Header.HeaderSkipper))
@@ -98,7 +97,7 @@ namespace SabreTools.Features
// Now write out if there are any items left // Now write out if there are any items left
Writer.WriteStatsToConsole(datdata); Writer.WriteStatsToConsole(datdata);
Writer.Write(datdata, OutputDir); Writer.Write(datdata, OutputDir!);
} }
} }
// Otherwise, process all DATs into the same output // Otherwise, process all DATs into the same output
@@ -114,15 +113,14 @@ namespace SabreTools.Features
} }
// Perform additional processing steps // Perform additional processing steps
Extras.ApplyExtras(datdata); Extras!.ApplyExtras(datdata);
Splitter.ApplySplitting(datdata, useTags: true); Splitter!.ApplySplitting(datdata, useTags: true);
Filter.ApplyFilters(datdata); datdata.ExecuteFilters(FilterRunner!);
// datdata.ExecuteFilters(FilterRunner); // TODO: Replace Filter.ApplyFilters with this Cleaner!.ApplyCleaning(datdata);
Cleaner.ApplyCleaning(datdata); Remover!.ApplyRemovals(datdata);
Remover.ApplyRemovals(datdata);
// Set depot information // Set depot information
datdata.Header.InputDepot = Header.InputDepot?.Clone() as DepotInformation; datdata.Header.InputDepot = Header!.InputDepot?.Clone() as DepotInformation;
// If we have overridden the header skipper, set it now // If we have overridden the header skipper, set it now
if (!string.IsNullOrEmpty(Header.HeaderSkipper)) if (!string.IsNullOrEmpty(Header.HeaderSkipper))
@@ -149,7 +147,7 @@ namespace SabreTools.Features
// Now write out if there are any items left // Now write out if there are any items left
Writer.WriteStatsToConsole(datdata); Writer.WriteStatsToConsole(datdata);
Writer.Write(datdata, OutputDir); Writer.Write(datdata, OutputDir!);
} }
return true; return true;

View File

@@ -16,13 +16,13 @@ namespace SabreTools.Features
Description = "Prints version"; Description = "Prints version";
_featureType = ParameterType.Flag; _featureType = ParameterType.Flag;
LongDescription = "Prints current program version."; LongDescription = "Prints current program version.";
Features = new Dictionary<string, Feature>(); Features = [];
// Common Features // Common Features
AddCommonFeatures(); AddCommonFeatures();
} }
public override bool ProcessFeatures(Dictionary<string, Feature> features) public override bool ProcessFeatures(Dictionary<string, Feature?> features)
{ {
// If the base fails, just fail out // If the base fails, just fail out
if (!base.ProcessFeatures(features)) if (!base.ProcessFeatures(features))

View File

@@ -109,7 +109,7 @@ namespace SabreTools
} }
// Now process the current feature // Now process the current feature
Dictionary<string, Feature> features = _help.GetEnabledFeatures(); Dictionary<string, Feature?> features = _help.GetEnabledFeatures();
bool success = false; bool success = false;
switch (featureName) switch (featureName)
{ {

View File

@@ -5,6 +5,7 @@
<TargetFrameworks>net6.0;net8.0</TargetFrameworks> <TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<Authors>Matt Nadareski</Authors> <Authors>Matt Nadareski</Authors>
<Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright> <Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>