From defe1c53aa02a20d1c3450a72247d6eef0aaade8 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 24 Oct 2023 23:33:53 -0400 Subject: [PATCH] Port a version of XgdInfo from MPF --- Wrappers/XgdInfo.cs | 190 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 Wrappers/XgdInfo.cs diff --git a/Wrappers/XgdInfo.cs b/Wrappers/XgdInfo.cs new file mode 100644 index 00000000..722fc293 --- /dev/null +++ b/Wrappers/XgdInfo.cs @@ -0,0 +1,190 @@ +namespace SabreTools.Serialization.Wrappers +{ + /// + /// Contains information specific to an XGD disc + /// + /// TODO: Convert this to a proper WrapperBase implementation + public class XgdInfo + { + #region Properties + + /// + /// Indicates whether the information in this object is fully instantiated or not + /// + public bool Initialized { get; private set; } + + /// + /// Raw XMID/XeMID string that all other information is derived from + /// +#if NET48 + public string RawXMID { get; private set; } +#else + public string? RawXMID { get; private set; } +#endif + + /// + /// XGD1 XMID + /// +#if NET48 + public Models.Xbox.XMID XMID { get; private set; } +#else + public Models.Xbox.XMID? XMID { get; private set; } +#endif + + /// + /// XGD2/3 XeMID + /// +#if NET48 + public Models.Xbox.XeMID XeMID { get; private set; } +#else + public Models.Xbox.XeMID? XeMID { get; private set; } +#endif + + #endregion + + #region Extension Properties + + /// + /// Get the human-readable serial string + /// +#if NET48 + public string Serial +#else + public string? Serial +#endif + { + get + { + if (!this.Initialized) + return null; + + try + { + // XGD1 doesn't use PlatformIdentifier + if (XMID != null) + return $"{XMID.PublisherIdentifier}-{XMID.GameID}"; + + // XGD2/3 uses a specific identifier + else if (XeMID?.PlatformIdentifier == '2') + return $"{XeMID.PublisherIdentifier}-{XeMID.PlatformIdentifier}{XeMID.GameID}"; + + return null; + } + catch + { + return null; + } + } + } + + /// + /// Get the human-readable version string + /// +#if NET48 + public string Version +#else + public string? Version +#endif + { + get + { + if (!this.Initialized) + return null; + + try + { + // XGD1 doesn't use PlatformIdentifier + if (XMID != null) + return $"1.{XMID.VersionNumber}"; + + // XGD2/3 uses a specific identifier + else if (XeMID?.PlatformIdentifier == '2') + return $"1.{XeMID.SKU}"; + + return null; + } + catch + { + return null; + } + } + } + + #endregion + + #region Constructors + + /// + /// Populate a set of XGD information from a Master ID (XMID/XeMID) string + /// + /// XMID/XeMID string representing the DMI information + public XgdInfo(string xmid) + { + this.Initialized = false; + if (string.IsNullOrWhiteSpace(xmid)) + return; + + this.RawXMID = xmid.TrimEnd('\0'); + if (string.IsNullOrWhiteSpace(this.RawXMID)) + return; + + // XGD1 information is 8 characters + if (this.RawXMID.Length == 8) + this.Initialized = ParseXGD1XMID(this.RawXMID); + + // XGD2/3 information is semi-variable length + else if (this.RawXMID.Length == 13 || this.RawXMID.Length == 14 || this.RawXMID.Length == 21 || this.RawXMID.Length == 22) + this.Initialized = ParseXGD23XeMID(this.RawXMID); + } + + #endregion + + #region Helpers + + /// + /// Parse an XGD1 XMID string + /// + /// XMID string to attempt to parse + /// True if the XMID could be parsed, false otherwise + private bool ParseXGD1XMID(string rawXmid) + { + try + { + var xmid = new Strings.XMID().Deserialize(rawXmid); + if (xmid == null) + return false; + + this.XMID = xmid; + return true; + } + catch + { + return false; + } + } + + /// + /// Parse an XGD2/3 XeMID string + /// + /// XeMID string to attempt to parse + /// True if the XeMID could be parsed, false otherwise + private bool ParseXGD23XeMID(string rawXemid) + { + try + { + var xemid = new Strings.XeMID().Deserialize(rawXemid); + if (xemid == null) + return false; + + this.XeMID = xemid; + return true; + } + catch + { + return false; + } + } + + #endregion + } +}