Add verbose flag to IRDKit, improve printing

This commit is contained in:
Deterous
2024-02-01 10:31:07 +09:00
parent e30ac0961a
commit 4116c56b7d
5 changed files with 105 additions and 51 deletions
+95 -47
View File
@@ -44,6 +44,9 @@ namespace IRDKit
[Option('r', "recurse", HelpText = "Recurse through all subdirectories and generate IRDs for all ISOs")] [Option('r', "recurse", HelpText = "Recurse through all subdirectories and generate IRDs for all ISOs")]
public bool Recurse { get; set; } public bool Recurse { get; set; }
[Option('v', "verbose", HelpText = "Print more information during IRD creation")]
public bool Verbose { get; set; }
} }
/// <summary> /// <summary>
@@ -111,12 +114,17 @@ namespace IRDKit
case CreateOptions opt: case CreateOptions opt:
// Validate ISO paths // Validate ISO paths
ArgumentNullException.ThrowIfNull(opt.ISOPath); if (opt.ISOPath == null || !opt.ISOPath.Any())
{
Console.Error.WriteLine("Provide a valid ISO path to create an IRD");
return;
}
foreach (string isoPath in opt.ISOPath) foreach (string isoPath in opt.ISOPath)
{ {
// Validate ISO path // Validate ISO path
ArgumentNullException.ThrowIfNull(isoPath); if (string.IsNullOrEmpty(isoPath))
continue;
// If directory, search for all ISOs in current directory // If directory, search for all ISOs in current directory
if (Directory.Exists(isoPath)) if (Directory.Exists(isoPath))
@@ -125,44 +133,59 @@ namespace IRDKit
IEnumerable<string> isoFiles; IEnumerable<string> isoFiles;
if (opt.Recurse) if (opt.Recurse)
{ {
if (isoPath == ".") if (opt.Verbose && isoPath == ".")
Console.WriteLine($"Recursively searching for ISOs in current directory"); Console.WriteLine($"Recursively searching for ISOs in current directory");
else else if (opt.Verbose)
Console.WriteLine($"Recursively searching for ISOs in {isoPath}"); Console.WriteLine($"Recursively searching for ISOs in {isoPath}");
isoFiles = Directory.EnumerateFiles(isoPath, "*.iso", SearchOption.AllDirectories); isoFiles = Directory.EnumerateFiles(isoPath, "*.iso", SearchOption.AllDirectories);
} }
else else
{ {
if (isoPath == ".") if (opt.Verbose && isoPath == ".")
Console.WriteLine($"Searching for ISOs in current directory"); Console.WriteLine($"Searching for ISOs in current directory");
else else if (opt.Verbose)
Console.WriteLine($"Searching for ISOs in {isoPath}"); Console.WriteLine($"Searching for ISOs in {isoPath}");
isoFiles = Directory.EnumerateFiles(isoPath, "*.iso", SearchOption.TopDirectoryOnly); isoFiles = Directory.EnumerateFiles(isoPath, "*.iso", SearchOption.TopDirectoryOnly);
} }
// Warn if no files are found // Warn if no files are found
if (!isoFiles.Any()) if (!isoFiles.Any())
Console.WriteLine("No ISOs found (ensure .iso extension)"); {
if (opt.Recurse)
Console.Error.WriteLine($"No ISOs found in {isoPath} (ensure .iso extension)");
else
Console.Error.WriteLine($"No ISOs found in {isoPath} (ensure .iso extension, or try use -r)");
continue;
}
// Determine output IRD folder
string outputPath = Path.GetDirectoryName(opt.IRDPath);
// Create an IRD file for all ISO files found // Create an IRD file for all ISO files found
foreach (string file in isoFiles) foreach (string file in isoFiles)
ISO2IRD(file); ISO2IRD(file, irdPath: outputPath, verbose: opt.Verbose);
} }
else else
{ {
// Check that given file exists // Check that given file exists
if (!File.Exists(isoPath)) throw new ArgumentException("Not a valid file or directory"); if (!File.Exists(isoPath))
// Save to given output path, if only 1 IRD is being created
if (opt.ISOPath.Count() == 1 && opt.IRDPath != null && opt.IRDPath != "")
{ {
string irdPath = ISO2IRD(isoPath, opt.IRDPath, opt.Key, opt.KeyFile, opt.GetKeyLog, opt.Layerbreak); Console.Error.WriteLine($"ISO not found: {isoPath}");
return;
}
// Only one ISO is being processed
if (!string.IsNullOrEmpty(opt.IRDPath) && opt.ISOPath.Count() == 1)
{
// Save to given output path and filename, if only 1 IRD is being created
string irdPath = ISO2IRD(isoPath, irdPath: opt.IRDPath, hexKey: opt.Key, keyPath: opt.KeyFile, getKeyLog: opt.GetKeyLog, layerbreak: opt.Layerbreak, verbose: opt.Verbose);
if (irdPath != null) if (irdPath != null)
Console.WriteLine($"IRD saved to {irdPath}"); Console.WriteLine($"IRD saved to {irdPath}");
} }
else else
{ {
string irdPath = ISO2IRD(isoPath, null, opt.Key, opt.KeyFile, opt.GetKeyLog, opt.Layerbreak); // Save to given output path, if more than 1 IRD is being created
string irdPath = ISO2IRD(isoPath, irdPath: Path.GetDirectoryName(opt.IRDPath), verbose: opt.Verbose);
if (irdPath != null) if (irdPath != null)
Console.WriteLine($"IRD saved to {irdPath}"); Console.WriteLine($"IRD saved to {irdPath}");
} }
@@ -175,7 +198,11 @@ namespace IRDKit
case InfoOptions opt: case InfoOptions opt:
// Validate required parameter // Validate required parameter
ArgumentNullException.ThrowIfNull(opt.InPath); if (opt.InPath == null || !opt.InPath.Any())
{
Console.Error.WriteLine("Provide a valid ISO or IRD path to print info about");
return;
}
// Clear the output file path if it exists // Clear the output file path if it exists
if (opt.OutPath != null && opt.OutPath != "") if (opt.OutPath != null && opt.OutPath != "")
@@ -184,7 +211,8 @@ namespace IRDKit
foreach (string filePath in opt.InPath) foreach (string filePath in opt.InPath)
{ {
// Validate path // Validate path
ArgumentNullException.ThrowIfNull(filePath); if (string.IsNullOrEmpty(filePath))
continue;
// If directory, search for all ISOs in current directory // If directory, search for all ISOs in current directory
if (Directory.Exists(filePath)) if (Directory.Exists(filePath))
@@ -213,7 +241,10 @@ namespace IRDKit
// Warn if no files are found // Warn if no files are found
if (!isoFiles.Any() && !irdFiles.Any()) if (!isoFiles.Any() && !irdFiles.Any())
Console.WriteLine("No IRDs or ISOs found (ensure .ird and .iso extensions)"); {
Console.Error.WriteLine("No IRDs or ISOs found (ensure .ird and .iso extensions)");
return;
}
// Open JSON object // Open JSON object
if (opt.Json) if (opt.Json)
@@ -245,7 +276,7 @@ namespace IRDKit
{ {
// Not a valid ISO file despite extension, assume file is an IRD // Not a valid ISO file despite extension, assume file is an IRD
if (!opt.Json) if (!opt.Json)
Console.WriteLine($"{file} is not a valid ISO file\n"); Console.Error.WriteLine($"{file} is not a valid ISO file\n");
} }
} }
@@ -264,7 +295,11 @@ namespace IRDKit
else else
{ {
// Check that given file exists // Check that given file exists
if (!File.Exists(filePath)) throw new ArgumentException($"{filePath} is not a valid file or directory"); if (!File.Exists(filePath))
{
Console.Error.WriteLine($"{filePath} is not a valid file");
continue;
}
// Print info from given file // Print info from given file
PrintInfo(filePath, opt.Json, true, opt.OutPath); PrintInfo(filePath, opt.Json, true, opt.OutPath);
@@ -279,11 +314,12 @@ namespace IRDKit
// Process options from a `diff` command // Process options from a `diff` command
case DiffOptions opt: case DiffOptions opt:
// Validate required parameter // Validate required parameters
ArgumentNullException.ThrowIfNull(opt.InPath1); if (opt.InPath1 == null || opt.InPath2 == null || !File.Exists(opt.InPath1) || !File.Exists(opt.InPath2))
ArgumentNullException.ThrowIfNull(opt.InPath2); {
if (!File.Exists(opt.InPath1)) throw new ArgumentException($"{opt.InPath1} is not a valid file or directory"); Console.Error.WriteLine("Provide two paths to IRDs to compare");
if (!File.Exists(opt.InPath2)) throw new ArgumentException($"{opt.InPath2} is not a valid file or directory"); return;
}
// Clear the output file path if it exists // Clear the output file path if it exists
if (opt.OutPath != null && opt.OutPath != "") if (opt.OutPath != null && opt.OutPath != "")
@@ -355,9 +391,9 @@ namespace IRDKit
if (json) if (json)
return; return;
if (isISO) if (isISO)
Console.WriteLine($"{inPath} is not a valid ISO file\n"); Console.Error.WriteLine($"{inPath} is not a valid ISO file\n");
else else
Console.WriteLine($"{inPath} is not a valid IRD file\n"); Console.Error.WriteLine($"{inPath} is not a valid IRD file\n");
} }
} }
@@ -372,10 +408,13 @@ namespace IRDKit
public static void PrintISO(string isoPath, bool json, bool single = true, string outPath = null) public static void PrintISO(string isoPath, bool json, bool single = true, string outPath = null)
{ {
// Open ISO file for reading // Open ISO file for reading
using FileStream fs = new FileStream(isoPath, FileMode.Open, FileAccess.Read) ?? throw new FileNotFoundException(isoPath); using FileStream fs = new(isoPath, FileMode.Open, FileAccess.Read);
// Validate ISO file stream // Validate ISO file stream
if (!CDReader.Detect(fs)) if (fs == null || !CDReader.Detect(fs))
throw new InvalidFileSystemException($"{isoPath} is not a valid ISO file"); {
Console.Error.WriteLine($"{isoPath} is not a valid ISO file");
return;
}
// Create new ISO reader // Create new ISO reader
using CDReader reader = new(fs, true, true); using CDReader reader = new(fs, true, true);
@@ -412,7 +451,7 @@ namespace IRDKit
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
if (!json) if (!json)
Console.WriteLine($"{isoPath} is not a valid PS3 ISO file\n"); Console.Error.WriteLine($"{isoPath} is not a valid PS3 ISO file\n");
return; return;
} }
@@ -435,7 +474,7 @@ namespace IRDKit
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
if (!json) if (!json)
Console.WriteLine($"\\PS3_GAME\\PARAM.SFO not found in {isoPath}\n"); Console.Error.WriteLine($"\\PS3_GAME\\PARAM.SFO not found in {isoPath}\n");
} }
// End JSON object // End JSON object
@@ -469,7 +508,7 @@ namespace IRDKit
// Check they are different IRDs // Check they are different IRDs
if (Path.GetFullPath(irdPath1) == Path.GetFullPath(irdPath2)) if (Path.GetFullPath(irdPath1) == Path.GetFullPath(irdPath2))
{ {
Console.WriteLine("Provide two different IRDs for a diff"); Console.Error.WriteLine("Provide two different IRDs for a diff");
return; return;
} }
@@ -619,13 +658,13 @@ namespace IRDKit
/// <param name="keyPath">Disc key file (overridden by hex string if present)</param> /// <param name="keyPath">Disc key file (overridden by hex string if present)</param>
/// <param name="getKeyLog">GetKey log file (overridden by disc key or key file if present)</param> /// <param name="getKeyLog">GetKey log file (overridden by disc key or key file if present)</param>
/// <param name="layerbreak">Layerbreak value of disc</param> /// <param name="layerbreak">Layerbreak value of disc</param>
public static string ISO2IRD(string isoPath, string irdPath = null, string hexKey = null, string keyPath = null, string getKeyLog = null, long? layerbreak = null) public static string ISO2IRD(string isoPath, string irdPath = null, string hexKey = null, string keyPath = null, string getKeyLog = null, long? layerbreak = null, bool verbose = false)
{ {
// Check file exists // Check file exists
FileInfo iso = new(isoPath); FileInfo iso = new(isoPath);
if (!iso.Exists) if (!iso.Exists)
{ {
Console.WriteLine($"{nameof(isoPath)} is not a valid file or directory"); Console.Error.WriteLine($"{nameof(isoPath)} is not a valid file or directory");
return null; return null;
} }
@@ -645,7 +684,8 @@ namespace IRDKit
Console.WriteLine($"Creating {irdPath} with Key: {hexKey}"); Console.WriteLine($"Creating {irdPath} with Key: {hexKey}");
IRD ird1 = new ReIRD(isoPath, discKey, layerbreak); IRD ird1 = new ReIRD(isoPath, discKey, layerbreak);
ird1.Write(irdPath); ird1.Write(irdPath);
ird1.Print(); if (verbose)
ird1.Print();
return irdPath; return irdPath;
} }
catch (ArgumentException) catch (ArgumentException)
@@ -669,7 +709,8 @@ namespace IRDKit
IRD ird2 = new ReIRD(isoPath, discKey, layerbreak); IRD ird2 = new ReIRD(isoPath, discKey, layerbreak);
Console.WriteLine($"Creating {irdPath} with Key: {Convert.ToHexString(discKey)}"); Console.WriteLine($"Creating {irdPath} with Key: {Convert.ToHexString(discKey)}");
ird2.Write(irdPath); ird2.Write(irdPath);
ird2.Print(); if (verbose)
ird2.Print();
return irdPath; return irdPath;
} }
catch (ArgumentException) catch (ArgumentException)
@@ -691,7 +732,8 @@ namespace IRDKit
Console.WriteLine($"Creating {irdPath} with key from: {getKeyLog}"); Console.WriteLine($"Creating {irdPath} with key from: {getKeyLog}");
IRD ird3 = new ReIRD(isoPath, getKeyLog); IRD ird3 = new ReIRD(isoPath, getKeyLog);
ird3.Write(irdPath); ird3.Write(irdPath);
ird3.Print(); if (verbose)
ird3.Print();
return irdPath; return irdPath;
} }
catch (FileNotFoundException) catch (FileNotFoundException)
@@ -717,7 +759,8 @@ namespace IRDKit
Console.WriteLine($"Creating {irdPath} with Key: {Convert.ToHexString(discKey)}"); Console.WriteLine($"Creating {irdPath} with Key: {Convert.ToHexString(discKey)}");
IRD ird2 = new ReIRD(isoPath, discKey, layerbreak); IRD ird2 = new ReIRD(isoPath, discKey, layerbreak);
ird2.Write(irdPath); ird2.Write(irdPath);
ird2.Print(); if (verbose)
ird2.Print();
return irdPath; return irdPath;
} }
catch (ArgumentException) catch (ArgumentException)
@@ -742,7 +785,8 @@ namespace IRDKit
Console.WriteLine($"Creating {irdPath} with key from: {logfilePath}"); Console.WriteLine($"Creating {irdPath} with key from: {logfilePath}");
IRD ird3 = new ReIRD(isoPath, logfilePath); IRD ird3 = new ReIRD(isoPath, logfilePath);
ird3.Write(irdPath); ird3.Write(irdPath);
ird3.Print(); if (verbose)
ird3.Print();
return irdPath; return irdPath;
} }
catch (FileNotFoundException) catch (FileNotFoundException)
@@ -753,7 +797,8 @@ namespace IRDKit
} }
// No key provided, try get key from redump.org // No key provided, try get key from redump.org
Console.WriteLine("No key provided... Searching for key on redump.org"); if (verbose)
Console.WriteLine("No key provided... Searching for key on redump.org");
// Compute CRC32 hash // Compute CRC32 hash
byte[] crc32; byte[] crc32;
@@ -773,12 +818,12 @@ namespace IRDKit
int id; int id;
if (ids.Count == 0) if (ids.Count == 0)
{ {
Console.WriteLine("ISO not found in redump, cannot automatically retreive key"); Console.Error.WriteLine("ISO not found in redump and no valid key provided, cannot create IRD");
return null; return null;
} }
else if (ids.Count > 1) else if (ids.Count > 1)
{ {
// Compute SHA1 hash // More than one result for the CRC32 hash, compute SHA1 hash instead
byte[] sha1; byte[] sha1;
using (FileStream fs = File.OpenRead(isoPath)) using (FileStream fs = File.OpenRead(isoPath))
{ {
@@ -791,18 +836,19 @@ namespace IRDKit
List<int> ids2 = redump.CheckSingleSitePage("http://redump.org/discs/system/ps3/quicksearch/" + sha1_hash).ConfigureAwait(false).GetAwaiter().GetResult(); List<int> ids2 = redump.CheckSingleSitePage("http://redump.org/discs/system/ps3/quicksearch/" + sha1_hash).ConfigureAwait(false).GetAwaiter().GetResult();
if (ids2.Count == 0) if (ids2.Count == 0)
{ {
Console.WriteLine("ISO not found in redump, cannot automatically retreive key"); Console.Error.WriteLine("ISO not found in redump and no valid key provided, cannot create IRD");
return null; return null;
} }
else if (ids2.Count > 1) else if (ids2.Count > 1)
{ {
Console.WriteLine("Cannot automatically get key from redump. Please search redump.org and run again with -k"); Console.Error.WriteLine("Cannot automatically get key from redump. Please search redump.org and run again with -k");
return null; return null;
} }
id = ids2[0]; id = ids2[0];
} }
else else
{ {
// One result found, assume it is the PS3 ISO
id = ids[0]; id = ids[0];
} }
@@ -810,14 +856,16 @@ namespace IRDKit
byte[] key = redump.GetByteArrayAsync($"http://redump.org/disc/{id}/key").ConfigureAwait(false).GetAwaiter().GetResult(); byte[] key = redump.GetByteArrayAsync($"http://redump.org/disc/{id}/key").ConfigureAwait(false).GetAwaiter().GetResult();
if (key.Length != 16) if (key.Length != 16)
{ {
Console.WriteLine("Invalid key obtained from redump"); Console.Error.WriteLine("Invalid key obtained from redump and no valid key provided, cannot create IRD");
return null;
} }
// Create IRD with key from redump // Create IRD with key from redump
Console.WriteLine($"Creating {irdPath} with Key: {Convert.ToHexString(key)}"); Console.WriteLine($"Creating {irdPath} with Key from redump.org: {Convert.ToHexString(key)}");
IRD ird = new ReIRD(isoPath, key, layerbreak); IRD ird = new ReIRD(isoPath, key, layerbreak);
ird.Write(irdPath); ird.Write(irdPath);
ird.Print(); if (verbose)
ird.Print();
return irdPath; return irdPath;
} }
+4 -2
View File
@@ -2,6 +2,8 @@
IRDKit is a tool that allows direct use of LibIRD functionality from the command line interface. The basic usage is: IRDKit is a tool that allows direct use of LibIRD functionality from the command line interface. The basic usage is:
``` ```
irdkit game.iso game.ird irdkit create game.iso
irdkit info game.ird
irdkit diff game1.ird game2.ird
``` ```
For detailed usage, run `irdkit --help` For detailed usage, run `irdkit help`
+4 -1
View File
@@ -721,7 +721,7 @@ namespace LibIRD
HashFiles(fs, reader, rootDir); HashFiles(fs, reader, rootDir);
if (FileCount != fileCount) if (FileCount != fileCount)
{ {
Console.WriteLine($"Likely contains non-contiguous files: detected {FileCount} out of {fileCount} expected files"); Console.WriteLine($"{isoPath} contains splits files: detected {FileCount} out of {fileCount} expected files");
long[] tempFileKeys = FileKeys; long[] tempFileKeys = FileKeys;
Array.Resize(ref tempFileKeys, (int)FileCount); Array.Resize(ref tempFileKeys, (int)FileCount);
FileKeys = tempFileKeys; FileKeys = tempFileKeys;
@@ -950,6 +950,9 @@ namespace LibIRD
if (Array.Exists(FileKeys, element => element == firstSector)) if (Array.Exists(FileKeys, element => element == firstSector))
continue; continue;
if (fileClusters.Length > 1)
Console.WriteLine($"Split file detected: {filePath}");
// Add file offset to keys // Add file offset to keys
FileKeys[FileCount] = firstSector; FileKeys[FileCount] = firstSector;
+1
View File
@@ -13,6 +13,7 @@ IRDKit is a tool that allows direct use of LibIRD functionality from a command l
- Printing info about all ISOs and IRDs in a folder: `irdkit info .` - Printing info about all ISOs and IRDs in a folder: `irdkit info .`
- Creating an IRD from an ISO: `irdkit create game.iso` - Creating an IRD from an ISO: `irdkit create game.iso`
- Finding differences between two IRDs: `irdkit diff game1.ird game2.ird` - Finding differences between two IRDs: `irdkit diff game1.ird game2.ird`
For detailed usage, read more [here](IRDKit). For detailed usage, read more [here](IRDKit).
## Using the LibIRD library ## Using the LibIRD library