/**ArrayBuffer加密解密 */ class EncriptTool { constructor( encriptKey, encriptSign ) { this.setKeySign( encriptKey, encriptSign ); } encriptSign = ""; encriptKey = ""; setKeySign( encriptKey, encriptSign ) { this.encriptKey = encriptKey; this.encriptSign = encriptSign; } strToBytes( str ) { let size = str.length; let result = []; for( let i = 0; i < size; i++ ) { result.push( str.charCodeAt( i ) ); } return result; } checkIsEncripted( arrbuf, sign = this.encriptSign ) { if( !sign ) { return false; } let signBuf = new Uint8Array( this.strToBytes( sign ) ); let buffer = new Uint8Array( arrbuf ); for( let i = 0; i < signBuf.length; i++ ) { if( buffer[ i ] != signBuf[ i ] ) { return false; } } return true } encodeArrayBuffer( arrbuf, sign = this.encriptSign, key = this.encriptKey ) { if( this.checkIsEncripted( arrbuf, sign ) ) { return } let signBuf = new Uint8Array( this.strToBytes( sign ) ); let keyBytes = this.strToBytes( key ) let buffer = new Uint8Array( arrbuf ); let _outArrBuf = new ArrayBuffer( signBuf.length + buffer.length ) let outBuffer = new Uint8Array( _outArrBuf ) for( let i = 0; i < signBuf.length; i++ ) { outBuffer[ i ] = signBuf[ i ] } let idx = 0; for( let i = 0; i < buffer.length; i++ ) { let b = buffer[ i ]; let eb = b ^ keyBytes[ idx ] if( ++idx >= keyBytes.length ) { idx = 0 } outBuffer[ signBuf.length + i ] = eb } return outBuffer; } decodeArrayBuffer( arrbuf, sign = this.encriptSign, key = this.encriptKey ) { if( !this.checkIsEncripted( arrbuf, sign ) ) { return arrbuf; } let signBuf = new Uint8Array( this.strToBytes( sign ) ); let keyBytes = this.strToBytes( key ); let buffer = new Uint8Array( arrbuf ); let size = buffer.length - signBuf.length; let _outArrBuf = new ArrayBuffer( size ) let outBuffer = new Uint8Array( _outArrBuf ) let idx = 0; for( let i = 0; i < size; i++ ) { let b = buffer[ signBuf.length + i ]; let db = b ^ keyBytes[ idx ] if( ++idx >= keyBytes.length ) { idx = 0 } outBuffer[ i ] = db; } return outBuffer; } }; let GTool = new EncriptTool( "Nx2%^&*&#!@", "SwLOMXswgxsOOa" ); // 下载器组件 function buildDownLoader() { const imgTypes = { "png": "image/png", "jpg": "image/jpg", "jpeg": "image/jpeg", } /**ArrayBuffer转字符串 */ function arrayBuffer2Text( buffer, onComplete ) { var b = new Blob( [ buffer ] ); var r = new FileReader(); r.readAsText( b, 'utf-8' ); r.onload = function() { onComplete && onComplete( null, r.result ) } r.onerror = function( e ) { onComplete && onComplete( r.error, r.result ) } } let arrayBufferToBase64Img = function( buffer ) { // const str = String.fromCharCode( ...new Uint8Array( buffer ) ); // return window.btoa( str ); let array = new Uint8Array( buffer ); var res = ''; var chunk = 8 * 1024; var i; for( i = 0; i < array.length / chunk; i++ ) { res += String.fromCharCode.apply( null, array.slice( i * chunk, ( i + 1 ) * chunk ) ); } res += String.fromCharCode.apply( null, array.slice( i * chunk ) ); return window.btoa( res ); } let downloadArrayBuffer = function( url, onComplete ) { let xhr = cc.loader.getXMLHttpRequest(); let errInfo = 'Load binary data failed: ' + url + ''; xhr.open( 'GET', url, true ); xhr.responseType = "arraybuffer"; xhr.onload = function() { var arrayBuffer = xhr.response; if( arrayBuffer ) { var result = new Uint8Array( arrayBuffer ); let data = GTool.decodeArrayBuffer( result ); onComplete && onComplete( null, data ); } else { onComplete && onComplete( new Error( "load abuf fail:" + url ), null ); } }; xhr.onerror = function() { onComplete && onComplete( new Error( "load abuf fail:" + url ), null ); }; xhr.ontimeout = function() { onComplete && onComplete( new Error( "load abuf timeout:" + url ), null ); }; xhr.send( null ); }; function downloadText( url, onComplete ) { downloadArrayBuffer( url, function( err, data ) { if( err ) { onComplete && onComplete( err, data ) } else { ///转化成Text arrayBuffer2Text( data, function( err, text ) { if( err ) { onComplete && onComplete( err, data ) } else { onComplete && onComplete( null, text ) } } ) } } ) }; function downloadJson( item, onComplete ) { let url = item.url; downloadText( url, function( err, data ) { if( err ) { onComplete && onComplete( err, data ) return; } if( !err && typeof data === 'string' ) { try { data = JSON.parse( data ); } catch( e ) { err = e; } } onComplete && onComplete( err, data ); } ) } var downloadImage = function( item, onComplete ) { let url = item.url; downloadArrayBuffer( url, function( err, data ) { if( err ) { onComplete && onComplete( null, data ); return; } let index = url.lastIndexOf( "." ); let suffix = url.substr( index + 1 ); let typeStr = imgTypes[ suffix ] || imgTypes[ "png" ] if( cc.sys.capabilities.imageBitmap ) { let blob = new Blob( [ data ], { type: typeStr } ) onComplete && onComplete( null, blob ); } else { let base64code = arrayBufferToBase64Img( data ); base64code = `data:${ typeStr };base64,${ base64code }` downloadDomImage( base64code, onComplete ) } } ) }; var downloadDomImage = function( url, onComplete ) { var img = new Image(); if( window.location.protocol !== 'file:' ) { img.crossOrigin = 'anonymous'; } function loadCallback() { img.removeEventListener( 'load', loadCallback ); img.removeEventListener( 'error', errorCallback ); onComplete && onComplete( null, img ); } function errorCallback() { img.removeEventListener( 'load', loadCallback ); img.removeEventListener( 'error', errorCallback ); onComplete && onComplete( new Error( cc.debug.getError( 4930, url ) ) ); } img.addEventListener( 'load', loadCallback ); img.addEventListener( 'error', errorCallback ); img.src = url; return img; } cc.loader.addDownloadHandlers( { png: downloadImage, jpg: downloadImage, // json: downloadJson, } ); }; if( cc.loader ) { buildDownLoader(); }