From 1b7521feeb5f02de4d3972f5ddf7e0b3a033398d Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Thu, 15 Aug 2024 08:52:27 +0200 Subject: [PATCH 1/6] fix: drag and drop --- _cache_service_worker.js | 2 +- rom-patcher-js/RomPatcher.webapp.js | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/_cache_service_worker.js b/_cache_service_worker.js index 4e492f5..ec49986 100644 --- a/_cache_service_worker.js +++ b/_cache_service_worker.js @@ -6,7 +6,7 @@ */ var PRECACHE_ID = 'rom-patcher-js'; -var PRECACHE_VERSION = 'v30rc2b'; +var PRECACHE_VERSION = 'v30rc2c'; var PRECACHE_URLS = [ '/RomPatcher.js/', '/RomPatcher.js/index.html', '/RomPatcher.js/manifest.json', diff --git a/rom-patcher-js/RomPatcher.webapp.js b/rom-patcher-js/RomPatcher.webapp.js index c19be11..7cbf8e2 100644 --- a/rom-patcher-js/RomPatcher.webapp.js +++ b/rom-patcher-js/RomPatcher.webapp.js @@ -508,6 +508,15 @@ var RomPatcherWeb = (function () { return false; } + const _dragEventContainsFiles = function (evt) { + if (evt.dataTransfer.types) { + for (var i = 0; i < evt.dataTransfer.types.length; i++) { + if (evt.dataTransfer.types[i] === 'Files') + return true; + } + } + return false; + } const _initialize = function (newSettings, embededPatchInfo) { /* embeded patches */ var validEmbededPatch = _checkEmbededPatchParameter(embededPatchInfo); From 4a928085fc4893e8d6af446dd085d5afdc745c08 Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Wed, 21 Aug 2024 08:37:20 +0200 Subject: [PATCH 2/6] hotfix (bps): fixed bps creation checksums --- rom-patcher-js/modules/RomPatcher.format.bps.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rom-patcher-js/modules/RomPatcher.format.bps.js b/rom-patcher-js/modules/RomPatcher.format.bps.js index 9a2803c..ca8a4a3 100644 --- a/rom-patcher-js/modules/RomPatcher.format.bps.js +++ b/rom-patcher-js/modules/RomPatcher.format.bps.js @@ -1,4 +1,4 @@ -/* BPS module for Rom Patcher JS v20240721 - Marc Robledo 2016-2024 - http://www.marcrobledo.com/license */ +/* BPS module for Rom Patcher JS v20240821 - Marc Robledo 2016-2024 - http://www.marcrobledo.com/license */ /* File format specification: https://www.romhacking.net/documents/746/ */ const BPS_MAGIC='BPS1'; @@ -238,9 +238,9 @@ BPS.buildFromRoms=function(original, modified, deltaMode){ patch.actions=createBPSFromFilesLinear(original, modified); } - var patchFile=patch.export(); patch.sourceChecksum=original.hashCRC32(); patch.targetChecksum=modified.hashCRC32(); + var patchFile=patch.export(); patch.patchChecksum=patchFile.hashCRC32(0, patchFile.fileSize - 4); return patch; } From b2f1b8d57e423407652e2b1b57492d87d9568315 Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Wed, 21 Aug 2024 08:53:23 +0200 Subject: [PATCH 3/6] version 3.0RC3 --- _cache_service_worker.js | 2 +- index.html | 2 +- rom-patcher-js/RomPatcher.webapp.js | 184 ++++++++-------- rom-patcher-js/modules/BinFile.js | 4 +- .../modules/RomPatcher.format.aps_n64.js | 1 - test.js | 196 +++++++++--------- 6 files changed, 201 insertions(+), 188 deletions(-) diff --git a/_cache_service_worker.js b/_cache_service_worker.js index ec49986..fc5e7e4 100644 --- a/_cache_service_worker.js +++ b/_cache_service_worker.js @@ -6,7 +6,7 @@ */ var PRECACHE_ID = 'rom-patcher-js'; -var PRECACHE_VERSION = 'v30rc2c'; +var PRECACHE_VERSION = 'v30rc3'; var PRECACHE_URLS = [ '/RomPatcher.js/', '/RomPatcher.js/index.html', '/RomPatcher.js/manifest.json', diff --git a/index.html b/index.html index 536a7f4..e4dbab7 100644 --- a/index.html +++ b/index.html @@ -151,7 +151,7 @@ - Rom Patcher JS v3.0 RC2 by Marc Robledo + Rom Patcher JS v3.0 RC3 by Marc Robledo
See on GitHub Donate diff --git a/rom-patcher-js/RomPatcher.webapp.js b/rom-patcher-js/RomPatcher.webapp.js index 7cbf8e2..9dd2fbd 100644 --- a/rom-patcher-js/RomPatcher.webapp.js +++ b/rom-patcher-js/RomPatcher.webapp.js @@ -736,106 +736,110 @@ var RomPatcherWeb = (function () { if (ZIPManager.isZipFile(binFile)) { ZIPManager.unzipPatches(binFile._u8array.buffer); } else { - const parsedPatch = RomPatcher.parsePatchFile(binFile); - if (parsedPatch) { - patch = parsedPatch; - _setPatchInputSpinner(false); - - const embededPatchInfo = _getEmbededPatchInfo(binFile.fileName); - if (embededPatchInfo) { - /* custom crc32s validation */ - if (embededPatchInfo.inputCrc32) { - patch.validateSource = function (romFile, headerSize) { - for (var i = 0; i < embededPatchInfo.inputCrc32.length; i++) { - if (embededPatchInfo.inputCrc32[i] === romFile.hashCRC32(headerSize)) - return true; + try{ + const parsedPatch = RomPatcher.parsePatchFile(binFile); + if (parsedPatch) { + patch = parsedPatch; + _setPatchInputSpinner(false); + + const embededPatchInfo = _getEmbededPatchInfo(binFile.fileName); + if (embededPatchInfo) { + /* custom crc32s validation */ + if (embededPatchInfo.inputCrc32) { + patch.validateSource = function (romFile, headerSize) { + for (var i = 0; i < embededPatchInfo.inputCrc32.length; i++) { + if (embededPatchInfo.inputCrc32[i] === romFile.hashCRC32(headerSize)) + return true; + } + return false; } - return false; + patch.getValidationInfo = function () { + return { + 'type': 'CRC32', + 'value': embededPatchInfo.inputCrc32 + } + }; } - patch.getValidationInfo = function () { - return { - 'type': 'CRC32', - 'value': embededPatchInfo.inputCrc32 + + /* custom description */ + if (embededPatchInfo.description) { + patch.getDescription = function () { + return embededPatchInfo.description; } - }; - } - - /* custom description */ - if (embededPatchInfo.description) { - patch.getDescription = function () { - return embededPatchInfo.description; } } - } - - /* toggle ROM requirements */ - if (htmlElements.get('row-patch-requirements') && htmlElements.get('patch-requirements-value')) { - if (typeof patch.getValidationInfo === 'function' && patch.getValidationInfo()) { - var validationInfo = patch.getValidationInfo(); - if (Array.isArray(validationInfo) || !validationInfo.type) { - validationInfo = { - type: 'ROM', - value: validationInfo - } - } - htmlElements.setText('patch-requirements-value', ''); - - htmlElements.setText('patch-requirements-type', validationInfo.type === 'ROM' ? _('Required ROM:') : _('Required %s:').replace('%s', validationInfo.type)); - - if (!Array.isArray(validationInfo.value)) - validationInfo.value = [validationInfo.value]; - - validationInfo.value.forEach(function (value) { - var line = document.createElement('div'); - if (typeof value !== 'string') { - if (validationInfo.type === 'CRC32') { - value = value.toString(16); - while (value.length < 8) - value = '0' + value; - } else { - value = value.toString(); + + /* toggle ROM requirements */ + if (htmlElements.get('row-patch-requirements') && htmlElements.get('patch-requirements-value')) { + if (typeof patch.getValidationInfo === 'function' && patch.getValidationInfo()) { + var validationInfo = patch.getValidationInfo(); + if (Array.isArray(validationInfo) || !validationInfo.type) { + validationInfo = { + type: 'ROM', + value: validationInfo } } - /* - var a=document.createElement('a'); - a.href='https://www.google.com/search?q=%22'+value+'%22'; - a.target='_blank'; - a.className='clickable'; - a.innerHTML=value; - line.appendChild(a); - */ - line.innerHTML = value; - htmlElements.get('patch-requirements-value').appendChild(line); - }); - htmlElements.addClass('row-patch-requirements', 'show'); - } else { - htmlElements.setText('patch-requirements-value', ''); - htmlElements.removeClass('row-patch-requirements', 'show'); + htmlElements.setText('patch-requirements-value', ''); + + htmlElements.setText('patch-requirements-type', validationInfo.type === 'ROM' ? _('Required ROM:') : _('Required %s:').replace('%s', validationInfo.type)); + + if (!Array.isArray(validationInfo.value)) + validationInfo.value = [validationInfo.value]; + + validationInfo.value.forEach(function (value) { + var line = document.createElement('div'); + if (typeof value !== 'string') { + if (validationInfo.type === 'CRC32') { + value = value.toString(16); + while (value.length < 8) + value = '0' + value; + } else { + value = value.toString(); + } + } + /* + var a=document.createElement('a'); + a.href='https://www.google.com/search?q=%22'+value+'%22'; + a.target='_blank'; + a.className='clickable'; + a.innerHTML=value; + line.appendChild(a); + */ + line.innerHTML = value; + htmlElements.get('patch-requirements-value').appendChild(line); + }); + htmlElements.addClass('row-patch-requirements', 'show'); + } else { + htmlElements.setText('patch-requirements-value', ''); + htmlElements.removeClass('row-patch-requirements', 'show'); + } + } + + /* toggle patch description */ + if (typeof patch.getDescription === 'function' && patch.getDescription()) { + htmlElements.setText('patch-description', patch.getDescription()/* .replace(/\n/g, '
') */); + //htmlElements.setTitle('patch-description', patch.getDescription()); + htmlElements.addClass('row-patch-description', 'show'); + } else { + htmlElements.setText('patch-description', ''); + //htmlElements.setTitle('patch-description', ''); + htmlElements.removeClass('row-patch-description', 'show'); + } + + RomPatcherWeb.validateCurrentRom(_getChecksumStartOffset()); + + if (typeof settings.onloadpatch === 'function') { + settings.onloadpatch(binFile, embededPatchInfo, parsedPatch); + } + + if (transferFakeFile) { + htmlElements.setFakeFile('patch', binFile.fileName); } - } - - /* toggle patch description */ - if (typeof patch.getDescription === 'function' && patch.getDescription()) { - htmlElements.setText('patch-description', patch.getDescription()/* .replace(/\n/g, '
') */); - //htmlElements.setTitle('patch-description', patch.getDescription()); - htmlElements.addClass('row-patch-description', 'show'); } else { - htmlElements.setText('patch-description', ''); - //htmlElements.setTitle('patch-description', ''); - htmlElements.removeClass('row-patch-description', 'show'); + _setToastError(_('Invalid patch file')); } - - RomPatcherWeb.validateCurrentRom(_getChecksumStartOffset()); - - if (typeof settings.onloadpatch === 'function') { - settings.onloadpatch(binFile, embededPatchInfo, parsedPatch); - } - - if (transferFakeFile) { - htmlElements.setFakeFile('patch', binFile.fileName); - } - } else { - _setToastError(_('Invalid patch file')); + }catch(ex){ + _setToastError(ex.message); } } } diff --git a/rom-patcher-js/modules/BinFile.js b/rom-patcher-js/modules/BinFile.js index 53e3dfc..643cb93 100644 --- a/rom-patcher-js/modules/BinFile.js +++ b/rom-patcher-js/modules/BinFile.js @@ -1,5 +1,5 @@ /* -* BinFile.js (last update: 2024-02-27) +* BinFile.js (last update: 2024-08-21) * by Marc Robledo, https://www.marcrobledo.com * * a JS class for reading/writing sequentially binary data from/to a file @@ -188,7 +188,7 @@ BinFile.prototype.slice = function (offset, len, doNotClone) { else if (len === 0) throw new Error('zero length provided for slicing'); else - offset = Math.floor(offset); + len = Math.floor(len); if (offset === 0 && len === this.fileSize && doNotClone) return this; diff --git a/rom-patcher-js/modules/RomPatcher.format.aps_n64.js b/rom-patcher-js/modules/RomPatcher.format.aps_n64.js index 156bc84..34e371e 100644 --- a/rom-patcher-js/modules/RomPatcher.format.aps_n64.js +++ b/rom-patcher-js/modules/RomPatcher.format.aps_n64.js @@ -204,7 +204,6 @@ APS.buildFromRoms=function(original, modified){ }else{ patch.addRecord(offset, differentBytes); } - //NO se puede comentar??? why???? } } diff --git a/test.js b/test.js index 695e0cb..f6442ea 100644 --- a/test.js +++ b/test.js @@ -29,8 +29,8 @@ - ROM: New Super Mario Bros. (USA, Australia).nds [CRC32=0197576a] */ -const chalk=require('chalk'); -const { existsSync }=require('fs'); +const chalk = require('chalk'); +const { existsSync } = require('fs'); const BinFile = require('./rom-patcher-js/modules/BinFile'); const HashCalculator = require('./rom-patcher-js/modules/HashCalculator'); @@ -38,68 +38,68 @@ const RomPatcher = require('./rom-patcher-js/RomPatcher'); -const TEST_PATH='_test_files/'; -const TEST_PATCHES=[ +const TEST_PATH = '_test_files/'; +const TEST_PATCHES = [ { - title:'IPS - Super Mario Land 2 DX', - romFile:'Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb', - romCrc32:0xd5ec24e4, - patchFile:'SML2DXv181.ips', - patchCrc32:0x0b742316, - patchDownload:'https://www.romhacking.net/hacks/3784/', - outputCrc32:0xf0799017 - },{ - title:'BPS - Samurai Kid translation', - romFile:'Samurai Kid (Japan).gbc', - romCrc32:0x44a9ddfb, - patchFile:'samurai_kid_en_v1.bps', - patchCrc32:0x2144df1c, - patchDownload:'https://www.romhacking.net/translations/6297/', - outputCrc32:0xed238edb - },{ - title:'UPS - Mother 3 translation', - romFile:'Mother 3 (Japan).gba', - romCrc32:0x42ac9cb9, - patchFile:'mother3.ups', - patchCrc32:0x2144df1c, - patchDownload:'https://mother3.fobby.net/', - outputCrc32:0x8a3bc5a8 - },{ - title:'APS - Zelda OoT spanish translation', - romFile:'Legend of Zelda, The - Ocarina of Time (USA).z64', - romCrc32:0xcd16c529, - patchFile:'ZELDA64.APS', - patchCrc32:0x7b70119d, - patchDownload:'http://dorando.emuverse.com/projects/eduardo_a2j/zelda-ocarina-of-time.html', - outputCrc32:0x7866f1ca - },{ - title:'Tekkaman Blade translation', - romFile:'Uchuu no Kishi - Tekkaman Blade (Japan).sfc', - romCrc32:0x7e107c35, - patchFile:'Tekkaman Blade v1.0.rup', - patchCrc32:0x621ab323, - patchDownload:'https://www.romhacking.net/hacks/4633/', - outputCrc32:0xe83e9b0a - },{ - title:'NSMB Hack Domain Infusion', - romFile:'New Super Mario Bros. (USA, Australia).nds', - romCrc32:0x0197576a, - patchFile:'nsmb_infusion10a.xdelta', - patchCrc32:0xa211f97c, - patchDownload:'https://www.romhacking.net/hacks/2871/', - outputCrc32:0x9cecd976 + title: 'IPS - Super Mario Land 2 DX', + romFile: 'Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb', + romCrc32: 0xd5ec24e4, + patchFile: 'SML2DXv181.ips', + patchCrc32: 0x0b742316, + patchDownload: 'https://www.romhacking.net/hacks/3784/', + outputCrc32: 0xf0799017 + }, { + title: 'BPS - Samurai Kid translation', + romFile: 'Samurai Kid (Japan).gbc', + romCrc32: 0x44a9ddfb, + patchFile: 'samurai_kid_en_v1.bps', + patchCrc32: 0x2144df1c, + patchDownload: 'https://www.romhacking.net/translations/6297/', + outputCrc32: 0xed238edb + }, { + title: 'UPS - Mother 3 translation', + romFile: 'Mother 3 (Japan).gba', + romCrc32: 0x42ac9cb9, + patchFile: 'mother3.ups', + patchCrc32: 0x2144df1c, + patchDownload: 'https://mother3.fobby.net/', + outputCrc32: 0x8a3bc5a8 + }, { + title: 'APS - Zelda OoT spanish translation', + romFile: 'Legend of Zelda, The - Ocarina of Time (USA).z64', + romCrc32: 0xcd16c529, + patchFile: 'ZELDA64.APS', + patchCrc32: 0x7b70119d, + patchDownload: 'http://dorando.emuverse.com/projects/eduardo_a2j/zelda-ocarina-of-time.html', + outputCrc32: 0x7866f1ca + }, { + title: 'Tekkaman Blade translation', + romFile: 'Uchuu no Kishi - Tekkaman Blade (Japan).sfc', + romCrc32: 0x7e107c35, + patchFile: 'Tekkaman Blade v1.0.rup', + patchCrc32: 0x621ab323, + patchDownload: 'https://www.romhacking.net/hacks/4633/', + outputCrc32: 0xe83e9b0a + }, { + title: 'NSMB Hack Domain Infusion', + romFile: 'New Super Mario Bros. (USA, Australia).nds', + romCrc32: 0x0197576a, + patchFile: 'nsmb_infusion10a.xdelta', + patchCrc32: 0xa211f97c, + patchDownload: 'https://www.romhacking.net/hacks/2871/', + outputCrc32: 0x9cecd976 } ]; -const _test=function(title, testFunction){ - try{ - const startTime=(new Date()).getTime(); - const result=testFunction.call(); - - const executionTime=((new Date()).getTime() - startTime) / 1000; - console.log(chalk.greenBright('√ '+title + ' ('+executionTime+'s)')); - }catch(err){ - console.log(chalk.redBright('× '+title + ' - failed with error: '+err.message)); +const _test = function (title, testFunction) { + try { + const startTime = (new Date()).getTime(); + const result = testFunction.call(); + + const executionTime = ((new Date()).getTime() - startTime) / 1000; + console.log(chalk.greenBright('√ ' + title + ' (' + executionTime + 's)')); + } catch (err) { + console.log(chalk.redBright('× ' + title + ' - failed with error: ' + err.message)); } }; @@ -111,14 +111,14 @@ const TEST_DATA = (new Uint8Array([ -_test('HashCalculator integrity', function(){ - if(HashCalculator.md5(TEST_DATA) !== '55c76e7e683fd7cd63c673c5df3efa6e') +_test('HashCalculator integrity', function () { + if (HashCalculator.md5(TEST_DATA) !== '55c76e7e683fd7cd63c673c5df3efa6e') throw new Error('invalid MD5'); - if(HashCalculator.crc32(TEST_DATA).toString(16) !== '903a031b') + if (HashCalculator.crc32(TEST_DATA).toString(16) !== '903a031b') throw new Error('invalid CRC32'); - if(HashCalculator.adler32(TEST_DATA).toString(16) !== 'ef984205') + if (HashCalculator.adler32(TEST_DATA).toString(16) !== 'ef984205') throw new Error('invalid ADLER32'); - if(HashCalculator.crc16(TEST_DATA).toString(16) !== '96e4') + if (HashCalculator.crc16(TEST_DATA).toString(16) !== '96e4') throw new Error('invalid SHA1'); }); @@ -126,13 +126,23 @@ _test('HashCalculator integrity', function(){ const MODIFIED_TEST_DATA = (new Uint8Array([ 98, 91, 64, 8, 35, 53, 122, 167, 52, 253, 222, 156, 247, 82, 227, 213, 22, 221, 17, 247, 107, 102, 164, 254, 221, 8, 207, 63, 117, 164, 223, 10, 1, 77, 87, 123, 48, 9, 111, 64, 233, 118, 1, 36, 1, 60, 208, 245, 136, 126, 29, 231, 168, 18, 125, 172, 11, 184, 81, 20, 16, 30, 154, 16, 236, 21, 5, 74, 255, 112, 171, 198, 185, 89, 2, 98, 45, 164, 214, 55, 103, 15, 217, 95, 212, 133, 184, 21, 67, 144, 198, 163, 76, 35, 248, 229, 163, 37, 103, 33, 193, 96, 77, 255, 117, 89, 193, 61, 64, 253, 119, 82, 49, 187, 195, 165, 205, 140, 222, 134, 249, 68, 224, 248, 144, 207, 18, 126 ])).buffer; -['ips','bps','ppf','ups','aps','rup'].forEach(function(patchFormat){ - _test('create and apply '+patchFormat.toUpperCase(), function(){ - const originalFile=new BinFile(TEST_DATA); - const modifiedFile=new BinFile(MODIFIED_TEST_DATA); - const patch=RomPatcher.createPatch(originalFile, modifiedFile, patchFormat); - const patchedFile=RomPatcher.applyPatch(originalFile, patch, {requireValidation:true}); - if(patchedFile.hashCRC32() !== modifiedFile.hashCRC32()) +['ips', 'bps', 'ppf', 'ups', 'aps', 'rup'].forEach(function (patchFormat) { + _test('create and apply ' + patchFormat.toUpperCase(), function () { + const originalFile = new BinFile(TEST_DATA); + const modifiedFile = new BinFile(MODIFIED_TEST_DATA); + const patch = RomPatcher.createPatch(originalFile, modifiedFile, patchFormat); + const patchedFile = RomPatcher.applyPatch(originalFile, patch, { requireValidation: true }); + + if (patchFormat === 'bps') { + const patchFile = patch.export(); + const patchChecksum = patchFile.hashCRC32(0, patchFile.fileSize - 4); + if (patch.patchChecksum !== patchChecksum) + throw new Error('invalid patch checksum'); + else if (patchFile.hashCRC32() !== 0x2144df1c) + throw new Error('invalid BPS crc32'); + } + + if (patchedFile.hashCRC32() !== modifiedFile.hashCRC32()) throw new Error('modified and patched files\' crc32 do not match'); }) }); @@ -140,40 +150,40 @@ const MODIFIED_TEST_DATA = (new Uint8Array([ -TEST_PATCHES.forEach(function(patchInfo){ - const patchPath=TEST_PATH+'patches/'+patchInfo.patchFile; - if(!existsSync(patchPath)){ - console.log(chalk.yellow('! skipping patch '+patchInfo.title)); - console.log(chalk.yellow(' patch file not found: '+patchInfo.patchFile)); - console.log(chalk.yellow(' download patch at '+patchInfo.patchDownload)); +TEST_PATCHES.forEach(function (patchInfo) { + const patchPath = TEST_PATH + 'patches/' + patchInfo.patchFile; + if (!existsSync(patchPath)) { + console.log(chalk.yellow('! skipping patch ' + patchInfo.title)); + console.log(chalk.yellow(' patch file not found: ' + patchInfo.patchFile)); + console.log(chalk.yellow(' download patch at ' + patchInfo.patchDownload)); return false; } - const patchFile=new BinFile(patchPath); - if(patchFile.hashCRC32() !== patchInfo.patchCrc32){ + const patchFile = new BinFile(patchPath); + if (patchFile.hashCRC32() !== patchInfo.patchCrc32) { console.log(patchFile.hashCRC32().toString(16)); - console.log(chalk.yellow('! skipping '+patchInfo.title+' test: invalid patch crc32')); - console.log(chalk.yellow(' download correct patch at '+patchInfo.patchDownload)); + console.log(chalk.yellow('! skipping ' + patchInfo.title + ' test: invalid patch crc32')); + console.log(chalk.yellow(' download correct patch at ' + patchInfo.patchDownload)); return false; } - const romPath=TEST_PATH+'roms/'+patchInfo.romFile; - if(!existsSync(romPath)){ - console.log(chalk.yellow('! skipping patch '+patchInfo.title)); - console.log(chalk.yellow(' ROM file not found: '+patchInfo.romFile)); + const romPath = TEST_PATH + 'roms/' + patchInfo.romFile; + if (!existsSync(romPath)) { + console.log(chalk.yellow('! skipping patch ' + patchInfo.title)); + console.log(chalk.yellow(' ROM file not found: ' + patchInfo.romFile)); return false; } - const romFile=new BinFile(romPath); - if(romFile.hashCRC32() !== patchInfo.romCrc32){ - console.log(chalk.yellow('! skipping '+patchInfo.title+' test: invalid ROM crc32')); + const romFile = new BinFile(romPath); + if (romFile.hashCRC32() !== patchInfo.romCrc32) { + console.log(chalk.yellow('! skipping ' + patchInfo.title + ' test: invalid ROM crc32')); return false; } - _test('patch '+patchInfo.title, function(){ - const patch=RomPatcher.parsePatchFile(patchFile); - const patchedRom=RomPatcher.applyPatch(romFile, patch, {requireValidation:true}); - if(patchedRom.hashCRC32() !== patchInfo.outputCrc32) + _test('patch ' + patchInfo.title, function () { + const patch = RomPatcher.parsePatchFile(patchFile); + const patchedRom = RomPatcher.applyPatch(romFile, patch, { requireValidation: true }); + if (patchedRom.hashCRC32() !== patchInfo.outputCrc32) throw new Error('invalid patched file crc32'); }); }); From 5e248e2565608de6472fcaf281725291f3686698 Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Sun, 25 Aug 2024 19:59:59 +0200 Subject: [PATCH 4/6] refactor (bps): added BPS.calculateFileChecksum --- rom-patcher-js/modules/RomPatcher.format.bps.js | 9 ++++++--- test.js | 12 +++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/rom-patcher-js/modules/RomPatcher.format.bps.js b/rom-patcher-js/modules/RomPatcher.format.bps.js index ca8a4a3..b2e8266 100644 --- a/rom-patcher-js/modules/RomPatcher.format.bps.js +++ b/rom-patcher-js/modules/RomPatcher.format.bps.js @@ -26,6 +26,10 @@ BPS.prototype.toString=function(){ s+='\n#Actions: '+this.actions.length; return s } +BPS.prototype.calculateFileChecksum = function () { + var patchFile = this.export(); + return patchFile.hashCRC32(0, patchFile.fileSize - 4); +} BPS.prototype.validateSource=function(romFile,headerSize){return this.sourceChecksum===romFile.hashCRC32(headerSize)} BPS.prototype.getValidationInfo=function(){ return { @@ -121,7 +125,7 @@ BPS.fromFile=function(file){ patch.targetChecksum=file.readU32(); patch.patchChecksum=file.readU32(); - if(patch.patchChecksum!==file.hashCRC32(0, file.fileSize - 4)){ + if (patch.patchChecksum !== patch.calculateFileChecksum()) { throw new Error('Patch checksum mismatch'); } @@ -240,8 +244,7 @@ BPS.buildFromRoms=function(original, modified, deltaMode){ patch.sourceChecksum=original.hashCRC32(); patch.targetChecksum=modified.hashCRC32(); - var patchFile=patch.export(); - patch.patchChecksum=patchFile.hashCRC32(0, patchFile.fileSize - 4); + patch.patchChecksum = patch.calculateFileChecksum(); return patch; } diff --git a/test.js b/test.js index f6442ea..0d2d8d8 100644 --- a/test.js +++ b/test.js @@ -114,11 +114,11 @@ const TEST_DATA = (new Uint8Array([ _test('HashCalculator integrity', function () { if (HashCalculator.md5(TEST_DATA) !== '55c76e7e683fd7cd63c673c5df3efa6e') throw new Error('invalid MD5'); - if (HashCalculator.crc32(TEST_DATA).toString(16) !== '903a031b') + if (HashCalculator.crc32(TEST_DATA) !== 0x903a031b) throw new Error('invalid CRC32'); - if (HashCalculator.adler32(TEST_DATA).toString(16) !== 'ef984205') + if (HashCalculator.adler32(TEST_DATA) !== 0xef984205) throw new Error('invalid ADLER32'); - if (HashCalculator.crc16(TEST_DATA).toString(16) !== '96e4') + if (HashCalculator.crc16(TEST_DATA) !== 0x96e4) throw new Error('invalid SHA1'); }); @@ -134,11 +134,9 @@ const MODIFIED_TEST_DATA = (new Uint8Array([ const patchedFile = RomPatcher.applyPatch(originalFile, patch, { requireValidation: true }); if (patchFormat === 'bps') { - const patchFile = patch.export(); - const patchChecksum = patchFile.hashCRC32(0, patchFile.fileSize - 4); - if (patch.patchChecksum !== patchChecksum) + if (patch.patchChecksum !== patch.calculateFileChecksum()) throw new Error('invalid patch checksum'); - else if (patchFile.hashCRC32() !== 0x2144df1c) + else if (patch.export().hashCRC32() !== 0x2144df1c) throw new Error('invalid BPS crc32'); } From abb4a3ab8a07f6bd04d2cc5c87b1f40927c1f7f7 Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Sun, 25 Aug 2024 20:00:49 +0200 Subject: [PATCH 5/6] fix: safari is now ignored in setFakeFile --- rom-patcher-js/RomPatcher.webapp.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rom-patcher-js/RomPatcher.webapp.js b/rom-patcher-js/RomPatcher.webapp.js index 9dd2fbd..8284915 100644 --- a/rom-patcher-js/RomPatcher.webapp.js +++ b/rom-patcher-js/RomPatcher.webapp.js @@ -318,7 +318,8 @@ var RomPatcherWeb = (function () { return fallback || 0; }, setFakeFile: function (id, fileName) { - if (document.getElementById('rom-patcher-input-file-' + id)) { + const isBrowserSafari = /Safari/i.test(navigator.userAgent); /* safari does not show fake file name: https://pqina.nl/blog/set-value-to-file-input/#but-safari */ + if (!isBrowserSafari && document.getElementById('rom-patcher-input-file-' + id)) { try { /* add a fake file to the input file, so it shows the chosen file name */ const fakeFile = new File(new Uint8Array(0), fileName); From a4284790e0f61de308691eca5449c5452146ef41 Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Sun, 25 Aug 2024 20:01:04 +0200 Subject: [PATCH 6/6] version bump 3.0 RC4 --- _cache_service_worker.js | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_cache_service_worker.js b/_cache_service_worker.js index fc5e7e4..a7b12cd 100644 --- a/_cache_service_worker.js +++ b/_cache_service_worker.js @@ -6,7 +6,7 @@ */ var PRECACHE_ID = 'rom-patcher-js'; -var PRECACHE_VERSION = 'v30rc3'; +var PRECACHE_VERSION = 'v30rc4'; var PRECACHE_URLS = [ '/RomPatcher.js/', '/RomPatcher.js/index.html', '/RomPatcher.js/manifest.json', diff --git a/index.html b/index.html index e4dbab7..4bc987b 100644 --- a/index.html +++ b/index.html @@ -151,7 +151,7 @@ - Rom Patcher JS v3.0 RC3 by Marc Robledo + Rom Patcher JS v3.0 RC4 by Marc Robledo
See on GitHub Donate