mirror of
https://github.com/marcrobledo/RomPatcher.js.git
synced 2025-06-27 16:25:54 +00:00
added .mod (PMSR) support
This commit is contained in:
parent
30caa1f819
commit
462b2b6b11
8 changed files with 128 additions and 81 deletions
|
@ -8,8 +8,9 @@ A ROM patcher made in HTML5.
|
||||||
* APS
|
* APS
|
||||||
* BPS
|
* BPS
|
||||||
* RUP
|
* RUP
|
||||||
* VCDiff (xdelta)
|
|
||||||
* PPF
|
* PPF
|
||||||
|
* Paper Mario Star Rod (.mod)
|
||||||
|
* VCDiff (.xdelta)
|
||||||
* can patch and create patches
|
* can patch and create patches
|
||||||
* shows ROM CRC32, MD5 and SHA-1 before patching
|
* shows ROM CRC32, MD5 and SHA-1 before patching
|
||||||
* can remove headers before patching
|
* can remove headers before patching
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Rom Patcher JS v20190531 - Marc Robledo 2016-2019 - http://www.marcrobledo.com/license */
|
/* Rom Patcher JS v20200225 - Marc Robledo 2016-2020 - http://www.marcrobledo.com/license */
|
||||||
const TOO_BIG_ROM_SIZE=67108863;
|
const TOO_BIG_ROM_SIZE=67108863;
|
||||||
const HEADERS_INFO=[
|
const HEADERS_INFO=[
|
||||||
[/\.nes$/, 16, 1024], //interNES
|
[/\.nes$/, 16, 1024], //interNES
|
||||||
|
@ -199,7 +199,7 @@ addEvent(window,'load',function(){
|
||||||
translatableElements[i].innerHTML=_(translatableElements[i].dataset.localize);
|
translatableElements[i].innerHTML=_(translatableElements[i].dataset.localize);
|
||||||
}
|
}
|
||||||
|
|
||||||
el('row-file-patch').title=_('compatible_formats')+' IPS, UPS, APS, BPS, RUP, PPF, xdelta';
|
el('row-file-patch').title=_('compatible_formats')+' IPS, UPS, APS, BPS, RUP, PPF, MOD (Paper Mario Star Rod), xdelta';
|
||||||
|
|
||||||
el('input-file-rom').value='';
|
el('input-file-rom').value='';
|
||||||
el('input-file-patch').value='';
|
el('input-file-patch').value='';
|
||||||
|
@ -411,6 +411,8 @@ function _readPatchFile(){
|
||||||
patch=parseRUPFile(patchFile);
|
patch=parseRUPFile(patchFile);
|
||||||
}else if(header.startsWith(PPF_MAGIC)){
|
}else if(header.startsWith(PPF_MAGIC)){
|
||||||
patch=parsePPFFile(patchFile);
|
patch=parsePPFFile(patchFile);
|
||||||
|
}else if(header.startsWith(PMSR_MAGIC)){
|
||||||
|
patch=parseMODFile(patchFile);
|
||||||
}else if(header.startsWith(VCDIFF_MAGIC)){
|
}else if(header.startsWith(VCDIFF_MAGIC)){
|
||||||
patch=parseVCDIFF(patchFile);
|
patch=parseVCDIFF(patchFile);
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -30,7 +30,7 @@ caches.keys().then(function(cacheNames){
|
||||||
});
|
});
|
||||||
|
|
||||||
var PRECACHE_ID='rom-patcher-js';
|
var PRECACHE_ID='rom-patcher-js';
|
||||||
var PRECACHE_VERSION='v7';
|
var PRECACHE_VERSION='v7b';
|
||||||
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',
|
||||||
|
@ -56,6 +56,7 @@ var PRECACHE_URLS=[
|
||||||
'/RomPatcher.js/bps.js',
|
'/RomPatcher.js/bps.js',
|
||||||
'/RomPatcher.js/rup.js',
|
'/RomPatcher.js/rup.js',
|
||||||
'/RomPatcher.js/ppf.js',
|
'/RomPatcher.js/ppf.js',
|
||||||
|
'/RomPatcher.js/pmsr.js',
|
||||||
'/RomPatcher.js/vcdiff.js'
|
'/RomPatcher.js/vcdiff.js'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
31
index.html
31
index.html
|
@ -28,29 +28,32 @@
|
||||||
<script type="text/javascript" src="./bps.js"></script>
|
<script type="text/javascript" src="./bps.js"></script>
|
||||||
<script type="text/javascript" src="./rup.js"></script>
|
<script type="text/javascript" src="./rup.js"></script>
|
||||||
<script type="text/javascript" src="./ppf.js"></script>
|
<script type="text/javascript" src="./ppf.js"></script>
|
||||||
|
<script type="text/javascript" src="./pmsr.js"></script>
|
||||||
<script type="text/javascript" src="./vcdiff.js"></script>
|
<script type="text/javascript" src="./vcdiff.js"></script>
|
||||||
<script type="text/javascript" src="./libs/zip.js"></script>
|
<script type="text/javascript" src="./libs/zip.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript"><!--
|
<script type="text/javascript"><!--
|
||||||
|
/*
|
||||||
// PREDEFINED PATCHES EXAMPLE
|
// PREDEFINED PATCHES EXAMPLE
|
||||||
// uncomment this to enable predefined patches, Rom Patcher JS will fetch patches hosted in your server
|
// uncomment this to enable predefined patches, Rom Patcher JS will fetch patches hosted in your server
|
||||||
// format should be self explanatory
|
// - format should be self explanatory
|
||||||
// you can add validation to patch files that have no validation (like IPS or xdelta) by providing a crc
|
// - you can add provide crc for source files, allowing IPS to have validation!
|
||||||
// this object could be also dynamically generated by your server backend
|
// - this could be also dynamically generated by your server backend, allowing you to build your own patcher for your projects
|
||||||
/*var PREDEFINED_PATCHES=[
|
var PREDEFINED_PATCHES=[
|
||||||
//zip includes various patches+every patch file inside specified separately (best method)
|
|
||||||
{patch:'./_example/SML2DXv181.zip#SML2DXv181.ips',name:'Super Mario Land 2 DX v1.8.1 (USA/Europe)',crc:0xd5ec24e4},
|
|
||||||
{patch:'./_example/SML2DXv181.zip#SML2DXv181_jap.ips',name:'Super Mario Land 2 DX v1.8.1 (Japan)',crc:0xa715daf5},
|
|
||||||
|
|
||||||
//zip includes various patches but no patch file inside specified, user will be able to choose the desired patch file in a popup (not recommended, also only a single crc for all patches could be provided)
|
|
||||||
{patch:'./_example/SML2DXv181.zip',name:'Super Mario Land 2 DX v1.8.1 (All regions)'},
|
|
||||||
|
|
||||||
//zip includes a single patch (recommended)
|
//zip includes a single patch (recommended)
|
||||||
{patch:'./_example/SONICDX.zip',name:'Sonic 3D Blast Director\'s Cut v1.1',crc:0x44a2ca44},
|
{patch:'./_example/SONICDX.zip',name:'Sonic 3D Blast Director\'s Cut v1.1',crc:0x44a2ca44},
|
||||||
|
|
||||||
|
//if providing a zipped file, multiple patch files within it can be specified (recommended)
|
||||||
|
{patch:'./_example/SML2DXv181.zip#SML2DXv181.ips',name:'Super Mario Land 2 DX v1.8.1 (USA/Europe)',crc:0xd5ec24e4},
|
||||||
|
{patch:'./_example/SML2DXv181.zip#SML2DXv181_jap.ips',name:'Super Mario Land 2 DX v1.8.1 (Japan)',crc:0xa715daf5},
|
||||||
|
|
||||||
|
//if a patch file is not specified in a zipped file, user will be able to choose the desired patch file in a popup (not recommended, also only a single crc for all patches could be provided)
|
||||||
|
{patch:'./_example/SML2DXv181.zip',name:'Super Mario Land 2 DX v1.8.1 (All regions)'},
|
||||||
|
|
||||||
//uncompressed patch (not recommended because of bandwidth purposes)
|
//uncompressed patch (not recommended because of bandwidth purposes)
|
||||||
{patch:'./_example/MarvelousATI_EN_v1.07.xdelta',name:'Marvelous (SFC) ENG Translation v1.07',crc:0xcedf3ba7}
|
{patch:'./_example/MarvelousATI_EN_v1.07.xdelta',name:'Marvelous (SFC) ENG Translation v1.07',crc:0xcedf3ba7}
|
||||||
];*/
|
];
|
||||||
|
*/
|
||||||
--></script>
|
--></script>
|
||||||
</head>
|
</head>
|
||||||
<body><div id="column">
|
<body><div id="column">
|
||||||
|
@ -91,7 +94,7 @@
|
||||||
<div class="row" id="row-file-patch">
|
<div class="row" id="row-file-patch">
|
||||||
<div class="leftcol"><label for="input-file-patch" data-localize="patch_file">Patch file:</label></div>
|
<div class="leftcol"><label for="input-file-patch" data-localize="patch_file">Patch file:</label></div>
|
||||||
<div class="rightcol">
|
<div class="rightcol">
|
||||||
<input type="file" id="input-file-patch" accept=".ips,.ups,.bps,.aps,.rup,.ppf,.xdelta,.zip"/>
|
<input type="file" id="input-file-patch" accept=".ips,.ups,.bps,.aps,.rup,.ppf,.mod,.xdelta,.zip"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -146,7 +149,7 @@
|
||||||
|
|
||||||
<!-- FOOTER -->
|
<!-- FOOTER -->
|
||||||
<footer>
|
<footer>
|
||||||
Rom Patcher JS <small>v2.1</small> by <a href="/">Marc Robledo</a>
|
Rom Patcher JS <small>v2.2</small> by <a href="/">Marc Robledo</a>
|
||||||
<br />
|
<br />
|
||||||
<i class="icon github"></i> <a href="https://github.com/marcrobledo/RomPatcher.js/" target="_blank">See on GitHub</a>
|
<i class="icon github"></i> <a href="https://github.com/marcrobledo/RomPatcher.js/" target="_blank">See on GitHub</a>
|
||||||
<i class="icon heart"></i> <a href="https://www.paypal.me/marcrobledo/5" target="_blank" rel="nofollow">Donate</a>
|
<i class="icon heart"></i> <a href="https://www.paypal.me/marcrobledo/5" target="_blank" rel="nofollow">Donate</a>
|
||||||
|
|
87
pmsr.js
Normal file
87
pmsr.js
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/* PMSR (Paper Mario Star Rod) module for Rom Patcher JS v20200225 - Marc Robledo 2020 - http://www.marcrobledo.com/license */
|
||||||
|
/* File format specification: http://origami64.net/attachment.php?aid=790 (dead link) */
|
||||||
|
|
||||||
|
const PMSR_MAGIC='PMSR';
|
||||||
|
const YAY0_MAGIC='Yay0';
|
||||||
|
const PAPER_MARIO_USA10_CRC32=0xa7f5cd7e;
|
||||||
|
const PAPER_MARIO_USA10_FILE_SIZE=41943040;
|
||||||
|
|
||||||
|
|
||||||
|
function PMSR(){
|
||||||
|
this.targetSize=0;
|
||||||
|
this.records=[];
|
||||||
|
}
|
||||||
|
PMSR.prototype.addRecord=function(offset, data){
|
||||||
|
this.records.push({offset:offset, data:data})
|
||||||
|
}
|
||||||
|
PMSR.prototype.toString=function(){
|
||||||
|
var s='Star Rod patch';
|
||||||
|
s+='\nTarget file size: '+this.targetSize;
|
||||||
|
s+='\n#Records: '+this.records.length;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PMSR.prototype.validateSource=function(romFile){
|
||||||
|
return romFile.fileSize===PAPER_MARIO_USA10_FILE_SIZE && crc32(romFile)===PAPER_MARIO_USA10_CRC32;
|
||||||
|
}
|
||||||
|
PMSR.prototype.apply=function(romFile, validate){
|
||||||
|
if(validate && !this.validateSource(romFile)){
|
||||||
|
throw new Error('error_crc_input');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('a');
|
||||||
|
if(this.targetSize===romFile.fileSize){
|
||||||
|
tempFile=romFile.slice(0, romFile.fileSize);
|
||||||
|
}else{
|
||||||
|
tempFile=new MarcFile(this.targetSize);
|
||||||
|
romFile.copyToFile(tempFile,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('b');
|
||||||
|
for(var i=0; i<this.records.length; i++){
|
||||||
|
tempFile.seek(this.records[i].offset);
|
||||||
|
tempFile.writeBytes(this.records[i].data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseMODFile(file){
|
||||||
|
var patch=new PMSR();
|
||||||
|
|
||||||
|
/*file.seek(0);
|
||||||
|
if(file.readString(YAY0_MAGIC.length)===YAY0_MAGIC){
|
||||||
|
file=PMSR.YAY0_decode(file);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
patch.targetSize=PAPER_MARIO_USA10_FILE_SIZE;
|
||||||
|
|
||||||
|
file.seek(4);
|
||||||
|
var nRecords=file.readU32();
|
||||||
|
|
||||||
|
for(var i=0; i<nRecords; i++){
|
||||||
|
var offset=file.readU32();
|
||||||
|
var length=file.readU32();
|
||||||
|
patch.addRecord(offset, file.readBytes(length));
|
||||||
|
|
||||||
|
if((offset+length)>patch.targetSize)
|
||||||
|
patch.targetSize=offset+length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* to-do */
|
||||||
|
//MOD.prototype.export=function(fileName){return null}
|
||||||
|
//function createMODFromFiles(original, modified){return null}
|
||||||
|
|
||||||
|
|
||||||
|
/* https://github.com/pho/WindViewer/wiki/Yaz0-and-Yay0 */
|
||||||
|
PMSR.YAY0_decode=function(file){
|
||||||
|
/* to-do */
|
||||||
|
}
|
47
ppf.js
47
ppf.js
|
@ -1,4 +1,4 @@
|
||||||
/* PPF module for Rom Patcher JS v20200221 - Marc Robledo 2019-2020 - http://www.marcrobledo.com/license */
|
/* PPF module for Rom Patcher JS v20190401 - Marc Robledo 2019 - http://www.marcrobledo.com/license */
|
||||||
/* File format specification: https://www.romhacking.net/utilities/353/ */
|
/* File format specification: https://www.romhacking.net/utilities/353/ */
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@
|
||||||
const PPF_MAGIC='PPF';
|
const PPF_MAGIC='PPF';
|
||||||
const PPF_IMAGETYPE_BIN=0x00;
|
const PPF_IMAGETYPE_BIN=0x00;
|
||||||
const PPF_IMAGETYPE_GI=0x01;
|
const PPF_IMAGETYPE_GI=0x01;
|
||||||
const PPF_BEGIN_FILE_ID_DIZ_MAGIC='@BEG';//@BEGIN_FILE_ID.DIZ
|
|
||||||
|
|
||||||
function PPF(){
|
function PPF(){
|
||||||
this.version=3;
|
this.version=3;
|
||||||
|
@ -29,8 +28,6 @@ PPF.prototype.toString=function(){
|
||||||
s+='\nImage type: '+this.imageType;
|
s+='\nImage type: '+this.imageType;
|
||||||
s+='\nBlock check: '+!!this.blockCheck;
|
s+='\nBlock check: '+!!this.blockCheck;
|
||||||
s+='\nUndo data: '+this.undoData;
|
s+='\nUndo data: '+this.undoData;
|
||||||
if(this.fileIdDiz)
|
|
||||||
s+='\nFILE_ID.DIZ: '+this.fileIdDiz;
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
PPF.prototype.export=function(fileName){
|
PPF.prototype.export=function(fileName){
|
||||||
|
@ -47,9 +44,6 @@ PPF.prototype.export=function(fileName){
|
||||||
if(this.blockCheck){
|
if(this.blockCheck){
|
||||||
patchFileSize+=1024;
|
patchFileSize+=1024;
|
||||||
}
|
}
|
||||||
if(this.fileIdDiz){
|
|
||||||
patchFileSize+=18+this.fileIdDiz.length+16+4;
|
|
||||||
}
|
|
||||||
|
|
||||||
tempFile=new MarcFile(patchFileSize);
|
tempFile=new MarcFile(patchFileSize);
|
||||||
tempFile.fileName=fileName+'.ppf';
|
tempFile.fileName=fileName+'.ppf';
|
||||||
|
@ -66,7 +60,11 @@ PPF.prototype.export=function(fileName){
|
||||||
tempFile.writeU8(0x00); //dummy
|
tempFile.writeU8(0x00); //dummy
|
||||||
|
|
||||||
}else if(this.version===2){
|
}else if(this.version===2){
|
||||||
tempFile.writeU32(this.inputFileSize);
|
//unknown data?
|
||||||
|
tempFile.writeU8(0x00);
|
||||||
|
tempFile.writeU8(0x00);
|
||||||
|
tempFile.writeU8(0x00);
|
||||||
|
tempFile.writeU8(0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.blockCheck){
|
if(this.blockCheck){
|
||||||
|
@ -78,26 +76,17 @@ PPF.prototype.export=function(fileName){
|
||||||
tempFile.littleEndian=true;
|
tempFile.littleEndian=true;
|
||||||
for(var i=0; i<this.records.length; i++){
|
for(var i=0; i<this.records.length; i++){
|
||||||
tempFile.writeU32(this.records[i].offset & 0xffffffff);
|
tempFile.writeU32(this.records[i].offset & 0xffffffff);
|
||||||
|
//tempFile.writeU32(0x00000000); //to-do: limited to 4GB right now
|
||||||
if(this.version===3){
|
var offset2=this.records[i].offset;
|
||||||
var offset2=this.records[i].offset;
|
for(var j=0; j<32; j++)
|
||||||
for(var j=0; j<32; j++)
|
offset2=parseInt((offset2/2)>>>0);
|
||||||
offset2=parseInt((offset2/2)>>>0);
|
tempFile.writeU32(offset2);
|
||||||
tempFile.writeU32(offset2);
|
|
||||||
}
|
|
||||||
tempFile.writeU8(this.records[i].data.length);
|
tempFile.writeU8(this.records[i].data.length);
|
||||||
tempFile.writeBytes(this.records[i].data);
|
tempFile.writeBytes(this.records[i].data);
|
||||||
if(this.undoData)
|
if(this.undoData)
|
||||||
tempFile.writeBytes(this.records[i].undoData);
|
tempFile.writeBytes(this.records[i].undoData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.fileIdDiz){
|
|
||||||
tempFile.writeString('@BEGIN_FILE_ID.DIZ');
|
|
||||||
tempFile.writeString(this.fileIdDiz);
|
|
||||||
tempFile.writeString('@END_FILE_ID.DIZ');
|
|
||||||
tempFile.writeU16(this.fileIdDiz.length);
|
|
||||||
tempFile.writeU16(0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,27 +164,17 @@ function parsePPFFile(patchFile){
|
||||||
patchFile.skip(1);
|
patchFile.skip(1);
|
||||||
}else if(patch.version===2){
|
}else if(patch.version===2){
|
||||||
patch.blockCheck=true;
|
patch.blockCheck=true;
|
||||||
patch.inputFileSize=patchFile.readU32();
|
patchFile.skip(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(patch.blockCheck){
|
if(patch.blockCheck){
|
||||||
patch.blockCheck=patchFile.readBytes(1024);
|
patchFile.blockCheck=patchFile.readBytes(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
patchFile.littleEndian=true;
|
patchFile.littleEndian=true;
|
||||||
while(!patchFile.isEOF()){
|
while(!patchFile.isEOF()){
|
||||||
|
|
||||||
if(patchFile.readString(4)===PPF_BEGIN_FILE_ID_DIZ_MAGIC){
|
|
||||||
patchFile.skip(14);
|
|
||||||
//console.log('found file_id.diz begin');
|
|
||||||
patch.fileIdDiz=patchFile.readString(3072);
|
|
||||||
patch.fileIdDiz=patch.fileIdDiz.substr(0, patch.fileIdDiz.indexOf('@END_FILE_ID.DIZ'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
patchFile.skip(-4);
|
|
||||||
|
|
||||||
var offset;
|
var offset;
|
||||||
if(patch.version===3){
|
if(patch.version===3){
|
||||||
var u64_1=patchFile.readU32();
|
var u64_1=patchFile.readU32();
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
<?php
|
|
||||||
/*
|
|
||||||
this template code should build a valid PREDEFINED_PATCHES object structure for Rom Patcher JS
|
|
||||||
it's intended for sites that host multiple patches (like www.romhacking.net)
|
|
||||||
|
|
||||||
note: this has not been tested!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
if(isset($_GET["patch"])){
|
|
||||||
$patchFile=$_GET["patch"];
|
|
||||||
if(isset($_GET["compressed"])){
|
|
||||||
$patchFile.="#".$_GET["compressed"];
|
|
||||||
}
|
|
||||||
if(isset($_GET["name"])){
|
|
||||||
$patchName=addslashes($_GET["name"]);
|
|
||||||
}else{
|
|
||||||
$patchName=$_GET["patch"];
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "var PREDEFINED_PATCHES=[";
|
|
||||||
echo "{patch:'".$patchFile."',name:'".$patchName."'";
|
|
||||||
if(isset($_GET["crc"]) && preg_match("/^[0-9a-f]{1,8}$/i", $_GET["crc"])){
|
|
||||||
echo ", crc:0x".$_GET["crc"];
|
|
||||||
}
|
|
||||||
echo "}";
|
|
||||||
echo "];";
|
|
||||||
}
|
|
||||||
?>
|
|
|
@ -9,6 +9,7 @@ self.importScripts(
|
||||||
'./bps.js',
|
'./bps.js',
|
||||||
'./rup.js',
|
'./rup.js',
|
||||||
'./ppf.js',
|
'./ppf.js',
|
||||||
|
'./pmsr.js',
|
||||||
'./vcdiff.js'
|
'./vcdiff.js'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -32,6 +33,8 @@ self.onmessage = event => { // listen for messages from the main thread
|
||||||
patch=parseRUPFile(patchFile);
|
patch=parseRUPFile(patchFile);
|
||||||
}else if(header.startsWith(PPF_MAGIC)){
|
}else if(header.startsWith(PPF_MAGIC)){
|
||||||
patch=parsePPFFile(patchFile);
|
patch=parsePPFFile(patchFile);
|
||||||
|
}else if(header.startsWith(PMSR_MAGIC)){
|
||||||
|
patch=parseMODFile(patchFile);
|
||||||
}else if(header.startsWith(VCDIFF_MAGIC)){
|
}else if(header.startsWith(VCDIFF_MAGIC)){
|
||||||
patch=parseVCDIFF(patchFile);
|
patch=parseVCDIFF(patchFile);
|
||||||
}else{
|
}else{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue