diff --git a/Patcher/PatchClient/MainWindow.xaml.cs b/Patcher/PatchClient/MainWindow.xaml.cs index 1c1d8af..5f222aa 100644 --- a/Patcher/PatchClient/MainWindow.xaml.cs +++ b/Patcher/PatchClient/MainWindow.xaml.cs @@ -21,24 +21,18 @@ namespace PatchClient { Task.Run(() => { - FilePatcher bp = new FilePatcher() - { - TargetBase = Environment.CurrentDirectory, - PatchBase = LazyOperations.PatchFolder.FromCwd() - }; + PatchHelper patcher = new PatchHelper(Environment.CurrentDirectory, null, LazyOperations.PatchFolder.FromCwd()); - bp.ProgressChanged += Bp_ProgressChanged; + patcher.ProgressChanged += patcher_ProgressChanged; try { - if (bp.Run()) - { - MessageBox.Show("Patch completed without issues", "Patching Successful"); - } - else - { - MessageBox.Show("Failed to patch client.", "Patching Failed", MessageBoxButton.OK, MessageBoxImage.Error); - } + LazyOperations.CleanupTempDir(); + LazyOperations.PrepTempDir(); + + string message = patcher.ApplyPatches(); + + MessageBox.Show(message, "Patcher"); } catch(Exception ex) { @@ -54,7 +48,7 @@ namespace PatchClient }); } - private void Bp_ProgressChanged(object Sender, int Progress, int Total, int Percent, string Message = "", params LineItem[] AdditionalLineItems) + private void patcher_ProgressChanged(object Sender, int Progress, int Total, int Percent, string Message = "", params LineItem[] AdditionalLineItems) { string additionalInfo = ""; foreach (LineItem item in AdditionalLineItems) diff --git a/Patcher/PatchClient/PatchClient.csproj b/Patcher/PatchClient/PatchClient.csproj index 50f77b1..db0004b 100644 --- a/Patcher/PatchClient/PatchClient.csproj +++ b/Patcher/PatchClient/PatchClient.csproj @@ -6,6 +6,14 @@ true + + + + + + + + diff --git a/Patcher/PatchClient/Properties/launchSettings.json b/Patcher/PatchClient/Properties/launchSettings.json new file mode 100644 index 0000000..e0551b4 --- /dev/null +++ b/Patcher/PatchClient/Properties/launchSettings.json @@ -0,0 +1,7 @@ +{ + "profiles": { + "PatchClient": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/Patcher/PatchClient/Resources/xdelta3.exe b/Patcher/PatchClient/Resources/xdelta3.exe new file mode 100644 index 0000000..1cce3c5 Binary files /dev/null and b/Patcher/PatchClient/Resources/xdelta3.exe differ diff --git a/Patcher/PatchGenerator/MainWindow.xaml.cs b/Patcher/PatchGenerator/MainWindow.xaml.cs index 47eb5dc..90ffea5 100644 --- a/Patcher/PatchGenerator/MainWindow.xaml.cs +++ b/Patcher/PatchGenerator/MainWindow.xaml.cs @@ -120,13 +120,14 @@ namespace PatchGenerator GenProgressBar.DispatcherSetIndetermination(false); //generate patches - FileCompare bc = new FileCompare(targetFolder, compareFolder, patchBase); + //TODO - fix these weird variable names (why did I do this?) + PatchHelper patcher = new PatchHelper(compareFolder, targetFolder, patchBase); - bc.ProgressChanged += Bc_ProgressChanged; + patcher.ProgressChanged += patcher_ProgressChanged; - if (!bc.CompareAll()) + if (!patcher.GeneratePatches()) { - MessageBox.Show("Failed to generate diffs.", ":(", MessageBoxButton.OK, MessageBoxImage.Error); + MessageBox.Show("One of the provided folder paths doesn't exist.", "Oops :(", MessageBoxButton.OK, MessageBoxImage.Error); } //Copy patch client to output folder @@ -142,7 +143,7 @@ namespace PatchGenerator GenProgressMessageLabel.DispaatcherSetContent("Done"); } - private void Bc_ProgressChanged(object Sender, int Progress, int Total, int Percent, string Message = "", params LineItem[] AdditionalLineItems) + private void patcher_ProgressChanged(object Sender, int Progress, int Total, int Percent, string Message = "", params LineItem[] AdditionalLineItems) { string additionalInfo = ""; foreach (LineItem item in AdditionalLineItems) diff --git a/Patcher/PatchGenerator/PatchGenerator.csproj b/Patcher/PatchGenerator/PatchGenerator.csproj index e3bc973..3a3ee2e 100644 --- a/Patcher/PatchGenerator/PatchGenerator.csproj +++ b/Patcher/PatchGenerator/PatchGenerator.csproj @@ -11,15 +11,9 @@ - - References\Aki.ByteBanger.dll - References\Aki.Common.dll - - References\ComponentAce.Compression.Libs.zlib.dll - diff --git a/Patcher/PatcherUtils/FileCompare.cs b/Patcher/PatcherUtils/FileCompare.cs deleted file mode 100644 index 63aa4a2..0000000 --- a/Patcher/PatcherUtils/FileCompare.cs +++ /dev/null @@ -1,185 +0,0 @@ -// NOTES: -// - redo search pattern; -// - compare both directories against eachother, not just one to the other -// - add ability to handle missing directories - -using System.IO; -using Aki.Common.Utils; -using Aki.ByteBanger; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace PatcherUtils -{ - public class FileCompare - { - public string PatchBase; - public string TargetBase; - public string CompareBase; - private int fileCount; - private int fileIt; - - private int diffCount = 0; - private int newCount = 0; - private int delCount = 0; - private int matchCount = 0; - - private List TargetPaths; - private List ComparePaths; - private List AdditionalInfo = new List(); - - /// - /// Provides patch generation progress changes - /// - public event ProgressChangedHandler ProgressChanged; - protected virtual void RaiseProgressChanged(int progress, int total, string Message = "", params LineItem[] AdditionalLineItems) - { - int percent = (int)Math.Floor((double)progress / total * 100); - - ProgressChanged?.Invoke(this, progress, total, percent, Message, AdditionalLineItems); - } - - /// - /// Compare a target file to an assumed compareable file. - /// - /// The known target path - /// The assumed comparable file path - /// True if a comparison was made | False if a comparison could not be made - private bool Compare(string targetFile, string assumedCompareFile) - { - string patchFilePath = targetFile.Replace(TargetBase, PatchBase); - //we know our target file exists - byte[] targetData = VFS.ReadFile(targetFile); - - if(!File.Exists(assumedCompareFile)) - { - //save the data we won't have in our target as new - VFS.WriteFile($"{patchFilePath}.new", Zlib.Compress(targetData, ZlibCompression.Maximum)); - newCount++; - return true; - } - - //now our compare file is known to exist - byte[] compareData = VFS.ReadFile(assumedCompareFile); - - // get diffs - DiffResult result = PatchUtil.Diff(compareData, targetData); - - switch (result.Result) - { - case DiffResultType.Success: - VFS.WriteFile($"{patchFilePath}.bpf", result.PatchInfo.ToBytes()); - diffCount++; - return true; - - case DiffResultType.FilesMatch: - matchCount++; - return true; - - default: - return false; - } - } - - /// - /// Compares the base folders and generates patch files. - /// - /// True if patches were generated successfully | False if patch generation failed - public bool CompareAll() - { - DirectoryInfo targetDirInfo = new DirectoryInfo(TargetBase); - DirectoryInfo compareDirInfo = new DirectoryInfo(CompareBase); - - AdditionalInfo.Add(new LineItem("Diff Patch", "0")); - AdditionalInfo.Add(new LineItem("New Patch", "0")); - AdditionalInfo.Add(new LineItem("Del Patch", "0")); - AdditionalInfo.Add(new LineItem("Files Match", "0")); - - if (!targetDirInfo.Exists || !compareDirInfo.Exists) - { - Console.WriteLine("Target or Compare folder does not exist"); - return false; - } - - //Get all the files recursively - TargetPaths = new List(targetDirInfo.GetFiles("*.*", SearchOption.AllDirectories)); - ComparePaths = new List(compareDirInfo.GetFiles("*.*", SearchOption.AllDirectories)); - - RaiseProgressChanged(0, fileCount, "Generating diffs..."); - - /* Comparing Target files -> Compare files - * - Exists = Diff (.bfd file) - * - Doesn't Exist = New (.new file) - * - * Once everything has been compared from one side, any remaining paths in our ComparePaths - * are things that don't exist in our target and can be deleted (.del file) - */ - - for (int x = 0; x < TargetPaths.Count; x++) - { - FileInfo file = TargetPaths[x]; - - string assumedComparePath = file.DirectoryName.Replace(TargetBase, CompareBase); - - if (!Compare(file.FullName, VFS.Combine(assumedComparePath, file.Name))) - { - return false; - } - - //remove any existing files from our ComparePaths - FileInfo assumedFile = new FileInfo(VFS.Combine(assumedComparePath, file.Name)); - if (assumedFile.Exists && ComparePaths.Exists(x => x.FullName == assumedFile.FullName)) - { - ComparePaths.Remove(ComparePaths.Where(x => x.FullName == assumedFile.FullName).FirstOrDefault()); - } - - - AdditionalInfo[0].ItemValue = diffCount.ToString(); - AdditionalInfo[1].ItemValue = newCount.ToString(); - AdditionalInfo[3].ItemValue = matchCount.ToString(); - - fileIt++; - RaiseProgressChanged(fileIt, fileCount, file.Name, AdditionalInfo.ToArray()); - } - - - if (ComparePaths.Count == 0) - { - //if there are no files to delete, just return true - return true; - } - - //progress reset for files that need to be deleted - RaiseProgressChanged(0, ComparePaths.Count, "Processing .del files..."); - fileIt = 0; - fileCount = ComparePaths.Count; - - //the paths remaining in ComparePaths don't exist in our target and need to be removed during patching. - foreach (FileInfo file in ComparePaths) - { - //add del files replace root dir with patch base - string patchFilePath = file.FullName.Replace(CompareBase, PatchBase); - VFS.WriteFile($"{patchFilePath}.del", new byte[0]); - - delCount++; - AdditionalInfo[2].ItemValue = delCount.ToString(); - - fileIt++; - RaiseProgressChanged(fileIt, fileCount, "", AdditionalInfo.ToArray()); - } - - return true; - } - - public FileCompare(string TargetBase, string CompareBase, string PatchBase) - { - this.TargetBase = TargetBase; - this.CompareBase = CompareBase; - this.PatchBase = PatchBase; - - fileCount = VFS.GetFilesCount(TargetBase); - fileIt = 0; - } - } -} diff --git a/Patcher/PatcherUtils/FilePatcher.cs b/Patcher/PatcherUtils/FilePatcher.cs deleted file mode 100644 index f3ec4db..0000000 --- a/Patcher/PatcherUtils/FilePatcher.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.IO; -using Aki.Common.Utils; -using Aki.ByteBanger; -using System.Collections.Generic; -using System.Linq; - -namespace PatcherUtils -{ - public class FilePatcher - { - public string TargetBase; - public string PatchBase; - private int fileCount; - private int fileIt; - - private int diffCount; - private int newCount; - private int delCount; - - private List AdditionalInfo; - - - public event ProgressChangedHandler ProgressChanged; - - protected virtual void RaiseProgressChanged(int progress, int total, string Message = "", params LineItem[] AdditionalLineItems) - { - int percent = (int)Math.Floor((double)progress / total * 100); - - ProgressChanged?.Invoke(this, progress, total, percent, Message, AdditionalLineItems); - } - - public bool Patch(string targetfile, string patchfile) - { - byte[] target = VFS.ReadFile(targetfile); - byte[] patch = VFS.ReadFile(patchfile); - - PatchResult result = PatchUtil.Patch(target, PatchInfo.FromBytes(patch)); - - switch (result.Result) - { - case PatchResultType.Success: - VFS.WriteFile(targetfile, result.PatchedData); - return true; - - case PatchResultType.AlreadyPatched: - case PatchResultType.InputChecksumMismatch: - case PatchResultType.InputLengthMismatch: - return true; - - case PatchResultType.OutputChecksumMismatch: - default: - return false; - } - } - - private bool PatchAll(string targetpath, string patchpath) - { - DirectoryInfo di = new DirectoryInfo(patchpath); - - foreach (FileInfo file in di.GetFiles()) - { - FileInfo target = null; - - switch (file.Extension) - { - // patch - case ".bpf": - { - target = new FileInfo(VFS.Combine(targetpath, file.Name.Replace(".bpf", ""))); - - if (!Patch(target.FullName, file.FullName)) - { - // patch failed - return false; - } - - diffCount--; - } - break; - - // add new files - case ".new": - { - target = new FileInfo(VFS.Combine(targetpath, file.Name.Replace(".new", ""))); - VFS.WriteFile(target.FullName, Zlib.Decompress(VFS.ReadFile(file.FullName))); - newCount--; - } - break; - - // delete old files - case ".del": - { - target = new FileInfo(VFS.Combine(targetpath, file.Name.Replace(".del", ""))); - target.IsReadOnly = false; - target.Delete(); - delCount--; - } - break; - } - - AdditionalInfo[0].ItemValue = diffCount.ToString(); - AdditionalInfo[1].ItemValue = newCount.ToString(); - AdditionalInfo[2].ItemValue = delCount.ToString(); - - ++fileIt; - RaiseProgressChanged(fileIt, fileCount, target.Name, AdditionalInfo.ToArray()); - } - - foreach (DirectoryInfo directory in di.GetDirectories()) - { - PatchAll(VFS.Combine(targetpath, directory.Name), directory.FullName); - } - - di.Refresh(); - - if (di.GetFiles().Length == 0 && di.GetDirectories().Length == 0) - { - // remove empty folders - di.Delete(); - } - - return true; - } - - public bool Run() - { - fileCount = VFS.GetFilesCount(PatchBase); - - FileInfo[] files = new DirectoryInfo(PatchBase).GetFiles("*.*", SearchOption.AllDirectories); - - diffCount = files.Where(x => x.Extension == ".bpf").Count(); - newCount = files.Where(x => x.Extension == ".new").Count(); - delCount = files.Where(x => x.Extension == ".del").Count(); - - AdditionalInfo = new List() - { - new LineItem("Patches Remaining", diffCount.ToString()), - new LineItem("New Files to Inflate", newCount.ToString()), - new LineItem("Files to Delete", delCount.ToString()) - }; - - fileIt = 0; - return PatchAll(TargetBase, PatchBase); - } - } -} diff --git a/Patcher/PatcherUtils/LazyOperations.cs b/Patcher/PatcherUtils/LazyOperations.cs index d38d6aa..06d4098 100644 --- a/Patcher/PatcherUtils/LazyOperations.cs +++ b/Patcher/PatcherUtils/LazyOperations.cs @@ -12,12 +12,13 @@ namespace PatcherUtils /// public static string TempDir = "PATCHER_TEMP".FromCwd(); - private static string SevenZExe = "7za.exe"; /// /// The folder that the patches will be stored in /// - public static string PatchFolder = "Aki_Data\\Patcher"; + public static string PatchFolder = "Aki_Patches"; + + private static string SevenZExe = "7za.exe"; /// /// The path to the 7za.exe file in the @@ -30,6 +31,13 @@ namespace PatcherUtils /// public static string PatcherClientPath = $"{TempDir}\\{PatcherClient}"; + private static string XDelta3EXE = "xdelta3.exe"; + + /// + /// The path to the xdelta3.exe flie in the + /// + public static string XDelta3Path = $"{TempDir}\\{XDelta3EXE}"; + /// /// Streams embedded resources out of the assembly /// @@ -73,6 +81,11 @@ namespace PatcherUtils StreamResourceOut(resource, PatcherClientPath); break; } + case string a when a.EndsWith(XDelta3EXE): + { + StreamResourceOut(resource, XDelta3Path); + break; + } } } } diff --git a/Patcher/PatcherUtils/PatchHelper.cs b/Patcher/PatcherUtils/PatchHelper.cs new file mode 100644 index 0000000..29395de --- /dev/null +++ b/Patcher/PatcherUtils/PatchHelper.cs @@ -0,0 +1,278 @@ +using Aki.Common.Utils; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; + +namespace PatcherUtils +{ + public class PatchHelper + { + private string SourceFolder = ""; + private string TargetFolder = ""; + private string DeltaFolder = ""; + + private int fileCountTotal; + private int filesProcessed; + + private int deltaCount; + private int newCount; + private int delCount; + + private List AdditionalInfo = new List(); + + public event ProgressChangedHandler ProgressChanged; + + protected virtual void RaiseProgressChanged(int progress, int total, string Message = "", params LineItem[] AdditionalLineItems) + { + int percent = (int)Math.Floor((double)progress / total * 100); + + ProgressChanged?.Invoke(this, progress, total, percent, Message, AdditionalLineItems); + } + + public PatchHelper(string SourceFolder, string TargetFolder, string DeltaFolder) + { + this.SourceFolder = SourceFolder; + this.TargetFolder = TargetFolder; + this.DeltaFolder = DeltaFolder; + } + + private string GetDeltaPath(string sourceFile, string sourceFolder, string extension) + { + return Path.Join(DeltaFolder, $"{sourceFile.Replace(sourceFolder, "")}.{extension}"); + } + + private void ApplyDelta(string SourceFilePath, string DeltaFilePath) + { + string decodedPath = SourceFilePath + ".decoded"; + + Process.Start(new ProcessStartInfo + { + FileName = LazyOperations.XDelta3Path, + Arguments = $"-d -f -s \"{SourceFilePath}\" \"{DeltaFilePath}\" \"{decodedPath}\"", + CreateNoWindow = true + }) + .WaitForExit(); + + if(File.Exists(decodedPath)) + { + File.Delete(SourceFilePath); + File.Move(decodedPath, SourceFilePath); + } + } + + private void CreateDelta(string SourceFilePath, string TargetFilePath) + { + FileInfo sourceFileInfo = new FileInfo(SourceFilePath); + + string deltaPath = GetDeltaPath(SourceFilePath, SourceFolder, "delta"); + + Directory.CreateDirectory(deltaPath.Replace(sourceFileInfo.Name+".delta", "")); + + //TODO - don't hardcode FileName + + Process.Start(new ProcessStartInfo + { + FileName = LazyOperations.XDelta3Path, + Arguments = $"-0 -e -f -s \"{SourceFilePath}\" \"{TargetFilePath}\" \"{deltaPath}\"", + CreateNoWindow = true + }) + .WaitForExit(); + } + + private void CreateDelFile(string SourceFile) + { + FileInfo sourceFileInfo = new FileInfo(SourceFile); + + string deltaPath = GetDeltaPath(SourceFile, SourceFolder, "del"); + + Directory.CreateDirectory(deltaPath.Replace(sourceFileInfo.Name+".del", "")); + + File.Create(deltaPath); + } + + private void CreateNewFile(string TargetFile) + { + FileInfo targetSourceInfo = new FileInfo(TargetFile); + + string deltaPath = GetDeltaPath(TargetFile, TargetFolder, "new"); + + Directory.CreateDirectory(deltaPath.Replace(targetSourceInfo.Name+".new", "")); + + targetSourceInfo.CopyTo(deltaPath, true); + } + + public bool GeneratePatches() + { + //get all directory information needed + DirectoryInfo sourceDir = new DirectoryInfo(SourceFolder); + DirectoryInfo targetDir = new DirectoryInfo(TargetFolder); + DirectoryInfo deltaDir = Directory.CreateDirectory(DeltaFolder); + + //make sure all directories exist + if (!sourceDir.Exists || !targetDir.Exists || !deltaDir.Exists) + { + //One of the directories doesn't exist + return false; + } + + List SourceFiles = sourceDir.GetFiles("*", SearchOption.AllDirectories).ToList(); + + fileCountTotal = SourceFiles.Count; + + AdditionalInfo.Clear(); + AdditionalInfo.Add(new LineItem("Delta Patch", "0")); + AdditionalInfo.Add(new LineItem("New Patch", "0")); + AdditionalInfo.Add(new LineItem("Del Patch", "0")); + + filesProcessed = 0; + + RaiseProgressChanged(0, fileCountTotal, "Generating deltas..."); + + foreach (FileInfo targetFile in targetDir.GetFiles("*", SearchOption.AllDirectories)) + { + //find a matching source file based on the relative path of the file + FileInfo sourceFile = SourceFiles.Find(f => f.FullName.Replace(sourceDir.FullName, "") == targetFile.FullName.Replace(targetDir.FullName, "")); + + //if the target file doesn't exist in the source files, the target file needs to be added. + if (sourceFile == null) + { + CreateNewFile(targetFile.FullName); + + newCount++; + filesProcessed++; + + RaiseProgressChanged(filesProcessed, fileCountTotal, targetFile.Name, AdditionalInfo.ToArray()); + + continue; + } + + //if a matching source file was found, get the delta for it. + CreateDelta(sourceFile.FullName, targetFile.FullName); + + SourceFiles.Remove(sourceFile); + + deltaCount++; + filesProcessed++; + + AdditionalInfo[0].ItemValue = deltaCount.ToString(); + AdditionalInfo[1].ItemValue = newCount.ToString(); + + RaiseProgressChanged(filesProcessed, fileCountTotal, targetFile.Name, AdditionalInfo.ToArray()); + } + + //Any remaining source files do not exist in the target folder and can be removed. + //reset progress info + RaiseProgressChanged(0, SourceFiles.Count, "Processing .del files..."); + filesProcessed = 0; + fileCountTotal = SourceFiles.Count; + + foreach (FileInfo delFile in SourceFiles) + { + CreateDelFile(delFile.FullName); + + delCount++; + + AdditionalInfo[2].ItemValue = delCount.ToString(); + + filesProcessed++; + RaiseProgressChanged(filesProcessed, fileCountTotal, "", AdditionalInfo.ToArray()); + } + + return true; + } + + public string ApplyPatches() + { + //get needed directory information + DirectoryInfo sourceDir = new DirectoryInfo(SourceFolder); + DirectoryInfo deltaDir = new DirectoryInfo(DeltaFolder); + + //check directories exist + if (!sourceDir.Exists || !deltaDir.Exists) + { + return "One of the supplied directories doesn't exist"; + } + + List SourceFiles = sourceDir.GetFiles("*", SearchOption.AllDirectories).ToList(); + + List deltaFiles = deltaDir.GetFiles("*", SearchOption.AllDirectories).ToList(); + + deltaCount = deltaFiles.Where(x => x.Extension == ".delta").Count(); + newCount = deltaFiles.Where(x => x.Extension == ".new").Count(); + delCount = deltaFiles.Where(x => x.Extension == ".del").Count(); + + + AdditionalInfo = new List() + { + new LineItem("Patches Remaining", deltaCount.ToString()), + new LineItem("New Files to Add", newCount.ToString()), + new LineItem("Files to Delete", delCount.ToString()) + }; + + filesProcessed = 0; + + fileCountTotal = deltaFiles.Count; + + foreach (FileInfo deltaFile in deltaDir.GetFiles("*", SearchOption.AllDirectories)) + { + switch(deltaFile.Extension) + { + case ".delta": + { + //apply delta + FileInfo sourceFile = SourceFiles.Find(f => f.FullName.Replace(sourceDir.FullName, "") == deltaFile.FullName.Replace(deltaDir.FullName, "").Replace(".delta", "")); + + if(sourceFile == null) + { + return $"Failed to find matching source file for '{deltaFile.FullName}'"; + } + + ApplyDelta(sourceFile.FullName, deltaFile.FullName); + + deltaCount--; + + break; + } + case ".new": + { + //copy new file + string destination = Path.Join(sourceDir.FullName, deltaFile.FullName.Replace(deltaDir.FullName, "").Replace(".new", "")); + + File.Copy(deltaFile.FullName, destination); + + newCount--; + + break; + } + case ".del": + { + //remove unneeded file + string delFilePath = Path.Join(sourceDir.FullName, deltaFile.FullName.Replace(deltaDir.FullName, "").Replace(".del", "")); + + File.Delete(delFilePath); + + delCount--; + + break; + } + } + + AdditionalInfo[0].ItemValue = deltaCount.ToString(); + AdditionalInfo[1].ItemValue = newCount.ToString(); + AdditionalInfo[2].ItemValue = delCount.ToString(); + + ++filesProcessed; + RaiseProgressChanged(filesProcessed, fileCountTotal, deltaFile.Name, AdditionalInfo.ToArray()); + } + + LazyOperations.CleanupTempDir(); + + Directory.Delete(LazyOperations.PatchFolder, true); + + return $"Patching Complete. You can delete the patcher.exe file."; + } + } +} diff --git a/Patcher/PatcherUtils/PatcherUtils.csproj b/Patcher/PatcherUtils/PatcherUtils.csproj index 2582ff1..8e7ab05 100644 --- a/Patcher/PatcherUtils/PatcherUtils.csproj +++ b/Patcher/PatcherUtils/PatcherUtils.csproj @@ -7,23 +7,19 @@ + + - - ..\PatchGenerator\References\Aki.ByteBanger.dll - ..\PatchGenerator\References\Aki.Common.dll - - ..\PatchGenerator\References\ComponentAce.Compression.Libs.zlib.dll - diff --git a/Patcher/PatcherUtils/Resources/PatchClient.exe b/Patcher/PatcherUtils/Resources/PatchClient.exe index 26da804..8338438 100644 Binary files a/Patcher/PatcherUtils/Resources/PatchClient.exe and b/Patcher/PatcherUtils/Resources/PatchClient.exe differ diff --git a/Patcher/PatcherUtils/Resources/xdelta3.exe b/Patcher/PatcherUtils/Resources/xdelta3.exe new file mode 100644 index 0000000..1cce3c5 Binary files /dev/null and b/Patcher/PatcherUtils/Resources/xdelta3.exe differ