2022-01-09 10:49:14 +01:00
/* ZIP module for Rom Patcher JS v20220109 - Marc Robledo 2016-2022 - http://www.marcrobledo.com/license */
2021-09-20 08:47:26 +02:00
2019-05-31 21:00:39 +02:00
const ZIP _MAGIC = '\x50\x4b\x03\x04' ;
2021-09-20 08:47:26 +02:00
var ZIPManager = ( function ( ) {
2022-01-09 10:49:14 +01:00
const FILTER _PATCHES = /\.(ips|ups|bps|aps|rup|ppf|mod|xdelta)$/i ;
//const FILTER_ROMS=/(?<!\.(txt|diz|rtf|docx?|xlsx?|html?|pdf|jpe?g|gif|png|bmp|webp|zip|rar|7z))$/i; //negative lookbehind is not compatible with Safari https://stackoverflow.com/a/51568859
const FILTER _NON _ROMS = /(\.(txt|diz|rtf|docx?|xlsx?|html?|pdf|jpe?g|gif|png|bmp|webp|zip|rar|7z))$/i ;
2019-05-31 21:00:39 +02:00
2021-09-20 08:47:26 +02:00
var _unzipEntry = function ( zippedEntry , dest , dest2 , parse ) {
zippedEntry . getData ( new zip . BlobWriter ( ) , function ( blob ) {
var fileReader = new FileReader ( ) ;
fileReader . onload = function ( ) {
var unzippedFile = new MarcFile ( this . result ) ;
unzippedFile . fileName = zippedEntry . filename ;
2019-05-31 21:00:39 +02:00
2021-09-20 08:47:26 +02:00
if ( dest . patches ) {
dest . patches [ dest2 ] . fetchedFile = unzippedFile ;
if ( parse )
parseCustomPatch ( dest . patches [ dest2 ] ) ;
} if ( dest === romFile ) {
romFile = unzippedFile ;
_parseROM ( ) ;
} else if ( dest === patchFile ) {
patchFile = unzippedFile ;
_readPatchFile ( ) ;
2019-05-31 21:00:39 +02:00
}
2021-09-20 08:47:26 +02:00
} ;
fileReader . readAsArrayBuffer ( blob ) ;
} ) ;
} ;
return {
parseFile : function ( sourceFile , compressedFileIndex ) {
setMessage ( 'apply' , _ ( 'unzipping' ) , 'loading' ) ;
var arrayBuffer = sourceFile . _u8array . buffer ;
zip . createReader (
new zip . BlobReader ( new Blob ( [ arrayBuffer ] ) ) ,
/* success */
function ( zipReader ) {
zipReader . getEntries ( function ( zipEntries ) {
var filteredEntries = [ ] ;
for ( var i = 0 ; i < zipEntries . length ; i ++ ) {
2022-01-09 10:49:14 +01:00
if (
(
( sourceFile === romFile && ! FILTER _NON _ROMS . test ( zipEntries [ i ] . filename ) && ! FILTER _PATCHES . test ( zipEntries [ i ] . filename ) ) ||
( sourceFile !== romFile && FILTER _PATCHES . test ( zipEntries [ i ] . filename ) )
) && ! zipEntries [ i ] . directory
) {
2021-09-20 08:47:26 +02:00
filteredEntries . push ( zipEntries [ i ] ) ;
}
}
2019-05-31 21:00:39 +02:00
2021-09-20 08:47:26 +02:00
var customPatch = false ;
if ( isCustomPatcherEnabled ( ) ) {
for ( var i = 0 ; i < CUSTOM _PATCHER . length && ! customPatch ; i ++ ) {
if ( CUSTOM _PATCHER [ i ] . fetchedFile === sourceFile )
customPatch = CUSTOM _PATCHER [ i ] ;
}
}
2019-05-31 21:00:39 +02:00
2021-09-20 08:47:26 +02:00
if ( customPatch ) {
if ( customPatch . patches ) {
for ( var i = 0 ; i < customPatch . patches . length ; i ++ ) {
for ( var j = 0 ; j < filteredEntries . length ; j ++ ) {
if ( customPatch . patches [ i ] . file === filteredEntries [ j ] . filename ) {
_unzipEntry ( filteredEntries [ j ] , customPatch , i , i === compressedFileIndex ) ;
break ;
}
}
}
} else {
var nextOption ;
var customPatchIndex = CUSTOM _PATCHER . indexOf ( customPatch ) ;
customPatch . patches = [ ] ;
for ( var i = 0 ; i < filteredEntries . length ; i ++ ) {
customPatch . patches . push ( {
file : filteredEntries [ i ] . filename ,
fetchedFile : false ,
name : customPatch . name + ' - ' + filteredEntries [ i ] . filename ,
crc : customPatch . crc
} ) ;
var option ;
if ( i === 0 ) {
option = customPatch . selectOption ;
nextOption = option . nextSibling ;
} else {
option = document . createElement ( 'option' ) ;
if ( nextOption )
el ( 'input-file-patch' ) . insertBefore ( option , nextOption ) ;
else
el ( 'input-file-patch' ) . appendChild ( option ) ;
}
option . value = customPatchIndex + ',' + i ;
option . innerHTML = customPatch . patches [ i ] . name ;
nextOption = option . nextSibling ;
_unzipEntry ( filteredEntries [ i ] , customPatch , i , i === 0 ) ;
}
}
setTabApplyEnabled ( false ) ;
} else {
var _evtClickDialogEntry = function ( evt ) {
document . body . removeChild ( this . parentElement . parentElement . parentElement ) ;
_unzipEntry ( this . zipEntry , sourceFile ) ;
}
if ( filteredEntries . length > 1 ) {
var zipOverlay = document . createElement ( 'div' ) ;
zipOverlay . className = 'zip-overlay' ;
var zipDialog = document . createElement ( 'div' ) ;
zipDialog . className = 'zip-dialog' ;
var zipList = document . createElement ( 'ul' ) ;
zipList . className = 'zipped-files'
for ( var i = 0 ; i < filteredEntries . length ; i ++ ) {
var li = document . createElement ( 'li' ) ;
li . zipEntry = filteredEntries [ i ] ;
li . innerHTML = filteredEntries [ i ] . filename ;
addEvent ( li , 'click' , _evtClickDialogEntry ) ;
zipList . appendChild ( li ) ;
}
2022-01-09 10:49:14 +01:00
zipDialog . innerHTML = _ ( sourceFile === romFile ? 'rom_file' : 'patch_file' ) ;
2021-09-20 08:47:26 +02:00
zipDialog . appendChild ( zipList ) ;
zipOverlay . appendChild ( zipDialog ) ;
document . body . appendChild ( zipOverlay ) ;
} else if ( filteredEntries . length === 1 ) {
_unzipEntry ( filteredEntries [ 0 ] , sourceFile ) ;
} else {
if ( sourceFile === romFile ) {
romFile = null ;
} else if ( sourceFile === patchFile ) {
patchFile = null ;
setMessage ( 'apply' , _ ( 'error_invalid_patch' ) , 'error' ) ;
}
}
setTabApplyEnabled ( true ) ;
}
} ) ;
} ,
/* failed */
function ( zipReader ) {
setTabApplyEnabled ( true ) ;
setMessage ( 'apply' , _ ( 'error_unzipping' ) , 'error' ) ;
}
) ;
}
}
} ) ( ) ;