import SKIN_SPRITES from "./skinSprites" ; import regionParser from "./regionParser" ; import { LETTERS , DEFAULT_SKIN } from "./constants" ; import { parseViscolors } from "./utils" ; import * as SkinParserUtils from "./skinParserUtils" ; const shallowMerge = ( objs ) => objs . reduce ( ( prev , img ) => Object . assign ( prev , img ) , { } ) ; const CURSORS = [ "CLOSE" , "EQCLOSE" , "EQNORMAL" , "EQSLID" , "EQTITLE" , "MAINMENU" , "MMENU" , "MIN" , "NORMAL" , "PCLOSE" , "PNORMAL" , "POSBAR" , "PSIZE" , "PTBAR" , "PVSCROLL" , "PWINBUT" , "PWSNORM" , "PWSSIZE" , "SONGNAME" , "TITLEBAR" , "VOLBAL" , "WINBUT" , "WSNORMAL" , "WSPOSBAR" , ] ; async function genVizColors ( zip ) { const viscolor = await SkinParserUtils . getFileFromZip ( zip , "VISCOLOR" , "txt" , "text" ) ; return viscolor ? parseViscolors ( viscolor . contents ) : DEFAULT_SKIN . colors ; } async function genImages ( zip ) { const imageObjs = await Promise . all ( Object . keys ( SKIN_SPRITES ) . map ( ( fileName ) => SkinParserUtils . getSpriteUrisFromFilename ( zip , fileName ) ) ) ; return shallowMerge ( imageObjs ) ; } async function genCursors ( zip ) { const cursorObjs = await Promise . all ( CURSORS . map ( async ( cursorName ) => ( { [ cursorName ] : await SkinParserUtils . getCursorFromFilename ( zip , cursorName ) , } ) ) ) ; return shallowMerge ( cursorObjs ) ; } async function genRegion ( zip ) { const region = await SkinParserUtils . getFileFromZip ( zip , "REGION" , "txt" , "text" ) ; return region ? regionParser ( region . contents ) : { } ; } async function genGenTextSprites ( zip ) { const img = await SkinParserUtils . getImgFromFilename ( zip , "GEN" ) ; if ( img == null ) { return null ; } const canvas = document . createElement ( "canvas" ) ; const context = canvas . getContext ( "2d" ) ; canvas . width = img . width ; canvas . height = img . height ; context . drawImage ( img , 0 , 0 ) ; const getLetters = ( y , prefix ) => { const getColorAt = ( x ) => context . getImageData ( x , y , 1 , 1 ) . data . join ( "," ) ; let x = 1 ; const backgroundColor = getColorAt ( 0 ) ; const height = 7 ; return LETTERS . map ( ( letter ) => { let nextBackground = x ; while ( getColorAt ( nextBackground ) !== backgroundColor && nextBackground < canvas . width ) { nextBackground ++ ; } const width = nextBackground - x ; const name = `${ prefix }_${ letter }` ; const sprite = { x , y , height , width , name } ; x = nextBackground + 1 ; return sprite ; } ) ; } ; const letterWidths = { } ; const sprites = [ ... getLetters ( 88 , "GEN_TEXT_SELECTED" ) , ... getLetters ( 96 , "GEN_TEXT" ) , ] ; sprites . forEach ( ( sprite ) => { letterWidths [ sprite . name ] = sprite . width ; } ) ; return [ letterWidths , SkinParserUtils . getSpriteUrisFromImg ( img , sprites ) ] ; } async function skinParser ( zipFileBuffer , JSZip ) { const zip = await JSZip . loadAsync ( zipFileBuffer ) ; const [ colors , playlistStyle , images , cursors , region , genTextSprites , genExColors , ] = await Promise . all ( [ genVizColors ( zip ) , SkinParserUtils . getPlaylistStyle ( zip ) , genImages ( zip ) , genCursors ( zip ) , genRegion ( zip ) , genGenTextSprites ( zip ) , SkinParserUtils . getGenExColors ( zip ) , ] ) ; const [ genLetterWidths , genTextImages ] = genTextSprites || [ null , { } ] ; return { colors , playlistStyle , images : { ... images , ... genTextImages } , genLetterWidths , cursors , region , genExColors , } ; } export default skinParser ;