mirror of
https://github.com/lifegpc/GARbro.git
synced 2026-06-06 05:28:49 +08:00
Add Musica PAZ Writer (Not works)
This commit is contained in:
@@ -537,6 +537,9 @@
|
|||||||
<Compile Include="Morning\ArcTTD.cs" />
|
<Compile Include="Morning\ArcTTD.cs" />
|
||||||
<Compile Include="Musica\ArcPAZ.cs" />
|
<Compile Include="Musica\ArcPAZ.cs" />
|
||||||
<Compile Include="Musica\ArcSQZ.cs" />
|
<Compile Include="Musica\ArcSQZ.cs" />
|
||||||
|
<Compile Include="Musica\CreatePAZWidget.xaml.cs">
|
||||||
|
<DependentUpon>CreatePAZWidget.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Musica\WidgetPAZ.xaml.cs">
|
<Compile Include="Musica\WidgetPAZ.xaml.cs">
|
||||||
<DependentUpon>WidgetPAZ.xaml</DependentUpon>
|
<DependentUpon>WidgetPAZ.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -1138,6 +1141,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="Musica\CreatePAZWidget.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Musica\WidgetPAZ.xaml">
|
<Page Include="Musica\WidgetPAZ.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using GameRes.Compression;
|
using GameRes.Compression;
|
||||||
using GameRes.Cryptography;
|
using GameRes.Cryptography;
|
||||||
using GameRes.Formats.Strings;
|
using GameRes.Formats.Strings;
|
||||||
@@ -133,7 +134,7 @@ namespace GameRes.Formats.Musica
|
|||||||
public override string Description { get { return "Musica engine resource archive"; } }
|
public override string Description { get { return "Musica engine resource archive"; } }
|
||||||
public override uint Signature { get { return 0; } }
|
public override uint Signature { get { return 0; } }
|
||||||
public override bool IsHierarchic { get { return true; } }
|
public override bool IsHierarchic { get { return true; } }
|
||||||
public override bool CanWrite { get { return false; } }
|
public override bool CanWrite { get { return true; } }
|
||||||
|
|
||||||
public PazOpener ()
|
public PazOpener ()
|
||||||
{
|
{
|
||||||
@@ -319,7 +320,44 @@ namespace GameRes.Formats.Musica
|
|||||||
|
|
||||||
public override ResourceOptions GetDefaultOptions ()
|
public override ResourceOptions GetDefaultOptions ()
|
||||||
{
|
{
|
||||||
return new PazOptions { Scheme = GetScheme (Properties.Settings.Default.PAZTitle) };
|
return new PazOptions {
|
||||||
|
Scheme = GetScheme (Properties.Settings.Default.PAZTitle),
|
||||||
|
ArcName = Properties.Settings.Default.PAZArchiveKey,
|
||||||
|
CompressContents = Properties.Settings.Default.PAZCompressContents,
|
||||||
|
RetainDirs = Properties.Settings.Default.PAZRetainStructure,
|
||||||
|
Signature = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ResourceOptions GetOptions (object widget)
|
||||||
|
{
|
||||||
|
var create = widget as GUI.CreatePAZWidget;
|
||||||
|
if (null == create)
|
||||||
|
return base.GetDefaultOptions ();
|
||||||
|
|
||||||
|
string title = create.SelectedTitle ?? string.Empty;
|
||||||
|
string archive = create.SelectedArchive ?? string.Empty;
|
||||||
|
bool compress = create.CompressContents;
|
||||||
|
bool retain = create.RetainStructure;
|
||||||
|
|
||||||
|
Properties.Settings.Default.PAZTitle = title;
|
||||||
|
Properties.Settings.Default.PAZArchiveKey = archive;
|
||||||
|
Properties.Settings.Default.PAZCompressContents = compress;
|
||||||
|
Properties.Settings.Default.PAZRetainStructure = retain;
|
||||||
|
|
||||||
|
var options = new PazOptions {
|
||||||
|
Scheme = GetScheme (title),
|
||||||
|
ArcName = archive,
|
||||||
|
CompressContents = compress,
|
||||||
|
RetainDirs = retain,
|
||||||
|
Signature = 0,
|
||||||
|
};
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object GetCreationWidget ()
|
||||||
|
{
|
||||||
|
return new GUI.CreatePAZWidget (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object GetAccessWidget ()
|
public override object GetAccessWidget ()
|
||||||
@@ -327,6 +365,312 @@ namespace GameRes.Formats.Musica
|
|||||||
return new GUI.WidgetPAZ (this);
|
return new GUI.WidgetPAZ (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Create (Stream output, IEnumerable<Entry> list, ResourceOptions options,
|
||||||
|
EntryCallback callback)
|
||||||
|
{
|
||||||
|
if (null == output)
|
||||||
|
throw new ArgumentNullException ("output");
|
||||||
|
|
||||||
|
var paz_options = GetOptions<PazOptions> (options);
|
||||||
|
var scheme = paz_options.Scheme;
|
||||||
|
string arc_name = paz_options.ArcName ?? string.Empty;
|
||||||
|
PazKey keys = null;
|
||||||
|
|
||||||
|
bool use_crypto = scheme != null;
|
||||||
|
if (use_crypto)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty (arc_name))
|
||||||
|
throw new InvalidOperationException ("Archive key is not specified.");
|
||||||
|
arc_name = arc_name.ToLowerInvariant ();
|
||||||
|
if (null == scheme.ArcKeys || !scheme.ArcKeys.TryGetValue (arc_name, out keys))
|
||||||
|
throw new InvalidOperationException (string.Format ("Unknown archive key '{0}'.", arc_name));
|
||||||
|
if (VideoPazNames.Contains (arc_name))
|
||||||
|
throw new NotSupportedException ("Creation of MOV PAZ archives is not supported.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arc_name = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_audio = use_crypto && AudioPazNames.Contains (arc_name);
|
||||||
|
bool retain_dirs = paz_options.RetainDirs;
|
||||||
|
bool compress_contents = paz_options.CompressContents;
|
||||||
|
byte xor_key = 0;
|
||||||
|
|
||||||
|
var encoding = Encodings.cp932.WithFatalFallback ();
|
||||||
|
var data_key = use_crypto ? keys.DataKey : null;
|
||||||
|
var index_key = use_crypto ? keys.IndexKey : null;
|
||||||
|
int version = scheme != null ? scheme.Version : 0;
|
||||||
|
|
||||||
|
var entries = new List<PazCreateEntry>();
|
||||||
|
var used_names = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
|
||||||
|
string temp_path = Path.GetTempFileName ();
|
||||||
|
long data_offset = 0;
|
||||||
|
int callback_index = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var data_stream = new FileStream (temp_path, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
|
||||||
|
{
|
||||||
|
foreach (var entry in list)
|
||||||
|
{
|
||||||
|
string stored_name = retain_dirs ? entry.Name.Replace ("\\", "/") : Path.GetFileName (entry.Name);
|
||||||
|
if (string.IsNullOrWhiteSpace (stored_name))
|
||||||
|
continue;
|
||||||
|
if (!used_names.Add (stored_name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (null != callback)
|
||||||
|
callback (callback_index++, entry, arcStrings.MsgAddingFile);
|
||||||
|
|
||||||
|
var created = CreateEntryData (entry, stored_name, data_stream, ref data_offset,
|
||||||
|
compress_contents, is_audio, scheme, data_key, xor_key, encoding);
|
||||||
|
entries.Add (created);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null != callback)
|
||||||
|
callback (callback_index++, null, arcStrings.MsgWritingIndex);
|
||||||
|
|
||||||
|
long plain_index_size = CalculateIndexPlainSize (entries);
|
||||||
|
int aligned_index_size = (int)((plain_index_size + 7) & ~7);
|
||||||
|
uint index_size = (uint)aligned_index_size;
|
||||||
|
uint start_offset = version > 0 ? 0x20u : 0u;
|
||||||
|
long data_start = start_offset + 4 + aligned_index_size;
|
||||||
|
|
||||||
|
foreach (var item in entries)
|
||||||
|
item.Offset = data_start + item.DataOffset;
|
||||||
|
|
||||||
|
var index_buffer = BuildIndexBuffer (entries, aligned_index_size, index_key, xor_key);
|
||||||
|
uint stored_index_size = EncodeIndexSize (index_size, xor_key);
|
||||||
|
|
||||||
|
uint signature = version > 0 ? ResolveSignature (scheme, paz_options.Signature) : 0u;
|
||||||
|
|
||||||
|
output.Position = 0;
|
||||||
|
using (var writer = new BinaryWriter (output, Encoding.ASCII, true))
|
||||||
|
{
|
||||||
|
if (start_offset != 0)
|
||||||
|
{
|
||||||
|
writer.Write (signature);
|
||||||
|
if (start_offset > 4)
|
||||||
|
writer.Write (new byte[start_offset - 4]);
|
||||||
|
}
|
||||||
|
writer.Write (stored_index_size);
|
||||||
|
writer.Write (index_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
output.Position = data_start;
|
||||||
|
using (var data_stream = new FileStream (temp_path, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
|
{
|
||||||
|
data_stream.CopyTo (output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try { File.Delete (temp_path); } catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static long CalculateIndexPlainSize (IList<PazCreateEntry> entries)
|
||||||
|
{
|
||||||
|
long size = 4;
|
||||||
|
foreach (var entry in entries)
|
||||||
|
size += entry.NameBytes.Length + 1 + 8 + 4 + 4 + 4 + 4;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] BuildIndexBuffer (IList<PazCreateEntry> entries, int aligned_size, byte[] index_key, byte xor_key)
|
||||||
|
{
|
||||||
|
var index_stream = new MemoryStream (Math.Max (aligned_size, 8));
|
||||||
|
using (var writer = new BinaryWriter (index_stream, Encoding.ASCII, true))
|
||||||
|
{
|
||||||
|
writer.Write (entries.Count);
|
||||||
|
foreach (var entry in entries)
|
||||||
|
{
|
||||||
|
writer.Write (entry.NameBytes);
|
||||||
|
writer.Write ((byte)0);
|
||||||
|
writer.Write (entry.Offset);
|
||||||
|
writer.Write (entry.UnpackedSize);
|
||||||
|
writer.Write (entry.Size);
|
||||||
|
writer.Write (entry.AlignedSize);
|
||||||
|
writer.Write (entry.IsPacked ? 1 : 0);
|
||||||
|
}
|
||||||
|
writer.Flush ();
|
||||||
|
}
|
||||||
|
if (index_stream.Length < aligned_size)
|
||||||
|
index_stream.SetLength (aligned_size);
|
||||||
|
var buffer = index_stream.ToArray ();
|
||||||
|
if (buffer.Length > 0 && null != index_key)
|
||||||
|
{
|
||||||
|
var crypto = new Blowfish (index_key);
|
||||||
|
crypto.Encipher (buffer, buffer.Length);
|
||||||
|
}
|
||||||
|
if (xor_key != 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < buffer.Length; ++i)
|
||||||
|
buffer[i] ^= xor_key;
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint EncodeIndexSize (uint index_size, byte xor_key)
|
||||||
|
{
|
||||||
|
if (0 == xor_key)
|
||||||
|
return index_size;
|
||||||
|
uint mask = (uint)(xor_key << 24 | xor_key << 16 | xor_key << 8 | xor_key);
|
||||||
|
return index_size ^ mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint ResolveSignature (PazScheme scheme, uint explicit_value)
|
||||||
|
{
|
||||||
|
if (explicit_value != 0)
|
||||||
|
return explicit_value;
|
||||||
|
foreach (var pair in KnownSchemes)
|
||||||
|
{
|
||||||
|
if (object.ReferenceEquals (pair.Value, scheme))
|
||||||
|
return pair.Key;
|
||||||
|
}
|
||||||
|
return 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
PazCreateEntry CreateEntryData (Entry entry, string stored_name, FileStream data_stream, ref long data_offset,
|
||||||
|
bool compress_contents, bool is_audio, PazScheme scheme, byte[] data_key,
|
||||||
|
byte xor_key, Encoding encoding)
|
||||||
|
{
|
||||||
|
string file_path = entry.Name;
|
||||||
|
using (var input = File.Open (file_path, FileMode.Open, FileAccess.Read))
|
||||||
|
{
|
||||||
|
long file_length = input.Length;
|
||||||
|
if (file_length < 0 || file_length > uint.MaxValue)
|
||||||
|
throw new FileSizeException (entry.Name);
|
||||||
|
if (file_length > int.MaxValue)
|
||||||
|
throw new FileSizeException (entry.Name);
|
||||||
|
|
||||||
|
var raw = new byte[file_length];
|
||||||
|
int read = 0;
|
||||||
|
while (read < raw.Length)
|
||||||
|
{
|
||||||
|
int chunk = input.Read (raw, read, raw.Length - read);
|
||||||
|
if (0 == chunk)
|
||||||
|
break;
|
||||||
|
read += chunk;
|
||||||
|
}
|
||||||
|
if (read != raw.Length)
|
||||||
|
throw new EndOfStreamException (entry.Name);
|
||||||
|
|
||||||
|
bool should_compress = compress_contents && ShouldCompressFile (entry) && raw.Length > 0;
|
||||||
|
byte[] payload = raw;
|
||||||
|
bool is_packed = false;
|
||||||
|
if (should_compress)
|
||||||
|
{
|
||||||
|
using (var packed_stream = new MemoryStream (raw.Length))
|
||||||
|
{
|
||||||
|
using (var zstream = new ZLibStream (packed_stream, CompressionMode.Compress, CompressionLevel.Level9, true))
|
||||||
|
{
|
||||||
|
zstream.Write (raw, 0, raw.Length);
|
||||||
|
}
|
||||||
|
var packed = packed_stream.ToArray ();
|
||||||
|
if (packed.Length < raw.Length)
|
||||||
|
{
|
||||||
|
payload = packed;
|
||||||
|
is_packed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = new PazCreateEntry ();
|
||||||
|
info.Name = stored_name;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
info.NameBytes = encoding.GetBytes (stored_name);
|
||||||
|
}
|
||||||
|
catch (EncoderFallbackException X)
|
||||||
|
{
|
||||||
|
throw new InvalidFileName (stored_name, arcStrings.MsgIllegalCharacters, X);
|
||||||
|
}
|
||||||
|
|
||||||
|
info.UnpackedSize = (uint)raw.Length;
|
||||||
|
info.Size = (uint)payload.Length;
|
||||||
|
info.IsPacked = is_packed;
|
||||||
|
|
||||||
|
byte[] aligned;
|
||||||
|
if (0 == (payload.Length & 7))
|
||||||
|
{
|
||||||
|
aligned = (byte[])payload.Clone ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int aligned_size = (payload.Length + 7) & ~7;
|
||||||
|
aligned = new byte[aligned_size];
|
||||||
|
Buffer.BlockCopy (payload, 0, aligned, 0, payload.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int version = scheme != null ? scheme.Version : 0;
|
||||||
|
if (version > 0)
|
||||||
|
{
|
||||||
|
string password = string.Empty;
|
||||||
|
if (!is_packed && scheme != null && scheme.TypeKeys != null)
|
||||||
|
password = scheme.GetTypePassword (stored_name, is_audio);
|
||||||
|
if (!string.IsNullOrEmpty (password))
|
||||||
|
{
|
||||||
|
string key_string = string.Format ("{0} {1:X08} {2}", stored_name.ToLowerInvariant(), info.UnpackedSize, password);
|
||||||
|
var key_bytes = Encodings.cp932.GetBytes (key_string);
|
||||||
|
var rc4 = new Rc4Transform (key_bytes);
|
||||||
|
if (version >= 2)
|
||||||
|
{
|
||||||
|
uint crc = Crc32.Compute (key_bytes, 0, key_bytes.Length);
|
||||||
|
int skip = (int)(crc >> 12) & 0xFF;
|
||||||
|
for (int i = 0; i < skip; ++i)
|
||||||
|
rc4.NextByte ();
|
||||||
|
}
|
||||||
|
rc4.TransformBlock (aligned, 0, payload.Length, aligned, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aligned.Length > 0 && null != data_key)
|
||||||
|
{
|
||||||
|
var crypto = new Blowfish (data_key);
|
||||||
|
crypto.Encipher (aligned, aligned.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xor_key != 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < aligned.Length; ++i)
|
||||||
|
aligned[i] ^= xor_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.AlignedSize = (uint)aligned.Length;
|
||||||
|
info.DataOffset = data_offset;
|
||||||
|
|
||||||
|
data_stream.Position = data_offset;
|
||||||
|
data_stream.Write (aligned, 0, aligned.Length);
|
||||||
|
data_offset += aligned.Length;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShouldCompressFile (Entry entry)
|
||||||
|
{
|
||||||
|
if ("image" == entry.Type || "archive" == entry.Type)
|
||||||
|
return false;
|
||||||
|
if (entry.Name.HasExtension (".ogg"))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PazCreateEntry
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public byte[] NameBytes;
|
||||||
|
public long DataOffset;
|
||||||
|
public long Offset;
|
||||||
|
public uint UnpackedSize;
|
||||||
|
public uint Size;
|
||||||
|
public uint AlignedSize;
|
||||||
|
public bool IsPacked;
|
||||||
|
}
|
||||||
|
|
||||||
PazScheme GetScheme (string title)
|
PazScheme GetScheme (string title)
|
||||||
{
|
{
|
||||||
PazScheme scheme;
|
PazScheme scheme;
|
||||||
@@ -395,5 +739,9 @@ namespace GameRes.Formats.Musica
|
|||||||
public class PazOptions : ResourceOptions
|
public class PazOptions : ResourceOptions
|
||||||
{
|
{
|
||||||
public PazScheme Scheme;
|
public PazScheme Scheme;
|
||||||
|
public string ArcName;
|
||||||
|
public bool CompressContents;
|
||||||
|
public bool RetainDirs;
|
||||||
|
public uint Signature;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
26
ArcFormats/Musica/CreatePAZWidget.xaml
Normal file
26
ArcFormats/Musica/CreatePAZWidget.xaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<Grid x:Class="GameRes.Formats.GUI.CreatePAZWidget"
|
||||||
|
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">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,5">
|
||||||
|
<StackPanel Orientation="Vertical" Margin="0,0,10,0">
|
||||||
|
<Label Content="Title" Target="{Binding ElementName=Title}" Padding="4,0,0,5"/>
|
||||||
|
<ComboBox Name="Title" Width="200"
|
||||||
|
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=PAZTitle, Mode=TwoWay}"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<Label Content="Archive key" Target="{Binding ElementName=Archive}" Padding="4,0,0,5"/>
|
||||||
|
<ComboBox Name="Archive" Width="180"
|
||||||
|
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=PAZArchiveKey, Mode=TwoWay}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
<CheckBox Grid.Row="1" Name="Compress" Content="Compress contents" Margin="0,0,0,5"
|
||||||
|
IsChecked="{Binding Source={x:Static p:Settings.Default}, Path=PAZCompressContents, Mode=TwoWay}"/>
|
||||||
|
<CheckBox Grid.Row="2" Name="Retain" Content="Retain folder structure"
|
||||||
|
IsChecked="{Binding Source={x:Static p:Settings.Default}, Path=PAZRetainStructure, Mode=TwoWay}"/>
|
||||||
|
</Grid>
|
||||||
94
ArcFormats/Musica/CreatePAZWidget.xaml.cs
Normal file
94
ArcFormats/Musica/CreatePAZWidget.xaml.cs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using GameRes.Formats.Musica;
|
||||||
|
using GameRes.Formats.Properties;
|
||||||
|
using GameRes.Formats.Strings;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.GUI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for CreatePAZWidget.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class CreatePAZWidget : Grid
|
||||||
|
{
|
||||||
|
readonly PazOpener m_paz;
|
||||||
|
|
||||||
|
public CreatePAZWidget (PazOpener paz)
|
||||||
|
{
|
||||||
|
m_paz = paz;
|
||||||
|
InitializeComponent ();
|
||||||
|
Title.SelectionChanged += TitleSelectionChanged;
|
||||||
|
PopulateTitles ();
|
||||||
|
UpdateArchiveList ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopulateTitles ()
|
||||||
|
{
|
||||||
|
var titles = new List<string> { arcStrings.ArcNoEncryption };
|
||||||
|
titles.AddRange (m_paz.KnownTitles.Keys.OrderBy (x => x));
|
||||||
|
Title.ItemsSource = titles;
|
||||||
|
string saved_title = Settings.Default.PAZTitle;
|
||||||
|
if (!string.IsNullOrEmpty (saved_title) && titles.Contains (saved_title))
|
||||||
|
Title.SelectedValue = saved_title;
|
||||||
|
else if (titles.Count > 0)
|
||||||
|
Title.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TitleSelectionChanged (object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
UpdateArchiveList ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateArchiveList ()
|
||||||
|
{
|
||||||
|
string title = Title.SelectedValue as string;
|
||||||
|
PazScheme scheme = null;
|
||||||
|
if (!string.IsNullOrEmpty (title))
|
||||||
|
m_paz.KnownTitles.TryGetValue (title, out scheme);
|
||||||
|
|
||||||
|
List<string> arc_keys = (scheme != null && scheme.ArcKeys != null)
|
||||||
|
? scheme.ArcKeys.Keys.OrderBy (x => x).ToList ()
|
||||||
|
: new List<string> ();
|
||||||
|
|
||||||
|
Archive.ItemsSource = arc_keys;
|
||||||
|
string saved_key = Settings.Default.PAZArchiveKey;
|
||||||
|
if (!string.IsNullOrEmpty (saved_key) && arc_keys.Contains (saved_key))
|
||||||
|
Archive.SelectedValue = saved_key;
|
||||||
|
else if (arc_keys.Count > 0)
|
||||||
|
Archive.SelectedIndex = 0;
|
||||||
|
else
|
||||||
|
Archive.Text = scheme != null ? (saved_key ?? string.Empty) : string.Empty;
|
||||||
|
|
||||||
|
Archive.IsEnabled = scheme != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SelectedTitle
|
||||||
|
{
|
||||||
|
get { return Title.SelectedValue as string ?? Title.Text; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SelectedArchive
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Archive.IsEnabled)
|
||||||
|
return string.Empty;
|
||||||
|
var selected = Archive.SelectedValue as string;
|
||||||
|
if (!string.IsNullOrEmpty (selected))
|
||||||
|
return selected;
|
||||||
|
return Archive.Text ?? string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CompressContents
|
||||||
|
{
|
||||||
|
get { return Compress.IsChecked ?? false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RetainStructure
|
||||||
|
{
|
||||||
|
get { return Retain.IsChecked ?? false; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
ArcFormats/Properties/Settings.Designer.cs
generated
36
ArcFormats/Properties/Settings.Designer.cs
generated
@@ -646,6 +646,42 @@ namespace GameRes.Formats.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||||
|
public string PAZArchiveKey {
|
||||||
|
get {
|
||||||
|
return ((string)(this["PAZArchiveKey"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["PAZArchiveKey"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||||
|
public bool PAZCompressContents {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["PAZCompressContents"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["PAZCompressContents"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||||
|
public bool PAZRetainStructure {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["PAZRetainStructure"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["PAZRetainStructure"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||||
|
|||||||
@@ -158,6 +158,15 @@
|
|||||||
<Setting Name="PAZTitle" Type="System.String" Scope="User">
|
<Setting Name="PAZTitle" Type="System.String" Scope="User">
|
||||||
<Value Profile="(Default)" />
|
<Value Profile="(Default)" />
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="PAZArchiveKey" Type="System.String" Scope="User">
|
||||||
|
<Value Profile="(Default)" />
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="PAZCompressContents" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">False</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="PAZRetainStructure" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">True</Value>
|
||||||
|
</Setting>
|
||||||
<Setting Name="EAGLSEncryption" Type="System.String" Scope="User">
|
<Setting Name="EAGLSEncryption" Type="System.String" Scope="User">
|
||||||
<Value Profile="(Default)" />
|
<Value Profile="(Default)" />
|
||||||
</Setting>
|
</Setting>
|
||||||
|
|||||||
@@ -160,6 +160,15 @@
|
|||||||
<setting name="PAZTitle" serializeAs="String">
|
<setting name="PAZTitle" serializeAs="String">
|
||||||
<value />
|
<value />
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="PAZArchiveKey" serializeAs="String">
|
||||||
|
<value />
|
||||||
|
</setting>
|
||||||
|
<setting name="PAZCompressContents" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="PAZRetainStructure" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
<setting name="EAGLSEncryption" serializeAs="String">
|
<setting name="EAGLSEncryption" serializeAs="String">
|
||||||
<value />
|
<value />
|
||||||
</setting>
|
</setting>
|
||||||
|
|||||||
Reference in New Issue
Block a user