Improve archives for FE3H.

Can be opened within an archive like an NSP.
Will work properly on the existing data0/data1.bin names
This commit is contained in:
KillzXGaming 2019-09-15 16:01:50 -04:00
parent 3bfbafbada
commit 4d72a725c5

View file

@ -7,6 +7,7 @@ using Toolbox;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using System.IO;
namespace FirstPlugin
{
@ -16,7 +17,7 @@ namespace FirstPlugin
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Fire Emblem Three Houses Archive" };
public string[] Extension { get; set; } = new string[] { "*.idx" };
public string[] Extension { get; set; } = new string[] { "*.bin" , "*.idx" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
@ -28,7 +29,7 @@ namespace FirstPlugin
public bool Identify(System.IO.Stream stream)
{
return (FileName == "LINKDATA.IDX");
return (FileName == "LINKDATA.IDX" || FileName == "DATA0.bin");
}
public Type[] Types
@ -57,7 +58,7 @@ namespace FirstPlugin
for (int i = 0; i < FileCount; i++)
{
FileEntry entry = new FileEntry(FilePath);
FileEntry entry = new FileEntry(FilePath, this);
entry.FileName = $"file {i}";
entry.Read(reader);
@ -88,6 +89,8 @@ namespace FirstPlugin
public class FileEntry : ArchiveFileInfo
{
private LINKDATA ParentFile;
public string SourcePath { get; set; }
public ulong Offset;
@ -95,8 +98,9 @@ namespace FirstPlugin
public ulong CompSize;
public ulong CompFlags;
public FileEntry(string path) {
public FileEntry(string path, LINKDATA data) {
SourcePath = path;
ParentFile = data;
}
public void Read(FileReader reader)
@ -107,36 +111,61 @@ namespace FirstPlugin
CompFlags = reader.ReadUInt64();
}
public override byte[] FileData
public override Stream FileDataStream
{
get
{
string path = SourcePath.Replace("IDX", "BIN");
if (!System.IO.File.Exists(path))
return new byte[0];
using (var reader = new FileReader(path))
if (ParentFile.IFileInfo.ArchiveParent != null)
{
reader.SeekBegin((long)Offset);
if (CompFlags != 0)
foreach (var file in ParentFile.IFileInfo.ArchiveParent.Files)
{
uint chunkSize = reader.ReadUInt32();
uint numChunks = reader.ReadUInt32();
uint size = reader.ReadUInt32();
if (chunkSize == 0xffffffff)
if (file.FileName.Contains("DATA1.bin"))
{
return GetData(new FileReader(file.FileDataStream, true));
}
reader.SeekBegin((long)Offset);
return reader.ReadBytes((int)Size);
}
else
return reader.ReadBytes((int)Size);
return new MemoryStream();
}
else
{
string path = "";
if (SourcePath.Contains("LINKDATA.IDX"))
path = SourcePath.Replace("IDX", "BIN");
if (SourcePath.Contains("DATA1.bin"))
path = SourcePath.Replace("DATA0", "DATA1");
if (!System.IO.File.Exists(path))
return new MemoryStream();
using (var reader = new FileReader(path, true))
{
return GetData(reader);
}
}
}
}
private Stream GetData(FileReader reader)
{
reader.SeekBegin((long)Offset);
if (CompFlags != 0)
{
uint chunkSize = reader.ReadUInt32();
uint numChunks = reader.ReadUInt32();
uint size = reader.ReadUInt32();
if (chunkSize == 0xffffffff)
{
}
reader.SeekBegin((long)Offset);
return new SubStream(reader.BaseStream, (long)Offset, (long)Size);
}
else
return new SubStream(reader.BaseStream, (long)Offset, (long)Size);
}
}
}
}