mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-27 15:44:00 +08:00
(DAT/hibiki): try to read archive index from adjacent archive.
This commit is contained in:
parent
32b256b013
commit
18f52a78f8
@ -49,12 +49,22 @@ namespace GameRes.Formats.YaneSDK
|
|||||||
{
|
{
|
||||||
if (!file.Name.HasExtension (".dat"))
|
if (!file.Name.HasExtension (".dat"))
|
||||||
return null;
|
return null;
|
||||||
int count = (short)(file.View.ReadUInt16 (0) ^ 0x8080);
|
int count = ReadCount (file);
|
||||||
if (!IsSaneCount (count))
|
if (!IsSaneCount (count))
|
||||||
return null;
|
return null;
|
||||||
var scheme = QueryScheme (file.Name);
|
var scheme = QueryScheme (file.Name);
|
||||||
if (null == scheme)
|
if (null == scheme)
|
||||||
return null;
|
return null;
|
||||||
|
return TryOpenWithScheme (file, count, scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ReadCount (ArcView file)
|
||||||
|
{
|
||||||
|
return (short)(file.View.ReadUInt16 (0) ^ 0x8080);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcFile TryOpenWithScheme (ArcView file, int count, HibikiDatScheme scheme)
|
||||||
|
{
|
||||||
var dat_name = Path.GetFileName (file.Name).ToLowerInvariant();
|
var dat_name = Path.GetFileName (file.Name).ToLowerInvariant();
|
||||||
IList<HibikiTocRecord> toc_table = null;
|
IList<HibikiTocRecord> toc_table = null;
|
||||||
if (scheme.ArcMap != null && scheme.ArcMap.TryGetValue (dat_name, out toc_table))
|
if (scheme.ArcMap != null && scheme.ArcMap.TryGetValue (dat_name, out toc_table))
|
||||||
@ -62,17 +72,12 @@ namespace GameRes.Formats.YaneSDK
|
|||||||
if (toc_table.Count != count)
|
if (toc_table.Count != count)
|
||||||
toc_table = null;
|
toc_table = null;
|
||||||
}
|
}
|
||||||
var lst_name = Path.ChangeExtension (file.Name, ".lst");
|
using (var input = OpenLstIndex (file, dat_name, scheme))
|
||||||
Stream input;
|
|
||||||
if (VFS.FileExists (lst_name))
|
|
||||||
input = VFS.OpenStream (lst_name);
|
|
||||||
else
|
|
||||||
input = file.CreateStream();
|
|
||||||
|
|
||||||
using (var dec = new XoredStream (input, 0x80))
|
using (var dec = new XoredStream (input, 0x80))
|
||||||
using (var index = new BinaryReader (dec))
|
using (var index = new BinaryReader (dec))
|
||||||
{
|
{
|
||||||
const int name_length = 0x100;
|
const int name_length = 0x100;
|
||||||
|
int data_offset = 2 + (name_length + 10) * count;
|
||||||
index.BaseStream.Position = 2;
|
index.BaseStream.Position = 2;
|
||||||
Func<int, Entry> read_entry;
|
Func<int, Entry> read_entry;
|
||||||
if (null == toc_table)
|
if (null == toc_table)
|
||||||
@ -105,7 +110,8 @@ namespace GameRes.Formats.YaneSDK
|
|||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
var entry = read_entry (i);
|
var entry = read_entry (i);
|
||||||
if (!entry.CheckPlacement (file.MaxOffset))
|
if (null == entry || string.IsNullOrWhiteSpace (entry.Name)
|
||||||
|
|| entry.Offset < data_offset || entry.Size > file.MaxOffset)
|
||||||
return null;
|
return null;
|
||||||
dir.Add (entry);
|
dir.Add (entry);
|
||||||
}
|
}
|
||||||
@ -113,6 +119,33 @@ namespace GameRes.Formats.YaneSDK
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream OpenLstIndex (ArcView file, string dat_name, HibikiDatScheme scheme)
|
||||||
|
{
|
||||||
|
var lst_name = Path.ChangeExtension (file.Name, ".lst");
|
||||||
|
if (VFS.FileExists (lst_name))
|
||||||
|
return VFS.OpenStream (lst_name);
|
||||||
|
else if ("init.dat" == dat_name)
|
||||||
|
return file.CreateStream();
|
||||||
|
// try to open 'init.dat' archive in the same directory
|
||||||
|
var init_dat = VFS.CombinePath (VFS.GetDirectoryName (file.Name), "init.dat");
|
||||||
|
if (!VFS.FileExists (init_dat))
|
||||||
|
return file.CreateStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var init = VFS.OpenView (init_dat))
|
||||||
|
using (var init_arc = TryOpenWithScheme (init, ReadCount (init), scheme))
|
||||||
|
{
|
||||||
|
lst_name = Path.GetFileName (lst_name);
|
||||||
|
var lst_entry = init_arc.Dir.First (e => e.Name == lst_name);
|
||||||
|
return init_arc.OpenEntry (lst_entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return file.CreateStream();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
{
|
{
|
||||||
var harc = arc as HibikiArchive;
|
var harc = arc as HibikiArchive;
|
||||||
|
Loading…
Reference in New Issue
Block a user