From d37285960f4096d0c9e06e4f9961a80d99bf516c Mon Sep 17 00:00:00 2001 From: scientificworld Date: Fri, 9 Jan 2026 11:13:05 +0800 Subject: [PATCH] feat: (DAT/TIMELEAP) add support for unencrypted archive used in trial edition --- ArcFormats/FrontWing/ArcDAT.cs | 47 ++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/ArcFormats/FrontWing/ArcDAT.cs b/ArcFormats/FrontWing/ArcDAT.cs index 9abbb8bb..3a1ce1a1 100644 --- a/ArcFormats/FrontWing/ArcDAT.cs +++ b/ArcFormats/FrontWing/ArcDAT.cs @@ -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 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 (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); }