From 18cdf9d7edc5bc1de2064ae6bbc9749e221894a4 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 27 Dec 2022 01:07:46 -0800 Subject: [PATCH] Use new SGA extraction --- BurnOutSharp.Models/SGA/File.cs | 3 ++ BurnOutSharp/FileType/SGA.cs | 69 +++++++++++++++++++++++++++++++++ BurnOutSharp/Scanner.cs | 8 ++++ BurnOutSharp/Tools/Utilities.cs | 1 + README.md | 2 +- Test/Program.cs | 2 +- 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 BurnOutSharp/FileType/SGA.cs diff --git a/BurnOutSharp.Models/SGA/File.cs b/BurnOutSharp.Models/SGA/File.cs index 51a56004..013e280e 100644 --- a/BurnOutSharp.Models/SGA/File.cs +++ b/BurnOutSharp.Models/SGA/File.cs @@ -1,5 +1,8 @@ namespace BurnOutSharp.Models.SGA { + /// + /// SGA game archive + /// /// public class File { diff --git a/BurnOutSharp/FileType/SGA.cs b/BurnOutSharp/FileType/SGA.cs new file mode 100644 index 00000000..b3404cf0 --- /dev/null +++ b/BurnOutSharp/FileType/SGA.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 +{ + /// + /// SGA game archive + /// + public class SGA : 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 SGA file itself fails + try + { + string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); + Directory.CreateDirectory(tempPath); + + // Create the wrapper + Wrappers.SGA sga = Wrappers.SGA.Create(stream); + if (sga == null) + return null; + + // Loop through and extract all files + sga.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 a0d6f7c5..eb4709ad 100644 --- a/BurnOutSharp/Scanner.cs +++ b/BurnOutSharp/Scanner.cs @@ -473,6 +473,14 @@ namespace BurnOutSharp AppendToDictionary(protections, subProtections); } + // SGA + if (scannable is SGA) + { + var subProtections = scannable.Scan(this, stream, fileName); + PrependToKeys(subProtections, fileName); + AppendToDictionary(protections, subProtections); + } + // Tape Archive if (scannable is TapeArchive) { diff --git a/BurnOutSharp/Tools/Utilities.cs b/BurnOutSharp/Tools/Utilities.cs index bab01b92..932ec652 100644 --- a/BurnOutSharp/Tools/Utilities.cs +++ b/BurnOutSharp/Tools/Utilities.cs @@ -640,6 +640,7 @@ namespace BurnOutSharp.Tools case SupportedFileType.RAR: return new FileType.RAR(); case SupportedFileType.SevenZip: return new FileType.SevenZip(); case SupportedFileType.SFFS: return new FileType.SFFS(); + case SupportedFileType.SGA: return new FileType.SGA(); case SupportedFileType.TapeArchive: return new FileType.TapeArchive(); case SupportedFileType.Textfile: return new FileType.Textfile(); case SupportedFileType.VBSP: return new FileType.VBSP(); diff --git a/README.md b/README.md index d05743fe..4afb9323 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ Below is a list of container formats that are supported in some way: | PlayJ audio file (PLJ) | No | Yes | No | | | Portable Executable | Yes | Yes | No* | Some packed executables are supported | | RAR archive (RAR) | No | Yes | Yes | Via `SharpCompress` | -| SGA? | No | No | No | Skeleton only | +| SGA game archive | Yes | Yes | Yes | | | StarForce Filesystem file (SFFS) | No | Yes | No | Skeleton only | | Tape archive (TAR) | No | Yes | Yes | Via `SharpCompress` | | Valve Package File (VPK) | Yes | Yes | Yes | | diff --git a/Test/Program.cs b/Test/Program.cs index 6e75c120..03246e37 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -424,7 +424,7 @@ namespace Test pak.Print(); } - // PAK + // SGA else if (ft == SupportedFileType.SGA) { // Build the archive information