diff --git a/SabreTools.Models/VPK/ArchiveMD5SectionEntry.cs b/SabreTools.Models/VPK/ArchiveMD5SectionEntry.cs
new file mode 100644
index 0000000..c726dff
--- /dev/null
+++ b/SabreTools.Models/VPK/ArchiveMD5SectionEntry.cs
@@ -0,0 +1,27 @@
+using System.Runtime.InteropServices;
+
+namespace SabreTools.Models.VPK
+{
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public sealed class ArchiveMD5SectionEntry
+ {
+ public uint ArchiveIndex;
+
+ ///
+ /// Where to start reading bytes
+ ///
+ public uint StartingOffset;
+
+ ///
+ /// How many bytes to check
+ ///
+ public uint Count;
+
+ ///
+ /// Expected checksum
+ ///
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public byte[]? MD5Checksum = new byte[16];
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/VPK/DirectoryEntry.cs b/SabreTools.Models/VPK/DirectoryEntry.cs
index 0412469..4b8a789 100644
--- a/SabreTools.Models/VPK/DirectoryEntry.cs
+++ b/SabreTools.Models/VPK/DirectoryEntry.cs
@@ -3,17 +3,37 @@ using System.Runtime.InteropServices;
namespace SabreTools.Models.VPK
{
///
+ ///
[StructLayout(LayoutKind.Sequential)]
public sealed class DirectoryEntry
{
+ ///
+ /// A 32bit CRC of the file's data.
+ ///
public uint CRC;
+ ///
+ /// The number of bytes contained in the index file.
+ ///
public ushort PreloadBytes;
+ ///
+ /// A zero based index of the archive this file's data is contained in.
+ /// If 0x7fff, the data follows the directory.
+ ///
public ushort ArchiveIndex;
+ ///
+ /// If ArchiveIndex is 0x7fff, the offset of the file data relative to the
+ /// end of the directory (see the header for more details).
+ /// Otherwise, the offset of the data from the start of the specified archive.
+ ///
public uint EntryOffset;
+ ///
+ /// If zero, the entire file is stored in the preload data.
+ /// Otherwise, the number of bytes stored starting at EntryOffset.
+ ///
public uint EntryLength;
///
diff --git a/SabreTools.Models/VPK/DirectoryItem.cs b/SabreTools.Models/VPK/DirectoryItem.cs
index 3d12235..6e6d824 100644
--- a/SabreTools.Models/VPK/DirectoryItem.cs
+++ b/SabreTools.Models/VPK/DirectoryItem.cs
@@ -1,6 +1,7 @@
namespace SabreTools.Models.VPK
{
///
+ ///
public sealed class DirectoryItem
{
public string? Extension { get; set; }
diff --git a/SabreTools.Models/VPK/ExtendedHeader.cs b/SabreTools.Models/VPK/ExtendedHeader.cs
index f4f8e58..e62a8cf 100644
--- a/SabreTools.Models/VPK/ExtendedHeader.cs
+++ b/SabreTools.Models/VPK/ExtendedHeader.cs
@@ -6,27 +6,33 @@ namespace SabreTools.Models.VPK
/// Added in version 2.
///
///
+ ///
[StructLayout(LayoutKind.Sequential)]
public sealed class ExtendedHeader
{
///
- /// Reserved
+ /// How many bytes of file content are stored in this
+ /// VPK file (0 in CSGO)
///
- public uint Dummy0;
+ public uint FileDataSectionSize;
///
- /// Archive hash length
+ /// The size, in bytes, of the section containing MD5
+ /// checksums for external archive content
///
- public uint ArchiveHashLength;
+ public uint ArchiveMD5SectionSize;
///
- /// Looks like some more MD5 hashes.
+ /// The size, in bytes, of the section containing MD5
+ /// checksums for content in this file (should always be 48)
///
- public uint ExtraLength;
+ public uint OtherMD5SectionSize;
///
- /// Reserved
+ /// The size, in bytes, of the section containing the public
+ /// key and signature. This is either 0 (CSGO & The Ship) or
+ /// 296 (HL2, HL2:DM, HL2:EP1, HL2:EP2, HL2:LC, TF2, DOD:S & CS:S)
///
- public uint Dummy1;
+ public uint SignatureSectionSize;
}
}
diff --git a/SabreTools.Models/VPK/Header.cs b/SabreTools.Models/VPK/Header.cs
index ccaa7ff..aa57e1c 100644
--- a/SabreTools.Models/VPK/Header.cs
+++ b/SabreTools.Models/VPK/Header.cs
@@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
namespace SabreTools.Models.VPK
{
///
+ ///
[StructLayout(LayoutKind.Sequential)]
public sealed class Header
{
@@ -13,6 +14,9 @@ namespace SabreTools.Models.VPK
public uint Version;
- public uint DirectoryLength;
+ ///
+ /// The size, in bytes, of the directory tree
+ ///
+ public uint TreeSize;
}
}
diff --git a/SabreTools.Models/VPK/OtherMD5Section.cs b/SabreTools.Models/VPK/OtherMD5Section.cs
new file mode 100644
index 0000000..976e6c3
--- /dev/null
+++ b/SabreTools.Models/VPK/OtherMD5Section.cs
@@ -0,0 +1,18 @@
+using System.Runtime.InteropServices;
+
+namespace SabreTools.Models.VPK
+{
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public sealed class OtherMD5Section
+ {
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public byte[]? TreeChecksum = new byte[16];
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public byte[]? ArchiveMD5SectionChecksum = new byte[16];
+
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public byte[]? WholeFileChecksum = new byte[16];
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/VPK/SignatureSection.cs b/SabreTools.Models/VPK/SignatureSection.cs
new file mode 100644
index 0000000..1e1ae22
--- /dev/null
+++ b/SabreTools.Models/VPK/SignatureSection.cs
@@ -0,0 +1,29 @@
+using System.Runtime.InteropServices;
+
+namespace SabreTools.Models.VPK
+{
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public sealed class SignatureSection
+ {
+ ///
+ /// Always seen as 160 (0xA0) bytes
+ ///
+ public uint PublicKeySize;
+
+ ///
+ ///
+ ///
+ public byte[]? PublicKey;
+
+ ///
+ /// Always seen as 128 (0x80) bytes
+ ///
+ public uint SignatureSize;
+
+ ///
+ ///
+ ///
+ public byte[]? Signature;
+ }
+}
\ No newline at end of file