Skip to content

Commit

Permalink
Add methods for getting file data from the vfs (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
CosmicDreamsOfCode authored Aug 12, 2024
1 parent 1976e08 commit 8259692
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,4 @@ AppPackages/
#####
# End of core ignore list, below put you custom 'per project' settings (patterns or path)
#####
/GalanthusCli/Properties/launchSettings.json
17 changes: 17 additions & 0 deletions Galanthus/GameManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,21 @@ public static bool LoadGame(string inDirectory, Platform inPlatform, Compression

return true;
}
public static Block<byte> GetFileBytesFromPath(string filePath, string inDirectory)
{
string dataDir = Path.Combine(inDirectory, CodeName, "sdf", Platform.ToString().ToLower(), "data");

Check warning on line 135 in Galanthus/GameManager.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'paths' in 'string Path.Combine(params string[] paths)'.
Block<byte> data = null;

Check warning on line 136 in Galanthus/GameManager.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.
if (filePath != null)
{
foreach (Structs.File file in m_toc.Files)

Check warning on line 139 in Galanthus/GameManager.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
{
if (file.Name == filePath)
{
data = m_toc.GetFileBytes(file, dataDir);
break;
}
}
}
return data;

Check warning on line 148 in Galanthus/GameManager.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.
}
}
115 changes: 115 additions & 0 deletions Galanthus/SdfToc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Galanthus.Structs;
using Galanthus.Utils;
using StreamUtils;
using File = Galanthus.Structs.File;

namespace Galanthus;

Expand Down Expand Up @@ -516,4 +518,117 @@ public void Dispose()
header.Dispose();
}
}

public unsafe Block<Byte> GetFileBytes(File fileEntry, string dataDir)
{
int outBufferSize = 0;
string sdfPath = null;

Check warning on line 525 in Galanthus/SdfToc.cs

View workflow job for this annotation

GitHub Actions / build

Converting null literal or possible null value to non-nullable type.

//get final file size
foreach (DataSlice dataSlice in fileEntry.DataSlices)
{
if (fileEntry.DdsIndex != -1)
{
outBufferSize += m_ddsHeaders[fileEntry.DdsIndex].Size;
}

if (!TryGetDataFile(dataSlice, out string? sdfName))
{
Console.WriteLine($"Wrong index {dataSlice.Index}");
continue;
}

sdfPath = Path.Combine(dataDir, sdfName);
if (System.IO.File.Exists(sdfPath))
{
outBufferSize += (int)dataSlice.DecompressedSize;
}

}
Block<Byte> outBuffer = new(outBufferSize);


//add dds header
if (fileEntry.DdsIndex != -1)
{
m_ddsHeaders[fileEntry.DdsIndex].CopyTo(outBuffer);
outBuffer.Shift(m_ddsHeaders[fileEntry.DdsIndex].Size);
}

//read slices
foreach (DataSlice dataSlice in fileEntry.DataSlices)
{
if (!TryGetDataFile(dataSlice, out string? sdfName))
{
Console.WriteLine($"Wrong index {dataSlice.Index}");
continue;
}

sdfPath = Path.Combine(dataDir, sdfName);
if (System.IO.File.Exists(sdfPath))
{
using (DataStream stream = BlockStream.FromFile(sdfPath, dataSlice.Offset, (int)dataSlice.CompressedSize))
{
//read slice
Block<Byte> compressedBuffer = new((int)dataSlice.CompressedSize);
stream.ReadExactly(compressedBuffer);

//decrypt slice
if (dataSlice.IsEncrypted)
{
if (m_header.Version >= 0x29 && compressedBuffer.Size >= 8)
{
// first they use XTEA encryption, then they use des encryption
XTEA((uint*)compressedBuffer.Ptr, 32);

// DES-PCBC
// Problem is c# doesnt have native support for it
if (Crypto.DecryptDes((nuint)compressedBuffer.Ptr, (compressedBuffer.Size >> 3) << 3, (nuint)compressedBuffer.Ptr, (nuint)KeyManager.Key.Ptr,

Check warning on line 586 in Galanthus/SdfToc.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
(nuint)KeyManager.Iv.Ptr) != 0)

Check warning on line 587 in Galanthus/SdfToc.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
{
return null;

Check warning on line 589 in Galanthus/SdfToc.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.
}
}
else if (compressedBuffer.Size >= 0x100)
{
// AES-192-OFB
// Problem is c# doesnt have native support for it
if (Crypto.DecryptAes((nuint)compressedBuffer.Ptr, 0x100, (nuint)compressedBuffer.Ptr, (nuint)KeyManager.Key.Ptr,

Check warning on line 596 in Galanthus/SdfToc.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
(nuint)KeyManager.Iv.Ptr) != 0)
{
return null;
}
}
}

//decompress slice
if (dataSlice.IsCompressed)
{
if (!dataSlice.IsOodle)
{
ZStd.Decompress(compressedBuffer, ref outBuffer);
}
else
{
Console.WriteLine("Oodle slice!");
}
}
else
{
compressedBuffer.CopyTo(outBuffer);
}

outBuffer.Shift((int)dataSlice.DecompressedSize);
compressedBuffer.Dispose();
}
}
else
{
Console.WriteLine($"{sdfName} does not exist, skipping slice.");
}
}

outBuffer.ResetShift();
return outBuffer;
}
}
2 changes: 1 addition & 1 deletion GalanthusCli/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.CommandLine;
using System.IO;
using Galanthus;
Expand Down

0 comments on commit 8259692

Please sign in to comment.