(GYU): handle enctypted images with non-numeric filenames.

This commit is contained in:
morkt
2018-08-20 14:49:45 +04:00
parent 50ca23ec03
commit 6e5c60ee2c
3 changed files with 38 additions and 28 deletions

View File

@@ -34,6 +34,7 @@ using GameRes.Utility;
using GameRes.Compression; using GameRes.Compression;
using GameRes.Cryptography; using GameRes.Cryptography;
using GameRes.Formats.Strings; using GameRes.Formats.Strings;
using System.Collections;
namespace GameRes.Formats.ExHibit namespace GameRes.Formats.ExHibit
{ {
@@ -50,7 +51,8 @@ namespace GameRes.Formats.ExHibit
[Serializable] [Serializable]
public class GyuMap : ResourceScheme public class GyuMap : ResourceScheme
{ {
public Dictionary<string, Dictionary<int, uint>> KnownKeys; public Dictionary<string, Dictionary<int, uint>> NumericKeys;
public Dictionary<string, Dictionary<string, uint>> StringKeys;
} }
[Export(typeof(ImageFormat))] [Export(typeof(ImageFormat))]
@@ -60,12 +62,15 @@ namespace GameRes.Formats.ExHibit
public override string Description { get { return "ExHIBIT engine image format"; } } public override string Description { get { return "ExHIBIT engine image format"; } }
public override uint Signature { get { return 0x1A555947; } } // 'GYU' public override uint Signature { get { return 0x1A555947; } } // 'GYU'
public static Dictionary<string, Dictionary<int, uint>> KnownKeys = new Dictionary<string, Dictionary<int, uint>>(); GyuMap DefaultScheme = new GyuMap {
NumericKeys = new Dictionary<string, Dictionary<int, uint>>(),
StringKeys = new Dictionary<string, Dictionary<string, uint>>(),
};
public override ResourceScheme Scheme public override ResourceScheme Scheme
{ {
get { return new GyuMap { KnownKeys = KnownKeys }; } get { return DefaultScheme; }
set { KnownKeys = ((GyuMap)value).KnownKeys; } set { DefaultScheme = (GyuMap)value; }
} }
public override ImageMetaData ReadMetaData (IBinaryStream stream) public override ImageMetaData ReadMetaData (IBinaryStream stream)
@@ -85,27 +90,31 @@ namespace GameRes.Formats.ExHibit
}; };
} }
IDictionary<int, uint> CurrentMap = null; IDictionary CurrentMap = null;
public override ImageData Read (IBinaryStream stream, ImageMetaData info) public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{ {
var meta = (GyuMetaData)info; var meta = (GyuMetaData)info;
if (0 == meta.Key) if (0 == meta.Key)
{ {
bool got_key = false; object token = null;
var name = Path.GetFileNameWithoutExtension (meta.FileName); if (null == CurrentMap)
int num; CurrentMap = QueryScheme();
if (int.TryParse (name, out num)) if (CurrentMap != null)
{ {
if (null == CurrentMap) var name = Path.GetFileNameWithoutExtension (meta.FileName);
CurrentMap = QueryScheme(); int num;
got_key = CurrentMap != null && CurrentMap.TryGetValue (num, out meta.Key); 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; CurrentMap = null;
throw new UnknownEncryptionScheme ("Unknown image encryption key"); throw new UnknownEncryptionScheme ("Unknown image encryption key");
} }
meta.Key = (uint)CurrentMap[token];
} }
var reader = new GyuReader (stream.AsStream, meta); var reader = new GyuReader (stream.AsStream, meta);
reader.Unpack(); reader.Unpack();
@@ -117,12 +126,8 @@ namespace GameRes.Formats.ExHibit
throw new System.NotImplementedException ("GyuFormat.Write not implemented"); throw new System.NotImplementedException ("GyuFormat.Write not implemented");
} }
private IDictionary<int, uint> QueryScheme () private IDictionary QueryScheme ()
{ {
if (0 == KnownKeys.Count)
return null;
if (1 == KnownKeys.Count)
return KnownKeys.First().Value;
var options = Query<GyuOptions> (arcStrings.GYUImageEncrypted); var options = Query<GyuOptions> (arcStrings.GYUImageEncrypted);
return options.Scheme; return options.Scheme;
} }
@@ -134,14 +139,18 @@ namespace GameRes.Formats.ExHibit
public override object GetAccessWidget () 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<int, uint> GetScheme (string title) IDictionary GetScheme (string title)
{ {
Dictionary<int, uint> scheme = null; Dictionary<int, uint> num_scheme = null;
KnownKeys.TryGetValue (title, out scheme); if (DefaultScheme.NumericKeys.TryGetValue (title, out num_scheme))
return scheme; return num_scheme;
Dictionary<string, uint> 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 class GyuOptions : ResourceOptions
{ {
public IDictionary<int, uint> Scheme; public IDictionary Scheme;
} }
} }

View File

@@ -3,8 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:p="clr-namespace:GameRes.Formats.Properties" xmlns:p="clr-namespace:GameRes.Formats.Properties"
xmlns:ex="clr-namespace:GameRes.Formats.ExHibit"> xmlns:ex="clr-namespace:GameRes.Formats.ExHibit">
<ComboBox Name="Title" ItemsSource="{Binding Source={x:Static ex:GyuFormat.KnownKeys}, Mode=OneWay}" <ComboBox Name="Title"
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=GYUTitle, Mode=TwoWay}" SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=GYUTitle, Mode=TwoWay}"
SelectedValuePath="Key" DisplayMemberPath="Key"
Width="200" Grid.Row="1" HorizontalAlignment="Left"/> Width="200" Grid.Row="1" HorizontalAlignment="Left"/>
</StackPanel> </StackPanel>

View File

@@ -1,4 +1,5 @@
using System.Windows.Controls; using System.Collections.Generic;
using System.Windows.Controls;
namespace GameRes.Formats.GUI namespace GameRes.Formats.GUI
{ {
@@ -7,9 +8,10 @@ namespace GameRes.Formats.GUI
/// </summary> /// </summary>
public partial class WidgetGYU : StackPanel public partial class WidgetGYU : StackPanel
{ {
public WidgetGYU() public WidgetGYU (IEnumerable<string> titles)
{ {
InitializeComponent(); InitializeComponent();
Title.ItemsSource = titles;
} }
} }
} }