feat: (DAT/TIMELEAP) add support for unencrypted archive used in trial edition

This commit is contained in:
scientificworld
2026-01-09 11:13:05 +08:00
parent 402b2fb7ca
commit d37285960f

View File

@@ -31,6 +31,19 @@ using GameRes.Utility;
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))]
public class DatOpener : ArchiveFormat
{
@@ -52,7 +65,17 @@ namespace GameRes.Formats.FrontWing
if (file.MaxOffset < index_size + 4)
return null;
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;
var dir = new List<Entry> (count);
@@ -67,7 +90,7 @@ namespace GameRes.Formats.FrontWing
index_offset += 0x50;
dir.Add (entry);
}
return new ArcFile (file, this, dir);
return new TimeLeapArchive (file, this, dir, encrypted);
}
static readonly byte[] keyTable = {
@@ -80,16 +103,20 @@ namespace GameRes.Formats.FrontWing
public override Stream OpenEntry (ArcFile arc, Entry entry)
{
var data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
for (int i = 1; i < data.Length; i += 4)
var tarc = arc as TimeLeapArchive;
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);
}