Skip to content

Commit

Permalink
Parse PSX/PS2/KP2 exe date from logs (#639)
Browse files Browse the repository at this point in the history
* Parse EXE date from Redumper

* Parse EXE date from DIC logs

* Fix DIC exe date parsing

* Split PS EXE name from EXE info

* Remove redundant path splitting
  • Loading branch information
Deterous committed Jan 31, 2024
1 parent 747ac4e commit 285e94c
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 52 deletions.
1 change: 1 addition & 0 deletions CHANGELIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- Fix information pulling for CleanRip and UIC
- Add UMD handling for the disc info window
- Detect Photo CD
- Parse PSX/PS2/KP2 exe date from logs (Deterous)

### 3.0.3 (2023-12-04)

Expand Down
121 changes: 75 additions & 46 deletions MPF.Core/InfoTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,66 @@ internal static void GetLibCryptDetected(SubmissionInfo info, string basePath)
return di.Units[0]?.Body?.DiscTypeIdentifier;
}

internal static string? GetPlayStationExecutableName(char? driveLetter)
{
// If there's no drive letter, we can't get exe name
if (driveLetter == null)
return null;

// Convert drive letter to drive path
string drivePath = driveLetter + ":\\";
return GetPlayStationExecutableName(drivePath);
}

internal static string? GetPlayStationExecutableName(string? drivePath)
{
// If there's no drive path, we can't get exe name
if (string.IsNullOrEmpty(drivePath))
return null;

// If the folder no longer exists, we can't get exe name
if (!Directory.Exists(drivePath))
return null;

// Get the two paths that we will need to check
string psxExePath = Path.Combine(drivePath, "PSX.EXE");
string systemCnfPath = Path.Combine(drivePath, "SYSTEM.CNF");

// Read the CNF file as an INI file
var systemCnf = new IniFile(systemCnfPath);
string bootValue = string.Empty;

// PlayStation uses "BOOT" as the key
if (systemCnf.ContainsKey("BOOT"))
bootValue = systemCnf["BOOT"];

// PlayStation 2 uses "BOOT2" as the key
if (systemCnf.ContainsKey("BOOT2"))
bootValue = systemCnf["BOOT2"];

// If we had any boot value, parse it and get the executable name
if (!string.IsNullOrEmpty(bootValue))
{
var match = Regex.Match(bootValue, @"cdrom.?:\\?(.*)", RegexOptions.Compiled);
if (match.Groups.Count > 1)
{
string? serial = match.Groups[1].Value;

// Some games may have the EXE in a subfolder
serial = Path.GetFileName(serial);

return serial;
}
}

// If the SYSTEM.CNF value can't be found, try PSX.EXE
if (File.Exists(psxExePath))
return "PSX.EXE";

// If neither can be found, we return null
return null;
}

/// <summary>
/// Get the EXE date from a PlayStation disc, if possible
/// </summary>
Expand All @@ -400,7 +460,7 @@ internal static bool GetPlayStationExecutableInfo(char? driveLetter, out string?
if (driveLetter == null)
return false;

// If the folder no longer exists, we can't do this part
// Convert drive letter to drive path
string drivePath = driveLetter + ":\\";
return GetPlayStationExecutableInfo(drivePath, out serial, out region, out date);
}
Expand All @@ -425,54 +485,23 @@ internal static bool GetPlayStationExecutableInfo(string? drivePath, out string?
if (!Directory.Exists(drivePath))
return false;

// Get the two paths that we will need to check
string psxExePath = Path.Combine(drivePath, "PSX.EXE");
string systemCnfPath = Path.Combine(drivePath, "SYSTEM.CNF");

// Try both of the common paths that contain information
string? exeName = null;

// Read the CNF file as an INI file
var systemCnf = new IniFile(systemCnfPath);
string bootValue = string.Empty;

// PlayStation uses "BOOT" as the key
if (systemCnf.ContainsKey("BOOT"))
bootValue = systemCnf["BOOT"];

// PlayStation 2 uses "BOOT2" as the key
if (systemCnf.ContainsKey("BOOT2"))
bootValue = systemCnf["BOOT2"];

// If we had any boot value, parse it and get the executable name
if (!string.IsNullOrEmpty(bootValue))
{
var match = Regex.Match(bootValue, @"cdrom.?:\\?(.*)", RegexOptions.Compiled);
if (match.Groups.Count > 1)
{
// EXE name may have a trailing `;` after
// EXE name should always be in all caps
exeName = match.Groups[1].Value
.Split(';')[0]
.ToUpperInvariant();

// Serial is most of the EXE name normalized
serial = exeName
.Replace('_', '-')
.Replace(".", string.Empty);
// Get the executable name
string? exeName = GetPlayStationExecutableName(drivePath);

// Some games may have the EXE in a subfolder
serial = Path.GetFileName(serial);
}
}
// If no executable found, we can't do this part
if (exeName == null)
return false;

// If the SYSTEM.CNF value can't be found, try PSX.EXE
if (string.IsNullOrEmpty(exeName) && File.Exists(psxExePath))
exeName = "PSX.EXE";
// EXE name may have a trailing `;` after
// EXE name should always be in all caps
exeName = exeName
.Split(';')[0]
.ToUpperInvariant();

// If neither can be found, we return false
if (string.IsNullOrEmpty(exeName))
return false;
// Serial is most of the EXE name normalized
serial = exeName
.Replace('_', '-')
.Replace(".", string.Empty);

// Get the region, if possible
region = GetPlayStationRegion(exeName);
Expand Down
78 changes: 75 additions & 3 deletions MPF.Core/Modules/DiscImageCreator/Parameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,14 @@ public override void GenerateSubmissionInfo(SubmissionInfo info, Options options
break;

case RedumpSystem.KonamiPython2:
info.CommonDiscInfo!.EXEDateBuildDate = GetPlayStationEXEDate($"{basePath}_volDesc.txt", InfoTool.GetPlayStationExecutableName(drive?.Name));

if (InfoTool.GetPlayStationExecutableInfo(drive?.Name, out var pythonTwoSerial, out Region? pythonTwoRegion, out var pythonTwoDate))
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalSerialName] = pythonTwoSerial ?? string.Empty;
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? pythonTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
info.CommonDiscInfo.EXEDateBuildDate ??= pythonTwoDate;
}

info.VersionAndEditions!.Version = InfoTool.GetPlayStation2Version(drive?.Name) ?? string.Empty;
Expand Down Expand Up @@ -785,12 +787,14 @@ public override void GenerateSubmissionInfo(SubmissionInfo info, Options options
break;

case RedumpSystem.SonyPlayStation:
info.CommonDiscInfo!.EXEDateBuildDate = GetPlayStationEXEDate($"{basePath}_volDesc.txt", InfoTool.GetPlayStationExecutableName(drive?.Name), true);

if (InfoTool.GetPlayStationExecutableInfo(drive?.Name, out var playstationSerial, out Region? playstationRegion, out var playstationDate))
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalSerialName] = playstationSerial ?? string.Empty;
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
info.CommonDiscInfo.EXEDateBuildDate ??= playstationDate;
}

bool? psEdcStatus = null;
Expand All @@ -804,12 +808,14 @@ public override void GenerateSubmissionInfo(SubmissionInfo info, Options options
break;

case RedumpSystem.SonyPlayStation2:
info.CommonDiscInfo!.EXEDateBuildDate = GetPlayStationEXEDate($"{basePath}_volDesc.txt", InfoTool.GetPlayStationExecutableName(drive?.Name));

if (InfoTool.GetPlayStationExecutableInfo(drive?.Name, out var playstationTwoSerial, out Region? playstationTwoRegion, out var playstationTwoDate))
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalSerialName] = playstationTwoSerial ?? string.Empty;
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
info.CommonDiscInfo.EXEDateBuildDate ??= playstationTwoDate;
}

info.VersionAndEditions!.Version = InfoTool.GetPlayStation2Version(drive?.Name) ?? string.Empty;
Expand Down Expand Up @@ -2971,6 +2977,72 @@ private static long GetErrorCount(string edcecc)
}
}

/// <summary>
/// Get the PSX/PS2/KP2 EXE Date from the log, if possible
/// </summary>
/// <param name="log">Log file location</param>
/// <param name="serial">Internal serial</param>
/// <param name="psx">True if PSX disc, false otherwise</param>
/// <returns>EXE date if possible, null otherwise</returns>
public static string? GetPlayStationEXEDate(string log, string? exeName, bool psx = false)
{
// If the file doesn't exist, we can't get the info
if (!File.Exists(log))
return null;

// If the EXE name is not valid, we can't get the info
if (string.IsNullOrEmpty(exeName))
return null;

try
{
string? exeDate = null;
using var sr = File.OpenText(log);
var line = sr.ReadLine();
while (line != null)
{
// Trim the line for later use
line = line.Trim();

// The exe date is listed in a single line, File Identifier: ABCD_123.45;1
if (line.Length >= "File Identifier: ".Length + 11 &&
line.StartsWith("File Identifier:") &&
line.Substring("File Identifier: ".Length) == exeName)
{
// Account for Y2K date problem
if (exeDate != null && exeDate!.Substring(0, 2) == "19")
{
string decade = exeDate!.Substring(2, 1);
// Does only PSX need to account for 1920s-60s?
if (decade == "0" || decade == "1" ||
psx && (decade == "2" || decade == "3" || decade == "4" || decade == "5" || decade == "6"))
exeDate = $"20{exeDate!.Substring(2)}";
}

// Currently stored date is the EXE date, return it
return exeDate;
}

// The exe datetime is listed in a single line
if (line.Length >= "Recording Date and Time: ".Length + 10 &&
line.StartsWith("Recording Date and Time:"))
{
// exe date: ISO datetime (yyyy-MM-ddT.....)
exeDate = line.Substring("Recording Date and Time: ".Length, 10);
}

line = sr.ReadLine();
}

return null;
}
catch
{
// We don't care what the exception is right now
return null;
}
}

/// <summary>
/// Get the build info from a GD-ROM LD area, if possible
/// </summary>
Expand Down
48 changes: 45 additions & 3 deletions MPF.Core/Modules/Redumper/Parameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -413,12 +413,13 @@ public override void GenerateSubmissionInfo(SubmissionInfo info, Options options
break;

case RedumpSystem.KonamiPython2:
info.CommonDiscInfo!.EXEDateBuildDate = GetEXEDate($"{basePath}.log");
if (InfoTool.GetPlayStationExecutableInfo(drive?.Name, out var pythonTwoSerial, out Region? pythonTwoRegion, out var pythonTwoDate))
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalSerialName] = pythonTwoSerial ?? string.Empty;
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? pythonTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = pythonTwoDate;
info.CommonDiscInfo.EXEDateBuildDate ??= pythonTwoDate;
}

info.VersionAndEditions!.Version = InfoTool.GetPlayStation2Version(drive?.Name) ?? string.Empty;
Expand Down Expand Up @@ -477,12 +478,13 @@ public override void GenerateSubmissionInfo(SubmissionInfo info, Options options
break;

case RedumpSystem.SonyPlayStation:
info.CommonDiscInfo!.EXEDateBuildDate = GetEXEDate($"{basePath}.log");
if (InfoTool.GetPlayStationExecutableInfo(drive?.Name, out var playstationSerial, out Region? playstationRegion, out var playstationDate))
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalSerialName] = playstationSerial ?? string.Empty;
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationDate;
info.CommonDiscInfo.EXEDateBuildDate ??= playstationDate;
}

info.CopyProtection!.AntiModchip = GetPlayStationAntiModchipDetected($"{basePath}.log").ToYesNo();
Expand All @@ -492,12 +494,13 @@ public override void GenerateSubmissionInfo(SubmissionInfo info, Options options
break;

case RedumpSystem.SonyPlayStation2:
info.CommonDiscInfo!.EXEDateBuildDate = GetEXEDate($"{basePath}.log");
if (InfoTool.GetPlayStationExecutableInfo(drive?.Name, out var playstationTwoSerial, out Region? playstationTwoRegion, out var playstationTwoDate))
{
// Ensure internal serial is pulled from local data
info.CommonDiscInfo!.CommentsSpecialFields![SiteCode.InternalSerialName] = playstationTwoSerial ?? string.Empty;
info.CommonDiscInfo.Region = info.CommonDiscInfo.Region ?? playstationTwoRegion;
info.CommonDiscInfo.EXEDateBuildDate = playstationTwoDate;
info.CommonDiscInfo.EXEDateBuildDate ??= playstationTwoDate;
}

info.VersionAndEditions!.Version = InfoTool.GetPlayStation2Version(drive?.Name) ?? string.Empty;
Expand Down Expand Up @@ -1686,6 +1689,45 @@ public static long GetErrorCount(string log)
}
}

/// <summary>
/// Get the EXE Date from the log, if possible
/// </summary>
/// <param name="log">Log file location</param>
/// <returns>EXE date if possible, null otherwise</returns>
public static string? GetEXEDate(string log)
{
// If the file doesn't exist, we can't get the info
if (!File.Exists(log))
return null;

try
{
using var sr = File.OpenText(log);
var line = sr.ReadLine();
while (line != null)
{
// Trim the line for later use
line = line.Trim();

// The exe date is listed in a single line
if (line.StartsWith("EXE date:"))
{
// exe date: yyyy-MM-dd
return line.Substring("EXE date: ".Length);
}

line = sr.ReadLine();
}

return null;
}
catch
{
// We don't care what the exception is right now
return null;
}
}

/// <summary>
/// Get hardware information from the input file, if possible
/// </summary>
Expand Down

0 comments on commit 285e94c

Please sign in to comment.