From 43e8517bf059b3e7ff03d8a48cd58d65ff420910 Mon Sep 17 00:00:00 2001 From: Deterous <138427222+Deterous@users.noreply.github.com> Date: Fri, 24 Nov 2023 21:46:16 +1300 Subject: [PATCH] Refactor for .NET8 --- IRDKit/IRDKit.csproj | 5 +-- LibIRD/IRD.cs | 77 +++++++++++++++++++------------------------ LibIRD/LibIRD.csproj | 3 +- LibIRD/PS3_DiscSFB.cs | 2 +- LibIRD/ReIRD.cs | 18 +++++----- 5 files changed, 49 insertions(+), 56 deletions(-) diff --git a/IRDKit/IRDKit.csproj b/IRDKit/IRDKit.csproj index caff1f8..374381a 100644 --- a/IRDKit/IRDKit.csproj +++ b/IRDKit/IRDKit.csproj @@ -8,13 +8,14 @@ ./nupkg net6.0;net7.0;net8.0 win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64 + latest 0.1.0 Deterous Library for ISO Rebuild Data - Copyright (c) 2023 Deterous - + Copyright (c) Deterous 2023 + README.md https://github.com/Deterous/LibIRD git ps3 iso ird redump diff --git a/LibIRD/IRD.cs b/LibIRD/IRD.cs index ce42334..a160393 100644 --- a/LibIRD/IRD.cs +++ b/LibIRD/IRD.cs @@ -33,32 +33,32 @@ namespace LibIRD /// IRD file signature /// /// "3IRD" - private static readonly byte[] Magic = { 0x33, 0x49, 0x52, 0x44 }; + private static readonly byte[] Magic = [0x33, 0x49, 0x52, 0x44]; /// /// MD5 hash of null /// - private static readonly byte[] NullMD5 = new byte[] { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e }; + private static readonly byte[] NullMD5 = [0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e]; /// /// AES CBC Encryption Key for Data 1 (Disc Key) /// - private static readonly byte[] D1AesKey = { 0x38, 0x0B, 0xCF, 0x0B, 0x53, 0x45, 0x5B, 0x3C, 0x78, 0x17, 0xAB, 0x4F, 0xA3, 0xBA, 0x90, 0xED }; + private static readonly byte[] D1AesKey = [0x38, 0x0B, 0xCF, 0x0B, 0x53, 0x45, 0x5B, 0x3C, 0x78, 0x17, 0xAB, 0x4F, 0xA3, 0xBA, 0x90, 0xED]; /// /// AES CBC Initial Value for Data 1 (Disc Key) /// - private static readonly byte[] D1AesIV = { 0x69, 0x47, 0x47, 0x72, 0xAF, 0x6F, 0xDA, 0xB3, 0x42, 0x74, 0x3A, 0xEF, 0xAA, 0x18, 0x62, 0x87 }; + private static readonly byte[] D1AesIV = [0x69, 0x47, 0x47, 0x72, 0xAF, 0x6F, 0xDA, 0xB3, 0x42, 0x74, 0x3A, 0xEF, 0xAA, 0x18, 0x62, 0x87]; /// /// AES CBC Encryption Key for Data 2 (Disc ID) /// - private static readonly byte[] D2AesKey = { 0x7C, 0xDD, 0x0E, 0x02, 0x07, 0x6E, 0xFE, 0x45, 0x99, 0xB1, 0xB8, 0x2C, 0x35, 0x99, 0x19, 0xB3 }; + private static readonly byte[] D2AesKey = [0x7C, 0xDD, 0x0E, 0x02, 0x07, 0x6E, 0xFE, 0x45, 0x99, 0xB1, 0xB8, 0x2C, 0x35, 0x99, 0x19, 0xB3]; /// /// AES CBC Initial Value for Data 2 (Disc ID) /// - private static readonly byte[] D2AesIV = { 0x22, 0x26, 0x92, 0x8D, 0x44, 0x03, 0x2F, 0x43, 0x6A, 0xFD, 0x26, 0x7E, 0x74, 0x8B, 0x23, 0x93 }; + private static readonly byte[] D2AesIV = [0x22, 0x26, 0x92, 0x8D, 0x44, 0x03, 0x2F, 0x43, 0x6A, 0xFD, 0x26, 0x7E, 0x74, 0x8B, 0x23, 0x93]; #endregion @@ -88,7 +88,7 @@ namespace LibIRD /// /// Extra Config /// - /// Reserved, usually set to 0x0000 + /// Usually set to 0x0000, set to 0x0001 for redump-style IRDs public ushort ExtraConfig { get; set; } = 0x0000; // Default to zero /// @@ -217,7 +217,7 @@ namespace LibIRD /// The same value stored in PARAM.SFO / VERSION /// /// 5 bytes, ASCII, e.g. "01.20" - public string GameVersion { get; private set; } + public string DiscVersion { get; private set; } /// /// The same value stored in PARAM.SFO / APP_VER @@ -312,7 +312,7 @@ namespace LibIRD string titleID, string title, string sysVersion, - string gameVersion, + string discVersion, string appVersion, byte[] header, byte[] footer, @@ -329,7 +329,7 @@ namespace LibIRD TitleID = titleID; Title = title; SystemVersion = sysVersion; - GameVersion = gameVersion; + DiscVersion = discVersion; AppVersion = appVersion; HeaderLength = (uint)header.Length; Header = header; @@ -476,10 +476,8 @@ namespace LibIRD private protected static byte[] GenerateD2(byte[] d2) { // Validate id - if (d2 == null) - throw new ArgumentNullException(nameof(d2)); - if (d2.Length != 16) - throw new ArgumentException("Disc ID must be a byte array of length 16", nameof(d2)); + if (d2 == null) throw new ArgumentNullException(nameof(d2)); + if (d2.Length != 16) throw new ArgumentException("Disc ID must be a byte array of length 16", nameof(d2)); // Setup AES encryption using Aes aes = Aes.Create() ?? throw new InvalidOperationException("AES not available. Change your system settings"); @@ -639,33 +637,26 @@ namespace LibIRD // New ISO Reader from DiscUtils CDReader reader = new(fs, true, true); - // Redump-style IRDs set the lowest bit of ExtraConfig to 1 - ExtraConfig |= 0x01; - - // If generating redump-style IRD, read PS3 Metadata from PS3_DISC.SFB + // If generating redump-style IRD if (redump) { + // Redump-style IRDs set the lowest bit of ExtraConfig to 1 + ExtraConfig |= 0x01; + + // Redump-style IRDs use fields in PS3_DISC.SFB using DiscUtils.Streams.SparseStream s = reader.OpenFile("PS3_DISC.SFB", FileMode.Open, FileAccess.Read); // Parse PS3_DISC.SFB file PS3_DiscSFB ps3_DiscSFB = new(s); - // Redump-style IRDs use the TITLE ID + // If a valid TITLE_ID field is present, remove the hyphen to fit into standard IRD file if (ps3_DiscSFB.Field.ContainsKey("TITLE_ID") && ps3_DiscSFB.Field["TITLE_ID"].Length == 10 && ps3_DiscSFB.Field["TITLE_ID"][4] == '-') - { - // Use the TITLE_ID from PS3_DISC.SFB TitleID = string.Concat(ps3_DiscSFB.Field["TITLE_ID"].AsSpan(0, 4), ps3_DiscSFB.Field["TITLE_ID"].AsSpan(5, 5)); - } - else - { - // Valid Title ID not found in PS3_DISC.SFB, use the one in PS3_GAME/PARAM.SFO - redump = false; - } // If the version field is present, this is a multi-game disc // Redump-style IRDs use the VERSION field from PS3_DISC.SFB instead of VERSION from PARAM.SFO if (ps3_DiscSFB.Field.ContainsKey("VERSION")) - GameVersion = ps3_DiscSFB.Field["VERSION"]; + DiscVersion = ps3_DiscSFB.Field["VERSION"]; } // Read PS3 Metadata from PARAM.SFO @@ -673,12 +664,11 @@ namespace LibIRD { // Parse PARAM.SFO file ParamSFO paramSFO = new(s); - // Store required values for IRD - if (!redump) - TitleID = paramSFO["TITLE_ID"]; + // If PS3_DISC.SFB did not set TitleID, use PARAM.SFO TITLE_ID + TitleID ??= paramSFO["TITLE_ID"]; Title = paramSFO["TITLE"]; - if (GameVersion == null) - GameVersion = paramSFO["VERSION"]; + // If PS3_DISC.SFB did not set DiscVersion, use PARAM.SFO VERSION + DiscVersion ??= paramSFO["VERSION"]; AppVersion = paramSFO["APP_VER"]; } @@ -706,7 +696,7 @@ namespace LibIRD // Determine file offsets and hashes uint fileCount = FileCount; FileCount = 0; - ProcessFiles(fs, reader, rootDir); + HashFiles(fs, reader, rootDir); if (FileCount != fileCount) throw new InvalidFileSystemException("Unexpected ISO filesystem error: "); Array.Sort(FileKeys, FileHashes); @@ -923,12 +913,13 @@ namespace LibIRD /// /// /// - private void ProcessFiles(FileStream fs, CDReader reader, DiscDirectoryInfo dir) + private void HashFiles(FileStream fs, CDReader reader, DiscDirectoryInfo dir) { // Process all files in current directory foreach (DiscFileInfo fileInfo in dir.GetFiles()) { string filePath = fileInfo.FullName; + // Try get the first sector from the file extents instead DiscUtils.Streams.StreamExtent[] fileExtents = reader.PathToExtents(filePath); if (fileExtents == null || fileExtents.Length <= 0) @@ -992,7 +983,7 @@ namespace LibIRD // Recursively process all subfolders of current directory foreach (DiscDirectoryInfo dirInfo in dir.GetDirectories()) { - ProcessFiles(fs, reader, dirInfo); + HashFiles(fs, reader, dirInfo); } } @@ -1081,10 +1072,10 @@ namespace LibIRD bw.Write(systemVersionBuf, 0, 4); // PARAM.SFO / VERSION - byte[] buf = Encoding.ASCII.GetBytes(GameVersion); - byte[] gameVersionBuf = new byte[5]; - Array.Copy(buf, 0, gameVersionBuf, 0, buf.Length); - bw.Write(gameVersionBuf, 0, 5); + byte[] buf = Encoding.ASCII.GetBytes(DiscVersion); + byte[] discVersionBuf = new byte[5]; + Array.Copy(buf, 0, discVersionBuf, 0, buf.Length); + bw.Write(discVersionBuf, 0, 5); // PARAM.SFO / APP_VER buf = Encoding.ASCII.GetBytes(AppVersion); @@ -1198,7 +1189,7 @@ namespace LibIRD // Read System, Game, and App Version string sysVersion = Encoding.ASCII.GetString(br.ReadBytes(4)); - string gameVersion = Encoding.ASCII.GetString(br.ReadBytes(5)); + string discVersion = Encoding.ASCII.GetString(br.ReadBytes(5)); string appVersion = Encoding.ASCII.GetString(br.ReadBytes(5)); // Read UID (for Version 7) @@ -1259,7 +1250,7 @@ namespace LibIRD titleID, title, sysVersion, - gameVersion, + discVersion, appVersion, header, footer, @@ -1290,7 +1281,7 @@ namespace LibIRD print.AppendLine($"Title ID: {TitleID}"); print.AppendLine($"Title: {Title}"); print.AppendLine($"PUP Version: {SystemVersion}"); - print.AppendLine($"Game Version: {GameVersion}"); + print.AppendLine($"Disc Version: {DiscVersion}"); print.AppendLine($"App Version: {AppVersion}"); print.AppendLine($"Regions: {RegionCount}"); print.AppendLine($"Files: {FileCount}"); diff --git a/LibIRD/LibIRD.csproj b/LibIRD/LibIRD.csproj index 49978c5..d46aebe 100644 --- a/LibIRD/LibIRD.csproj +++ b/LibIRD/LibIRD.csproj @@ -4,12 +4,13 @@ net6.0;net7.0;net8.0 win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64 + latest 0.1.0 Deterous Library for ISO Rebuild Data - Copyright (c) 2023 Deterous + Copyright (c) Deterous 2023 README.md https://github.com/Deterous/LibIRD git diff --git a/LibIRD/PS3_DiscSFB.cs b/LibIRD/PS3_DiscSFB.cs index bfe60fa..fb1932a 100644 --- a/LibIRD/PS3_DiscSFB.cs +++ b/LibIRD/PS3_DiscSFB.cs @@ -77,7 +77,7 @@ namespace LibIRD // Process all field headers sfbStream.Seek(0x20, SeekOrigin.Begin); string field = Encoding.ASCII.GetString(br.ReadBytes(0x10)).Trim('\0'); - Field = new Dictionary { }; + Field = []; while (field != null && field != "") { // Find location of value diff --git a/LibIRD/ReIRD.cs b/LibIRD/ReIRD.cs index ab11d64..c869ecc 100644 --- a/LibIRD/ReIRD.cs +++ b/LibIRD/ReIRD.cs @@ -131,12 +131,12 @@ namespace LibIRD private static byte[] GenerateID(long size, Region region = Region.NONE) { if (size > BDLayerSize) // if BD-50, Disc ID is fixed - return new byte[]{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + return [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; else // else if BD-25, Disc ID has a byte referring to disc region { - return new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x00, 0x02, 0x00, (byte)region, 0x00, 0x00, 0x00, 0x01 }; + return [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x02, 0x00, (byte)region, 0x00, 0x00, 0x00, 0x01 ]; } } @@ -164,7 +164,7 @@ namespace LibIRD byte[] total_sectors = BitConverter.GetBytes((uint)(size / SectorSize + 8067071)); // Initial portion of PIC (24 bytes) - pic = new byte[]{ + pic = [ // [4098 bytes] [2x 0x00] ["DI"] [v1] [10units] [DI num] 0x10, 0x02, 0x00, 0x00, 0x44, 0x49, 0x01, 0x10, 0x00, 0x00, 0x20, 0x00, // ["BDR"] [2 layers] @@ -190,7 +190,7 @@ namespace LibIRD // 2nd Layer sector end location 0x01, 0xEF, 0xFF, 0xFE, // Remaining 32 bytes are zeroes - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]; // 3k3y style: 0x03 at last byte if (exactIRD) pic[114] = 0x03; @@ -204,8 +204,8 @@ namespace LibIRD byte[] end_sector = BitConverter.GetBytes((uint)(size / SectorSize + 1048574)); // Initial portion of PIC (24 bytes) - pic = new byte[]{ 0x10, 0x02, 0x00, 0x00, 0x44, 0x49, 0x01, 0x08, 0x00, 0x00, 0x20, 0x00, - 0x42, 0x44, 0x4F, 0x01, 0x11, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + pic = [ 0x10, 0x02, 0x00, 0x00, 0x44, 0x49, 0x01, 0x08, 0x00, 0x00, 0x20, 0x00, + 0x42, 0x44, 0x4F, 0x01, 0x11, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Total sectors used on disc (4 bytes) total_sectors[3], total_sectors[2], total_sectors[1], total_sectors[0], // Layer sector start location (4 bytes) @@ -217,7 +217,7 @@ namespace LibIRD 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]; } return pic;