81 lines
2.7 KiB
C#
81 lines
2.7 KiB
C#
|
//Written for games in the Heat Engine.
|
|||
|
//AirMech https://store.steampowered.com/app/206500
|
|||
|
//AirMech Wastelands https://store.steampowered.com/app/595770
|
|||
|
//AirMech Command https://store.steampowered.com/app/364630
|
|||
|
using System.IO;
|
|||
|
using System.IO.Compression;
|
|||
|
|
|||
|
namespace Heat_Extractor
|
|||
|
{
|
|||
|
class Program
|
|||
|
{
|
|||
|
public static BinaryReader br;
|
|||
|
static MemoryStream nameTable = new();
|
|||
|
static void Main(string[] args)
|
|||
|
{
|
|||
|
br = new(File.OpenRead(args[0]));
|
|||
|
|
|||
|
if (new string(br.ReadChars(4)) != "HPK\0")
|
|||
|
throw new System.Exception("This is not a Heat Engine HPK file.");
|
|||
|
|
|||
|
br.ReadInt32();//1
|
|||
|
int fileCount = br.ReadInt32();
|
|||
|
int filesStart = br.ReadInt32();
|
|||
|
br.ReadInt32();//1
|
|||
|
br.ReadInt32();
|
|||
|
int nameSize = br.ReadInt32();
|
|||
|
|
|||
|
br.ReadInt16();
|
|||
|
using (var ds = new DeflateStream(new MemoryStream(br.ReadBytes(nameSize - 2)), CompressionMode.Decompress))
|
|||
|
ds.CopyTo(nameTable);
|
|||
|
|
|||
|
System.Collections.Generic.List<Subfile> subfiles = new();
|
|||
|
for (int i = 0; i < fileCount; i++)
|
|||
|
subfiles.Add(new());
|
|||
|
|
|||
|
br.BaseStream.Position = filesStart;
|
|||
|
string path = Path.GetDirectoryName(args[0]) + "//" + Path.GetFileNameWithoutExtension(args[0]);
|
|||
|
foreach (Subfile file in subfiles)
|
|||
|
{
|
|||
|
Directory.CreateDirectory(path + "//" + Path.GetDirectoryName(file.name));
|
|||
|
FileStream fs = File.Create(path + "//" + file.name);
|
|||
|
if (file.sizeCompressed == file.sizeUncompressed)
|
|||
|
{
|
|||
|
BinaryWriter bw = new(fs);
|
|||
|
bw.Write(br.ReadBytes(file.sizeUncompressed));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
br.ReadInt16();
|
|||
|
using (var ds = new DeflateStream(new MemoryStream(br.ReadBytes(file.sizeCompressed - 2)), CompressionMode.Decompress))
|
|||
|
ds.CopyTo(fs);
|
|||
|
}
|
|||
|
|
|||
|
fs.Close();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
class Subfile
|
|||
|
{
|
|||
|
public int sizeCompressed = br.ReadInt32();
|
|||
|
public int start = br.ReadInt32();
|
|||
|
public int sizeUncompressed = br.ReadInt32();
|
|||
|
float unknown = br.ReadSingle();
|
|||
|
public string name = name(br.ReadInt32());
|
|||
|
}
|
|||
|
|
|||
|
static string name(int start)
|
|||
|
{
|
|||
|
nameTable.Position = start;
|
|||
|
string name = "";
|
|||
|
byte x = (byte)nameTable.ReadByte();
|
|||
|
while (x != 0)
|
|||
|
{
|
|||
|
name += (char)x;
|
|||
|
x = (byte)nameTable.ReadByte();
|
|||
|
}
|
|||
|
return name;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|