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 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))]
@ -268,25 +289,41 @@ namespace GameRes.Formats
{ "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 ()
{
var widget = new GUI.WidgetINT (Settings.Default.INTEncryption ?? new IntEncryptionInfo());
var args = new ParametersRequestEventArgs
{
Notice = arcStrings.INTNotice,
InputWidget = widget,
};
FormatCatalog.Instance.InvokeParametersRequest (this, args);
if (!args.InputResult)
throw new OperationCanceledException();
Settings.Default.INTEncryption = widget.Info;
return widget.GetKey();
}
public override object GetAccessWidget ()
{
return new GUI.WidgetINT (Settings.Default.INTEncryption ?? new IntEncryptionInfo());
var options = GetOptions<IntOptions> (args.Options);
return options.EncryptionInfo.GetKey();
}
}
}

View File

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

View File

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

View File

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

View File

@ -21,10 +21,10 @@ namespace GameRes.Formats.GUI
/// </summary>
public partial class WidgetINT : Grid
{
public WidgetINT (IntEncryptionInfo encryption_info)
public WidgetINT ()
{
InitializeComponent();
this.DataContext = encryption_info;
this.DataContext = GameRes.Formats.Properties.Settings.Default.INTEncryption ?? new IntEncryptionInfo();
Passphrase.TextChanged += OnPassphraseChanged;
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))]

View File

@ -182,6 +182,14 @@ namespace GameRes
{
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);

View File

@ -837,15 +837,21 @@ namespace GARbro.GUI
private void OnParametersRequest (object sender, ParametersRequestEventArgs e)
{
var control = e.InputWidget as UIElement;
if (null != control)
var format = sender as ArchiveFormat;
if (null != format)
{
bool busy_state = m_busy_state;
var param_dialog = new ArcParametersDialog (control, e.Notice);
param_dialog.Owner = this;
e.InputResult = param_dialog.ShowDialog() ?? false;
if (busy_state)
SetBusyState();
var control = format.GetAccessWidget() as UIElement;
if (null != control)
{
bool busy_state = m_busy_state;
var param_dialog = new ArcParametersDialog (control, e.Notice);
param_dialog.Owner = this;
e.InputResult = param_dialog.ShowDialog() ?? false;
if (e.InputResult)
e.Options = format.GetOptions (control);
if (busy_state)
SetBusyState();
}
}
}
}