using System; using System.ComponentModel; using static System.Buffers.Binary.BinaryPrimitives; namespace PKHeX.Core { /// /// Details about the Console and specific timestamps. /// /// size: 0x138 [TypeConverter(typeof(ExpandableObjectConverter))] public sealed class SystemData8b : SaveBlock { // Structure: // (u32 count, u64 FILETIME) Start Time // (u32 count, u64 FILETIME) Latest Save Time // (u32 count, u64 FILETIME) Penalty Timeout Time // (u32 count, u64 FILETIME) Last Daily Event Time // byte[208] ClockSnapshot (char[0x24]) // u32 "fd_bgmEvnet" // s64[6] reserved private const int SIZE_GMTIME = 12; private const int SIZE_SNAPSHOT = 0xD0; private const int OFS_SNAPSHOT = 4 + (3 * SIZE_GMTIME) + SIZE_GMTIME; // 0x34 private const int OFS_FDBGM = OFS_SNAPSHOT + SIZE_SNAPSHOT; private const int OFS_RESERVED = OFS_FDBGM + 4; private const int SIZE_TOTAL = OFS_RESERVED + (6 * 8); // 0x138 public SystemData8b(SAV8BS sav, int offset) : base(sav) => Offset = offset; public uint CountStart { get => ReadUInt32LittleEndian(Data.AsSpan(Offset + 0 + (0 * SIZE_GMTIME))); set => WriteUInt32LittleEndian(Data.AsSpan(Offset + 0 + (0 * SIZE_GMTIME)), value); } public long TicksStart { get => ReadInt64LittleEndian(Data.AsSpan(Offset + 4 + (0 * SIZE_GMTIME))); set => WriteInt64LittleEndian(Data.AsSpan(Offset + 4 + (0 * SIZE_GMTIME)), value); } public uint CountLatest { get => ReadUInt32LittleEndian(Data.AsSpan(Offset + 0 + (1 * SIZE_GMTIME))); set => WriteUInt32LittleEndian(Data.AsSpan(Offset + 0 + (1 * SIZE_GMTIME)), value); } public long TicksLatest { get => ReadInt64LittleEndian(Data.AsSpan(Offset + 4 + (1 * SIZE_GMTIME))); set => WriteInt64LittleEndian(Data.AsSpan(Offset + 4 + (1 * SIZE_GMTIME)), value); } public uint CountPenalty { get => ReadUInt32LittleEndian(Data.AsSpan(Offset + 0 + (2 * SIZE_GMTIME))); set => WriteUInt32LittleEndian(Data.AsSpan(Offset + 0 + (2 * SIZE_GMTIME)), value); } public long TicksPenalty { get => ReadInt64LittleEndian(Data.AsSpan(Offset + 4 + (2 * SIZE_GMTIME))); set => WriteInt64LittleEndian(Data.AsSpan(Offset + 4 + (2 * SIZE_GMTIME)), value); } public uint CountDaily { get => ReadUInt32LittleEndian(Data.AsSpan(Offset + 0 + (3 * SIZE_GMTIME))); set => WriteUInt32LittleEndian(Data.AsSpan(Offset + 0 + (3 * SIZE_GMTIME)), value); } public long TicksDaily { get => ReadInt64LittleEndian(Data.AsSpan(Offset + 4 + (3 * SIZE_GMTIME))); set => WriteInt64LittleEndian(Data.AsSpan(Offset + 4 + (3 * SIZE_GMTIME)), value); } // byte[] nxSnapshot // u32 fd_bgmEvnet // THESE ARE IN UTC public DateTime TimestampStart { get => DateTime.FromFileTimeUtc(TicksStart); set => TicksStart = value.ToFileTimeUtc(); } public DateTime TimestampLatest { get => DateTime.FromFileTimeUtc(TicksLatest); set => TicksLatest = value.ToFileTimeUtc(); } public DateTime TimestampPenalty { get => DateTime.FromFileTimeUtc(TicksPenalty); set => TicksPenalty = value.ToFileTimeUtc(); } public DateTime TimestampDaily { get => DateTime.FromFileTimeUtc(TicksDaily); set => TicksDaily = value.ToFileTimeUtc(); } public DateTime LocalTimestampStart { get => TimestampStart .ToLocalTime(); set => TimestampStart = value.ToUniversalTime(); } public DateTime LocalTimestampLatest { get => TimestampLatest .ToLocalTime(); set => TimestampLatest = value.ToUniversalTime(); } public DateTime LocalTimestampPenalty { get => TimestampPenalty.ToLocalTime(); set => TimestampPenalty = value.ToUniversalTime(); } public DateTime LocalTimestampDaily { get => TimestampDaily .ToLocalTime(); set => TimestampDaily = value.ToUniversalTime(); } public string LastSavedTime { get { var stamp = LocalTimestampLatest; return $"{stamp.Year:0000}-{stamp.Month:00}-{stamp.Day:00} {stamp.Hour:00}ː{stamp.Minute:00}ː{stamp.Second:00}"; // not : } } } }