diff --git a/BurnOutSharp/FileType/VPK.cs b/BurnOutSharp/FileType/VPK.cs new file mode 100644 index 00000000..627485ad --- /dev/null +++ b/BurnOutSharp/FileType/VPK.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Concurrent; +using System.IO; +using BurnOutSharp.Interfaces; +using static BurnOutSharp.Utilities.Dictionary; + +namespace BurnOutSharp.FileType +{ + /// + /// Valve Package File + /// + public class VPK : IScannable + { + /// + public ConcurrentDictionary> Scan(Scanner scanner, string file) + { + if (!File.Exists(file)) + return null; + + using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return Scan(scanner, fs, file); + } + } + + /// + public ConcurrentDictionary> Scan(Scanner scanner, Stream stream, string file) + { + // If the VPK file itself fails + try + { + string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(tempPath); + + // Create the wrapper + Wrappers.VPK vpk = Wrappers.VPK.Create(stream); + if (vpk == null) + return null; + + // Loop through and extract all files + vpk.ExtractAll(tempPath); + + // Collect and format all found protections + var protections = scanner.GetProtections(tempPath); + + // If temp directory cleanup fails + try + { + Directory.Delete(tempPath, true); + } + catch (Exception ex) + { + if (scanner.IncludeDebug) Console.WriteLine(ex); + } + + // Remove temporary path references + StripFromKeys(protections, tempPath); + + return protections; + } + catch (Exception ex) + { + if (scanner.IncludeDebug) Console.WriteLine(ex); + } + + return null; + } + } +} diff --git a/BurnOutSharp/Scanner.cs b/BurnOutSharp/Scanner.cs index e9c23436..8e8ad37b 100644 --- a/BurnOutSharp/Scanner.cs +++ b/BurnOutSharp/Scanner.cs @@ -465,6 +465,14 @@ namespace BurnOutSharp AppendToDictionary(protections, subProtections); } + // VPK + if (fileName != null && scannable is VPK) + { + var subProtections = scannable.Scan(this, fileName); + PrependToKeys(subProtections, fileName); + AppendToDictionary(protections, subProtections); + } + // XZ if (scannable is XZ) { diff --git a/BurnOutSharp/Tools/Utilities.cs b/BurnOutSharp/Tools/Utilities.cs index 6c88b24b..1d7418dc 100644 --- a/BurnOutSharp/Tools/Utilities.cs +++ b/BurnOutSharp/Tools/Utilities.cs @@ -641,7 +641,7 @@ namespace BurnOutSharp.Tools case SupportedFileType.TapeArchive: return new FileType.TapeArchive(); case SupportedFileType.Textfile: return new FileType.Textfile(); case SupportedFileType.VBSP: return new FileType.Valve(); - case SupportedFileType.VPK: return new FileType.Valve(); + case SupportedFileType.VPK: return new FileType.VPK(); case SupportedFileType.WAD: return new FileType.Valve(); case SupportedFileType.XZ: return new FileType.XZ(); case SupportedFileType.XZP: return new FileType.Valve();