package zip 
{
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.filesystem.File;
    import flash.net.URLRequest;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLLoader;
    import flash.utils.ByteArray;
    import deng.fzip.FZip;
    import deng.fzip.FZipFile;
	import Alert;
	import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
	

	public class ZIPResourceLoader 
	{
        public var resourcesURL:String = "http://127.0.0.1:8000/resources.zip";
        public var localFilePath:String = File.applicationStorageDirectory.nativePath + File.separator + "resources.zip";
        public var zipLoader:URLLoader = new URLLoader();
        public var md5URL:String = "http://127.0.0.1:8000/resources.zip.md5";
        public var md5LocalFilePath:String = File.applicationStorageDirectory.nativePath + File.separator + "resources.zip.md5";


		public function ZIPResourceLoader() 
		{
            zipLoader.dataFormat = URLLoaderDataFormat.BINARY;
            zipLoader.addEventListener(Event.COMPLETE, onZipLoaded);
            zipLoader.addEventListener(IOErrorEvent.IO_ERROR, onZipLoadError);
		    zipLoader.addEventListener(Event.OPEN, onZipLoadStart); // показ окна, о начале
            zipLoader.load(new URLRequest(resourcesURL));
		}
		
		public function onZipLoadStart(event:Event):void 
        {
            Alert.showMessage("Load resources.zip started!");
        }
	
        public function onZipLoaded(event:Event):void 
	    {
            var zipBytes:ByteArray = zipLoader.data;
            var fileStream:FileStream = new FileStream();
            fileStream.open(new File(localFilePath), FileMode.WRITE);
            fileStream.writeBytes(zipBytes, 0, zipBytes.length);
            fileStream.close();
			
			loadMD5();
        }

        public function onZipLoadError(event:IOErrorEvent):void 
	    {
            Alert.showMessage("Failed to load resources.zip");
        }
		
		public function loadMD5():void 
		{
			var md5Loader:URLLoader = new URLLoader();
			md5Loader.addEventListener(Event.COMPLETE, onMD5Loaded);
			md5Loader.addEventListener(IOErrorEvent.IO_ERROR, onMD5LoadError);
			md5Loader.load(new URLRequest(md5URL));
		}
		
		public function onMD5Loaded(event:Event):void 
		{
			var md5:String = event.target.data;
			var md5FileStream:FileStream = new FileStream();
			md5FileStream.open(new File(md5LocalFilePath), FileMode.WRITE);
			md5FileStream.writeUTFBytes(md5);
			md5FileStream.close();
			
			checkMD5(md5);
		}
		
		public function onMD5LoadError(event:IOErrorEvent):void 
		{
			Alert.showMessage("Failed to load resources.zip.md5");
		}
		
		public function checkMD5(newMD5:String):void 
		{
			var oldMD5FileStream:FileStream = new FileStream();
			oldMD5FileStream.open(new File(md5LocalFilePath), FileMode.READ);
			var oldMD5:String = oldMD5FileStream.readUTFBytes(oldMD5FileStream.bytesAvailable);
			oldMD5FileStream.close();
			
			if (newMD5 != oldMD5) 
			{
				downloadZip();
			} 
			else 
			{
				Alert.showMessage("MD5 matches. Skipping download and extraction.");
			}
		}
		
		public function downloadZip():void 
		{
			var zipDownloadLoader:URLLoader = new URLLoader();
			zipDownloadLoader.dataFormat = URLLoaderDataFormat.BINARY;
            zipDownloadLoader.addEventListener(Event.COMPLETE, onZipDownloaded);
            zipDownloadLoader.addEventListener(IOErrorEvent.IO_ERROR, onZipDownloadError);
		    zipDownloadLoader.addEventListener(Event.OPEN, onZipDownloadStart); // показ окна, о начале
            zipDownloadLoader.load(new URLRequest(resourcesURL));
		}
		
		public function onZipDownloadStart(event:Event):void 
        {
            Alert.showMessage("Download resources.zip started!");
        }
        
        public function onZipDownloaded(event:Event):void 
	    {
            var zipBytes:ByteArray = (event.target as URLLoader).data;
            var fileStream:FileStream = new FileStream();
            fileStream.open(new File(localFilePath), FileMode.WRITE);
            fileStream.writeBytes(zipBytes, 0, zipBytes.length);
            fileStream.close();
            
            extractZip();
        }
        
        public function onZipDownloadError(event:IOErrorEvent):void 
	    {
            Alert.showMessage("Failed to download resources.zip");
        }

        public function extractZip():void 
        {
            var zipFile:FZip = new FZip();
            zipFile.addEventListener(Event.COMPLETE, onZipExtracted);
            zipFile.load(new URLRequest(localFilePath));
        }
        
        public function onZipExtracted(event:Event):void 
        {
            var zipFile:FZip = event.target as FZip;
            try {
                for (var i:int = 0; i < zipFile.getFileCount(); i++) 
                {
                    var zipEntry:FZipFile = zipFile.getFileAt(i);
                    var targetFilePath:String = File.applicationStorageDirectory.nativePath + File.separator + "cache/resources" + File.separator + zipEntry.filename;
                    var targetFile:File = new File(targetFilePath);
                    if (zipEntry.filename.charAt(zipEntry.filename.length - 1) == "/")
                    {
                        targetFile.createDirectory();
                    }
                    else 
                    {
                        var targetFileStream:FileStream = new FileStream();
                        targetFileStream.open(targetFile, FileMode.WRITE);
                        targetFileStream.writeBytes(zipEntry.content);
                        targetFileStream.close();
                    }
                }
                Alert.showMessage("Extracted successfully!");
            } catch (error:Error) {
                Alert.showMessage("Failed to extract resources.zip: " + error.message + " (" + error.errorID + ")");
            } 
        }
    }
} смотри крч, оно его качает раньше а потом проверяет на устройстве должно быть на оборот, сначала проверяет md5 а потом уже качает его