mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
feat: (DAT/TIMELEAP) add support for unencrypted archive used in trial edition
This commit is contained in:
@@ -31,6 +31,19 @@ using GameRes.Utility;
|
|||||||
|
|
||||||
namespace GameRes.Formats.FrontWing
|
namespace GameRes.Formats.FrontWing
|
||||||
{
|
{
|
||||||
|
internal class TimeLeapArchive : ArcFile
|
||||||
|
{
|
||||||
|
private bool m_encrypted;
|
||||||
|
|
||||||
|
public bool IsEncrypted { get { return m_encrypted; } }
|
||||||
|
|
||||||
|
public TimeLeapArchive (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, bool encrypted)
|
||||||
|
: base (arc, impl, dir)
|
||||||
|
{
|
||||||
|
m_encrypted = encrypted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Export(typeof(ArchiveFormat))]
|
[Export(typeof(ArchiveFormat))]
|
||||||
public class DatOpener : ArchiveFormat
|
public class DatOpener : ArchiveFormat
|
||||||
{
|
{
|
||||||
@@ -52,7 +65,17 @@ namespace GameRes.Formats.FrontWing
|
|||||||
if (file.MaxOffset < index_size + 4)
|
if (file.MaxOffset < index_size + 4)
|
||||||
return null;
|
return null;
|
||||||
var index = file.View.ReadBytes (file.MaxOffset - 4 - index_size, (uint)index_size);
|
var index = file.View.ReadBytes (file.MaxOffset - 4 - index_size, (uint)index_size);
|
||||||
NibbleSwap (index);
|
bool encrypted = false;
|
||||||
|
for (int i = 0; i < 40 && index[i] != 0; i++)
|
||||||
|
{
|
||||||
|
if (index[i] < 0x20 || index[i] >= 0x7f)
|
||||||
|
{
|
||||||
|
encrypted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (encrypted)
|
||||||
|
NibbleSwap (index);
|
||||||
|
|
||||||
int index_offset = 0;
|
int index_offset = 0;
|
||||||
var dir = new List<Entry> (count);
|
var dir = new List<Entry> (count);
|
||||||
@@ -67,7 +90,7 @@ namespace GameRes.Formats.FrontWing
|
|||||||
index_offset += 0x50;
|
index_offset += 0x50;
|
||||||
dir.Add (entry);
|
dir.Add (entry);
|
||||||
}
|
}
|
||||||
return new ArcFile (file, this, dir);
|
return new TimeLeapArchive (file, this, dir, encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly byte[] keyTable = {
|
static readonly byte[] keyTable = {
|
||||||
@@ -80,16 +103,20 @@ namespace GameRes.Formats.FrontWing
|
|||||||
|
|
||||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
{
|
{
|
||||||
var data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
|
var tarc = arc as TimeLeapArchive;
|
||||||
for (int i = 1; i < data.Length; i += 4)
|
var data = tarc.File.View.ReadBytes (entry.Offset, entry.Size);
|
||||||
|
if (tarc.IsEncrypted)
|
||||||
{
|
{
|
||||||
data[i] = (byte)(-data[i] & 0xff);
|
for (int i = 1; i < data.Length; i += 4)
|
||||||
|
{
|
||||||
|
data[i] = (byte)(-data[i] & 0xff);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < data.Length; i += 3)
|
||||||
|
{
|
||||||
|
data[i] ^= keyTable[i / 5 % 5 + i % 6];
|
||||||
|
}
|
||||||
|
NibbleSwap (data, 2, 6);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < data.Length; i += 3)
|
|
||||||
{
|
|
||||||
data[i] ^= keyTable[i / 5 % 5 + i % 6];
|
|
||||||
}
|
|
||||||
NibbleSwap(data, 2, 6);
|
|
||||||
return new BinMemoryStream (data);
|
return new BinMemoryStream (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user