mirror of
https://github.com/crskycode/GARbro.git
synced 2025-01-11 20:39:29 +08:00
implemented Nitro+ archives creation.
encryption not implemented yet.
This commit is contained in:
parent
881a95c165
commit
8697257e79
@ -74,6 +74,9 @@
|
|||||||
<Compile Include="CreateINTWidget.xaml.cs">
|
<Compile Include="CreateINTWidget.xaml.cs">
|
||||||
<DependentUpon>CreateINTWidget.xaml</DependentUpon>
|
<DependentUpon>CreateINTWidget.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="CreateNPAWidget.xaml.cs">
|
||||||
|
<DependentUpon>CreateNPAWidget.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="CreateONSWidget.xaml.cs">
|
<Compile Include="CreateONSWidget.xaml.cs">
|
||||||
<DependentUpon>CreateONSWidget.xaml</DependentUpon>
|
<DependentUpon>CreateONSWidget.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -153,6 +156,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="CreateNPAWidget.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="CreateONSWidget.xaml">
|
<Page Include="CreateONSWidget.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@ -32,11 +34,12 @@ using ZLibNet;
|
|||||||
using GameRes.Formats.Strings;
|
using GameRes.Formats.Strings;
|
||||||
using GameRes.Formats.Properties;
|
using GameRes.Formats.Properties;
|
||||||
|
|
||||||
namespace GameRes.Formats
|
namespace GameRes.Formats.NitroPlus
|
||||||
{
|
{
|
||||||
internal class NpaEntry : PackedEntry
|
internal class NpaEntry : PackedEntry
|
||||||
{
|
{
|
||||||
public byte[] RawName;
|
public byte[] RawName;
|
||||||
|
public int FolderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class NpaArchive : ArcFile
|
internal class NpaArchive : ArcFile
|
||||||
@ -68,6 +71,9 @@ namespace GameRes.Formats
|
|||||||
public class NpaOptions : ResourceOptions
|
public class NpaOptions : ResourceOptions
|
||||||
{
|
{
|
||||||
public NpaTitleId TitleId { get; set; }
|
public NpaTitleId TitleId { get; set; }
|
||||||
|
public bool CompressContents { get; set; }
|
||||||
|
public int Key1 { get; set; }
|
||||||
|
public int Key2 { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Export(typeof(ArchiveFormat))]
|
[Export(typeof(ArchiveFormat))]
|
||||||
@ -77,8 +83,12 @@ namespace GameRes.Formats
|
|||||||
public override string Description { get { return arcStrings.NPADescription; } }
|
public override string Description { get { return arcStrings.NPADescription; } }
|
||||||
public override uint Signature { get { return 0x0141504e; } } // NPA\x01
|
public override uint Signature { get { return 0x0141504e; } } // NPA\x01
|
||||||
public override bool IsHierarchic { get { return true; } }
|
public override bool IsHierarchic { get { return true; } }
|
||||||
|
public override bool CanCreate { get { return true; } }
|
||||||
|
|
||||||
/// <summary>Known encryption schemes.</summary>
|
/// <summary>
|
||||||
|
/// Known encryption schemes.
|
||||||
|
/// Order should match NpaTitleId enumeration.
|
||||||
|
/// </summary>
|
||||||
public static readonly string[] KnownSchemes = new string[] {
|
public static readonly string[] KnownSchemes = new string[] {
|
||||||
arcStrings.ArcNoEncryption,
|
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",
|
||||||
@ -89,6 +99,9 @@ namespace GameRes.Formats
|
|||||||
"Kimi to Kanojo to Kanojo no Koi", "Phenomeno", "Nekoda -Nyanda-",
|
"Kimi to Kanojo to Kanojo no Koi", "Phenomeno", "Nekoda -Nyanda-",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public const int DefaultKey1 = 0x4147414e;
|
||||||
|
public const int DefaultKey2 = 0x21214f54;
|
||||||
|
|
||||||
public override ArcFile TryOpen (ArcView file)
|
public override ArcFile TryOpen (ArcView file)
|
||||||
{
|
{
|
||||||
int key1 = file.View.ReadInt32 (7);
|
int key1 = file.View.ReadInt32 (7);
|
||||||
@ -130,7 +143,7 @@ namespace GameRes.Formats
|
|||||||
raw_name[x] += DecryptName (x, i, key);
|
raw_name[x] += DecryptName (x, i, key);
|
||||||
var info_offset = cur_offset + 5 + name_size;
|
var info_offset = cur_offset + 5 + name_size;
|
||||||
|
|
||||||
uint id = file.View.ReadUInt32 (info_offset);
|
int id = file.View.ReadInt32 (info_offset);
|
||||||
uint offset = file.View.ReadUInt32 (info_offset+4);
|
uint offset = file.View.ReadUInt32 (info_offset+4);
|
||||||
uint size = file.View.ReadUInt32 (info_offset+8);
|
uint size = file.View.ReadUInt32 (info_offset+8);
|
||||||
uint unpacked_size = file.View.ReadUInt32 (info_offset+12);
|
uint unpacked_size = file.View.ReadUInt32 (info_offset+12);
|
||||||
@ -140,12 +153,13 @@ namespace GameRes.Formats
|
|||||||
Offset = dir_size+offset+41,
|
Offset = dir_size+offset+41,
|
||||||
Size = size,
|
Size = size,
|
||||||
UnpackedSize = unpacked_size,
|
UnpackedSize = unpacked_size,
|
||||||
IsPacked = compressed,
|
|
||||||
RawName = raw_name,
|
RawName = raw_name,
|
||||||
|
FolderId = id,
|
||||||
};
|
};
|
||||||
if (!entry.CheckPlacement (file.MaxOffset))
|
if (!entry.CheckPlacement (file.MaxOffset))
|
||||||
return null;
|
return null;
|
||||||
entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
|
entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
|
||||||
|
entry.IsPacked = compressed && entry.Type != "image";
|
||||||
dir.Add (entry);
|
dir.Add (entry);
|
||||||
}
|
}
|
||||||
cur_offset += 4 + name_size + 17;
|
cur_offset += 4 + name_size + 17;
|
||||||
@ -156,23 +170,94 @@ namespace GameRes.Formats
|
|||||||
return new ArcFile (file, this, dir);
|
return new ArcFile (file, this, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Create (Stream output, IEnumerable<Entry> list, ResourceOptions options,
|
||||||
|
EntryCallback callback)
|
||||||
|
{
|
||||||
|
var npa_options = GetOptions<NpaOptions> (options);
|
||||||
|
int callback_count = 0;
|
||||||
|
|
||||||
|
// build file index
|
||||||
|
var index = new Indexer (list, npa_options);
|
||||||
|
|
||||||
|
output.Position = 41 + index.Size;
|
||||||
|
long data_offset = 0;
|
||||||
|
|
||||||
|
// write files
|
||||||
|
foreach (var entry in index.Entries.Where (e => e.Type != "directory"))
|
||||||
|
{
|
||||||
|
if (data_offset > uint.MaxValue)
|
||||||
|
throw new FileSizeException();
|
||||||
|
if (null != callback)
|
||||||
|
callback (callback_count++, entry, arcStrings.MsgAddingFile);
|
||||||
|
using (var file = File.OpenRead (entry.Name))
|
||||||
|
{
|
||||||
|
var size = file.Length;
|
||||||
|
if (size > uint.MaxValue)
|
||||||
|
throw new FileSizeException();
|
||||||
|
entry.Offset = data_offset;
|
||||||
|
entry.UnpackedSize = (uint)size;
|
||||||
|
if (entry.IsPacked)
|
||||||
|
{
|
||||||
|
using (var zstream = new ZLibStream (output, CompressionMode.Compress,
|
||||||
|
CompressionLevel.Level9, true))
|
||||||
|
{
|
||||||
|
file.CopyTo (zstream);
|
||||||
|
zstream.Flush();
|
||||||
|
entry.Size = (uint)zstream.TotalOut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file.CopyTo (output);
|
||||||
|
entry.Size = entry.UnpackedSize;
|
||||||
|
}
|
||||||
|
data_offset += entry.Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (null != callback)
|
||||||
|
callback (callback_count++, null, arcStrings.MsgWritingIndex);
|
||||||
|
|
||||||
|
output.Position = 0;
|
||||||
|
using (var header = new BinaryWriter (output, Encoding.ASCII, true))
|
||||||
|
{
|
||||||
|
header.Write (Signature);
|
||||||
|
header.Write ((short)0);
|
||||||
|
header.Write ((byte)0);
|
||||||
|
header.Write (npa_options.Key1);
|
||||||
|
header.Write (npa_options.Key2);
|
||||||
|
header.Write (npa_options.CompressContents);
|
||||||
|
header.Write (npa_options.TitleId != NpaTitleId.NotEncrypted);
|
||||||
|
header.Write (index.TotalCount);
|
||||||
|
header.Write (index.FolderCount);
|
||||||
|
header.Write (index.FileCount);
|
||||||
|
header.Write ((long)0);
|
||||||
|
header.Write (index.Size);
|
||||||
|
foreach (var entry in index.Entries)
|
||||||
|
{
|
||||||
|
header.Write (entry.RawName.Length);
|
||||||
|
header.Write (entry.RawName);
|
||||||
|
header.Write ((byte)("directory" == entry.Type ? 1 : 2));
|
||||||
|
header.Write (entry.FolderId);
|
||||||
|
header.Write ((uint)entry.Offset);
|
||||||
|
header.Write (entry.Size);
|
||||||
|
header.Write (entry.UnpackedSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
{
|
{
|
||||||
if (arc is NpaArchive && entry is NpaEntry)
|
if (arc is NpaArchive && entry is NpaEntry)
|
||||||
return OpenEncryptedEntry (arc as NpaArchive, entry as NpaEntry);
|
return OpenEncryptedEntry (arc as NpaArchive, entry as NpaEntry);
|
||||||
|
|
||||||
var input = arc.File.CreateStream (entry.Offset, entry.Size);
|
var input = arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
return UnpackEntry (input, entry);
|
return UnpackEntry (input, entry as PackedEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream UnpackEntry (Stream input, Entry entry)
|
private Stream UnpackEntry (Stream input, PackedEntry entry)
|
||||||
{
|
{
|
||||||
if (entry.Type != "image")
|
if (null != entry && entry.IsPacked)
|
||||||
{
|
|
||||||
var npa_entry = entry as PackedEntry;
|
|
||||||
if (null != npa_entry && npa_entry.IsPacked)
|
|
||||||
return new ZLibStream (input, CompressionMode.Decompress);
|
return new ZLibStream (input, CompressionMode.Decompress);
|
||||||
}
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +310,7 @@ namespace GameRes.Formats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
byte DecryptName (int index, int curfile, int arc_key)
|
public static byte DecryptName (int index, int curfile, int arc_key)
|
||||||
{
|
{
|
||||||
int key = 0xFC*index;
|
int key = 0xFC*index;
|
||||||
|
|
||||||
@ -242,7 +327,7 @@ namespace GameRes.Formats
|
|||||||
return (byte)(key & 0xff);
|
return (byte)(key & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte GetKeyFromEntry (NpaEntry entry, NpaTitleId game_id, int key2)
|
internal static byte GetKeyFromEntry (NpaEntry entry, NpaTitleId game_id, int key2)
|
||||||
{
|
{
|
||||||
int key1;
|
int key1;
|
||||||
switch (game_id)
|
switch (game_id)
|
||||||
@ -311,19 +396,12 @@ namespace GameRes.Formats
|
|||||||
|
|
||||||
public override ResourceOptions GetDefaultOptions ()
|
public override ResourceOptions GetDefaultOptions ()
|
||||||
{
|
{
|
||||||
return new NpaOptions { TitleId = Settings.Default.NPAScheme };
|
return new NpaOptions {
|
||||||
}
|
TitleId = GetTitleId (Settings.Default.NPAScheme),
|
||||||
|
CompressContents = Settings.Default.NPACompressContents,
|
||||||
public override ResourceOptions GetOptions (object w)
|
Key1 = (int)Settings.Default.NPAKey1,
|
||||||
{
|
Key2 = (int)Settings.Default.NPAKey2,
|
||||||
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 ()
|
||||||
@ -331,6 +409,11 @@ namespace GameRes.Formats
|
|||||||
return new GUI.WidgetNPA();
|
return new GUI.WidgetNPA();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override object GetCreationWidget ()
|
||||||
|
{
|
||||||
|
return new GUI.CreateNPAWidget();
|
||||||
|
}
|
||||||
|
|
||||||
NpaTitleId QueryGameEncryption ()
|
NpaTitleId QueryGameEncryption ()
|
||||||
{
|
{
|
||||||
var options = Query<NpaOptions> (arcStrings.ArcEncryptedNotice);
|
var options = Query<NpaOptions> (arcStrings.ArcEncryptedNotice);
|
||||||
@ -419,4 +502,110 @@ namespace GameRes.Formats
|
|||||||
new byte[] { 0xdc,0xdc,0xec,0xcd,0xdb,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0x1e,0x4e,0x66,0xb6 },
|
new byte[] { 0xdc,0xdc,0xec,0xcd,0xdb,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0xdc,0x1e,0x4e,0x66,0xb6 },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Archive creation helper.
|
||||||
|
/// </summary>
|
||||||
|
internal class Indexer
|
||||||
|
{
|
||||||
|
List<NpaEntry> m_entries;
|
||||||
|
Encoding m_encoding = Encodings.cp932.WithFatalFallback();
|
||||||
|
int m_key;
|
||||||
|
int m_size = 0;
|
||||||
|
int m_directory_count = 0;
|
||||||
|
int m_file_count = 0;
|
||||||
|
|
||||||
|
public IEnumerable<NpaEntry> Entries { get { return m_entries; } }
|
||||||
|
|
||||||
|
public int Key { get { return m_key; } }
|
||||||
|
public int Size { get { return m_size; } }
|
||||||
|
public int TotalCount { get { return m_entries.Count; } }
|
||||||
|
public int FolderCount { get { return m_directory_count; } }
|
||||||
|
public int FileCount { get { return m_file_count; } }
|
||||||
|
|
||||||
|
public Indexer (IEnumerable<Entry> source_list, NpaOptions options)
|
||||||
|
{
|
||||||
|
m_entries = new List<NpaEntry> (source_list.Count());
|
||||||
|
var game_id = options.TitleId;
|
||||||
|
if (game_id == NpaTitleId.LAMENTO || game_id == NpaTitleId.LAMENTOTR)
|
||||||
|
m_key = options.Key1 + options.Key2;
|
||||||
|
else
|
||||||
|
m_key = options.Key1 * options.Key2;
|
||||||
|
|
||||||
|
foreach (var entry in source_list)
|
||||||
|
{
|
||||||
|
string name = entry.Name;
|
||||||
|
var dir = Path.GetDirectoryName (name);
|
||||||
|
int folder_id = 0;
|
||||||
|
if (!string.IsNullOrEmpty (dir))
|
||||||
|
folder_id = AddDirectory (dir);
|
||||||
|
|
||||||
|
bool compress = options.CompressContents;
|
||||||
|
if (compress) // don't compress images
|
||||||
|
compress = !FormatCatalog.Instance.LookupFileName (name).OfType<ImageFormat>().Any();
|
||||||
|
var npa_entry = new NpaEntry
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
IsPacked = compress,
|
||||||
|
RawName = EncodeName (name, m_entries.Count),
|
||||||
|
FolderId = folder_id,
|
||||||
|
};
|
||||||
|
++m_file_count;
|
||||||
|
AddEntry (npa_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] EncodeName (string name, int entry_number)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] raw_name = m_encoding.GetBytes (name);
|
||||||
|
for (int i = 0; i < name.Length; ++i)
|
||||||
|
raw_name[i] -= NpaOpener.DecryptName (i, entry_number, m_key);
|
||||||
|
return raw_name;
|
||||||
|
}
|
||||||
|
catch (EncoderFallbackException X)
|
||||||
|
{
|
||||||
|
throw new InvalidFileName (name, arcStrings.MsgIllegalCharacters, X);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddEntry (NpaEntry entry)
|
||||||
|
{
|
||||||
|
m_entries.Add (entry);
|
||||||
|
m_size += 4 + entry.RawName.Length + 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<string, int> m_directory_map = new Dictionary<string, int>();
|
||||||
|
|
||||||
|
int AddDirectory (string dir)
|
||||||
|
{
|
||||||
|
int folder_id = 0;
|
||||||
|
if (m_directory_map.TryGetValue (dir, out folder_id))
|
||||||
|
return folder_id;
|
||||||
|
string path = "";
|
||||||
|
foreach (var component in dir.Split (Path.DirectorySeparatorChar))
|
||||||
|
{
|
||||||
|
path = Path.Combine (path, component);
|
||||||
|
if (m_directory_map.TryGetValue (path, out folder_id))
|
||||||
|
continue;
|
||||||
|
folder_id = ++m_directory_count;
|
||||||
|
m_directory_map[path] = folder_id;
|
||||||
|
|
||||||
|
var npa_entry = new NpaEntry
|
||||||
|
{
|
||||||
|
Name = path,
|
||||||
|
Type = "directory",
|
||||||
|
Offset = 0,
|
||||||
|
Size = 0,
|
||||||
|
UnpackedSize = 0,
|
||||||
|
IsPacked = false,
|
||||||
|
RawName = EncodeName (path, m_entries.Count),
|
||||||
|
FolderId = folder_id,
|
||||||
|
};
|
||||||
|
m_entries.Add (npa_entry);
|
||||||
|
}
|
||||||
|
return folder_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
67
ArcFormats/CreateNPAWidget.xaml
Normal file
67
ArcFormats/CreateNPAWidget.xaml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<Grid x:Class="GameRes.Formats.GUI.CreateNPAWidget"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:s="clr-namespace:GameRes.Formats.Strings"
|
||||||
|
xmlns:p="clr-namespace:GameRes.Formats.Properties"
|
||||||
|
xmlns:gui="clr-namespace:GameRes.Formats.GUI">
|
||||||
|
<Grid.Resources>
|
||||||
|
<gui:KeyConverter x:Key="keyConverter"/>
|
||||||
|
<Style TargetType="{x:Type TextBox}">
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="Validation.HasError" Value="True">
|
||||||
|
<Setter Property="ToolTip"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
<ControlTemplate x:Key="errorIndicator">
|
||||||
|
<DockPanel>
|
||||||
|
<TextBlock DockPanel.Dock="Right" Foreground="Red" FontWeight="Bold" Text="!" VerticalAlignment="Center"/>
|
||||||
|
<Border BorderBrush="Red" BorderThickness="1">
|
||||||
|
<AdornedElementPlaceholder Name="ValidationAdorner" />
|
||||||
|
</Border>
|
||||||
|
</DockPanel>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Grid.Resources>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<StackPanel Orientation="Vertical" Margin="0,0,0,5" Grid.Row="0">
|
||||||
|
<Label Content="{x:Static s:arcStrings.NPALabelScheme}" Target="{Binding ElementName=EncryptionWidget}" Padding="4,0,0,5" HorizontalAlignment="Left"/>
|
||||||
|
<gui:WidgetNPA x:Name="EncryptionWidget" HorizontalAlignment="Left"/>
|
||||||
|
</StackPanel>
|
||||||
|
<Button Content="{x:Static s:arcStrings.ArcReset}" Width="70" Height="25" VerticalAlignment="Top" Margin="20,0,0,5" Click="Reset_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Orientation="Vertical" Margin="0,0,0,5" Grid.Row="1">
|
||||||
|
<Label Content="{x:Static s:arcStrings.NPAKeys}" Target="{Binding ElementName=Key1Box}" Padding="4,0,0,5"/>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="70"/>
|
||||||
|
<ColumnDefinition Width="70"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBox Name="Key1Box" Grid.Column="0" Margin="0,0,5,0" Validation.ErrorTemplate="{StaticResource errorIndicator}">
|
||||||
|
<TextBox.Text>
|
||||||
|
<Binding Path="NPAKey1" Source="{x:Static p:Settings.Default}" Converter="{StaticResource keyConverter}" UpdateSourceTrigger="PropertyChanged">
|
||||||
|
<Binding.ValidationRules>
|
||||||
|
<gui:PasskeyRule/>
|
||||||
|
</Binding.ValidationRules>
|
||||||
|
</Binding>
|
||||||
|
</TextBox.Text>
|
||||||
|
</TextBox>
|
||||||
|
<TextBox Name="Key2Box" Grid.Column="1" Margin="5,0,0,0">
|
||||||
|
<TextBox.Text>
|
||||||
|
<Binding Path="NPAKey2" Source="{x:Static p:Settings.Default}" Converter="{StaticResource keyConverter}" UpdateSourceTrigger="PropertyChanged">
|
||||||
|
<Binding.ValidationRules>
|
||||||
|
<gui:PasskeyRule/>
|
||||||
|
</Binding.ValidationRules>
|
||||||
|
</Binding>
|
||||||
|
</TextBox.Text>
|
||||||
|
</TextBox>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
<CheckBox Name="CompressContents" Content="{x:Static s:arcStrings.NPACompressContents}" Grid.Row="2" Margin="0,5,0,5"
|
||||||
|
IsChecked="{Binding Source={x:Static p:Settings.Default}, Path=NPACompressContents, Mode=TwoWay}"/>
|
||||||
|
</Grid>
|
24
ArcFormats/CreateNPAWidget.xaml.cs
Normal file
24
ArcFormats/CreateNPAWidget.xaml.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
using GameRes.Formats.NitroPlus;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.GUI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for CreateNPAWidget.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class CreateNPAWidget : Grid
|
||||||
|
{
|
||||||
|
public CreateNPAWidget ()
|
||||||
|
{
|
||||||
|
InitializeComponent ();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Reset_Click (object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.EncryptionWidget.Scheme.SelectedIndex = 0;
|
||||||
|
this.Key1Box.Text = NpaOpener.DefaultKey1.ToString ("X8");
|
||||||
|
this.Key2Box.Text = NpaOpener.DefaultKey2.ToString ("X8");
|
||||||
|
this.CompressContents.IsChecked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
ArcFormats/Properties/Settings.Designer.cs
generated
42
ArcFormats/Properties/Settings.Designer.cs
generated
@ -25,10 +25,10 @@ namespace GameRes.Formats.Properties {
|
|||||||
|
|
||||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
[global::System.Configuration.DefaultSettingValueAttribute("NotEncrypted")]
|
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||||
public global::GameRes.Formats.NpaTitleId NPAScheme {
|
public string NPAScheme {
|
||||||
get {
|
get {
|
||||||
return ((global::GameRes.Formats.NpaTitleId)(this["NPAScheme"]));
|
return ((string)(this["NPAScheme"]));
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
this["NPAScheme"] = value;
|
this["NPAScheme"] = value;
|
||||||
@ -201,5 +201,41 @@ namespace GameRes.Formats.Properties {
|
|||||||
this["RPAKey"] = value;
|
this["RPAKey"] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||||
|
public bool NPACompressContents {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["NPACompressContents"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["NPACompressContents"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("1095188814")]
|
||||||
|
public uint NPAKey1 {
|
||||||
|
get {
|
||||||
|
return ((uint)(this["NPAKey1"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["NPAKey1"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("555831124")]
|
||||||
|
public uint NPAKey2 {
|
||||||
|
get {
|
||||||
|
return ((uint)(this["NPAKey2"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["NPAKey2"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="GameRes.Formats.Properties" GeneratedClassName="Settings">
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="GameRes.Formats.Properties" GeneratedClassName="Settings">
|
||||||
<Profiles />
|
<Profiles />
|
||||||
<Settings>
|
<Settings>
|
||||||
<Setting Name="NPAScheme" Type="GameRes.Formats.NpaTitleId" Scope="User">
|
<Setting Name="NPAScheme" Type="System.String" Scope="User">
|
||||||
<Value Profile="(Default)">NotEncrypted</Value>
|
<Value Profile="(Default)" />
|
||||||
</Setting>
|
</Setting>
|
||||||
<Setting Name="XP3Scheme" Type="System.String" Scope="User">
|
<Setting Name="XP3Scheme" Type="System.String" Scope="User">
|
||||||
<Value Profile="(Default)" />
|
<Value Profile="(Default)" />
|
||||||
@ -47,5 +47,14 @@
|
|||||||
<Setting Name="RPAKey" Type="System.UInt32" Scope="User">
|
<Setting Name="RPAKey" Type="System.UInt32" Scope="User">
|
||||||
<Value Profile="(Default)">1111638594</Value>
|
<Value Profile="(Default)">1111638594</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="NPACompressContents" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">False</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="NPAKey1" Type="System.UInt32" Scope="User">
|
||||||
|
<Value Profile="(Default)">1095188814</Value>
|
||||||
|
</Setting>
|
||||||
|
<Setting Name="NPAKey2" Type="System.UInt32" Scope="User">
|
||||||
|
<Value Profile="(Default)">555831124</Value>
|
||||||
|
</Setting>
|
||||||
</Settings>
|
</Settings>
|
||||||
</SettingsFile>
|
</SettingsFile>
|
37
ArcFormats/Strings/arcStrings.Designer.cs
generated
37
ArcFormats/Strings/arcStrings.Designer.cs
generated
@ -124,6 +124,15 @@ namespace GameRes.Formats.Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Reset.
|
||||||
|
/// </summary>
|
||||||
|
public static string ArcReset {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ArcReset", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to âge proprietary image format.
|
/// Looks up a localized string similar to âge proprietary image format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -315,6 +324,15 @@ namespace GameRes.Formats.Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Compress contents.
|
||||||
|
/// </summary>
|
||||||
|
public static string NPACompressContents {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("NPACompressContents", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Nitro+ resource archive.
|
/// Looks up a localized string similar to Nitro+ resource archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -324,6 +342,25 @@ namespace GameRes.Formats.Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Encryption keys
|
||||||
|
///(required even if contents is not encrypted).
|
||||||
|
/// </summary>
|
||||||
|
public static string NPAKeys {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("NPAKeys", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Encryption scheme.
|
||||||
|
/// </summary>
|
||||||
|
public static string NPALabelScheme {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("NPALabelScheme", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Nitro+ Steins;Gate resource archive.
|
/// Looks up a localized string similar to Nitro+ Steins;Gate resource archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -139,6 +139,9 @@ Choose appropriate encryption scheme.</value>
|
|||||||
<data name="ArcNoEncryption" xml:space="preserve">
|
<data name="ArcNoEncryption" xml:space="preserve">
|
||||||
<value>no encryption</value>
|
<value>no encryption</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ArcReset" xml:space="preserve">
|
||||||
|
<value>Reset</value>
|
||||||
|
</data>
|
||||||
<data name="GRPDescription" xml:space="preserve">
|
<data name="GRPDescription" xml:space="preserve">
|
||||||
<value>âge proprietary image format</value>
|
<value>âge proprietary image format</value>
|
||||||
</data>
|
</data>
|
||||||
@ -204,9 +207,19 @@ predefined encryption scheme.</value>
|
|||||||
<data name="MsgWritingIndex" xml:space="preserve">
|
<data name="MsgWritingIndex" xml:space="preserve">
|
||||||
<value>Writing index...</value>
|
<value>Writing index...</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="NPACompressContents" xml:space="preserve">
|
||||||
|
<value>Compress contents</value>
|
||||||
|
</data>
|
||||||
<data name="NPADescription" xml:space="preserve">
|
<data name="NPADescription" xml:space="preserve">
|
||||||
<value>Nitro+ resource archive</value>
|
<value>Nitro+ resource archive</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="NPAKeys" xml:space="preserve">
|
||||||
|
<value>Encryption keys
|
||||||
|
(required even if contents is not encrypted)</value>
|
||||||
|
</data>
|
||||||
|
<data name="NPALabelScheme" xml:space="preserve">
|
||||||
|
<value>Encryption scheme</value>
|
||||||
|
</data>
|
||||||
<data name="NPASteinsGateDescription" xml:space="preserve">
|
<data name="NPASteinsGateDescription" xml:space="preserve">
|
||||||
<value>Nitro+ Steins;Gate resource archive</value>
|
<value>Nitro+ Steins;Gate resource archive</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -136,6 +136,9 @@
|
|||||||
<data name="ArcNoEncryption" xml:space="preserve">
|
<data name="ArcNoEncryption" xml:space="preserve">
|
||||||
<value>без шифрования</value>
|
<value>без шифрования</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ArcReset" xml:space="preserve">
|
||||||
|
<value>Сбросить</value>
|
||||||
|
</data>
|
||||||
<data name="INTCreationNotice" xml:space="preserve">
|
<data name="INTCreationNotice" xml:space="preserve">
|
||||||
<value>Создание зашифрованных архивов не реализовано.</value>
|
<value>Создание зашифрованных архивов не реализовано.</value>
|
||||||
</data>
|
</data>
|
||||||
@ -189,6 +192,16 @@
|
|||||||
<data name="MsgWritingIndex" xml:space="preserve">
|
<data name="MsgWritingIndex" xml:space="preserve">
|
||||||
<value>Записывается оглавление...</value>
|
<value>Записывается оглавление...</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="NPACompressContents" xml:space="preserve">
|
||||||
|
<value>Сжать содержимое</value>
|
||||||
|
</data>
|
||||||
|
<data name="NPAKeys" xml:space="preserve">
|
||||||
|
<value>Ключи шифрования
|
||||||
|
(требуются даже если содержимое не шифруется)</value>
|
||||||
|
</data>
|
||||||
|
<data name="NPALabelScheme" xml:space="preserve">
|
||||||
|
<value>Способ шифрования</value>
|
||||||
|
</data>
|
||||||
<data name="ONSArchiveType" xml:space="preserve">
|
<data name="ONSArchiveType" xml:space="preserve">
|
||||||
<value>Тип архива</value>
|
<value>Тип архива</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
<Grid x:Class="GameRes.Formats.GUI.WidgetNPA"
|
<Grid x:Class="GameRes.Formats.GUI.WidgetNPA"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:fmt="clr-namespace:GameRes.Formats"
|
xmlns:fmt="clr-namespace:GameRes.Formats.NitroPlus"
|
||||||
xmlns:p="clr-namespace:GameRes.Formats.Properties"
|
xmlns:p="clr-namespace:GameRes.Formats.Properties"
|
||||||
MaxWidth="250">
|
MaxWidth="250">
|
||||||
<ComboBox Name="Scheme" Width="180"
|
<ComboBox Name="Scheme" Width="180"
|
||||||
ItemsSource="{Binding Source={x:Static fmt:NpaOpener.KnownSchemes}, Mode=OneWay}"/>
|
ItemsSource="{Binding Source={x:Static fmt:NpaOpener.KnownSchemes}, Mode=OneWay}"
|
||||||
|
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=NPAScheme, Mode=TwoWay}"/>
|
||||||
</Grid>
|
</Grid>
|
@ -2,6 +2,7 @@
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using GameRes.Formats.Properties;
|
using GameRes.Formats.Properties;
|
||||||
|
using GameRes.Formats.NitroPlus;
|
||||||
|
|
||||||
namespace GameRes.Formats.GUI
|
namespace GameRes.Formats.GUI
|
||||||
{
|
{
|
||||||
@ -12,15 +13,14 @@ namespace GameRes.Formats.GUI
|
|||||||
{
|
{
|
||||||
public WidgetNPA ()
|
public WidgetNPA ()
|
||||||
{
|
{
|
||||||
|
var selected = Settings.Default.NPAScheme;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
var sorted = NpaOpener.KnownSchemes.Skip (1).OrderBy (x => x);
|
var sorted = NpaOpener.KnownSchemes.Skip (1).OrderBy (x => x);
|
||||||
Scheme.ItemsSource = NpaOpener.KnownSchemes.Take(1).Concat (sorted);
|
Scheme.ItemsSource = NpaOpener.KnownSchemes.Take(1).Concat (sorted);
|
||||||
Scheme.SelectedItem = NpaOpener.KnownSchemes[(int)Settings.Default.NPAScheme];
|
if (NpaTitleId.NotEncrypted == NpaOpener.GetTitleId (selected))
|
||||||
}
|
Scheme.SelectedIndex = 0;
|
||||||
|
else
|
||||||
public string GetScheme()
|
Scheme.SelectedValue = selected;
|
||||||
{
|
|
||||||
return Scheme.SelectedItem as string;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<userSettings>
|
<userSettings>
|
||||||
<GameRes.Formats.Properties.Settings>
|
<GameRes.Formats.Properties.Settings>
|
||||||
<setting name="NPAScheme" serializeAs="String">
|
<setting name="NPAScheme" serializeAs="String">
|
||||||
<value>NotEncrypted</value>
|
<value />
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="XP3Scheme" serializeAs="String">
|
<setting name="XP3Scheme" serializeAs="String">
|
||||||
<value />
|
<value />
|
||||||
@ -49,6 +49,15 @@
|
|||||||
<setting name="RPAKey" serializeAs="String">
|
<setting name="RPAKey" serializeAs="String">
|
||||||
<value>1111638594</value>
|
<value>1111638594</value>
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="NPACompressContents" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="NPAKey1" serializeAs="String">
|
||||||
|
<value>1095188814</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="NPAKey2" serializeAs="String">
|
||||||
|
<value>555831124</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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user