Add systemtime, (underground item, poketch, both no GUI)

systemtime to be integrated to trainer info editor later
This commit is contained in:
Kurt 2021-11-20 23:54:27 -08:00
parent 9d5cff5221
commit ee567a7d15
4 changed files with 194 additions and 2 deletions

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core
public class SAV8BS : SaveFile, ISaveFileRevision, ITrainerStatRecord
{
// Save Data Attributes
protected internal override string ShortSummary => $"{OT} ({Version}) - {Played.LastSavedTime}";
protected internal override string ShortSummary => $"{OT} ({Version}) - {System.LastSavedTime}";
public override string Extension => string.Empty;
public override IReadOnlyList<string> PKMExtensions => Array.FindAll(PKM.Extensions, f =>
@ -20,21 +20,59 @@ public SAV8BS(byte[] data, bool exportable = true) : base(data, exportable)
{
Work = new FlagWork8b(this, 0x00004);
Items = new MyItem8b(this, 0x0563C);
Underground = new UndergroundItemList8b(this, 0x111BC);
// saveItemShortcut
PartyInfo = new Party8b(this, 0x14098);
BoxLayout = new BoxLayout8b(this, 0x148AA);
// Box[]
// PLAYER_DATA:
Config = new ConfigSave8b(this, 0x79B74); // size: 0x40
MyStatus = new MyStatus8b(this, 0x79BB4); // size: 0x50
Played = new PlayTime8b(this, 0x79C04); // size: 0x04
Contest = new Contest8b(this, 0x79C08); // size: 0x720
Zukan = new Zukan8b(this, 0x7A328); // size: 0x30B8
// 0x7D3E0 - Trainer Battle Data (bool,bool)[707]
// 0x7E9F8 - Menu selections (TopMenuItemTypeInt32, bool IsNew)[8], TopMenuItemTypeInt32 LastSelected
// 0x7EA3C - _FIELDOBJ_SAVE Objects[1000] (sizeof (0x44, 17 int fields), total size 0x109A0
Records = new Record8b(this, 0x8F3DC); // size: 0x78
// 0x8F454 - ENC_SV_DATA
// PLAYER_SAVE_DATA
// SaveBallDecoData
// SaveSealData[]
// _RANDOM_GROUP
// KinomiGrowSaveData -- berry trees
// PoffinSaveData -- poffins
// BTLTOWER_SAVEWORK -- BP counts and battle tower stats
System = new SystemData8b(this, 0x95DAC);
Poketch = new Poketch8b(this, 0); // todo
Daycare = new Daycare8b(this, 0x96080); // 0x2C0
// 0x96340 - _DENDOU_SAVEDATA
// BadgeSaveData
// BoukenNote
// TV_DATA
// UgSaveData
// GMS_DATA
// PLAYER_NETWORK_DATA
// UnionSaveData
// CON_PHOTO_LANG_DATA -- contest photo language data
// ZUKAN_PERSONAL_RND_DATA
// CON_PHOTO_EXT_DATA[]
// GMS_POINT_HISTORY_EXT_DATA[]
// UgCountRecord
// ReBuffnameData
// 0xE9818 -- 0x10 byte[] MD5 hash of all savedata;
// v1.1 additions
// 0xE9828 -- RECORD_ADD_DATA: 0x30-sized[12] (0x120 bytes)
// MysteryGiftSaveData
// ZUKAN_PERSONAL_RND_DATA -- Spinda PID storage (17 * 2)
// POKETCH_POKETORE_COUNT_ARRAY -- (u16 species, u16 unused, i32 count, i32 reserved, i32 reserved) = 0x10bytes
// PLAYREPORT_DATA -- reporting player progress online?
// MT_DATA mtData; -- 0x400 bytes
// DENDOU_SAVE_ADD -- language tracking of members (hall of fame?)
Initialize();
}
@ -140,6 +178,7 @@ public override bool ChecksumsValid
// public Box8 BoxInfo { get; }
public FlagWork8b Work { get; }
public MyItem8b Items { get; }
public UndergroundItemList8b Underground { get; }
public Party8b PartyInfo { get; }
// public MyItem Items { get; }
public BoxLayout8b BoxLayout { get; }
@ -150,6 +189,8 @@ public override bool ChecksumsValid
// public Misc8 Misc { get; }
public Zukan8b Zukan { get; }
public Record8b Records { get; }
public SystemData8b System { get; }
public Poketch8b Poketch { get; }
public Daycare8b Daycare { get; }
#endregion

View File

@ -0,0 +1,45 @@
using System.ComponentModel;
namespace PKHeX.Core
{
/// <summary>
/// Details about the Poketch corner app.
/// </summary>
/// <remarks>size: ???</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class Poketch8b : SaveBlock
{
public const int APP_REGIST_MAX = 20;
public const int POKETCH_MAP_MARK_MAX = 6;
public const int POKETCH_DOTART_DATA_BYTESIZE = 192;
public const int POKETCH_POKE_HISTORY_COUNT_MAX = 12;
public const int POKETCH_PEDOMETER_MAX = 99999;
public const int POKETCH_CALENDER_MONTH_MAX = 12;
public Poketch8b(SaveFile sav, int offset) : base(sav) => Offset = offset;
public enum PoketchApp8b
{
DWATCH = 0,
CALC = 1,
MEMO = 2,
PEDOMETER = 3,
POKELIST = 4,
NATSUKI_CHECK = 5,
DOWSING = 6,
SODATEYA_CAMERA = 7,
POKEMON_HISTORY = 8,
COUNTER = 9,
AWATCH = 10,
MAP_MARKING = 11,
COINTOSS = 12,
CALENDER = 13,
DOTART = 14,
ROULETTE = 15,
POKEMON_COUNTER = 16,
KITCHEN_TIMER = 17,
COLOR_CHANGER = 18,
HIDEN_WAZA = 19,
}
}
}

View File

@ -0,0 +1,57 @@
using System;
using System.ComponentModel;
namespace PKHeX.Core
{
/// <summary>
/// Details about the Poketch corner app.
/// </summary>
/// <remarks>size: ???</remarks>
[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[???] Snapshot
// u32 "fd_bgmEvnet"
// s64[6] reserved
private const int SIZE_GMTIME = 12;
public SystemData8b(SaveFile sav, int offset) : base(sav) => Offset = offset;
public uint CountStart { get => BitConverter.ToUInt32(Data, Offset + 0 + (0 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0 + (0 * SIZE_GMTIME)); }
public long TicksStart { get => BitConverter. ToInt64(Data, Offset + 4 + (0 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 4 + (0 * SIZE_GMTIME)); }
public uint CountLatest { get => BitConverter.ToUInt32(Data, Offset + 0 + (1 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0 + (1 * SIZE_GMTIME)); }
public long TicksLatest { get => BitConverter. ToInt64(Data, Offset + 4 + (1 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 4 + (1 * SIZE_GMTIME)); }
public uint CountPenalty { get => BitConverter.ToUInt32(Data, Offset + 0 + (2 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0 + (2 * SIZE_GMTIME)); }
public long TicksPenalty { get => BitConverter. ToInt64(Data, Offset + 4 + (2 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 4 + (2 * SIZE_GMTIME)); }
public uint CountDaily { get => BitConverter.ToUInt32(Data, Offset + 0 + (3 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0 + (3 * SIZE_GMTIME)); }
public long TicksDaily { get => BitConverter. ToInt64(Data, Offset + 4 + (3 * SIZE_GMTIME)); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 4 + (3 * SIZE_GMTIME)); }
// 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 :
}
}
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
namespace PKHeX.Core
{
public sealed class UndergroundItemList8b : SaveBlock
{
public const int ItemSaveSize = 999;
public const int ItemMaxCount = 999;
public const int StatueMaxCount = 99;
public UndergroundItemList8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;
public IReadOnlyList<UndergroundItem8b> ReadItems()
{
var result = new UndergroundItem8b[ItemSaveSize];
for (int i = 0; i < result.Length; i++)
result[i] = new UndergroundItem8b(Data, Offset, i);
return result;
}
}
public class UndergroundItem8b
{
private const int SIZE = 0xC;
public readonly int Index; // not serialized
public int Count { get; set; }
public bool HideNewFlag { get; set; }
public bool IsFavoriteFlag { get; set; }
public UndergroundItem8b(byte[] data, int baseOffset, int index)
{
Index = index;
var offset = baseOffset + (SIZE * index);
Count = BitConverter.ToInt32(data, offset + 0);
HideNewFlag = BitConverter.ToUInt32(data, offset + 4) == 1;
IsFavoriteFlag = BitConverter.ToUInt32(data, offset + 8) == 1;
}
public void Write(byte[] data, int baseOffset)
{
var offset = baseOffset + (SIZE * Index);
BitConverter.GetBytes(Count).CopyTo(data, offset + 0);
BitConverter.GetBytes(HideNewFlag ? 1u : 0u).CopyTo(data, offset + 4);
BitConverter.GetBytes(IsFavoriteFlag ? 1u : 0u).CopyTo(data, offset + 8);
}
}
}