From 6e5c60ee2cbf8b889a699d093c0f3fc38bfd43c5 Mon Sep 17 00:00:00 2001 From: morkt Date: Mon, 20 Aug 2018 14:49:45 +0400 Subject: [PATCH] (GYU): handle enctypted images with non-numeric filenames. --- ArcFormats/ExHibit/ImageGYU.cs | 57 ++++++++++++++++------------ ArcFormats/ExHibit/WidgetGYU.xaml | 3 +- ArcFormats/ExHibit/WidgetGYU.xaml.cs | 6 ++- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/ArcFormats/ExHibit/ImageGYU.cs b/ArcFormats/ExHibit/ImageGYU.cs index c0bf9f62..184e5858 100644 --- a/ArcFormats/ExHibit/ImageGYU.cs +++ b/ArcFormats/ExHibit/ImageGYU.cs @@ -34,6 +34,7 @@ using GameRes.Utility; using GameRes.Compression; using GameRes.Cryptography; using GameRes.Formats.Strings; +using System.Collections; namespace GameRes.Formats.ExHibit { @@ -50,7 +51,8 @@ namespace GameRes.Formats.ExHibit [Serializable] public class GyuMap : ResourceScheme { - public Dictionary> KnownKeys; + public Dictionary> NumericKeys; + public Dictionary> StringKeys; } [Export(typeof(ImageFormat))] @@ -60,12 +62,15 @@ namespace GameRes.Formats.ExHibit public override string Description { get { return "ExHIBIT engine image format"; } } public override uint Signature { get { return 0x1A555947; } } // 'GYU' - public static Dictionary> KnownKeys = new Dictionary>(); + GyuMap DefaultScheme = new GyuMap { + NumericKeys = new Dictionary>(), + StringKeys = new Dictionary>(), + }; public override ResourceScheme Scheme { - get { return new GyuMap { KnownKeys = KnownKeys }; } - set { KnownKeys = ((GyuMap)value).KnownKeys; } + get { return DefaultScheme; } + set { DefaultScheme = (GyuMap)value; } } public override ImageMetaData ReadMetaData (IBinaryStream stream) @@ -85,27 +90,31 @@ namespace GameRes.Formats.ExHibit }; } - IDictionary CurrentMap = null; + IDictionary CurrentMap = null; public override ImageData Read (IBinaryStream stream, ImageMetaData info) { var meta = (GyuMetaData)info; if (0 == meta.Key) { - bool got_key = false; - var name = Path.GetFileNameWithoutExtension (meta.FileName); - int num; - if (int.TryParse (name, out num)) + object token = null; + if (null == CurrentMap) + CurrentMap = QueryScheme(); + if (CurrentMap != null) { - if (null == CurrentMap) - CurrentMap = QueryScheme(); - got_key = CurrentMap != null && CurrentMap.TryGetValue (num, out meta.Key); + var name = Path.GetFileNameWithoutExtension (meta.FileName); + int num; + if (int.TryParse (name, out num) && CurrentMap.Contains (num)) + token = num; + else if (CurrentMap.Contains (name)) + token = name; } - if (!got_key) + if (null == token) { CurrentMap = null; throw new UnknownEncryptionScheme ("Unknown image encryption key"); } + meta.Key = (uint)CurrentMap[token]; } var reader = new GyuReader (stream.AsStream, meta); reader.Unpack(); @@ -117,12 +126,8 @@ namespace GameRes.Formats.ExHibit throw new System.NotImplementedException ("GyuFormat.Write not implemented"); } - private IDictionary QueryScheme () + private IDictionary QueryScheme () { - if (0 == KnownKeys.Count) - return null; - if (1 == KnownKeys.Count) - return KnownKeys.First().Value; var options = Query (arcStrings.GYUImageEncrypted); return options.Scheme; } @@ -134,14 +139,18 @@ namespace GameRes.Formats.ExHibit public override object GetAccessWidget () { - return new GUI.WidgetGYU(); + var titles = DefaultScheme.NumericKeys.Keys.Concat (DefaultScheme.StringKeys.Keys).OrderBy (x => x); + return new GUI.WidgetGYU (titles); } - Dictionary GetScheme (string title) + IDictionary GetScheme (string title) { - Dictionary scheme = null; - KnownKeys.TryGetValue (title, out scheme); - return scheme; + Dictionary num_scheme = null; + if (DefaultScheme.NumericKeys.TryGetValue (title, out num_scheme)) + return num_scheme; + Dictionary str_scheme = null; + DefaultScheme.StringKeys.TryGetValue (title, out str_scheme); + return str_scheme; } } @@ -330,6 +339,6 @@ namespace GameRes.Formats.ExHibit public class GyuOptions : ResourceOptions { - public IDictionary Scheme; + public IDictionary Scheme; } } diff --git a/ArcFormats/ExHibit/WidgetGYU.xaml b/ArcFormats/ExHibit/WidgetGYU.xaml index fa4736f6..48acf354 100644 --- a/ArcFormats/ExHibit/WidgetGYU.xaml +++ b/ArcFormats/ExHibit/WidgetGYU.xaml @@ -3,8 +3,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:p="clr-namespace:GameRes.Formats.Properties" xmlns:ex="clr-namespace:GameRes.Formats.ExHibit"> - diff --git a/ArcFormats/ExHibit/WidgetGYU.xaml.cs b/ArcFormats/ExHibit/WidgetGYU.xaml.cs index bf681387..b7ed5f12 100644 --- a/ArcFormats/ExHibit/WidgetGYU.xaml.cs +++ b/ArcFormats/ExHibit/WidgetGYU.xaml.cs @@ -1,4 +1,5 @@ -using System.Windows.Controls; +using System.Collections.Generic; +using System.Windows.Controls; namespace GameRes.Formats.GUI { @@ -7,9 +8,10 @@ namespace GameRes.Formats.GUI /// public partial class WidgetGYU : StackPanel { - public WidgetGYU() + public WidgetGYU (IEnumerable titles) { InitializeComponent(); + Title.ItemsSource = titles; } } }