Compare commits

...

26 Commits

Author SHA1 Message Date
Crsky
c44ab6ae03 fix: Add zh-Hant strings 2026-03-17 20:19:47 +08:00
Crsky
83f4abd211 Merge pull request #179 from love80312/master
Add Traditional Chinese language files
2026-03-17 20:15:27 +08:00
Crsky
0fd41b39f4 Merge pull request #180 from crskycode/feat/support-tlg-ref
feat: Support TLGref
2026-03-17 20:07:13 +08:00
Crsky
75b1799b54 feat: Support TLGref 2026-03-17 20:03:54 +08:00
笙歌
2f424474f5 Merge pull request #1 from love80312/add-zh-hant
Add zh hant
2026-03-17 19:28:34 +08:00
笙歌
43948a6e07 arcStrings.zh-Hant.resx 2026-03-17 19:27:57 +08:00
笙歌
4b003410c5 garStrings.zh-Hant.resx 2026-03-17 19:27:24 +08:00
笙歌
3fe5dadf72 guiStrings.zh-Hant.resx 2026-03-17 19:26:48 +08:00
Crsky
f58958c892 Update packages 2026-03-17 18:31:47 +08:00
Crsky
030d3adbbc Use old SixLabors.ImageSharp 2026-03-17 18:12:05 +08:00
Crsky
f61d08f1d9 Merge pull request #178 from crskycode/fix/xp3-webp-detection
fix: Fix XP3 RIFF detection
2026-03-17 17:32:33 +08:00
Crsky
47c8219417 Merge pull request #174 from crskycode/feat/suppor-tlg-mux-qoi
feat: Support TLG mux qoi
2026-03-17 17:32:00 +08:00
Crsky
bbd7476b6f style: format 2026-03-17 17:29:53 +08:00
Crsky
be1485a429 perf: Use stream decode in DecodeQOI 2026-03-17 17:12:41 +08:00
Crsky
94b6bc22f0 fix: Fix XP3 RIFF detection 2026-03-17 16:35:26 +08:00
Crsky
387d6110ce fix: Add argument check 2026-03-17 11:05:12 +08:00
Crsky
60b0f0bf40 feat: Add TLG mux qoi archive 2026-03-17 10:44:30 +08:00
Crsky
bb2c831206 feat: Support multi-layer qoi 2026-03-17 09:41:29 +08:00
Crsky
efbabb0ab3 Merge pull request #177 from akiWagashi/master
Add supprot for SimpleCrypt32 of Entis
2026-03-15 14:46:33 +08:00
akiWagashi
89a617854d Update code style 2026-03-15 12:09:31 +08:00
akiWagashi
3ba4ef5e4e Add supprot for SimpleCrypt32 of Entis 2026-03-15 01:09:55 +08:00
Crsky
cd548330a9 feat: Support TLGqoi file 2026-03-14 02:26:39 +08:00
Crsky
c4d3c71513 feat: Support TLG mux qoi 2026-03-13 23:58:37 +08:00
Crsky
612eb2d0ad (Entis): Support ERISACrypt 2026-03-10 14:43:26 +08:00
Crsky
ed4ff6de9a Update BCnEncoder.Net package 2026-03-06 10:57:23 +08:00
Crsky
1e6fc9c810 Remove local nuget package source 2026-03-06 10:56:57 +08:00
22 changed files with 1888 additions and 19 deletions

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\SixLabors.ImageSharp.3.1.12\build\SixLabors.ImageSharp.props" Condition="Exists('..\packages\SixLabors.ImageSharp.3.1.12\build\SixLabors.ImageSharp.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -52,8 +51,8 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="BCnEncoder, Version=2.2.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BCnEncoder.Net.2.2.1\lib\netstandard2.0\BCnEncoder.dll</HintPath>
<Reference Include="BCnEncoder, Version=2.3.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BCnEncoder.Net.2.3.0\lib\netstandard2.0\BCnEncoder.dll</HintPath>
</Reference>
<Reference Include="CommunityToolkit.HighPerformance, Version=8.4.0.0, Culture=neutral, PublicKeyToken=4aff67a105548ee2, processorArchitecture=MSIL">
<HintPath>..\packages\CommunityToolkit.HighPerformance.8.4.0\lib\netstandard2.0\CommunityToolkit.HighPerformance.dll</HintPath>
@@ -61,11 +60,14 @@
<Reference Include="ICSharpCode.SharpZipLib, Version=1.4.2.13, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.1.4.2\lib\netstandard2.0\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="K4os.Compression.LZ4, Version=1.3.8.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
<HintPath>..\packages\K4os.Compression.LZ4.1.3.8\lib\net462\K4os.Compression.LZ4.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.HashCode, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.HashCode.6.0.0\lib\net462\Microsoft.Bcl.HashCode.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.Numerics, Version=10.0.0.3, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Numerics.10.0.3\lib\net462\Microsoft.Bcl.Numerics.dll</HintPath>
<Reference Include="Microsoft.Bcl.Numerics, Version=10.0.0.5, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Numerics.10.0.5\lib\net462\Microsoft.Bcl.Numerics.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Win32.Registry, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll</HintPath>
@@ -99,6 +101,9 @@
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="SixLabors.ImageSharp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d998eea7b14cab13, processorArchitecture=MSIL">
<HintPath>..\packages\SixLabors.ImageSharp.2.1.13\lib\net472\SixLabors.ImageSharp.dll</HintPath>
</Reference>
<Reference Include="Snappier, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a1b25124e6e13a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Snappier.1.3.0\lib\net472\Snappier.dll</HintPath>
</Reference>
@@ -128,6 +133,9 @@
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encoding.CodePages, Version=10.0.0.5, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encoding.CodePages.10.0.5\lib\net462\System.Text.Encoding.CodePages.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.6.3\lib\net462\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
@@ -201,6 +209,7 @@
<Compile Include="Kid\ImageKLZ.cs" />
<Compile Include="Kid\ImageLBG.cs" />
<Compile Include="Kid\ImageSPC.cs" />
<Compile Include="KiriKiri\ArcTLG.cs" />
<Compile Include="Kogado\ArcARC.cs" />
<Compile Include="Ice\ImageIBM.cs" />
<Compile Include="Ice\ScriptISD.cs" />
@@ -963,6 +972,7 @@
<Compile Include="VnEngine\ImageZAW.cs" />
<EmbeddedResource Include="Abogado\keytable.dat" />
<EmbeddedResource Include="Strings\arcStrings.ja-JP.resx" />
<EmbeddedResource Include="Strings\arcStrings.zh-Hant.resx" />
<EmbeddedResource Include="Unity\strings.dat" />
<EmbeddedResource Include="ScrPlayer\ImgControlTable1" />
<EmbeddedResource Include="ScrPlayer\ImgControlTable2" />
@@ -1410,7 +1420,6 @@ xcopy "$(ProjectDir)\Resources\*" "$(TargetDir)\GameData\" /D /Y &gt;NUL</PostBu
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\System.ValueTuple.4.6.2\build\net471\System.ValueTuple.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.ValueTuple.4.6.2\build\net471\System.ValueTuple.targets'))" />
<Error Condition="!Exists('..\packages\SixLabors.ImageSharp.3.1.12\build\SixLabors.ImageSharp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SixLabors.ImageSharp.3.1.12\build\SixLabors.ImageSharp.props'))" />
</Target>
<Import Project="..\packages\System.ValueTuple.4.6.2\build\net471\System.ValueTuple.targets" Condition="Exists('..\packages\System.ValueTuple.4.6.2\build\net471\System.ValueTuple.targets')" />
</Project>

View File

@@ -29,6 +29,7 @@ using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using GameRes.Formats.Strings;
@@ -131,11 +132,27 @@ namespace GameRes.Formats.Entis
if (EncType.Raw == nent.Encryption || null == narc || null == narc.Password)
return input;
if (EncType.SimpleCrypt32 == nent.Encryption)
{
if (0 != size % 4)
throw new InvalidFormatException ();
using (input)
return DecodeSimpleCrypt32 (input, narc.Password, BitConverter.ToUInt32 (nent.Extra, 4));
}
if (EncType.BSHFCrypt == nent.Encryption)
{
using (input)
return DecodeBSHF (input, narc.Password);
}
if (EncType.ERISACrypt == nent.Encryption)
{
Stream enc;
using (input)
enc = DecodeBSHF (input, narc.Password);
return new ErisaNemesisStream (enc, (int)entry.Size);
}
Trace.WriteLine (string.Format ("{0}: encryption scheme 0x{1:x8} not implemented",
nent.Name, nent.Encryption));
return input;
@@ -232,6 +249,37 @@ namespace GameRes.Formats.Entis
return new MemoryStream (buf);
}
Stream DecodeSimpleCrypt32(Stream input, string password, uint imul_key)
{
var xor_key_map = Encoding.UTF8.GetBytes (password);
imul_key ^= Crc32.Compute (xor_key_map, 0, xor_key_map.Length);
for (int i = 0; i < xor_key_map.Length; i++)
{
var key_byte = (byte)~xor_key_map[i];
xor_key_map[i] = (byte)(key_byte ^ (key_byte * 7));
}
var buffer = new byte[input.Length];
input.Read(buffer, 0, (int)input.Length);
var buffer_span = MemoryMarshal.Cast<byte, uint> (buffer);
var xor_key_span = MemoryMarshal.Cast<byte, uint> (xor_key_map);
for (int i = 0; i < buffer_span.Length; i += xor_key_span.Length)
{
var window_size = Math.Min (buffer_span.Length - i, xor_key_span.Length);
var window_span = buffer_span.Slice (i, window_size);
for (int j = 0; j < window_size; j++)
{
window_span[j] = (window_span[j] * imul_key) ^ xor_key_span[j];
}
}
return new MemoryStream (buffer);
}
public override ResourceOptions GetDefaultOptions ()
{
return new NoaOptions {
@@ -306,7 +354,7 @@ namespace GameRes.Formats.Entis
entry.Encryption = m_file.View.ReadUInt32 (dir_offset);
m_found_encrypted = m_found_encrypted || (EncType.Raw != entry.Encryption && EncType.ERISACode != entry.Encryption);
bool is_packed = EncType.ERISACode == entry.Encryption;
bool is_packed = EncType.ERISACode == entry.Encryption || EncType.ERISACrypt == entry.Encryption;
dir_offset += 4;
entry.Offset = base_offset + m_file.View.ReadInt64 (dir_offset);

View File

@@ -0,0 +1,109 @@
//! \file ArcTLG.cs
//! \date Tue Mar 17 2026 10:35:55
//! \brief KiriKiri TLG image implementation.
//---------------------------------------------------------------------------
// TLGqoi multi-layer image decoder
//
// C# port by crsky
//
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
namespace GameRes.Formats.KiriKiri
{
internal class TlgLayerEntry : Entry
{
public int Index;
}
[Export(typeof(ArchiveFormat))]
public class TlgOpener : ArchiveFormat
{
public override string Tag { get { return "TLG"; } }
public override string Description { get { return "KiriKiri game engine image format"; } }
public override uint Signature { get { return 0x71474C54; } } // 'TLGq'
public override bool IsHierarchic { get { return false; } }
public override bool CanWrite { get { return false; } }
public TlgOpener ()
{
Extensions = new string[] { "tlg" };
}
public override ArcFile TryOpen (ArcView file)
{
if (!file.View.AsciiEqual (0, "TLGqoi") || !file.View.AsciiEqual (7, "raw"))
return null;
var qhdr = Array.Empty<byte> ();
var offset = 0x14;
while (true)
{
var entry_signature = file.View.ReadInt32 (offset);
var entry_size = file.View.ReadInt32 (offset+4);
offset += 8;
if (0x52444851 == entry_signature) // 'QHDR'
{
if (0x30 != entry_size)
return null;
qhdr = file.View.ReadBytes (offset, (uint)entry_size);
if (entry_size != qhdr.Length)
return null;
offset += entry_size;
}
else if (0 == entry_signature && 0 == entry_size)
break;
else
return null;
}
if (0 == qhdr.Length)
return null;
var layer_count = qhdr.ToInt32 (4);
if (layer_count < 1)
return null;
var block_count = qhdr.ToInt32 (12);
if (0 == block_count)
return null;
var dir = new List<Entry> (layer_count);
for (var i = 0; i < layer_count; i++)
{
dir.Add (new TlgLayerEntry
{
Name = string.Format ("{0}#{1:D3}.tlg", Path.GetFileNameWithoutExtension (file.Name), i),
Size = (uint)file.MaxOffset,
Type = "image",
Index = i,
});
}
return new ArcFile (file, this, dir);
}
static readonly ResourceInstance<ImageFormat> s_TlgFormat = new ResourceInstance<ImageFormat> ("TLG");
public override IImageDecoder OpenImage (ArcFile arc, Entry entry)
{
var layer_entry = entry as TlgLayerEntry;
if (null == layer_entry)
return base.OpenImage (arc, entry);
var input = arc.File.CreateStream ();
try
{
var info = s_TlgFormat.Value.ReadMetaData (input);
if (null == info)
throw new InvalidFormatException ();
if (info is TlgMetaData tlg)
{
tlg.LayerIndex = layer_entry.Index;
}
return new ImageFormatDecoder (input, s_TlgFormat.Value, info);
}
catch
{
input.Dispose ();
throw;
}
}
}
}

View File

@@ -104,6 +104,22 @@ namespace GameRes.Formats.KiriKiri
input.Read (header, 0, 5);
uint signature = header.ToUInt32 (0);
GuessEntryTypeBySignature (entry, signature);
if (0x46464952 == signature) // 'RIFF'
{
if (entry.UnpackedSize >= 12)
{
var header_ext = new byte[12];
Array.Copy (header, header_ext, header.Length);
input.Read (header_ext, header.Length, header_ext.Length-header.Length);
header = header_ext;
if (header.AsciiEqual (8, "WAVE"))
entry.Type = "audio";
else if (header.AsciiEqual (8, "WEBP"))
entry.Type = "image";
else if (header.AsciiEqual (8, "AVI "))
entry.Type = "video";
}
}
if (0x184D2204 == signature) // LZ4 magic
{
// assume no scripts are compressed using LZ4, return decompressed stream right away

View File

@@ -16,13 +16,16 @@ using GameRes.Utility;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using K4os.Compression.LZ4;
using System.Threading.Tasks;
namespace GameRes.Formats.KiriKiri
{
internal class TlgMetaData : ImageMetaData
{
public int Version;
public int DataOffset;
public long DataOffset;
public int LayerIndex;
}
[Export(typeof(ImageFormat))]
@@ -35,7 +38,7 @@ namespace GameRes.Formats.KiriKiri
public TlgFormat ()
{
Extensions = new string[] { "tlg", "tlg5", "tlg6" };
Signatures = new uint[] { 0x30474C54, 0x35474C54, 0x36474C54, 0x35474CAB, 0x584D4B4A };
Signatures = new uint[] { 0x30474C54, 0x35474C54, 0x36474C54, 0x35474CAB, 0x584D4B4A, 0x6D474C54, 0x71474C54, 0x72474C54 };
}
public override ImageMetaData ReadMetaData (IBinaryStream stream)
@@ -45,7 +48,7 @@ namespace GameRes.Formats.KiriKiri
if (!header.AsciiEqual ("TLG0.0\x00sds\x1a"))
offset = 0;
int version;
if (!header.AsciiEqual (offset+6, "\x00raw\x1a"))
if (!header.AsciiEqual (offset+6, "\x00raw\x1a") && !header.AsciiEqual (offset+6, "\x00idx\x1a"))
return null;
if (0xAB == header[offset])
header[offset] = (byte)'T';
@@ -53,6 +56,12 @@ namespace GameRes.Formats.KiriKiri
version = 6;
else if (header.AsciiEqual (offset, "TLG5.0"))
version = 5;
else if (header.AsciiEqual (offset, "TLGmux"))
version = 0;
else if (header.AsciiEqual (offset, "TLGqoi"))
version = 1;
else if (header.AsciiEqual (offset, "TLGref"))
version = 2;
else if (header.AsciiEqual (offset, "XXXYYY"))
{
version = 5;
@@ -102,6 +111,9 @@ namespace GameRes.Formats.KiriKiri
{
var meta = (TlgMetaData)info;
if (2 == meta.Version)
return ReadREF (file, meta);
var image = ReadTlg (file, meta);
int tail_size = (int)Math.Min (file.Length - file.Position, 512);
@@ -137,6 +149,10 @@ namespace GameRes.Formats.KiriKiri
src.Position = info.DataOffset;
if (6 == info.Version)
return ReadV6 (src, info);
else if (0 == info.Version)
return ReadMUX (src, info);
else if (1 == info.Version)
return ReadQOI (src, info);
else
return ReadV5 (src, info);
}
@@ -1085,6 +1101,488 @@ namespace GameRes.Formats.KiriKiri
}
}
}
byte[] DecodeQOI (IBinaryStream src, uint width, uint height)
{
var count = 4*width*height;
var output = new byte [count];
var qoi = new QoiDecodeStream (src);
uint pixel = 0;
var run = 0;
var dst = 0;
while (dst < count)
{
if (run > 1)
--run;
else
{
run = qoi.Read (out pixel);
}
output[dst ] = (byte)pixel;
output[dst+1] = (byte)(pixel >> 8);
output[dst+2] = (byte)(pixel >> 16);
output[dst+3] = (byte)(pixel >> 24);
dst += 4;
}
return output;
}
class Lz4DecodeStream
{
readonly IBinaryStream m_input;
readonly byte[][] m_buffer;
readonly int[] m_size;
int m_index;
int m_pos;
const int BUFFER_SIZE = 0x8000;
public Lz4DecodeStream (IBinaryStream input)
{
m_input = input;
m_buffer = new byte[2][];
m_size = new int[2];
for (var i = 0; i < m_buffer.Length; i++)
m_buffer[i] = new byte[BUFFER_SIZE];
}
bool FillBuffer ()
{
if (m_input.Position == m_input.Length)
return false;
var v1 = m_input.ReadUInt16 ();
var v2 = m_input.ReadUInt16 ();
var input = m_input.ReadBytes (v2);
if (v2 != input.Length)
throw new EndOfStreamException ();
var size = v1 & 0x7FFF;
if (0 == size)
size = 0x8000;
var dst = m_index ^ 1;
var dic = m_index;
int num;
if (0 != (v1 & 0x8000))
{
if (0 == m_size[dic])
throw new InvalidFormatException ();
num = LZ4Codec.Decode (input, m_buffer[dst], m_buffer[dic].AsSpan (0, m_size[dic]));
}
else
num = LZ4Codec.Decode (input, m_buffer[dst]);
if (-1 == num || size != num)
throw new InvalidFormatException ();
m_size[dst] = num;
m_index ^= 1;
m_pos = 0;
return true;
}
public int ReadByte ()
{
if (m_pos == m_size[m_index])
{
if (!FillBuffer ())
return -1;
}
var idx = m_index;
if (m_pos == m_size[idx])
return -1;
return m_buffer[idx][m_pos++];
}
}
class RunDecodeStream
{
readonly Lz4DecodeStream m_input;
public RunDecodeStream (IBinaryStream input)
{
m_input = new Lz4DecodeStream (input);
}
public int Read ()
{
var value = 0;
var shift = 0;
while (shift < 32)
{
var b = m_input.ReadByte ();
if (-1 == b)
throw new EndOfStreamException ();
value |= (int)(b & 0x7F) << shift;
if (0 == (b & 0x80))
break;
shift += 7;
}
return value;
}
}
static class QoiCodec
{
public const int Index = 0x00;
public const int Diff = 0x40;
public const int Luma = 0x80;
public const int Run = 0xC0;
public const int Rgb = 0xFE;
public const int Rgba = 0xFF;
public const int Mask2 = 0xC0;
public const int HashTableSize = 64;
}
class QoiDecodeStream
{
readonly IBinaryStream m_input;
readonly byte[] m_table;
uint m_pixel;
public QoiDecodeStream (IBinaryStream input)
{
m_input = input;
m_table = new byte [4*QoiCodec.HashTableSize];
m_pixel = 0xFF000000;
}
public int Read (out uint output)
{
var r = (byte)m_pixel;
var g = (byte)(m_pixel >> 8);
var b = (byte)(m_pixel >> 16);
var a = (byte)(m_pixel >> 24);
var run = 1;
var b1 = m_input.ReadByte ();
if (-1 == b1)
throw new EndOfStreamException ();
if (QoiCodec.Rgb == b1)
{
var rgb = m_input.ReadInt24 ();
r = (byte)rgb;
g = (byte)(rgb >> 8);
b = (byte)(rgb >> 16);
}
else if (QoiCodec.Rgba == b1)
{
var rgba = m_input.ReadInt32 ();
r = (byte)rgba;
g = (byte)(rgba >> 8);
b = (byte)(rgba >> 16);
a = (byte)(rgba >> 24);
}
else if (QoiCodec.Index == (b1 & QoiCodec.Mask2))
{
var p1 = (b1 & ~QoiCodec.Mask2) * 4;
r = m_table[p1 ];
g = m_table[p1+1];
b = m_table[p1+2];
a = m_table[p1+3];
}
else if (QoiCodec.Diff == (b1 & QoiCodec.Mask2))
{
r += (byte)(((b1 >> 4) & 0x03) - 2);
g += (byte)(((b1 >> 2) & 0x03) - 2);
b += (byte)((b1 & 0x03) - 2);
}
else if (QoiCodec.Luma == (b1 & QoiCodec.Mask2))
{
var b2 = m_input.ReadByte ();
if (-1 == b2)
throw new EndOfStreamException ();
var vg = (b1 & 0x3F) - 32;
r += (byte)(vg - 8 + ((b2 >> 4) & 0x0F));
g += (byte)vg;
b += (byte)(vg - 8 + (b2 & 0x0F));
}
else if (QoiCodec.Run == (b1 & QoiCodec.Mask2))
{
run = (b1 & 0x3F) + 1;
}
var p2 = (r*3 + g*5 + b*7 + a*11) % QoiCodec.HashTableSize*4;
m_table[p2 ] = r;
m_table[p2+1] = g;
m_table[p2+2] = b;
m_table[p2+3] = a;
m_pixel = (uint)(r | (g << 8) | (b << 16) | (a << 24));
output = (uint)(b | (g << 8) | (r << 16) | (a << 24));
return run;
}
}
class QoiBlockDecoder
{
readonly QoiDecodeStream m_qoi;
readonly RunDecodeStream m_run;
readonly int m_pixel_count;
readonly int m_layer_index;
readonly int m_layer_count;
readonly byte[] m_output;
readonly int m_dst;
public QoiBlockDecoder (byte[] qoi, byte[] run, int pixel_count, int layer_index, int layer_count, byte[] output, int dst)
{
m_qoi = new QoiDecodeStream (new BinMemoryStream (qoi));
m_run = new RunDecodeStream (new BinMemoryStream (run));
m_pixel_count = pixel_count;
m_layer_index = layer_index;
m_layer_count = layer_count;
m_output = output;
m_dst = dst;
}
public void Decode ()
{
m_qoi.Read (out var p0);
m_qoi.Read (out var p1);
if (0 != p0 || 0xFF000000 != p1)
throw new InvalidFormatException ();
var r0 = m_run.Read ();
if (0 != r0)
throw new InvalidFormatException ();
var dst = m_dst;
var count = m_pixel_count;
var skip = m_layer_index;
while (count --> 0)
{
var r1 = m_qoi.Read (out var pixel);
var r2 = m_run.Read ();
var run = r1 + r2;
while (run --> 0)
{
if (skip > 0)
--skip;
else
{
skip = m_layer_count-1;
m_output[dst ] = (byte)pixel;
m_output[dst+1] = (byte)(pixel >> 8);
m_output[dst+2] = (byte)(pixel >> 16);
m_output[dst+3] = (byte)(pixel >> 24);
dst += 4;
}
}
}
}
}
long[] DecodeArray (ReadOnlySpan<byte> input)
{
var output = new List<long> (input.Length);
var i = 0;
while (i < input.Length)
{
long value = 0;
var shift = 0;
while (shift < 64)
{
var b = input[i++];
value |= (long)(b & 0x7F) << shift;
if (0 == (b & 0x80))
break;
shift += 7;
if (i >= input.Length)
throw new EndOfStreamException ();
}
output.Add (value);
}
return output.ToArray ();
}
long[] ReadArray (IBinaryStream src, long offset, int signature)
{
src.Position = offset;
if (signature != src.ReadInt32 ())
throw new InvalidFormatException ();
var length = src.ReadInt32 ();
var input = src.ReadBytes (length);
if (input.Length != length)
throw new EndOfStreamException ();
return DecodeArray (input);
}
byte[] DecodeMultiLayerQOI (IBinaryStream src, uint width, uint height, byte[] qhdr, int layer)
{
var data_offset = src.Position;
var layer_count = qhdr.ToInt32 (4);
var block_height = qhdr.ToInt32 (8);
var block_count = qhdr.ToInt32 (12);
var dtbl_offset = qhdr.ToInt64 (24);
var rtbl_offset = qhdr.ToInt64 (32);
if (layer_count < 1)
throw new InvalidFormatException ();
if (0 == block_count)
throw new NotImplementedException ();
if (layer >= layer_count)
throw new ArgumentOutOfRangeException ();
long[] dtbl = ReadArray (src, data_offset+dtbl_offset, 0x4C425444);
if (0 == dtbl.Length || dtbl.Length != 1+2*block_count || dtbl[0] != dtbl.Length-1)
throw new InvalidFormatException ();
long[] rtbl = ReadArray (src, data_offset+rtbl_offset, 0x4C425452);
if (0 == rtbl.Length || rtbl.Length != 1+block_count || rtbl[0] != rtbl.Length-1)
throw new InvalidFormatException ();
var tasks = new List<Task> (block_count);
var output = new byte[4*width*height];
var qoi_offset = data_offset;
var run_offset = src.Position;
for (var i = 0; i < block_count; i++)
{
var qoi_size = (int) dtbl[1+2*i];
var run_size = (int) rtbl[1+i];
var num_pixels = (int) dtbl[1+2*i+1];
src.Position = qoi_offset;
var qoi = src.ReadBytes (qoi_size);
if (qoi_size != qoi.Length)
throw new EndOfStreamException ();
src.Position = run_offset;
var run = src.ReadBytes (run_size);
if (run_size != run.Length)
throw new EndOfStreamException ();
qoi_offset += qoi_size;
run_offset += run_size;
var dst = block_height*i * 4*(int)width;
var decoder = new QoiBlockDecoder (qoi, run, num_pixels, layer, layer_count, output, dst);
var task = Task.Run (() => decoder.Decode ());
tasks.Add (task);
}
Task.WhenAll (tasks).Wait ();
return output;
}
byte[] ReadQOI (IBinaryStream src, TlgMetaData info)
{
var qhdr = Array.Empty<byte> ();
while (true)
{
var entry_signature = src.ReadInt32 ();
var entry_size = src.ReadInt32 ();
if (0x52444851 == entry_signature) // 'QHDR'
{
if (0x30 != entry_size)
throw new InvalidFormatException ();
qhdr = src.ReadBytes (entry_size);
if (qhdr.Length != entry_size)
throw new EndOfStreamException ();
}
else if (0 == entry_signature && 0 == entry_size)
break;
else
throw new InvalidFormatException ();
}
if (0 != qhdr.Length)
return DecodeMultiLayerQOI (src, info.Width, info.Height, qhdr, info.LayerIndex);
return DecodeQOI (src, info.Width, info.Height);
}
byte[] ReadMUX (IBinaryStream src, TlgMetaData info)
{
src.Position = info.DataOffset;
var slices = new List<TlgMetaData> ();
while (true)
{
var entry_signature = src.ReadInt32 ();
var entry_size = src.ReadInt32 ();
if (0x58554D43 == entry_signature) // 'CMUX'
{
var entry = src.ReadBytes (entry_size);
var count = entry.ToInt32 (0);
if (0 == count)
throw new InvalidFormatException ();
var offset = 4;
for (var i = 0; i < count; i++)
{
slices.Add (new TlgMetaData
{
OffsetX = entry.ToInt32 (offset),
OffsetY = entry.ToInt32 (offset+4),
Width = entry.ToUInt32 (offset+8),
Height = entry.ToUInt32 (offset+12),
DataOffset = entry.ToInt64 (offset+16)
});
offset += 24;
}
}
else if (0 == entry_signature && 0 == entry_size)
break;
else
throw new InvalidFormatException ();
}
var data_offset = src.Position;
var image = new byte [4*info.Width*info.Height];
foreach (var slice_info in slices)
{
src.Position = data_offset + slice_info.DataOffset;
byte[] slice;
var header = src.ReadBytes (11);
if (header.AsciiEqual (0, "TLGqoi") && header.AsciiEqual (7, "raw"))
{
var channels = src.ReadByte ();
var width = src.ReadUInt32 ();
var height = src.ReadUInt32 ();
if (3 != channels && 4 != channels)
throw new InvalidFormatException ();
if (width != slice_info.Width || height != slice_info.Height)
throw new InvalidFormatException ();
slice = ReadQOI (src, slice_info);
}
else
throw new NotImplementedException ();
BlendImage (image, info, slice, slice_info, 0);
}
return image;
}
ImageData ReadREF (IBinaryStream src, TlgMetaData info)
{
src.Position = info.DataOffset;
var qref = Array.Empty<byte> ();
while (true)
{
var entry_signature = src.ReadInt32 ();
var entry_size = src.ReadInt32 ();
if (0x46455251 == entry_signature) // 'QREF'
{
if (entry_size < 16)
throw new InvalidFormatException ();
qref = src.ReadBytes (entry_size);
if (qref.Length != entry_size)
throw new EndOfStreamException ();
}
else if (0 == entry_signature && 0 == entry_size)
break;
else
throw new InvalidFormatException ();
}
if (0 == qref.Length)
throw new InvalidFormatException ();
var layer_index = qref.ToInt32 (4);
var name_length = qref.ToInt32 (12);
if (name_length < 2)
throw new InvalidFormatException ();
var name = Encoding.Unicode.GetString (qref, 16, name_length);
if (string.IsNullOrEmpty (name))
throw new InvalidFormatException ();
using (var ref_tlg = VFS.OpenBinaryStream (name))
{
var ref_meta = ReadMetaData (ref_tlg) as TlgMetaData;
if (1 != ref_meta.Version)
throw new InvalidFormatException ();
ref_meta.LayerIndex = layer_index;
return Read (ref_tlg, ref_meta);
}
}
}
internal class TagsParser

View File

Binary file not shown.

View File

@@ -0,0 +1,406 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AMIBaseArchive" xml:space="preserve">
<value>原壓縮檔案</value>
</data>
<data name="AMIBaseTooltip" xml:space="preserve">
<value>新的壓縮檔案將會包含原檔案中的項目。</value>
</data>
<data name="AMIChooseBase" xml:space="preserve">
<value>請選擇原壓縮檔案</value>
</data>
<data name="AMIDescription" xml:space="preserve">
<value>Amaterasu Translations Muv-Luv 壓縮檔案</value>
</data>
<data name="AMINoFiles" xml:space="preserve">
<value>未找到適合AMI壓縮檔案的項目。</value>
</data>
<data name="ArcEncryptedNotice" xml:space="preserve">
<value>壓縮檔案已加密。
請選擇正確的加密方式。</value>
</data>
<data name="ArcNoEncryption" xml:space="preserve">
<value>沒有加密。</value>
</data>
<data name="ArcReset" xml:space="preserve">
<value>重置</value>
</data>
<data name="GRPDescription" xml:space="preserve">
<value>âge專用圖像格式</value>
</data>
<data name="GSCDescription" xml:space="preserve">
<value>Liar-soft專用腳本格式</value>
</data>
<data name="INTCreationNotice" xml:space="preserve">
<value>尚不支持創建加密壓縮檔案。</value>
</data>
<data name="INTDescription" xml:space="preserve">
<value>CatSystem2引擎壓縮檔案</value>
</data>
<data name="INTKeyRequirement" xml:space="preserve">
<value>密鑰是一個32位的16進制整數</value>
</data>
<data name="INTLabelNumericKey" xml:space="preserve">
<value>密鑰</value>
</data>
<data name="INTNotice" xml:space="preserve">
<value>壓縮檔案目錄已加密。</value>
</data>
<data name="KogadoDescription" xml:space="preserve">
<value>工畫堂引擎壓縮檔案</value>
</data>
<data name="LabelPassphrase" xml:space="preserve">
<value>密碼</value>
</data>
<data name="LabelScheme" xml:space="preserve">
<value>方式</value>
</data>
<data name="LWGDescription" xml:space="preserve">
<value>Liar-soft圖像檔案</value>
</data>
<data name="MsgAddingFile" xml:space="preserve">
<value>正在添加檔案……</value>
</data>
<data name="MsgCalculatingChecksum" xml:space="preserve">
<value>正在計算校驗和……</value>
</data>
<data name="MsgCompressingIndex" xml:space="preserve">
<value>正在壓縮索引……</value>
</data>
<data name="MsgCreationKeyRequired" xml:space="preserve">
<value>創建壓縮檔案需要密鑰。</value>
</data>
<data name="MsgEncNotImplemented" xml:space="preserve">
<value>加密方式暫不支持。</value>
</data>
<data name="MsgExtensionTooLong" xml:space="preserve">
<value>檔案擴展名太長。</value>
</data>
<data name="MsgFileNameTooLong" xml:space="preserve">
<value>檔案名太長。</value>
</data>
<data name="MsgIllegalCharacters" xml:space="preserve">
<value>檔案名中包含非法字符。</value>
</data>
<data name="MsgInvalidImageFormat" xml:space="preserve">
<value>{0}: 無法識別圖像格式。</value>
</data>
<data name="MsgInvalidVersion" xml:space="preserve">
<value>無效的檔案版本。</value>
</data>
<data name="MsgNoExtension" xml:space="preserve">
<value>檔案名需要包含擴展名。</value>
</data>
<data name="MsgTooManyFiles" xml:space="preserve">
<value>檔案數目超過壓縮檔案限制。</value>
</data>
<data name="MsgUpdatingIndex" xml:space="preserve">
<value>正在更新索引……</value>
</data>
<data name="MsgWritingIndex" xml:space="preserve">
<value>正在建立索引……</value>
</data>
<data name="NPACompressContents" xml:space="preserve">
<value>壓縮內容</value>
</data>
<data name="NPADescription" xml:space="preserve">
<value>Nitro+壓縮檔案</value>
</data>
<data name="NPAKeys" xml:space="preserve">
<value>密鑰
(未加密內容仍需要)</value>
</data>
<data name="NPASteinsGateDescription" xml:space="preserve">
<value>Nitro+ Steins;Gate壓縮檔案</value>
</data>
<data name="NSADescription" xml:space="preserve">
<value>NScripter引擎壓縮檔案</value>
</data>
<data name="ONSArchiveType" xml:space="preserve">
<value>壓縮檔案類型</value>
</data>
<data name="ONSCompression" xml:space="preserve">
<value>壓縮方式</value>
</data>
<data name="ONSCompressionNone" xml:space="preserve">
<value>無</value>
</data>
<data name="PDDescription" xml:space="preserve">
<value>Flying Shine壓縮檔案</value>
</data>
<data name="PDScrambleContents" xml:space="preserve">
<value>打亂內容</value>
</data>
<data name="RPADescription" xml:space="preserve">
<value>Ren'Py引擎壓縮檔案</value>
</data>
<data name="RPALabelKey" xml:space="preserve">
<value>32位密鑰</value>
</data>
<data name="SCRDescription" xml:space="preserve">
<value>Amaterasu Translations Muv-Luv腳本檔案</value>
</data>
<data name="SGLabelEncoding" xml:space="preserve">
<value>檔案名編碼</value>
</data>
<data name="TooltipHex" xml:space="preserve">
<value>十六進制數</value>
</data>
<data name="WARCLabelLength" xml:space="preserve">
<value>檔案名最大長度
(不包括擴展名)</value>
</data>
<data name="XFLDescription" xml:space="preserve">
<value>Liar-soft遊戲壓縮檔案</value>
</data>
<data name="XP3CompressContents" xml:space="preserve">
<value>壓縮內容</value>
</data>
<data name="XP3CompressHeader" xml:space="preserve">
<value>壓縮目錄</value>
</data>
<data name="XP3Description" xml:space="preserve">
<value>KiriKiri引擎壓縮檔案</value>
</data>
<data name="XP3LabelVersion" xml:space="preserve">
<value>版本</value>
</data>
<data name="XP3RetainStructure" xml:space="preserve">
<value>保持目錄結構</value>
</data>
<data name="YPFDescription" xml:space="preserve">
<value>Yu-Ris引擎壓縮檔案</value>
</data>
<data name="YPFLabelKey" xml:space="preserve">
<value>8位密鑰</value>
</data>
<data name="YPFLabelVersion" xml:space="preserve">
<value>壓縮檔案版本</value>
</data>
<data name="YPFNotice" xml:space="preserve">
<value>壓縮檔案的目錄已加密。
請選擇正確的加密方式。</value>
</data>
<data name="LabelEncScheme" xml:space="preserve">
<value>加密方式</value>
</data>
<data name="DPKKeys" xml:space="preserve">
<value>密鑰</value>
</data>
<data name="ArcDefault" xml:space="preserve">
<value>預設</value>
</data>
<data name="ArcHex32Bit" xml:space="preserve">
<value>32位十六進制數</value>
</data>
<data name="KCAPDefault" xml:space="preserve">
<value>預設</value>
</data>
<data name="MBLNotice" xml:space="preserve">
<value>壓縮檔案包含已加密的腳本。
請選擇加密方式或輸入密碼。</value>
</data>
<data name="ArcTitleOrPassword" xml:space="preserve">
<value>請選擇遊戲名稱或輸入密碼</value>
</data>
<data name="RPMEncryptedNotice" xml:space="preserve">
<value>檔案與RPM壓縮檔案格式相似,
但無法猜測正確的密鑰。
請選擇正確的加密方式。</value>
</data>
<data name="QLIEDefaultScheme" xml:space="preserve">
<value>使用預設加密方式</value>
</data>
<data name="INTChooseExe" xml:space="preserve">
<value>請選擇遊戲的EXE檔案</value>
</data>
<data name="INTExeButton" xml:space="preserve">
<value>檢查EXE</value>
</data>
<data name="INTExeFiles" xml:space="preserve">
<value>可執行檔案</value>
</data>
<data name="INTMessage1" xml:space="preserve">
<value>請按「檢查EXE」按鈕在遊戲程序檔案中尋找密鑰。</value>
</data>
<data name="INTMessage2" xml:space="preserve">
<value>或者,您也可以輸入壓縮檔案的密鑰或者選擇一個現成的加密方式。</value>
</data>
<data name="INTKeyNotFound" xml:space="preserve">
<value>在{0}當中沒有找到密鑰。</value>
</data>
<data name="ArcIgnoreEncryption" xml:space="preserve">
<value>忽略加密。</value>
</data>
<data name="ArcImageEncrypted" xml:space="preserve">
<value>圖像已加密。</value>
</data>
<data name="MCGChoose" xml:space="preserve">
<value>請選擇遊戲名稱或輸入密鑰</value>
</data>
<data name="MCGLabelKey" xml:space="preserve">
<value>8位加密密鑰</value>
</data>
<data name="MCAEncryptedNotice" xml:space="preserve">
<value>壓縮檔案的內容已被加密。</value>
</data>
<data name="YPFTryGuess" xml:space="preserve">
<value>嘗試猜測</value>
</data>
<data name="AGSMightBeEncrypted" xml:space="preserve">
<value>壓縮檔案可能被加密,選擇適當的加密方案。</value>
</data>
<data name="XP3EncryptedNotice" xml:space="preserve">
<value>壓縮檔案可能被加密,選擇適當的加密方案。</value>
</data>
<data name="GALChoose" xml:space="preserve">
<value>請選擇遊戲名稱或輸入密鑰</value>
</data>
<data name="GYUImageEncrypted" xml:space="preserve">
<value>圖像已加密。
請選擇正確的加密方式。</value>
</data>
<data name="FJSYSNotice" xml:space="preserve">
<value>壓縮檔案包含已加密的腳本。
請選擇加密方式或輸入密碼。</value>
</data>
<data name="RCTApplyMask" xml:space="preserve">
<value>從RC8位圖中加載透明度數據</value>
</data>
<data name="RCTOverlayFrames" xml:space="preserve">
<value>自動組合增量幀</value>
</data>
<data name="ZIPEncryptedNotice" xml:space="preserve">
<value>壓縮檔案的內容已被加密。</value>
</data>
<data name="OGGFixCrc" xml:space="preserve">
<value>修復Ogg檔案校驗和</value>
</data>
<data name="DefaultEncoding" xml:space="preserve">
<value>預設檔案名編碼</value>
</data>
<data name="ODNAudioSampleRate" xml:space="preserve">
<value>預設音頻採樣率</value>
</data>
<data name="Tim2AlphaFormat" xml:space="preserve">
<value>選擇Tim2圖片透明度格式。
這無法從檔案中正確獲取。</value>
</data>
</root>

View File

@@ -218,6 +218,10 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -238,6 +242,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BCnEncoder.Net" version="2.2.1" targetFramework="net472" />
<package id="BCnEncoder.Net" version="2.3.0" targetFramework="net472" />
<package id="CommunityToolkit.HighPerformance" version="8.4.0" targetFramework="net472" />
<package id="K4os.Compression.LZ4" version="1.3.8" targetFramework="net472" />
<package id="Microsoft.Bcl.HashCode" version="6.0.0" targetFramework="net472" />
<package id="Microsoft.Bcl.Numerics" version="10.0.3" targetFramework="net472" />
<package id="Microsoft.Bcl.Numerics" version="10.0.5" targetFramework="net472" />
<package id="Microsoft.Win32.Registry" version="5.0.0" targetFramework="net472" />
<package id="NAudio" version="2.2.1" targetFramework="net472" />
<package id="NAudio.Asio" version="2.2.1" targetFramework="net472" />
@@ -15,7 +16,7 @@
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net472" />
<package id="NVorbis" version="0.10.5" targetFramework="net472" />
<package id="SharpZipLib" version="1.4.2" targetFramework="net472" />
<package id="SixLabors.ImageSharp" version="3.1.12" targetFramework="net472" />
<package id="SixLabors.ImageSharp" version="2.1.13" targetFramework="net472" />
<package id="Snappier" version="1.3.0" targetFramework="net472" />
<package id="System.Buffers" version="4.6.1" targetFramework="net472" />
<package id="System.Memory" version="4.6.3" targetFramework="net472" />
@@ -23,6 +24,7 @@
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net472" />
<package id="System.Security.AccessControl" version="6.0.1" targetFramework="net472" />
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net472" />
<package id="System.Text.Encoding.CodePages" version="10.0.5" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.6.3" targetFramework="net472" />
<package id="System.ValueTuple" version="4.6.2" targetFramework="net472" />
<package id="ZstdSharp.Port" version="0.8.7" targetFramework="net472" />

View File

@@ -5,6 +5,10 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -25,6 +29,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -9,6 +9,10 @@
<assemblyIdentity name="Concentus" publicKeyToken="2f7fb9b49ffdfe20" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.2.0" newVersion="2.2.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -29,6 +33,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -98,6 +98,10 @@
</userSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -118,6 +122,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -314,6 +314,7 @@
<EmbeddedResource Include="Strings\guiStrings.ru-RU.resx" />
<EmbeddedResource Include="..\LICENSE" />
<EmbeddedResource Include="Strings\guiStrings.zh-Hans.resx" />
<EmbeddedResource Include="Strings\guiStrings.zh-Hant.resx" />
<None Include="packages.config" />
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings">

View File

@@ -0,0 +1,571 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ButtonCancel" xml:space="preserve">
<value>取消</value>
</data>
<data name="ButtonExtract" xml:space="preserve">
<value>提取</value>
</data>
<data name="ButtonOK" xml:space="preserve">
<value>確定</value>
</data>
<data name="CtxMenuClose" xml:space="preserve">
<value>_關閉</value>
</data>
<data name="CtxMenuCopy" xml:space="preserve">
<value>複製</value>
</data>
<data name="CtxMenuCreate" xml:space="preserve">
<value>創建壓縮檔案...</value>
</data>
<data name="CtxMenuCut" xml:space="preserve">
<value>剪切</value>
</data>
<data name="CtxMenuDelete" xml:space="preserve">
<value>_刪除</value>
</data>
<data name="CtxMenuExplorer" xml:space="preserve">
<value>在_資源管理器中瀏覽</value>
</data>
<data name="CtxMenuExtract" xml:space="preserve">
<value>提取</value>
</data>
<data name="CtxMenuOpen" xml:space="preserve">
<value>打開</value>
</data>
<data name="CtxMenuPaste" xml:space="preserve">
<value>粘貼</value>
</data>
<data name="CtxMenuRefresh" xml:space="preserve">
<value>刷新</value>
</data>
<data name="CtxMenuRename" xml:space="preserve">
<value>_重命名</value>
</data>
<data name="CtxMenuSortBy" xml:space="preserve">
<value>排序方式</value>
</data>
<data name="CtxMenuSortByName" xml:space="preserve">
<value>名稱</value>
</data>
<data name="CtxMenuSortBySize" xml:space="preserve">
<value>大小</value>
</data>
<data name="CtxMenuSortByType" xml:space="preserve">
<value>類型</value>
</data>
<data name="CtxMenuUnsorted" xml:space="preserve">
<value>未分類</value>
</data>
<data name="HeaderName" xml:space="preserve">
<value>名稱</value>
</data>
<data name="HeaderSize" xml:space="preserve">
<value>大小</value>
</data>
<data name="HeaderType" xml:space="preserve">
<value>類型</value>
</data>
<data name="LabelArchiveFormat" xml:space="preserve">
<value>壓縮檔案格式</value>
</data>
<data name="LabelArchiveName" xml:space="preserve">
<value>壓縮檔案名稱</value>
</data>
<data name="LabelArchiveOptions" xml:space="preserve">
<value>壓縮選項</value>
</data>
<data name="LabelExtractAllTo" xml:space="preserve">
<value>從{0}中提取檔案到</value>
</data>
<data name="LabelExtractFileTo" xml:space="preserve">
<value>將{0}解壓到</value>
</data>
<data name="MenuAbout" xml:space="preserve">
<value>關於遊戲資源瀏覽器(GARbro)</value>
</data>
<data name="MsgDeletedItem" xml:space="preserve">
<value>已刪除{0}</value>
</data>
<data name="MsgDirectoryNotFound" xml:space="preserve">
<value>未找到資料夾。</value>
</data>
<data name="MsgEmptyArchive" xml:space="preserve">
<value>壓縮包無內容。</value>
</data>
<data name="MsgErrorExtracting" xml:space="preserve">
<value>提取檔案失敗。</value>
</data>
<data name="MsgErrorOpening" xml:space="preserve">
<value>打開檔案失敗。</value>
</data>
<data name="MsgExtractComplete" xml:space="preserve">
<value>已將{0}提取至{1}。</value>
</data>
<data name="MsgExtractedFiles1" xml:space="preserve">
<value>已提取檔案:{0}。</value>
</data>
<data name="MsgExtractingArchive" xml:space="preserve">
<value>正在從{0}中提取檔案……</value>
</data>
<data name="MsgExtractingFile" xml:space="preserve">
<value>正在從{0}中提取檔案……</value>
</data>
<data name="MsgExtractingTo" xml:space="preserve">
<value>正在從{0}中提取檔案至{1}……</value>
</data>
<data name="MsgImageSize" xml:space="preserve">
<value>圖像 {0} x {1} x {2}bpp [{3}]</value>
</data>
<data name="MsgNoFiles" xml:space="preserve">
<value>沒有可以提取的檔案。</value>
</data>
<data name="MsgReady" xml:space="preserve">
<value>就緒</value>
</data>
<data name="MsgUnableInterpretImage" xml:space="preserve">
<value>無法讀取圖像格式。</value>
</data>
<data name="MsgVersion" xml:space="preserve">
<value>版本 {0}</value>
</data>
<data name="TextAboutBuiltin" xml:space="preserve">
<value>[內置]</value>
</data>
<data name="TextAboutArchives" xml:space="preserve">
<value>壓縮檔案</value>
</data>
<data name="TextAboutImages" xml:space="preserve">
<value>圖像</value>
</data>
<data name="TextAboutTitle" xml:space="preserve">
<value>關於遊戲資源瀏覽器(GARbro)</value>
</data>
<data name="TextAllFiles" xml:space="preserve">
<value>全部檔案</value>
</data>
<data name="TextAsIs" xml:space="preserve">
<value>保持原樣</value>
</data>
<data name="TextChooseArchive" xml:space="preserve">
<value>選擇壓縮檔案位置</value>
</data>
<data name="TextChooseDestDir" xml:space="preserve">
<value>選擇目標資料夾</value>
</data>
<data name="TextCreateArchive" xml:space="preserve">
<value>創建壓縮檔案</value>
</data>
<data name="TextCreateArchiveError" xml:space="preserve">
<value>創建壓縮檔案失敗。</value>
</data>
<data name="Type_directory" xml:space="preserve">
<value>&lt;資料夾&gt;</value>
</data>
<data name="TextEncoding" xml:space="preserve">
<value>文本編碼</value>
</data>
<data name="TextExtractImages" xml:space="preserve">
<value>提取圖像</value>
</data>
<data name="TextExtractText" xml:space="preserve">
<value>提取文字</value>
</data>
<data name="TextExtractTitle" xml:space="preserve">
<value>從壓縮檔案中提取</value>
</data>
<data name="TextParametersTitle" xml:space="preserve">
<value>壓縮檔案參數</value>
</data>
<data name="TextSaveAs" xml:space="preserve">
<value>另存為</value>
</data>
<data name="TextSaveImagesAs" xml:space="preserve">
<value>將圖像另存為</value>
</data>
<data name="TextTitle" xml:space="preserve">
<value>遊戲資源瀏覽器(GARbro)</value>
</data>
<data name="TooltipBack" xml:space="preserve">
<value>後退</value>
</data>
<data name="TooltipForward" xml:space="preserve">
<value>前進</value>
</data>
<data name="MsgOverwrite" xml:space="preserve">
<value>檔案{0}
已經存在。
是否覆蓋?</value>
</data>
<data name="TextConfirmOverwrite" xml:space="preserve">
<value>確認覆蓋</value>
</data>
<data name="MsgCreatingArchive" xml:space="preserve">
<value>正在創建壓縮檔案{0}</value>
</data>
<data name="MenuOpen" xml:space="preserve">
<value>打開...</value>
</data>
<data name="MenuRecent" xml:space="preserve">
<value>最近使用過的檔案</value>
</data>
<data name="MsgChooseFiles" xml:space="preserve">
<value>請選擇需要提取的檔案</value>
</data>
<data name="MenuExit" xml:space="preserve">
<value>_退出</value>
</data>
<data name="MenuFile" xml:space="preserve">
<value>_檔案</value>
</data>
<data name="MenuHelp" xml:space="preserve">
<value>_幫助</value>
</data>
<data name="MsgExtractedFiles2" xml:space="preserve">
<value>已提取{0}個檔案</value>
</data>
<data name="MsgFiles1" xml:space="preserve">
<value>{0}個檔案</value>
</data>
<data name="MsgFiles2" xml:space="preserve">
<value>{0}個檔案</value>
</data>
<data name="MsgConfirmDeleteFiles" xml:space="preserve">
<value>您確定要刪除這些檔案嗎?</value>
</data>
<data name="TextDeleteFiles" xml:space="preserve">
<value>刪除檔案</value>
</data>
<data name="MsgDeletedItems1" xml:space="preserve">
<value>已刪除{0}個檔案。</value>
</data>
<data name="MsgDeletedItems2" xml:space="preserve">
<value>已刪除{0}個檔案。</value>
</data>
<data name="MenuFitWindow" xml:space="preserve">
<value>讓預覽視窗適應圖像</value>
</data>
<data name="MenuToggleMenuBar" xml:space="preserve">
<value>顯示/隱藏_主選單爛</value>
</data>
<data name="MenuToggleStatusBar" xml:space="preserve">
<value>顯示/隱藏_狀態欄</value>
</data>
<data name="MenuToggleToolBar" xml:space="preserve">
<value>顯示/隱藏_工具欄</value>
</data>
<data name="MenuView" xml:space="preserve">
<value>_視圖</value>
</data>
<data name="CtxMenuConvert" xml:space="preserve">
<value>轉換多媒體檔案...</value>
</data>
<data name="ButtonConvert" xml:space="preserve">
<value>轉換</value>
</data>
<data name="LabelDestinationFormat" xml:space="preserve">
<value>請選擇目標檔案類型</value>
</data>
<data name="TextConvertMedia" xml:space="preserve">
<value>媒體轉換</value>
</data>
<data name="MsgConvertingFile" xml:space="preserve">
<value>正在轉換檔案{0}</value>
</data>
<data name="TextMediaConvertError" xml:space="preserve">
<value>轉換錯誤。</value>
</data>
<data name="LabelEncoding" xml:space="preserve">
<value>正在編碼</value>
</data>
<data name="TextConvertAudio" xml:space="preserve">
<value>將音頻轉換為常規格式</value>
</data>
<data name="TextExtractAudio" xml:space="preserve">
<value>提取音頻</value>
</data>
<data name="TooltipAudioFormats" xml:space="preserve">
<value>WAV,MP3或OGG</value>
</data>
<data name="TextAboutAudio" xml:space="preserve">
<value>音頻</value>
</data>
<data name="TextAboutLicense" xml:space="preserve">
<value>許可證書</value>
</data>
<data name="MsgUnableInterpretAudio" xml:space="preserve">
<value>無法讀取音頻格式。</value>
</data>
<data name="MsgNoMediaFiles" xml:space="preserve">
<value>沒有選擇媒體檔案。</value>
</data>
<data name="TextAudioConversion" xml:space="preserve">
<value>音頻檔案將被轉換為WAV,MP3或OGG格式。</value>
</data>
<data name="LabelSkipFailures" xml:space="preserve">
<value>跳過不可轉換的檔案</value>
</data>
<data name="MsgNoMatching" xml:space="preserve">
<value>沒有與「{0}」匹配的項目。</value>
</data>
<data name="MsgSelectedFiles1" xml:space="preserve">
<value>選中{0}個檔案。</value>
</data>
<data name="MsgSelectedFiles2" xml:space="preserve">
<value>選中{0}個檔案。</value>
</data>
<data name="LabelEnterMask" xml:space="preserve">
<value>請輸入通配符掩碼</value>
</data>
<data name="TextSelectFiles" xml:space="preserve">
<value>選擇檔案</value>
</data>
<data name="TextErrorExtracting" xml:space="preserve">
<value>提取{0}時發生錯誤。
{1}</value>
</data>
<data name="CtxMenuFileType" xml:space="preserve">
<value>選擇檔案類型</value>
</data>
<data name="Type_NONE" xml:space="preserve">
<value>無</value>
</data>
<data name="LabelDestinationDir" xml:space="preserve">
<value>目標資料夾</value>
</data>
<data name="MsgPlaying" xml:space="preserve">
<value>正在播放 {0} / {3} / {2}bps / {1}Hz</value>
<comment>{0}=filename, {1}=sampling rate, {2}=bitrate, {3}=total time </comment>
</data>
<data name="LabelDevSite" xml:space="preserve">
<value>項目主頁</value>
</data>
<data name="CtxMenuSelectByMask" xml:space="preserve">
<value>用代號選擇檔案……</value>
</data>
<data name="ButtonAbort" xml:space="preserve">
<value>中止</value>
</data>
<data name="ButtonContinue" xml:space="preserve">
<value>繼續</value>
</data>
<data name="LabelIgnoreErrors" xml:space="preserve">
<value>忽略錯誤</value>
</data>
<data name="TextExtractionError" xml:space="preserve">
<value>檔案提取錯誤</value>
</data>
<data name="ButtonOverwrite" xml:space="preserve">
<value>覆蓋</value>
</data>
<data name="ButtonRename" xml:space="preserve">
<value>重命名</value>
</data>
<data name="ButtonSkip" xml:space="preserve">
<value>跳過</value>
</data>
<data name="LabelApplyToAll" xml:space="preserve">
<value>應用於所有重複檔案</value>
</data>
<data name="LabelDuplicateFileQuestion" xml:space="preserve">
<value>應該做什麼?</value>
</data>
<data name="TextErrorConverting" xml:space="preserve">
<value>轉換檔案時發生錯誤
{0}
{1}</value>
</data>
<data name="TextFileAlreadyExists" xml:space="preserve">
<value>檔案{0}已經存在。</value>
</data>
<data name="ButtonDownload" xml:space="preserve">
<value>下載</value>
</data>
<data name="LabelReleaseNotes" xml:space="preserve">
<value>發行註記</value>
</data>
<data name="MenuCheckUpdates" xml:space="preserve">
<value>檢查更新……</value>
</data>
<data name="MsgNoUpdates" xml:space="preserve">
<value>無可用更新。</value>
</data>
<data name="MsgUpdateAvailable" xml:space="preserve">
<value>有可用格式數據庫更新。</value>
</data>
<data name="MsgUpdateComplete" xml:space="preserve">
<value>格式數據庫已更新。</value>
</data>
<data name="MsgUpdateFailed" xml:space="preserve">
<value>更新檢查失敗。</value>
</data>
<data name="MsgUpToDate" xml:space="preserve">
<value>GARbro 已是最新版本。</value>
</data>
<data name="TextNewVersion" xml:space="preserve">
<value>新版本已可用:</value>
</data>
<data name="TextUpdateTitle" xml:space="preserve">
<value>應用程序更新</value>
</data>
<data name="TextVisitPage" xml:space="preserve">
<value>訪問下載頁面</value>
</data>
<data name="MsgDownloadFailed" xml:space="preserve">
<value>更新下載失敗。</value>
</data>
<data name="ButtonApply" xml:space="preserve">
<value>應用</value>
</data>
<data name="MenuPreferences" xml:space="preserve">
<value>偏好設置</value>
</data>
<data name="TextFormats" xml:space="preserve">
<value>格式</value>
</data>
<data name="TextPreferences" xml:space="preserve">
<value>偏好設置</value>
</data>
<data name="TextViewer" xml:space="preserve">
<value>圖像查看器</value>
</data>
<data name="winDownScaleImage" xml:space="preserve">
<value>縮放大圖以適應視窗</value>
</data>
<data name="Type_archive" xml:space="preserve">
<value>檔案</value>
</data>
<data name="Type_audio" xml:space="preserve">
<value>音頻</value>
</data>
<data name="Type_image" xml:space="preserve">
<value>圖像</value>
</data>
<data name="Type_script" xml:space="preserve">
<value>腳本</value>
</data>
<data name="TextOK" xml:space="preserve">
<value>確認</value>
</data>
<data name="Type_video" xml:space="preserve">
<value>影片</value>
</data>
</root>

View File

@@ -144,6 +144,7 @@
</EmbeddedResource>
<EmbeddedResource Include="Strings\garStrings.ru-RU.resx" />
<EmbeddedResource Include="Strings\garStrings.zh-Hans.resx" />
<EmbeddedResource Include="Strings\garStrings.zh-Hant.resx" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

View File

@@ -0,0 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BMPExtensionsDesc" xml:space="preserve">
<value>啟用各種擴展,如透明度支持</value>
</data>
<data name="BMPExtensionsText" xml:space="preserve">
<value>啟用 BMP 格式擴展</value>
</data>
<data name="JPEGQualityText" xml:space="preserve">
<value>JPEG 壓縮品質</value>
</data>
<data name="MsgFileIsEmpty" xml:space="preserve">
<value>檔案為空。</value>
</data>
<data name="MsgFileTooLarge" xml:space="preserve">
<value>檔案尺寸太大。</value>
</data>
<data name="MsgInvalidEncryption" xml:space="preserve">
<value>不正確的加密方式。</value>
</data>
<data name="MsgInvalidFileName" xml:space="preserve">
<value>無效的檔案名。</value>
</data>
<data name="MsgInvalidFormat" xml:space="preserve">
<value>無效的檔案格式。</value>
</data>
<data name="MsgUnknownEncryption" xml:space="preserve">
<value>未知的加密方式。</value>
</data>
<data name="MsgUnknownFormat" xml:space="preserve">
<value>無法作為壓縮包打開檔案。</value>
</data>
</root>

View File

@@ -23,6 +23,10 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -43,6 +47,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -5,6 +5,10 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -25,6 +29,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -5,6 +5,10 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -25,6 +29,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -5,6 +5,10 @@
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.Numerics" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Registry" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
@@ -25,6 +29,10 @@
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.CodePages" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.5" newVersion="10.0.0.5" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="LocalSource" value=".\nupkg" />
</packageSources>
</configuration>

View File

Binary file not shown.