Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*.userprefs

# Build results
Build/
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
Expand Down
103 changes: 91 additions & 12 deletions AlienPAK/Explorer.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
using Assimp;
using CATHODE;
using CATHODE.LEGACY;
using DirectXTexNet;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Metadata;
using System.Threading;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using Assimp;
using Assimp.Unmanaged;
using CATHODE;
using CATHODE.LEGACY;
using CathodeLib;
using DirectXTexNet;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
using static CATHODE.Materials.Material;

namespace AlienPAK
Expand Down Expand Up @@ -503,6 +495,82 @@ private void ExportSelectedFile()
ExportNode(FileTree.SelectedNode);
}

private PAK2.File getPAK2File(string pakFileName)
{
return (
(PAK2)pak.File).Entries.FirstOrDefault(
o => o.Filename.Replace('\\', '/') == pakFileName.Replace('\\', '/')
);
}

private bool hktHasMagicNumber(PAK2.File pakFile, out int startIndex)
{
startIndex = -1;

try
{
if (pakFile == null)
{
return false;
}

if (pakFile.Content.Length == 0 || pakFile.Content.Length < 4)
{
return false;
}

uint magic1 = 0x57E0E057;
//uint magic2 = 0x10C0C010;

// Check only first 20 bytes, since
// the magic numbers appears after 12 bytes
for (int i = 0; i < 20; i++)
{
uint num = BitConverter.ToUInt32(pakFile.Content, i);

if (num == magic1)
{
startIndex = i;
return true;
}
}

}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}

return false;
}

private void extractHktFile(string pakFileName, string saveDestination)
{
try
{
var pakFile = this.getPAK2File(pakFileName);

if (pakFile == null)
{
return;
}

if (this.hktHasMagicNumber(pakFile, out int startIdx))
{
using (FileStream fs = new FileStream(saveDestination, FileMode.Create, FileAccess.Write))
{
fs.Write(pakFile.Content, startIdx, pakFile.Content.Length - startIdx);
}
}

}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
MessageBox.Show(ex.ToString(), "Export failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

/* Export the selected PAK entry as a standalone file */
private void ExportNode(TreeNode node, string outputFolder = "") //If you set outputFolder, the user won't get a filepicker
{
Expand All @@ -520,6 +588,11 @@ private void ExportNode(TreeNode node, string outputFolder = "") //If you set ou
string fileName = Path.GetFileName(node.Text);
while (Path.GetExtension(fileName).Length != 0) fileName = fileName.Substring(0, fileName.Length - Path.GetExtension(fileName).Length); //Remove extensions from output filename

if (this.hktHasMagicNumber(this.getPAK2File(nodeVal), out int startIndex))
{
filter += "|Havok Packfile|*.hkx";
}

string pickedFileName = "";
if (outputFolder == "")
{
Expand All @@ -545,13 +618,19 @@ private void ExportNode(TreeNode node, string outputFolder = "") //If you set ou
}

Cursor.Current = Cursors.WaitCursor;

try
{
switch (pak.Type)
{
case PAKType.ANIMATIONS:
case PAKType.UI:
case PAKType.CHR_INFO:
if (Path.GetExtension(pickedFileName).ToUpper() == ".HKX")
{
this.extractHktFile(nodeVal, pickedFileName);
break;
}
File.WriteAllBytes(pickedFileName, ((PAK2)pak.File).Entries.FirstOrDefault(o => o.Filename.Replace('\\', '/') == nodeVal.Replace('\\', '/'))?.Content);
break;
case PAKType.TEXTURES:
Expand Down