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 //! \date Wed Apr 22 09:52:23 2015
//! \brief AZ system archive implementation. //! \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 // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
@ -28,11 +28,34 @@ using System.Collections.Generic;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.IO; using System.IO;
using GameRes.Compression; using GameRes.Compression;
using GameRes.Formats.Properties;
using GameRes.Formats.Strings; using GameRes.Formats.Strings;
using GameRes.Utility; using GameRes.Utility;
namespace GameRes.Formats.AZSys 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))] [Export(typeof(ArchiveFormat))]
public class ArcOpener : ArchiveFormat public class ArcOpener : ArchiveFormat
{ {
@ -47,6 +70,14 @@ namespace GameRes.Formats.AZSys
Extensions = new string[] { "arc" }; 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) public override ArcFile TryOpen (ArcView file)
{ {
int ext_count = file.View.ReadInt32 (4); int ext_count = file.View.ReadInt32 (4);
@ -65,6 +96,7 @@ namespace GameRes.Formats.AZSys
var reader = new IndexReader (packed_index, count); var reader = new IndexReader (packed_index, count);
var index = reader.Unpack(); var index = reader.Unpack();
int index_offset = 0; int index_offset = 0;
bool contains_scripts = false;
var dir = new List<Entry> (count); var dir = new List<Entry> (count);
for (int i = 0; i < count; ++i) 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.Offset = base_offset + LittleEndian.ToUInt32 (index, index_offset);
entry.Size = LittleEndian.ToUInt32 (index, index_offset + 4); entry.Size = LittleEndian.ToUInt32 (index, index_offset + 4);
if (entry.CheckPlacement (file.MaxOffset)) if (entry.CheckPlacement (file.MaxOffset))
{
dir.Add (entry); dir.Add (entry);
contains_scripts = contains_scripts || name.EndsWith (".asb", StringComparison.InvariantCultureIgnoreCase);
}
} }
index_offset += 0x40; index_offset += 0x40;
} }
if (0 == dir.Count) if (0 == dir.Count)
return null; 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) public override Stream OpenEntry (ArcFile arc, Entry entry)
{ {
if (entry.Size < 20 var azarc = arc as AsbArchive;
|| !entry.Name.EndsWith (".asb", StringComparison.InvariantCultureIgnoreCase) if (null == azarc || entry.Size < 20
|| !arc.File.View.AsciiEqual (entry.Offset, "ASB\x1a")) || !arc.File.View.AsciiEqual (entry.Offset, "ASB\x1a"))
return arc.File.CreateStream (entry.Offset, entry.Size); return arc.File.CreateStream (entry.Offset, entry.Size);
uint packed = arc.File.View.ReadUInt32 (entry.Offset+4); uint packed = arc.File.View.ReadUInt32 (entry.Offset+4);
@ -97,7 +135,7 @@ namespace GameRes.Formats.AZSys
if (12 + packed != entry.Size) if (12 + packed != entry.Size)
return arc.File.CreateStream (entry.Offset, 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; key ^= ((key << 12) | key) << 11;
uint first = arc.File.View.ReadUInt16 (entry.Offset+16); 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); 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 internal class IndexReader
{ {
byte[] m_input; 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="Ankh\ArcGRP.cs" />
<Compile Include="ArcCG.cs" /> <Compile Include="ArcCG.cs" />
<Compile Include="ArcZIP.cs" /> <Compile Include="ArcZIP.cs" />
<Compile Include="AZSys\WidgetAZ.xaml.cs">
<DependentUpon>WidgetAZ.xaml</DependentUpon>
</Compile>
<Compile Include="CommonStreams.cs" /> <Compile Include="CommonStreams.cs" />
<Compile Include="Cri\ArcCPK.cs" /> <Compile Include="Cri\ArcCPK.cs" />
<Compile Include="Cri\ArcSPC.cs" /> <Compile Include="Cri\ArcSPC.cs" />
@ -489,6 +492,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="AZSys\WidgetAZ.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="CatSystem\CreateINTWidget.xaml"> <Page Include="CatSystem\CreateINTWidget.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@ -501,5 +501,17 @@ namespace GameRes.Formats.Properties {
this["ZIPEncodingCP"] = value; 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"> <Setting Name="ZIPEncodingCP" Type="System.Int32" Scope="User">
<Value Profile="(Default)">932</Value> <Value Profile="(Default)">932</Value>
</Setting> </Setting>
<Setting Name="AZScriptScheme" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>

View File

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