diff --git a/ArcFormats/ShiinaRio/WarcEncryption.cs b/ArcFormats/ShiinaRio/WarcEncryption.cs index 74555b42..897393c6 100644 --- a/ArcFormats/ShiinaRio/WarcEncryption.cs +++ b/ArcFormats/ShiinaRio/WarcEncryption.cs @@ -1156,18 +1156,20 @@ namespace GameRes.Formats.ShiinaRio { public void Decrypt (byte[] data, int index, uint length, uint flags) { - if (length >= 0x200 && (flags & 0x204) == 0x204) + if ((flags & 0x204) == 0x204) DoCountCrypt (data, index, (int)length); } public void Encrypt (byte[] data, int index, uint length, uint flags) { - if (length >= 0x200 && (flags & 0x104) == 0x104) + if ((flags & 0x104) == 0x104) DoCountCrypt (data, index, (int)length); } void DoCountCrypt (byte[] data, int index, int length) { + if (length < 0x200) + return; length = (length & 0x7E) | 1; byte count_00 = 0, count_FF = 0; for (int i = 0; i < length; ++i) @@ -1182,6 +1184,39 @@ namespace GameRes.Formats.ShiinaRio } } + [Serializable] + public class AltCountCrypt : IDecryptExtra + { + public void Decrypt (byte[] data, int index, uint length, uint flags) + { + if ((flags & 0x204) == 0x204) + DoCountCrypt (data, index, (int)length); + } + + public void Encrypt (byte[] data, int index, uint length, uint flags) + { + if ((flags & 0x104) == 0x104) + DoCountCrypt (data, index, (int)length); + } + + void DoCountCrypt (byte[] data, int index, int length) + { + if (length < 0x400) + return; + length = (length & 0x7E) | 1; + byte count_00 = 0, count_FF = 0; + for (int i = 0; i < length; ++i) + { + if (0xFF == data[index+i]) + count_FF++; + else if (0 == data[index+i]) + count_00++; + } + data[index + 0x100] ^= count_FF; + data[index + 0x104] ^= count_00; + } + } + [Serializable] public class UshimitsuCrypt : IDecryptExtra {