mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-24 20:04:13 +08:00
(XP3): recognize filenames stored in hash table.
This commit is contained in:
parent
86fb8d4a0e
commit
69e29dc0f9
@ -148,6 +148,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
|
||||
var crypt_algorithm = new Lazy<ICrypt> (QueryCryptAlgorithm);
|
||||
|
||||
var filename_map = new Dictionary<uint, string>();
|
||||
var dir = new List<Entry>();
|
||||
dir_offset = 0;
|
||||
using (var header = new BinaryReader (header_stream, Encoding.Unicode))
|
||||
@ -155,12 +156,22 @@ namespace GameRes.Formats.KiriKiri
|
||||
while (-1 != header.PeekChar())
|
||||
{
|
||||
uint entry_signature = header.ReadUInt32();
|
||||
if (0x656c6946 != entry_signature) // "File"
|
||||
{
|
||||
break;
|
||||
}
|
||||
long entry_size = header.ReadInt64();
|
||||
if (entry_size < 0)
|
||||
return null;
|
||||
dir_offset += 12 + entry_size;
|
||||
if (0x6E666E68 == entry_signature) // "hnfn"
|
||||
{
|
||||
uint hash = header.ReadUInt32();
|
||||
int name_size = header.ReadInt16();
|
||||
entry_size -= 6;
|
||||
if (name_size * 2 <= entry_size)
|
||||
{
|
||||
filename_map[hash] = new string (header.ReadChars (name_size));
|
||||
}
|
||||
}
|
||||
else if (0x656C6946 == entry_signature) // "File"
|
||||
{
|
||||
var entry = new Xp3Entry();
|
||||
while (entry_size > 0)
|
||||
{
|
||||
@ -174,7 +185,6 @@ namespace GameRes.Formats.KiriKiri
|
||||
switch (section)
|
||||
{
|
||||
case 0x6f666e69: // "info"
|
||||
{
|
||||
if (entry.Size != 0 || !string.IsNullOrEmpty (entry.Name))
|
||||
{
|
||||
goto NextEntry; // ambiguous entry, ignore
|
||||
@ -200,19 +210,21 @@ namespace GameRes.Formats.KiriKiri
|
||||
else
|
||||
entry.Cipher = NoCryptAlgorithm;
|
||||
|
||||
var name = new string (header.ReadChars (name_size));
|
||||
string name = null;
|
||||
if (0 == filename_map.Count || !filename_map.TryGetValue (entry.Hash, out name))
|
||||
{
|
||||
name = new string (header.ReadChars (name_size));
|
||||
if (entry.Cipher.ObfuscatedIndex && ObfuscatedPathRe.IsMatch (name))
|
||||
{
|
||||
goto NextEntry;
|
||||
}
|
||||
}
|
||||
entry.Name = name;
|
||||
entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
|
||||
entry.IsEncrypted = !(entry.Cipher is NoCrypt)
|
||||
&& !(entry.Cipher.StratupTjsNotEncrypted && "startup.tjs" == name);
|
||||
break;
|
||||
}
|
||||
case 0x6d676573: // "segm"
|
||||
{
|
||||
int segment_count = (int)(section_size / 0x1c);
|
||||
if (segment_count > 0)
|
||||
{
|
||||
@ -237,7 +249,6 @@ namespace GameRes.Formats.KiriKiri
|
||||
entry.Offset = entry.Segments.First().Offset;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x726c6461: // "adlr"
|
||||
if (4 == section_size)
|
||||
entry.Hash = header.ReadUInt32();
|
||||
@ -256,10 +267,13 @@ namespace GameRes.Formats.KiriKiri
|
||||
}
|
||||
dir.Add (entry);
|
||||
}
|
||||
}
|
||||
NextEntry:
|
||||
header.BaseStream.Position = dir_offset;
|
||||
}
|
||||
}
|
||||
if (0 == dir.Count)
|
||||
return null;
|
||||
var arc = new ArcFile (file, this, dir);
|
||||
try
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user