mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
support old LPK archives with different index entry size.
This commit is contained in:
@@ -104,7 +104,7 @@ namespace GameRes.Formats.Lucifen
|
|||||||
public static readonly Dictionary<string, EncryptionScheme> KnownSchemes =
|
public static readonly Dictionary<string, EncryptionScheme> KnownSchemes =
|
||||||
new Dictionary<string, EncryptionScheme> {
|
new Dictionary<string, EncryptionScheme> {
|
||||||
{ "Default", DefaultScheme },
|
{ "Default", DefaultScheme },
|
||||||
{ "Lycoris Radiata", new EncryptionScheme {
|
{ "Terios games", new EncryptionScheme {
|
||||||
BaseKey = new Key (0x39A5B67D, 0xD63AB5E9), ContentXor = 0xa6, RotatePattern = 0x36147352,
|
BaseKey = new Key (0x39A5B67D, 0xD63AB5E9), ContentXor = 0xa6, RotatePattern = 0x36147352,
|
||||||
ImportGameInit = false } },
|
ImportGameInit = false } },
|
||||||
};
|
};
|
||||||
@@ -182,9 +182,9 @@ namespace GameRes.Formats.Lucifen
|
|||||||
{
|
{
|
||||||
if (0 == CurrentFileMap.Count)
|
if (0 == CurrentFileMap.Count)
|
||||||
ImportKeys (file.Name);
|
ImportKeys (file.Name);
|
||||||
|
if (!CurrentFileMap.TryGetValue (name, out file_key))
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
if (!CurrentFileMap.TryGetValue (name, out file_key) && CurrentScheme.ImportGameInit)
|
|
||||||
return null;
|
|
||||||
return Open (basename, file, CurrentScheme, file_key);
|
return Open (basename, file, CurrentScheme, file_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,13 +421,15 @@ namespace GameRes.Formats.Lucifen
|
|||||||
int m_index_width;
|
int m_index_width;
|
||||||
int m_entries_offset;
|
int m_entries_offset;
|
||||||
|
|
||||||
public LpkInfo Info { get { return m_info; } }
|
public LpkInfo Info { get { return m_info; } }
|
||||||
|
public int EntrySize { get; private set; }
|
||||||
|
|
||||||
public IndexReader (LpkInfo info)
|
public IndexReader (LpkInfo info)
|
||||||
{
|
{
|
||||||
if (!info.Flag1)
|
if (!info.Flag1)
|
||||||
throw new NotSupportedException ("Not supported LPK index format");
|
throw new NotSupportedException ("Not supported LPK index format");
|
||||||
m_info = info;
|
m_info = info;
|
||||||
|
EntrySize = m_info.PackedEntries ? 13 : 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Entry> Read (byte[] index)
|
public List<Entry> Read (byte[] index)
|
||||||
@@ -448,6 +450,12 @@ namespace GameRes.Formats.Lucifen
|
|||||||
int letter_table_length = LittleEndian.ToInt32 (m_index, index_offset);
|
int letter_table_length = LittleEndian.ToInt32 (m_index, index_offset);
|
||||||
index_offset += 4;
|
index_offset += 4;
|
||||||
m_entries_offset = index_offset + letter_table_length;
|
m_entries_offset = index_offset + letter_table_length;
|
||||||
|
if (m_entries_offset >= m_index.Length)
|
||||||
|
return null;
|
||||||
|
if ((m_index.Length - m_entries_offset) / EntrySize < count)
|
||||||
|
EntrySize = (m_index.Length - m_entries_offset) / count;
|
||||||
|
if (EntrySize < 8 || m_info.PackedEntries && EntrySize < 12)
|
||||||
|
return null;
|
||||||
|
|
||||||
m_dir = new List<Entry> (count);
|
m_dir = new List<Entry> (count);
|
||||||
m_name = new byte[260];
|
m_name = new byte[260];
|
||||||
@@ -486,16 +494,16 @@ namespace GameRes.Formats.Lucifen
|
|||||||
Type = FormatCatalog.Instance.GetTypeFromName (name),
|
Type = FormatCatalog.Instance.GetTypeFromName (name),
|
||||||
IsPacked = m_info.PackedEntries,
|
IsPacked = m_info.PackedEntries,
|
||||||
};
|
};
|
||||||
int entry_size = m_info.PackedEntries ? 13 : 9;
|
int entry_pos = m_entries_offset + EntrySize * entry_num;
|
||||||
int entry_pos = m_entries_offset + entry_size*entry_num;
|
if (entry_pos+EntrySize > m_index.Length)
|
||||||
if (entry_pos+entry_size > m_index.Length)
|
|
||||||
throw new InvalidFormatException ("Invalid LPK entry index");
|
throw new InvalidFormatException ("Invalid LPK entry index");
|
||||||
entry.Flag = m_index[entry_pos];
|
if (0 != (EntrySize & 1))
|
||||||
long offset = LittleEndian.ToUInt32 (m_index, entry_pos+1);
|
entry.Flag = m_index[entry_pos++];
|
||||||
|
long offset = LittleEndian.ToUInt32 (m_index, entry_pos);
|
||||||
entry.Offset = m_info.AlignedOffset ? offset << 11 : offset;
|
entry.Offset = m_info.AlignedOffset ? offset << 11 : offset;
|
||||||
entry.Size = LittleEndian.ToUInt32 (m_index, entry_pos+5);
|
entry.Size = LittleEndian.ToUInt32 (m_index, entry_pos+4);
|
||||||
if (entry.IsPacked)
|
if (entry.IsPacked)
|
||||||
entry.UnpackedSize = LittleEndian.ToUInt32 (m_index, entry_pos+9);
|
entry.UnpackedSize = LittleEndian.ToUInt32 (m_index, entry_pos+8);
|
||||||
else
|
else
|
||||||
entry.UnpackedSize = entry.Size;
|
entry.UnpackedSize = entry.Size;
|
||||||
m_dir.Add (entry);
|
m_dir.Add (entry);
|
||||||
|
|||||||
Reference in New Issue
Block a user