2024-07-21 12:52:54 +02:00
/* ZIP module for Rom Patcher JS v20230721 - Marc Robledo 2016-2024 - 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-04-26 12:52:02 +02:00
const FILTER _PATCHES = /\.(ips|ups|bps|aps|rup|ppf|mod|xdelta|vcdiff)$/i ;
2022-01-09 10:49:14 +01:00
//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 ] ) ;
}
}
2024-07-21 12:52:54 +02:00
/* sort patch files by name and folder */
filteredEntries
. sort ( function ( file1 , file2 ) {
return file1 . filename . toLowerCase ( ) . localeCompare ( file2 . filename . toLowerCase ( ) ) ;
} )
. sort ( function ( file1 , file2 ) {
var file1Folder = file1 . filename . indexOf ( '/' ) === - 1 ? 0 : 1 ;
var file2Folder = file2 . filename . indexOf ( '/' ) === - 1 ? 0 : 1 ;
return file1Folder - file2Folder ;
} ) ;
2021-09-20 08:47:26 +02:00
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
2022-03-24 22:38:53 +01:00
if ( customPatch ) {
2021-09-20 08:47:26 +02:00
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 ) {
2022-03-24 22:38:53 +01:00
UI . hideDialog ( 'zip' ) ;
2021-09-20 08:47:26 +02:00
_unzipEntry ( this . zipEntry , sourceFile ) ;
}
if ( filteredEntries . length > 1 ) {
2022-03-24 22:38:53 +01:00
document . getElementById ( 'zip-dialog-message' ) . innerHTML = _ ( sourceFile === romFile ? 'rom_file' : 'patch_file' ) ;
var zipList = document . getElementById ( 'zip-dialog-file-list' ) ;
zipList . innerHTML = '' ;
2021-09-20 08:47:26 +02:00
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-03-24 22:38:53 +01:00
UI . showDialog ( 'zip' ) ;
2021-09-20 08:47:26 +02:00
} else if ( filteredEntries . length === 1 ) {
_unzipEntry ( filteredEntries [ 0 ] , sourceFile ) ;
} else {
if ( sourceFile === romFile ) {
romFile = null ;
2022-03-24 22:38:53 +01:00
setMessage ( 'apply' , _ ( 'no_valid_file_found' ) , 'error' ) ;
2021-09-20 08:47:26 +02:00
} else if ( sourceFile === patchFile ) {
patchFile = null ;
setMessage ( 'apply' , _ ( 'error_invalid_patch' ) , 'error' ) ;
}
}
setTabApplyEnabled ( true ) ;
}
} ) ;
} ,
/* failed */
function ( zipReader ) {
setTabApplyEnabled ( true ) ;
setMessage ( 'apply' , _ ( 'error_unzipping' ) , 'error' ) ;
}
) ;
}
}
} ) ( ) ;