diff --git a/ArcFormats/KiriKiri/ArcXP3.cs b/ArcFormats/KiriKiri/ArcXP3.cs index b453106e..0470fc9e 100644 --- a/ArcFormats/KiriKiri/ArcXP3.cs +++ b/ArcFormats/KiriKiri/ArcXP3.cs @@ -52,10 +52,10 @@ namespace GameRes.Formats.KiriKiri { List m_segments = new List(); - public bool IsEncrypted { get; set; } - public ICrypt Cipher { get; set; } + public bool IsEncrypted { get; set; } + public ICrypt Cipher { get; set; } public List Segments { get { return m_segments; } } - public uint Hash { get; set; } + public uint Hash { get; set; } } public class Xp3Options : ResourceOptions @@ -71,6 +71,7 @@ namespace GameRes.Formats.KiriKiri public class Xp3Scheme : ResourceScheme { public Dictionary KnownSchemes; + public Dictionary ExeMap; } // Archive version 1: encrypt file first, then calculate checksum @@ -96,18 +97,10 @@ namespace GameRes.Formats.KiriKiri (byte)'X', (byte)'P', (byte)'3', 0x0d, 0x0a, 0x20, 0x0a, 0x1a, 0x8b, 0x67, 0x01 }; - public override ResourceScheme Scheme - { - get { return new Xp3Scheme { KnownSchemes = KnownSchemes }; } - set { KnownSchemes = ((Xp3Scheme)value).KnownSchemes; } - } - public bool ForceEncryptionQuery = true; private static readonly ICrypt NoCryptAlgorithm = new NoCrypt(); - public static Dictionary KnownSchemes = new Dictionary(); - public override ArcFile TryOpen (ArcView file) { long base_offset = 0; @@ -146,7 +139,7 @@ namespace GameRes.Formats.KiriKiri header_stream = ZLibCompressor.DeCompress (input); } - var crypt_algorithm = new Lazy (QueryCryptAlgorithm, false); + var crypt_algorithm = new Lazy (() => QueryCryptAlgorithm (file), false); var filename_map = new Dictionary(); var dir = new List(); @@ -461,8 +454,11 @@ NextEntry: return new GUI.WidgetXP3(); } - ICrypt QueryCryptAlgorithm () + ICrypt QueryCryptAlgorithm (ArcView file) { + var alg = GuessCryptAlgorithm (file); + if (null != alg) + return alg; var options = Query (arcStrings.XP3EncryptedNotice); return options.Scheme; } @@ -500,7 +496,7 @@ NextEntry: bool compress_contents = xp3_options.CompressContents; bool retain_dirs = xp3_options.RetainDirs; - bool use_encryption = scheme != NoCryptAlgorithm; + bool use_encryption = !(scheme is NoCrypt); using (var writer = new BinaryWriter (output, Encoding.ASCII, true)) { @@ -750,6 +746,40 @@ NextEntry: return false; return true; } + + ICrypt GuessCryptAlgorithm (ArcView file) + { + if (0 == KiriKiriScheme.ExeMap.Count) + return null; + var exe_pattern = VFS.CombinePath (VFS.GetDirectoryName (file.Name), "*.exe"); + foreach (var exe in VFS.GetFiles (exe_pattern).Select (e => Path.GetFileName (e.Name))) + { + string title; + if (KiriKiriScheme.ExeMap.TryGetValue (exe, out title)) + { + Settings.Default.XP3Scheme = title; + return GetScheme (title); + } + } + return null; + } + + static Xp3Scheme KiriKiriScheme = new Xp3Scheme + { + KnownSchemes = new Dictionary(), + ExeMap = new Dictionary(), + }; + + public static IDictionary KnownSchemes + { + get { return KiriKiriScheme.KnownSchemes; } + } + + public override ResourceScheme Scheme + { + get { return KiriKiriScheme; } + set { KiriKiriScheme = (Xp3Scheme)value; } + } } internal class Xp3Stream : Stream