mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Enforce nullability in SabreTools program
This commit is contained in:
@@ -39,7 +39,7 @@ namespace SabreTools.DatTools
|
||||
/// <returns>True if the DAT was written correctly, false otherwise</returns>
|
||||
public static bool Write(
|
||||
DatFile datFile,
|
||||
string outDir,
|
||||
string ?outDir,
|
||||
bool overwrite = true,
|
||||
bool ignoreblanks = false,
|
||||
bool quotes = true,
|
||||
@@ -53,7 +53,7 @@ namespace SabreTools.DatTools
|
||||
}
|
||||
|
||||
// Ensure the output directory is set and created
|
||||
outDir = outDir.Ensure(create: true);
|
||||
outDir = outDir?.Ensure(create: true);
|
||||
|
||||
InternalStopwatch watch = new($"Writing out internal dat to '{outDir}'");
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace SabreTools.DatTools
|
||||
logger.User($"A total of {datFile.Items.TotalCount - datFile.Items.RemovedCount} items will be written out to '{datFile.Header.FileName}'");
|
||||
|
||||
// Get the outfile names
|
||||
Dictionary<DatFormat, string> outfiles = datFile.Header.CreateOutFileNames(outDir, overwrite);
|
||||
Dictionary<DatFormat, string> outfiles = datFile.Header.CreateOutFileNames(outDir!, overwrite);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using SabreTools.Core;
|
||||
using SabreTools.Core.Tools;
|
||||
using SabreTools.DatFiles;
|
||||
@@ -25,7 +24,7 @@ namespace SabreTools.Features
|
||||
public Batch()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "bt", "batch" };
|
||||
Flags = ["bt", "batch"];
|
||||
Description = "Enable batch mode";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = @"Run a special mode that takes input files as lists of batch commands to run sequentially. Each command has to be its own line and must be followed by a semicolon (`;`). Commented lines may start with either `REM` or `#`. Multiple batch files are allowed but they will be run independently from each other.
|
||||
@@ -62,7 +61,7 @@ Reset the internal state: reset();";
|
||||
// Try to read each input as a batch run file
|
||||
foreach (string path in Inputs)
|
||||
{
|
||||
InternalStopwatch watch = new($"Processing '{path}'...");
|
||||
var watch = new InternalStopwatch($"Processing '{path}'...");
|
||||
ProcessScript(path);
|
||||
watch.Stop();
|
||||
}
|
||||
@@ -90,7 +89,7 @@ Reset the internal state: reset();";
|
||||
string[] lines = File.ReadAllLines(path);
|
||||
|
||||
// Each batch file has its own state
|
||||
BatchState batchState = new();
|
||||
var batchState = new BatchState();
|
||||
|
||||
// Process each command line
|
||||
foreach (string line in lines)
|
||||
@@ -139,7 +138,7 @@ Reset the internal state: reset();";
|
||||
/// </summary>
|
||||
private abstract class BatchCommand
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public List<string> Arguments { get; private set; } = [];
|
||||
|
||||
/// <summary>
|
||||
@@ -872,12 +871,12 @@ Reset the internal state: reset();";
|
||||
public override void Process(BatchState batchState)
|
||||
{
|
||||
// Get overwrite value, if possible
|
||||
bool? overwrite = true;
|
||||
bool overwrite = true;
|
||||
if (Arguments.Count == 1)
|
||||
overwrite = Arguments[0].AsYesNo();
|
||||
overwrite = Arguments[0].AsYesNo() ?? true;
|
||||
|
||||
// Write out the dat with the current state
|
||||
Writer.Write(batchState.DatFile, batchState.OutputDirectory, overwrite: overwrite.Value);
|
||||
Writer.Write(batchState.DatFile, batchState.OutputDirectory, overwrite: overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace SabreTools.Features
|
||||
public DatFromDir()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "d", "d2d", "dfd" };
|
||||
Flags = ["d", "d2d", "dfd"];
|
||||
Description = "Create DAT(s) from an input directory";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = "Create a DAT file from an input directory or set of files. By default, this will output a DAT named based on the input directory and the current date. It will also treat all archives as possible games and add all three hashes (CRC, MD5, SHA-1) for each file.";
|
||||
Features = new Dictionary<string, Help.Feature>();
|
||||
Features = [];
|
||||
|
||||
// Common Features
|
||||
AddCommonFeatures();
|
||||
@@ -68,10 +68,10 @@ namespace SabreTools.Features
|
||||
|
||||
// Apply the specialized field removals to the cleaner
|
||||
if (!addFileDates)
|
||||
Remover.PopulateExclusionsFromList(new List<string> { "DatItem.Date" });
|
||||
Remover!.PopulateExclusionsFromList(["DatItem.Date"]);
|
||||
|
||||
// Create a new DATFromDir object and process the inputs
|
||||
DatFile basedat = DatFile.Create(Header);
|
||||
DatFile basedat = DatFile.Create(Header!);
|
||||
basedat.Header.Date = DateTime.Now.ToString("yyyy-MM-dd");
|
||||
|
||||
// For each input directory, create a DAT
|
||||
@@ -98,11 +98,11 @@ namespace SabreTools.Features
|
||||
if (success)
|
||||
{
|
||||
// Perform additional processing steps
|
||||
Extras.ApplyExtras(datdata);
|
||||
Splitter.ApplySplitting(datdata, useTags: false);
|
||||
datdata.ExecuteFilters(FilterRunner);
|
||||
Cleaner.ApplyCleaning(datdata);
|
||||
Remover.ApplyRemovals(datdata);
|
||||
Extras!.ApplyExtras(datdata);
|
||||
Splitter!.ApplySplitting(datdata, useTags: false);
|
||||
datdata.ExecuteFilters(FilterRunner!);
|
||||
Cleaner!.ApplyCleaning(datdata);
|
||||
Remover!.ApplyRemovals(datdata);
|
||||
|
||||
// Write out the file
|
||||
Writer.Write(datdata, OutputDir);
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using SabreTools.Help;
|
||||
using SabreTools.Help;
|
||||
|
||||
namespace SabreTools.Features
|
||||
{
|
||||
@@ -11,7 +9,7 @@ namespace SabreTools.Features
|
||||
public DisplayHelp()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "?", "h", "help" };
|
||||
Flags = ["?", "h", "help"];
|
||||
Description = "Show this help";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = "Built-in to most of the programs is a basic help text.";
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using SabreTools.Help;
|
||||
using SabreTools.Help;
|
||||
|
||||
namespace SabreTools.Features
|
||||
{
|
||||
@@ -11,7 +9,7 @@ namespace SabreTools.Features
|
||||
public DisplayHelpDetailed()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "??", "hd", "help-detailed" };
|
||||
Flags = ["??", "hd", "help-detailed"];
|
||||
Description = "Show this detailed help";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = "Display a detailed help text to the screen.";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using SabreTools.Core;
|
||||
using SabreTools.Core.Tools;
|
||||
using SabreTools.FileTypes;
|
||||
using SabreTools.Hashing;
|
||||
@@ -18,7 +17,7 @@ namespace SabreTools.Features
|
||||
public Extract()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "ex", "extract" };
|
||||
Flags = ["ex", "extract"];
|
||||
Description = "Extract and remove copier headers";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = @"This will detect, store, and remove copier headers from a file or folder of files. The headers are backed up and collated by the hash of the unheadered file. Files are then output without the detected copier header alongside the originals with the suffix .new. No input files are altered in the process. Only uncompressed files will be processed.
|
||||
@@ -67,7 +66,7 @@ The following systems have headers that this program can work with:
|
||||
/// <param name="outDir">Output directory to write the file to, empty means the same directory as the input file</param>
|
||||
/// <param name="nostore">True if headers should not be stored in the database, false otherwise</param>
|
||||
/// <returns>True if the output file was created, false otherwise</returns>
|
||||
private bool DetectTransformStore(string file, string outDir, bool nostore)
|
||||
private bool DetectTransformStore(string file, string? outDir, bool nostore)
|
||||
{
|
||||
// Create the output directory if it doesn't exist
|
||||
if (!string.IsNullOrWhiteSpace(outDir) && !Directory.Exists(outDir))
|
||||
@@ -91,9 +90,10 @@ The following systems have headers that this program can work with:
|
||||
{
|
||||
// Extract the header as a string for the database
|
||||
using var fs = File.OpenRead(file);
|
||||
byte[] hbin = new byte[int.Parse(rule.StartOffset)];
|
||||
fs.Read(hbin, 0, int.Parse(rule.StartOffset));
|
||||
hstr = TextHelper.ByteArrayToString(hbin);
|
||||
int startOffset = int.Parse(rule.StartOffset ?? "0");
|
||||
byte[] hbin = new byte[startOffset];
|
||||
fs.Read(hbin, 0, startOffset);
|
||||
hstr = TextHelper.ByteArrayToString(hbin)!;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -101,7 +101,7 @@ The following systems have headers that this program can work with:
|
||||
}
|
||||
|
||||
// Apply the rule to the file
|
||||
string newfile = (string.IsNullOrWhiteSpace(outDir) ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file)));
|
||||
string newfile = string.IsNullOrWhiteSpace(outDir) ? Path.GetFullPath(file) + ".new" : Path.Combine(outDir, Path.GetFileName(file));
|
||||
rule.TransformFile(file, newfile);
|
||||
|
||||
// If the output file doesn't exist, return false
|
||||
@@ -111,8 +111,8 @@ The following systems have headers that this program can work with:
|
||||
// Now add the information to the database if it's not already there
|
||||
if (!nostore)
|
||||
{
|
||||
BaseFile baseFile = BaseFile.GetInfo(newfile, hashes: [HashType.SHA1], asFiles: TreatAsFile.NonArchive);
|
||||
AddHeaderToDatabase(hstr, TextHelper.ByteArrayToString(baseFile.SHA1), rule.SourceFile);
|
||||
BaseFile? baseFile = BaseFile.GetInfo(newfile, hashes: [HashType.SHA1], asFiles: TreatAsFile.NonArchive);
|
||||
AddHeaderToDatabase(hstr, TextHelper.ByteArrayToString(baseFile!.SHA1)!, rule.SourceFile!);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using SabreTools.Core;
|
||||
using SabreTools.Core.Tools;
|
||||
using SabreTools.FileTypes;
|
||||
using SabreTools.Hashing;
|
||||
@@ -17,7 +16,7 @@ namespace SabreTools.Features
|
||||
public Restore()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "re", "restore" };
|
||||
Flags = ["re", "restore"];
|
||||
Description = "Restore header to file based on SHA-1";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = @"This will make use of stored copier headers and reapply them to files if they match the included hash. More than one header can be applied to a file, so they will be output to new files, suffixed with .newX, where X is a number. No input files are altered in the process. Only uncompressed files will be processed.
|
||||
@@ -61,17 +60,17 @@ The following systems have headers that this program can work with:
|
||||
/// <param name="file">Name of the file to be parsed</param>
|
||||
/// <param name="outDir">Output directory to write the file to, empty means the same directory as the input file</param>
|
||||
/// <returns>True if a header was found and appended, false otherwise</returns>
|
||||
public bool RestoreHeader(string file, string outDir)
|
||||
public bool RestoreHeader(string file, string? outDir)
|
||||
{
|
||||
// Create the output directory if it doesn't exist
|
||||
if (!string.IsNullOrWhiteSpace(outDir) && !Directory.Exists(outDir))
|
||||
Directory.CreateDirectory(outDir);
|
||||
|
||||
// First, get the SHA-1 hash of the file
|
||||
BaseFile baseFile = BaseFile.GetInfo(file, hashes: [HashType.SHA1], asFiles: TreatAsFile.NonArchive);
|
||||
BaseFile? baseFile = BaseFile.GetInfo(file, hashes: [HashType.SHA1], asFiles: TreatAsFile.NonArchive);
|
||||
|
||||
// Retrieve a list of all related headers from the database
|
||||
List<string> headers = RetrieveHeadersFromDatabase(TextHelper.ByteArrayToString(baseFile.SHA1));
|
||||
List<string> headers = RetrieveHeadersFromDatabase(TextHelper.ByteArrayToString(baseFile!.SHA1)!);
|
||||
|
||||
// If we have nothing retrieved, we return false
|
||||
if (headers.Count == 0)
|
||||
@@ -100,14 +99,14 @@ The following systems have headers that this program can work with:
|
||||
EnsureDatabase();
|
||||
|
||||
// Open the database connection
|
||||
SqliteConnection dbc = new(HeadererConnectionString);
|
||||
SqliteConnection dbc = new SqliteConnection(HeadererConnectionString);
|
||||
dbc.Open();
|
||||
|
||||
// Create the output list of headers
|
||||
List<string> headers = new();
|
||||
List<string> headers = [];
|
||||
|
||||
string query = $"SELECT header, type FROM data WHERE sha1='{SHA1}'";
|
||||
SqliteCommand slc = new(query, dbc);
|
||||
SqliteCommand slc = new SqliteCommand(query, dbc);
|
||||
SqliteDataReader sldr = slc.ExecuteReader();
|
||||
|
||||
if (sldr.HasRows)
|
||||
@@ -138,7 +137,7 @@ The following systems have headers that this program can work with:
|
||||
/// <param name="output">Outputted file</param>
|
||||
/// <param name="bytesToAddToHead">Bytes to be added to head of file</param>
|
||||
/// <param name="bytesToAddToTail">Bytes to be added to tail of file</param>
|
||||
private static void AppendBytes(string input, string output, byte[] bytesToAddToHead, byte[] bytesToAddToTail)
|
||||
private static void AppendBytes(string input, string output, byte[]? bytesToAddToHead, byte[]? bytesToAddToTail)
|
||||
{
|
||||
// If any of the inputs are invalid, skip
|
||||
if (!File.Exists(input))
|
||||
@@ -157,7 +156,7 @@ The following systems have headers that this program can work with:
|
||||
/// <param name="output">Outputted stream</param>
|
||||
/// <param name="bytesToAddToHead">Bytes to be added to head of stream</param>
|
||||
/// <param name="bytesToAddToTail">Bytes to be added to tail of stream</param>
|
||||
private static void AppendBytes(Stream input, Stream output, byte[] bytesToAddToHead, byte[] bytesToAddToTail)
|
||||
private static void AppendBytes(Stream input, Stream output, byte[]? bytesToAddToHead, byte[]? bytesToAddToTail)
|
||||
{
|
||||
// Write out prepended bytes
|
||||
if (bytesToAddToHead != null && bytesToAddToHead.Length > 0)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using SabreTools.DatFiles;
|
||||
using SabreTools.DatTools;
|
||||
using SabreTools.FileTypes;
|
||||
@@ -17,7 +16,7 @@ namespace SabreTools.Features
|
||||
public Sort()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "ss", "sort" };
|
||||
Flags = ["ss", "sort"];
|
||||
Description = "Sort inputs by a set of DATs";
|
||||
_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.";
|
||||
@@ -43,7 +42,7 @@ namespace SabreTools.Features
|
||||
AddFeature(TarFlag);
|
||||
AddFeature(TorrentGzipFlag);
|
||||
this[TorrentGzipFlag]!.AddFeature(RombaFlag);
|
||||
this[TorrentGzipFlag][RombaFlag]!.AddFeature(RombaDepthInt32Input);
|
||||
this[TorrentGzipFlag]![RombaFlag]!.AddFeature(RombaDepthInt32Input);
|
||||
//AddFeature(SharedInputs.TorrentLrzipFlag);
|
||||
//AddFeature(SharedInputs.TorrentLz4Flag);
|
||||
//AddFeature(SharedInputs.TorrentRarFlag);
|
||||
@@ -74,7 +73,7 @@ namespace SabreTools.Features
|
||||
var outputFormat = GetOutputFormat(features);
|
||||
|
||||
// If we have the romba flag
|
||||
if (Header.OutputDepot?.IsActive == true)
|
||||
if (Header!.OutputDepot?.IsActive == true)
|
||||
{
|
||||
// Update TorrentGzip output
|
||||
if (outputFormat == OutputFormat.TorrentGzip)
|
||||
@@ -108,9 +107,9 @@ namespace SabreTools.Features
|
||||
// If we have the depot flag, respect it
|
||||
bool success;
|
||||
if (Header.InputDepot?.IsActive ?? false)
|
||||
success = Rebuilder.RebuildDepot(datdata, Inputs, Path.Combine(OutputDir, datdata.Header.FileName), date, delete, inverse, outputFormat);
|
||||
success = Rebuilder.RebuildDepot(datdata, Inputs, Path.Combine(OutputDir!, datdata.Header.FileName!), date, delete, inverse, outputFormat);
|
||||
else
|
||||
success = Rebuilder.RebuildGeneric(datdata, Inputs, Path.Combine(OutputDir, datdata.Header.FileName), quickScan, date, delete, inverse, outputFormat, asFiles);
|
||||
success = Rebuilder.RebuildGeneric(datdata, Inputs, Path.Combine(OutputDir!, datdata.Header.FileName!), quickScan, date, delete, inverse, outputFormat, asFiles);
|
||||
|
||||
// If we have a success and we're updating the DAT, write it out
|
||||
if (success && updateDat)
|
||||
@@ -127,7 +126,7 @@ namespace SabreTools.Features
|
||||
// Otherwise, process all DATs into the same output
|
||||
else
|
||||
{
|
||||
InternalStopwatch watch = new("Populating internal DAT");
|
||||
var watch = new InternalStopwatch("Populating internal DAT");
|
||||
|
||||
// Add all of the input DATs into one huge internal DAT
|
||||
DatFile datdata = DatFile.Create();
|
||||
@@ -149,9 +148,9 @@ namespace SabreTools.Features
|
||||
// If we have the depot flag, respect it
|
||||
bool success;
|
||||
if (Header.InputDepot?.IsActive ?? false)
|
||||
success = Rebuilder.RebuildDepot(datdata, Inputs, OutputDir, date, delete, inverse, outputFormat);
|
||||
success = Rebuilder.RebuildDepot(datdata, Inputs, OutputDir!, date, delete, inverse, outputFormat);
|
||||
else
|
||||
success = Rebuilder.RebuildGeneric(datdata, Inputs, OutputDir, quickScan, date, delete, inverse, outputFormat, asFiles);
|
||||
success = Rebuilder.RebuildGeneric(datdata, Inputs, OutputDir!, quickScan, date, delete, inverse, outputFormat, asFiles);
|
||||
|
||||
// If we have a success and we're updating the DAT, write it out
|
||||
if (success && updateDat)
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace SabreTools.Features
|
||||
public Split()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "sp", "split" };
|
||||
Flags = ["sp", "split"];
|
||||
Description = "Split input DATs by a given criteria";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = "This feature allows the user to split input DATs by a number of different possible criteria. See the individual input information for details. More than one split type is allowed at a time.";
|
||||
Features = new Dictionary<string, Help.Feature>();
|
||||
Features = [];
|
||||
|
||||
// Common Features
|
||||
AddCommonFeatures();
|
||||
@@ -64,7 +64,7 @@ namespace SabreTools.Features
|
||||
foreach (ParentablePath file in files)
|
||||
{
|
||||
// Create and fill the new DAT
|
||||
DatFile internalDat = DatFile.Create(Header);
|
||||
DatFile internalDat = DatFile.Create(Header!);
|
||||
Parser.ParseInto(internalDat, file);
|
||||
|
||||
// Get the output directory
|
||||
@@ -75,14 +75,16 @@ namespace SabreTools.Features
|
||||
if (splittingMode.HasFlag(SplittingMode.Extension))
|
||||
{
|
||||
(DatFile? extADat, DatFile? extBDat) = DatTools.Splitter.SplitByExtension(internalDat, GetList(features, ExtAListValue), GetList(features, ExtBListValue));
|
||||
if (extADat != null && extBDat != null)
|
||||
{
|
||||
var watch = new InternalStopwatch("Outputting extension-split DATs");
|
||||
|
||||
InternalStopwatch watch = new("Outputting extension-split DATs");
|
||||
// Output both possible DatFiles
|
||||
Writer.Write(extADat, OutputDir);
|
||||
Writer.Write(extBDat, OutputDir);
|
||||
|
||||
// Output both possible DatFiles
|
||||
Writer.Write(extADat, OutputDir);
|
||||
Writer.Write(extBDat, OutputDir);
|
||||
|
||||
watch.Stop();
|
||||
watch.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
// Hash splitting
|
||||
@@ -90,7 +92,7 @@ namespace SabreTools.Features
|
||||
{
|
||||
Dictionary<string, DatFile> typeDats = DatTools.Splitter.SplitByHash(internalDat);
|
||||
|
||||
InternalStopwatch watch = new("Outputting hash-split DATs");
|
||||
var watch = new InternalStopwatch("Outputting hash-split DATs");
|
||||
|
||||
// Loop through each type DatFile
|
||||
#if NET452_OR_GREATER || NETCOREAPP
|
||||
@@ -117,7 +119,7 @@ namespace SabreTools.Features
|
||||
logger.Warning("This feature is not implemented: level-split");
|
||||
DatTools.Splitter.SplitByLevel(
|
||||
internalDat,
|
||||
OutputDir,
|
||||
OutputDir!,
|
||||
GetBoolean(features, ShortValue),
|
||||
GetBoolean(features, BaseValue));
|
||||
}
|
||||
@@ -127,7 +129,7 @@ namespace SabreTools.Features
|
||||
{
|
||||
(DatFile lessThan, DatFile greaterThan) = DatTools.Splitter.SplitBySize(internalDat, GetInt64(features, RadixInt64Value));
|
||||
|
||||
InternalStopwatch watch = new("Outputting size-split DATs");
|
||||
var watch = new InternalStopwatch("Outputting size-split DATs");
|
||||
|
||||
// Output both possible DatFiles
|
||||
Writer.Write(lessThan, OutputDir);
|
||||
@@ -142,7 +144,7 @@ namespace SabreTools.Features
|
||||
logger.Warning("This feature is not implemented: level-split");
|
||||
List<DatFile> sizedDats = DatTools.Splitter.SplitByTotalSize(internalDat, GetInt64(features, ChunkSizeInt64Value));
|
||||
|
||||
InternalStopwatch watch = new("Outputting total-size-split DATs");
|
||||
var watch = new InternalStopwatch("Outputting total-size-split DATs");
|
||||
|
||||
// Loop through each type DatFile
|
||||
#if NET452_OR_GREATER || NETCOREAPP
|
||||
@@ -168,7 +170,7 @@ namespace SabreTools.Features
|
||||
{
|
||||
Dictionary<ItemType, DatFile> typeDats = DatTools.Splitter.SplitByType(internalDat);
|
||||
|
||||
InternalStopwatch watch = new("Outputting ItemType DATs");
|
||||
var watch = new InternalStopwatch("Outputting ItemType DATs");
|
||||
|
||||
// Loop through each type DatFile
|
||||
#if NET452_OR_GREATER || NETCOREAPP
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace SabreTools.Features
|
||||
public Stats()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "st", "stats" };
|
||||
Flags = ["st", "stats"];
|
||||
Description = "Get statistics on all input DATs";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = @"This will output by default the combined statistics for all input DAT files.
|
||||
@@ -49,13 +49,13 @@ The stats that are outputted are as follows:
|
||||
if (!base.ProcessFeatures(features))
|
||||
return false;
|
||||
|
||||
string filename = Header.FileName;
|
||||
string filename = Header!.FileName!;
|
||||
if (Path.GetFileName(filename) != filename)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(OutputDir))
|
||||
OutputDir = Path.GetDirectoryName(filename);
|
||||
else
|
||||
OutputDir = Path.Combine(OutputDir, Path.GetDirectoryName(filename));
|
||||
OutputDir = Path.Combine(OutputDir, Path.GetDirectoryName(filename)!);
|
||||
|
||||
filename = Path.GetFileName(filename);
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace SabreTools.Features
|
||||
public Update()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "ud", "update" };
|
||||
Flags = ["ud", "update"];
|
||||
Description = "Update and manipulate DAT(s)";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = "This is the multitool part of the program, allowing for almost every manipulation to a DAT, or set of DATs. This is also a combination of many different programs that performed DAT manipulation that work better together.";
|
||||
Features = new Dictionary<string, Help.Feature>();
|
||||
Features = [];
|
||||
|
||||
// Common Features
|
||||
AddCommonFeatures();
|
||||
@@ -38,7 +38,7 @@ namespace SabreTools.Features
|
||||
this[OutputTypeListInput]!.AddFeature(ReplaceExtensionStringInput);
|
||||
this[OutputTypeListInput]!.AddFeature(RemoveExtensionsFlag);
|
||||
this[OutputTypeListInput]!.AddFeature(RombaFlag);
|
||||
this[OutputTypeListInput][RombaFlag]!.AddFeature(RombaDepthInt32Input);
|
||||
this[OutputTypeListInput]![RombaFlag]!.AddFeature(RombaDepthInt32Input);
|
||||
this[OutputTypeListInput]!.AddFeature(DeprecatedFlag);
|
||||
|
||||
AddHeaderFeatures();
|
||||
@@ -68,11 +68,11 @@ namespace SabreTools.Features
|
||||
AddFeature(BaseReplaceFlag);
|
||||
this[BaseReplaceFlag]!.AddFeature(BaseDatListInput);
|
||||
this[BaseReplaceFlag]!.AddFeature(UpdateFieldListInput);
|
||||
this[BaseReplaceFlag][UpdateFieldListInput]!.AddFeature(OnlySameFlag);
|
||||
this[BaseReplaceFlag]![UpdateFieldListInput]!.AddFeature(OnlySameFlag);
|
||||
AddFeature(ReverseBaseReplaceFlag);
|
||||
this[ReverseBaseReplaceFlag]!.AddFeature(BaseDatListInput);
|
||||
this[ReverseBaseReplaceFlag]!.AddFeature(UpdateFieldListInput);
|
||||
this[ReverseBaseReplaceFlag][UpdateFieldListInput]!.AddFeature(OnlySameFlag);
|
||||
this[ReverseBaseReplaceFlag]![UpdateFieldListInput]!.AddFeature(OnlySameFlag);
|
||||
AddFeature(DiffCascadeFlag);
|
||||
this[DiffCascadeFlag]!.AddFeature(SkipFirstOutputFlag);
|
||||
AddFeature(DiffReverseCascadeFlag);
|
||||
@@ -95,7 +95,7 @@ namespace SabreTools.Features
|
||||
var updateMode = GetUpdateMode(features);
|
||||
|
||||
// Normalize the extensions
|
||||
Header.AddExtension = (string.IsNullOrWhiteSpace(Header.AddExtension) || Header.AddExtension.StartsWith(".")
|
||||
Header!.AddExtension = (string.IsNullOrWhiteSpace(Header.AddExtension) || Header.AddExtension.StartsWith(".")
|
||||
? Header.AddExtension
|
||||
: $".{Header.AddExtension}");
|
||||
Header.ReplaceExtension = (string.IsNullOrWhiteSpace(Header.ReplaceExtension) || Header.ReplaceExtension.StartsWith(".")
|
||||
@@ -114,14 +114,14 @@ namespace SabreTools.Features
|
||||
{
|
||||
Header.Name = (updateMode != 0 ? "DiffDAT" : "MergeDAT")
|
||||
+ (Header.Type == "SuperDAT" ? "-SuperDAT" : string.Empty)
|
||||
+ (Cleaner.DedupeRoms != DedupeType.None ? "-deduped" : string.Empty);
|
||||
+ (Cleaner!.DedupeRoms != DedupeType.None ? "-deduped" : string.Empty);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Header.Description))
|
||||
{
|
||||
Header.Description = (updateMode != 0 ? "DiffDAT" : "MergeDAT")
|
||||
+ (Header.Type == "SuperDAT" ? "-SuperDAT" : string.Empty)
|
||||
+ (Cleaner.DedupeRoms != DedupeType.None ? " - deduped" : string.Empty);
|
||||
+ (Cleaner!.DedupeRoms != DedupeType.None ? " - deduped" : string.Empty);
|
||||
|
||||
if (!GetBoolean(features, NoAutomaticDateValue))
|
||||
Header.Description += $" ({Header.Date})";
|
||||
@@ -149,7 +149,7 @@ namespace SabreTools.Features
|
||||
List<ParentablePath> basePaths = PathTool.GetFilesOnly(GetList(features, BaseDatListValue));
|
||||
|
||||
// Ensure the output directory
|
||||
OutputDir = OutputDir.Ensure();
|
||||
OutputDir = OutputDir?.Ensure();
|
||||
|
||||
// If we're in standard update mode, run through all of the inputs
|
||||
if (updateMode == UpdateMode.None)
|
||||
@@ -172,14 +172,14 @@ namespace SabreTools.Features
|
||||
|| datFile.Header.DatFormat.HasFlag(DatFormat.SSV));
|
||||
|
||||
// Perform additional processing steps
|
||||
Extras.ApplyExtras(datFile);
|
||||
Splitter.ApplySplitting(datFile, useTags: false);
|
||||
datFile.ExecuteFilters(FilterRunner);
|
||||
Cleaner.ApplyCleaning(datFile);
|
||||
Remover.ApplyRemovals(datFile);
|
||||
Extras!.ApplyExtras(datFile);
|
||||
Splitter!.ApplySplitting(datFile, useTags: false);
|
||||
datFile.ExecuteFilters(FilterRunner!);
|
||||
Cleaner!.ApplyCleaning(datFile);
|
||||
Remover!.ApplyRemovals(datFile);
|
||||
|
||||
// Get the correct output path
|
||||
string realOutDir = inputPath.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue));
|
||||
string realOutDir = inputPath.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue))!;
|
||||
|
||||
// Try to output the file, overwriting only if it's not in the current directory
|
||||
Writer.Write(datFile, realOutDir, overwrite: GetBoolean(features, InplaceValue));
|
||||
@@ -215,11 +215,11 @@ namespace SabreTools.Features
|
||||
datHeaders = DatFileTool.PopulateUserData(userInputDat, inputPaths);
|
||||
|
||||
// Perform additional processing steps
|
||||
Extras.ApplyExtras(userInputDat);
|
||||
Splitter.ApplySplitting(userInputDat, useTags: false);
|
||||
userInputDat.ExecuteFilters(FilterRunner);
|
||||
Cleaner.ApplyCleaning(userInputDat);
|
||||
Remover.ApplyRemovals(userInputDat);
|
||||
Extras!.ApplyExtras(userInputDat);
|
||||
Splitter!.ApplySplitting(userInputDat, useTags: false);
|
||||
userInputDat.ExecuteFilters(FilterRunner!);
|
||||
Cleaner!.ApplyCleaning(userInputDat);
|
||||
Remover!.ApplyRemovals(userInputDat);
|
||||
|
||||
// Output only DatItems that are duplicated across inputs
|
||||
if (updateMode.HasFlag(UpdateMode.DiffDupesOnly))
|
||||
@@ -258,7 +258,7 @@ namespace SabreTools.Features
|
||||
for (int j = 0; j < inputPaths.Count; j++)
|
||||
#endif
|
||||
{
|
||||
string path = inputPaths[j].GetOutputPath(OutputDir, GetBoolean(features, InplaceValue));
|
||||
string path = inputPaths[j].GetOutputPath(OutputDir, GetBoolean(features, InplaceValue))!;
|
||||
|
||||
// Try to output the file
|
||||
Writer.Write(datFiles[j], path, overwrite: GetBoolean(features, InplaceValue));
|
||||
@@ -314,7 +314,7 @@ namespace SabreTools.Features
|
||||
for (int j = startIndex; j < inputPaths.Count; j++)
|
||||
#endif
|
||||
{
|
||||
string path = inputPaths[j].GetOutputPath(OutputDir, GetBoolean(features, InplaceValue));
|
||||
string path = inputPaths[j].GetOutputPath(OutputDir, GetBoolean(features, InplaceValue))!;
|
||||
|
||||
// Try to output the file
|
||||
Writer.Write(datFiles[j], path, overwrite: GetBoolean(features, InplaceValue));
|
||||
@@ -346,7 +346,7 @@ namespace SabreTools.Features
|
||||
// Perform additional processing steps
|
||||
Extras.ApplyExtras(repDat);
|
||||
Splitter.ApplySplitting(repDat, useTags: false);
|
||||
repDat.ExecuteFilters(FilterRunner);
|
||||
repDat.ExecuteFilters(FilterRunner!);
|
||||
Cleaner.ApplyCleaning(repDat);
|
||||
Remover.ApplyRemovals(repDat);
|
||||
|
||||
@@ -354,7 +354,7 @@ namespace SabreTools.Features
|
||||
DatFileTool.DiffAgainst(userInputDat, repDat, GetBoolean(Features, ByGameValue));
|
||||
|
||||
// Finally output the diffed DatFile
|
||||
string interOutDir = inputPath.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue));
|
||||
string interOutDir = inputPath.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue))!;
|
||||
Writer.Write(repDat, interOutDir, overwrite: GetBoolean(features, InplaceValue));
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
});
|
||||
@@ -382,7 +382,7 @@ namespace SabreTools.Features
|
||||
// Perform additional processing steps
|
||||
Extras.ApplyExtras(repDat);
|
||||
Splitter.ApplySplitting(repDat, useTags: false);
|
||||
repDat.ExecuteFilters(FilterRunner);
|
||||
repDat.ExecuteFilters(FilterRunner!);
|
||||
Cleaner.ApplyCleaning(repDat);
|
||||
Remover.ApplyRemovals(repDat);
|
||||
|
||||
@@ -395,7 +395,7 @@ namespace SabreTools.Features
|
||||
GetBoolean(features, OnlySameValue));
|
||||
|
||||
// Finally output the replaced DatFile
|
||||
string interOutDir = inputPath.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue));
|
||||
string interOutDir = inputPath.GetOutputPath(OutputDir, GetBoolean(features, InplaceValue))!;
|
||||
Writer.Write(repDat, interOutDir, overwrite: GetBoolean(features, InplaceValue));
|
||||
#if NET40_OR_GREATER || NETCOREAPP
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace SabreTools.Features
|
||||
public Verify()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "ve", "verify" };
|
||||
Flags = ["ve", "verify"];
|
||||
Description = "Verify a folder against DATs";
|
||||
_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.";
|
||||
@@ -103,7 +103,7 @@ namespace SabreTools.Features
|
||||
// Otherwise, process all DATs into the same output
|
||||
else
|
||||
{
|
||||
InternalStopwatch watch = new("Populating internal DAT");
|
||||
var watch = new InternalStopwatch("Populating internal DAT");
|
||||
|
||||
// Add all of the input DATs into one huge internal DAT
|
||||
DatFile datdata = DatFile.Create();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using SabreTools.Core;
|
||||
using SabreTools.Help;
|
||||
|
||||
@@ -12,7 +11,7 @@ namespace SabreTools.Features
|
||||
public Version()
|
||||
{
|
||||
Name = Value;
|
||||
Flags = new List<string>() { "v", "version" };
|
||||
Flags = ["v", "version"];
|
||||
Description = "Prints version";
|
||||
_featureType = ParameterType.Flag;
|
||||
LongDescription = "Prints current program version.";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using SabreTools.Core;
|
||||
using SabreTools.Features;
|
||||
using SabreTools.Help;
|
||||
@@ -17,7 +16,7 @@ namespace SabreTools
|
||||
/// <summary>
|
||||
/// Help object that determines available functionality
|
||||
/// </summary>
|
||||
private static FeatureSet _help;
|
||||
private static FeatureSet? _help;
|
||||
|
||||
/// <summary>
|
||||
/// Logging object
|
||||
@@ -43,7 +42,7 @@ namespace SabreTools
|
||||
_help = RetrieveHelp();
|
||||
|
||||
// Credits take precidence over all
|
||||
if ((new List<string>(args)).Contains("--credits"))
|
||||
if (new List<string>(args).Contains("--credits"))
|
||||
{
|
||||
FeatureSet.OutputCredits();
|
||||
LoggerImpl.Close();
|
||||
@@ -81,7 +80,7 @@ namespace SabreTools
|
||||
featureName = _help.GetFeatureName(featureName);
|
||||
|
||||
// Get the associated feature
|
||||
BaseFeature feature = _help[featureName] as BaseFeature;
|
||||
BaseFeature feature = (_help[featureName] as BaseFeature)!;
|
||||
|
||||
// If we had the help feature first
|
||||
if (featureName == DisplayHelp.Value || featureName == DisplayHelpDetailed.Value)
|
||||
@@ -161,16 +160,16 @@ namespace SabreTools
|
||||
{
|
||||
// Create and add the header to the Help object
|
||||
string barrier = "-----------------------------------------";
|
||||
List<string> helpHeader = new()
|
||||
{
|
||||
List<string> helpHeader =
|
||||
[
|
||||
"SabreTools - Manipulate, convert, and use DAT files",
|
||||
barrier,
|
||||
"Usage: SabreTools [option] [flags] [filename|dirname] ...",
|
||||
string.Empty
|
||||
};
|
||||
];
|
||||
|
||||
// Create the base help object with header
|
||||
FeatureSet help = new(helpHeader);
|
||||
var help = new FeatureSet(helpHeader);
|
||||
|
||||
// Add all of the features
|
||||
help.Add(new DisplayHelp());
|
||||
@@ -198,7 +197,7 @@ namespace SabreTools
|
||||
if (inputs.Count == 0)
|
||||
{
|
||||
logger.Error("This feature requires at least one input");
|
||||
_help.OutputIndividualFeature(feature.Name);
|
||||
_help?.OutputIndividualFeature(feature.Name);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Assembly Properties -->
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
||||
<CheckEolTargetFramework>false</CheckEolTargetFramework>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Version>1.1.2</Version>
|
||||
|
||||
<!-- Package Properties -->
|
||||
<Authors>Matt Nadareski</Authors>
|
||||
<Copyright>Copyright (c)2016-2024 Matt Nadareski</Copyright>
|
||||
<PackageProjectUrl>https://github.com/SabreTools/</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/SabreTools/SabreTools</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user