0
0
mirror of https://github.com/sp-tarkov/patcher.git synced 2025-02-12 16:50:45 -05:00

Merge pull request #1 from DrakiaXYZ/feat-hdiff

Switch from xdelta to hdiff
This commit is contained in:
waffle-lord 2024-12-29 09:01:55 -05:00 committed by GitHub
commit 2a5d47a392
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 19 additions and 183 deletions

Binary file not shown.

View File

@ -1,161 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using PatcherUtils.Model;
namespace PatcherUtils.Helpers;
public class XdeltaProcessHelper
{
private readonly int _timeout = (int)TimeSpan.FromMinutes(10).TotalMilliseconds;
private string _args;
private string _sourcePath;
private string _deltaPath;
private string _decodedPath;
private bool _isDebug;
public XdeltaProcessHelper(string args, string sourcePath, string deltaPath, string decodedPath, bool isDebug)
{
_args = args;
_sourcePath = sourcePath;
_deltaPath = deltaPath;
_decodedPath = decodedPath;
_isDebug = isDebug;
}
public bool Run() => _isDebug ? RunDebug() : RunNormal();
private bool RunNormal()
{
try
{
using var proc = new Process();
proc.StartInfo = new ProcessStartInfo
{
FileName = LazyOperations.XDelta3Path,
Arguments = $"{_args} \"{_sourcePath}\" \"{_deltaPath}\" \"{_decodedPath}\"",
CreateNoWindow = true
};
proc.Start();
if (!proc.WaitForExit(_timeout))
{
PatchLogger.LogError("xdelta3 process timed out");
PatchLogger.LogDebug($"xdelta exit code: {proc.ExitCode}");
return false;
}
PatchLogger.LogDebug($"xdelta exit code: {proc.ExitCode}");
return true;
}
catch (Exception ex)
{
PatchLogger.LogException(ex);
return false;
}
}
private bool DebugPathsCheck()
{
try
{
var stream = File.Open(_sourcePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
stream.Close();
stream.Dispose();
PatchLogger.LogDebug($"File is openable: {_sourcePath}");
}
catch (Exception ex)
{
PatchLogger.LogException(ex);
return false;
}
try
{
var stream = File.Open(_deltaPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
stream.Close();
stream.Dispose();
PatchLogger.LogDebug($"File is openable: {_deltaPath}");
}
catch (Exception ex)
{
PatchLogger.LogException(ex);
return false;
}
return true;
}
private bool RunDebug()
{
if (!DebugPathsCheck())
{
return false;
}
using var proc = new Process();
proc.StartInfo = new ProcessStartInfo
{
FileName = LazyOperations.XDelta3Path,
Arguments = $"{_args} \"{_sourcePath}\" \"{_deltaPath}\" \"{_decodedPath}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
var outputBuilder = new StringBuilder();
var errorBuilder = new StringBuilder();
using AutoResetEvent outputWaitHandle = new AutoResetEvent(false);
using AutoResetEvent errorWaitHandle = new AutoResetEvent(false);
proc.OutputDataReceived += (s, e) =>
{
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
outputBuilder.AppendLine(e.Data);
}
};
proc.ErrorDataReceived += (s, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
errorBuilder.AppendLine(e.Data);
}
};
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
if (!proc.WaitForExit(_timeout) || !outputWaitHandle.WaitOne(_timeout) || !errorWaitHandle.WaitOne(_timeout))
{
PatchLogger.LogError("xdelta3 process timed out");
PatchLogger.LogDebug($"xdelta exit code: {proc.ExitCode}");
return false;
}
PatchLogger.LogDebug("__xdelta stdout__");
PatchLogger.LogDebug(outputBuilder.ToString());
PatchLogger.LogDebug("__xdelta stderr__");
PatchLogger.LogDebug(errorBuilder.ToString());
PatchLogger.LogDebug($"xdelta exit code: {proc.ExitCode}");
return true;
}
}

View File

@ -32,12 +32,12 @@ namespace PatcherUtils
/// </summary> /// </summary>
public static string PatcherClientPath = $"{TempDir}\\{PatcherClient}"; public static string PatcherClientPath = $"{TempDir}\\{PatcherClient}";
private static string XDelta3EXE = "xdelta3.exe"; private static string HDiffEXE = "hdiffz.exe";
/// <summary> /// <summary>
/// The path to the xdelta3.exe flie in the <see cref="TempDir"/> /// The path to the hdiffz.exe file in the <see cref="TempDir"/>
/// </summary> /// </summary>
public static string XDelta3Path = $"{TempDir}\\{XDelta3EXE}"; public static string HDiffPath = $"{TempDir}\\{HDiffEXE}";
/// <summary> /// <summary>
/// Streams embedded resources out of the assembly /// Streams embedded resources out of the assembly
@ -90,9 +90,9 @@ namespace PatcherUtils
StreamResourceOut(assembly, resource, PatcherClientPath); StreamResourceOut(assembly, resource, PatcherClientPath);
break; break;
} }
case string a when a.EndsWith(XDelta3EXE): case string a when a.EndsWith(HDiffEXE):
{ {
StreamResourceOut(assembly, resource, XDelta3Path); StreamResourceOut(assembly, resource, HDiffPath);
break; break;
} }
} }

View File

@ -1,5 +1,6 @@
using PatchClient.Models; using PatchClient.Models;
using PatcherUtils.Model; using PatcherUtils.Model;
using SharpHDiffPatch.Core;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@ -9,7 +10,6 @@ using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using PleOps.XdeltaSharp.Decoder;
namespace PatcherUtils namespace PatcherUtils
{ {
@ -116,11 +116,11 @@ namespace PatcherUtils
try try
{ {
using var inputFile = new FileStream(SourceFilePath, FileMode.Open); HDiffPatch patcher = new HDiffPatch();
using var patchFile = new FileStream(DeltaFilePath, FileMode.Open); HDiffPatch.LogVerbosity = Verbosity.Quiet;
using var decodedFile = new FileStream(decodedPath, FileMode.Create);
using var decoder = new Decoder(inputFile, patchFile, decodedFile); patcher.Initialize(DeltaFilePath);
decoder.Run(); patcher.Patch(SourceFilePath, decodedPath, false, default, false, false);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -162,10 +162,11 @@ namespace PatcherUtils
PatchLogger.LogException(ex); PatchLogger.LogException(ex);
} }
// The parameters we use here are important to allow patch application using the SharpHDiffPatch.Core library, please don't change them
Process.Start(new ProcessStartInfo Process.Start(new ProcessStartInfo
{ {
FileName = LazyOperations.XDelta3Path, FileName = LazyOperations.HDiffPath,
Arguments = $"-0 -e -f -S none -s \"{SourceFilePath}\" \"{TargetFilePath}\" \"{deltaPath}\"", Arguments = $"-s-64 -c-zstd-21-24 -d \"{SourceFilePath}\" \"{TargetFilePath}\" \"{deltaPath}\"",
CreateNoWindow = true CreateNoWindow = true
}) })
.WaitForExit(); .WaitForExit();
@ -302,7 +303,7 @@ namespace PatcherUtils
Parallel.ForEach(targetFiles, Parallel.ForEach(targetFiles,
new ParallelOptions() { MaxDegreeOfParallelism = 5 }, targetFile => new ParallelOptions() { MaxDegreeOfParallelism = 10 }, targetFile =>
{ {
//find a matching source file based on the relative path of the file //find a matching source file based on the relative path of the file
FileInfo sourceFile = sourceFiles.Find(f => FileInfo sourceFile = sourceFiles.Find(f =>

View File

@ -6,13 +6,9 @@
<FileVersion>2.15.3</FileVersion> <FileVersion>2.15.3</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="Resources\xdelta3.exe" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\7z.dll" /> <EmbeddedResource Include="Resources\7z.dll" />
<EmbeddedResource Include="Resources\xdelta3.exe" /> <EmbeddedResource Include="Resources\hdiffz.exe" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -22,7 +18,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="PleOps.XdeltaSharp" Version="1.3.0" /> <PackageReference Include="SharpHDiffPatch.Core" Version="2.2.8" />
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" /> <PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" />
</ItemGroup> </ItemGroup>

Binary file not shown.