using System.Collections.Generic; using System.IO; using System.Text; namespace BinaryObjectScanner.Wrappers { public class NCF : WrapperBase { #region Descriptive Properties /// public override string DescriptionString => "Half-Life No Cache File (NCF)"; #endregion #region Pass-Through Properties #region Header /// #if NET48 public uint Dummy0 => _model.Header.Dummy0; #else public uint? Dummy0 => _model.Header?.Dummy0; #endif /// #if NET48 public uint MajorVersion => _model.Header.MajorVersion; #else public uint? MajorVersion => _model.Header?.MajorVersion; #endif /// #if NET48 public uint MinorVersion => _model.Header.MinorVersion; #else public uint? MinorVersion => _model.Header?.MinorVersion; #endif /// #if NET48 public uint CacheID => _model.Header.CacheID; #else public uint? CacheID => _model.Header?.CacheID; #endif /// #if NET48 public uint LastVersionPlayed => _model.Header.LastVersionPlayed; #else public uint? LastVersionPlayed => _model.Header?.LastVersionPlayed; #endif /// #if NET48 public uint Dummy1 => _model.Header.Dummy1; #else public uint? Dummy1 => _model.Header?.Dummy1; #endif /// #if NET48 public uint Dummy2 => _model.Header.Dummy2; #else public uint? Dummy2 => _model.Header?.Dummy2; #endif /// #if NET48 public uint FileSize => _model.Header.FileSize; #else public uint? FileSize => _model.Header?.FileSize; #endif /// #if NET48 public uint BlockSize => _model.Header.BlockSize; #else public uint? BlockSize => _model.Header?.BlockSize; #endif /// #if NET48 public uint BlockCount => _model.Header.BlockCount; #else public uint? BlockCount => _model.Header?.BlockCount; #endif /// #if NET48 public uint Dummy3 => _model.Header.Dummy3; #else public uint? Dummy3 => _model.Header?.Dummy3; #endif #endregion #region Directory Header /// #if NET48 public uint DH_Dummy0 => _model.DirectoryHeader.Dummy0; #else public uint? DH_Dummy0 => _model.DirectoryHeader?.Dummy0; #endif /// #if NET48 public uint DH_CacheID => _model.DirectoryHeader.CacheID; #else public uint? DH_CacheID => _model.DirectoryHeader?.CacheID; #endif /// #if NET48 public uint DH_LastVersionPlayed => _model.DirectoryHeader.LastVersionPlayed; #else public uint? DH_LastVersionPlayed => _model.DirectoryHeader?.LastVersionPlayed; #endif /// #if NET48 public uint DH_ItemCount => _model.DirectoryHeader.ItemCount; #else public uint? DH_ItemCount => _model.DirectoryHeader?.ItemCount; #endif /// #if NET48 public uint DH_FileCount => _model.DirectoryHeader.FileCount; #else public uint? DH_FileCount => _model.DirectoryHeader?.FileCount; #endif /// #if NET48 public uint DH_ChecksumDataLength => _model.DirectoryHeader.ChecksumDataLength; #else public uint? DH_ChecksumDataLength => _model.DirectoryHeader?.ChecksumDataLength; #endif /// #if NET48 public uint DH_DirectorySize => _model.DirectoryHeader.DirectorySize; #else public uint? DH_DirectorySize => _model.DirectoryHeader?.DirectorySize; #endif /// #if NET48 public uint DH_NameSize => _model.DirectoryHeader.NameSize; #else public uint? DH_NameSize => _model.DirectoryHeader?.NameSize; #endif /// #if NET48 public uint DH_Info1Count => _model.DirectoryHeader.Info1Count; #else public uint? DH_Info1Count => _model.DirectoryHeader?.Info1Count; #endif /// #if NET48 public uint DH_CopyCount => _model.DirectoryHeader.CopyCount; #else public uint? DH_CopyCount => _model.DirectoryHeader?.CopyCount; #endif /// #if NET48 public uint DH_LocalCount => _model.DirectoryHeader.LocalCount; #else public uint? DH_LocalCount => _model.DirectoryHeader?.LocalCount; #endif /// #if NET48 public uint DH_Dummy1 => _model.DirectoryHeader.Dummy1; #else public uint? DH_Dummy1 => _model.DirectoryHeader?.Dummy1; #endif /// #if NET48 public uint DH_Dummy2 => _model.DirectoryHeader.Dummy2; #else public uint? DH_Dummy2 => _model.DirectoryHeader?.Dummy2; #endif /// #if NET48 public uint DH_Checksum => _model.DirectoryHeader.Checksum; #else public uint? DH_Checksum => _model.DirectoryHeader?.Checksum; #endif #endregion #region Directory Entries /// #if NET48 public SabreTools.Models.NCF.DirectoryEntry[] DirectoryEntries => _model.DirectoryEntries; #else public SabreTools.Models.NCF.DirectoryEntry?[]? DirectoryEntries => _model.DirectoryEntries; #endif #endregion #region Directory Names /// #if NET48 public Dictionary DirectoryNames => _model.DirectoryNames; #else public Dictionary? DirectoryNames => _model.DirectoryNames; #endif #endregion #region Directory Info 1 Entries /// #if NET48 public SabreTools.Models.NCF.DirectoryInfo1Entry[] DirectoryInfo1Entries => _model.DirectoryInfo1Entries; #else public SabreTools.Models.NCF.DirectoryInfo1Entry?[]? DirectoryInfo1Entries => _model.DirectoryInfo1Entries; #endif #endregion #region Directory Info 2 Entries /// #if NET48 public SabreTools.Models.NCF.DirectoryInfo2Entry[] DirectoryInfo2Entries => _model.DirectoryInfo2Entries; #else public SabreTools.Models.NCF.DirectoryInfo2Entry?[]? DirectoryInfo2Entries => _model.DirectoryInfo2Entries; #endif #endregion #region Directory Copy Entries /// #if NET48 public SabreTools.Models.NCF.DirectoryCopyEntry[] DirectoryCopyEntries => _model.DirectoryCopyEntries; #else public SabreTools.Models.NCF.DirectoryCopyEntry?[]? DirectoryCopyEntries => _model.DirectoryCopyEntries; #endif #endregion #region Directory Local Entries /// #if NET48 public SabreTools.Models.NCF.DirectoryLocalEntry[] DirectoryLocalEntries => _model.DirectoryLocalEntries; #else public SabreTools.Models.NCF.DirectoryLocalEntry?[]? DirectoryLocalEntries => _model.DirectoryLocalEntries; #endif #endregion #region Unknown Header /// #if NET48 public uint UH_Dummy0 => _model.UnknownHeader.Dummy0; #else public uint? UH_Dummy0 => _model.UnknownHeader?.Dummy0; #endif /// #if NET48 public uint UH_Dummy1 => _model.UnknownHeader.Dummy1; #else public uint? UH_Dummy1 => _model.UnknownHeader?.Dummy1; #endif #endregion #region Unknown Entries /// #if NET48 public SabreTools.Models.NCF.UnknownEntry[] UnknownEntries => _model.UnknownEntries; #else public SabreTools.Models.NCF.UnknownEntry?[]? UnknownEntries => _model.UnknownEntries; #endif #endregion #region Checksum Header /// #if NET48 public uint CH_Dummy0 => _model.ChecksumHeader.Dummy0; #else public uint? CH_Dummy0 => _model.ChecksumHeader?.Dummy0; #endif /// #if NET48 public uint CH_ChecksumSize => _model.ChecksumHeader.ChecksumSize; #else public uint? CH_ChecksumSize => _model.ChecksumHeader?.ChecksumSize; #endif #endregion #region Checksum Map Header /// #if NET48 public uint CMH_Dummy0 => _model.ChecksumMapHeader.Dummy0; #else public uint? CMH_Dummy0 => _model.ChecksumMapHeader?.Dummy0; #endif /// #if NET48 public uint CMH_Dummy1 => _model.ChecksumMapHeader.Dummy1; #else public uint? CMH_Dummy1 => _model.ChecksumMapHeader?.Dummy1; #endif /// #if NET48 public uint CMH_ItemCount => _model.ChecksumMapHeader.ItemCount; #else public uint? CMH_ItemCount => _model.ChecksumMapHeader?.ItemCount; #endif /// #if NET48 public uint CMH_ChecksumCount => _model.ChecksumMapHeader.ChecksumCount; #else public uint? CMH_ChecksumCount => _model.ChecksumMapHeader?.ChecksumCount; #endif #endregion #region Checksum Map Entries /// #if NET48 public SabreTools.Models.NCF.ChecksumMapEntry[] ChecksumMapEntries => _model.ChecksumMapEntries; #else public SabreTools.Models.NCF.ChecksumMapEntry?[]? ChecksumMapEntries => _model.ChecksumMapEntries; #endif #endregion #region Checksum Entries /// #if NET48 public SabreTools.Models.NCF.ChecksumEntry[] ChecksumEntries => _model.ChecksumEntries; #else public SabreTools.Models.NCF.ChecksumEntry?[]? ChecksumEntries => _model.ChecksumEntries; #endif #endregion #endregion #region Constructors /// #if NET48 public NCF(SabreTools.Models.NCF.File model, byte[] data, int offset) #else public NCF(SabreTools.Models.NCF.File? model, byte[]? data, int offset) #endif : base(model, data, offset) { // All logic is handled by the base class } /// #if NET48 public NCF(SabreTools.Models.NCF.File model, Stream data) #else public NCF(SabreTools.Models.NCF.File? model, Stream? data) #endif : base(model, data) { // All logic is handled by the base class } /// /// Create an NCF from a byte array and offset /// /// Byte array representing the NCF /// Offset within the array to parse /// An NCF wrapper on success, null on failure #if NET48 public static NCF Create(byte[] data, int offset) #else public static NCF? Create(byte[]? data, int offset) #endif { // If the data is invalid if (data == null) return null; // If the offset is out of bounds if (offset < 0 || offset >= data.Length) return null; // Create a memory stream and use that MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset); return Create(dataStream); } /// /// Create a NCF from a Stream /// /// Stream representing the NCF /// An NCF wrapper on success, null on failure #if NET48 public static NCF Create(Stream data) #else public static NCF? Create(Stream? data) #endif { // If the data is invalid if (data == null || data.Length == 0 || !data.CanSeek || !data.CanRead) return null; var file = new SabreTools.Serialization.Streams.NCF().Deserialize(data); if (file == null) return null; try { return new NCF(file, data); } catch { return null; } } #endregion #region Printing /// public override StringBuilder PrettyPrint() { StringBuilder builder = new StringBuilder(); Printing.NCF.Print(builder, _model); return builder; } #if NET6_0_OR_GREATER /// public override string ExportJSON() => System.Text.Json.JsonSerializer.Serialize(_model, _jsonSerializerOptions); #endif #endregion } }