using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Utility;
namespace DBPF.Package
{
/// <summary>
/// Represents a *.package as used by The Sims 2. Kept modular to allow
/// for changes as required by various expansions. Allows for reading,
/// writing and decompressing *.package files (DBPF).
/// </summary>
public class PackageFile
{
private string ID; //(DBPF - the type of dat)
private string MajorVersion; //Version Major (1 in TS2/SC4 Dats)
private string MinorVersion; //Version Minor (0 in SC4 dats, 1 in most TS2 packages)
private byte[] Reserved; //Reserved (Users can store DBPF info data here if they want)
private string DateCreated; //Date Created in Hex (Unused in Version 1.1)
private string DateModified; //Date Modified in Hex (Unused in Version 1.1)
private UInt32 IndexMajVer; //Index Major Version (Always 7 in TS2/SC4 dats)
private UInt32 NumEntries; //Number of entries in the index
private UInt32 FirstEntry; //Location of first index entry
private UInt32 IndexSize; //Size of index
private UInt32 NumHoles; //Number of Hole entries in the Hole Record
private UInt32 HoleLocation; //Location of the Hole Record
private UInt32 HoleSize; //Size of the Hole Record
private UInt32 IndexLoVer; //Index Minor Version (Version 1.1+ in TS2 only)
private byte[] VerReserved; //Reserved for future use in other versions.
private List<IndexEntry> m_IndexTable;
//Compressed entries in the archive, stored in the archive's *.dir file.
//Checked against m_IndexTable upon archive extraction, to determine
//which files are compresed.
private List<IndexEntry> m_CompressedEntries;
private FileStream m_MemStream;
private BinaryReader m_Reader;
private BinaryWriter m_Writer;
private ASCIIEncoding m_Encoding;
//Partially complete index entries generated when creating an NMap for
//files in a folder that are added to an archive.
private List<IndexEntry> m_GeneratedIndexEntries;
private string m_Path;
/// <summary>
/// Instantiates a new instance of this class for reading
/// a *.package archive.
/// </summary>
/// <param name="ArchivePath">The full path and name of the archive.</param>
public PackageFile(string ArchivePath)
{
m_IndexTable = new List<IndexEntry>();
m_CompressedEntries = new List<IndexEntry>();
m_MemStream = File.OpenRead(ArchivePath);
m_Reader = new BinaryReader(m_MemStream);
m_Encoding = new ASCIIEncoding();
}
/// <summary>
/// Instantiates a new instance of this class for
/// creating a *.package archive from a directory.
/// </summary>
/// <param name="DirPath">The full path and name of the directory.</param>
/// <param name="Compress">Set to true if you wish to compress archive.</param>
public PackageFile(string DirPath, bool Compress)
{
m_MemStream = File.Create(DirPath + "\\" + Path.GetFileNameWithoutExtension(DirPath) + ".package");
m_Encoding = new ASCIIEncoding();
m_GeneratedIndexEntries = new List<IndexEntry>();
m_Path = DirPath;
FindExtensionsInDir();
CreatePackage();
}
/// <summary>
/// Finds all the extensions in the directory given to the
/// constructor of this class, and creates NMaps for them.
/// </summary>
private void FindExtensionsInDir()
{
string[] Files = Directory.GetFiles(m_Path);
List<string> Extensions = new List<string>();
foreach (string TmpFile in Files)
{
string TmpExtension = Path.GetExtension(TmpFile);
Extensions.Add(TmpExtension);
}
string[] ExtensionsArray = Extensions.ToArray();
for (int i = 0; i < Extensions.Count; i++)
{
if (!ExtensionsArray.Equals(".package"))
{
if (i != 0)
{
//Current extension in the array didn't equal the last one,
//so we know we can create a NameMap for it.
if (!ExtensionsArray.Equals(ExtensionsArray))
{
NameMap NMap = <span class="vb-function">new</span> NameMap(NameMap.DetermineTypeID(ExtensionsArray<span style="font-weight:bold;">), m_Path);
m_GeneratedIndexEntries.AddRange(NMap.CreateNMap());
}
}
<span class="cpp-keyword">else</span> <span class="cpp-keyword">if</span> (i == <span class="cpp-literal"><span class="cpp-number">0</span></span>)
{
NameMap NMap = <span class="vb-function">new</span> NameMap(NameMap.DetermineTypeID(ExtensionsArray<span style="font-weight:bold;">), m_Path);
m_GeneratedIndexEntries.AddRange(NMap.CreateNMap());
}
}
}
}
<span class="cpp-keyword">private</span> <span class="cpp-keyword">void</span> CreatePackage()
{
MemoryStream PackageStream = <span class="vb-function">new</span> MemoryStream();
BinaryWriter PackageWriter = <span class="vb-function">new</span> BinaryWriter(PackageStream);
PackageStream = WriteFilesToPackage(PackageWriter, PackageStream);
PackageStream.Seek(<span class="cpp-literal"><span class="cpp-number">0</span></span>, SeekOrigin.Begin);
PackageStream = WriteIndexTable(PackageWriter, PackageStream);
PackageStream.Seek(<span class="cpp-literal"><span class="cpp-number">0</span></span>, SeekOrigin.Begin);
PackageStream = WritePackageHeader(PackageWriter, PackageStream);
PackageStream.Seek(<span class="cpp-literal"><span class="cpp-number">0</span></span>, SeekOrigin.Begin);
m_Reader = <span class="vb-function">new</span> BinaryReader(PackageStream);
m_Writer = <span class="vb-function">new</span> BinaryWriter(m_MemStream);
m_Writer.Write(m_Reader.ReadBytes((<span class="cpp-keyword">int</span>)PackageStream.Length));
m_Writer.Flush();
PackageWriter.Close();
m_Writer.Close();
m_Reader.Close();
}
<span class="cpp-directive">#region</span> Archive writing functions
<span class="cpp-keyword">private</span> MemoryStream WritePackageHeader(BinaryWriter Writer, MemoryStream MemStream)
{
MemStream.SetLength(MemStream.Length + <span class="cpp-literal"><span class="cpp-number">96</span></span>);
<span class="cpp-comment">//Identifier (DBPF - the type of dat).</span>
Writer.Write(m_Encoding.GetBytes(<span class="cpp-literal">"DBPF"</span>));
<span class="cpp-comment">//Version Major (1 in TS2/SC4 Dats). </span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">1</span></span>);
<span class="cpp-comment">//Version Minor (0 in SC4 dats, 1 in most TS2 packages).</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">1</span></span>);
<span class="cpp-comment">//Reserved (Users can store DBPF info data here if they want).</span>
Writer.Write(<span class="vb-function">new</span> <span class="cpp-keyword">byte</span>[<span class="cpp-literal"><span class="cpp-number">12</span></span>]);
<span class="cpp-comment">//Date Created in Hex (Unused in Version 1.1).</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">0</span></span>);
<span class="cpp-comment">//Date Modified in Hex (Unused in Version 1.1).</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">0</span></span>);
<span class="cpp-comment">//Index Major Version (Always 7 in TS2/SC4 dats).</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">7</span></span>);
<span class="cpp-comment">//Number of entries in the index.</span>
Writer.Write((<span class="cpp-keyword">uint</span>)m_GeneratedIndexEntries.Count);
<span class="cpp-comment">//Location of first index entry.</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">96</span></span>);
<span class="cpp-comment">//Size of index.</span>
Writer.Write(IndexSize);
<span class="cpp-comment">//Number of Hole entries in the Hole Record.</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">0</span></span>);
<span class="cpp-comment">//Location of the Hole Record. </span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">0</span></span>);
<span class="cpp-comment">//Size of the Hole Record.</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">0</span></span>);
<span class="cpp-comment">//Index Minor Version (Version 1.1+ in TS2 only).</span>
<span class="cpp-comment">//01 = 0 </span>
<span class="cpp-comment">//02 = 1</span>
Writer.Write((<span class="cpp-keyword">uint</span>)<span class="cpp-literal"><span class="cpp-number">01</span></span>);
<span class="cpp-comment">//Reserved for future use in other versions.</span>
Writer.Write(<span class="vb-function">new</span> <span class="cpp-keyword">byte</span>[<span class="cpp-literal"><span class="cpp-number">32</span></span>]);
<span class="cpp-keyword">return</span> MemStream;
}
<span class="cpp-keyword">private</span> MemoryStream WriteIndexTable(BinaryWriter Writer, MemoryStream MemStream)
{
<span class="cpp-keyword">uint</span> TmpIndexSize = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">foreach</span> (IndexEntry TmpEntry <span class="cpp-keyword">in</span> m_GeneratedIndexEntries)
{
TmpIndexSize += <span class="cpp-literal"><span class="cpp-number">5</span></span> * <span class="cpp-literal"><span class="cpp-number">4</span></span>; <span class="cpp-comment">//20 bytes</span>
MemStream.SetLength(MemStream.Length + TmpIndexSize);
Writer.Write(TmpEntry.TypeID);
Writer.Write(TmpEntry.GroupID);
Writer.Write(TmpEntry.InstanceID);
Writer.Write(TmpEntry.Location);
Writer.Write(TmpEntry.Size);
Writer.Flush();
}
IndexSize = TmpIndexSize;
<span class="cpp-keyword">return</span> MemStream;
}
<span class="cpp-keyword">private</span> MemoryStream WriteFilesToPackage(BinaryWriter Writer, MemoryStream MemStream)
{
FileStream FStream;
BinaryReader FileReader;
<span class="cpp-keyword">foreach</span> (IndexEntry TmpEntry <span class="cpp-keyword">in</span> m_GeneratedIndexEntries)
{
FStream = File.OpenRead(TmpEntry.Name);
FileReader = <span class="vb-function">new</span> BinaryReader(FStream);
TmpEntry.Location = (<span class="cpp-keyword">uint</span>)MemStream.Position;
TmpEntry.Size = (<span class="cpp-keyword">uint</span>)FStream.Length;
Writer.Write(FileReader.ReadBytes((<span class="cpp-keyword">int</span>)FStream.Length));
Writer.Flush();
FileReader.Close();
}
<span class="cpp-keyword">return</span> MemStream;
}
<span class="cpp-directive">#endregion</span>
<span class="cpp-directive">#region</span> Archive reading functions
<span class="cpp-comment">/// <summary></span>
<span class="cpp-comment">/// Reads the header of a *.package (DBPF) archive.</span>
<span class="cpp-comment">/// </summary></span>
<span class="cpp-comment">/// <returns>True if header was read, false if archive</span>
<span class="cpp-comment">/// wasn't a DBPF archive.</returns></span>
<span class="cpp-keyword">private</span> <span class="cpp-keyword">bool</span> ReadHeader()
{
ID = m_Encoding.GetString(m_Reader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">4</span></span>));
<span class="cpp-keyword">if</span> (!ID.Equals(<span class="cpp-literal">"DBPF"</span>))
{
MessageBox.Show(<span class="cpp-literal">"Couldn't read package ID!"</span>);
<span class="cpp-keyword">return</span> <span class="cpp-literal">false</span>;
}
MajorVersion = HexEncoding.ToString(m_Reader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">4</span></span>));
MinorVersion = HexEncoding.ToString(m_Reader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">4</span></span>));
Reserved = m_Reader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">12</span></span>);
DateCreated = HexEncoding.ToString(m_Reader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">4</span></span>));
DateModified = HexEncoding.ToString(m_Reader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">4</span></span>));
IndexMajVer = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
NumEntries = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
FirstEntry = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
IndexSize = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
NumHoles = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
HoleLocation = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
HoleSize = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
IndexLoVer = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>() - <span class="cpp-literal"><span class="cpp-number">1</span></span>;
VerReserved = m_Reader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">32</span></span>);
<span class="cpp-keyword">return</span> <span class="cpp-literal">true</span>;
}
<span class="cpp-comment">/// <summary></span>
<span class="cpp-comment">/// Reads the index table of a *.package (DBPF) archive.</span>
<span class="cpp-comment">/// </summary></span>
<span class="cpp-keyword">private</span> <span class="cpp-keyword">void</span> ReadIndex()
{
m_MemStream.Seek(FirstEntry, SeekOrigin.Begin);
<span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-literal"><span class="cpp-number">0</span></span>; i < NumEntries; i++)
{
<span class="cpp-keyword">try</span>
{
IndexEntry TmpEntry = <span class="vb-function">new</span> IndexEntry();
TmpEntry.TypeID = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
TmpEntry.GroupID = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
TmpEntry.InstanceID = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
<span class="cpp-comment">//Check the archive's version to determine whether or not to read</span>
<span class="cpp-comment">//a second instance ID.</span>
<span class="cpp-keyword">if</span> ((IndexMajVer == <span class="cpp-literal"><span class="cpp-number">7</span></span>) && (IndexLoVer == <span class="cpp-literal"><span class="cpp-number">1</span></span>))
TmpEntry.InstanceID<span class="cpp-literal"><span class="cpp-number">2</span></span> = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
TmpEntry.Location = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
TmpEntry.Size = m_Reader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
<span class="cpp-comment">//Check for *.dir file, which is a directory of all</span>
<span class="cpp-comment">//compressed files in an archive.</span>
<span class="cpp-keyword">if</span> ((InternalPackageFormats)TmpEntry.TypeID == InternalPackageFormats.Directory)
{
<span class="cpp-keyword">long</span> CurrentStreamPos = m_MemStream.Position;
m_MemStream.Seek(TmpEntry.Location, SeekOrigin.Begin);
<span class="cpp-comment">//Dump filedata into the entry's databuffer.</span>
TmpEntry.Data = <span class="vb-function">new</span> MemoryStream(m_Reader.ReadBytes((<span class="cpp-keyword">int</span>)TmpEntry.Size));
TmpEntry.DataReader = <span class="vb-function">new</span> BinaryReader(TmpEntry.Data);
<span class="cpp-comment">//Loop through the filedata, reading all the dir entries</span>
<span class="cpp-comment">//of compressed files, and add them to m_CompressedEntries.</span>
<span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> j = <span class="cpp-literal"><span class="cpp-number">0</span></span>; j <= TmpEntry.Size; j++)
{
IndexEntry CompressedEntry = <span class="vb-function">new</span> IndexEntry();
CompressedEntry.TypeID = TmpEntry.DataReader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
CompressedEntry.GroupID = TmpEntry.DataReader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
CompressedEntry.InstanceID = TmpEntry.DataReader.ReadUInt<span class="cpp-literal"><span class="cpp-number">32</span></span>();
CompressedEntry.UnpackedHexSize = HexEncoding.ToString(TmpEntry.DataReader.ReadBytes(<span class="cpp-literal"><span class="cpp-number">4</span></span>));
<span class="cpp-comment">//A dir entry in the *.dir file/record takes 16 bytes.</span>
j += <span class="cpp-literal"><span class="cpp-number">12</span></span> + CompressedEntry.UnpackedHexSize.Length;
m_CompressedEntries.Add(CompressedEntry);
}
<span class="cpp-comment">//Seek back to the position in the index table where we left off.</span>
m_MemStream.Seek(CurrentStreamPos, SeekOrigin.Begin);
TmpEntry.Data.Close();
TmpEntry.DataReader.Close();
}
m_IndexTable.Add(TmpEntry);
}
<span class="cpp-keyword">catch</span> (Exception)
{
<span class="cpp-keyword">return</span>;
}
}
}
<span class="cpp-keyword">public</span> <span class="cpp-keyword">void</span> ExtractArchive(<span class="cpp-keyword">string</span> Path)
{
<span class="cpp-keyword">foreach</span> (IndexEntry CompressedEntry <span class="cpp-keyword">in</span> m_CompressedEntries)
{
<span class="cpp-keyword">foreach</span> (IndexEntry TmpEntry <span class="cpp-keyword">in</span> m_IndexTable)
{
<span class="cpp-keyword">if</span> (CompressedEntry.InstanceID == TmpEntry.InstanceID)
TmpEntry.Compressed = <span class="cpp-literal">true</span>;
}
}
<span class="cpp-keyword">int</span> CurrentFilename = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">string</span> CurrentExtension = <span class="cpp-keyword">string</span>.Empty;
BinaryWriter Writer;
FileStream Stream;
<span class="cpp-keyword">if</span> (!Directory.Exists(Path))
Directory.CreateDirectory(Path);
<span class="cpp-keyword">foreach</span> (IndexEntry TmpEntry <span class="cpp-keyword">in</span> m_IndexTable)
{
m_MemStream.Seek(TmpEntry.Location, SeekOrigin.Begin);
<span class="cpp-comment">//Dump filedata into the entry's databuffer.</span>
TmpEntry.Data = <span class="vb-function">new</span> MemoryStream(m_Reader.ReadBytes((<span class="cpp-keyword">int</span>)TmpEntry.Size));
TmpEntry.DataReader = <span class="vb-function">new</span> BinaryReader(TmpEntry.Data);
<span class="cpp-keyword">if</span> (TmpEntry.Compressed)
{
TmpEntry.ReadCompressedHeader();
<span class="cpp-keyword">byte</span>[] buf = Uncompress(TmpEntry.Data.ToArray(), TmpEntry.UnpackedSize, <span class="cpp-literal"><span class="cpp-number">9</span></span>);
TmpEntry.Data = <span class="vb-function">new</span> MemoryStream(buf);
buf = <span class="cpp-literal">null</span>;
}
CurrentFilename++;
CurrentExtension = DetermineFileExtension((InternalPackageFormats)TmpEntry.TypeID);
Stream = File.Open(Path + <span class="cpp-literal">"\\"</span> + CurrentFilename + CurrentExtension, FileMode.OpenOrCreate);
Writer = <span class="vb-function">new</span> BinaryWriter(Stream);
Writer.Write(TmpEntry.Data.ToArray());
TmpEntry.Data.Close();
TmpEntry.DataReader.Close();
Stream.Close();
Writer.Close();
}
}
<span class="cpp-directive">#endregion</span>
<span class="cpp-keyword">public</span> <span class="cpp-keyword">bool</span> LoadArchive()
{
<span class="cpp-keyword">if</span> (!ReadHeader())
<span class="cpp-keyword">return</span> <span class="cpp-literal">false</span>;
ReadIndex();
<span class="cpp-keyword">return</span> <span class="cpp-literal">true</span>;
}
<span class="cpp-directive">#region</span> Helper Functions
<span class="cpp-comment">/// <summary></span>
<span class="cpp-comment">/// Uncompresses the File Data passed</span>
<span class="cpp-comment">/// </summary></span>
<span class="cpp-comment">/// <param name="data">Relevant File Data</param></span>
<span class="cpp-comment">/// <param name="targetSize">Size of the uncompressed Data</param></span>
<span class="cpp-comment">/// <param name="offset">File offset, where we should start to decompress from</param></span>
<span class="cpp-comment">/// <returns>The uncompressed FileData</returns></span>
<span class="cpp-keyword">public</span> <span class="cpp-keyword">static</span> <span class="cpp-keyword">Byte</span>[] Uncompress(<span class="cpp-keyword">Byte</span>[] data, <span class="cpp-keyword">uint</span> targetSize, <span class="cpp-keyword">int</span> offset)
{
<span class="cpp-keyword">Byte</span>[] uncdata = <span class="cpp-literal">null</span>;
<span class="cpp-keyword">int</span> index = offset;
<span class="cpp-keyword">try</span>
{
uncdata = <span class="vb-function">new</span> <span class="cpp-keyword">Byte</span>[targetSize];
}
<span class="cpp-keyword">catch</span> (Exception)
{
uncdata = <span class="vb-function">new</span> <span class="cpp-keyword">Byte</span>[<span class="cpp-literal"><span class="cpp-number">0</span></span>];
}
<span class="cpp-keyword">int</span> uncindex = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">int</span> plaincount = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">int</span> copycount = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">int</span> copyoffset = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">Byte</span> cc = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">Byte</span> cc<span class="cpp-literal"><span class="cpp-number">1</span></span> = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">Byte</span> cc<span class="cpp-literal"><span class="cpp-number">2</span></span> = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">Byte</span> cc<span class="cpp-literal"><span class="cpp-number">3</span></span> = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
<span class="cpp-keyword">int</span> source;
<span class="cpp-keyword">try</span>
{
<span class="cpp-keyword">while</span> ((index < data.Length) && (data[index] < <span class="cpp-literal">0xfc</span>))
{
cc = data[index++];
<span class="cpp-keyword">if</span> ((cc & <span class="cpp-literal">0x80</span>) == <span class="cpp-literal"><span class="cpp-number">0</span></span>)
{
cc<span class="cpp-literal"><span class="cpp-number">1</span></span> = data[index++];
plaincount = (cc & <span class="cpp-literal">0x03</span>);
copycount = ((cc & <span class="cpp-literal">0x1C</span>) >> <span class="cpp-literal"><span class="cpp-number">2</span></span>) + <span class="cpp-literal"><span class="cpp-number">3</span></span>;
copyoffset = ((cc & <span class="cpp-literal">0x60</span>) << <span class="cpp-literal"><span class="cpp-number">3</span></span>) + cc<span class="cpp-literal"><span class="cpp-number">1</span></span> + <span class="cpp-literal"><span class="cpp-number">1</span></span>;
}
<span class="cpp-keyword">else</span> <span class="cpp-keyword">if</span> ((cc & <span class="cpp-literal">0x40</span>) == <span class="cpp-literal"><span class="cpp-number">0</span></span>)
{
cc<span class="cpp-literal"><span class="cpp-number">1</span></span> = data[index++];
cc<span class="cpp-literal"><span class="cpp-number">2</span></span> = data[index++];
plaincount = (cc<span class="cpp-literal"><span class="cpp-number">1</span></span> & <span class="cpp-literal">0xC0</span>) >> <span class="cpp-literal"><span class="cpp-number">6</span></span>;
copycount = (cc & <span class="cpp-literal">0x3F</span>) + <span class="cpp-literal"><span class="cpp-number">4</span></span>;
copyoffset = ((cc<span class="cpp-literal"><span class="cpp-number">1</span></span> & <span class="cpp-literal">0x3F</span>) << <span class="cpp-literal"><span class="cpp-number">8</span></span>) + cc<span class="cpp-literal"><span class="cpp-number">2</span></span> + <span class="cpp-literal"><span class="cpp-number">1</span></span>;
}
<span class="cpp-keyword">else</span> <span class="cpp-keyword">if</span> ((cc & <span class="cpp-literal">0x20</span>) == <span class="cpp-literal"><span class="cpp-number">0</span></span>)
{
cc<span class="cpp-literal"><span class="cpp-number">1</span></span> = data[index++];
cc<span class="cpp-literal"><span class="cpp-number">2</span></span> = data[index++];
cc<span class="cpp-literal"><span class="cpp-number">3</span></span> = data[index++];
plaincount = (cc & <span class="cpp-literal">0x03</span>);
copycount = ((cc & <span class="cpp-literal">0x0C</span>) << <span class="cpp-literal"><span class="cpp-number">6</span></span>) + cc<span class="cpp-literal"><span class="cpp-number">3</span></span> + <span class="cpp-literal"><span class="cpp-number">5</span></span>;
copyoffset = ((cc & <span class="cpp-literal">0x10</span>) << <span class="cpp-literal"><span class="cpp-number">12</span></span>) + (cc<span class="cpp-literal"><span class="cpp-number">1</span></span> << <span class="cpp-literal"><span class="cpp-number">8</span></span>) + cc<span class="cpp-literal"><span class="cpp-number">2</span></span> + <span class="cpp-literal"><span class="cpp-number">1</span></span>;
}
<span class="cpp-keyword">else</span>
{
plaincount = (cc - <span class="cpp-literal">0xDF</span>) << <span class="cpp-literal"><span class="cpp-number">2</span></span>;
copycount = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
copyoffset = <span class="cpp-literal"><span class="cpp-number">0</span></span>;
}
<span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-literal"><span class="cpp-number">0</span></span>; i < plaincount; i++) uncdata[uncindex++] = data[index++];
source = uncindex - copyoffset;
<span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-literal"><span class="cpp-number">0</span></span>; i < copycount; i++) uncdata[uncindex++] = uncdata[source++];
}<span class="cpp-comment">//while</span>
} <span class="cpp-comment">//try</span>
<span class="cpp-keyword">catch</span> (Exception ex)
{
<span class="cpp-comment">//Helper.ExceptionMessage("", ex);</span>
<span class="cpp-keyword">throw</span> ex;
}
<span class="cpp-keyword">if</span> (index < data.Length)
{
plaincount = (data[index++] & <span class="cpp-literal">0x03</span>);
<span class="cpp-keyword">for</span> (<span class="cpp-keyword">int</span> i = <span class="cpp-literal"><span class="cpp-number">0</span></span>; i < plaincount; i++)
{
<span class="cpp-keyword">if</span> (uncindex >= uncdata.Length) <span class="cpp-keyword">break</span>;
uncdata[uncindex++] = data[index++];
}
}
<span class="cpp-keyword">return</span> uncdata;
}
<span class="cpp-keyword">private</span> <span class="cpp-keyword">string</span> DetermineFileExtension(InternalPackageFormats TypeID)
{
<span class="cpp-keyword">switch</span> (TypeID)
{
<span class="cpp-keyword">case</span> InternalPackageFormats.UIData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ui"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WallGraph:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wgra"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LotDescription:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".desc"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BinaryIndex:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".binx"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.JPG:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".jpg"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.NameReference:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nref"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BusinessInfo:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".bnfo"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TextureImage:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".txtr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.XA:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".xa"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ThreeDArray:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".3dary"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TwoDArray:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".2dary"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TextureOverlay:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".xtol"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Popups:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pops"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SimScores:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".scor"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ThreeDID:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".3didr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BehaviourConstant:
<span class="cpp-keyword">return</span> <span class="cpp-literal">"bcon"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BehaviourFunction:
<span class="cpp-keyword">return</span> <span class="cpp-literal">"bhav"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CatalogString:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cats"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CatalogDescription:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ctss"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TextLists:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".str#"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PieMenuStrings:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".tta"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FaceProperties:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".face"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FamilyInformation:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fami"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FamilyUnknown:
<span class="cpp-keyword">return</span> <span class="cpp-literal">"famh"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Function:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fcns"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.AudioReference:
<span class="cpp-keyword">return</span> <span class="cpp-literal">"fwav"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.GlobalData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".glob"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HouseDescriptor:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".hous"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TexturedMaterial:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".txmt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WorldDatabase:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wrld"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SkinToneXML:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".xstn"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CinematicScene:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cine"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Memory:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ngbh"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.NameMap:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nmap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ObjectData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objd"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ObjectFunctions:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objf"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ObjectMaterial:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objm"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ImageColorPalette:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".palt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PERS:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pers"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Slot:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".slot"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TTAT:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ttat"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TRPR:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".trpr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TRCN:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".trcn"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.<span class="cpp-keyword">Object</span>:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".mobjt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HitList:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".hls"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.GeometricNode:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".gmnd"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LightMap:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".lightmap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WallLayer:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wll"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FamilyTies:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".famt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PMAP:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pmap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SimDescription:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pdat"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FencePostLayer:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fpl"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HoodTerrain:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nhtr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.NID:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nid"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.AgedCPF:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cpf"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Anim:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".anim"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SMAP:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".smap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BMP:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".bmp"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Vertext:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".vertext"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FacialStructure:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".lxnr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.MaterialShader:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".matshad"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WantsFears:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wfr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ContentRegistry:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".creg"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CIGE:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cige"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ResourceNode:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cres"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PropertySet:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cpf"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.VersionInfo:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ver"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HoodView:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nhvw"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LargeImage:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".lifo"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.OBJT:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Shape:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".shpe"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.EffectsScript:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fx"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.GeometricData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".gmdc"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LargeJPG:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".jfif"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BHAVTree:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".tree"</span>;
<span class="cpp-keyword">default</span>:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".xyz"</span>;
}
}
<span class="cpp-directive">#endregion</span>
<span class="cpp-comment">/// <summary></span>
<span class="cpp-comment">/// Returns an array representing the IndexTable of the loaded archive.</span>
<span class="cpp-comment">/// The index table contains entries which in turn contains information</span>
<span class="cpp-comment">/// about each file in the archive that they represent, such as location</span>
<span class="cpp-comment">/// and size of actual filedata, as well as a type ID representing the </span>
<span class="cpp-comment">/// file's extension.</span>
<span class="cpp-comment">/// </summary></span>
<span class="cpp-keyword">public</span> IndexEntry[] IndexTable
{
get { <span class="cpp-keyword">return</span> m_IndexTable.ToArray(); }
}
}
}
</pre></div><!–ENDSCRIPT–>
The problem, if it isn't obvious yet, is that I am as of yet incapable of creating *.package files that can be extracted with my *.package reading code (and, thus, by other *.package reading tools as well). A thing I've noticed is that when I try to extract a *.package archive created with my *.package writing methods, the files seems to grow in size incrementally as they are extracted/created, which seems to suggest that there is something wrong with the way I am writing my Index Table. If needed, here's the specification I'm using for this code: <a href="http://www.sims2wiki.info/wiki.php?title=DBPF">*.package specification</a>
Any suggestions?
Thanks in advance!
Edit - Whoops, here's the class for creating NMaps;
<!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre><span class="cpp-keyword">using</span> System;
<span class="cpp-keyword">using</span> System.Collections.Generic;
<span class="cpp-keyword">using</span> System.Text;
<span class="cpp-keyword">using</span> System.IO;
<span class="cpp-keyword">using</span> System.Windows.Forms;
<span class="cpp-keyword">namespace</span> DBPF.Package
{
<span class="cpp-comment">/// <summary></span>
<span class="cpp-comment">/// Encapsulates methods for creating, and returning a handle to, a</span>
<span class="cpp-comment">/// new NameMap file that can be put in a new *.package file along</span>
<span class="cpp-comment">/// with the files referenced in the new NameMap file.</span>
<span class="cpp-comment">/// </summary></span>
<span class="cpp-keyword">class</span> NameMap
{
<span class="cpp-keyword">private</span> string m_Filename; <span class="cpp-comment">//Filename of this file (unimportant, as these files don't map their own names).</span>
<span class="cpp-keyword">private</span> string m_Path; <span class="cpp-comment">//Path of the created file.</span>
<span class="cpp-keyword">private</span> InternalPackageFormats m_TypeID; <span class="cpp-comment">//TypeID of the filetype that this file maps.</span>
<span class="cpp-keyword">private</span> uint m_NumItems; <span class="cpp-comment">//Number of files with the filetype that corresponds to this file.</span>
List<IndexEntry> m_Files; <span class="cpp-comment">//List of files that are contained in this NMap.</span>
<span class="cpp-keyword">public</span> NameMap(InternalPackageFormats <span class="cpp-keyword">TypeID</span>, string Path)
{
m_TypeID = <span class="cpp-keyword">TypeID</span>;
m_Path = Path;
m_Filename = DetermineFileExtension(m_TypeID).Replace(<span class="cpp-literal">"."</span>, <span class="cpp-literal">""</span>);
m_Files = <span class="cpp-keyword">new</span> List<IndexEntry>();
}
<span class="cpp-keyword">public</span> List<IndexEntry> CreateNMap()
{
string[] Files = Directory.GetFiles(m_Path);
FileStream NMap = File.Create(m_Path + <span class="cpp-literal">"\\"</span> + m_Filename + <span class="cpp-literal">".nmap"</span>);
BinaryWriter Writer = <span class="cpp-keyword">new</span> BinaryWriter(NMap);
Random Rnd = <span class="cpp-keyword">new</span> Random();
m_NumItems = (uint)Files.Length;
Writer.Write(m_NumItems);
uint InstanceID = <span class="cpp-number">0</span>;
foreach (string TmpName in Files)
{
<span class="cpp-keyword">if</span> (DetermineFileExtension(m_TypeID).Equals(Path.GetExtension(TmpName)))
{
IndexEntry TmpEntry = <span class="cpp-keyword">new</span> IndexEntry();
TmpEntry.Name = TmpName;
TmpEntry.InstanceID = InstanceID++;
TmpEntry.<span class="cpp-keyword">TypeID</span> = (uint)m_TypeID;
<span class="cpp-comment">//Is it neccessary to 'fill out' GroupID?</span>
Writer.Write((uint)0x0);
Writer.Write(TmpEntry.InstanceID);
Writer.Write((uint)TmpEntry.Name.Length);
Writer.Write(Encoding.ASCII.GetBytes(Path.GetFileNameWithoutExtension(TmpEntry.Name)));
m_Files.Add(TmpEntry);
}
}
IndexEntry NMapEntry = <span class="cpp-keyword">new</span> IndexEntry();
NMapEntry.Name = m_Path + <span class="cpp-literal">"\\"</span> + m_Filename + <span class="cpp-literal">".nmap"</span>;
NMapEntry.InstanceID = InstanceID++;
NMapEntry.<span class="cpp-keyword">TypeID</span> = (uint)InternalPackageFormats.NameMap;
m_Files.Add(NMapEntry);
NMap.Close();
Writer.Close();
<span class="cpp-keyword">return</span> m_Files;
}
#region Helper Functions
<span class="cpp-comment">/// <summary></span>
<span class="cpp-comment">/// Determines a filetype based upon a TypeID.</span>
<span class="cpp-comment">/// </summary></span>
<span class="cpp-comment">/// <param name="TypeID">A TypeID in the InternalPackageFormats enum.</param></span>
<span class="cpp-comment">/// <returns>A string containing the filetype.</returns></span>
<span class="cpp-keyword">private</span> string DetermineFileExtension(InternalPackageFormats <span class="cpp-keyword">TypeID</span>)
{
<span class="cpp-keyword">switch</span> (<span class="cpp-keyword">TypeID</span>)
{
<span class="cpp-keyword">case</span> InternalPackageFormats.UIData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ui"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WallGraph:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wgra"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LotDescription:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".desc"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BinaryIndex:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".binx"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.JPG:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".jpg"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.NameReference:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nref"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BusinessInfo:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".bnfo"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TextureImage:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".txtr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.XA:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".xa"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ThreeDArray:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".3dary"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TwoDArray:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".2dary"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TextureOverlay:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".xtol"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Popups:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pops"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SimScores:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".scor"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ThreeDID:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".3didr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BehaviourConstant:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".bcon"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BehaviourFunction:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".bhav"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CatalogString:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cats"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CatalogDescription:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ctss"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TextLists:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".str#"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PieMenuStrings:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".tta"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FaceProperties:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".face"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FamilyInformation:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fami"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FamilyUnknown:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".famh"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Function:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fcns"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.AudioReference:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fwav"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.GlobalData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".glob"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HouseDescriptor:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".hous"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TexturedMaterial:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".txmt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WorldDatabase:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wrld"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SkinToneXML:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".xstn"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CinematicScene:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cine"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Memory:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ngbh"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.NameMap:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nmap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ObjectData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objd"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ObjectFunctions:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objf"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ObjectMaterial:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objm"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ImageColorPalette:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".palt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PERS:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pers"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Slot:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".slot"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TTAT:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ttat"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TRPR:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".trpr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.TRCN:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".trcn"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Object:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".mobjt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HitList:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".hls"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.GeometricNode:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".gmnd"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LightMap:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".lightmap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WallLayer:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wll"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FamilyTies:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".famt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PMAP:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pmap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SimDescription:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".pdat"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FencePostLayer:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fpl"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HoodTerrain:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nhtr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.NID:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nid"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.AgedCPF:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cpf"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Anim:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".anim"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.SMAP:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".smap"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BMP:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".bmp"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Vertext:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".vertext"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.FacialStructure:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".lxnr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.MaterialShader:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".matshad"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.WantsFears:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".wfr"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ContentRegistry:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".creg"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.CIGE:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cige"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.ResourceNode:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cres"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.PropertySet:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".cpf"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.VersionInfo:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".ver"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.HoodView:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".nhvw"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LargeImage:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".lifo"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.OBJT:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".objt"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.Shape:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".shpe"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.EffectsScript:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".fx"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.GeometricData:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".gmdc"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.LargeJPG:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".jfif"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.BHAVTree:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".tree"</span>;
<span class="cpp-keyword">case</span> InternalPackageFormats.DirectXMesh:
<span class="cpp-keyword">return</span> <span class="cpp-literal">".x"</span>;
<span class="cpp-keyword">default</span>:
<span class="cpp-keyword">return</span> <span class="cpp-literal">"xyz"</span>;
}
}
<span class="cpp-comment">/// <summary></span>
<span class="cpp-comment">/// Determines a TypeID based upon a file extension.</span>
<span class="cpp-comment">/// </summary></span>
<span class="cpp-comment">/// <param name="Extension">The extension of a file.</param></span>
<span class="cpp-comment">/// <returns>A TypeID in the InternalPackageFormats enum.</returns></span>
<span class="cpp-keyword">public</span> <span class="cpp-keyword">static</span> InternalPackageFormats DetermineTypeID(string Extension)
{
<span class="cpp-keyword">switch</span> (Extension)
{
<span class="cpp-keyword">case</span> <span class="cpp-literal">".cpf"</span>:
<span class="cpp-keyword">return</span> InternalPackageFormats.AgedCPF;
<span class="cpp-keyword">case</span> <span class="cpp-literal">".x"</span>:
<span class="cpp-keyword">return</span> InternalPackageFormats.DirectXMesh;
<span class="cpp-keyword">default</span>:
<span class="cpp-keyword">return</span> InternalPackageFormats.UnkownFiletype;
}
}
#endregion
}
}
</pre></div><!–ENDSCRIPT–>
Just in case, here's the specs: <a href="http://www.sims2wiki.info/wiki.php?title=NMAP">NMap Specification</a>
[.net] Creating a *.package archive
Ok, so I've been trying to create a *.package archive successfully for a while now. At first, I tried writing directly to a file, but now I've decided writing directly to a memory stream that I can resize at will seems easier. Below is my entire class for reading and writing to and from package files. The reading part need'nt be looked at though, because as far as I can tell, it is fully compatible with all the *.package files I can throw at it.
I can't be arsed to read all of that code at the moment, but typically if something is growing that shouldn't, that typically means something you think is being deleted really isn't (which is common when working with streams, at least with me). If I were you I'd simply trace down to the line/function that causes the size to grow when it should, that would, of course, point you in the right direction.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement