2024-03-22 13:03:07 -04:00
|
|
|
|
using System;
|
|
|
|
|
using PatcherUtils.Model;
|
2021-08-01 15:12:22 -04:00
|
|
|
|
using System.IO;
|
2021-08-01 00:36:37 -04:00
|
|
|
|
using System.Reflection;
|
2024-03-22 13:03:07 -04:00
|
|
|
|
using SevenZip;
|
2021-08-01 00:36:37 -04:00
|
|
|
|
|
|
|
|
|
namespace PatcherUtils
|
|
|
|
|
{
|
|
|
|
|
public class LazyOperations
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A directory to store temporary data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static string TempDir = "PATCHER_TEMP".FromCwd();
|
|
|
|
|
|
2021-08-01 15:12:22 -04:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The folder that the patches will be stored in
|
|
|
|
|
/// </summary>
|
2024-05-23 20:07:47 -04:00
|
|
|
|
public static string PatchFolder = "SPT_Patches";
|
2021-12-17 16:02:31 -05:00
|
|
|
|
|
2024-03-22 13:03:07 -04:00
|
|
|
|
private static string SevenZDll = "7z.dll";
|
2021-08-01 15:12:22 -04:00
|
|
|
|
|
2021-08-01 00:36:37 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The path to the 7za.exe file in the <see cref="TempDir"/>
|
|
|
|
|
/// </summary>
|
2024-03-22 13:03:07 -04:00
|
|
|
|
public static string SevenZDllPath = $"{TempDir}\\{SevenZDll}";
|
2021-08-01 00:36:37 -04:00
|
|
|
|
|
2021-08-01 15:12:22 -04:00
|
|
|
|
private static string PatcherClient = "PatchClient.exe";
|
2021-08-01 00:36:37 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// The path to the patcher.exe file in the <see cref="TempDir"/>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static string PatcherClientPath = $"{TempDir}\\{PatcherClient}";
|
|
|
|
|
|
2024-12-27 18:36:40 -08:00
|
|
|
|
private static string HDiffEXE = "hdiffz.exe";
|
2021-12-17 16:02:31 -05:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-12-27 18:36:40 -08:00
|
|
|
|
/// The path to the hdiffz.exe file in the <see cref="TempDir"/>
|
2021-12-17 16:02:31 -05:00
|
|
|
|
/// </summary>
|
2024-12-27 18:36:40 -08:00
|
|
|
|
public static string HDiffPath = $"{TempDir}\\{HDiffEXE}";
|
2021-12-17 16:02:31 -05:00
|
|
|
|
|
2021-08-01 00:36:37 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Streams embedded resources out of the assembly
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="ResourceName"></param>
|
|
|
|
|
/// <param name="OutputFilePath"></param>
|
|
|
|
|
/// <remarks>The resource will not be streamed out if the <paramref name="OutputFilePath"/> already exists</remarks>
|
2021-12-29 11:04:02 -05:00
|
|
|
|
private static void StreamResourceOut(Assembly assembly, string ResourceName, string OutputFilePath)
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
|
|
|
|
FileInfo outputFile = new FileInfo(OutputFilePath);
|
|
|
|
|
|
2022-02-23 09:04:50 -05:00
|
|
|
|
if (outputFile.Exists)
|
|
|
|
|
{
|
2022-06-14 21:26:23 -04:00
|
|
|
|
PatchLogger.LogInfo($"Deleting Existing Resource: {outputFile.Name}");
|
2022-02-23 09:04:50 -05:00
|
|
|
|
outputFile.Delete();
|
|
|
|
|
}
|
2021-08-01 00:36:37 -04:00
|
|
|
|
|
|
|
|
|
if (!outputFile.Directory.Exists)
|
|
|
|
|
{
|
2022-06-14 21:26:23 -04:00
|
|
|
|
PatchLogger.LogInfo($"Creating Resource Directory: {outputFile.Directory.Name}");
|
2021-08-01 00:36:37 -04:00
|
|
|
|
Directory.CreateDirectory(outputFile.Directory.FullName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using (FileStream fs = File.Create(OutputFilePath))
|
2021-12-29 11:04:02 -05:00
|
|
|
|
using (Stream s = assembly.GetManifestResourceStream(ResourceName))
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
|
|
|
|
s.CopyTo(fs);
|
2022-06-14 21:26:23 -04:00
|
|
|
|
PatchLogger.LogInfo($"Resourced streamed out of assembly: {outputFile.Name}");
|
2021-08-01 00:36:37 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Checks the resources in the assembly and streams them to the temp directory for later use.
|
|
|
|
|
/// </summary>
|
2021-12-29 11:04:02 -05:00
|
|
|
|
public static void ExtractResourcesToTempDir(Assembly assembly = null)
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
2021-12-29 11:04:02 -05:00
|
|
|
|
if(assembly == null) assembly = Assembly.GetExecutingAssembly();
|
|
|
|
|
|
|
|
|
|
foreach (string resource in assembly.GetManifestResourceNames())
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
2021-12-25 20:24:00 -05:00
|
|
|
|
switch (resource)
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
2024-03-22 13:03:07 -04:00
|
|
|
|
case string a when a.EndsWith(SevenZDll):
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
2024-03-22 13:03:07 -04:00
|
|
|
|
StreamResourceOut(assembly, resource, SevenZDllPath);
|
2021-08-01 00:36:37 -04:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case string a when a.EndsWith(PatcherClient):
|
|
|
|
|
{
|
2021-12-29 11:04:02 -05:00
|
|
|
|
StreamResourceOut(assembly, resource, PatcherClientPath);
|
2021-08-01 00:36:37 -04:00
|
|
|
|
break;
|
|
|
|
|
}
|
2024-12-27 18:36:40 -08:00
|
|
|
|
case string a when a.EndsWith(HDiffEXE):
|
2021-12-17 16:02:31 -05:00
|
|
|
|
{
|
2024-12-27 18:36:40 -08:00
|
|
|
|
StreamResourceOut(assembly, resource, HDiffPath);
|
2021-12-17 16:02:31 -05:00
|
|
|
|
break;
|
|
|
|
|
}
|
2021-08-01 00:36:37 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-22 13:03:07 -04:00
|
|
|
|
public static void CompressDirectory(string SourceDirectoryPath, string DestinationFilePath, IProgress<int> progress)
|
2021-08-01 15:12:22 -04:00
|
|
|
|
{
|
2024-05-03 14:57:08 -04:00
|
|
|
|
try
|
2021-08-01 15:12:22 -04:00
|
|
|
|
{
|
2024-05-03 14:57:08 -04:00
|
|
|
|
PatchLogger.LogInfo($"Compressing: {SourceDirectoryPath}");
|
|
|
|
|
PatchLogger.LogInfo($"Output file: {DestinationFilePath}");
|
|
|
|
|
var outputFile = new FileInfo(DestinationFilePath);
|
|
|
|
|
SevenZipBase.SetLibraryPath(SevenZDllPath);
|
|
|
|
|
|
|
|
|
|
PatchLogger.LogInfo($"7z.dll set: {SevenZDllPath}");
|
|
|
|
|
|
|
|
|
|
var compressor = new SevenZipCompressor()
|
|
|
|
|
{
|
|
|
|
|
ArchiveFormat = OutArchiveFormat.SevenZip,
|
|
|
|
|
CompressionMethod = CompressionMethod.Lzma2,
|
2024-05-04 10:56:49 -04:00
|
|
|
|
CompressionLevel = CompressionLevel.Normal,
|
|
|
|
|
PreserveDirectoryRoot = true
|
2024-05-03 14:57:08 -04:00
|
|
|
|
};
|
2021-08-01 15:12:22 -04:00
|
|
|
|
|
2024-05-03 14:57:08 -04:00
|
|
|
|
compressor.Compressing += (_, args) => { progress.Report(args.PercentDone); };
|
|
|
|
|
|
|
|
|
|
using var outputStream = outputFile.OpenWrite();
|
|
|
|
|
|
|
|
|
|
PatchLogger.LogInfo("Starting compression");
|
|
|
|
|
|
|
|
|
|
compressor.CompressDirectory(SourceDirectoryPath, outputStream);
|
|
|
|
|
|
|
|
|
|
PatchLogger.LogInfo("Compression complete");
|
2024-03-22 13:03:07 -04:00
|
|
|
|
|
2024-05-03 14:57:08 -04:00
|
|
|
|
outputFile.Refresh();
|
2022-06-14 21:26:23 -04:00
|
|
|
|
|
2024-05-03 14:57:08 -04:00
|
|
|
|
// failed to compress data
|
|
|
|
|
if (!outputFile.Exists || outputFile.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
PatchLogger.LogError("Failed to compress patcher");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
2024-03-22 13:03:07 -04:00
|
|
|
|
{
|
2024-05-03 14:57:08 -04:00
|
|
|
|
PatchLogger.LogException(ex);
|
2024-03-22 13:03:07 -04:00
|
|
|
|
}
|
2021-08-01 15:12:22 -04:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-01 00:36:37 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Deletes the <see cref="TempDir"/> recursively
|
|
|
|
|
/// </summary>
|
2021-08-01 15:12:22 -04:00
|
|
|
|
public static void CleanupTempDir()
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
|
|
|
|
DirectoryInfo dir = new DirectoryInfo(TempDir);
|
|
|
|
|
|
2021-12-25 20:24:00 -05:00
|
|
|
|
if (dir.Exists)
|
2021-08-01 00:36:37 -04:00
|
|
|
|
{
|
|
|
|
|
dir.Delete(true);
|
2024-05-03 14:57:08 -04:00
|
|
|
|
PatchLogger.LogInfo("Temp directory deleted");
|
2021-08-01 00:36:37 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|