diff --git a/SabreTools.Serialization/Deserializers/AACS.cs b/SabreTools.Serialization/Deserializers/AACS.cs index eee08998..c8341b33 100644 --- a/SabreTools.Serialization/Deserializers/AACS.cs +++ b/SabreTools.Serialization/Deserializers/AACS.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using SabreTools.IO.Extensions; -using SabreTools.Models.AACS; +using SabreTools.Serialization.Models.AACS; namespace SabreTools.Serialization.Deserializers { diff --git a/SabreTools.Serialization/Deserializers/AppPkgHeader.cs b/SabreTools.Serialization/Deserializers/AppPkgHeader.cs index a13fb44c..2736f569 100644 --- a/SabreTools.Serialization/Deserializers/AppPkgHeader.cs +++ b/SabreTools.Serialization/Deserializers/AppPkgHeader.cs @@ -1,14 +1,14 @@ using System.IO; using System.Text; using SabreTools.IO.Extensions; -using static SabreTools.Models.PlayStation4.Constants; +using static SabreTools.Serialization.Models.PlayStation4.Constants; namespace SabreTools.Serialization.Deserializers { - public class AppPkgHeader : BaseBinaryDeserializer + public class AppPkgHeader : BaseBinaryDeserializer { /// - public override SabreTools.Models.PlayStation4.AppPkgHeader? Deserialize(Stream? data) + public override SabreTools.Serialization.Models.PlayStation4.AppPkgHeader? Deserialize(Stream? data) { // If the data is invalid if (data == null || !data.CanRead) @@ -17,7 +17,7 @@ namespace SabreTools.Serialization.Deserializers try { // Create a new app.pkg header to fill - var appPkgHeader = new SabreTools.Models.PlayStation4.AppPkgHeader(); + var appPkgHeader = new SabreTools.Serialization.Models.PlayStation4.AppPkgHeader(); appPkgHeader.Magic = data.ReadUInt32BigEndian(); if (appPkgHeader.Magic != AppPkgMagic) diff --git a/SabreTools.Serialization/Deserializers/BDPlus.cs b/SabreTools.Serialization/Deserializers/BDPlus.cs index a601a229..34bac04c 100644 --- a/SabreTools.Serialization/Deserializers/BDPlus.cs +++ b/SabreTools.Serialization/Deserializers/BDPlus.cs @@ -1,8 +1,8 @@ using System.IO; using System.Text; using SabreTools.IO.Extensions; -using SabreTools.Models.BDPlus; -using static SabreTools.Models.BDPlus.Constants; +using SabreTools.Serialization.Models.BDPlus; +using static SabreTools.Serialization.Models.BDPlus.Constants; namespace SabreTools.Serialization.Deserializers { diff --git a/SabreTools.Serialization/Deserializers/Catalog.cs b/SabreTools.Serialization/Deserializers/Catalog.cs index d4cd7910..8f86fc26 100644 --- a/SabreTools.Serialization/Deserializers/Catalog.cs +++ b/SabreTools.Serialization/Deserializers/Catalog.cs @@ -3,12 +3,12 @@ using System.Text; namespace SabreTools.Serialization.Deserializers { - public class Catalog : JsonFile + public class Catalog : JsonFile { #region IByteDeserializer /// Catalog.js file is encoded as UTF-16 LE - public override SabreTools.Models.Xbox.Catalog? Deserialize(byte[]? data, int offset) + public override SabreTools.Serialization.Models.Xbox.Catalog? Deserialize(byte[]? data, int offset) => Deserialize(data, offset, new UnicodeEncoding()); #endregion @@ -16,7 +16,7 @@ namespace SabreTools.Serialization.Deserializers #region IFileDeserializer /// Catalog.js file is encoded as UTF-16 LE - public override SabreTools.Models.Xbox.Catalog? Deserialize(string? path) + public override SabreTools.Serialization.Models.Xbox.Catalog? Deserialize(string? path) => Deserialize(path, new UnicodeEncoding()); #endregion @@ -24,7 +24,7 @@ namespace SabreTools.Serialization.Deserializers #region IStreamDeserializer /// Catalog.js file is encoded as UTF-16 LE - public override SabreTools.Models.Xbox.Catalog? Deserialize(Stream? data) + public override SabreTools.Serialization.Models.Xbox.Catalog? Deserialize(Stream? data) => Deserialize(data, new UnicodeEncoding()); #endregion diff --git a/SabreTools.Serialization/Deserializers/CueSheet.cs b/SabreTools.Serialization/Deserializers/CueSheet.cs index 84a3d5e3..3ac80422 100644 --- a/SabreTools.Serialization/Deserializers/CueSheet.cs +++ b/SabreTools.Serialization/Deserializers/CueSheet.cs @@ -3,14 +3,14 @@ using System.Collections.Generic; using System.IO; using System.Text; using System.Text.RegularExpressions; -using SabreTools.Models.CueSheets; +using SabreTools.Serialization.Models.CueSheets; namespace SabreTools.Serialization.Deserializers { - public class CueSheet : BaseBinaryDeserializer + public class CueSheet : BaseBinaryDeserializer { /// - public override SabreTools.Models.CueSheets.CueSheet? Deserialize(Stream? data) + public override SabreTools.Serialization.Models.CueSheets.CueSheet? Deserialize(Stream? data) { // If the data is invalid if (data == null || !data.CanRead) @@ -20,7 +20,7 @@ namespace SabreTools.Serialization.Deserializers { // Setup the reader and output var reader = new StreamReader(data, Encoding.UTF8); - var cueSheet = new SabreTools.Models.CueSheets.CueSheet(); + var cueSheet = new SabreTools.Serialization.Models.CueSheets.CueSheet(); var cueFiles = new List(); // Read the next line from the input diff --git a/SabreTools.Serialization/Deserializers/IRD.cs b/SabreTools.Serialization/Deserializers/IRD.cs index 9485592b..1c78ad63 100644 --- a/SabreTools.Serialization/Deserializers/IRD.cs +++ b/SabreTools.Serialization/Deserializers/IRD.cs @@ -4,10 +4,10 @@ using SabreTools.IO.Extensions; namespace SabreTools.Serialization.Deserializers { - public class IRD : BaseBinaryDeserializer + public class IRD : BaseBinaryDeserializer { /// - public override SabreTools.Models.IRD.File? Deserialize(Stream? data) + public override SabreTools.Serialization.Models.IRD.File? Deserialize(Stream? data) { // If the data is invalid if (data == null || !data.CanRead) @@ -16,7 +16,7 @@ namespace SabreTools.Serialization.Deserializers try { // Deserialize the IRD - var ird = new SabreTools.Models.IRD.File(); + var ird = new SabreTools.Serialization.Models.IRD.File(); ird.Magic = data.ReadBytes(4); string magic = Encoding.ASCII.GetString(ird.Magic); diff --git a/SabreTools.Serialization/Deserializers/PIC.cs b/SabreTools.Serialization/Deserializers/PIC.cs index ac050446..b87b2a8b 100644 --- a/SabreTools.Serialization/Deserializers/PIC.cs +++ b/SabreTools.Serialization/Deserializers/PIC.cs @@ -2,8 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Text; using SabreTools.IO.Extensions; -using SabreTools.Models.PIC; -using static SabreTools.Models.PIC.Constants; +using SabreTools.Serialization.Models.PIC; +using static SabreTools.Serialization.Models.PIC.Constants; namespace SabreTools.Serialization.Deserializers { diff --git a/SabreTools.Serialization/Deserializers/SFB.cs b/SabreTools.Serialization/Deserializers/SFB.cs index f598b531..da881a35 100644 --- a/SabreTools.Serialization/Deserializers/SFB.cs +++ b/SabreTools.Serialization/Deserializers/SFB.cs @@ -1,14 +1,14 @@ using System.IO; using System.Text; using SabreTools.IO.Extensions; -using static SabreTools.Models.PlayStation3.Constants; +using static SabreTools.Serialization.Models.PlayStation3.Constants; namespace SabreTools.Serialization.Deserializers { - public class SFB : BaseBinaryDeserializer + public class SFB : BaseBinaryDeserializer { /// - public override SabreTools.Models.PlayStation3.SFB? Deserialize(Stream? data) + public override SabreTools.Serialization.Models.PlayStation3.SFB? Deserialize(Stream? data) { // If the data is invalid if (data == null || !data.CanRead) @@ -17,7 +17,7 @@ namespace SabreTools.Serialization.Deserializers try { // Deserialize the SFB - var sfb = new SabreTools.Models.PlayStation3.SFB(); + var sfb = new SabreTools.Serialization.Models.PlayStation3.SFB(); sfb.Magic = data.ReadUInt32BigEndian(); if (sfb.Magic != SFBMagic) diff --git a/SabreTools.Serialization/Deserializers/SFO.cs b/SabreTools.Serialization/Deserializers/SFO.cs index 43d8a2bc..4a2df7d9 100644 --- a/SabreTools.Serialization/Deserializers/SFO.cs +++ b/SabreTools.Serialization/Deserializers/SFO.cs @@ -1,14 +1,14 @@ using System.IO; using SabreTools.IO.Extensions; -using SabreTools.Models.PlayStation3; -using static SabreTools.Models.PlayStation3.Constants; +using SabreTools.Serialization.Models.PlayStation3; +using static SabreTools.Serialization.Models.PlayStation3.Constants; namespace SabreTools.Serialization.Deserializers { - public class SFO : BaseBinaryDeserializer + public class SFO : BaseBinaryDeserializer { /// - public override SabreTools.Models.PlayStation3.SFO? Deserialize(Stream? data) + public override SabreTools.Serialization.Models.PlayStation3.SFO? Deserialize(Stream? data) { // If the data is invalid if (data == null || !data.CanRead) @@ -17,7 +17,7 @@ namespace SabreTools.Serialization.Deserializers try { // Create a new SFO to fill - var sfo = new SabreTools.Models.PlayStation3.SFO(); + var sfo = new SabreTools.Serialization.Models.PlayStation3.SFO(); #region Header diff --git a/SabreTools.Serialization/Deserializers/XMID.cs b/SabreTools.Serialization/Deserializers/XMID.cs index 8e43d5a4..e4b87b2d 100644 --- a/SabreTools.Serialization/Deserializers/XMID.cs +++ b/SabreTools.Serialization/Deserializers/XMID.cs @@ -2,17 +2,17 @@ using SabreTools.Serialization.Interfaces; namespace SabreTools.Serialization.Deserializers { - public partial class XMID : IStringDeserializer + public partial class XMID : IStringDeserializer { /// - public static SabreTools.Models.Xbox.XMID? DeserializeString(string? str) + public static SabreTools.Serialization.Models.Xbox.XMID? DeserializeString(string? str) { var deserializer = new XMID(); return deserializer.Deserialize(str); } /// - public SabreTools.Models.Xbox.XMID? Deserialize(string? str) + public SabreTools.Serialization.Models.Xbox.XMID? Deserialize(string? str) { if (string.IsNullOrEmpty(str)) return null; @@ -29,12 +29,12 @@ namespace SabreTools.Serialization.Deserializers /// /// XMID string to attempt to parse /// Filled XMID on success, null on error - private static SabreTools.Models.Xbox.XMID? ParseXMID(string? xmidString) + private static SabreTools.Serialization.Models.Xbox.XMID? ParseXMID(string? xmidString) { if (xmidString == null || xmidString.Length != 8) return null; - var xmid = new SabreTools.Models.Xbox.XMID(); + var xmid = new SabreTools.Serialization.Models.Xbox.XMID(); xmid.PublisherIdentifier = xmidString.Substring(0, 2); xmid.GameID = xmidString.Substring(2, 3); diff --git a/SabreTools.Serialization/Deserializers/XeMID.cs b/SabreTools.Serialization/Deserializers/XeMID.cs index 0faaf546..0c2301f4 100644 --- a/SabreTools.Serialization/Deserializers/XeMID.cs +++ b/SabreTools.Serialization/Deserializers/XeMID.cs @@ -2,17 +2,17 @@ using SabreTools.Serialization.Interfaces; namespace SabreTools.Serialization.Deserializers { - public partial class XeMID : IStringDeserializer + public partial class XeMID : IStringDeserializer { /// - public static SabreTools.Models.Xbox.XeMID? DeserializeString(string? str) + public static SabreTools.Serialization.Models.Xbox.XeMID? DeserializeString(string? str) { var deserializer = new XeMID(); return deserializer.Deserialize(str); } /// - public SabreTools.Models.Xbox.XeMID? Deserialize(string? str) + public SabreTools.Serialization.Models.Xbox.XeMID? Deserialize(string? str) { if (string.IsNullOrEmpty(str)) return null; @@ -29,14 +29,14 @@ namespace SabreTools.Serialization.Deserializers /// /// XeMID string to attempt to parse /// Filled XeMID on success, null on error - private static SabreTools.Models.Xbox.XeMID? ParseXeMID(string? xemidString) + private static SabreTools.Serialization.Models.Xbox.XeMID? ParseXeMID(string? xemidString) { if (xemidString == null) return null; if (!(xemidString.Length == 13 || xemidString.Length == 14 || xemidString.Length == 21 || xemidString.Length == 22)) return null; - var xemid = new SabreTools.Models.Xbox.XeMID(); + var xemid = new SabreTools.Serialization.Models.Xbox.XeMID(); xemid.PublisherIdentifier = xemidString.Substring(0, 2); xemid.PlatformIdentifier = xemidString[2]; diff --git a/SabreTools.Serialization/Models/AACS/CopyrightRecord.cs b/SabreTools.Serialization/Models/AACS/CopyrightRecord.cs new file mode 100644 index 00000000..4ceb43bf --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/CopyrightRecord.cs @@ -0,0 +1,16 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// This record type is undocumented but found in real media key blocks + /// + public sealed class CopyrightRecord : Record + { + /// + /// Null-terminated ASCII string representing the copyright + /// + [MarshalAs(UnmanagedType.LPStr)] + public string? Copyright; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/DriveRevocationListEntry.cs b/SabreTools.Serialization/Models/AACS/DriveRevocationListEntry.cs new file mode 100644 index 00000000..9331d99d --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/DriveRevocationListEntry.cs @@ -0,0 +1,25 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.AACS +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class DriveRevocationListEntry + { + /// + /// A 2-byte Range value indicates the range of revoked ID’s starting + /// from the ID contained in the record. A value of zero in the Range + /// field indicates that only one ID is being revoked, a value of one + /// in the Range field indicates two ID’s are being revoked, and so on. + /// + public ushort Range; + + /// + /// A 6-byte Drive ID value identifying the Licensed Drive being revoked + /// (or the first in a range of Licensed Drives being revoked, in the + /// case of a non-zero Range value). + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[]? DriveID; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/DriveRevocationListRecord.cs b/SabreTools.Serialization/Models/AACS/DriveRevocationListRecord.cs new file mode 100644 index 00000000..4cb6cfb2 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/DriveRevocationListRecord.cs @@ -0,0 +1,26 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// A properly formatted type 3 or type 4 Media Key Block contains exactly + /// one Drive Revocation List Record. It follows the Host Revocation List + /// Record, although it may not immediately follow it. + /// + /// The Drive Revocation List Record is identical to the Host Revocation + /// List Record, except it has type 2016, and it contains Drive Revocation + /// List Entries, not Host Revocation List Entries. The Drive Revocation List + /// Entries refer to Drive IDs in the Drive Certificates. + /// + /// + public sealed class DriveRevocationListRecord : Record + { + /// + /// The total number of Drive Revocation List Entry fields that follow. + /// + public uint TotalNumberOfEntries { get; set; } + + /// + /// Revocation list entries + /// + public DriveRevocationSignatureBlock[]? SignatureBlocks { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/DriveRevocationSignatureBlock.cs b/SabreTools.Serialization/Models/AACS/DriveRevocationSignatureBlock.cs new file mode 100644 index 00000000..e3a9a121 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/DriveRevocationSignatureBlock.cs @@ -0,0 +1,17 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + public sealed class DriveRevocationSignatureBlock + { + /// + /// The number of Drive Revocation List Entry fields in the signature block. + /// + public uint NumberOfEntries { get; set; } + + /// + /// A list of 8-byte Host Drive List Entry fields, the length of this + /// list being equal to the number in the signature block. + /// + public DriveRevocationListEntry[]? EntryFields { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/EndOfMediaKeyBlockRecord.cs b/SabreTools.Serialization/Models/AACS/EndOfMediaKeyBlockRecord.cs new file mode 100644 index 00000000..d393f8b0 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/EndOfMediaKeyBlockRecord.cs @@ -0,0 +1,23 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// A properly formatted MKB shall contain an End of Media Key Block Record. + /// When a device encounters this Record it stops processing the MKB, using + /// whatever Km value it has calculated up to that point as the final Km for + /// that MKB (pending possible checks for correctness of the key, as + /// described previously). + /// + /// + public sealed class EndOfMediaKeyBlockRecord : Record + { + /// + /// AACS LA’s signature on the data in the Media Key Block up to, + /// but not including, this record. Devices depending on the Version + /// Number in the Type and Version Record must verify the signature. + /// Other devices may ignore the signature data. If any device + /// determines that the signature does not verify or is omitted, it + /// must refuse to use the Media Key. + /// + public byte[]? SignatureData { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/Enums.cs b/SabreTools.Serialization/Models/AACS/Enums.cs new file mode 100644 index 00000000..f1437a26 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/Enums.cs @@ -0,0 +1,69 @@ +namespace SabreTools.Serialization.Models.AACS +{ + public enum MediaKeyBlockType : uint + { + /// + /// (Type 3). This is a normal Media Key Block suitable for being recorded + /// on a AACS Recordable Media. Both Class I and Class II Licensed Products + /// use it to directly calculate the Media Key. + /// + Type3 = 0x00031003, + + /// + /// (Type 4). This is a Media Key Block that has been designed to use Key + /// Conversion Data (KCD). Thus, it is suitable only for pre-recorded media + /// from which the KCD is derived. Both Class I and Class II Licensed Products + /// use it to directly calculate the Media Key. + /// + Type4 = 0x00041003, + + /// + /// (Type 10). This is a Class II Media Key Block (one that has the functionality + /// of a Sequence Key Block). This can only be processed by Class II Licensed + /// Products; Class I Licensed Products are revoked in Type 10 Media Key Blocks + /// and cannot process them. This type does not contain the Host Revocation List + /// Record, the Drive Revocation List Record, and the Media Key Data Record, as + /// described in the following sections. It does contain the records shown in + /// Section 3.2.5.2, which are only processed by Class II Licensed Products. + /// + Type10 = 0x000A1003, + + /// + /// Type 2.0 Category C. + /// This is the Media Key Block Type found on "UHD" media (AACS v2.0) + /// + /// + Type20 = 0x48141003, + + /// + /// Type 2.1 Category C. + /// This is the Media Key Block Type found on "UHD" media (AACS v2.1) + /// + /// + Type21 = 0x48151003, + } + + public enum RecordType : byte + { + EndOfMediaKeyBlock = 0x02, + ExplicitSubsetDifference = 0x04, + MediaKeyData = 0x05, + SubsetDifferenceIndex = 0x07, + MediaKeyVariantData = 0x0C, + TypeAndVersion = 0x10, + DriveRevocationList = 0x20, + HostRevocationList = 0x21, + VerifyMediaKey = 0x81, + + // Not documented + Copyright = 0x7F, + + // Record types only found in UHD media (AACS v2) + // + Unknown0x28_AACS2 = 0x28, + DriveRevocationList_AACS2 = 0x30, + HostRevocationList_AACS2 = 0x31, + VerifyMediaKey_AACS2 = 0x86, + EmptyRecord0xF8_AACS2 = 0xF8, + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/ExplicitSubsetDifferenceRecord.cs b/SabreTools.Serialization/Models/AACS/ExplicitSubsetDifferenceRecord.cs new file mode 100644 index 00000000..7288d6d5 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/ExplicitSubsetDifferenceRecord.cs @@ -0,0 +1,11 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + public sealed class ExplicitSubsetDifferenceRecord : Record + { + /// + /// In this record, each subset-difference is encoded with 5 bytes. + /// + public SubsetDifference[]? SubsetDifferences { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/GenericRecord.cs b/SabreTools.Serialization/Models/AACS/GenericRecord.cs new file mode 100644 index 00000000..636466e6 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/GenericRecord.cs @@ -0,0 +1,13 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// This represents any record that does not have a concrete model yet + /// + public sealed class GenericRecord : Record + { + /// + /// Unparsed data comprising the record after the header + /// + public byte[]? Data { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/HostRevocationListEntry.cs b/SabreTools.Serialization/Models/AACS/HostRevocationListEntry.cs new file mode 100644 index 00000000..31baa5ff --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/HostRevocationListEntry.cs @@ -0,0 +1,25 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.AACS +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class HostRevocationListEntry + { + /// + /// A 2-byte Range value indicates the range of revoked ID’s starting + /// from the ID contained in the record. A value of zero in the Range + /// field indicates that only one ID is being revoked, a value of one + /// in the Range field indicates two ID’s are being revoked, and so on. + /// + public ushort Range; + + /// + /// A 6-byte Host ID value identifying the host being revoked (or the + /// first in a range of hosts being revoked, in the case of a non-zero + /// Range value). + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[]? HostID; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/HostRevocationListRecord.cs b/SabreTools.Serialization/Models/AACS/HostRevocationListRecord.cs new file mode 100644 index 00000000..cec5a6a8 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/HostRevocationListRecord.cs @@ -0,0 +1,29 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// A properly formatted type 3 or type 4 Media Key Block shall have exactly + /// one Host Revocation List Record as its second record. This record provides + /// a list of hosts that have been revoked by the AACS LA. The AACS specification + /// is applicable to PC-based system where a Licensed Drive and PC Host act + /// together as the Recording Device and/or Playback Device for AACS Content. + /// AACS uses a drive-host authentication protocol for the host to verify the + /// integrity of the data received from the Licensed Drive, and for the Licensed + /// Drive to check the validity of the host application. The Type and Version + /// Record and the Host Revocation List Record are guaranteed to be the first two + /// records of a Media Key Block, to make it easier for Licensed Drives to extract + /// this data from an arbitrary Media Key Block. + /// + /// + public sealed class HostRevocationListRecord : Record + { + /// + /// The total number of Host Revocation List Entry fields that follow. + /// + public uint TotalNumberOfEntries { get; set; } + + /// + /// Revocation list entries + /// + public HostRevocationSignatureBlock[]? SignatureBlocks { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/HostRevocationSignatureBlock.cs b/SabreTools.Serialization/Models/AACS/HostRevocationSignatureBlock.cs new file mode 100644 index 00000000..cf57f8bb --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/HostRevocationSignatureBlock.cs @@ -0,0 +1,17 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + public sealed class HostRevocationSignatureBlock + { + /// + /// The number of Host Revocation List Entry fields in the signature block. + /// + public uint NumberOfEntries { get; set; } + + /// + /// A list of 8-byte Host Revocation List Entry fields, the length of this + /// list being equal to the number in the signature block. + /// + public HostRevocationListEntry[]? EntryFields { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/MediaKeyBlock.cs b/SabreTools.Serialization/Models/AACS/MediaKeyBlock.cs new file mode 100644 index 00000000..a4691c5a --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/MediaKeyBlock.cs @@ -0,0 +1,14 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// A Media Key Block is formatted as a sequence of contiguous Records. + /// + /// + public sealed class MediaKeyBlock + { + /// + /// Records + /// + public Record[]? Records { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/MediaKeyDataRecord.cs b/SabreTools.Serialization/Models/AACS/MediaKeyDataRecord.cs new file mode 100644 index 00000000..d964fbcf --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/MediaKeyDataRecord.cs @@ -0,0 +1,18 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// This record gives the associated encrypted media key data for the + /// subset-differences identified in the Explicit Subset-Difference Record. + /// + /// + public sealed class MediaKeyDataRecord : Record + { + /// + /// Each subset difference has its associated 16 bytes in this + /// record, in the same order it is encountered in the subset-difference + /// record. This 16 bytes is the ciphertext value C in the media + /// key calculation. + /// + public byte[][]? MediaKeyData { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/Record.cs b/SabreTools.Serialization/Models/AACS/Record.cs new file mode 100644 index 00000000..7e353347 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/Record.cs @@ -0,0 +1,28 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// Each Record begins with a one-byte Record Type field, followed by a + /// three-byte Record Length field. + /// + /// The following subsections describe the currently defined Record types, + /// and how a device processes each. All multi-byte integers, including + /// the length field, are “Big Endian”; in other words, the most significant + /// byte comes first in the record. + /// + /// + public abstract class Record + { + /// + /// The Record Type field value indicates the type of the Record. + /// + public RecordType RecordType { get; set; } + + /// + /// The Record Length field value indicates the number of bytes in + /// the Record, including the Record Type and the Record Length + /// fields themselves. Record lengths are always multiples of 4 bytes. + /// + // UInt24 not UInt32 + public uint RecordLength { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/SubsetDifference.cs b/SabreTools.Serialization/Models/AACS/SubsetDifference.cs new file mode 100644 index 00000000..c6f38b78 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/SubsetDifference.cs @@ -0,0 +1,23 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.AACS +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class SubsetDifference + { + /// + /// The mask for u is given by the first byte. That byte is + /// treated as a number, the number of low-order 0-bits in + /// the mask. For example, the value 0x01 denotes a mask of + /// 0xFFFFFFFE; value 0x0A denotes a mask of 0xFFFFFC00. + /// + public byte Mask; + + /// + /// The last 4 bytes are the uv number, most significant + /// byte first. + /// + public uint Number; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/SubsetDifferenceIndexRecord.cs b/SabreTools.Serialization/Models/AACS/SubsetDifferenceIndexRecord.cs new file mode 100644 index 00000000..846b9001 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/SubsetDifferenceIndexRecord.cs @@ -0,0 +1,26 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// This is a speed-up record which can be ignored by devices not wishing to + /// take advantage of it. It is a lookup table which allows devices to quickly + /// find their subset-difference in the Explicit Subset-Difference record, + /// without processing the entire record. This Subset-Difference Index record + /// is always present, and always precedes the Explicit Subset-Difference record + /// in the MKB, although it does not necessarily immediately precede it. + /// + /// + public sealed class SubsetDifferenceIndexRecord : Record + { + /// + /// The number of devices per index offset. + /// + public uint Span { get; set; } + + /// + /// These offsets refer to the offset within the following Explicit + /// Subset-Difference record, with 0 being the start of the record. + /// + // UInt24 not UInt32 + public uint[]? Offsets { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/TypeAndVersionRecord.cs b/SabreTools.Serialization/Models/AACS/TypeAndVersionRecord.cs new file mode 100644 index 00000000..c334f200 --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/TypeAndVersionRecord.cs @@ -0,0 +1,32 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// Devices, except for recording devices which are writing Media Key Block + /// Extensions, may ignore this record. Recording devices shall verify the + /// signature (see End of Media Key Block record) and use the Version Number + /// in this record to determine if a new Media Key BLock Extension is, in + /// fact, more recent than the Media Key Block Extension that is currently + /// on the media. + /// + /// + public sealed class TypeAndVersionRecord : Record + { + /// + /// For AACS applications, the MKBType field is one of three values. + /// It is not an error for a Type 3 Media Key Block to be used for + /// controlling access to AACS Content on pre- recorded media. In + /// this case, the device shall not use the KCD. + /// + public MediaKeyBlockType MediaKeyBlockType { get; set; } + + /// + /// The Version Number is a 32-bit unsigned integer. Each time the + /// licensing agency changes the revocation, it increments the version + /// number and inserts the new value in subsequent Media Key Blocks. + /// Thus, larger values indicate more recent Media Key Blocks. The + /// Version Numbers begin at 1; 0 is a special value used for test + /// Media Key Blocks. + /// + public uint VersionNumber { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AACS/VerifyMediaKeyRecord.cs b/SabreTools.Serialization/Models/AACS/VerifyMediaKeyRecord.cs new file mode 100644 index 00000000..edcfddcc --- /dev/null +++ b/SabreTools.Serialization/Models/AACS/VerifyMediaKeyRecord.cs @@ -0,0 +1,24 @@ +namespace SabreTools.Serialization.Models.AACS +{ + /// + /// A properly formatted MKB shall have exactly one Verify Media Key Record + /// as its first record. The presence of the Verify Media Key Record in an MKB + /// is mandatory, but the use of the Record by a device is not mandatory. The + /// device may use the Verify Media Key Record to verify the correctness of a + /// given MKB, or of its processing of it. If everything is correct, the device + /// should observe the condition: + /// [AES_128D(vKm, C]msb_64 == 0x0123456789ABCDEF)] + /// where Km is the Media Key value. + /// + /// + public sealed class VerifyMediaKeyRecord : Record + { + /// + /// Bytes 4 through 19 of the Record contain the ciphertext value + /// Cv = AES-128E (Km, 0x0123456789ABCDEF || 0xXXXXXXXXXXXXXXXX) + /// where 0xXXXXXXXXXXXXXXXX is an arbitrary 8-byte value, and Km is + /// the correct final Media Key value. + /// + public byte[]? CiphertextValue { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/AttractMode/MetadataFile.cs b/SabreTools.Serialization/Models/AttractMode/MetadataFile.cs index 6ad4b8b2..53537961 100644 --- a/SabreTools.Serialization/Models/AttractMode/MetadataFile.cs +++ b/SabreTools.Serialization/Models/AttractMode/MetadataFile.cs @@ -5,7 +5,7 @@ namespace SabreTools.Serialization.Models.AttractMode /// public class MetadataFile { - [SabreTools.Models.Required] + [Required] public string[]? Header { get; set; } public Row[]? Row { get; set; } diff --git a/SabreTools.Serialization/Models/AttractMode/Row.cs b/SabreTools.Serialization/Models/AttractMode/Row.cs index 5b31f722..54a341da 100644 --- a/SabreTools.Serialization/Models/AttractMode/Row.cs +++ b/SabreTools.Serialization/Models/AttractMode/Row.cs @@ -3,7 +3,7 @@ namespace SabreTools.Serialization.Models.AttractMode public class Row { /// Also called Romname - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } public string? Title { get; set; } diff --git a/SabreTools.Serialization/Models/BDPlus/Constants.cs b/SabreTools.Serialization/Models/BDPlus/Constants.cs new file mode 100644 index 00000000..75568154 --- /dev/null +++ b/SabreTools.Serialization/Models/BDPlus/Constants.cs @@ -0,0 +1,9 @@ +namespace SabreTools.Serialization.Models.BDPlus +{ + public static class Constants + { + public static readonly byte[] SignatureBytes = [0x42, 0x44, 0x53, 0x56, 0x4D, 0x5F, 0x43, 0x43]; + + public const string SignatureString = "BDSVM_CC"; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/BDPlus/SVM.cs b/SabreTools.Serialization/Models/BDPlus/SVM.cs new file mode 100644 index 00000000..2f873ca4 --- /dev/null +++ b/SabreTools.Serialization/Models/BDPlus/SVM.cs @@ -0,0 +1,50 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.BDPlus +{ + /// + public sealed class SVM + { + /// + /// "BDSVM_CC" + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)] + public string? Signature; + + /// + /// Unknown data + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] + public byte[]? Unknown1 = new byte[5]; + + /// + /// Version year + /// + public ushort Year; + + /// + /// Version month + /// + public byte Month; + + /// + /// Version day + /// + public byte Day; + + /// + /// Unknown data + /// + public uint Unknown2; + + /// + /// Length + /// + public uint Length; + + /// + /// Length bytes of data + /// + public byte[]? Data { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Charts/SongIni.cs b/SabreTools.Serialization/Models/Charts/SongIni.cs new file mode 100644 index 00000000..f171bbbc --- /dev/null +++ b/SabreTools.Serialization/Models/Charts/SongIni.cs @@ -0,0 +1,621 @@ +using System; + +namespace SabreTools.Serialization.Models.Charts +{ + /// + /// [song]/[Song] + public class SongIni + { + #region Song/Chart Metadata + + /// + /// Title of the song. + /// + /// name + public string? Name { get; set; } + + /// + /// Artist(s) or band(s) behind the song. + /// + /// artist + public string? Artist { get; set; } + + /// + /// Title of the album the song is featured in. + /// + /// album + public string? Album { get; set; } + + /// + /// Genre of the song. + /// + /// genre + public string? Genre { get; set; } + + /// + /// Sub-genre for the song. + /// + /// sub_genre + public string? SubGenre { get; set; } + + /// + /// Year of the song’s release. + /// + /// year + public string? Year { get; set; } + + /// + /// Community member responsible for charting the song. + /// + /// charter, frets + public string? Charter { get; set; } + + /// + /// Version number for the song. + /// + /// version + public long? Version { get; set; } + + /// + /// Track number of the song within the album it's from. + /// + /// album_track, track + public long? AlbumTrack { get; set; } + + /// + /// Track number of the song within the playlist/setlist it's from. + /// + /// playlist_track + public long? PlaylistTrack { get; set; } + + /// + /// Length of the song's audio in milliseconds. + /// + /// song_length + public long? SongLength { get; set; } + + /// + /// Timestamp in milliseconds where the song preview starts. + /// + /// preview_start_time + public long? PreviewStartTime { get; set; } + + /// + /// Timestamp in milliseconds that the preview should stop at. + /// + /// preview_end_time + public long? PreviewEndTime { get; set; } + + /// + /// Flavor text for this song, usually shown after picking the song or during loading. + /// + /// loading_phrase + public string? LoadingPhrase { get; set; } + + #endregion + + #region Song/Chart Metadata (Game-Specific) + + /// + /// (FoFiX) Hex color to use in the song screen for the cassette. + /// + /// cassettecolor + public string? CassetteColor { get; set; } + + /// + /// (FoFiX) Miscellaneous tags for the chart. + /// Only known valid value is `cover`. + /// + /// tags + public string? Tags { get; set; } + + /// + /// (PS) Two timestamps in milliseconds for preview start and end time. + /// Example: `55000 85000` + /// + /// preview + public long[]? Preview { get; set; } + + /// + /// (CH) Playlist that the song should show up in. + /// + /// playlist + public string? Playlist { get; set; } + + /// + /// (CH) Sub-playlist that the song should show up in. + /// + /// sub_playlist + public string? SubPlaylist { get; set; } + + /// + /// (CH) Indicates if this song is a modchart. + /// Meant for sorting purposes only. + /// + /// modchart + public bool? Modchart { get; set; } + + /// + /// (CH) Indicates if the song has lyrics or not. + /// Meant for sorting purposes only. + /// + /// lyrics + public bool? Lyrics { get; set; } + + #endregion + + #region Track Difficulties + + /// + /// Overall difficulty of the song. + /// + /// diff_band + public long? DiffBand { get; set; } + + /// + /// Difficulty of the Lead Guitar track. + /// + /// diff_guitar + public long? DiffGuitar { get; set; } + + /// + /// Difficulty of the 6-Fret Lead track. + /// + /// diff_guitarghl + public long? DiffGuitarGHL { get; set; } + + /// + /// Difficulty of the Guitar Co-op track. + /// + /// diff_guitar_coop + public long? DiffGuitarCoop { get; set; } + + /// + /// Difficulty of the 6-Fret Guitar Co-op track. + /// + /// diff_guitar_coop_ghl + public long? DiffGuitarCoopGHL { get; set; } + + /// + /// Difficulty of the Pro Guitar track. + /// + /// diff_guitar_real + public long? DiffGuitarReal { get; set; } + + /// + /// Difficulty of the Pro Guitar 22-fret track. + /// + /// diff_guitar_real_22 + public long? DiffGuitarReal22 { get; set; } + + /// + /// Difficulty of the Rhythm Guitar track. + /// + /// diff_rhythm + public long? DiffRhythm { get; set; } + + /// + /// Difficulty of the 6-Fret Rhythm Guitar track. + /// + /// diff_rhythm_ghl + public long? DiffRhythmGHL { get; set; } + + /// + /// Difficulty of the Bass Guitar track. + /// + /// diff_bass + public long? DiffBass { get; set; } + + /// + /// Difficulty of the 6-Fret Bass track. + /// + /// diff_bassghl + public long? DiffBassGHL { get; set; } + + /// + /// Difficulty of the Pro Bass track. + /// + /// diff_bass_real + public long? DiffBassReal { get; set; } + + /// + /// Difficulty of the Pro Bass 22-fret track. + /// + /// diff_bass_real_22 + public long? DiffBassReal22 { get; set; } + + /// + /// Difficulty of the Drums track. + /// + /// diff_drums + public long? DiffDrums { get; set; } + + /// + /// Difficulty of the Pro Drums track. + /// + /// diff_drums_real + public long? DiffDrumsReal { get; set; } + + /// + /// Difficulty of the Drums Real track. + /// + /// diff_drums_real_ps + public long? DiffDrumsRealPS { get; set; } + + /// + /// Difficulty of the Keys track. + /// + /// diff_keys + public long? DiffKeys { get; set; } + + /// + /// Difficulty of the Pro Keys track. + /// + /// diff_keys_real + public long? DiffKeysReal { get; set; } + + /// + /// Difficulty of the Keys Real track. + /// + /// diff_keys_real_ps + public long? DiffKeysRealPS { get; set; } + + /// + /// Difficulty of the Vocals track. + /// + /// diff_vocals + public long? DiffVocals { get; set; } + + /// + /// Difficulty of the Harmonies track. + /// + /// diff_vocals_harm + public long? DiffVocalsHarm { get; set; } + + /// + /// Difficulty of the Dance track. + /// + /// diff_dance + public long? DiffDance { get; set; } + + #endregion + + #region Chart Properties + + /// + /// Forces the Drums track to be Pro Drums. + /// + /// pro_drums, pro_drum (FoFiX) + public bool? ProDrums { get; set; } + + /// + /// Forces the Drums track to be 5-lane. + /// + /// five_lane_drums + public bool? FiveLaneDrums { get; set; } + + /// + /// Specifies a voice type for the singer (either "male" or "female"). + /// + /// vocal_gender + public string? VocalGender { get; set; } + + /// + /// Specifies a tuning for 17-fret Pro Guitar. + /// + /// real_guitar_tuning + public string? RealGuitarTuning { get; set; } + + /// + /// Specifies a tuning for 22-fret Pro Guitar. + /// + /// real_guitar_22_tuning + public string? RealGuitar22Tuning { get; set; } + + /// + /// Specifies a tuning for 17-fret Pro Bass. + /// + /// real_bass_tuning + public string? RealBassTuning { get; set; } + + /// + /// Specifies a tuning for 22-fret Pro Bass. + /// + /// real_bass_22_tuning + public string? RealBass22Tuning { get; set; } + + /// + /// Specifies the number of lanes for the right hand in Real Keys. + /// + /// real_keys_lane_count_right + public long? RealKeysLaneCountRight { get; set; } + + /// + /// Specifies the number of lanes for the left hand in Real Keys. + /// + /// real_keys_lane_count_left + public long? RealKeysLaneCountLeft { get; set; } + + /// + /// Delays the chart relative to the audio by the specified number of milliseconds. + /// Higher = later notes. Can be negative. + /// + /// delay + [Obsolete] + public long? Delay { get; set; } + + /// + /// Overrides the default sustain cutoff threshold with a specified value in ticks. + /// + /// sustain_cutoff_threshold + [Obsolete] + public long? SustainCutoffThreshold { get; set; } + + /// + /// Overrides the default HOPO threshold with a specified value in ticks. + /// + /// hopo_frequency + [Obsolete] + public long? HopoFrequency { get; set; } + + /// + /// Sets the HOPO threshold to be a 1/8th step. + /// + /// eighthnote_hopo + [Obsolete] + public bool? EighthNoteHopo { get; set; } + + /// + /// Overrides the .mid note number for Star Power on 5-Fret Guitar. + /// Valid values are 103 and 116. + /// + /// multiplier_note, star_power_note (PS) + [Obsolete] + public long? MultiplierNote { get; set; } + + #endregion + + #region Chart Properties (Game-Specific) + + /// + /// (PS) Sets 5 to 4 Lane Drums Fallback Note + /// + /// drum_fallback_blue + public bool? DrumFallbackBlue { get; set; } + + /// + /// (FoFiX) Marks a song as a tutorial and hides it from Quickplay. + /// + /// tutorial + public bool? Tutorial { get; set; } + + /// + /// (FoFiX) Marks a song as a boss battle. + /// + /// boss_battle + public bool? BossBattle { get; set; } + + /// + /// (FoFiX) Overrides the natural HOPO threshold using numbers from 0 to 5. + /// + /// hopofreq + [Obsolete] + public long? HopoFreq { get; set; } + + /// + /// (FoFiX) Sets the "early hit window" size. + /// Valid values are "none", "half", or "full". + /// + /// early_hit_window_size + public string? EarlyHitWindowSize { get; set; } + + /// + /// (CH) Sets whether or not end events in the chart will be respected. + /// + /// end_events + public bool? EndEvents { get; set; } + + /// + /// (PS) Enables .mid SysEx events for guitar sliders/tap notes. + /// + /// sysex_slider + public bool? SysExSlider { get; set; } + + /// + /// (PS) Enables .mid SysEx events for Real Drums hi-hat pedal control. + /// + /// sysex_high_hat_ctrl + public bool? SysExHighHatCtrl { get; set; } + + /// + /// (PS) Enables .mid SysEx events for Real Drums rimshot hits. + /// + /// sysex_rimshot + public bool? SysExRimshot { get; set; } + + /// + /// (PS) Enables .mid SysEx events for guitar open notes. + /// + /// sysex_open_bass + public bool? SysExOpenBass { get; set; } + + /// + /// (PS) Enables .mid SysEx events for Pro Guitar/Bass slide directions. + /// + /// sysex_pro_slide + public bool? SysExProSlide { get; set; } + + /// + /// (PS) Sound sample set index for guitar. + /// + /// guitar_type + public long? GuitarType { get; set; } + + /// + /// (PS) Sound sample set index for bass. + /// + /// bass_type + public long? BassType { get; set; } + + /// + /// (PS) Sound sample set index for drums. + /// + /// kit_type + public long? KitType { get; set; } + + /// + /// (PS) Sound sample set index for keys. + /// + /// keys_type + public long? KeysType { get; set; } + + /// + /// (PS) Sound sample set index for dance. + /// + /// dance_type + public long? DanceType { get; set; } + + #endregion + + #region Images and Other Resources + + /// + /// Name of an icon image to display for this song. + /// Included in either the chart folder or the game the chart was made for, or sourced from this repository of icons. + /// + /// icon + public string? Icon { get; set; } + + /// + /// Name for a background image file. + /// + /// background + public string? Background { get; set; } + + /// + /// Name for a background video file. + /// + /// video + public string? Video { get; set; } + + /// + /// Name for a background video file. + /// + /// video_loop + public bool? VideoLoop { get; set; } + + /// + /// Timestamp in milliseconds where playback of an included video will start. Can be negative. + /// This tag controls the time relative to the video, not relative to the chart. Negative values will delay the video, positive values will make the video be at a further point in when the chart starts. + /// + /// video_start_time + public long? VideoStartTime { get; set; } + + /// + /// Timestamp in milliseconds where playback of an included video will end. -1 means no time is specified. + /// This is assumed to also be relative to the video, not the chart. + /// + /// video_end_time + public long? VideoEndTime { get; set; } + + /// + /// Name for a cover image file. + /// + /// cover + public string? Cover { get; set; } + + #endregion + + #region Images and Other Resources (Game-Specific) + + /// + /// (PS) Name for banner A. + /// + /// link_name_a + public string? LinkNameA { get; set; } + + /// + /// (PS) Name for banner B. + /// + /// link_name_b + public string? LinkNameB { get; set; } + + /// + /// (PS) Link that clicking banner A will open. + /// + /// banner_link_a + public string? BannerLinkA { get; set; } + + /// + /// (PS) Link that clicking banner B will open. + /// + /// banner_link_b + public string? BannerLinkB { get; set; } + + #endregion + + #region Miscellaneous (Game-Specific) + + /// + /// (FoFiX) High score data. + /// + /// scores + public string? Scores { get; set; } + + /// + /// (FoFiX) Additional score data. + /// + /// scores_ext + public string? ScoresExt { get; set; } + + /// + /// (FoFiX) Play count. + /// + /// count + public long? Count { get; set; } + + /// + /// (PS) Player's rating of the song + /// + /// rating + public long? Rating { get; set; } + + /// + /// (FoFiX) Career ID for this song. + /// + /// unlock_id + public string? UnlockId { get; set; } + + /// + /// (FoFiX) The career ID that must be completed to unlock this song. + /// + /// unlock_require + public string? UnlockRequire { get; set; } + + /// + /// (FoFiX) Text to display if the song is locked. + /// + /// unlock_text + public string? UnlockText { get; set; } + + /// + /// (FoFiX) Indicates if the song is unlocked. + /// + /// unlock_completed + public long? UnlockCompleted { get; set; } + + /// + /// (Editor on Fire) Sets a velocity number for drums accent notes. + /// + /// eof_midi_import_drum_accent_velocity + public long? EoFMidiImportDrumAccentVelocity { get; set; } + + /// + /// (Editor on Fire) Sets a velocity number for drums ghost notes. + /// + /// eof_midi_import_drum_ghost_velocity + public long? EoFMidiImportDrumGhostVelocity { get; set; } + + #endregion + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Charts/Tier.cs b/SabreTools.Serialization/Models/Charts/Tier.cs new file mode 100644 index 00000000..d5dee17e --- /dev/null +++ b/SabreTools.Serialization/Models/Charts/Tier.cs @@ -0,0 +1,16 @@ +namespace SabreTools.Serialization.Models.Charts +{ + /// + public class Tier + { + /// + /// Display name of the tier. + /// + public string? Name { get; set; } + + /// + /// Name used for associating a song with this tier, and for checking unlock requirements. + /// + public string? UnlockId { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Charts/TitlesIni.cs b/SabreTools.Serialization/Models/Charts/TitlesIni.cs new file mode 100644 index 00000000..3f9f8a64 --- /dev/null +++ b/SabreTools.Serialization/Models/Charts/TitlesIni.cs @@ -0,0 +1,18 @@ +namespace SabreTools.Serialization.Models.Charts +{ + /// + /// [titles] + public class TitlesIni + { + /// + /// A space-separated list of .ini sections to include in the career. + /// + /// sections + public string[]? SectionList { get; set; } + + /// + /// This entry points to other sections that should be used as part of the career. + /// + public Tier[]? Sections { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/ClrMamePro/Archive.cs b/SabreTools.Serialization/Models/ClrMamePro/Archive.cs index fe8d979d..f6511ca5 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Archive.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Archive.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Archive { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/ClrMamePro/BiosSet.cs b/SabreTools.Serialization/Models/ClrMamePro/BiosSet.cs index 5cd846da..b6beb499 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/BiosSet.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/BiosSet.cs @@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class BiosSet { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// description - [SabreTools.Models.Required] + [Required] public string? Description { get; set; } /// default diff --git a/SabreTools.Serialization/Models/ClrMamePro/Chip.cs b/SabreTools.Serialization/Models/ClrMamePro/Chip.cs index f666f26a..a5714fb4 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Chip.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Chip.cs @@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Chip { /// type, (cpu|audio) - [SabreTools.Models.Required] + [Required] public string? Type { get; set; } /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// flags diff --git a/SabreTools.Serialization/Models/ClrMamePro/DipSwitch.cs b/SabreTools.Serialization/Models/ClrMamePro/DipSwitch.cs index dc3d462c..2aa8a47f 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/DipSwitch.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/DipSwitch.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class DipSwitch { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// entry diff --git a/SabreTools.Serialization/Models/ClrMamePro/Disk.cs b/SabreTools.Serialization/Models/ClrMamePro/Disk.cs index 3c1e1868..ed1be3fa 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Disk.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Disk.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Disk { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// md5 diff --git a/SabreTools.Serialization/Models/ClrMamePro/Driver.cs b/SabreTools.Serialization/Models/ClrMamePro/Driver.cs index f77fbe56..ce4ef187 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Driver.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Driver.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Driver { /// status, (good|imperfect|preliminary) - [SabreTools.Models.Required] + [Required] public string? Status { get; set; } /// color, (good|imperfect|preliminary) diff --git a/SabreTools.Serialization/Models/ClrMamePro/GameBase.cs b/SabreTools.Serialization/Models/ClrMamePro/GameBase.cs index 25f71a49..b0818a22 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/GameBase.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/GameBase.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public abstract class GameBase { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// description diff --git a/SabreTools.Serialization/Models/ClrMamePro/Input.cs b/SabreTools.Serialization/Models/ClrMamePro/Input.cs index b8c7ed8d..cf8ebd86 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Input.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Input.cs @@ -4,14 +4,14 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Input { /// players, Numeric/remarks> - [SabreTools.Models.Required] + [Required] public string? Players { get; set; } /// control public string? Control { get; set; } /// buttons, Numeric - [SabreTools.Models.Required] + [Required] public string? Buttons { get; set; } /// coins, Numeric diff --git a/SabreTools.Serialization/Models/ClrMamePro/Media.cs b/SabreTools.Serialization/Models/ClrMamePro/Media.cs index 3f7c1936..261ea398 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Media.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Media.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Media { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// md5 diff --git a/SabreTools.Serialization/Models/ClrMamePro/Release.cs b/SabreTools.Serialization/Models/ClrMamePro/Release.cs index dfcc592f..cc0ec47e 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Release.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Release.cs @@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Release { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// region - [SabreTools.Models.Required] + [Required] public string? Region { get; set; } /// language diff --git a/SabreTools.Serialization/Models/ClrMamePro/Rom.cs b/SabreTools.Serialization/Models/ClrMamePro/Rom.cs index 5d3771fa..529fe7c0 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Rom.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Rom.cs @@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Rom { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// size, Numeric - [SabreTools.Models.Required] + [Required] public string? Size { get; set; } /// crc diff --git a/SabreTools.Serialization/Models/ClrMamePro/Sample.cs b/SabreTools.Serialization/Models/ClrMamePro/Sample.cs index 507202c7..c7c18c07 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Sample.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Sample.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Sample { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/ClrMamePro/Sound.cs b/SabreTools.Serialization/Models/ClrMamePro/Sound.cs index e774edfb..1943abb5 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Sound.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Sound.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Sound { /// channels, Numeric? - [SabreTools.Models.Required] + [Required] public string? Channels { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/ClrMamePro/Video.cs b/SabreTools.Serialization/Models/ClrMamePro/Video.cs index e4d35535..a86bd62e 100644 --- a/SabreTools.Serialization/Models/ClrMamePro/Video.cs +++ b/SabreTools.Serialization/Models/ClrMamePro/Video.cs @@ -4,11 +4,11 @@ namespace SabreTools.Serialization.Models.ClrMamePro public class Video { /// screen, (raster|vector) - [SabreTools.Models.Required] + [Required] public string? Screen { get; set; } /// orientation, (vertical|horizontal) - [SabreTools.Models.Required] + [Required] public string? Orientation { get; set; } /// x, Numeric? diff --git a/SabreTools.Serialization/Models/CueSheets/CueFile.cs b/SabreTools.Serialization/Models/CueSheets/CueFile.cs new file mode 100644 index 00000000..b2542110 --- /dev/null +++ b/SabreTools.Serialization/Models/CueSheets/CueFile.cs @@ -0,0 +1,26 @@ +/// +/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf +/// +namespace SabreTools.Serialization.Models.CueSheets +{ + /// + /// Represents a single FILE in a cuesheet + /// + public class CueFile + { + /// + /// filename + /// + public string? FileName { get; set; } + + /// + /// filetype + /// + public CueFileType FileType { get; set; } + + /// + /// List of TRACK in FILE + /// + public CueTrack[]? Tracks { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/CueSheets/CueIndex.cs b/SabreTools.Serialization/Models/CueSheets/CueIndex.cs new file mode 100644 index 00000000..84719384 --- /dev/null +++ b/SabreTools.Serialization/Models/CueSheets/CueIndex.cs @@ -0,0 +1,33 @@ +/// +/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf +/// +namespace SabreTools.Serialization.Models.CueSheets +{ + /// + /// Represents a single INDEX in a TRACK + /// + public class CueIndex + { + /// + /// INDEX number, between 0 and 99 + /// + public int Index { get; set; } + + /// + /// Starting time of INDEX in minutes + /// + public int Minutes { get; set; } + + /// + /// Starting time of INDEX in seconds + /// + /// There are 60 seconds in a minute + public int Seconds { get; set; } + + /// + /// Starting time of INDEX in frames. + /// + /// There are 75 frames per second + public int Frames { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/CueSheets/CueSheet.cs b/SabreTools.Serialization/Models/CueSheets/CueSheet.cs new file mode 100644 index 00000000..54da3965 --- /dev/null +++ b/SabreTools.Serialization/Models/CueSheets/CueSheet.cs @@ -0,0 +1,41 @@ +/// +/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf +/// +namespace SabreTools.Serialization.Models.CueSheets +{ + /// + /// Represents a single cuesheet + /// + public class CueSheet + { + /// + /// CATALOG + /// + public string? Catalog { get; set; } + + /// + /// CDTEXTFILE + /// + public string? CdTextFile { get; set; } + + /// + /// PERFORMER + /// + public string? Performer { get; set; } + + /// + /// SONGWRITER + /// + public string? Songwriter { get; set; } + + /// + /// TITLE + /// + public string? Title { get; set; } + + /// + /// List of FILE in cuesheet + /// + public CueFile[]? Files { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/CueSheets/CueTrack.cs b/SabreTools.Serialization/Models/CueSheets/CueTrack.cs new file mode 100644 index 00000000..5c71b84b --- /dev/null +++ b/SabreTools.Serialization/Models/CueSheets/CueTrack.cs @@ -0,0 +1,63 @@ +/// +/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf +/// +namespace SabreTools.Serialization.Models.CueSheets +{ + /// + /// Represents a single TRACK in a FILE + /// + public class CueTrack + { + /// + /// Track number. The range is 1 to 99. + /// + public int Number { get; set; } + + /// + /// Track datatype + /// + public CueTrackDataType DataType { get; set; } + + /// + /// FLAGS + /// + public CueTrackFlag Flags { get; set; } + + /// + /// ISRC + /// + /// 12 characters in length + public string? ISRC { get; set; } + + /// + /// PERFORMER + /// + public string? Performer { get; set; } + + /// + /// SONGWRITER + /// + public string? Songwriter { get; set; } + + /// + /// TITLE + /// + public string? Title { get; set; } + + /// + /// PREGAP + /// + public PreGap? PreGap { get; set; } + + /// + /// List of INDEX in TRACK + /// + /// Must start with 0 or 1 and then sequential + public CueIndex[]? Indices { get; set; } + + /// + /// POSTGAP + /// + public PostGap? PostGap { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/CueSheets/Enums.cs b/SabreTools.Serialization/Models/CueSheets/Enums.cs new file mode 100644 index 00000000..5e9a5cc0 --- /dev/null +++ b/SabreTools.Serialization/Models/CueSheets/Enums.cs @@ -0,0 +1,116 @@ +using System; + +/// +/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf +/// +namespace SabreTools.Serialization.Models.CueSheets +{ + /// + /// The audio or data file’s filetype + /// + public enum CueFileType + { + /// + /// Intel binary file (least significant byte first). Use for data files. + /// + BINARY, + + /// + /// Motorola binary file (most significant byte first). Use for data files. + /// + MOTOROLA, + + /// + /// Audio AIFF file (44.1KHz 16-bit stereo) + /// + AIFF, + + /// + /// Audio WAVE file (44.1KHz 16-bit stereo) + /// + WAVE, + + /// + /// Audio MP3 file (44.1KHz 16-bit stereo) + /// + MP3, + } + + /// + /// Track datatype + /// + public enum CueTrackDataType + { + /// + /// AUDIO, Audio/Music (2352) + /// + AUDIO, + + /// + /// CDG, Karaoke CD+G (2448) + /// + CDG, + + /// + /// MODE1/2048, CD-ROM Mode1 Data (cooked) + /// + MODE1_2048, + + /// + /// MODE1/2352 CD-ROM Mode1 Data (raw) + /// + MODE1_2352, + + /// + /// MODE2/2336, CD-ROM XA Mode2 Data + /// + MODE2_2336, + + /// + /// MODE2/2352, CD-ROM XA Mode2 Data + /// + MODE2_2352, + + /// + /// CDI/2336, CD-I Mode2 Data + /// + CDI_2336, + + /// + /// CDI/2352, CD-I Mode2 Data + /// + CDI_2352, + } + + /// + /// Special subcode flags within a track + /// + [Flags] + public enum CueTrackFlag + { + /// + /// DCP, Digital copy permitted + /// + DCP = 1 << 0, + + /// + /// 4CH, Four channel audio + /// + FourCH = 1 << 1, + + /// + /// PRE, Pre-emphasis enabled (audio tracks only) + /// + PRE = 1 << 2, + + /// + /// SCMS, Serial Copy Management System (not supported by all recorders) + /// + SCMS = 1 << 3, + + /// + /// DATA, set for data files. This flag is set automatically based on the track’s filetype + /// + DATA = 1 << 4, + } +} diff --git a/SabreTools.Serialization/Models/CueSheets/PostGap.cs b/SabreTools.Serialization/Models/CueSheets/PostGap.cs new file mode 100644 index 00000000..ab3b068e --- /dev/null +++ b/SabreTools.Serialization/Models/CueSheets/PostGap.cs @@ -0,0 +1,28 @@ +/// +/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf +/// +namespace SabreTools.Serialization.Models.CueSheets +{ + /// + /// Represents POSTGAP information of a track + /// + public class PostGap + { + /// + /// Length of POSTGAP in minutes + /// + public int Minutes { get; set; } + + /// + /// Length of POSTGAP in seconds + /// + /// There are 60 seconds in a minute + public int Seconds { get; set; } + + /// + /// Length of POSTGAP in frames. + /// + /// There are 75 frames per second + public int Frames { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/CueSheets/PreGap.cs b/SabreTools.Serialization/Models/CueSheets/PreGap.cs new file mode 100644 index 00000000..960a4d41 --- /dev/null +++ b/SabreTools.Serialization/Models/CueSheets/PreGap.cs @@ -0,0 +1,28 @@ +/// +/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf +/// +namespace SabreTools.Serialization.Models.CueSheets +{ + /// + /// Represents PREGAP information of a track + /// + public class PreGap + { + /// + /// Length of PREGAP in minutes + /// + public int Minutes { get; set; } + + /// + /// Length of PREGAP in seconds + /// + /// There are 60 seconds in a minute + public int Seconds { get; set; } + + /// + /// Length of PREGAP in frames. + /// + /// There are 75 frames per second + public int Frames { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/DVD/AudioSubPictureAttributesTable.cs b/SabreTools.Serialization/Models/DVD/AudioSubPictureAttributesTable.cs new file mode 100644 index 00000000..4cb2684a --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/AudioSubPictureAttributesTable.cs @@ -0,0 +1,32 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + public sealed class AudioSubPictureAttributesTable + { + /// + /// Number of title sets + /// + public ushort NumberOfTitleSets { get; set; } + + /// + /// Reserved + /// + public ushort Reserved { get; set; } + + /// + /// End address (last byte of last VTS_ATRT) + /// + public uint EndAddress { get; set; } + + /// + /// Offset to VTS_ATRT n + /// + /// NumberOfTitleSets entries + public uint[]? Offsets { get; set; } + + /// + /// Entries + /// + public AudioSubPictureAttributesTableEntry[]? Entries { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/AudioSubPictureAttributesTableEntry.cs b/SabreTools.Serialization/Models/DVD/AudioSubPictureAttributesTableEntry.cs new file mode 100644 index 00000000..35a42c66 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/AudioSubPictureAttributesTableEntry.cs @@ -0,0 +1,23 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + public sealed class AudioSubPictureAttributesTableEntry + { + /// + /// End address (EA) + /// + public uint EndAddress { get; set; } + + /// + /// VTS_CAT (copy of offset 022-025 of the VTS IFO file) + /// 0=unspecified, 1=Karaoke + /// + public uint Category { get; set; } + + /// + /// Copy of VTS attributes (offset 100 and on from the VTS IFO + /// file, usually 0x300 bytes long) + /// + public byte[]? AttributesCopy { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/CellAddressTable.cs b/SabreTools.Serialization/Models/DVD/CellAddressTable.cs new file mode 100644 index 00000000..b29abd44 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/CellAddressTable.cs @@ -0,0 +1,27 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + public sealed class CellAddressTable + { + /// + /// Number of VOB IDs + /// + public ushort NumberOfVOBIDs { get; set; } + + /// + /// Reserved + /// + public ushort Reserved { get; set; } + + /// + /// End address (last byte of last entry) + /// + public uint EndAddress { get; set; } + + /// + /// 12-byte entries + /// + /// NumberOfVOBIDs entries + public CellAddressTableEntry[]? Entries { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/CellAddressTableEntry.cs b/SabreTools.Serialization/Models/DVD/CellAddressTableEntry.cs new file mode 100644 index 00000000..da83acbe --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/CellAddressTableEntry.cs @@ -0,0 +1,34 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.DVD +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class CellAddressTableEntry + { + /// + /// VOBidn + /// + public ushort VOBIdentity; + + /// + /// CELLidn + /// + public byte CellIdentity; + + /// + /// Reserved + /// + public byte Reserved; + + /// + /// Starting sector within VOB + /// + public uint StartingSectorWithinVOB; + + /// + /// Ending sector within VOB + /// + public uint EndingSectorWithinVOB; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/Constants.cs b/SabreTools.Serialization/Models/DVD/Constants.cs new file mode 100644 index 00000000..b1ec6964 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/Constants.cs @@ -0,0 +1,9 @@ +namespace SabreTools.Serialization.Models.DVD +{ + public static class Constants + { + public const string VideoManagerIFOSignature = "DVDVIDEO-VMG"; + + public const string VideoTitleSetIFOSignature = "DVDVIDEO-VTS"; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/Enums.cs b/SabreTools.Serialization/Models/DVD/Enums.cs new file mode 100644 index 00000000..930f6bef --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/Enums.cs @@ -0,0 +1,56 @@ +using System; + +namespace SabreTools.Serialization.Models.DVD +{ + [Flags] + public enum ProgramChainCategory : byte + { + MenuTypeTitle = 0x02, + Entry = 0x80, + } + + [Flags] + public enum TitleType : byte + { + /// + /// Uop0 Time play or search + /// + Uop0TimePlayOrSearch = 0x01, + + /// + /// Uop1 PTT play or search + /// + Uop1PTTPlayOrSearch = 0x02, + + /// + /// Jump/Link/Call commands - exist + /// + JumpLinkCallExist = 0x04, + + /// + /// Jump/Link/Call commands - button + /// + JumpLinkCallButton = 0x08, + + /// + /// Jump/Link/Call commands - pre/post + /// + JumpLinkCallPrePost = 0x10, + + /// + /// Jump/Link/Call commands - cell + /// + JumpLinkCallCell = 0x20, + + /// + /// 0=one_sequential_pgc + /// 1=not one_sequential (random, shuffle, stills, loops, or more than one pgc) + /// + ComplexPGC = 0x40, + + /// + /// Reserved + /// + Reserved = 0x80, + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/LanguageUnitTable.cs b/SabreTools.Serialization/Models/DVD/LanguageUnitTable.cs new file mode 100644 index 00000000..d1289178 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/LanguageUnitTable.cs @@ -0,0 +1,34 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + public sealed class LanguageUnitTable + { + /// + /// Number of Language Units + /// + public ushort NumberOfLanguageUnits { get; set; } + + /// + /// Reserved + /// + public ushort Reserved { get; set; } + + /// + /// End address (last byte of last PGC in last LU) + /// relative to VMGM_PGCI_UT + /// + public uint EndAddress { get; set; } + + /// + /// Language Units + /// + /// NumberOfVOBIDs entries + public LanguageUnitTableEntry[]? Entries { get; set; } + + /// + /// Program Chains + /// + /// NumberOfVOBIDs entries + public ProgramChainTable[]? ProgramChains { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/LanguageUnitTableEntry.cs b/SabreTools.Serialization/Models/DVD/LanguageUnitTableEntry.cs new file mode 100644 index 00000000..52c69c09 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/LanguageUnitTableEntry.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.DVD +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class LanguageUnitTableEntry + { + /// + /// ISO639 language code + /// + public ushort ISO639LanguageCode; + + /// + /// Reserved for language code extension + /// + public byte Reserved; + + /// + /// Menu existence flag [80 = title] + /// + public byte MenuExistenceFlag; + + /// + /// Offset to VMGM_LU, relative to VMGM_PGCI_UT + /// + public uint LanguageUnitOffset; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/ParentalManagementMasksTable.cs b/SabreTools.Serialization/Models/DVD/ParentalManagementMasksTable.cs new file mode 100644 index 00000000..1a81daac --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/ParentalManagementMasksTable.cs @@ -0,0 +1,37 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + /// The VMG_PTL_MAIT is searched by country, and points to + /// the table for each country. + /// + /// + public sealed class ParentalManagementMasksTable + { + /// + /// Number of countries + /// + public ushort NumberOfCountries { get; set; } + + /// + /// Number of title sets (NTs) + /// + public ushort NumberOfTitleSets { get; set; } + + /// + /// End address (last byte of last PTL_MAIT) + /// + public uint EndAddress { get; set; } + + /// + /// Entries + /// + public ParentalManagementMasksTableEntry[]? Entries { get; set; } + + /// + /// The PTL_MAIT contains the 16-bit masks for the VMG and + /// all title sets for parental management level 8 followed + /// by the masks for level 7, and so on to level 1. + /// + public byte[][]? BitMasks { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/ParentalManagementMasksTableEntry.cs b/SabreTools.Serialization/Models/DVD/ParentalManagementMasksTableEntry.cs new file mode 100644 index 00000000..629e4caf --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/ParentalManagementMasksTableEntry.cs @@ -0,0 +1,24 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.DVD +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class ParentalManagementMasksTableEntry + { + /// + /// Country code + /// + public ushort CountryCode; + + /// + /// Reserved + /// + public ushort Reserved; + + /// + /// Offset to PTL_MAIT + /// + public uint Offset; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/ProgramChainTable.cs b/SabreTools.Serialization/Models/DVD/ProgramChainTable.cs new file mode 100644 index 00000000..7f11c4a5 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/ProgramChainTable.cs @@ -0,0 +1,28 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + public sealed class ProgramChainTable + { + /// + /// Number of Program Chains + /// + public ushort NumberOfProgramChains { get; set; } + + /// + /// Reserved + /// + public ushort Reserved { get; set; } + + /// + /// End address (last byte of last PGC in this LU) + /// relative to VMGM_LU + /// + public uint EndAddress { get; set; } + + /// + /// Program Chains + /// + /// NumberOfProgramChains entries + public ProgramChainTableEntry[]? Entries { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/ProgramChainTableEntry.cs b/SabreTools.Serialization/Models/DVD/ProgramChainTableEntry.cs new file mode 100644 index 00000000..d342616b --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/ProgramChainTableEntry.cs @@ -0,0 +1,30 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.DVD +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class ProgramChainTableEntry + { + /// + /// PGC category + /// + [MarshalAs(UnmanagedType.U1)] + public ProgramChainCategory Category; + + /// + /// Unknown + /// + public byte Unknown; + + /// + /// Parental management mask + /// + public ushort ParentalManagementMask; + + /// + /// Offset to VMGM_PGC, relative to VMGM_LU + /// + public uint Offset; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/TitlesTable.cs b/SabreTools.Serialization/Models/DVD/TitlesTable.cs new file mode 100644 index 00000000..0272601c --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/TitlesTable.cs @@ -0,0 +1,27 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + public sealed class TitlesTable + { + /// + /// Number of titles + /// + public ushort NumberOfTitles { get; set; } + + /// + /// Reserved + /// + public ushort Reserved { get; set; } + + /// + /// End address (last byte of last entry) + /// + public uint EndAddress { get; set; } + + /// + /// 12-byte entries + /// + /// NumberOfTitles entries + public TitlesTableEntry[]? Entries { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/TitlesTableEntry.cs b/SabreTools.Serialization/Models/DVD/TitlesTableEntry.cs new file mode 100644 index 00000000..ff5cab93 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/TitlesTableEntry.cs @@ -0,0 +1,46 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.DVD +{ + /// + [StructLayout(LayoutKind.Sequential)] + public sealed class TitlesTableEntry + { + /// + /// Title type + /// + [MarshalAs(UnmanagedType.U1)] + public TitleType TitleType; + + /// + /// Number of angles + /// + public byte NumberOfAngles; + + /// + /// Number of chapters (PTTs) + /// + public ushort NumberOfChapters; + + /// + /// Parental management mask + /// + public ushort ParentalManagementMask; + + /// + /// Video Title Set number (VTSN) + /// + public byte VideoTitleSetNumber; + + /// + /// Title number within VTS (VTS_TTN) + /// + public byte TitleNumberWithinVTS; + + /// + /// Start sector for VTS, referenced to whole disk + /// (video_ts.ifo starts at sector 00000000) + /// + public uint VTSStartSector; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/VOBUAddressMap.cs b/SabreTools.Serialization/Models/DVD/VOBUAddressMap.cs new file mode 100644 index 00000000..d5e1cfa6 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/VOBUAddressMap.cs @@ -0,0 +1,16 @@ +namespace SabreTools.Serialization.Models.DVD +{ + /// + public sealed class VOBUAddressMap + { + /// + /// End address (last byte of last entry) + /// + public uint EndAddress { get; set; } + + /// + /// Starting sector within VOB of nth VOBU + /// + public uint[]? StartingSectors { get; set; } + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/VideoManagerIFO.cs b/SabreTools.Serialization/Models/DVD/VideoManagerIFO.cs new file mode 100644 index 00000000..281cc77f --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/VideoManagerIFO.cs @@ -0,0 +1,159 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.DVD +{ + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public sealed class VideoManagerIFO + { + /// + /// "DVDVIDEO-VMG" + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)] + public string? Signature; + + /// + /// Last sector of VMG set (last sector of BUP) + /// + public uint LastVMGSetSector; + + /// + /// Last sector of IFO + /// + public uint LastIFOSector; + + /// + /// Version number + /// - Byte 0 - Reserved, should be 0 + /// - Byte 1, Bits 7-4 - Major version number + /// - Byte 1, Bits 3-0 - Minor version number + /// + public ushort VersionNumber; + + /// + /// VMG category + /// + /// byte1=prohibited region mask + public uint VMGCategory; + + /// + /// Number of volumes + /// + public ushort NumberOfVolumes; + + /// + /// Volume number + /// + public ushort VolumeNumber; + + /// + /// Side ID + /// + public byte SideID; + + /// + /// Number of title sets + /// + public ushort NumberOfTitleSets; + + /// + /// Provider ID + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[]? ProviderID; + + /// + /// VMG POS + /// + public ulong VMGPOS; + + /// + /// End byte address of VMGI_MAT + /// + public uint InformationManagementTableEndByteAddress; + + /// + /// Start address of FP_PGC (First Play program chain) + /// + public uint FirstPlayProgramChainStartAddress; + + /// + /// Start sector of Menu VOB + /// + public uint MenuVOBStartSector; + + /// + /// Sector pointer to TT_SRPT (table of titles) + /// + public uint TableOfTitlesSectorPointer; + + /// + /// Sector pointer to VMGM_PGCI_UT (Menu Program Chain table) + /// + public uint MenuProgramChainTableSectorPointer; + + /// + /// Sector pointer to VMG_PTL_MAIT (Parental Management masks) + /// + public uint ParentalManagementMasksSectorPointer; + + /// + /// Sector pointer to VMG_VTS_ATRT (copies of VTS audio/sub-picture attributes) + /// + public uint AudioSubPictureAttributesSectorPointer; + + /// + /// Sector pointer to VMG_TXTDT_MG (text data) + /// + public uint TextDataSectorPointer; + + /// + /// Sector pointer to VMGM_C_ADT (menu cell address table) + /// + public uint MenuCellAddressTableSectorPointer; + + /// + /// Sector pointer to VMGM_VOBU_ADMAP (menu VOBU address map) + /// + public uint MenuVOBUAddressMapSectorPointer; + + /// + /// Video attributes of VMGM_VOBS + /// + public ushort VideoAttributes; + + /// + /// Number of audio streams in VMGM_VOBS + /// + public ushort NumberOfAudioStreams; + + /// + /// Audio attributes of VMGM_VOBS + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public ulong[]? AudioAttributes; + + /// + /// Unknown + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[]? Unknown; + + /// + /// Number of subpicture streams in VMGM_VOBS (0 or 1) + /// + public ushort NumberOfSubpictureStreams; + + /// + /// Subpicture attributes of VMGM_VOBS + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[]? SubpictureAttributes; + + /// + /// Reserved + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] + public byte[]? Reserved; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DVD/VideoTitleSetIFO.cs b/SabreTools.Serialization/Models/DVD/VideoTitleSetIFO.cs new file mode 100644 index 00000000..b37ccab1 --- /dev/null +++ b/SabreTools.Serialization/Models/DVD/VideoTitleSetIFO.cs @@ -0,0 +1,169 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.DVD +{ + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public sealed class VideoTitleSetIFO + { + /// + /// "DVDVIDEO-VTS" + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 12)] + public string? Signature; + + /// + /// Last sector of title set (last sector of BUP) + /// + public uint LastTitleSetSector; + + /// + /// Last sector of IFO + /// + public uint LastIFOSector; + + /// + /// Version number + /// - Byte 0 - Reserved, should be 0 + /// - Byte 1, Bits 7-4 - Major version number + /// - Byte 1, Bits 3-0 - Minor version number + /// + public ushort VersionNumber; + + /// + /// VTS category + /// + /// 0=unspecified, 1=Karaoke + public uint VMGCategory; + + /// + /// Number of volumes + /// + public ushort NumberOfVolumes; + + /// + /// Volume number + /// + public ushort VolumeNumber; + + /// + /// Side ID + /// + public byte SideID; + + /// + /// Number of title sets + /// + public ushort NumberOfTitleSets; + + /// + /// Provider ID + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[]? ProviderID; + + /// + /// VMG POS + /// + public ulong VMGPOS; + + /// + /// End byte address of VTS_MAT + /// + public uint InformationManagementTableEndByteAddress; + + /// + /// Start address of FP_PGC (First Play program chain) + /// + public uint FirstPlayProgramChainStartAddress; + + /// + /// Start sector of Menu VOB + /// + public uint MenuVOBStartSector; + + /// + /// Start sector of Title VOB + /// + public uint TitleVOBStartSector; + + /// + /// Sector pointer to VTS_PTT_SRPT (table of Titles and Chapters) + /// + public uint TableOfTitlesAndChaptersSectorPointer; + + /// + /// Sector pointer to VTS_PGCI (Title Program Chain table) + /// + public uint TitleProgramChainTableSectorPointer; + + /// + /// Sector pointer to VTSM_PGCI_UT (Menu Program Chain table) + /// + public uint MenuProgramChainTableSectorPointer; + + /// + /// Sector pointer to VTS_TMAPTI (time map) + /// + public uint TimeMapSectorPointer; + + /// + /// Sector pointer to VTSM_C_ADT (menu cell address table) + /// + public uint MenuCellAddressTableSectorPointer; + + /// + /// Sector pointer to VTSM_VOBU_ADMAP (menu VOBU address map) + /// + public uint MenuVOBUAddressMapSectorPointer; + + /// + /// Sector pointer to VTS_C_ADT (title set cell address table) + /// + public uint TitleSetCellAddressTableSectorPointer; + + /// + /// Sector pointer to VTS_VOBU_ADMAP (title set VOBU address map) + /// + public uint TitleSetVOBUAddressMapSectorPointer; + + /// + /// Video attributes of VTSM_VOBS + /// + public ushort VideoAttributes; + + /// + /// Number of audio streams in VTSM_VOBS + /// + public ushort NumberOfAudioStreams; + + /// + /// Audio attributes of VTSM_VOBS + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public ulong[]? AudioAttributes; + + /// + /// Unknown + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] + public byte[]? Unknown; + + /// + /// Number of subpicture streams in VTSM_VOBS (0 or 1) + /// + public ushort NumberOfSubpictureStreams; + + /// + /// Subpicture attributes of VTSM_VOBS + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[]? SubpictureAttributes; + + /// + /// Reserved + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] + public byte[]? Reserved; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/DosCenter/File.cs b/SabreTools.Serialization/Models/DosCenter/File.cs index 14d6f008..f6157df6 100644 --- a/SabreTools.Serialization/Models/DosCenter/File.cs +++ b/SabreTools.Serialization/Models/DosCenter/File.cs @@ -4,15 +4,15 @@ namespace SabreTools.Serialization.Models.DosCenter public class File { /// name, attribute - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// size, attribute, numeric - [SabreTools.Models.Required] + [Required] public string? Size { get; set; } /// crc, attribute - [SabreTools.Models.Required] + [Required] public string? CRC { get; set; } /// sha1, attribute diff --git a/SabreTools.Serialization/Models/DosCenter/Game.cs b/SabreTools.Serialization/Models/DosCenter/Game.cs index 71c55405..55c9c459 100644 --- a/SabreTools.Serialization/Models/DosCenter/Game.cs +++ b/SabreTools.Serialization/Models/DosCenter/Game.cs @@ -4,7 +4,7 @@ namespace SabreTools.Serialization.Models.DosCenter public class Game { /// name - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } /// file diff --git a/SabreTools.Serialization/Models/EverdriveSMDB/Row.cs b/SabreTools.Serialization/Models/EverdriveSMDB/Row.cs index 23f843d1..48c2eb04 100644 --- a/SabreTools.Serialization/Models/EverdriveSMDB/Row.cs +++ b/SabreTools.Serialization/Models/EverdriveSMDB/Row.cs @@ -5,19 +5,19 @@ namespace SabreTools.Serialization.Models.EverdriveSMDB /// public class Row { - [SabreTools.Models.Required] + [Required] public string? SHA256 { get; set; } - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] public string? SHA1 { get; set; } - [SabreTools.Models.Required] + [Required] public string? MD5 { get; set; } - [SabreTools.Models.Required] + [Required] public string? CRC32 { get; set; } public string? Size { get; set; } diff --git a/SabreTools.Serialization/Models/Hashfile/MD2.cs b/SabreTools.Serialization/Models/Hashfile/MD2.cs index a95826ae..4d43e617 100644 --- a/SabreTools.Serialization/Models/Hashfile/MD2.cs +++ b/SabreTools.Serialization/Models/Hashfile/MD2.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class MD2 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/MD4.cs b/SabreTools.Serialization/Models/Hashfile/MD4.cs index 9ebfef26..5074d3bc 100644 --- a/SabreTools.Serialization/Models/Hashfile/MD4.cs +++ b/SabreTools.Serialization/Models/Hashfile/MD4.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class MD4 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/MD5.cs b/SabreTools.Serialization/Models/Hashfile/MD5.cs index 7ce1c630..772925d1 100644 --- a/SabreTools.Serialization/Models/Hashfile/MD5.cs +++ b/SabreTools.Serialization/Models/Hashfile/MD5.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class MD5 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/RIPEMD128.cs b/SabreTools.Serialization/Models/Hashfile/RIPEMD128.cs index 48682e41..95084c22 100644 --- a/SabreTools.Serialization/Models/Hashfile/RIPEMD128.cs +++ b/SabreTools.Serialization/Models/Hashfile/RIPEMD128.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class RIPEMD128 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/RIPEMD160.cs b/SabreTools.Serialization/Models/Hashfile/RIPEMD160.cs index f62c6e49..7efcfb2f 100644 --- a/SabreTools.Serialization/Models/Hashfile/RIPEMD160.cs +++ b/SabreTools.Serialization/Models/Hashfile/RIPEMD160.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class RIPEMD160 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/SFV.cs b/SabreTools.Serialization/Models/Hashfile/SFV.cs index 1eacdfaf..1a007851 100644 --- a/SabreTools.Serialization/Models/Hashfile/SFV.cs +++ b/SabreTools.Serialization/Models/Hashfile/SFV.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class SFV { - [SabreTools.Models.Required] + [Required] public string? File { get; set; } - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/SHA1.cs b/SabreTools.Serialization/Models/Hashfile/SHA1.cs index d7f8bd6c..84b455b1 100644 --- a/SabreTools.Serialization/Models/Hashfile/SHA1.cs +++ b/SabreTools.Serialization/Models/Hashfile/SHA1.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class SHA1 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/SHA256.cs b/SabreTools.Serialization/Models/Hashfile/SHA256.cs index ea360bee..86ecfd12 100644 --- a/SabreTools.Serialization/Models/Hashfile/SHA256.cs +++ b/SabreTools.Serialization/Models/Hashfile/SHA256.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class SHA256 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/SHA384.cs b/SabreTools.Serialization/Models/Hashfile/SHA384.cs index 941c7bb7..0afbeb3c 100644 --- a/SabreTools.Serialization/Models/Hashfile/SHA384.cs +++ b/SabreTools.Serialization/Models/Hashfile/SHA384.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class SHA384 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/SHA512.cs b/SabreTools.Serialization/Models/Hashfile/SHA512.cs index 31a75d57..7bfd0be8 100644 --- a/SabreTools.Serialization/Models/Hashfile/SHA512.cs +++ b/SabreTools.Serialization/Models/Hashfile/SHA512.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class SHA512 { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Hashfile/SpamSum.cs b/SabreTools.Serialization/Models/Hashfile/SpamSum.cs index b61c1d2f..74512309 100644 --- a/SabreTools.Serialization/Models/Hashfile/SpamSum.cs +++ b/SabreTools.Serialization/Models/Hashfile/SpamSum.cs @@ -5,10 +5,10 @@ namespace SabreTools.Serialization.Models.Hashfile /// public class SpamSum { - [SabreTools.Models.Required] + [Required] public string? Hash { get; set; } - [SabreTools.Models.Required] + [Required] public string? File { get; set; } } } \ No newline at end of file diff --git a/SabreTools.Serialization/Models/IRD/File.cs b/SabreTools.Serialization/Models/IRD/File.cs new file mode 100644 index 00000000..3462217e --- /dev/null +++ b/SabreTools.Serialization/Models/IRD/File.cs @@ -0,0 +1,140 @@ +namespace SabreTools.Serialization.Models.IRD +{ + /// + /// + public class File + { + /// + /// "3IRD" + /// + public byte[]? Magic { get; set; } + + /// + /// Version + /// + /// Versions 6 - 9 are accepted + public byte Version { get; set; } + + /// + /// The same value stored in PARAM.SFO / TITLE_ID + /// + /// 9 bytes, ASCII, stored without dashes + public string? TitleID { get; set; } + + /// + /// Number of bytes that follow containing the title + /// + public byte TitleLength { get; set; } + + /// + /// The same value stored in PARAM.SFO / TITLE + /// + /// bytes, ASCII + public string? Title { get; set; } + + /// + /// The same value stored in PARAM.SFO / PS3_SYSTEM_VER + /// + /// 4 bytes, ASCII, missing uses "0000" + public string? SystemVersion { get; set; } + + /// + /// The same value stored in PARAM.SFO / VERSION + /// + /// 5 bytes, ASCII + public string? GameVersion { get; set; } + + /// + /// The same value stored in PARAM.SFO / APP_VER + /// + /// 5 bytes, ASCII + public string? AppVersion { get; set; } + + /// + /// Length of the gzip-compressed header data + /// + public uint HeaderLength { get; set; } + + /// + /// Gzip-compressed header data + /// + public byte[]? Header { get; set; } + + /// + /// Length of the gzip-compressed footer data + /// + public uint FooterLength { get; set; } + + /// + /// Gzip-compressed footer data + /// + public byte[]? Footer { get; set; } + + /// + /// Number of complete regions in the image + /// + public byte RegionCount { get; set; } + + /// + /// MD5 hashes for all complete regions in the image + /// + /// regions, 16-bytes per hash + public byte[][]? RegionHashes { get; set; } + + /// + /// Number of decrypted files in the image + /// + public uint FileCount { get; set; } + + /// + /// Starting sector for each decrypted file + /// + /// files, alternating with each entry + public ulong[]? FileKeys { get; set; } + + /// + /// MD5 hashes for all decrypted files in the image + /// + /// files, 16-bytes per hash, alternating with each entry + public byte[][]? FileHashes { get; set; } + + /// + /// Extra Config, usually 0x0000 + /// + public ushort ExtraConfig { get; set; } + + /// + /// Attachments, usually 0x0000 + /// + public ushort Attachments { get; set; } + + /// + /// D1 key + /// + /// 16 bytes + public byte[]? Data1Key { get; set; } + + /// + /// D2 key + /// + /// 16 bytes + public byte[]? Data2Key { get; set; } + + /// + /// Uncompressed PIC data + /// + /// 115 bytes, before D1/D2 keys on version 9 + public byte[]? PIC { get; set; } + + /// + /// Unique Identifier + /// + /// Not present on version 6 and prior, after AppVersion on version 7 + public uint UID { get; set; } + + /// + /// IRD content CRC + /// + public uint CRC { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/Listrom/Row.cs b/SabreTools.Serialization/Models/Listrom/Row.cs index e85f3fad..5ebce8e2 100644 --- a/SabreTools.Serialization/Models/Listrom/Row.cs +++ b/SabreTools.Serialization/Models/Listrom/Row.cs @@ -14,7 +14,7 @@ namespace SabreTools.Serialization.Models.Listrom /// public class Row { - [SabreTools.Models.Required] + [Required] public string? Name { get; set; } public string? Size { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Adjuster.cs b/SabreTools.Serialization/Models/Listxml/Adjuster.cs index 3024a624..dd0f7171 100644 --- a/SabreTools.Serialization/Models/Listxml/Adjuster.cs +++ b/SabreTools.Serialization/Models/Listxml/Adjuster.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("adjuster")] public class Adjuster { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Analog.cs b/SabreTools.Serialization/Models/Listxml/Analog.cs index 628cfcea..6b9e4b39 100644 --- a/SabreTools.Serialization/Models/Listxml/Analog.cs +++ b/SabreTools.Serialization/Models/Listxml/Analog.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("analog")] public class Analog { - [SabreTools.Models.Required] + [Required] [XmlAttribute("mask")] public string? Mask { get; set; } } diff --git a/SabreTools.Serialization/Models/Listxml/BiosSet.cs b/SabreTools.Serialization/Models/Listxml/BiosSet.cs index e406a3fd..2af1bb23 100644 --- a/SabreTools.Serialization/Models/Listxml/BiosSet.cs +++ b/SabreTools.Serialization/Models/Listxml/BiosSet.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("biosset")] public class BiosSet { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("description")] public string? Description { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Chip.cs b/SabreTools.Serialization/Models/Listxml/Chip.cs index beba4d0d..2e9f672d 100644 --- a/SabreTools.Serialization/Models/Listxml/Chip.cs +++ b/SabreTools.Serialization/Models/Listxml/Chip.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("chip")] public class Chip { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } @@ -14,7 +14,7 @@ namespace SabreTools.Serialization.Models.Listxml public string? Tag { get; set; } /// (cpu|audio) - [SabreTools.Models.Required] + [Required] [XmlAttribute("type")] public string? Type { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Condition.cs b/SabreTools.Serialization/Models/Listxml/Condition.cs index e01276a7..43b16ca7 100644 --- a/SabreTools.Serialization/Models/Listxml/Condition.cs +++ b/SabreTools.Serialization/Models/Listxml/Condition.cs @@ -6,20 +6,20 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("condition")] public class Condition { - [SabreTools.Models.Required] + [Required] [XmlAttribute("tag")] public string? Tag { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("mask")] public string? Mask { get; set; } /// (eq|ne|gt|le|lt|ge) - [SabreTools.Models.Required] + [Required] [XmlAttribute("relation")] public string? Relation { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("value")] public string? Value { get; set; } } diff --git a/SabreTools.Serialization/Models/Listxml/ConfLocation.cs b/SabreTools.Serialization/Models/Listxml/ConfLocation.cs index 8d5c7f61..1b9cd0f3 100644 --- a/SabreTools.Serialization/Models/Listxml/ConfLocation.cs +++ b/SabreTools.Serialization/Models/Listxml/ConfLocation.cs @@ -6,12 +6,12 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("conflocation")] public class ConfLocation { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } /// Numeric? - [SabreTools.Models.Required] + [Required] [XmlAttribute("number")] public string? Number { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/ConfSetting.cs b/SabreTools.Serialization/Models/Listxml/ConfSetting.cs index 573e9308..6a5bd8b8 100644 --- a/SabreTools.Serialization/Models/Listxml/ConfSetting.cs +++ b/SabreTools.Serialization/Models/Listxml/ConfSetting.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("confsetting")] public class ConfSetting { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("value")] public string? Value { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Configuration.cs b/SabreTools.Serialization/Models/Listxml/Configuration.cs index c50fe883..ea0b584f 100644 --- a/SabreTools.Serialization/Models/Listxml/Configuration.cs +++ b/SabreTools.Serialization/Models/Listxml/Configuration.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("configuration")] public class Configuration { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("tag")] public string? Tag { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Control.cs b/SabreTools.Serialization/Models/Listxml/Control.cs index 7d806a0b..c1ca1c23 100644 --- a/SabreTools.Serialization/Models/Listxml/Control.cs +++ b/SabreTools.Serialization/Models/Listxml/Control.cs @@ -7,7 +7,7 @@ namespace SabreTools.Serialization.Models.Listxml public class Control { /// (joy|stick|paddle|pedal|lightgun|positional|dial|trackball|mouse|only_buttons|keypad|keyboard|mahjong|hanafuda|gambling) - [SabreTools.Models.Required] + [Required] [XmlAttribute("type")] public string? Type { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Device.cs b/SabreTools.Serialization/Models/Listxml/Device.cs index 15bfb1be..92ce141e 100644 --- a/SabreTools.Serialization/Models/Listxml/Device.cs +++ b/SabreTools.Serialization/Models/Listxml/Device.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("device")] public class Device { - [SabreTools.Models.Required] + [Required] [XmlAttribute("type")] public string? Type { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/DeviceRef.cs b/SabreTools.Serialization/Models/Listxml/DeviceRef.cs index 2387c785..d343e95a 100644 --- a/SabreTools.Serialization/Models/Listxml/DeviceRef.cs +++ b/SabreTools.Serialization/Models/Listxml/DeviceRef.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("device_ref")] public class DeviceRef { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } } diff --git a/SabreTools.Serialization/Models/Listxml/DipLocation.cs b/SabreTools.Serialization/Models/Listxml/DipLocation.cs index 1aa09a70..757df434 100644 --- a/SabreTools.Serialization/Models/Listxml/DipLocation.cs +++ b/SabreTools.Serialization/Models/Listxml/DipLocation.cs @@ -6,12 +6,12 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("diplocation")] public class DipLocation { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } /// Numeric? - [SabreTools.Models.Required] + [Required] [XmlAttribute("number")] public string? Number { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/DipSwitch.cs b/SabreTools.Serialization/Models/Listxml/DipSwitch.cs index 544d366c..7acc239f 100644 --- a/SabreTools.Serialization/Models/Listxml/DipSwitch.cs +++ b/SabreTools.Serialization/Models/Listxml/DipSwitch.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("dipswitch")] public class DipSwitch { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("tag")] public string? Tag { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/DipValue.cs b/SabreTools.Serialization/Models/Listxml/DipValue.cs index 330cc991..5b6fd1a6 100644 --- a/SabreTools.Serialization/Models/Listxml/DipValue.cs +++ b/SabreTools.Serialization/Models/Listxml/DipValue.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("dipvalue")] public class DipValue { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("value")] public string? Value { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Disk.cs b/SabreTools.Serialization/Models/Listxml/Disk.cs index ba3f4245..605b5adc 100644 --- a/SabreTools.Serialization/Models/Listxml/Disk.cs +++ b/SabreTools.Serialization/Models/Listxml/Disk.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("disk")] public class Disk { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Display.cs b/SabreTools.Serialization/Models/Listxml/Display.cs index f96b333a..925899f8 100644 --- a/SabreTools.Serialization/Models/Listxml/Display.cs +++ b/SabreTools.Serialization/Models/Listxml/Display.cs @@ -10,7 +10,7 @@ namespace SabreTools.Serialization.Models.Listxml public string? Tag { get; set; } /// (raster|vector|lcd|svg|unknown) - [SabreTools.Models.Required] + [Required] [XmlAttribute("type")] public string? Type { get; set; } @@ -31,7 +31,7 @@ namespace SabreTools.Serialization.Models.Listxml public string? Height { get; set; } /// Numeric - [SabreTools.Models.Required] + [Required] [XmlAttribute("refresh")] public string? Refresh { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Driver.cs b/SabreTools.Serialization/Models/Listxml/Driver.cs index 0f05ac73..edbeceb5 100644 --- a/SabreTools.Serialization/Models/Listxml/Driver.cs +++ b/SabreTools.Serialization/Models/Listxml/Driver.cs @@ -7,7 +7,7 @@ namespace SabreTools.Serialization.Models.Listxml public class Driver { /// (good|imperfect|preliminary), (good|preliminary|test) in older versions - [SabreTools.Models.Required] + [Required] [XmlAttribute("status")] public string? Status { get; set; } @@ -24,17 +24,17 @@ namespace SabreTools.Serialization.Models.Listxml public string? PaletteSize { get; set; } /// (good|imperfect|preliminary) - [SabreTools.Models.Required] + [Required] [XmlAttribute("emulation")] public string? Emulation { get; set; } /// (good|imperfect|preliminary) - [SabreTools.Models.Required] + [Required] [XmlAttribute("cocktail")] public string? Cocktail { get; set; } /// (supported|unsupported) - [SabreTools.Models.Required] + [Required] [XmlAttribute("savestate")] public string? SaveState { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Extension.cs b/SabreTools.Serialization/Models/Listxml/Extension.cs index b9b64d20..6964fd65 100644 --- a/SabreTools.Serialization/Models/Listxml/Extension.cs +++ b/SabreTools.Serialization/Models/Listxml/Extension.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("extension")] public class Extension { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } } diff --git a/SabreTools.Serialization/Models/Listxml/Feature.cs b/SabreTools.Serialization/Models/Listxml/Feature.cs index 601021d9..f89b2b52 100644 --- a/SabreTools.Serialization/Models/Listxml/Feature.cs +++ b/SabreTools.Serialization/Models/Listxml/Feature.cs @@ -7,7 +7,7 @@ namespace SabreTools.Serialization.Models.Listxml public class Feature { /// (protection|timing|graphics|palette|sound|capture|camera|microphone|controls|keyboard|mouse|media|disk|printer|tape|punch|drum|rom|comms|lan|wan) - [SabreTools.Models.Required] + [Required] [XmlAttribute("type")] public string? Type { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/GameBase.cs b/SabreTools.Serialization/Models/Listxml/GameBase.cs index 9a450b5c..98fb287d 100644 --- a/SabreTools.Serialization/Models/Listxml/GameBase.cs +++ b/SabreTools.Serialization/Models/Listxml/GameBase.cs @@ -8,7 +8,7 @@ namespace SabreTools.Serialization.Models.Listxml /// public abstract class GameBase { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } @@ -41,7 +41,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlAttribute("sampleof")] public string? SampleOf { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("description")] public string? Description { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Input.cs b/SabreTools.Serialization/Models/Listxml/Input.cs index 343eb201..a45270c8 100644 --- a/SabreTools.Serialization/Models/Listxml/Input.cs +++ b/SabreTools.Serialization/Models/Listxml/Input.cs @@ -15,7 +15,7 @@ namespace SabreTools.Serialization.Models.Listxml public string? Tilt { get; set; } /// Numeric - [SabreTools.Models.Required] + [Required] [XmlAttribute("players")] public string? Players { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Instance.cs b/SabreTools.Serialization/Models/Listxml/Instance.cs index 92b654d7..dd6b9d33 100644 --- a/SabreTools.Serialization/Models/Listxml/Instance.cs +++ b/SabreTools.Serialization/Models/Listxml/Instance.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("instance")] public class Instance { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("briefname")] public string? BriefName { get; set; } } diff --git a/SabreTools.Serialization/Models/Listxml/Mame.cs b/SabreTools.Serialization/Models/Listxml/Mame.cs index 5933cc90..fa0771f2 100644 --- a/SabreTools.Serialization/Models/Listxml/Mame.cs +++ b/SabreTools.Serialization/Models/Listxml/Mame.cs @@ -13,7 +13,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlAttribute("debug")] public string? Debug { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("mameconfig")] public string? MameConfig { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Port.cs b/SabreTools.Serialization/Models/Listxml/Port.cs index a677053f..58d3c14f 100644 --- a/SabreTools.Serialization/Models/Listxml/Port.cs +++ b/SabreTools.Serialization/Models/Listxml/Port.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("port")] public class Port { - [SabreTools.Models.Required] + [Required] [XmlAttribute("tag")] public string? Tag { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/RamOption.cs b/SabreTools.Serialization/Models/Listxml/RamOption.cs index 69c5217a..037555f1 100644 --- a/SabreTools.Serialization/Models/Listxml/RamOption.cs +++ b/SabreTools.Serialization/Models/Listxml/RamOption.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("ramoption")] public class RamOption { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Rom.cs b/SabreTools.Serialization/Models/Listxml/Rom.cs index c708380a..62ec4079 100644 --- a/SabreTools.Serialization/Models/Listxml/Rom.cs +++ b/SabreTools.Serialization/Models/Listxml/Rom.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("rom")] public class Rom { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } @@ -14,7 +14,7 @@ namespace SabreTools.Serialization.Models.Listxml public string? Bios { get; set; } /// Numeric - [SabreTools.Models.Required] + [Required] [XmlAttribute("size")] public string? Size { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Sample.cs b/SabreTools.Serialization/Models/Listxml/Sample.cs index 2c65ed77..a616e0bd 100644 --- a/SabreTools.Serialization/Models/Listxml/Sample.cs +++ b/SabreTools.Serialization/Models/Listxml/Sample.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("sample")] public class Sample { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } } diff --git a/SabreTools.Serialization/Models/Listxml/Slot.cs b/SabreTools.Serialization/Models/Listxml/Slot.cs index 0689229c..651b3d9c 100644 --- a/SabreTools.Serialization/Models/Listxml/Slot.cs +++ b/SabreTools.Serialization/Models/Listxml/Slot.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("slot")] public class Slot { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/SlotOption.cs b/SabreTools.Serialization/Models/Listxml/SlotOption.cs index 84079404..5bede4c2 100644 --- a/SabreTools.Serialization/Models/Listxml/SlotOption.cs +++ b/SabreTools.Serialization/Models/Listxml/SlotOption.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("slotoption")] public class SlotOption { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("devname")] public string? DevName { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/SoftwareList.cs b/SabreTools.Serialization/Models/Listxml/SoftwareList.cs index a75d3d4e..29892de2 100644 --- a/SabreTools.Serialization/Models/Listxml/SoftwareList.cs +++ b/SabreTools.Serialization/Models/Listxml/SoftwareList.cs @@ -6,16 +6,16 @@ namespace SabreTools.Serialization.Models.Listxml [XmlRoot("softwarelist")] public class SoftwareList { - [SabreTools.Models.Required] + [Required] [XmlAttribute("tag")] public string? Tag { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } /// (original|compatible) - [SabreTools.Models.Required] + [Required] [XmlAttribute("status")] public string? Status { get; set; } diff --git a/SabreTools.Serialization/Models/Listxml/Sound.cs b/SabreTools.Serialization/Models/Listxml/Sound.cs index 68e9c949..e7fe7ddd 100644 --- a/SabreTools.Serialization/Models/Listxml/Sound.cs +++ b/SabreTools.Serialization/Models/Listxml/Sound.cs @@ -7,7 +7,7 @@ namespace SabreTools.Serialization.Models.Listxml public class Sound { /// Numeric - [SabreTools.Models.Required] + [Required] [XmlAttribute("channels")] public string? Channels { get; set; } } diff --git a/SabreTools.Serialization/Models/Listxml/Video.cs b/SabreTools.Serialization/Models/Listxml/Video.cs index 66dd552c..d7fdfaa4 100644 --- a/SabreTools.Serialization/Models/Listxml/Video.cs +++ b/SabreTools.Serialization/Models/Listxml/Video.cs @@ -7,12 +7,12 @@ namespace SabreTools.Serialization.Models.Listxml public class Video { /// (raster|vector) - [SabreTools.Models.Required] + [Required] [XmlAttribute("screen")] public string? Screen { get; set; } /// (vertical|horizontal) - [SabreTools.Models.Required] + [Required] [XmlAttribute("orientation")] public string? Orientation { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Archive.cs b/SabreTools.Serialization/Models/Logiqx/Archive.cs index 661d1b9e..16620cbe 100644 --- a/SabreTools.Serialization/Models/Logiqx/Archive.cs +++ b/SabreTools.Serialization/Models/Logiqx/Archive.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("archive")] public class Archive { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } } diff --git a/SabreTools.Serialization/Models/Logiqx/BiosSet.cs b/SabreTools.Serialization/Models/Logiqx/BiosSet.cs index e6dab442..d39a7739 100644 --- a/SabreTools.Serialization/Models/Logiqx/BiosSet.cs +++ b/SabreTools.Serialization/Models/Logiqx/BiosSet.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("biosset")] public class BiosSet { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("description")] public string? Description { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/DeviceRef.cs b/SabreTools.Serialization/Models/Logiqx/DeviceRef.cs index 01f97d96..5c179435 100644 --- a/SabreTools.Serialization/Models/Logiqx/DeviceRef.cs +++ b/SabreTools.Serialization/Models/Logiqx/DeviceRef.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("device_ref")] public class DeviceRef { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } } diff --git a/SabreTools.Serialization/Models/Logiqx/Dir.cs b/SabreTools.Serialization/Models/Logiqx/Dir.cs index d7ba371f..5eb76620 100644 --- a/SabreTools.Serialization/Models/Logiqx/Dir.cs +++ b/SabreTools.Serialization/Models/Logiqx/Dir.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("dir")] public class Dir { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Disk.cs b/SabreTools.Serialization/Models/Logiqx/Disk.cs index e97ed987..eb27558c 100644 --- a/SabreTools.Serialization/Models/Logiqx/Disk.cs +++ b/SabreTools.Serialization/Models/Logiqx/Disk.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("disk")] public class Disk { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Driver.cs b/SabreTools.Serialization/Models/Logiqx/Driver.cs index fd6a619a..66a87f3d 100644 --- a/SabreTools.Serialization/Models/Logiqx/Driver.cs +++ b/SabreTools.Serialization/Models/Logiqx/Driver.cs @@ -7,22 +7,22 @@ namespace SabreTools.Serialization.Models.Logiqx public class Driver { /// (good|imperfect|preliminary) - [SabreTools.Models.Required] + [Required] [XmlAttribute("status")] public string? Status { get; set; } /// (good|imperfect|preliminary) - [SabreTools.Models.Required] + [Required] [XmlAttribute("emulation")] public string? Emulation { get; set; } /// (good|imperfect|preliminary) - [SabreTools.Models.Required] + [Required] [XmlAttribute("cocktail")] public string? Cocktail { get; set; } /// (supported|unsupported) - [SabreTools.Models.Required] + [Required] [XmlAttribute("savestate")] public string? SaveState { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/GameBase.cs b/SabreTools.Serialization/Models/Logiqx/GameBase.cs index 55a5307b..793f21e2 100644 --- a/SabreTools.Serialization/Models/Logiqx/GameBase.cs +++ b/SabreTools.Serialization/Models/Logiqx/GameBase.cs @@ -8,7 +8,7 @@ namespace SabreTools.Serialization.Models.Logiqx /// public abstract class GameBase { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } @@ -57,7 +57,7 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlElement("comment")] public string[]? Comment { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("description")] public string? Description { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Header.cs b/SabreTools.Serialization/Models/Logiqx/Header.cs index a2902179..31a19ec0 100644 --- a/SabreTools.Serialization/Models/Logiqx/Header.cs +++ b/SabreTools.Serialization/Models/Logiqx/Header.cs @@ -10,11 +10,11 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlElement("id")] public string? Id { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("description")] public string? Description { get; set; } @@ -25,14 +25,14 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlElement("category")] public string? Category { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("version")] public string? Version { get; set; } [XmlElement("date")] public string? Date { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("author")] public string? Author { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Media.cs b/SabreTools.Serialization/Models/Logiqx/Media.cs index e5f12d6e..2f52791e 100644 --- a/SabreTools.Serialization/Models/Logiqx/Media.cs +++ b/SabreTools.Serialization/Models/Logiqx/Media.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("media")] public class Media { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Release.cs b/SabreTools.Serialization/Models/Logiqx/Release.cs index d3418b06..e833c06f 100644 --- a/SabreTools.Serialization/Models/Logiqx/Release.cs +++ b/SabreTools.Serialization/Models/Logiqx/Release.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("release")] public class Release { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("region")] public string? Region { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Rom.cs b/SabreTools.Serialization/Models/Logiqx/Rom.cs index b0bc2f2f..92a3ae74 100644 --- a/SabreTools.Serialization/Models/Logiqx/Rom.cs +++ b/SabreTools.Serialization/Models/Logiqx/Rom.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("rom")] public class Rom { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("size")] public string? Size { get; set; } diff --git a/SabreTools.Serialization/Models/Logiqx/Sample.cs b/SabreTools.Serialization/Models/Logiqx/Sample.cs index 5878b9c1..941ee541 100644 --- a/SabreTools.Serialization/Models/Logiqx/Sample.cs +++ b/SabreTools.Serialization/Models/Logiqx/Sample.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("sample")] public class Sample { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } } diff --git a/SabreTools.Serialization/Models/Logiqx/SoftwareList.cs b/SabreTools.Serialization/Models/Logiqx/SoftwareList.cs index 4085115d..f7cfba55 100644 --- a/SabreTools.Serialization/Models/Logiqx/SoftwareList.cs +++ b/SabreTools.Serialization/Models/Logiqx/SoftwareList.cs @@ -6,16 +6,16 @@ namespace SabreTools.Serialization.Models.Logiqx [XmlRoot("softwarelist")] public class SoftwareList { - [SabreTools.Models.Required] + [Required] [XmlAttribute("tag")] public string? Tag { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } /// (original|compatible) - [SabreTools.Models.Required] + [Required] [XmlAttribute("status")] public string? Status { get; set; } diff --git a/SabreTools.Serialization/Models/Metadata/Adjuster.cs b/SabreTools.Serialization/Models/Metadata/Adjuster.cs index adeea10a..806524a3 100644 --- a/SabreTools.Serialization/Models/Metadata/Adjuster.cs +++ b/SabreTools.Serialization/Models/Metadata/Adjuster.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/ConfSetting.cs b/SabreTools.Serialization/Models/Metadata/ConfSetting.cs index 267dd0dc..541f0e38 100644 --- a/SabreTools.Serialization/Models/Metadata/ConfSetting.cs +++ b/SabreTools.Serialization/Models/Metadata/ConfSetting.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/Configuration.cs b/SabreTools.Serialization/Models/Metadata/Configuration.cs index 0a355439..0efaf8fc 100644 --- a/SabreTools.Serialization/Models/Metadata/Configuration.cs +++ b/SabreTools.Serialization/Models/Metadata/Configuration.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/DataArea.cs b/SabreTools.Serialization/Models/Metadata/DataArea.cs index cc0305f5..52051250 100644 --- a/SabreTools.Serialization/Models/Metadata/DataArea.cs +++ b/SabreTools.Serialization/Models/Metadata/DataArea.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/Device.cs b/SabreTools.Serialization/Models/Metadata/Device.cs index 2ee0f16c..c7b2ee31 100644 --- a/SabreTools.Serialization/Models/Metadata/Device.cs +++ b/SabreTools.Serialization/Models/Metadata/Device.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/DipSwitch.cs b/SabreTools.Serialization/Models/Metadata/DipSwitch.cs index eb890954..fbb593f2 100644 --- a/SabreTools.Serialization/Models/Metadata/DipSwitch.cs +++ b/SabreTools.Serialization/Models/Metadata/DipSwitch.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/DipValue.cs b/SabreTools.Serialization/Models/Metadata/DipValue.cs index 19c6a2d9..2567dec8 100644 --- a/SabreTools.Serialization/Models/Metadata/DipValue.cs +++ b/SabreTools.Serialization/Models/Metadata/DipValue.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/DiskArea.cs b/SabreTools.Serialization/Models/Metadata/DiskArea.cs index 592b4fab..bce5c54f 100644 --- a/SabreTools.Serialization/Models/Metadata/DiskArea.cs +++ b/SabreTools.Serialization/Models/Metadata/DiskArea.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/Dump.cs b/SabreTools.Serialization/Models/Metadata/Dump.cs index dbdcf3bc..51849800 100644 --- a/SabreTools.Serialization/Models/Metadata/Dump.cs +++ b/SabreTools.Serialization/Models/Metadata/Dump.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/Header.cs b/SabreTools.Serialization/Models/Metadata/Header.cs index cee4d22d..b5e89181 100644 --- a/SabreTools.Serialization/Models/Metadata/Header.cs +++ b/SabreTools.Serialization/Models/Metadata/Header.cs @@ -1,5 +1,3 @@ -using SabreTools.Models; - namespace SabreTools.Serialization.Models.Metadata { /// diff --git a/SabreTools.Serialization/Models/Metadata/Machine.cs b/SabreTools.Serialization/Models/Metadata/Machine.cs index 3c52a392..5badab42 100644 --- a/SabreTools.Serialization/Models/Metadata/Machine.cs +++ b/SabreTools.Serialization/Models/Metadata/Machine.cs @@ -1,5 +1,3 @@ -using SabreTools.Models; - namespace SabreTools.Serialization.Models.Metadata { /// diff --git a/SabreTools.Serialization/Models/Metadata/MetadataFile.cs b/SabreTools.Serialization/Models/Metadata/MetadataFile.cs index 44d2575f..b7607753 100644 --- a/SabreTools.Serialization/Models/Metadata/MetadataFile.cs +++ b/SabreTools.Serialization/Models/Metadata/MetadataFile.cs @@ -1,5 +1,3 @@ -using SabreTools.Models; - namespace SabreTools.Serialization.Models.Metadata { /// diff --git a/SabreTools.Serialization/Models/Metadata/Part.cs b/SabreTools.Serialization/Models/Metadata/Part.cs index c9531905..14b58ab9 100644 --- a/SabreTools.Serialization/Models/Metadata/Part.cs +++ b/SabreTools.Serialization/Models/Metadata/Part.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/Port.cs b/SabreTools.Serialization/Models/Metadata/Port.cs index 0c2a8050..2b2f3955 100644 --- a/SabreTools.Serialization/Models/Metadata/Port.cs +++ b/SabreTools.Serialization/Models/Metadata/Port.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/Slot.cs b/SabreTools.Serialization/Models/Metadata/Slot.cs index 51f0e911..d780b9b3 100644 --- a/SabreTools.Serialization/Models/Metadata/Slot.cs +++ b/SabreTools.Serialization/Models/Metadata/Slot.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/Software.cs b/SabreTools.Serialization/Models/Metadata/Software.cs index 72e4a241..b9e9480b 100644 --- a/SabreTools.Serialization/Models/Metadata/Software.cs +++ b/SabreTools.Serialization/Models/Metadata/Software.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/Metadata/SoftwareList.cs b/SabreTools.Serialization/Models/Metadata/SoftwareList.cs index f251afb3..109bfb29 100644 --- a/SabreTools.Serialization/Models/Metadata/SoftwareList.cs +++ b/SabreTools.Serialization/Models/Metadata/SoftwareList.cs @@ -1,6 +1,5 @@ using System.Xml.Serialization; using Newtonsoft.Json; -using SabreTools.Models; namespace SabreTools.Serialization.Models.Metadata { diff --git a/SabreTools.Serialization/Models/OpenMSX/Software.cs b/SabreTools.Serialization/Models/OpenMSX/Software.cs index 2d808eab..7bee7ffb 100644 --- a/SabreTools.Serialization/Models/OpenMSX/Software.cs +++ b/SabreTools.Serialization/Models/OpenMSX/Software.cs @@ -6,26 +6,26 @@ namespace SabreTools.Serialization.Models.OpenMSX [XmlRoot("software")] public class Software { - [SabreTools.Models.Required] + [Required] [XmlElement("title")] public string? Title { get; set; } [XmlElement("genmsxid")] public string? GenMSXID { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("system")] public string? System { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("company")] public string? Company { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("year")] public string? Year { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("country")] public string? Country { get; set; } diff --git a/SabreTools.Serialization/Models/PIC/Constants.cs b/SabreTools.Serialization/Models/PIC/Constants.cs new file mode 100644 index 00000000..a0374b5a --- /dev/null +++ b/SabreTools.Serialization/Models/PIC/Constants.cs @@ -0,0 +1,17 @@ +namespace SabreTools.Serialization.Models.PIC +{ + /// + /// + public class Constants + { + public const string DiscTypeIdentifierROM = "BDO"; + + public const string DiscTypeIdentifierROMUltra = "BDU"; + + public const string DiscTypeIdentifierReWritable = "BDW"; + + public const string DiscTypeIdentifierRecordable = "BDR"; + + public const string DiscTypeIdentifierXGD4 = "XG4"; + } +} diff --git a/SabreTools.Serialization/Models/PIC/DiscInformation.cs b/SabreTools.Serialization/Models/PIC/DiscInformation.cs new file mode 100644 index 00000000..7fceda32 --- /dev/null +++ b/SabreTools.Serialization/Models/PIC/DiscInformation.cs @@ -0,0 +1,34 @@ +namespace SabreTools.Serialization.Models.PIC +{ + /// + /// Disc Information and Emergency Brake data shall be read from the PIC zone. DI units that + /// contain physical information shall be returned.Emergency Brake data shall be returned.The + /// information shall be collected from the layer specified in the Layer field of the CDB. If any data + /// can be returned, 4 100 bytes shall be returned. + /// + /// + /// + public class DiscInformation + { + /// + /// 2048 bytes for BD-ROM, 3584 bytes for BD-R/RE + /// + /// Big-endian format + public ushort DataStructureLength { get; set; } + + /// + /// Should be 0x00 + /// + public byte Reserved0 { get; set; } + + /// + /// Should be 0x00 + /// + public byte Reserved1 { get; set; } + + /// + /// Disc information and emergency brake units + /// + public DiscInformationUnit[]? Units { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/PIC/DiscInformationUnit.cs b/SabreTools.Serialization/Models/PIC/DiscInformationUnit.cs new file mode 100644 index 00000000..8a2d0876 --- /dev/null +++ b/SabreTools.Serialization/Models/PIC/DiscInformationUnit.cs @@ -0,0 +1,22 @@ +namespace SabreTools.Serialization.Models.PIC +{ + /// + /// + public class DiscInformationUnit + { + /// + /// Unit header + /// + public DiscInformationUnitHeader? Header { get; set; } + + /// + /// Unit body + /// + public DiscInformationUnitBody? Body { get; set; } + + /// + /// Unit trailer (BD-R/RE only) + /// + public DiscInformationUnitTrailer? Trailer { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/PIC/DiscInformationUnitBody.cs b/SabreTools.Serialization/Models/PIC/DiscInformationUnitBody.cs new file mode 100644 index 00000000..5cae30b5 --- /dev/null +++ b/SabreTools.Serialization/Models/PIC/DiscInformationUnitBody.cs @@ -0,0 +1,24 @@ +namespace SabreTools.Serialization.Models.PIC +{ + /// + /// + /// TODO: Write models for the dependent contents, if possible + public class DiscInformationUnitBody + { + /// + /// Disc Type Identifier + /// + public string? DiscTypeIdentifier { get; set; } + + /// + /// Disc Size/Class/Version + /// + public byte DiscSizeClassVersion { get; set; } + + /// + /// DI Unit Format dependent contents + /// + /// 52 bytes for BD-ROM, 100 bytes for BD-R/RE + public byte[]? FormatDependentContents { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/PIC/DiscInformationUnitHeader.cs b/SabreTools.Serialization/Models/PIC/DiscInformationUnitHeader.cs new file mode 100644 index 00000000..4622d239 --- /dev/null +++ b/SabreTools.Serialization/Models/PIC/DiscInformationUnitHeader.cs @@ -0,0 +1,47 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.PIC +{ + /// + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public class DiscInformationUnitHeader + { + /// + /// Disc Information Identifier "DI" + /// Emergency Brake Identifier "EB" + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)] + public string? DiscInformationIdentifier; + + /// + /// Disc Information Format + /// + public byte DiscInformationFormat; + + /// + /// Number of DI units in each DI block + /// + public byte NumberOfUnitsInBlock; + + /// + /// Should be 0x00 + /// + public byte Reserved0; + + /// + /// DI unit Sequence Number + /// + public byte SequenceNumber; + + /// + /// Number of bytes in use in this DI unit + /// + public byte BytesInUse; + + /// + /// Should be 0x00 + /// + public byte Reserved1; + } +} diff --git a/SabreTools.Serialization/Models/PIC/DiscInformationUnitTrailer.cs b/SabreTools.Serialization/Models/PIC/DiscInformationUnitTrailer.cs new file mode 100644 index 00000000..7610084d --- /dev/null +++ b/SabreTools.Serialization/Models/PIC/DiscInformationUnitTrailer.cs @@ -0,0 +1,37 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.PIC +{ + /// + /// BD-R/RE only + /// + /// + /// + [StructLayout(LayoutKind.Sequential)] + public class DiscInformationUnitTrailer + { + /// + /// Disc Manufacturer ID + /// + /// 6 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[]? DiscManufacturerID; + + /// + /// Media Type ID + /// + /// 3 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[]? MediaTypeID; + + /// + /// Time Stamp + /// + public ushort TimeStamp; + + /// + /// Product Revision Number + /// + public byte ProductRevisionNumber; + } +} diff --git a/SabreTools.Serialization/Models/PlayStation3/Constants.cs b/SabreTools.Serialization/Models/PlayStation3/Constants.cs new file mode 100644 index 00000000..bfe4942d --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation3/Constants.cs @@ -0,0 +1,67 @@ +// TODO: Add more constants from the wiki +namespace SabreTools.Serialization.Models.PlayStation3 +{ + /// + public static class Constants + { + /// + /// Identifying bytes for SFO file + /// + public const uint SFOMagic = 0x00505346; + + /// + /// Identifying bytes for SFB file + /// + public const uint SFBMagic = 0x2E534642; + + #region Hybrid Flags + + /// + /// Not dependant of other disc files, enables a network connection to PSN store + /// + public const char FlagDiscBenefits = 'S'; + + /// + /// dev_bdvd/PS3_CONTENT/THEMEDIR/PARAM.SFO + /// + public const char FlagThemes = 'T'; + + /// + /// dev_bdvd/PS3_CONTENT/VIDEODIR/PARAM.SFO + /// + public const char FlagVideo = 'V'; + + /// + /// friends? (unknown yet, usually combined with g/p?) + /// + public const char FlagFriends = 'f'; + + /// + /// dev_bdvd/PS3_GAME/USRDIR/PARAM.SFO + /// dev_bdvd/PS3_EXTRA/PARAM.SFO + /// + public const char FlagGameExtras = 'g'; + + /// + /// music? + /// + public const char FlagMusic = 'm'; + + /// + /// photo? (unknown yet, used with v, fv,..) + /// + public const char FlagPhoto = 'p'; + + /// + /// dev_bdvd/PS3_UPDATE/PS3UPDAT.PUP + /// + public const char FlagFirmwareUpdate = 'u'; + + /// + /// dev_bdvd/PS3_VPRM/PARAM.SFO + /// + public const char FlagMovie = 'v'; + + #endregion + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/PlayStation3/Enums.cs b/SabreTools.Serialization/Models/PlayStation3/Enums.cs new file mode 100644 index 00000000..4cd1d574 --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation3/Enums.cs @@ -0,0 +1,31 @@ +// TODO: Add more enumerations from the wiki +namespace SabreTools.Serialization.Models.PlayStation3 +{ + /// + public enum DataFormat : ushort + { + /// + /// UTF-8 Special Mode, NOT NULL terminated + /// + /// + /// Used in SFO's generated by the system and/or linked to an user (Game Saves and Trophies). + /// + UTF8SpecialMode = 0x0004, + + /// + /// UTF-8 character string, NULL terminated (0x00) + /// + /// + /// Can be used any character from the system fonts. The NULL byte is counted as part of the used bytes in len + /// + UTF8 = 0x0204, + + /// + /// Integer 32 bits unsigned + /// + /// + /// Always has a length of 4 bytes in len and max_len (even in the case some bytes are not used, all them are marked as used) + /// + Integer = 0x0404, + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/PlayStation3/SFB.cs b/SabreTools.Serialization/Models/PlayStation3/SFB.cs new file mode 100644 index 00000000..00da177d --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation3/SFB.cs @@ -0,0 +1,109 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.PlayStation3 +{ + /// + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public class SFB + { + /// + /// ".SFB" + /// + public uint Magic; + + /// + /// File version(?) + /// + public uint FileVersion; + + /// + /// Unknown (zeroes) + /// + /// 0x18 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x18)] + public byte[]? Reserved1; + + /// + /// "HYBRID_FLAG" (Flags type) + /// + /// 0x10 bytes + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x10)] + public string? FlagsType; + + /// + /// Disc Content Data Offset + /// + public uint DiscContentDataOffset; + + /// + /// Disc Content Data Length + /// + public uint DiscContentDataLength; + + /// + /// Unknown (zeroes) + /// + /// 0x08 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x08)] + public byte[]? Reserved2; + + /// + /// "TITLE_ID" (Disc Title Name) + /// + /// 0x08 bytes + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x08)] + public string? DiscTitleName; + + /// + /// Unknown (zeroes) + /// + /// 0x08 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x08)] + public byte[]? Reserved3; + + /// + /// Disc Version Data Offset + /// + public uint DiscVersionDataOffset; + + /// + /// Disc Version Data Length + /// + public uint DiscVersionDataLength; + + /// + /// Unknown (zeroes) + /// + /// 0x188 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x188)] + public byte[]? Reserved4; + + /// + /// Disc Content (Hybrid Flags) + /// + /// 0x20 bytes + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)] + public string? DiscContent; + + /// + /// Disc Title + /// + /// 0x10 bytes + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x10)] + public string? DiscTitle; + + /// + /// Disc Version + /// + /// 0x10 bytes + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x10)] + public string? DiscVersion; + + /// + /// Unknown (zeroes) + /// + /// 0x3C0 bytes + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x3C0)] + public byte[]? Reserved5; + } +} diff --git a/SabreTools.Serialization/Models/PlayStation3/SFO.cs b/SabreTools.Serialization/Models/PlayStation3/SFO.cs new file mode 100644 index 00000000..4bd6a37e --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation3/SFO.cs @@ -0,0 +1,55 @@ +namespace SabreTools.Serialization.Models.PlayStation3 +{ + /// + public class SFO + { + /// + /// SFO header + /// + public SFOHeader? Header { get; set; } + + /// + /// Index table + /// + public SFOIndexTableEntry[]? IndexTable { get; set; } + + /// + /// Key table + /// + /// + /// Composed by a number of key entries defined with tables_entries in + /// the header, are short utf8 strings in capitals, NULL terminated + /// (0x00), and ordered alphabetically (from A to Z). This alphabetically + /// order defines the order of the associated entries in the other + /// two tables (index_table, and data_table) + /// + /// The end offset of this table needs to be aligned to a multiply of + /// 32bits (4 bytes), this is made with a padding at the end of key_table + /// when needed (in a few SFO's the table is aligned naturally as a + /// coincidence caused by the length of the key names used, when this + /// happens there is no padding needed) + /// + public string[]? KeyTable { get; set; } + + /// + /// Padding + /// + /// Enough bytes to align to 4 bytes + public byte[]? Padding { get; set; } + + /// + /// Data table + /// + /// + /// Composed by a number of data entries defined with tables_entries in + /// the header, every entry in this table is defined by the associated entry + /// in the index_table by using: fmt, len, max_len, and offset. There is + /// no padding between entries neither at the end of this table + /// + /// Some data entries can be filled with zeroes (not used, but availables for + /// being used). This entries can be considered reserved, and are marked with + /// a len = 0 in the associated entry in the index_table + /// + public byte[][]? DataTable { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/PlayStation3/SFOHeader.cs b/SabreTools.Serialization/Models/PlayStation3/SFOHeader.cs new file mode 100644 index 00000000..9174dab3 --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation3/SFOHeader.cs @@ -0,0 +1,34 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.PlayStation3 +{ + /// + [StructLayout(LayoutKind.Sequential)] + public class SFOHeader + { + /// + /// "\0PSF" + /// + public uint Magic; + + /// + /// Version + /// + public uint Version; + + /// + /// Absolute start offset of key_table + /// + public uint KeyTableStart; + + /// + /// Absolute start offset of data_table + /// + public uint DataTableStart; + + /// + /// Number of entries in index_table, key_table, and data_table + /// + public uint TablesEntries; + } +} diff --git a/SabreTools.Serialization/Models/PlayStation3/SFOIndexTableEntry.cs b/SabreTools.Serialization/Models/PlayStation3/SFOIndexTableEntry.cs new file mode 100644 index 00000000..27c17574 --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation3/SFOIndexTableEntry.cs @@ -0,0 +1,37 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.PlayStation3 +{ + /// + [StructLayout(LayoutKind.Sequential)] + public class SFOIndexTableEntry + { + /// + /// Key relative offset. + /// (Absolute start offset of key) - (Absolute start offset of key_table) + /// + public ushort KeyOffset; + + /// + /// Data type + /// + [MarshalAs(UnmanagedType.U2)] + public DataFormat DataFormat; + + /// + /// Data used length + /// + public uint DataLength; + + /// + /// Data total length. TITLE_ID is always = 16 bytes + /// + public uint DataMaxLength; + + /// + /// Data relative offset. + /// (Absolute start offset of data_1) - (Absolute start offset of data_table) + /// + public uint DataOffset; + } +} diff --git a/SabreTools.Serialization/Models/PlayStation4/AppPkgHeader.cs b/SabreTools.Serialization/Models/PlayStation4/AppPkgHeader.cs new file mode 100644 index 00000000..0b945fe3 --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation4/AppPkgHeader.cs @@ -0,0 +1,237 @@ +using System.Runtime.InteropServices; + +namespace SabreTools.Serialization.Models.PlayStation4 +{ + /// + /// All numeric values are big-endian + [StructLayout(LayoutKind.Sequential)] + public class AppPkgHeader + { + /// + /// Identifying bytes for app.pkg file, "\7FCNT" + /// + public uint Magic; + + /// + /// PKG Type + /// + public uint Type; + + /// + /// PKG Unknown Field + /// + public uint PKGUnknown; + + /// + /// PKG File count + /// + public uint FileCount; + + /// + /// PKG Entry count + /// + public uint EntryCount; + + /// + /// SC Entry count + /// + public ushort SCEntryCount; + + /// + /// PKG Entry count (duplicated) + /// + public ushort EntryCount2; + + /// + /// PKG File Table offset + /// + public uint TableOffset; + + /// + /// PKG Entry data size + /// + public uint EntryDataSize; + + /// + /// Offset of PKG Entries + /// + public ulong BodyOffset; + + /// + /// Length of all PKG Entries + /// + public ulong BodySize; + + /// + /// PKG Content offset + /// + public ulong ContentOffset; + + /// + /// PKG Content size + /// + public ulong ContentSize; + + /// + /// PKG Content ID + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x24)] + public string? ContentID; + + /// + /// PKG Content Padding (Zeroes) + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xC)] + public byte[]? ContentZeroes; + + /// + /// PKG DRM Type + /// + public uint DRMType; + + /// + /// PKG Content Type + /// + public uint ContentType; + + /// + /// PKG Content Flags + /// + public uint ContentFlags; + + /// + /// PKG Promote Size + /// + public uint PromoteSize; + + /// + /// PKG Version Date + /// + public uint VersionDate; + + /// + /// PKG Content Flags + /// + public uint VersionHash; + + /// + /// PKG Padding Section 1 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x78)] + public byte[]? Zeroes1; + + /// + /// PKG SHA256 for Main Entry 1 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public byte[]? MainEntry1SHA256; + + /// + /// PKG SHA256 for Main Entry 2 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public byte[]? MainEntry2SHA256; + + /// + /// PKG SHA256 for Digest Table + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public byte[]? DigestTableSHA256; + + /// + /// PKG SHA256 for Main Table + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public byte[]? MainTableSHA256; + + /// + /// PKG Padding Section 2 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x280)] + public byte[]? Zeroes2; + + /// + /// PFS Unknown Field + /// + public uint PFSUnknown; + + /// + /// PFS Image Count + /// + public uint PFSImageCount; + + /// + /// PFS Image Flags + /// + public ulong PFSImageFlags; + + /// + /// PFS Image Offset + /// + public ulong PFSImageOffset; + + /// + /// PFS Image Size + /// + public ulong PFSImageSize; + + /// + /// Mount Image Offset + /// + public ulong MountImageOffset; + + /// + /// Mount Image Size + /// + public ulong MountImageSize; + + /// + /// PKG Size + /// + public ulong PKGSize; + + /// + /// PKG Signed Size + /// + public uint PKGSignedSize; + + /// + /// PKG Signed Size + /// + public uint PKGCacheSize; + + /// + /// SHA256 for PFS Image + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public byte[]? PFSImageSHA256; + + /// + /// SHA256 for PFS Signed + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public byte[]? PFSSignedSHA256; + + /// + /// PFS Split Size nth 0 + /// + public ulong PFSSplitSize0; + + /// + /// PFS Split Size nth 1 + /// + public ulong PFSSplitSize1; + + /// + /// PKG Padding Section 3 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0xB50)] + public byte[]? Zeroes3; + + /// + /// SHA256 for PKG + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] + public byte[]? PKGSHA256; + } +} diff --git a/SabreTools.Serialization/Models/PlayStation4/Constants.cs b/SabreTools.Serialization/Models/PlayStation4/Constants.cs new file mode 100644 index 00000000..25bca9db --- /dev/null +++ b/SabreTools.Serialization/Models/PlayStation4/Constants.cs @@ -0,0 +1,11 @@ +namespace SabreTools.Serialization.Models.PlayStation4 +{ + /// + public class Constants + { + /// + /// Identifying bytes for app.pkg file, "\7FCNT" + /// + public const uint AppPkgMagic = 0x7F434E54; + } +} diff --git a/SabreTools.Serialization/Models/SeparatedValue/MetadataFile.cs b/SabreTools.Serialization/Models/SeparatedValue/MetadataFile.cs index 6d7177a9..08cd76fa 100644 --- a/SabreTools.Serialization/Models/SeparatedValue/MetadataFile.cs +++ b/SabreTools.Serialization/Models/SeparatedValue/MetadataFile.cs @@ -2,7 +2,7 @@ namespace SabreTools.Serialization.Models.SeparatedValue { public class MetadataFile { - [SabreTools.Models.Required] + [Required] public string[]? Header { get; set; } public Row[]? Row { get; set; } diff --git a/SabreTools.Serialization/Models/SeparatedValue/Row.cs b/SabreTools.Serialization/Models/SeparatedValue/Row.cs index 2cffabbc..6a97ae97 100644 --- a/SabreTools.Serialization/Models/SeparatedValue/Row.cs +++ b/SabreTools.Serialization/Models/SeparatedValue/Row.cs @@ -15,14 +15,14 @@ namespace SabreTools.Serialization.Models.SeparatedValue public string? Description { get; set; } /// Game Name - [SabreTools.Models.Required] + [Required] public string? GameName { get; set; } /// Game Description public string? GameDescription { get; set; } /// Type - [SabreTools.Models.Required] + [Required] public string? Type { get; set; } /// Rom Name diff --git a/SabreTools.Serialization/Models/SoftwareList/DataArea.cs b/SabreTools.Serialization/Models/SoftwareList/DataArea.cs index b5b35e0d..6c98b177 100644 --- a/SabreTools.Serialization/Models/SoftwareList/DataArea.cs +++ b/SabreTools.Serialization/Models/SoftwareList/DataArea.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("dataarea")] public class DataArea { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("size")] public string? Size { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/DipSwitch.cs b/SabreTools.Serialization/Models/SoftwareList/DipSwitch.cs index 273523c8..1f031fef 100644 --- a/SabreTools.Serialization/Models/SoftwareList/DipSwitch.cs +++ b/SabreTools.Serialization/Models/SoftwareList/DipSwitch.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("dipswitch")] public class DipSwitch { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("tag")] public string? Tag { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/DipValue.cs b/SabreTools.Serialization/Models/SoftwareList/DipValue.cs index 2ce14172..fe4abc79 100644 --- a/SabreTools.Serialization/Models/SoftwareList/DipValue.cs +++ b/SabreTools.Serialization/Models/SoftwareList/DipValue.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("dipvalue")] public class DipValue { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("value")] public string? Value { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/Disk.cs b/SabreTools.Serialization/Models/SoftwareList/Disk.cs index c9325824..576625d6 100644 --- a/SabreTools.Serialization/Models/SoftwareList/Disk.cs +++ b/SabreTools.Serialization/Models/SoftwareList/Disk.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("disk")] public class Disk { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/DiskArea.cs b/SabreTools.Serialization/Models/SoftwareList/DiskArea.cs index beaa803c..656f778d 100644 --- a/SabreTools.Serialization/Models/SoftwareList/DiskArea.cs +++ b/SabreTools.Serialization/Models/SoftwareList/DiskArea.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("diskarea")] public class DiskArea { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/Feature.cs b/SabreTools.Serialization/Models/SoftwareList/Feature.cs index 4e3469d2..3ec6b2ea 100644 --- a/SabreTools.Serialization/Models/SoftwareList/Feature.cs +++ b/SabreTools.Serialization/Models/SoftwareList/Feature.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("feature")] public class Feature { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/Info.cs b/SabreTools.Serialization/Models/SoftwareList/Info.cs index 0653def4..b60b31ce 100644 --- a/SabreTools.Serialization/Models/SoftwareList/Info.cs +++ b/SabreTools.Serialization/Models/SoftwareList/Info.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("info")] public class Info { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/Part.cs b/SabreTools.Serialization/Models/SoftwareList/Part.cs index e35fde4c..18d9814b 100644 --- a/SabreTools.Serialization/Models/SoftwareList/Part.cs +++ b/SabreTools.Serialization/Models/SoftwareList/Part.cs @@ -6,11 +6,11 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("part")] public class Part { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } - [SabreTools.Models.Required] + [Required] [XmlAttribute("interface")] public string? Interface { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/Rom.cs b/SabreTools.Serialization/Models/SoftwareList/Rom.cs index af4dd352..3a2535f1 100644 --- a/SabreTools.Serialization/Models/SoftwareList/Rom.cs +++ b/SabreTools.Serialization/Models/SoftwareList/Rom.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("rom")] public class Rom { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/SharedFeat.cs b/SabreTools.Serialization/Models/SoftwareList/SharedFeat.cs index 04cbc41d..f9fab41c 100644 --- a/SabreTools.Serialization/Models/SoftwareList/SharedFeat.cs +++ b/SabreTools.Serialization/Models/SoftwareList/SharedFeat.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("sharedfeat")] public class SharedFeat { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/Software.cs b/SabreTools.Serialization/Models/SoftwareList/Software.cs index 2ae373d0..f280bc1c 100644 --- a/SabreTools.Serialization/Models/SoftwareList/Software.cs +++ b/SabreTools.Serialization/Models/SoftwareList/Software.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("software")] public class Software { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } @@ -17,15 +17,15 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlAttribute("supported")] public string? Supported { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("description")] public string? Description { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("year")] public string? Year { get; set; } - [SabreTools.Models.Required] + [Required] [XmlElement("publisher")] public string? Publisher { get; set; } diff --git a/SabreTools.Serialization/Models/SoftwareList/SoftwareList.cs b/SabreTools.Serialization/Models/SoftwareList/SoftwareList.cs index 985f3de2..ea25bd87 100644 --- a/SabreTools.Serialization/Models/SoftwareList/SoftwareList.cs +++ b/SabreTools.Serialization/Models/SoftwareList/SoftwareList.cs @@ -6,7 +6,7 @@ namespace SabreTools.Serialization.Models.SoftwareList [XmlRoot("softwarelist")] public class SoftwareList { - [SabreTools.Models.Required] + [Required] [XmlAttribute("name")] public string? Name { get; set; } diff --git a/SabreTools.Serialization/Models/Xbox/Attribute.cs b/SabreTools.Serialization/Models/Xbox/Attribute.cs new file mode 100644 index 00000000..3ca3a696 --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/Attribute.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json; + +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// Extra attributes relating to package, in catalog.js + /// + public class Attribute + { + /// + /// "supports4k": + /// True if package supports 4K, false otherwise + /// + [JsonProperty("supports4k", NullValueHandling = NullValueHandling.Ignore)] + public bool? Supports4K { get; set; } + + /// + /// "supportsHdr": + /// True if package supports HDR, false otherwise + /// + [JsonProperty("supportsHdr", NullValueHandling = NullValueHandling.Ignore)] + public bool? SupportsHDR { get; set; } + + /// + /// "isXboxOneXEnhanced": + /// True if package is XboxOne X enhanced, false otherwise + /// + [JsonProperty("isXboxOneXEnhanced", NullValueHandling = NullValueHandling.Ignore)] + public bool? IsXboxOneXEnhanced { get; set; } + + } +} diff --git a/SabreTools.Serialization/Models/Xbox/Catalog.cs b/SabreTools.Serialization/Models/Xbox/Catalog.cs new file mode 100644 index 00000000..752aa92d --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/Catalog.cs @@ -0,0 +1,173 @@ +using Newtonsoft.Json; + +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// Contains metadata information about XboxOne and XboxSX discs + /// Stored in a JSON file on the disc at /MSXC/Metadata/catalog.js + /// + [JsonObject] + public class Catalog + { + /// + /// "version": + /// Version of this catalog.js file + /// Known values: 1.0, 2.0, 2.1, 4.0, 4.1 (4.1 not confirmed on a disc) + /// + [JsonProperty("version")] + public string? Version { get; set; } + + /// + /// "discNumber": + /// Varies for each disc in set + /// 0 is reserved and shouldnt be used + /// Known Versions Present: 4.0 + /// + [JsonProperty("discNumber", NullValueHandling = NullValueHandling.Ignore)] + public int? DiscNumber { get; set; } + + /// + /// "discCount": + /// Total number of discs in set + /// Same value for each disc in the set + /// Known Versions Present: 4.0 + /// + [JsonProperty("discCount", NullValueHandling = NullValueHandling.Ignore)] + public int? DiscCount { get; set; } + + /// + /// "discSetId": + /// 8 hex character ID for the set itself + /// Same value for each disc in the set + /// Known Versions Present: 4.0 + /// + [JsonProperty("discSetId", NullValueHandling = NullValueHandling.Ignore)] + public string? DiscSetID { get; set; } + + /// + /// "bundle": + /// Package details for the bundle itself + /// Known fields used: ProductID, XboxProductID, + /// OneStoreProductID, Titles, VUI, Images + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("bundle", NullValueHandling = NullValueHandling.Ignore)] + public Package? Bundle { get; set; } + + /// + /// "launchPackage": + /// Package name to use as launch package + /// Before 4.0, object=Package with only ContentID filled + /// For 4.0 onwards, object=String, representing filename + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("launchPackage", NullValueHandling = NullValueHandling.Ignore)] + public object? LaunchPackage { get; set; } + + /// + /// "packages": + /// Package details for each package on disc + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("packages")] + public Package[]? Packages { get; set; } + + /// + /// "siblings": + /// List of Package Names that are related to this disc + /// The console picks the correct one to use + /// Known Versions Present: 4.0 + /// + [JsonProperty("siblings", NullValueHandling = NullValueHandling.Ignore)] + public string[][]? Siblings { get; set; } + + #region v1.0 only + + // The below fields are usually present in a Package sub-field + // but for v1.0 catalog.js files, they are at the root Catalog object + + /// + /// "productId": + /// Hex identifier for package Product ID + /// Known Versions Present: 1.0 + /// Exists within Packages[].ProductID for v2.0 onwards + /// + [JsonProperty("productId", NullValueHandling = NullValueHandling.Ignore)] + public string? ProductID { get; set; } + + /// + /// "contentId": + /// Hex content identifier + /// Known Versions present: 1.0 + /// Exists within Packages[].ContentID for v2.0 onwards + /// + [JsonProperty("contentId", NullValueHandling = NullValueHandling.Ignore)] + public string? ContentID { get; set; } + + /// + /// "titleId": + /// 8 hex character package Title ID + /// Known Versions Present: 1.0 + /// Exists within Packages[].TitleID for v2.0 onwards + /// + [JsonProperty("titleId", NullValueHandling = NullValueHandling.Ignore)] + public string? TitleID { get; set; } + + /// + /// "titles" + /// List of name of package for each locale + /// Known Versions Present: 1.0 + /// Exists within Packages[].Titles for v2.0 onwards + /// + [JsonProperty("titles", NullValueHandling = NullValueHandling.Ignore)] + public Title[]? Titles { get; set; } + + /// + /// "vui": + /// List of Voice User Interface packages titles for each locale + /// Known Versions Present: 1.0 + /// Exists within Packages[].VUI for v2.0 onwards + /// + [JsonProperty("vui", NullValueHandling = NullValueHandling.Ignore)] + public Title[]? VUI { get; set; } + + /// + /// "images": + /// List of paths to each image in MSXC/Metadata// + /// Known Versions Present: 1.0 + /// Exists within Packages[].Images for v2.0 onwards + /// + [JsonProperty("images", NullValueHandling = NullValueHandling.Ignore)] + public Image[]? Images { get; set; } + + /// + /// "ratings": + /// List of package age ratings for each relevant rating system + /// Known Versions Present: 1.0 + /// Exists within Packages[].Ratings for v2.0 onwards + /// + [JsonProperty("ratings", NullValueHandling = NullValueHandling.Ignore)] + public Rating[]? Ratings { get; set; } + + /// + /// "size": + /// Size of package in bytes + /// Known Versions Present: 1.0 + /// Exists within Packages[].Size for v2.0 onwards + /// + [JsonProperty("size", NullValueHandling = NullValueHandling.Ignore)] + public long? Size { get; set; } + + /// + /// "type": + /// Package Type + /// Known values: "Game" (Game package), "Durable" (DLC package) + /// Known Versions Present: 1.0 + /// Exists within Packages[].Type for v2.0 onwards + /// + [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] + public string? Type { get; set; } + + #endregion + } +} diff --git a/SabreTools.Serialization/Models/Xbox/Constants.cs b/SabreTools.Serialization/Models/Xbox/Constants.cs new file mode 100644 index 00000000..950c9115 --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/Constants.cs @@ -0,0 +1,201 @@ +using System.Collections.Generic; + +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// + /// + public static class Constants + { + /// + /// Mapping of all Xbox 360 media subtypes to long names + /// + public static readonly Dictionary MediaSubtypes = new() + { + { 'F', "XGD3" }, + { 'X', "XGD2" }, + { 'Z', "Games on Demand / Marketplace Demo" }, + }; + + /// + /// Mapping of all publisher 2-letter codes to long names + /// + public static readonly Dictionary Publishers = new() + { + { "AB", "Ambush Reality" }, + { "AC", "Acclaim Entertainment" }, + { "AD", "Andamiro USA Corp." }, + { "AH", "Arush Entertainment" }, + { "AK", "Artdink" }, + { "AP", "Aquaplus" }, + { "AQ", "Aqua System" }, + { "AS", "ASK" }, + { "AT", "Atlus" }, + { "AV", "Activision" }, + { "AW", "Arc System Works" }, + { "AX", "Aksys Games" }, + { "AY", "Aspyr Media" }, + + { "BA", "Bandai" }, + { "BB", "BigBen" }, + { "BD", "Bravado" }, + { "BE", "Blueside Inc." }, + { "BF", "Blind Ferret Entertainment" }, + { "BG", "BradyGames" }, + { "BH", "Blackhole" }, + { "BL", "Black Box" }, + { "BM", "BAM! Entertainment" }, + { "BR", "Broccoli Co." }, + { "BS", "Bethesda Softworks" }, + { "BT", "Brash Entertainment" }, + { "BU", "Bunkasha Co." }, + { "BV", "Buena Vista Games" }, + { "BW", "BBC Multimedia" }, + { "BZ", "Blizzard" }, + + { "CC", "Capcom" }, + { "CK", "Kemco Corporation" }, // TODO: Confirm + { "CM", "Codemasters" }, + { "CT", "CTO" }, + { "CV", "Crave Entertainment" }, + + { "DC", "DreamCatcher Interactive" }, + { "DE", "Destineer" }, + { "DX", "Davilex" }, + + { "EA", "Electronic Arts" }, + { "EC", "Encore Software" }, + { "EF", "E-Frontier" }, + { "EL", "Enlight Software" }, + { "EM", "Empire Interactive" }, + { "ES", "Eidos Interactive" }, + { "EV", "Evolved Games" }, + + { "FE", "Focus Entertainment (formerly Focus Home Interactive)" }, // TODO: Confirm + { "FI", "Fox Interactive" }, + { "FL", "Fluent Entertainment" }, + { "FO", "505 Games" }, + { "FS", "From Software" }, + + { "GE", "Genki Co." }, + { "GF", "Gameloft" }, + { "GV", "Groove Games" }, + + { "HE", "Tru Blu (Entertainment division of Home Entertainment Suppliers)" }, + { "HP", "Hip Games" }, + { "HU", "Hudson Soft" }, + { "HW", "Highwaystar" }, + + { "IA", "Mad Catz Interactive" }, // TODO: Confirm + { "IF", "Idea Factory" }, + { "IG", "Infogrames" }, + { "IL", "Interlex Corporation" }, + { "IM", "Imagine Media" }, + { "IO", "Ignition Entertainment" }, + { "IP", "Interplay Entertainment" }, + { "IX", "InXile Entertainment" }, + + { "JA", "Jaleco Entertainment" }, + { "JW", "JoWooD Entertainment" }, + + { "KA", "Konami Osaka / Major A" }, + { "KB", "Kemco" }, // TODO: Confirm + { "KI", "Kids Station Inc." }, // TODO: Confirm + { "KN", "Konami" }, + { "KO", "Koei" }, + { "KT", "Konami Tokyo" }, + { "KU", "Kobi and/or GAE (formerly Global A Entertainment)" }, // TODO: Confirm + { "KY", "Kalypso" }, + + { "LA", "LucasArts" }, + { "LS", "Black Bean Games (publishing arm of Leader S.p.A.)" }, // TODO: Confirm + + { "MD", "Metro3D" }, + { "ME", "Medix" }, + { "MI", "Microïds" }, // TODO: Confirm + { "MJ", "Majesco Entertainment" }, + { "MM", "Myelin Media" }, + { "MP", "MediaQuest" }, // TODO: Confirm + { "MS", "Microsoft Game Studios" }, + { "MW", "Midway Games" }, + { "MX", "Empire Interactive" }, // TODO: Confirm + + { "NK", "NewKidCo" }, + { "NL", "NovaLogic" }, + { "NM", "Namco" }, + + { "OG", "O-Games" }, + { "OX", "Oxygen Interactive" }, + + { "PC", "Playlogic Entertainment" }, + { "PL", "Phantagram Co., Ltd. / Playlogic Entertainment" }, // TODO: Confirm + + { "RA", "Rage" }, + + { "SA", "Sammy" }, + { "SC", "SCi Games" }, + { "SE", "Sega" }, + { "SN", "SNK" }, + { "SP", "Southpeak Games" }, + { "SQ", "Square Enix" }, + { "SS", "Simon & Schuster" }, + { "ST", "Studio Nine" }, + { "SU", "Success Corporation" }, + { "SW", "Swing! Deutschland" }, + + { "TA", "Takara" }, + { "TC", "Tecmo" }, + { "TD", "The 3DO Company" }, + { "TK", "Takuyo" }, + { "TM", "TDK Mediactive" }, + { "TQ", "THQ" }, + { "TS", "Titus Interactive" }, + { "TT", "Take-Two Interactive Software" }, + + { "US", "Ubisoft" }, + + { "VC", "Victor Interactive Software" }, + { "VG", "Valcon Games" }, + { "VN", "Vivendi Universal Games (Former Interplay)" }, // TODO: Confirm + { "VU", "Vivendi Universal Games" }, + { "VV", "Vicarious Visions" }, + + { "WE", "Wanadoo Edition" }, + { "WR", "Warner Bros. Interactive Entertainment" }, + + { "XA", "Xbox Live Arcade" }, + { "XI", "Xicat Interactive / XPEC Entertainment and Idea Factory" }, // TODO: Confirm + { "XK", "Xbox Kiosk" }, + { "XL", "Xbox Live" }, + { "XM", "Evolved Games" }, // TODO: Confirm + { "XP", "XPEC Entertainment" }, + { "XR", "Panorama" }, // TODO: Confirm + + { "YB", "YBM Sisa (South-Korea)" }, + + { "ZD", "Zushi Games (formerly Zoo Digital Publishing)" }, + + { "" + (char)0x00 + (char)0x01, "Microsoft Downloadable Content" }, + { "" + (char)0x05 + (char)0x04, "Zuma's Revenge" }, + { "" + (char)0xAA + (char)0xAA, "Arcania - Gothic 4" }, + { "" + (char)0xFF + (char)0xED, "Microsoft Downloadable Content" }, + { "" + (char)0xFF + (char)0xFD, "Microsoft Downloadable Content" }, + { "" + (char)0xFF + (char)0xFE, "Microsoft Downloadable Content" }, + { "" + (char)0xFF + (char)0xFF, "Microsoft Downloadable Content" }, + }; + + /// + /// Mapping of all region 1-letter codes to long names + /// + public static readonly Dictionary Regions = new() + { + { 'A', "USA" }, + { 'E', "Europe" }, + { 'H', "Japan / Europe" }, + { 'J', "Japan / Asia" }, + { 'K', "USA / Japan" }, + { 'L', "USA / Europe" }, + { 'W', "World" }, + }; + } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Models/Xbox/Image.cs b/SabreTools.Serialization/Models/Xbox/Image.cs new file mode 100644 index 00000000..42ceb5ce --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/Image.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; + +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// List of image files associated with a package in catalog.js + /// + public class Image + { + /// + /// "size": + /// String representing image size + /// Known values: "100x100", "208x208", "480x480" + /// + [JsonProperty("size", NullValueHandling = NullValueHandling.Ignore)] + public string? Size { get; set; } + + /// + /// "image": + /// File name of image within MSXC/Metadata// + /// + [JsonProperty("image", NullValueHandling = NullValueHandling.Ignore)] + public string? Name { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/Xbox/Package.cs b/SabreTools.Serialization/Models/Xbox/Package.cs new file mode 100644 index 00000000..1c504ae9 --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/Package.cs @@ -0,0 +1,162 @@ +using Newtonsoft.Json; + +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// Metadata about each package on disc, in catalog.js + /// Packages are stored within /MSXC/ + /// + public class Package + { + /// + /// "packageName": + /// Package name of variant + /// Matches MSXC/ and MSXC/Metdata/ + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("packageName", NullValueHandling = NullValueHandling.Ignore)] + public string? PackageName { get; set; } + + /// + /// "productId": + /// Hex identifier for package Product ID + /// Known Versions Present: 2.0, 2.1 + /// + [JsonProperty("productId", NullValueHandling = NullValueHandling.Ignore)] + public string? ProductID { get; set; } + + /// + /// "contentId": + /// Hex content identifier + /// Known Versions present: 2.0, 2.1 + /// + [JsonProperty("contentId", NullValueHandling = NullValueHandling.Ignore)] + public string? ContentID { get; set; } + + /// + /// "xboxProductId": + /// Hex product identifier + /// Known Versions Present: 4.0 + /// + [JsonProperty("xboxProductId", NullValueHandling = NullValueHandling.Ignore)] + public string? XboxProductID { get; set; } + + /// + /// "oneStoreProductId": + /// Partner Center Product ID + /// 12 character uppercase alphanumeric + /// Known Versions Present: 4.0 + /// + [JsonProperty("oneStoreProductId", NullValueHandling = NullValueHandling.Ignore)] + public string? OneStoreProductID { get; set; } + + /// + /// "allowedOneStoreProductIds": + /// List of OneStoreProductID that this package is associated with + /// Used for DLC packages only (Type = "Durable") + /// Known Versions Present: 4.0 + /// + [JsonProperty("allowedOneStoreProductIds", NullValueHandling = NullValueHandling.Ignore)] + public string[]? AllowedOneStoreProductIDs { get; set; } + + /// + /// "franchiseGameHubId": + /// Hex identifier + /// Optionally used to mark package as game hub + /// Known Versions Present: 4.1 + /// + [JsonProperty("franchiseGameHubId", NullValueHandling = NullValueHandling.Ignore)] + public string? FranchiseGameHubID { get; set; } + + /// + /// "associatedFranchiseGameHubId": + /// Hex identifier + /// Marks corresponding FranchiseGameHubID that this package is launched with + /// Known Versions Present: 4.1 + /// + [JsonProperty("associatedFranchiseGameHubId", NullValueHandling = NullValueHandling.Ignore)] + public string? AssociatedFranchiseGameHubID { get; set; } + + /// + /// "titleId": + /// 8 hex character package Title ID + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("titleId", NullValueHandling = NullValueHandling.Ignore)] + public string? TitleID { get; set; } + + /// + /// "titles" + /// List of name of package for each locale + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("titles", NullValueHandling = NullValueHandling.Ignore)] + public Title[]? Titles { get; set; } + + /// + /// "vui": + /// List of Voice User Interface packages titles for each locale + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("vui", NullValueHandling = NullValueHandling.Ignore)] + public Title[]? VUI { get; set; } + + /// + /// "images": + /// List of paths to each image in MSXC/Metadata// + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("images", NullValueHandling = NullValueHandling.Ignore)] + public Image[]? Images { get; set; } + + /// + /// "ratings": + /// List of package age ratings for each relevant rating system + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("ratings", NullValueHandling = NullValueHandling.Ignore)] + public Rating[]? Ratings { get; set; } + + /// + /// "attributes": + /// Extra attributes associated with this package + /// Known Versions Present: 2.1, 4.0 + /// + [JsonProperty("attributes", NullValueHandling = NullValueHandling.Ignore)] + public Attribute[]? Attributes { get; set; } + + /// + /// "variants": + /// Alternative packages + /// Known Versions Present: 4.0 + /// + [JsonProperty("variants", NullValueHandling = NullValueHandling.Ignore)] + public Package[]? Variants { get; set; } + + /// + /// "generation": + /// Console generation the package is for + /// Known values: "8" (XboxOne), "9" (Xbox Series X|S) + /// Known Versions Present: 4.0 + /// + [JsonProperty("generation", NullValueHandling = NullValueHandling.Ignore)] + public string? Generation { get; set; } + + /// + /// "size": + /// Size of package in bytes + /// Known Versions Present: 2.0, 2.1 + /// + [JsonProperty("size", NullValueHandling = NullValueHandling.Ignore)] + public long? Size { get; set; } + + /// + /// "type": + /// Package Type + /// Known values: "Game" (Game package), "Durable" (DLC package) + /// Known Versions Present: 2.0, 2.1, 4.0 + /// + [JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)] + public string? Type { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/Xbox/Rating.cs b/SabreTools.Serialization/Models/Xbox/Rating.cs new file mode 100644 index 00000000..da1277cb --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/Rating.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; + +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// Package rating for each rating system, in catalog.js + /// + public class Rating + { + /// + /// "system": + /// Name of rating system + /// Known values: COB-AU, PEGI, PCBP, USK, China, CERO, ESRB, GCAM, CSRR, + /// COB, DJCTQ, GRB, OFLC, OFLC-NZ, PEGIPortugal, FPB, Microsoft + /// + [JsonProperty("system", NullValueHandling = NullValueHandling.Ignore)] + public string? System { get; set; } + + /// + /// "value": + /// String representing rating value, depends on rating system + /// + [JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)] + public string? Value { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/Xbox/Title.cs b/SabreTools.Serialization/Models/Xbox/Title.cs new file mode 100644 index 00000000..66496feb --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/Title.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; + +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// Package Title for each locale, for catalog.js + /// + public class Title + { + /// + /// "locale": + /// String representing locale that this title is in + /// Known values: "default", "en", "de", "fr", "ar", "zh-hans", + /// "zh-hant", "zh-TW", "zh-HK", "zh-CN", "zh-SG", etc + /// + [JsonProperty("locale", NullValueHandling = NullValueHandling.Ignore)] + public string? Locale { get; set; } + + /// + /// "title": + /// Package title + /// + [JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)] + public string? Name { get; set; } + } +} diff --git a/SabreTools.Serialization/Models/Xbox/XMID.cs b/SabreTools.Serialization/Models/Xbox/XMID.cs new file mode 100644 index 00000000..9464e796 --- /dev/null +++ b/SabreTools.Serialization/Models/Xbox/XMID.cs @@ -0,0 +1,37 @@ +namespace SabreTools.Serialization.Models.Xbox +{ + /// + /// Contains information specific to an XGD disc + /// + /// + /// XGD1 XMID Format Information: + /// + /// AABBBCCD + /// - AA => The two-ASCII-character publisher identifier (see Constants.Publishers for details) + /// - BBB => Game ID + /// - CC => Version number + /// - D => Region identifier (see Constants.Regions for details) + /// + public class XMID + { + /// + /// 2-character publisher identifier + /// + public string? PublisherIdentifier { get; set; } + + /// + /// 3-character Game ID + /// + public string? GameID { get; set; } + + /// + /// 2-character Internal version number + /// + public string? VersionNumber { get; set; } + + /// + /// 1-character Region identifier character + /// + /// Contains information specific to an XGD disc + /// + /// + /// XGD2/3 XeMID Format Information: + /// + /// AABCCCDDEFFGHH(IIIIIIII) + /// - AA => The two-ASCII-character publisher identifier (see Constants.Publishers for details) + /// - B => Platform identifier; 2 indicates Xbox 360. + /// - CCC => Game ID + /// - DD => SKU number (unique per SKU of a title) + /// - E => Region identifier (see Constants.Regions for details) + /// - FF => Base version; usually starts at 01 (can be 1 or 2 characters) + /// - G => Media type identifier (see Constants.MediaSubtypes for details) + /// - HH => Disc number stored in [disc number][total discs] format + /// - IIIIIIII => 8-hex-digit certification submission identifier; usually on test discs only + /// + public class XeMID + { + /// + /// 2-character publisher identifier + /// + public string? PublisherIdentifier { get; set; } + + /// + /// 1-character Platform disc is made for, 2 indicates Xbox 360 + /// + public char PlatformIdentifier { get; set; } + + /// + /// 3-character Game ID + /// + public string? GameID { get; set; } + + /// + /// 2-character Title-specific SKU + /// + public string? SKU { get; set; } + + /// + /// 1-character Region identifier character + /// + public char RegionIdentifier { get; set; } + + /// + /// 2-character Base version of executables, usually starts at 01 + /// + public string? BaseVersion { get; set; } + + /// + /// 1-character Media subtype identifier + /// + public char MediaSubtypeIdentifier { get; set; } + + /// + /// 2-character Disc number stored in [disc number][total discs] format + /// + public string? DiscNumberIdentifier { get; set; } + + /// + /// 8-hex-digit certification submission identifier; usually on test discs only + /// + public string? CertificationSubmissionIdentifier { get; set; } + } +} diff --git a/SabreTools.Serialization/NoFilterAttribute.cs b/SabreTools.Serialization/NoFilterAttribute.cs new file mode 100644 index 00000000..cebb22ec --- /dev/null +++ b/SabreTools.Serialization/NoFilterAttribute.cs @@ -0,0 +1,8 @@ +namespace SabreTools.Serialization +{ + /// + /// Marks a key as unable to be filtered on + /// + [System.AttributeUsage(System.AttributeTargets.Field)] + public class NoFilterAttribute : System.Attribute { } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Printers/AACSMediaKeyBlock.cs b/SabreTools.Serialization/Printers/AACSMediaKeyBlock.cs index 0088353d..c0dc7cf1 100644 --- a/SabreTools.Serialization/Printers/AACSMediaKeyBlock.cs +++ b/SabreTools.Serialization/Printers/AACSMediaKeyBlock.cs @@ -1,6 +1,6 @@ using System.Text; -using SabreTools.Models.AACS; using SabreTools.Serialization.Interfaces; +using SabreTools.Serialization.Models.AACS; namespace SabreTools.Serialization.Printers { diff --git a/SabreTools.Serialization/Printers/BDPlusSVM.cs b/SabreTools.Serialization/Printers/BDPlusSVM.cs index 4aa1f0a2..55ef6805 100644 --- a/SabreTools.Serialization/Printers/BDPlusSVM.cs +++ b/SabreTools.Serialization/Printers/BDPlusSVM.cs @@ -1,6 +1,6 @@ using System.Text; -using SabreTools.Models.BDPlus; using SabreTools.Serialization.Interfaces; +using SabreTools.Serialization.Models.BDPlus; namespace SabreTools.Serialization.Printers { diff --git a/SabreTools.Serialization/Printers/IRD.cs b/SabreTools.Serialization/Printers/IRD.cs index ab058b43..4cba8920 100644 --- a/SabreTools.Serialization/Printers/IRD.cs +++ b/SabreTools.Serialization/Printers/IRD.cs @@ -1,6 +1,6 @@ using System.Text; -using SabreTools.Models.IRD; using SabreTools.Serialization.Interfaces; +using SabreTools.Serialization.Models.IRD; namespace SabreTools.Serialization.Printers { diff --git a/SabreTools.Serialization/Printers/PIC.cs b/SabreTools.Serialization/Printers/PIC.cs index 451d2895..6f15e4eb 100644 --- a/SabreTools.Serialization/Printers/PIC.cs +++ b/SabreTools.Serialization/Printers/PIC.cs @@ -1,6 +1,6 @@ using System.Text; -using SabreTools.Models.PIC; using SabreTools.Serialization.Interfaces; +using SabreTools.Serialization.Models.PIC; namespace SabreTools.Serialization.Printers { diff --git a/SabreTools.Serialization/Printers/XMID.cs b/SabreTools.Serialization/Printers/XMID.cs index b4ced806..72bf53db 100644 --- a/SabreTools.Serialization/Printers/XMID.cs +++ b/SabreTools.Serialization/Printers/XMID.cs @@ -1,16 +1,16 @@ using System.Text; using SabreTools.Serialization.Interfaces; -using static SabreTools.Models.Xbox.Constants; +using static SabreTools.Serialization.Models.Xbox.Constants; namespace SabreTools.Serialization.Printers { - public class XMID : IPrinter + public class XMID : IPrinter { /// - public void PrintInformation(StringBuilder builder, SabreTools.Models.Xbox.XMID model) + public void PrintInformation(StringBuilder builder, SabreTools.Serialization.Models.Xbox.XMID model) => Print(builder, model); - public static void Print(StringBuilder builder, SabreTools.Models.Xbox.XMID xmid) + public static void Print(StringBuilder builder, SabreTools.Serialization.Models.Xbox.XMID xmid) { builder.AppendLine("Xbox Media Identifier Information:"); builder.AppendLine("-------------------------"); diff --git a/SabreTools.Serialization/Printers/XeMID.cs b/SabreTools.Serialization/Printers/XeMID.cs index 236fff9a..2334a692 100644 --- a/SabreTools.Serialization/Printers/XeMID.cs +++ b/SabreTools.Serialization/Printers/XeMID.cs @@ -1,16 +1,16 @@ using System.Text; using SabreTools.Serialization.Interfaces; -using static SabreTools.Models.Xbox.Constants; +using static SabreTools.Serialization.Models.Xbox.Constants; namespace SabreTools.Serialization.Printers { - public class XeMID : IPrinter + public class XeMID : IPrinter { /// - public void PrintInformation(StringBuilder builder, SabreTools.Models.Xbox.XeMID model) + public void PrintInformation(StringBuilder builder, SabreTools.Serialization.Models.Xbox.XeMID model) => Print(builder, model); - public static void Print(StringBuilder builder, SabreTools.Models.Xbox.XeMID xemid) + public static void Print(StringBuilder builder, SabreTools.Serialization.Models.Xbox.XeMID xemid) { builder.AppendLine("Xbox Media Identifier Information:"); builder.AppendLine("-------------------------"); diff --git a/SabreTools.Serialization/RequiredAttribute.cs b/SabreTools.Serialization/RequiredAttribute.cs new file mode 100644 index 00000000..0b81e5f8 --- /dev/null +++ b/SabreTools.Serialization/RequiredAttribute.cs @@ -0,0 +1,9 @@ +namespace SabreTools.Serialization +{ + /// + /// Marks a property as required on write + /// + /// TODO: Use reflection to determine required fields on write + [System.AttributeUsage(System.AttributeTargets.Property)] + public class RequiredAttribute : System.Attribute { } +} \ No newline at end of file diff --git a/SabreTools.Serialization/Serializers/Catalog.cs b/SabreTools.Serialization/Serializers/Catalog.cs index 0c479c68..ed15655f 100644 --- a/SabreTools.Serialization/Serializers/Catalog.cs +++ b/SabreTools.Serialization/Serializers/Catalog.cs @@ -3,10 +3,10 @@ using System.Text; namespace SabreTools.Serialization.Serializers { - public class Catalog : JsonFile + public class Catalog : JsonFile { /// Catalog.js file is encoded as UTF-16 LE - public override Stream? SerializeStream(SabreTools.Models.Xbox.Catalog? obj) + public override Stream? SerializeStream(SabreTools.Serialization.Models.Xbox.Catalog? obj) => Serialize(obj, new UnicodeEncoding()); } } diff --git a/SabreTools.Serialization/Serializers/CueSheet.cs b/SabreTools.Serialization/Serializers/CueSheet.cs index d3ecd993..ef538ba8 100644 --- a/SabreTools.Serialization/Serializers/CueSheet.cs +++ b/SabreTools.Serialization/Serializers/CueSheet.cs @@ -1,14 +1,14 @@ using System; using System.IO; using System.Text; -using SabreTools.Models.CueSheets; +using SabreTools.Serialization.Models.CueSheets; namespace SabreTools.Serialization.Serializers { - public class CueSheet : BaseBinarySerializer + public class CueSheet : BaseBinarySerializer { /// - public override Stream? SerializeStream(SabreTools.Models.CueSheets.CueSheet? obj) + public override Stream? SerializeStream(SabreTools.Serialization.Models.CueSheets.CueSheet? obj) { // If the cuesheet is null if (obj == null) @@ -41,7 +41,7 @@ namespace SabreTools.Serialization.Serializers /// /// CueSheet to write /// StreamWriter to write to - private static void WriteCueSheet(SabreTools.Models.CueSheets.CueSheet cueSheet, StreamWriter sw) + private static void WriteCueSheet(SabreTools.Serialization.Models.CueSheets.CueSheet cueSheet, StreamWriter sw) { // If we don't have any files, it's invalid if (cueSheet.Files == null) diff --git a/SabreTools.Serialization/Serializers/IRD.cs b/SabreTools.Serialization/Serializers/IRD.cs index 6f98e270..c81af3fc 100644 --- a/SabreTools.Serialization/Serializers/IRD.cs +++ b/SabreTools.Serialization/Serializers/IRD.cs @@ -4,10 +4,10 @@ using System.Text; namespace SabreTools.Serialization.Serializers { - public class IRD : BaseBinarySerializer + public class IRD : BaseBinarySerializer { /// - public override Stream? SerializeStream(SabreTools.Models.IRD.File? obj) + public override Stream? SerializeStream(SabreTools.Serialization.Models.IRD.File? obj) { // If the data is invalid if (obj?.Magic == null) diff --git a/SabreTools.Serialization/Serializers/XMID.cs b/SabreTools.Serialization/Serializers/XMID.cs index c0c607c6..f6a98802 100644 --- a/SabreTools.Serialization/Serializers/XMID.cs +++ b/SabreTools.Serialization/Serializers/XMID.cs @@ -3,17 +3,17 @@ using SabreTools.Serialization.Interfaces; namespace SabreTools.Serialization.Serializers { - public partial class XMID : IStringSerializer + public partial class XMID : IStringSerializer { /// - public static string? SerializeString(SabreTools.Models.Xbox.XMID? obj) + public static string? SerializeString(SabreTools.Serialization.Models.Xbox.XMID? obj) { var deserializer = new XMID(); return deserializer.Serialize(obj); } /// - public string? Serialize(SabreTools.Models.Xbox.XMID? obj) + public string? Serialize(SabreTools.Serialization.Models.Xbox.XMID? obj) { if (obj == null) return null; diff --git a/SabreTools.Serialization/Serializers/XeMID.cs b/SabreTools.Serialization/Serializers/XeMID.cs index 09ae4bb1..1f6814d5 100644 --- a/SabreTools.Serialization/Serializers/XeMID.cs +++ b/SabreTools.Serialization/Serializers/XeMID.cs @@ -3,17 +3,17 @@ using SabreTools.Serialization.Interfaces; namespace SabreTools.Serialization.Serializers { - public partial class XeMID : IStringSerializer + public partial class XeMID : IStringSerializer { /// - public static string? SerializeString(SabreTools.Models.Xbox.XeMID? obj) + public static string? SerializeString(SabreTools.Serialization.Models.Xbox.XeMID? obj) { var deserializer = new XeMID(); return deserializer.Serialize(obj); } /// - public string? Serialize(SabreTools.Models.Xbox.XeMID? obj) + public string? Serialize(SabreTools.Serialization.Models.Xbox.XeMID? obj) { if (obj == null) return null; diff --git a/SabreTools.Serialization/WrapperFactory.cs b/SabreTools.Serialization/WrapperFactory.cs index 9d89370e..c4d71f27 100644 --- a/SabreTools.Serialization/WrapperFactory.cs +++ b/SabreTools.Serialization/WrapperFactory.cs @@ -159,7 +159,7 @@ namespace SabreTools.Serialization #region BDPlusSVM - if (magic.StartsWith(SabreTools.Models.BDPlus.Constants.SignatureBytes)) + if (magic.StartsWith(SabreTools.Serialization.Models.BDPlus.Constants.SignatureBytes)) return WrapperType.BDPlusSVM; if (extension.Equals("svm", StringComparison.OrdinalIgnoreCase)) diff --git a/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs b/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs index a6b9531d..4e6473f8 100644 --- a/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs +++ b/SabreTools.Serialization/Wrappers/AACSMediaKeyBlock.cs @@ -1,5 +1,5 @@ using System.IO; -using SabreTools.Models.AACS; +using SabreTools.Serialization.Models.AACS; namespace SabreTools.Serialization.Wrappers { diff --git a/SabreTools.Serialization/Wrappers/BDPlusSVM.cs b/SabreTools.Serialization/Wrappers/BDPlusSVM.cs index fd51ed98..806af61c 100644 --- a/SabreTools.Serialization/Wrappers/BDPlusSVM.cs +++ b/SabreTools.Serialization/Wrappers/BDPlusSVM.cs @@ -1,5 +1,5 @@ using System.IO; -using SabreTools.Models.BDPlus; +using SabreTools.Serialization.Models.BDPlus; namespace SabreTools.Serialization.Wrappers { diff --git a/SabreTools.Serialization/Wrappers/IRD.cs b/SabreTools.Serialization/Wrappers/IRD.cs index 69b3751a..317e0913 100644 --- a/SabreTools.Serialization/Wrappers/IRD.cs +++ b/SabreTools.Serialization/Wrappers/IRD.cs @@ -2,7 +2,7 @@ using System.IO; namespace SabreTools.Serialization.Wrappers { - public class IRD : WrapperBase + public class IRD : WrapperBase { #region Descriptive Properties @@ -14,22 +14,22 @@ namespace SabreTools.Serialization.Wrappers #region Constructors /// - public IRD(SabreTools.Models.IRD.File model, byte[] data) : base(model, data) { } + public IRD(SabreTools.Serialization.Models.IRD.File model, byte[] data) : base(model, data) { } /// - public IRD(SabreTools.Models.IRD.File model, byte[] data, int offset) : base(model, data, offset) { } + public IRD(SabreTools.Serialization.Models.IRD.File model, byte[] data, int offset) : base(model, data, offset) { } /// - public IRD(SabreTools.Models.IRD.File model, byte[] data, int offset, int length) : base(model, data, offset, length) { } + public IRD(SabreTools.Serialization.Models.IRD.File model, byte[] data, int offset, int length) : base(model, data, offset, length) { } /// - public IRD(SabreTools.Models.IRD.File model, Stream data) : base(model, data) { } + public IRD(SabreTools.Serialization.Models.IRD.File model, Stream data) : base(model, data) { } /// - public IRD(SabreTools.Models.IRD.File model, Stream data, long offset) : base(model, data, offset) { } + public IRD(SabreTools.Serialization.Models.IRD.File model, Stream data, long offset) : base(model, data, offset) { } /// - public IRD(SabreTools.Models.IRD.File model, Stream data, long offset, long length) : base(model, data, offset, length) { } + public IRD(SabreTools.Serialization.Models.IRD.File model, Stream data, long offset, long length) : base(model, data, offset, length) { } #endregion diff --git a/SabreTools.Serialization/Wrappers/PIC.cs b/SabreTools.Serialization/Wrappers/PIC.cs index ea297cbe..28edcbdc 100644 --- a/SabreTools.Serialization/Wrappers/PIC.cs +++ b/SabreTools.Serialization/Wrappers/PIC.cs @@ -1,5 +1,5 @@ using System.IO; -using SabreTools.Models.PIC; +using SabreTools.Serialization.Models.PIC; namespace SabreTools.Serialization.Wrappers { diff --git a/SabreTools.Serialization/Wrappers/XMID.cs b/SabreTools.Serialization/Wrappers/XMID.cs index 0f6bdfee..7f74175c 100644 --- a/SabreTools.Serialization/Wrappers/XMID.cs +++ b/SabreTools.Serialization/Wrappers/XMID.cs @@ -1,10 +1,10 @@ using System.IO; using System.Text; -using static SabreTools.Models.Xbox.Constants; +using static SabreTools.Serialization.Models.Xbox.Constants; namespace SabreTools.Serialization.Wrappers { - public class XMID : WrapperBase + public class XMID : WrapperBase { #region Descriptive Properties @@ -63,22 +63,22 @@ namespace SabreTools.Serialization.Wrappers #region Constructors /// - public XMID(SabreTools.Models.Xbox.XMID model, byte[] data) : base(model, data) { } + public XMID(SabreTools.Serialization.Models.Xbox.XMID model, byte[] data) : base(model, data) { } /// - public XMID(SabreTools.Models.Xbox.XMID model, byte[] data, int offset) : base(model, data, offset) { } + public XMID(SabreTools.Serialization.Models.Xbox.XMID model, byte[] data, int offset) : base(model, data, offset) { } /// - public XMID(SabreTools.Models.Xbox.XMID model, byte[] data, int offset, int length) : base(model, data, offset, length) { } + public XMID(SabreTools.Serialization.Models.Xbox.XMID model, byte[] data, int offset, int length) : base(model, data, offset, length) { } /// - public XMID(SabreTools.Models.Xbox.XMID model, Stream data) : base(model, data) { } + public XMID(SabreTools.Serialization.Models.Xbox.XMID model, Stream data) : base(model, data) { } /// - public XMID(SabreTools.Models.Xbox.XMID model, Stream data, long offset) : base(model, data, offset) { } + public XMID(SabreTools.Serialization.Models.Xbox.XMID model, Stream data, long offset) : base(model, data, offset) { } /// - public XMID(SabreTools.Models.Xbox.XMID model, Stream data, long offset, long length) : base(model, data, offset, length) { } + public XMID(SabreTools.Serialization.Models.Xbox.XMID model, Stream data, long offset, long length) : base(model, data, offset, length) { } #endregion diff --git a/SabreTools.Serialization/Wrappers/XeMID.cs b/SabreTools.Serialization/Wrappers/XeMID.cs index 0f181919..f61c3949 100644 --- a/SabreTools.Serialization/Wrappers/XeMID.cs +++ b/SabreTools.Serialization/Wrappers/XeMID.cs @@ -1,10 +1,10 @@ using System.IO; using System.Text; -using static SabreTools.Models.Xbox.Constants; +using static SabreTools.Serialization.Models.Xbox.Constants; namespace SabreTools.Serialization.Wrappers { - public class XeMID : WrapperBase + public class XeMID : WrapperBase { #region Descriptive Properties @@ -78,22 +78,22 @@ namespace SabreTools.Serialization.Wrappers #region Constructors /// - public XeMID(SabreTools.Models.Xbox.XeMID model, byte[] data) : base(model, data) { } + public XeMID(SabreTools.Serialization.Models.Xbox.XeMID model, byte[] data) : base(model, data) { } /// - public XeMID(SabreTools.Models.Xbox.XeMID model, byte[] data, int offset) : base(model, data, offset) { } + public XeMID(SabreTools.Serialization.Models.Xbox.XeMID model, byte[] data, int offset) : base(model, data, offset) { } /// - public XeMID(SabreTools.Models.Xbox.XeMID model, byte[] data, int offset, int length) : base(model, data, offset, length) { } + public XeMID(SabreTools.Serialization.Models.Xbox.XeMID model, byte[] data, int offset, int length) : base(model, data, offset, length) { } /// - public XeMID(SabreTools.Models.Xbox.XeMID model, Stream data) : base(model, data) { } + public XeMID(SabreTools.Serialization.Models.Xbox.XeMID model, Stream data) : base(model, data) { } /// - public XeMID(SabreTools.Models.Xbox.XeMID model, Stream data, long offset) : base(model, data, offset) { } + public XeMID(SabreTools.Serialization.Models.Xbox.XeMID model, Stream data, long offset) : base(model, data, offset) { } /// - public XeMID(SabreTools.Models.Xbox.XeMID model, Stream data, long offset, long length) : base(model, data, offset, length) { } + public XeMID(SabreTools.Serialization.Models.Xbox.XeMID model, Stream data, long offset, long length) : base(model, data, offset, length) { } #endregion