added GUI widget for encrypted ASB scripts.

This commit is contained in:
morkt 2016-04-20 17:52:23 +04:00
parent 65459934b2
commit 0daf668703
7 changed files with 114 additions and 7 deletions

View File

@ -2,7 +2,7 @@
//! \date Wed Apr 22 09:52:23 2015
//! \brief AZ system archive implementation.
//
// Copyright (C) 2015 by morkt
// Copyright (C) 2015-2016 by morkt
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
@ -28,11 +28,34 @@ using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using GameRes.Compression;
using GameRes.Formats.Properties;
using GameRes.Formats.Strings;
using GameRes.Utility;
namespace GameRes.Formats.AZSys
{
[Serializable]
public class AsbScheme : ResourceScheme
{
public Dictionary<string, uint> KnownKeys;
}
internal class AsbOptions : ResourceOptions
{
public uint AsbKey;
}
internal class AsbArchive : ArcFile
{
public readonly uint Key;
public AsbArchive (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, uint key)
: base (arc, impl, dir)
{
Key = key;
}
}
[Export(typeof(ArchiveFormat))]
public class ArcOpener : ArchiveFormat
{
@ -47,6 +70,14 @@ namespace GameRes.Formats.AZSys
Extensions = new string[] { "arc" };
}
public static Dictionary<string, uint> KnownKeys = new Dictionary<string, uint>();
public override ResourceScheme Scheme
{
get { return new AsbScheme { KnownKeys = KnownKeys }; }
set { KnownKeys = ((AsbScheme)value).KnownKeys; }
}
public override ArcFile TryOpen (ArcView file)
{
int ext_count = file.View.ReadInt32 (4);
@ -65,6 +96,7 @@ namespace GameRes.Formats.AZSys
var reader = new IndexReader (packed_index, count);
var index = reader.Unpack();
int index_offset = 0;
bool contains_scripts = false;
var dir = new List<Entry> (count);
for (int i = 0; i < count; ++i)
{
@ -75,21 +107,27 @@ namespace GameRes.Formats.AZSys
entry.Offset = base_offset + LittleEndian.ToUInt32 (index, index_offset);
entry.Size = LittleEndian.ToUInt32 (index, index_offset + 4);
if (entry.CheckPlacement (file.MaxOffset))
{
dir.Add (entry);
contains_scripts = contains_scripts || name.EndsWith (".asb", StringComparison.InvariantCultureIgnoreCase);
}
}
index_offset += 0x40;
}
if (0 == dir.Count)
return null;
return new ArcFile (file, this, dir);
if (!contains_scripts || 0 == KnownKeys.Count)
return new ArcFile (file, this, dir);
var options = Query<AsbOptions> (arcStrings.ArcEncryptedNotice);
if (0 == options.AsbKey)
return new ArcFile (file, this, dir);
return new AsbArchive (file, this, dir, options.AsbKey);
}
static readonly uint[] KnownKeys = new uint[] { 0x1de71cb9 }; // Triptych
public override Stream OpenEntry (ArcFile arc, Entry entry)
{
if (entry.Size < 20
|| !entry.Name.EndsWith (".asb", StringComparison.InvariantCultureIgnoreCase)
var azarc = arc as AsbArchive;
if (null == azarc || entry.Size < 20
|| !arc.File.View.AsciiEqual (entry.Offset, "ASB\x1a"))
return arc.File.CreateStream (entry.Offset, entry.Size);
uint packed = arc.File.View.ReadUInt32 (entry.Offset+4);
@ -97,7 +135,7 @@ namespace GameRes.Formats.AZSys
if (12 + packed != entry.Size)
return arc.File.CreateStream (entry.Offset, entry.Size);
uint key = KnownKeys[0] ^ unpacked;
uint key = azarc.Key ^ unpacked;
key ^= ((key << 12) | key) << 11;
uint first = arc.File.View.ReadUInt16 (entry.Offset+16);
@ -121,6 +159,24 @@ namespace GameRes.Formats.AZSys
return new ZLibStream (new MemoryStream (input, 4, input.Length-4), CompressionMode.Decompress);
}
public override ResourceOptions GetDefaultOptions ()
{
return new AsbOptions { AsbKey = GetAsbKey (Settings.Default.AZScriptScheme) };
}
public override object GetAccessWidget ()
{
return new GUI.WidgetAZ();
}
uint GetAsbKey (string scheme)
{
uint key;
if (KnownKeys.TryGetValue (scheme, out key))
return key;
return 0;
}
internal class IndexReader
{
byte[] m_input;

View File

@ -0,0 +1,7 @@
<StackPanel x:Class="GameRes.Formats.GUI.WidgetAZ"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:p="clr-namespace:GameRes.Formats.Properties">
<ComboBox Name="Scheme" Width="180" ItemsSource="{Binding}"
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=AZScheme, Mode=TwoWay}"/>
</StackPanel>

View File

@ -0,0 +1,19 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using GameRes.Formats.AZSys;
namespace GameRes.Formats.GUI
{
/// <summary>
/// Interaction logic for WidgetAZ.xaml
/// </summary>
public partial class WidgetAZ : StackPanel
{
public WidgetAZ()
{
InitializeComponent();
Scheme.ItemsSource = ArcOpener.KnownKeys.Keys.OrderBy (x => x);
}
}
}

View File

@ -68,6 +68,9 @@
<Compile Include="Ankh\ArcGRP.cs" />
<Compile Include="ArcCG.cs" />
<Compile Include="ArcZIP.cs" />
<Compile Include="AZSys\WidgetAZ.xaml.cs">
<DependentUpon>WidgetAZ.xaml</DependentUpon>
</Compile>
<Compile Include="CommonStreams.cs" />
<Compile Include="Cri\ArcCPK.cs" />
<Compile Include="Cri\ArcSPC.cs" />
@ -489,6 +492,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="AZSys\WidgetAZ.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="CatSystem\CreateINTWidget.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -501,5 +501,17 @@ namespace GameRes.Formats.Properties {
this["ZIPEncodingCP"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string AZScriptScheme {
get {
return ((string)(this["AZScriptScheme"]));
}
set {
this["AZScriptScheme"] = value;
}
}
}
}

View File

@ -122,5 +122,8 @@
<Setting Name="ZIPEncodingCP" Type="System.Int32" Scope="User">
<Value Profile="(Default)">932</Value>
</Setting>
<Setting Name="AZScriptScheme" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>

View File

@ -124,6 +124,9 @@
<setting name="ZIPEncodingCP" serializeAs="String">
<value>932</value>
</setting>
<setting name="AZScriptScheme" serializeAs="String">
<value />
</setting>
</GameRes.Formats.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>