refactored ResourceOptions handling.

This commit is contained in:
morkt 2014-07-27 07:39:58 +04:00
parent 5253f8c776
commit 1c33e4c9d5
7 changed files with 137 additions and 66 deletions

View File

@ -34,7 +34,28 @@ namespace GameRes.Formats
public string Scheme { get; set; } public string Scheme { get; set; }
public string Password { get; set; } public string Password { get; set; }
public IntEncryptionInfo () { } public uint? GetKey ()
{
if (null != Key && Key.HasValue)
return Key;
if (!string.IsNullOrEmpty (Scheme))
{
IntOpener.KeyData keydata;
if (IntOpener.KnownSchemes.TryGetValue (Scheme, out keydata))
return keydata.Key;
}
if (!string.IsNullOrEmpty (Password))
return IntOpener.EncodePassPhrase (Password);
return null;
}
}
public class IntOptions : ResourceOptions
{
public IntEncryptionInfo EncryptionInfo { get; set; }
} }
[Export(typeof(ArchiveFormat))] [Export(typeof(ArchiveFormat))]
@ -268,25 +289,41 @@ namespace GameRes.Formats
{ "Sengoku Tenshi Djibril (trial)", new KeyData { Key=0xef870610, Passphrase="FW-8O9B6WDS" }}, { "Sengoku Tenshi Djibril (trial)", new KeyData { Key=0xef870610, Passphrase="FW-8O9B6WDS" }},
}; };
public override ResourceOptions GetDefaultOptions ()
{
return new IntOptions {
EncryptionInfo = Settings.Default.INTEncryption ?? new IntEncryptionInfo(),
};
}
public override ResourceOptions GetOptions (object w)
{
var widget = w as GUI.WidgetINT;
if (null != widget)
{
Settings.Default.INTEncryption = widget.Info;
return new IntOptions { EncryptionInfo = widget.Info };
}
return this.GetDefaultOptions();
}
public override object GetAccessWidget ()
{
return new GUI.WidgetINT ();
}
uint? QueryEncryptionInfo () uint? QueryEncryptionInfo ()
{ {
var widget = new GUI.WidgetINT (Settings.Default.INTEncryption ?? new IntEncryptionInfo());
var args = new ParametersRequestEventArgs var args = new ParametersRequestEventArgs
{ {
Notice = arcStrings.INTNotice, Notice = arcStrings.INTNotice,
InputWidget = widget,
}; };
FormatCatalog.Instance.InvokeParametersRequest (this, args); FormatCatalog.Instance.InvokeParametersRequest (this, args);
if (!args.InputResult) if (!args.InputResult)
throw new OperationCanceledException(); throw new OperationCanceledException();
Settings.Default.INTEncryption = widget.Info; var options = GetOptions<IntOptions> (args.Options);
return widget.GetKey(); return options.EncryptionInfo.GetKey();
}
public override object GetAccessWidget ()
{
return new GUI.WidgetINT (Settings.Default.INTEncryption ?? new IntEncryptionInfo());
} }
} }
} }

View File

@ -39,10 +39,15 @@ namespace GameRes.Formats
public enum NpaTitleId public enum NpaTitleId
{ {
CHAOSHEAD = 0, CHAOSHEADTR1, CHAOSHEADTR2, MURAMASATR, MURAMASA, SUMAGA, DJANGO, DJANGOTR, NotEncrypted,
CHAOSHEAD, CHAOSHEADTR1, CHAOSHEADTR2, MURAMASATR, MURAMASA, SUMAGA, DJANGO, DJANGOTR,
LAMENTO, LAMENTOTR, SWEETPOOL, SUMAGASP, DEMONBANE, MURAMASAAD, AXANAEL, KIKOKUGAI, SONICOMITR2, LAMENTO, LAMENTOTR, SWEETPOOL, SUMAGASP, DEMONBANE, MURAMASAAD, AXANAEL, KIKOKUGAI, SONICOMITR2,
SUMAGA3P, SONICOMI, LOSTX, LOSTXTRAILER, DRAMATICALMURDER, TOTONO, PHENOMENO, NEKODA, SUMAGA3P, SONICOMI, LOSTX, LOSTXTRAILER, DRAMATICALMURDER, TOTONO, PHENOMENO, NEKODA,
NotEncrypted }
public class NpaOptions : ResourceOptions
{
public NpaTitleId TitleId { get; set; }
} }
[Export(typeof(ArchiveFormat))] [Export(typeof(ArchiveFormat))]
@ -55,13 +60,13 @@ namespace GameRes.Formats
/// <summary>Known encryption schemes.</summary> /// <summary>Known encryption schemes.</summary>
public static readonly string[] KnownSchemes = new string[] { public static readonly string[] KnownSchemes = new string[] {
arcStrings.ArcNoEncryption,
"Chaos;Head", "Chaos;Head Trial 1", "Chaos;Head Trial 2", "Muramasa Trial", "Muramasa", "Chaos;Head", "Chaos;Head Trial 1", "Chaos;Head Trial 2", "Muramasa Trial", "Muramasa",
"Sumaga", "Zoku Satsuriku no Django", "Zoku Satsuriku no Django Trial", "Lamento", "Sumaga", "Zoku Satsuriku no Django", "Zoku Satsuriku no Django Trial", "Lamento",
"Lamento Trial", "Sweet Pool", "Sumaga Special", "Demonbane", "MuramasaAD", "Axanael", "Lamento Trial", "Sweet Pool", "Sumaga Special", "Demonbane", "MuramasaAD", "Axanael",
"Kikokugai", "Sonicomi Trial 2", "Sumaga 3% Trial", "Sonicomi Version 1.0", "Kikokugai", "Sonicomi Trial 2", "Sumaga 3% Trial", "Sonicomi Version 1.0",
"Guilty Crown Lost Xmas", "Guilty Crown Lost Xmas Trailer", "DRAMAtical Murder", "Guilty Crown Lost Xmas", "Guilty Crown Lost Xmas Trailer", "DRAMAtical Murder",
"Kimi to Kanojo to Kanojo no Koi", "Phenomeno", "Nekoda -Nyanda-", "Kimi to Kanojo to Kanojo no Koi", "Phenomeno", "Nekoda -Nyanda-",
arcStrings.ArcNoEncryption,
}; };
public override ArcFile TryOpen (ArcView file) public override ArcFile TryOpen (ArcView file)
@ -248,10 +253,14 @@ namespace GameRes.Formats
public static byte[] GenerateKeyTable (NpaTitleId title_id) public static byte[] GenerateKeyTable (NpaTitleId title_id)
{ {
if ((int)title_id >= OrderTable.Length) int index = (int)title_id;
if (index < 0 || index >= OrderTable.Length)
throw new ArgumentOutOfRangeException ("title_id", "Invalid title id specified"); throw new ArgumentOutOfRangeException ("title_id", "Invalid title id specified");
byte[] order = OrderTable[(int)title_id]; byte[] order = OrderTable[index];
if (null == order)
throw new ArgumentException ("Encryption key table not defined", "title_id");
var table = new byte[256]; var table = new byte[256];
for (int i = 0; i < 256; ++i) for (int i = 0; i < 256; ++i)
{ {
@ -273,6 +282,23 @@ namespace GameRes.Formats
return table; return table;
} }
public override ResourceOptions GetDefaultOptions ()
{
return new NpaOptions { TitleId = Settings.Default.NPAScheme };
}
public override ResourceOptions GetOptions (object w)
{
var widget = w as GUI.WidgetNPA;
if (null != widget)
{
NpaTitleId scheme = GetTitleId (widget.GetScheme());
Settings.Default.NPAScheme = scheme;
return new NpaOptions { TitleId = scheme };
}
return this.GetDefaultOptions();
}
public override object GetAccessWidget () public override object GetAccessWidget ()
{ {
return new GUI.WidgetNPA(); return new GUI.WidgetNPA();
@ -280,19 +306,16 @@ namespace GameRes.Formats
NpaTitleId QueryGameEncryption () NpaTitleId QueryGameEncryption ()
{ {
var widget = new GUI.WidgetNPA();
var args = new ParametersRequestEventArgs var args = new ParametersRequestEventArgs
{ {
Notice = arcStrings.ArcEncryptedNotice, Notice = arcStrings.ArcEncryptedNotice,
InputWidget = widget,
}; };
FormatCatalog.Instance.InvokeParametersRequest (this, args); FormatCatalog.Instance.InvokeParametersRequest (this, args);
if (!args.InputResult) if (!args.InputResult)
throw new OperationCanceledException(); throw new OperationCanceledException();
NpaTitleId scheme = GetTitleId (widget.GetScheme()); var options = GetOptions<NpaOptions> (args.Options);
Settings.Default.NPAScheme = scheme; return options.TitleId;
return scheme;
} }
public static NpaTitleId GetTitleId (string title) public static NpaTitleId GetTitleId (string title)
@ -324,6 +347,7 @@ namespace GameRes.Formats
}; };
static readonly byte[][] OrderTable = { static readonly byte[][] OrderTable = {
null, // NotEncrypted
// CHAOSHEAD // CHAOSHEAD
new byte[] { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, new byte[] { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
// CHAOSHEADTR1 // CHAOSHEADTR1

View File

@ -242,7 +242,7 @@ NextEntry:
{ {
return new Xp3Options { return new Xp3Options {
Version = Settings.Default.XP3Version, Version = Settings.Default.XP3Version,
Scheme = NoCryptAlgorithm, Scheme = GetScheme (Settings.Default.XP3Scheme),
CompressIndex = Settings.Default.XP3CompressHeader, CompressIndex = Settings.Default.XP3CompressHeader,
CompressContents = Settings.Default.XP3CompressContents, CompressContents = Settings.Default.XP3CompressContents,
RetainDirs = Settings.Default.XP3RetainStructure, RetainDirs = Settings.Default.XP3RetainStructure,
@ -251,13 +251,7 @@ NextEntry:
public override ResourceOptions GetOptions (object widget) public override ResourceOptions GetOptions (object widget)
{ {
var options = this.GetDefaultOptions() as Xp3Options; return this.GetDefaultOptions();
var w = widget as GUI.CreateXP3Widget;
if (null != w)
{
options.Scheme = w.EncryptionWidget.GetScheme();
}
return options;
} }
public override object GetCreationWidget () public override object GetCreationWidget ()
@ -272,17 +266,15 @@ NextEntry:
ICrypt QueryCryptAlgorithm () ICrypt QueryCryptAlgorithm ()
{ {
var widget = this.GetAccessWidget() as GUI.WidgetXP3;
var args = new ParametersRequestEventArgs var args = new ParametersRequestEventArgs
{ {
Notice = arcStrings.ArcEncryptedNotice, Notice = arcStrings.ArcEncryptedNotice,
InputWidget = widget,
}; };
FormatCatalog.Instance.InvokeParametersRequest (this, args); FormatCatalog.Instance.InvokeParametersRequest (this, args);
if (!args.InputResult) if (!args.InputResult)
throw new OperationCanceledException(); throw new OperationCanceledException();
return widget.GetScheme(); return GetOptions<Xp3Options> (args.Options).Scheme;
} }
public static ICrypt GetScheme (string scheme) public static ICrypt GetScheme (string scheme)

View File

@ -16,6 +16,11 @@ using GameRes.Formats.Properties;
namespace GameRes.Formats namespace GameRes.Formats
{ {
public class YpfOptions : ResourceOptions
{
public uint Key { get; set; }
}
[Export(typeof(ArchiveFormat))] [Export(typeof(ArchiveFormat))]
public class YpfOpener : ArchiveFormat public class YpfOpener : ArchiveFormat
{ {
@ -55,21 +60,38 @@ namespace GameRes.Formats
return new ZLibStream (input, CompressionMode.Decompress); return new ZLibStream (input, CompressionMode.Decompress);
} }
public override ResourceOptions GetDefaultOptions ()
{
return new YpfOptions { Key = Settings.Default.YPFKey };
}
public override ResourceOptions GetOptions (object w)
{
var widget = w as GUI.WidgetYPF;
if (null != widget)
{
uint last_key = widget.GetKey() ?? DefaultKey;
Settings.Default.YPFKey = last_key;
return new YpfOptions { Key = last_key };
}
return this.GetDefaultOptions();
}
public override object GetAccessWidget ()
{
return new GUI.WidgetYPF();
}
uint QueryEncryptionKey () uint QueryEncryptionKey ()
{ {
var widget = new GUI.WidgetYPF();
var args = new ParametersRequestEventArgs var args = new ParametersRequestEventArgs
{ {
Notice = arcStrings.YPFNotice, Notice = arcStrings.YPFNotice,
InputWidget = widget,
}; };
FormatCatalog.Instance.InvokeParametersRequest (this, args); FormatCatalog.Instance.InvokeParametersRequest (this, args);
if (!args.InputResult) if (!args.InputResult)
throw new OperationCanceledException(); throw new OperationCanceledException();
return GetOptions<YpfOptions> (args.Options).Key;
uint last_key = widget.GetKey() ?? DefaultKey;
Settings.Default.YPFKey = last_key;
return last_key;
} }
private class Parser private class Parser

View File

@ -21,10 +21,10 @@ namespace GameRes.Formats.GUI
/// </summary> /// </summary>
public partial class WidgetINT : Grid public partial class WidgetINT : Grid
{ {
public WidgetINT (IntEncryptionInfo encryption_info) public WidgetINT ()
{ {
InitializeComponent(); InitializeComponent();
this.DataContext = encryption_info; this.DataContext = GameRes.Formats.Properties.Settings.Default.INTEncryption ?? new IntEncryptionInfo();
Passphrase.TextChanged += OnPassphraseChanged; Passphrase.TextChanged += OnPassphraseChanged;
EncScheme.SelectionChanged += OnSchemeChanged; EncScheme.SelectionChanged += OnSchemeChanged;
@ -61,24 +61,6 @@ namespace GameRes.Formats.GUI
} }
} }
} }
public uint? GetKey ()
{
if (null != Info.Key && Info.Key.HasValue)
return Info.Key;
if (!string.IsNullOrEmpty (Info.Scheme))
{
IntOpener.KeyData keydata;
if (IntOpener.KnownSchemes.TryGetValue (Info.Scheme, out keydata))
return keydata.Key;
}
if (!string.IsNullOrEmpty (Info.Password))
return IntOpener.EncodePassPhrase (Info.Password);
return null;
}
} }
[ValueConversion(typeof(uint?), typeof(string))] [ValueConversion(typeof(uint?), typeof(string))]

View File

@ -182,6 +182,14 @@ namespace GameRes
{ {
return null; return null;
} }
protected OptType GetOptions<OptType> (ResourceOptions res_options) where OptType : ResourceOptions
{
var options = res_options as OptType;
if (null == options)
options = this.GetDefaultOptions() as OptType;
return options;
}
} }
public delegate void ParametersRequestEventHandler (object sender, ParametersRequestEventArgs e); public delegate void ParametersRequestEventHandler (object sender, ParametersRequestEventArgs e);

View File

@ -837,18 +837,24 @@ namespace GARbro.GUI
private void OnParametersRequest (object sender, ParametersRequestEventArgs e) private void OnParametersRequest (object sender, ParametersRequestEventArgs e)
{ {
var control = e.InputWidget as UIElement; var format = sender as ArchiveFormat;
if (null != format)
{
var control = format.GetAccessWidget() as UIElement;
if (null != control) if (null != control)
{ {
bool busy_state = m_busy_state; bool busy_state = m_busy_state;
var param_dialog = new ArcParametersDialog (control, e.Notice); var param_dialog = new ArcParametersDialog (control, e.Notice);
param_dialog.Owner = this; param_dialog.Owner = this;
e.InputResult = param_dialog.ShowDialog() ?? false; e.InputResult = param_dialog.ShowDialog() ?? false;
if (e.InputResult)
e.Options = format.GetOptions (control);
if (busy_state) if (busy_state)
SetBusyState(); SetBusyState();
} }
} }
} }
}
/// <summary> /// <summary>
/// TextBox that uses filesystem as source for autocomplete. /// TextBox that uses filesystem as source for autocomplete.