mirror of
https://github.com/crskycode/GARbro.git
synced 2025-01-12 04:49:32 +08:00
(Xp3Opener): decrypt text entries.
This commit is contained in:
parent
fc6192bb2f
commit
4262db76fb
@ -32,8 +32,6 @@ using System.Linq;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using GameRes.Compression;
|
using GameRes.Compression;
|
||||||
using GameRes.Utility;
|
using GameRes.Utility;
|
||||||
@ -340,20 +338,72 @@ NextEntry:
|
|||||||
var xp3_entry = entry as Xp3Entry;
|
var xp3_entry = entry as Xp3Entry;
|
||||||
if (null == xp3_entry)
|
if (null == xp3_entry)
|
||||||
return arc.File.CreateStream (entry.Offset, entry.Size);
|
return arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
// Trace.WriteLine (string.Format ("{0,-16} {3:X8} {1,11} {2,12}", xp3_entry.Name,
|
|
||||||
// xp3_entry.IsEncrypted ? "[encrypted]" : "",
|
Stream input;
|
||||||
// xp3_entry.Segments.First().IsCompressed ? "[compressed]" : "",
|
|
||||||
// xp3_entry.Hash));
|
|
||||||
if (1 == xp3_entry.Segments.Count && !xp3_entry.IsEncrypted)
|
if (1 == xp3_entry.Segments.Count && !xp3_entry.IsEncrypted)
|
||||||
{
|
{
|
||||||
var segment = xp3_entry.Segments.First();
|
var segment = xp3_entry.Segments.First();
|
||||||
if (segment.IsCompressed)
|
if (segment.IsCompressed)
|
||||||
return new ZLibStream (arc.File.CreateStream (segment.Offset, segment.PackedSize),
|
input = new ZLibStream (arc.File.CreateStream (segment.Offset, segment.PackedSize),
|
||||||
CompressionMode.Decompress);
|
CompressionMode.Decompress);
|
||||||
else
|
else
|
||||||
return arc.File.CreateStream (segment.Offset, segment.Size);
|
input = arc.File.CreateStream (segment.Offset, segment.Size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input = new Xp3Stream (arc.File, xp3_entry);
|
||||||
|
|
||||||
|
if (entry.Size <= 5 || "image" == entry.Type || "audio" == entry.Type)
|
||||||
|
return input;
|
||||||
|
|
||||||
|
var header = new byte[5];
|
||||||
|
input.Read (header, 0, 5);
|
||||||
|
if (0xFE == header[0] && 0xFE == header[1] && header[2] < 3 && 0xFF == header[3] && 0xFE == header[4])
|
||||||
|
return DecryptScript (header[2], input, xp3_entry.UnpackedSize);
|
||||||
|
|
||||||
|
if (!input.CanSeek)
|
||||||
|
return new PrefixStream (header, input);
|
||||||
|
input.Position = 0;
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream DecryptScript (int enc_type, Stream input, uint unpacked_size)
|
||||||
|
{
|
||||||
|
using (var reader = new BinaryReader (input, Encoding.Unicode, true))
|
||||||
|
{
|
||||||
|
if (2 == enc_type)
|
||||||
|
{
|
||||||
|
reader.ReadInt64(); // packed_size
|
||||||
|
reader.ReadInt64(); // unpacked_size
|
||||||
|
return new ZLibStream (input, CompressionMode.Decompress);
|
||||||
|
}
|
||||||
|
var output = new MemoryStream ((int)unpacked_size+2);
|
||||||
|
using (var writer = new BinaryWriter (output, Encoding.Unicode, true))
|
||||||
|
{
|
||||||
|
writer.Write ('\xFEFF'); // BOM
|
||||||
|
int c;
|
||||||
|
if (1 == enc_type)
|
||||||
|
{
|
||||||
|
while ((c = reader.Read()) != -1)
|
||||||
|
{
|
||||||
|
c = (c & 0xAAAA) >> 1 | (c & 0x5555) << 1;
|
||||||
|
writer.Write ((char)c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((c = reader.Read()) != -1)
|
||||||
|
{
|
||||||
|
if (c >= 0x20)
|
||||||
|
{
|
||||||
|
c = c ^ (((c & 0xFE) << 8) ^ 1);
|
||||||
|
writer.Write ((char)c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.Position = 0;
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
return new Xp3Stream (arc.File, xp3_entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ResourceOptions GetDefaultOptions ()
|
public override ResourceOptions GetDefaultOptions ()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user