A binary patch generation utility using BsDiff library for creating differential patches between original and modified game files.
PatchCreator creates binary patches that can transform original game files into modified versions, essential for:
- Distributing localization changes efficiently
- Creating update patches for games
- Reducing download sizes for modifications
cd Tools/PatchCreator
dotnet publish -c Release
# or use the main build script from project root
../../build.ps1PatchCreator/
├── original/ # Place original files here
├── [current dir]/ # Place modified files here
└── patch/ # Generated patches appear here
cd Tools/PatchCreator
# 1. Place original files in 'original' folder
# 2. Place modified files in current directory
# 3. Run patch generation
PatchCreator.exe- Automatic detection - Finds matching files between
original/and current directory - Async parallel processing - Creates multiple patches simultaneously with controlled concurrency
- Progress tracking - Shows real-time progress for each file with timing
- Cancellation support - Graceful Ctrl+C handling with cleanup
- Output generation - Creates
.patchfiles inpatch/folder
- Location:
patch/directory - Naming: Same filename as original (e.g.,
game.exe.patch) - Format: BsDiff binary patch format
- Usage: Can be applied with BsPatch utility
Creating patch for game.exe... [3s]
Creating patch for resources.dat... [1s]
Creating patch for localization.txt... [0s]
Done.
- Library: BsDiff (binary differential algorithm)
- Efficiency: Creates small patches for similar files
- Format: Standard BsDiff patch format
- Uses
Task.WhenAllwithSemaphoreSlimfor controlled concurrency - Thread-safe progress reporting with locking
- Respects CPU core count to prevent resource exhaustion
- Async file I/O operations for better performance
var files = Directory.GetFiles(originalDir)
.Select(x => (Original: x, ExpectedChangedPath: Path.Combine(dir, Path.GetFileName(x))))
.ToList();- Real-time timer display for each patch
- Thread-safe console output with cursor positioning
- Completion time reporting
- Cancellation support with cleanup
var tasks = files
.Select((file, index) => CreateFilePatchAsync(file, patchDir, startRow + index, lockObj, semaphore, appCts.Token))
.ToList();
await Task.WhenAll(tasks);static async Task CreateFilePatchAsync(
(string Original, string ExpectedChangedPath) file,
string patchDir,
int row,
object lockObj,
SemaphoreSlim semaphore,
CancellationToken cancellationToken)
{
var original = await File.ReadAllBytesAsync(file.Original, cancellationToken);
var changed = await File.ReadAllBytesAsync(file.ExpectedChangedPath, cancellationToken);
using var patch = File.Create(patchPath);
await Task.Run(() => BinaryPatch.Create(original, changed, patch), cancellationToken);
await patch.FlushAsync(cancellationToken);
}- BsDiff library - Binary differential algorithm
- System.IO - File operations
- System.Threading.Tasks - Async parallel processing
- System.Threading - SemaphoreSlim for concurrency control
- .NET 8