From 654deca933b1acf40c06fe5d6f65103562c5a534 Mon Sep 17 00:00:00 2001 From: sanasol Date: Tue, 27 Jan 2026 03:38:09 +0100 Subject: [PATCH] Add HYTALE_PATCH_SKIP to skip specific occurrences by index HYTALE_PATCH_SKIP=0 - skip first occurrence only HYTALE_PATCH_SKIP=0,2 - skip first and third HYTALE_PATCH_SKIP=0 HYTALE_PATCH_LIMIT=1 - patch only second occurrence Co-Authored-By: Claude Opus 4.5 --- backend/utils/clientPatcher.js | 35 +++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/backend/utils/clientPatcher.js b/backend/utils/clientPatcher.js index 46d8fde..442e478 100644 --- a/backend/utils/clientPatcher.js +++ b/backend/utils/clientPatcher.js @@ -185,7 +185,9 @@ class ClientPatcher { } /** - * Replace bytes with a limit on number of occurrences (for debugging) + * Replace bytes with skip/limit control (for debugging) + * HYTALE_PATCH_SKIP: comma-separated indices to skip (e.g., "0,2" skips 1st and 3rd) + * HYTALE_PATCH_LIMIT: max number of patches to apply */ replaceBytesLimited(buffer, oldBytes, newBytes, limit) { let count = 0; @@ -196,18 +198,36 @@ class ClientPatcher { return { buffer: result, count: 0 }; } + // Parse skip list from env + const skipIndices = (process.env.HYTALE_PATCH_SKIP || '') + .split(',') + .filter(s => s.trim()) + .map(s => parseInt(s.trim(), 10)); + if (skipIndices.length > 0) { + console.log(` Skip indices: ${skipIndices.join(', ')}`); + } + const positions = this.findAllOccurrences(result, oldBytes); - for (const pos of positions) { - if (count >= limit) { - console.log(` Skipping offset 0x${pos.toString(16)} (limit reached)`); - continue; - } + let patchedCount = 0; + for (let i = 0; i < positions.length; i++) { + const pos = positions[i]; // Log offset and surrounding bytes for debugging const before = result.slice(Math.max(0, pos - 8), pos); const after = result.slice(pos + oldBytes.length, Math.min(result.length, pos + oldBytes.length + 8)); - console.log(` Patching at offset 0x${pos.toString(16)} (${pos})`); + + if (skipIndices.includes(i)) { + console.log(` [${i}] Skipping offset 0x${pos.toString(16)} (in skip list)`); + continue; + } + + if (patchedCount >= limit) { + console.log(` [${i}] Skipping offset 0x${pos.toString(16)} (limit reached)`); + continue; + } + + console.log(` [${i}] Patching at offset 0x${pos.toString(16)} (${pos})`); console.log(` Before: ${before.toString('hex')}`); console.log(` Old pattern: ${oldBytes.slice(0, 20).toString('hex')}${oldBytes.length > 20 ? '...' : ''}`); console.log(` After: ${after.toString('hex')}`); @@ -216,6 +236,7 @@ class ClientPatcher { result.fill(0x00, pos, pos + oldBytes.length); } newBytes.copy(result, pos); + patchedCount++; count++; }