public void ReBuild()
{
string path = Path.GetDirectoryName(FileName) + "\\" + Path.GetFileNameWithoutExtension(FileName) + ".tmp";
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
DebugOutput.PrintLn("Creating Header Dummy...");
for (int i = 0; i < 8; i++)
fs.Write(BitConverter.GetBytes(0), 0, 4);
Header.EntryOffset = 0x20;
DebugOutput.PrintLn("Creating File Table...");
for (int i = 0; i < Header.FileCount; i++)
{
FileEntryStruct e = Files[i];
fs.Write(e.Hash, 0, 16);
fs.Write(BitConverter.GetBytes(e.BlockSizeIndex), 0, 4);
fs.Write(BitConverter.GetBytes(e.UncompressedSize), 0, 4);
fs.WriteByte(e.UncompressedSizeAdder);
fs.Write(BitConverter.GetBytes(e.DataOffset), 0, 4);
fs.WriteByte(e.DataOffsetAdder);
}
Header.BlockTableOffset = (uint)fs.Position;
DebugOutput.PrintLn("Creating Block Table...");
for (int i = 0; i < Header.FileCount; i++)
if (Files[i].BlockSizeIndex != 0xFFFFFFFF)
foreach (ushort u in Files[i].BlockSizes)
fs.Write(BitConverter.GetBytes(u), 0, 2);
Header.DataOffset = (uint)fs.Position;
DebugOutput.PrintLn("Appending Files...");
uint pos = (uint)fs.Position;
for (int i = 0; i < Header.FileCount; i++)
{
List<byte[]> blocks = GetBlocks(i);
FileEntryStruct e = Files[i];
DebugOutput.PrintLn("Rebuilding \"" + e.FileName + "\" (" + (i + 1) + "/" + Header.FileCount + ") " + BytesToString(e.UncompressedSize) + " ...");
e.DataOffset = pos;
e.DataOffsetAdder = 0;
for (int j = 0; j < blocks.Count; j++)
{
MemoryStream m = new MemoryStream(blocks[j]);
fs.Write(m.ToArray(), 0, (int)m.Length);
pos += (uint)m.Length;
}
Files[i] = e;
}
DebugOutput.PrintLn("Updating FileTable...");
fs.Seek(0x20, 0);
pos = (uint)fs.Position;
uint blocksizeindex = 0;
for (int i = 0; i < Header.FileCount; i++)
{
FileEntryStruct e = Files[i];
fs.Write(e.Hash, 0, 16);
if (e.BlockSizeIndex != 0xFFFFFFFF)
{
fs.Write(BitConverter.GetBytes(blocksizeindex), 0, 4);
e.BlockSizeIndex = blocksizeindex;
blocksizeindex += (uint)e.BlockSizes.Length;
}
else
fs.Write(BitConverter.GetBytes(0xFFFFFFFF), 0, 4);
fs.Write(BitConverter.GetBytes(e.UncompressedSize), 0, 4);
fs.WriteByte(e.UncompressedSizeAdder);
fs.Write(BitConverter.GetBytes(e.DataOffset), 0, 4);
fs.WriteByte(e.DataOffsetAdder);
e.MyOffset = pos;
Files[i] = e;
pos += 0x1E;
}
fs.Seek(0, 0);
DebugOutput.PrintLn("Rebuilding Header...");
fs.Write(BitConverter.GetBytes(Header.Magic), 0, 4);
fs.Write(BitConverter.GetBytes(Header.Version), 0, 4);
fs.Write(BitConverter.GetBytes(Header.DataOffset), 0, 4);
fs.Write(BitConverter.GetBytes(Header.EntryOffset), 0, 4);
fs.Write(BitConverter.GetBytes(Header.FileCount), 0, 4);
fs.Write(BitConverter.GetBytes(Header.BlockTableOffset), 0, 4);
fs.Write(BitConverter.GetBytes(Header.MaxBlockSize), 0, 4);
foreach (char c in Header.CompressionScheme)
fs.WriteByte((byte)c);
fs.Close();
File.Delete(FileName);
File.Move(path, FileName);
}