mirror of
https://github.com/marcrobledo/RomPatcher.js.git
synced 2025-06-27 16:25:54 +00:00
fix RUP overflow data not being processed as it should
fix RUP patch creation with different file sizes
This commit is contained in:
parent
1ee279b014
commit
df456bdfb9
4 changed files with 67 additions and 21 deletions
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var PRECACHE_ID = 'rom-patcher-js';
|
var PRECACHE_ID = 'rom-patcher-js';
|
||||||
var PRECACHE_VERSION = 'v30finalfix2';
|
var PRECACHE_VERSION = 'v31';
|
||||||
var PRECACHE_URLS = [
|
var PRECACHE_URLS = [
|
||||||
'/RomPatcher.js/', '/RomPatcher.js/index.html',
|
'/RomPatcher.js/', '/RomPatcher.js/index.html',
|
||||||
'/RomPatcher.js/manifest.json',
|
'/RomPatcher.js/manifest.json',
|
||||||
|
|
|
@ -151,7 +151,7 @@
|
||||||
<button id="button-settings" class="btn-transparent"><img src="./webapp/icon_settings.svg" loading="lazy" class="icon settings" /> <span data-localize="yes">Settings</span></button>
|
<button id="button-settings" class="btn-transparent"><img src="./webapp/icon_settings.svg" loading="lazy" class="icon settings" /> <span data-localize="yes">Settings</span></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
Rom Patcher JS <small><a href="legacy/" rel="nofollow">v3.0</a></small> by <a href="/">Marc Robledo</a>
|
Rom Patcher JS <small><a href="legacy/" rel="nofollow">v3.1</a></small> by <a href="/">Marc Robledo</a>
|
||||||
<br />
|
<br />
|
||||||
<img src="./webapp/icon_github.svg" loading="lazy" class="icon github" /> <a href="https://github.com/marcrobledo/RomPatcher.js/" target="_blank">See on GitHub</a>
|
<img src="./webapp/icon_github.svg" loading="lazy" class="icon github" /> <a href="https://github.com/marcrobledo/RomPatcher.js/" target="_blank">See on GitHub</a>
|
||||||
<img src="./webapp/icon_heart.svg" loading="lazy" class="icon heart" /> <a href="https://www.paypal.me/marcrobledo/5" target="_blank" rel="nofollow">Donate</a>
|
<img src="./webapp/icon_heart.svg" loading="lazy" class="icon heart" /> <a href="https://www.paypal.me/marcrobledo/5" target="_blank" rel="nofollow">Donate</a>
|
||||||
|
|
|
@ -219,6 +219,8 @@ const RomPatcher = (function () {
|
||||||
|
|
||||||
if (options.outputSuffix) {
|
if (options.outputSuffix) {
|
||||||
patchedRom.fileName = romFile.fileName.replace(/\.([^\.]*?)$/, ' (patched).$1');
|
patchedRom.fileName = romFile.fileName.replace(/\.([^\.]*?)$/, ' (patched).$1');
|
||||||
|
if(patchedRom.unpatched)
|
||||||
|
patchedRom.fileName = patchedRom.fileName.replace(' (patched)', ' (unpatched)');
|
||||||
} else if (patch._originalPatchFile) {
|
} else if (patch._originalPatchFile) {
|
||||||
patchedRom.fileName = patch._originalPatchFile.fileName.replace(/\.\w+$/i, (/\.\w+$/i.test(romFile.fileName) ? romFile.fileName.match(/\.\w+$/i)[0] : ''));
|
patchedRom.fileName = patch._originalPatchFile.fileName.replace(/\.\w+$/i, (/\.\w+$/i.test(romFile.fileName) ? romFile.fileName.match(/\.\w+$/i)[0] : ''));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* RUP module for Rom Patcher JS v20240721 - Marc Robledo 2018-2024 - http://www.marcrobledo.com/license */
|
/* RUP module for Rom Patcher JS v20241102 - Marc Robledo 2018-2024 - http://www.marcrobledo.com/license */
|
||||||
/* File format specification: http://www.romhacking.net/documents/288/ */
|
/* File format specification: http://www.romhacking.net/documents/288/ */
|
||||||
|
|
||||||
const RUP_MAGIC='NINJA2';
|
const RUP_MAGIC='NINJA2';
|
||||||
|
@ -40,7 +40,11 @@ RUP.prototype.toString=function(){
|
||||||
s+='\nTarget file size: '+file.targetFileSize;
|
s+='\nTarget file size: '+file.targetFileSize;
|
||||||
s+='\nSource MD5: '+file.sourceMD5;
|
s+='\nSource MD5: '+file.sourceMD5;
|
||||||
s+='\nTarget MD5: '+file.targetMD5;
|
s+='\nTarget MD5: '+file.targetMD5;
|
||||||
s+='\nOverflow text: '+file.overflowText;
|
if(file.overflowMode==='A'){
|
||||||
|
s+='\nOverflow mode: Append ' + file.overflowData.length + ' bytes';
|
||||||
|
}else if(file.overflowMode==='M'){
|
||||||
|
s+='\nOverflow mode: Minify ' + file.overflowData.length + ' bytes';
|
||||||
|
}
|
||||||
s+='\n#records: '+file.records.length;
|
s+='\n#records: '+file.records.length;
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
|
@ -50,8 +54,11 @@ RUP.prototype.toString=function(){
|
||||||
RUP.prototype.validateSource=function(romFile,headerSize){
|
RUP.prototype.validateSource=function(romFile,headerSize){
|
||||||
var md5string=romFile.hashMD5(headerSize);
|
var md5string=romFile.hashMD5(headerSize);
|
||||||
for(var i=0; i<this.files.length; i++){
|
for(var i=0; i<this.files.length; i++){
|
||||||
if(this.files[i].sourceMD5===md5string){
|
if(this.files[i].sourceMD5===md5string || this.files[i].targetMD5===md5string){
|
||||||
return this.files[i];
|
return {
|
||||||
|
file:this.files[i],
|
||||||
|
undo:this.files[i].targetMD5===md5string
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -77,32 +84,54 @@ RUP.prototype.apply=function(romFile, validate){
|
||||||
if(!validFile)
|
if(!validFile)
|
||||||
throw new Error('Source ROM checksum mismatch');
|
throw new Error('Source ROM checksum mismatch');
|
||||||
}else{
|
}else{
|
||||||
validFile=this.files[0];
|
validFile={
|
||||||
|
file:this.files[0],
|
||||||
|
undo:this.files[0].targetMD5===romFile.hashMD5()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var undo=validFile.undo;
|
||||||
|
var patch=validFile.file;
|
||||||
|
|
||||||
|
tempFile=new BinFile(!undo? patch.targetFileSize : patch.sourceFileSize);
|
||||||
tempFile=new BinFile(validFile.targetFileSize);
|
|
||||||
/* copy original file */
|
/* copy original file */
|
||||||
romFile.copyTo(tempFile, 0);
|
romFile.copyTo(tempFile, 0);
|
||||||
|
|
||||||
|
|
||||||
for(var i=0; i<validFile.records.length; i++){
|
for(var i=0; i<patch.records.length; i++){
|
||||||
var offset=validFile.records[i].offset;
|
var offset=patch.records[i].offset;
|
||||||
romFile.seek(offset);
|
romFile.seek(offset);
|
||||||
tempFile.seek(offset);
|
tempFile.seek(offset);
|
||||||
for(var j=0; j<validFile.records[i].xor.length; j++){
|
for(var j=0; j<patch.records[i].xor.length; j++){
|
||||||
tempFile.writeU8(
|
tempFile.writeU8(
|
||||||
(romFile.isEOF()?0x00:romFile.readU8()) ^ validFile.records[i].xor[j]
|
(romFile.isEOF()?0x00:romFile.readU8()) ^ patch.records[i].xor[j]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add overflow data if needed */
|
||||||
|
if(patch.overflowMode==='A' && !undo){ /* append */
|
||||||
|
tempFile.seek(patch.sourceFileSize);
|
||||||
|
tempFile.writeBytes(patch.overflowData.map((byte) => byte ^ 0xff));
|
||||||
|
}else if(patch.overflowMode==='M' && undo){ /* minify */
|
||||||
|
tempFile.seek(patch.targetFileSize);
|
||||||
|
tempFile.writeBytes(patch.overflowData.map((byte) => byte ^ 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
if(validate && tempFile.hashMD5()!==validFile.targetMD5){
|
|
||||||
|
if(
|
||||||
|
validate &&
|
||||||
|
(
|
||||||
|
(!undo && tempFile.hashMD5()!==patch.targetMD5) ||
|
||||||
|
(undo && tempFile.hashMD5()!==patch.sourceMD5)
|
||||||
|
)
|
||||||
|
){
|
||||||
throw new Error('Target ROM checksum mismatch');
|
throw new Error('Target ROM checksum mismatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(undo)
|
||||||
|
tempFile.unpatched=true;
|
||||||
|
|
||||||
return tempFile
|
return tempFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +190,10 @@ RUP.fromFile=function(file){
|
||||||
|
|
||||||
|
|
||||||
if(nextFile.sourceFileSize!==nextFile.targetFileSize){
|
if(nextFile.sourceFileSize!==nextFile.targetFileSize){
|
||||||
file.skip(1); //skip 'M' (source>target) or 'A' (source<target)
|
nextFile.overflowMode=file.readString(1); // 'M' (source>target) or 'A' (source<target)
|
||||||
nextFile.overflowText=file.readString(file.readVLV());
|
if(nextFile.overflowMode!=='M' && nextFile.overflowMode!=='A')
|
||||||
|
throw new Error('RUP: invalid overflow mode');
|
||||||
|
nextFile.overflowData=file.readBytes(file.readVLV());
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if(command===RUP_COMMAND_XOR_RECORD){
|
}else if(command===RUP_COMMAND_XOR_RECORD){
|
||||||
|
@ -229,8 +260,8 @@ RUP.prototype.export=function(fileName){
|
||||||
|
|
||||||
if(file.sourceFileSize!==file.targetFileSize){
|
if(file.sourceFileSize!==file.targetFileSize){
|
||||||
patchFileSize++; // M or A
|
patchFileSize++; // M or A
|
||||||
patchFileSize+=RUP_getVLVLen(file.overflowText);
|
patchFileSize+=RUP_getVLVLen(file.overflowData.length);
|
||||||
patchFileSize+=file.overflowText;
|
patchFileSize+=file.overflowData.length;
|
||||||
}
|
}
|
||||||
for(var j=0; j<file.records.length; j++){
|
for(var j=0; j<file.records.length; j++){
|
||||||
patchFileSize++; //command 0x01
|
patchFileSize++; //command 0x01
|
||||||
|
@ -279,8 +310,8 @@ RUP.prototype.export=function(fileName){
|
||||||
|
|
||||||
if(file.sourceFileSize!==file.targetFileSize){
|
if(file.sourceFileSize!==file.targetFileSize){
|
||||||
patchFile.writeString(file.sourceFileSize>file.targetFileSize?'M':'A');
|
patchFile.writeString(file.sourceFileSize>file.targetFileSize?'M':'A');
|
||||||
patchFile.writeVLV(file.overflowText.length);
|
patchFile.writeVLV(file.overflowData.length);
|
||||||
patchFile.writeString(file.overflowText);
|
patchFile.writeBytes(file.overflowData);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var j=0; j<file.records.length; j++){
|
for(var j=0; j<file.records.length; j++){
|
||||||
|
@ -314,10 +345,23 @@ RUP.buildFromRoms=function(original, modified){
|
||||||
targetFileSize:modified.fileSize,
|
targetFileSize:modified.fileSize,
|
||||||
sourceMD5:original.hashMD5(),
|
sourceMD5:original.hashMD5(),
|
||||||
targetMD5:modified.hashMD5(),
|
targetMD5:modified.hashMD5(),
|
||||||
overflowText:'',
|
overflowMode:null,
|
||||||
|
overflowData:[],
|
||||||
records:[]
|
records:[]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(file.sourceFileSize<file.targetFileSize){
|
||||||
|
modified.seek(file.sourceFileSize);
|
||||||
|
file.overflowMode='A';
|
||||||
|
file.overflowData=modified.readBytes(file.targetFileSize-file.sourceFileSize).map((byte) => byte ^ 0xff);
|
||||||
|
modified=modified.slice(0, file.sourceFileSize);
|
||||||
|
}else if(file.sourceFileSize>file.targetFileSize){
|
||||||
|
original.seek(file.targetFileSize);
|
||||||
|
file.overflowMode='M';
|
||||||
|
file.overflowData=original.readBytes(file.sourceFileSize-file.targetFileSize).map((byte) => byte ^ 0xff);
|
||||||
|
original=original.slice(0, file.targetFileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
original.seek(0);
|
original.seek(0);
|
||||||
modified.seek(0);
|
modified.seek(0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue