Skip to content

Latest commit

 

History

History
130 lines (104 loc) · 3.78 KB

File metadata and controls

130 lines (104 loc) · 3.78 KB

PatchCreator

en uk

A binary patch generation utility using BsDiff library for creating differential patches between original and modified game files.

🎯 Purpose

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

🛠️ Building

cd Tools/PatchCreator
dotnet publish -c Release
# or use the main build script from project root
../../build.ps1

🚀 Usage

Directory Setup

PatchCreator/
├── original/          # Place original files here
├── [current dir]/     # Place modified files here
└── patch/            # Generated patches appear here

Running the Tool

cd Tools/PatchCreator

# 1. Place original files in 'original' folder
# 2. Place modified files in current directory
# 3. Run patch generation
PatchCreator.exe

Process

  1. Automatic detection - Finds matching files between original/ and current directory
  2. Async parallel processing - Creates multiple patches simultaneously with controlled concurrency
  3. Progress tracking - Shows real-time progress for each file with timing
  4. Cancellation support - Graceful Ctrl+C handling with cleanup
  5. Output generation - Creates .patch files in patch/ folder

📊 Output Format

Patch Files

  • 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

Progress Display

Creating patch for game.exe... [3s]
Creating patch for resources.dat... [1s]
Creating patch for localization.txt... [0s]
Done.

🔧 Technical Details

Algorithm

  • Library: BsDiff (binary differential algorithm)
  • Efficiency: Creates small patches for similar files
  • Format: Standard BsDiff patch format

Parallel Processing

  • Uses Task.WhenAll with SemaphoreSlim for controlled concurrency
  • Thread-safe progress reporting with locking
  • Respects CPU core count to prevent resource exhaustion
  • Async file I/O operations for better performance

File Matching Logic

var files = Directory.GetFiles(originalDir)
    .Select(x => (Original: x, ExpectedChangedPath: Path.Combine(dir, Path.GetFileName(x))))
    .ToList();

Progress Tracking

  • Real-time timer display for each patch
  • Thread-safe console output with cursor positioning
  • Completion time reporting
  • Cancellation support with cleanup

📝 Code Overview

Main Processing Loop

var tasks = files
    .Select((file, index) => CreateFilePatchAsync(file, patchDir, startRow + index, lockObj, semaphore, appCts.Token))
    .ToList();

await Task.WhenAll(tasks);

Patch Creation

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);
}

🛠️ Development

Dependencies

  • BsDiff library - Binary differential algorithm
  • System.IO - File operations
  • System.Threading.Tasks - Async parallel processing
  • System.Threading - SemaphoreSlim for concurrency control
  • .NET 8