Files
fc/dev/project/build-templates/web-mobile2/downloader.js
T
2026-05-23 22:10:14 +08:00

255 lines
7.6 KiB
JavaScript

/**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();
}