diff --git a/PKHeX.Core/Saves/MemeCrypto/SwishCrypto.cs b/PKHeX.Core/Saves/MemeCrypto/SwishCrypto.cs
index e3f08f393..7529a4a61 100644
--- a/PKHeX.Core/Saves/MemeCrypto/SwishCrypto.cs
+++ b/PKHeX.Core/Saves/MemeCrypto/SwishCrypto.cs
@@ -174,12 +174,12 @@ public sealed class SCBlock : BlockInfo
///
/// What kind of block is it?
///
- public SCBlockType Type { get; set; }
+ public SCTypeCode Type { get; set; }
///
- /// For : What kind of array is it?
+ /// For : What kind of array is it?
///
- public SCBlockType SubType { get; set; }
+ public SCTypeCode SubType { get; set; }
///
/// Decrypted data for this block.
@@ -190,6 +190,10 @@ public sealed class SCBlock : BlockInfo
protected override bool ChecksumValid(byte[] data) => true;
protected override void SetChecksum(byte[] data) { }
+ public bool HasValue() => Type > SCTypeCode.Array;
+ public object GetValue() => Type.GetValue(Data);
+ public void SetValue(object value) => Type.SetValue(Data, value);
+
public SCBlock Clone()
{
var block = (SCBlock)MemberwiseClone();
@@ -197,24 +201,24 @@ public SCBlock Clone()
return block;
}
- private static int GetArrayEntrySize(SCBlockType type)
+ private static int GetArrayEntrySize(SCTypeCode type)
{
switch (type)
{
- case SCBlockType.Common3:
- case SCBlockType.Single1:
- case SCBlockType.Single5:
+ case SCTypeCode.Common3:
+ case SCTypeCode.Byte:
+ case SCTypeCode.SByte:
return 1;
- case SCBlockType.Single2:
- case SCBlockType.Single6:
+ case SCTypeCode.UInt16:
+ case SCTypeCode.Int16:
return 2;
- case SCBlockType.Single3:
- case SCBlockType.Single7:
- case SCBlockType.Single9:
+ case SCTypeCode.UInt32:
+ case SCTypeCode.Int32:
+ case SCTypeCode.Single:
return 4;
- case SCBlockType.Single4:
- case SCBlockType.Single8:
- case SCBlockType.Single10:
+ case SCTypeCode.UInt64:
+ case SCTypeCode.Int64:
+ case SCTypeCode.Double:
return 8;
default:
@@ -300,24 +304,24 @@ private int GetEncryptedDataSize()
const int size = 4 + 1; // key + type
switch (Type)
{
- case SCBlockType.Common1:
- case SCBlockType.Common2:
- case SCBlockType.Common3:
+ case SCTypeCode.Common1:
+ case SCTypeCode.Common2:
+ case SCTypeCode.Common3:
return size;
- case SCBlockType.Data:
+ case SCTypeCode.Object:
return size + 4 + Data.Length;
- case SCBlockType.Array:
+ case SCTypeCode.Array:
return size + 5 + Data.Length;
- case SCBlockType.Single1:
- case SCBlockType.Single2:
- case SCBlockType.Single3:
- case SCBlockType.Single4:
- case SCBlockType.Single5:
- case SCBlockType.Single6:
- case SCBlockType.Single7:
- case SCBlockType.Single8:
- case SCBlockType.Single9:
- case SCBlockType.Single10:
+ case SCTypeCode.Byte:
+ case SCTypeCode.UInt16:
+ case SCTypeCode.UInt32:
+ case SCTypeCode.UInt64:
+ case SCTypeCode.SByte:
+ case SCTypeCode.Int16:
+ case SCTypeCode.Int32:
+ case SCTypeCode.Int64:
+ case SCTypeCode.Single:
+ case SCTypeCode.Double:
return size + Data.Length;
default:
throw new ArgumentException(nameof(Type));
@@ -335,12 +339,12 @@ public byte[] GetEncryptedData()
result[4] = (byte)Type;
var out_ofs = 5;
- if (Type == SCBlockType.Data)
+ if (Type == SCTypeCode.Object)
{
BitConverter.GetBytes(Data.Length).CopyTo(result, out_ofs);
out_ofs += 4;
}
- else if (Type == SCBlockType.Array)
+ else if (Type == SCTypeCode.Array)
{
BitConverter.GetBytes(Data.Length / GetArrayEntrySize(SubType)).CopyTo(result, out_ofs);
result[out_ofs + 4] = (byte)SubType;
@@ -367,45 +371,45 @@ public static SCBlock ReadFromOffset(byte[] data, ref int offset)
var block = new SCBlock(key);
// Parse the block's type
- block.Type = (SCBlockType)block.CryptBytes(data, offset, 0, 1)[0];
+ block.Type = (SCTypeCode)block.CryptBytes(data, offset, 0, 1)[0];
switch (block.Type)
{
- case SCBlockType.Common1:
- case SCBlockType.Common2:
- case SCBlockType.Common3:
- // Block types A, B, Common are empty, and have no extra data.
+ case SCTypeCode.Common1:
+ case SCTypeCode.Common2:
+ case SCTypeCode.Common3:
+ // Block types are empty, and have no extra data.
offset++;
break;
- case SCBlockType.Data:
+ case SCTypeCode.Object:
var num_bytes = BitConverter.ToInt32(block.CryptBytes(data, offset, 1, 4), 0);
block.Data = block.CryptBytes(data, offset, 5, num_bytes);
offset += 5 + num_bytes;
break;
- case SCBlockType.Array:
+ case SCTypeCode.Array:
var num_entries = BitConverter.ToInt32(block.CryptBytes(data, offset, 1, 4), 0);
- block.SubType = (SCBlockType)block.CryptBytes(data, offset, 5, 1)[0];
+ block.SubType = (SCTypeCode)block.CryptBytes(data, offset, 5, 1)[0];
switch (block.SubType)
{
- case SCBlockType.Common3:
+ case SCTypeCode.Common3:
// This is an array of booleans.
block.Data = block.CryptBytes(data, offset, 6, num_entries);
offset += 6 + num_entries;
Debug.Assert(block.Data.All(entry => entry <= 1));
break;
- case SCBlockType.Single1:
- case SCBlockType.Single2:
- case SCBlockType.Single3:
- case SCBlockType.Single4:
- case SCBlockType.Single5:
- case SCBlockType.Single6:
- case SCBlockType.Single7:
- case SCBlockType.Single8:
- case SCBlockType.Single9:
- case SCBlockType.Single10:
+ case SCTypeCode.Byte:
+ case SCTypeCode.UInt16:
+ case SCTypeCode.UInt32:
+ case SCTypeCode.UInt64:
+ case SCTypeCode.SByte:
+ case SCTypeCode.Int16:
+ case SCTypeCode.Int32:
+ case SCTypeCode.Int64:
+ case SCTypeCode.Single:
+ case SCTypeCode.Double:
var entry_size = GetArrayEntrySize(block.SubType);
block.Data = block.CryptBytes(data, offset, 6, num_entries * entry_size);
offset += 6 + (num_entries * entry_size);
@@ -416,16 +420,16 @@ public static SCBlock ReadFromOffset(byte[] data, ref int offset)
}
break;
- case SCBlockType.Single1:
- case SCBlockType.Single2:
- case SCBlockType.Single3:
- case SCBlockType.Single4:
- case SCBlockType.Single5:
- case SCBlockType.Single6:
- case SCBlockType.Single7:
- case SCBlockType.Single8:
- case SCBlockType.Single9:
- case SCBlockType.Single10:
+ case SCTypeCode.Byte:
+ case SCTypeCode.UInt16:
+ case SCTypeCode.UInt32:
+ case SCTypeCode.UInt64:
+ case SCTypeCode.SByte:
+ case SCTypeCode.Int16:
+ case SCTypeCode.Int32:
+ case SCTypeCode.Int64:
+ case SCTypeCode.Single:
+ case SCTypeCode.Double:
{
var entry_size = GetArrayEntrySize(block.Type);
block.Data = block.CryptBytes(data, offset, 1, entry_size);
@@ -444,7 +448,7 @@ public static SCBlock ReadFromOffset(byte[] data, ref int offset)
/// Block type for a .
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1027:Mark enums with FlagsAttribute", Justification = "NOT FLAGS")]
- public enum SCBlockType
+ public enum SCTypeCode
{
None = 0,
@@ -453,19 +457,85 @@ public enum SCBlockType
Common2 = 2,
Common3 = 3,
- Data = 4,
+ Object = 4,
Array = 5,
- Single1 = 8,
- Single2 = 9,
- Single3 = 10,
- Single4 = 11,
- Single5 = 12,
- Single6 = 13,
- Single7 = 14,
- Single8 = 15,
- Single9 = 16,
- Single10 = 17,
+ Byte = 8,
+ UInt16 = 9,
+ UInt32 = 10,
+ UInt64 = 11,
+ SByte = 12,
+ Int16 = 13,
+ Int32 = 14,
+ Int64 = 15,
+ Single = 16,
+ Double = 17,
+ }
+
+ public static class SCTypeCodeExtensions
+ {
+ public static Type GetType(this SCTypeCode type)
+ {
+ return type switch
+ {
+ SCTypeCode.Byte => typeof(byte),
+ SCTypeCode.UInt16 => typeof(ushort),
+ SCTypeCode.UInt32 => typeof(uint),
+ SCTypeCode.UInt64 => typeof(ulong),
+
+ SCTypeCode.SByte => typeof(sbyte),
+ SCTypeCode.Int16 => typeof(short),
+ SCTypeCode.Int32 => typeof(int),
+ SCTypeCode.Int64 => typeof(long),
+
+ SCTypeCode.Single => typeof(float),
+ SCTypeCode.Double => typeof(double),
+
+ _ => throw new ArgumentException(nameof(type)),
+ };
+ }
+
+ public static object GetValue(this SCTypeCode type, byte[] data)
+ {
+ return type switch
+ {
+ SCTypeCode.Byte => data[0],
+ SCTypeCode.UInt16 => BitConverter.ToUInt16(data, 0),
+ SCTypeCode.UInt32 => BitConverter.ToUInt32(data, 0),
+ SCTypeCode.UInt64 => BitConverter.ToUInt64(data, 0),
+
+ SCTypeCode.SByte => (sbyte)data[0],
+ SCTypeCode.Int16 => BitConverter.ToInt16(data, 0),
+ SCTypeCode.Int32 => BitConverter.ToInt32(data, 0),
+ SCTypeCode.Int64 => BitConverter.ToInt64(data, 0),
+
+ SCTypeCode.Single => BitConverter.ToSingle(data, 0),
+ SCTypeCode.Double => BitConverter.ToDouble(data, 0),
+
+ _ => throw new ArgumentException(nameof(type)),
+ };
+ }
+
+ public static void SetValue(this SCTypeCode type, byte[] data, object value)
+ {
+ switch (type)
+ {
+ case SCTypeCode.Byte: data[0] = (byte)value; break;
+ case SCTypeCode.UInt16: BitConverter.GetBytes((ushort)value).CopyTo(data, 0); break;
+ case SCTypeCode.UInt32: BitConverter.GetBytes((uint)value).CopyTo(data, 0); break;
+ case SCTypeCode.UInt64: BitConverter.GetBytes((ulong)value).CopyTo(data, 0); break;
+
+ case SCTypeCode.SByte: data[0] = (byte)value; break;
+ case SCTypeCode.Int16: BitConverter.GetBytes((short)value).CopyTo(data, 0); break;
+ case SCTypeCode.Int32: BitConverter.GetBytes((int)value).CopyTo(data, 0); break;
+ case SCTypeCode.Int64: BitConverter.GetBytes((long)value).CopyTo(data, 0); break;
+
+ case SCTypeCode.Single: BitConverter.GetBytes((float)value).CopyTo(data, 0); break;
+ case SCTypeCode.Double: BitConverter.GetBytes((double)value).CopyTo(data, 0); break;
+
+ default: throw new ArgumentException(nameof(type));
+ }
+ }
}
}