using System;
using System.Collections.Generic;
using System.Text;
namespace DBPF
{
class DBPF1File
{
public UInt32 m_TypeID;
public UInt32 m_GroupID;
public UInt32 m_InstanceID;
public UInt32 m_Offset;
public UInt32 m_Size;
public byte[] m_Data;
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace DBPF
{
public class DBPF1Loader
{
//General data about the file loaded.
private string m_Header;
private UInt32 m_Version;
private UInt32 m_ArchiveID;
private UInt32 m_ArchiveType;
private UInt32 m_NumberOfFiles;
private UInt32 m_DirectoryOffset;
private UInt32 m_DirectorySize;
private DBPF1File[] m_FileList;
public DBPF1Loader(string Filename)
{
LoadArchive(Filename);
}
private void LoadArchive(string Filename)
{
FileStream Stream = File.OpenRead(Filename);
BinaryReader Reader = new BinaryReader(Stream);
byte[] Data = new byte[4];
//Read the header (4 bytes), and convert them from
//a binary to an ASCII encoding.
ASCIIEncoding Encoding = new ASCIIEncoding();
m_Header = Encoding.GetString(Reader.ReadBytes(4));
//Read the version signature.
m_Version = Reader.ReadUInt32();
//Read 16 null bytes from file, no idea what these are for.
for (int i = 0; i <= 15; i++)
Reader.ReadByte();
//Read the archive id.
m_ArchiveID = Reader.ReadUInt32();
//Read the archive type.
m_ArchiveType = Reader.ReadUInt32();
//Read an unknown UInt32.
Reader.ReadUInt32();
//Read the total number of files in this archive.
m_NumberOfFiles = Reader.ReadUInt32();
//Read the (initial) directory offset in this archive.
m_DirectoryOffset = Reader.ReadUInt32();
//Read the directory size in this archive.
m_DirectorySize = Reader.ReadUInt32();
//Read 48 unknown bytes.
for (int i = 0; i <= 47; i++)
Reader.ReadByte();
//Find the directory offset in the stream
Stream.Seek((long)m_DirectoryOffset, SeekOrigin.Current);
//The current offset in the stream at this point.
long CurrentOffset = Stream.Position;
//Array of files loaded by the loader.
//Initialized here because the total number of files is now known.
m_FileList = new DBPF1File[m_NumberOfFiles];
//Cycle through the number of files in the archive.
for (int y = 0; y < m_NumberOfFiles; y++)
{
DBPF1File TmpFile = new DBPF1File();
TmpFile.m_TypeID = Reader.ReadUInt32();
TmpFile.m_GroupID = Reader.ReadUInt32();
TmpFile.m_InstanceID = Reader.ReadUInt32();
TmpFile.m_Offset = Reader.ReadUInt32();
TmpFile.m_Size = Reader.ReadUInt32();
TmpFile.m_Data = new byte[TmpFile.m_Size];
//Seek to offset of the filedata,
Stream.Seek(TmpFile.m_Offset, SeekOrigin.Current);
//read the number of bytes specified in m_Size,
TmpFile.m_Data = Reader.ReadBytes((int)TmpFile.m_Size);
//and seek back again to the starting point
//from the beginning of the stream.
Stream.Seek(CurrentOffset, SeekOrigin.Begin);
//For each file, save the position in the stream
//at this point.
CurrentOffset = Stream.Position;
//Add the temporary file to the list of files loaded by
//the loader.
m_FileList[y] = TmpFile;
}
}
public void UnpackArchive(string Filename)
{
//Filetype extension for the current file.
string CurrentExtension = "";
//Incrementor for file names, because the actual
//filenames aren't known.
int CurrentFileName = 0;
Directory.CreateDirectory(Filename);
foreach (DBPF1File TmpFile in m_FileList)
{
/*1 - BMP image - (compressed)
2 - TGA image - (compressed)
5 - SKEL skeleton - (compressed)
7 - ANIM animation - (compressed)
9 - MESH model - (compressed)
11 - BND binding - (uncompressed)
12 - APR appearance - (uncompressed)
13 - OTF outfit - (uncompressed)
14 - PNG image - (uncompressed)
15 - PO purchasable object (uncompressed)
16 - COL collection - (compressed)
18 - HAG group - (compressed)
19 - JPEG image - (compressed)
20 - JPEG image - (uncompressed)*/
CurrentFileName++;
switch (TmpFile.m_TypeID)
{
case 1:
CurrentExtension = ".bmp";
break;
case 2:
CurrentExtension = ".tga";
break;
case 5:
CurrentExtension = ".skel";
break;
case 7:
CurrentExtension = ".anim";
break;
case 9:
CurrentExtension = ".mesh";
break;
case 11:
CurrentExtension = ".bnd";
break;
case 12:
CurrentExtension = ".apr";
break;
case 13:
CurrentExtension = ".otf";
break;
case 14:
CurrentExtension = ".png";
break;
case 15:
CurrentExtension = ".po";
break;
case 16:
CurrentExtension = ".col";
break;
case 18:
CurrentExtension = ".hag";
break;
case 19:
CurrentExtension = ".jpg";
break;
case 20:
CurrentExtension = ".jpg";
break;
}
FileStream Stream = File.Create(Filename + "\\" + CurrentFileName.ToString() + CurrentExtension);
BinaryWriter Writer = new BinaryWriter(Stream);
Writer.Write(TmpFile.m_Data);
Writer.Close();
Stream.Close();
}
}
public string Header
{
get{return m_Header;}
}
public UInt32 Version
{
get { return m_Version; }
}
public UInt32 ArchiveType
{
get { return m_ArchiveType; }
}
public UInt32 ArchiveID
{
get { return m_ArchiveID; }
}
public UInt32 NumberOfFiles
{
get { return m_NumberOfFiles; }
}
public UInt32 DirectoryOffset
{
get { return m_DirectoryOffset; }
}
public UInt32 DirectorySize
{
get { return m_DirectorySize; }
}
}
}