diff --git a/ArcFormats/KiriKiri/ArcXP3.cs b/ArcFormats/KiriKiri/ArcXP3.cs index 373278c4..b4a4e0cd 100644 --- a/ArcFormats/KiriKiri/ArcXP3.cs +++ b/ArcFormats/KiriKiri/ArcXP3.cs @@ -152,7 +152,9 @@ namespace GameRes.Formats.KiriKiri if (entry_size < 0) return null; dir_offset += 12 + entry_size; - if (0x6E666E68 == entry_signature || 0x46696C65 == entry_signature) // "hnfn" || "eliF" + if (0x6E666E68 == entry_signature // "hnfn" + || 0x6C696D73 == entry_signature // "smil" + || 0x46696C65 == entry_signature) // "eliF" { uint hash = header.ReadUInt32(); int name_size = header.ReadInt16(); diff --git a/ArcFormats/KiriKiri/CryptAlgorithms.cs b/ArcFormats/KiriKiri/CryptAlgorithms.cs index a9ed3e55..07935775 100644 --- a/ArcFormats/KiriKiri/CryptAlgorithms.cs +++ b/ArcFormats/KiriKiri/CryptAlgorithms.cs @@ -822,4 +822,31 @@ namespace GameRes.Formats.KiriKiri Decrypt (entry, offset, values, pos, count); } } + + [Serializable] + public class SmileCrypt : ICrypt + { + public override void Decrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count) + { + uint hash = entry.Hash ^ 0xD0F0BA7B; + byte key = (byte)(hash ^ (hash >> 8) ^ (hash >> 16) ^ (hash >> 24)); + if (0 == key) + key = 0x5E; + if (0 == offset && count > 0) + { + if (0 == (hash & 0xFF)) + hash = 0x7B; + values[pos] ^= (byte)hash; + } + for (int i = 0; i < count; ++i) + { + values[pos+i] ^= key; + } + } + + public override void Encrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count) + { + Decrypt (entry, offset, values, pos, count); + } + } }