private void OnBundlePriorityChanged(DownloadPriority downloadPriority) { if (downloadPriority == DownloadPriority.Immediate) { m_hasCurrentPriorityChanged = true; } }
/// <summary> /// Downloads a specific file from the Steam servers. /// </summary> /// <param name="file">The file to download, given from the manifest.</param> /// <param name="priority">The download priority.</param> /// <param name="cryptKey">The AES encryption key used for any encrypted files.</param> /// <returns>A byte array representing the file.</returns> public byte[] DownloadFile(Steam2Manifest.Node file, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null) { using (var ms = new MemoryStream()) { DownloadFileToStream(file, ms, priority, cryptKey); return(ms.ToArray()); } }
internal DownloadJob(Guid id, string displayName, string remoteUrl, string localFile, DownloadPriority priority) { this.id = id; DisplayName = displayName; RemoteUrl = remoteUrl; LocalFile = localFile; Priority = priority; Status = DownloadStatus.Unknown; }
/// <summary> /// 添加预备下载地址 /// </summary> /// <param name="uri">图像源地址</param> public static void AddUri(string uri, DownloadPriority priority) { if (!waitingUri.Contains(uri)) { waitingUri.Insert((int)(((int)priority / 4d) * waitingUri.Count), uri); } if (loadingUri.Count == 0) { webClient = new WebClient(); webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged); webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted); webClient.OpenReadAsync(new Uri(uri, UriKind.Relative), uri); loadingUri.Add(uri); } }
/// <summary> /// Gets the next download with the specified priority. /// </summary> /// <param name="priority">The priority of the download.</param> /// <returns>Returns the next download.</returns> private IDownloadItem GetNextDownloadWithPriority(DownloadPriority priority) { foreach (var downloadItem in _downloadQueue) { if (downloadItem.Priority == priority && downloadItem.DownloadState != DownloadState.Skipped) { return(downloadItem); } } return(null); }
public void OnBundleRequestedByUser() { if (state != AssetBundleDownloadState.Loadable) { if (m_overrideDownloadPriority != DownloadPriority.Immediate) { m_overrideDownloadPriority = DownloadPriority.Immediate; if (OnPriorityChanged != null) { OnPriorityChanged(m_overrideDownloadPriority); } } } }
public void ResetDownloadPriority() { if (state != AssetBundleDownloadState.Loadable) { if (m_overrideDownloadPriority != DownloadPriority.Medium) { m_overrideDownloadPriority = DownloadPriority.Medium; if (OnPriorityChanged != null) { OnPriorityChanged(m_overrideDownloadPriority); } } } }
/// <summary> /// 为Image图片控件设置图像源 /// </summary> /// <param name="image">目标图片</param> /// <param name="uri">图像源地址</param> /// <param name="isWaiting">是否等待下载完成后再赋值</param> public static void SetImageSource(Image image, string uri, DownloadPriority priority, bool isWaiting) { if (loadedUri.Contains(uri)) { image.Source = GlobalMethod.GetImage(uri, UriType.Default); } else { image.Source = null; AddUri(uri, priority); if (isWaiting) { DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(2000) }; EventHandler handler = null; timer.Tick += handler = (s, e) => { if (loadedUri.Contains(uri)) { timer.Stop(); timer.Tick -= handler; image.Source = GlobalMethod.GetImage(uri, UriType.Default); } }; timer.Start(); } } }
/// <summary> /// 下载资源文件 /// </summary> /// <param name="uri">资源相对地址<</param> /// <param name="priority">优先级</param> /// <param name="userToken">资源参数</param> /// <param name="isWaiting">是否等待</param> /// <param name="waitingTime">如果正在被下载,等待检测时间(单位:毫秒)</param> public void OpenReadAsync(string uri, DownloadPriority priority, object userToken, bool isWaiting, int waitingTime) { if (loadedUri.Contains(uri)) { Download(uri, userToken); } else { if (loadingUri.Contains(uri)) { //假如该资源正被下载中,则需要等待,每隔1秒检测一次是否已下载完成 if (isWaiting) { DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(waitingTime) }; EventHandler handler = null; timer.Tick += handler = (s, e) => { if (loadedUri.Contains(uri)) { timer.Stop(); timer.Tick -= handler; Download(uri, userToken); } }; timer.Start(); } } else { if (!waitingUri.Contains(uri)) { waitingUri.Insert((int)(((int)priority / 4d) * waitingUri.Count), uri); } if (loadingUri.Count < MaximumLimit) { loadingUri.Add(uri); Download(uri, userToken); } else { DispatcherTimer timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(waitingTime) }; EventHandler handler = null; timer.Tick += handler = (s, e) => { if (loadingUri.Count < MaximumLimit) { timer.Stop(); timer.Tick -= handler; loadingUri.Add(uri); Download(uri, userToken); } }; timer.Start(); } } } }
public void OnAssetBundleStateChanged(AssetBundleStateChangedEventArgs eventArgs) { if (state != eventArgs.State && !IsBundleLoaded()) { AssetBundleDownloadState oldState = state; if (state == AssetBundleDownloadState.NotBundled) { Debug.LogError(String.Format("AssetBundle: {0} is not bundled but it's state is changing to {1}", m_assetBundleName, eventArgs.State)); } //isretry is determined from errors in the state Debug.Log("State change: " + this + " > " + eventArgs.State + ", " + eventArgs.Error); if (eventArgs.IsRetry) { downloadRetries++; Debug.Log("OnAssetBundleStateChanged :: " + assetBundleName + " encountered an error. " + downloadRetries + "/3 errors encountered."); } if (downloadRetries >= 3) { Debug.Log("OnAssetBundleStateChanged :: " + assetBundleName + " is assumed to be blocked after 3 retries."); state = AssetBundleDownloadState.Blocked; error = "Attempted download 3 times, failed each time. Stopping"; return; } state = eventArgs.State; error = eventArgs.Error; if (OnStateChanged != null) { OnStateChanged(oldState, state); } //EventManager<Events>.Instance.TriggerEvent(Events.BundleStateChanged, this); if (state == AssetBundleDownloadState.Loadable) { m_overrideDownloadPriority = DownloadPriority.Medium; m_downloadPriority = DownloadPriority.Medium; } } }
/// <summary> /// Add downloaditem to background que /// </summary> /// <param name="downloadItem"> /// The download item. /// </param> public static void AddToBackgroundQue(DownloadItem downloadItem, DownloadPriority downloadPriority = DownloadPriority.Normal) { if (Get.Web.EnableAddToBackgroundQue == false) { return; } string path = WebCache.GetPathFromUrl(downloadItem.Url, downloadItem.Section); if (!File.Exists(path)) { lock (BackgroundDownloadQue) { var check = (from d in BackgroundDownloadQue where d.Url == downloadItem.Url select d).SingleOrDefault(); if (check == null) { downloadItem.Priority = downloadPriority; BackgroundDownloadQue.Add(downloadItem); } } } }
/// <summary> /// Downloads a specific file from the Steam servers. /// </summary> /// <param name="file">The file to download, given from the manifest.</param> /// <param name="priority">The download priority.</param> /// <param name="cryptKey">The AES encryption key used for any encrypted files.</param> /// <returns>A byte array representing the file.</returns> public byte[] DownloadFile(Steam2Manifest.Node file, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null) { if ((file.Attributes & Steam2Manifest.Node.Attribs.EncryptedFile) != 0 && cryptKey == null) { throw new Steam2Exception(string.Format("AES encryption key required for file: {0}", file.FullName)); } const uint MaxParts = 16; uint numFileparts = ( uint )Math.Ceiling(( float )file.SizeOrCount / ( float )file.Parent.BlockSize); uint numChunks = ( uint )Math.Ceiling(( float )numFileparts / ( float )MaxParts); MemoryStream ms = new MemoryStream(); for (uint x = 0; x < numChunks; ++x) { byte[] filePart = DownloadFileParts(file, x * MaxParts, MaxParts, priority, cryptKey); ms.Write(filePart, 0, filePart.Length); } return(ms.ToArray()); }
/// <summary> /// Creates a new transfer job. /// </summary> /// <param name="displayName">The display name.</param> /// <param name="remoteUrl">The remote URL.</param> /// <param name="localFile">The local file.</param> /// <param name="priority">The priority.</param> /// <exception cref="System.InvalidOperationException">An unexpected exception occurred trying to create the job.</exception> public IDownloadJob CreateJob(string displayName, string remoteUrl, string localFile, DownloadPriority priority = DownloadPriority.Normal) { if (!Path.IsPathRooted(localFile)) { localFile = new FileInfo(localFile).FullName; } var targetDir = Path.GetDirectoryName(localFile); if (!Directory.Exists(targetDir)) { Directory.CreateDirectory(targetDir); } if (File.Exists(localFile)) { File.Delete(localFile); } IBackgroundCopyManager bitsManager = null; IBackgroundCopyJob bitsJob = null; var id = Guid.Empty; try { bitsManager = (IBackgroundCopyManager) new BackgroundCopyManager(); bitsManager.CreateJob(displayName, BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, out id, out bitsJob); // *** // SET UP BITS JOB SETTINGS--TIMEOUTS/RETRY ETC // SEE THE FOLLOWING REFERENCES: // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/IBackgroundCopyJob2_setminimumretrydelay.asp?frame=true // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/IBackgroundCopyJob2_setnoprogresstimeout.asp?frame=true // ** http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/bg_job_priority.asp // *** // in constant set to 0; this makes BITS retry as soon as possible after an error bitsJob.SetMinimumRetryDelay(DownloadJob.DefaultMiniumRetryDelay); // in constant set to 5 seconds; BITS will set job to Error status if exceeded bitsJob.SetNoProgressTimeout(DownloadJob.DefaultNoProgressTimeout); bitsJob.SetPriority((BG_JOB_PRIORITY)(int)priority); bitsJob.AddFile(remoteUrl, localFile); bitsJob.SetNotifyFlags((uint)( BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_ERROR | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_MODIFICATION | BG_JOB_NOTIFICATION_TYPE.BG_NOTIFY_JOB_TRANSFERRED)); var job = new DownloadJob(id, displayName, remoteUrl, localFile, priority); // Set the notify interface to get BITS events bitsJob.SetNotifyInterface(job); return(job); } catch (COMException cex) { string error; bitsManager.GetErrorDescription(cex.ErrorCode, 1033, out error); throw new InvalidOperationException(error, cex); } finally { if (bitsJob != null) { Marshal.ReleaseComObject(bitsJob); } if (bitsManager != null) { Marshal.ReleaseComObject(bitsManager); } } }
private void UpdateStateOfBundlesInQueue() { ulong freeDiskSpace = GetFreeDiskSpace(); List <Bundle> bundlesSortedByPriority = m_bundleQueue.Values.ToList(); //put to list for (int i = bundlesSortedByPriority.Count - 1; i >= 0; i--) { //get the download priority, cache it and then remove all that cannot be downloaded DownloadPriority downloadPriority = bundlesSortedByPriority[i].GetDownloadPriority(); //any with the minInt value aren't downloadable if (downloadPriority == DownloadPriority.DoNotDownload) { if (bundlesSortedByPriority[i].state == AssetBundleDownloadState.Queued) { bundlesSortedByPriority[i].OnAssetBundleStateChanged(new AssetBundleStateChangedEventArgs(bundlesSortedByPriority[i].assetBundleName, AssetBundleDownloadState.WaitingManualPermission, null)); } bundlesSortedByPriority.RemoveAt(i); continue; } //these aren't relevant to state checks if (bundlesSortedByPriority[i].state == AssetBundleDownloadState.Loadable || bundlesSortedByPriority[i].state == AssetBundleDownloadState.Initialising || bundlesSortedByPriority[i].state == AssetBundleDownloadState.CRCCheck) { bundlesSortedByPriority.RemoveAt(i); } } //sort by priority then progress bundlesSortedByPriority.Sort(delegate(Bundle x, Bundle y) { int value1 = (int)x.GetDownloadPriority(); int value2 = (int)y.GetDownloadPriority(); int enumCompare = value1.CompareTo(value2); if (enumCompare == 0) { //if bundles are of same priority compare progress in reverse so highest is first enumCompare = y.GetProgressPercent().CompareTo(x.GetProgressPercent()); } if (enumCompare == 0) { if (x is SceneBundle && y is SceneBundle) { enumCompare = (x as SceneBundle).stateName.CompareTo((y as SceneBundle).stateName); } } return(enumCompare); }); for (int i = 0; i < bundlesSortedByPriority.Count; i++) { Bundle absi = bundlesSortedByPriority[i]; // Do we have any queued? Manual is higher priority than auto. switch (absi.state) { case AssetBundleDownloadState.Downloading: //keep checking download timeout. if (m_downloadTimeoutLastBytes == absi.downloadProgressBytes) { if (m_realtimeTimeoutStarted == 0) { m_realtimeTimeoutStarted = Time.realtimeSinceStartup; } else { if (Time.realtimeSinceStartup > m_realtimeTimeoutStarted + DownloadNoProgressTimeoutSeconds) { m_hasDownloadTimedOut = true; m_realtimeTimeoutStarted = 0; } } } else { //update download progress m_downloadTimeoutLastBytes = absi.downloadProgressBytes; } continue; case AssetBundleDownloadState.Blocked: absi.CheckBlockedState(); continue; case AssetBundleDownloadState.WaitingManualPermission: case AssetBundleDownloadState.Queued: //continue to checking code break; case AssetBundleDownloadState.NotBundled: default: //unknown or uncared about state, step over continue; } // Can we? Check disk space. bool hasInsufficientDiskSpace = freeDiskSpace <= (ulong)absi.downloadSizeRemainingBytes; if (hasInsufficientDiskSpace) { Debug.Log("AssetBundleManager::TryKickOffPendingDownload - HasSpaceForAssetBundleDownload - " + absi.assetBundleName + " = false. Blocked. Trying again with another."); absi.OnAssetBundleStateChanged(new AssetBundleStateChangedEventArgs(absi.assetBundleName, AssetBundleDownloadState.Blocked, ErrorDiskSpaceFull)); // Try again with a non-blocked download. // This absi will only unblock when the app restarts. continue; } // Can we? Other download in progress? if (m_assetBundleDownloaderManager.IsDownloading) { if (absi.state != AssetBundleDownloadState.Queued) { absi.OnAssetBundleStateChanged(new AssetBundleStateChangedEventArgs(absi.assetBundleName, AssetBundleDownloadState.Queued)); } continue; } Debug.Log("AssetBundleManager::TryKickOffPendingDownload - DoGameplayRulesAllowAssetBundleDownload - " + absi.assetBundleName + " = yes! Downloading this one and returning."); m_assetBundleDownloaderManager.StartDownloadThread(absi); } }
/// <summary> /// Gets the next download with the specified priority. /// </summary> /// <param name="priority">The priority of the download.</param> /// <returns>Returns the next download.</returns> private IDownloadItem GetNextDownloadWithPriority(DownloadPriority priority) { foreach (var downloadItem in _downloadQueue) { if (downloadItem.Priority == priority && downloadItem.DownloadState != DownloadState.Skipped) { return downloadItem; } } return null; }
byte[] DownloadFileParts( Steam2Manifest.Node file, uint filePart, uint numParts, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null ) { this.SendCommand( 7, // download file this.StorageID, this.MessageID, file.FileID, filePart, numParts, ( byte )priority ); uint storId = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); uint msgId = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); byte hasFile = this.Socket.Reader.ReadByte(); uint numChunks = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); uint fileModeValue = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); FileMode fileMode = ( FileMode )fileModeValue; MemoryStream ms = new MemoryStream(); for ( int x = 0 ; x < numChunks ; ++x ) { uint storId2 = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); uint msgId2 = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); uint chunkLen = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); uint storId3 = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); uint msgId3 = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); uint chunkLen2 = NetHelpers.EndianSwap( this.Socket.Reader.ReadUInt32() ); if ( chunkLen == 0 ) continue; byte[] chunk = null; int len = 0; if ( fileMode == FileMode.Compressed ) { chunk = this.Socket.Reader.ReadBytes( ( int )chunkLen ); len = DecompressFileChunk( ref chunk, ( int )file.Parent.BlockSize ); } else if ( fileMode == FileMode.Encrypted ) { len = DecryptFileChunk( out chunk, ( int )chunkLen, cryptKey ); } else if ( fileMode == FileMode.EncryptedAndCompressed ) { // Account for 2 integers before the encrypted data chunkLen -= 8; // Skip first integer (length of the encrypted data) this.Socket.Reader.ReadInt32(); // Length of decrypted and decompressed data int plainLen = this.Socket.Reader.ReadInt32(); DecryptFileChunk( out chunk, ( int )chunkLen, cryptKey ); len = DecompressFileChunk( ref chunk, plainLen ); } else if ( fileMode == FileMode.None ) { chunk = this.Socket.Reader.ReadBytes( ( int )chunkLen ); len = chunk.Length; } ms.Write( chunk, 0, len ); } byte[] data = ms.ToArray(); this.MessageID++; return data; }
/// <summary> /// Downloads a specific file from the Steam servers. /// </summary> /// <param name="file">The file to download, given from the manifest.</param> /// <param name="priority">The download priority.</param> /// <param name="cryptKey">The AES encryption key used for any encrypted files.</param> /// <returns>A byte array representing the file.</returns> public byte[] DownloadFile( Steam2Manifest.Node file, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null ) { if ( ( file.Attributes & Steam2Manifest.Node.Attribs.EncryptedFile ) != 0 && cryptKey == null ) { throw new Steam2Exception( string.Format( "AES encryption key required for file: {0}", file.FullName ) ); } const uint MaxParts = 16; uint numFileparts = ( uint )Math.Ceiling( ( float )file.SizeOrCount / ( float )file.Parent.BlockSize ); uint numChunks = ( uint )Math.Ceiling( ( float )numFileparts / ( float )MaxParts ); MemoryStream ms = new MemoryStream(); for ( uint x = 0 ; x < numChunks ; ++x ) { byte[] filePart = DownloadFileParts( file, x * MaxParts, MaxParts, priority, cryptKey ); ms.Write( filePart, 0, filePart.Length ); } return ms.ToArray(); }
/// <summary> /// Downloads a specific file from the Steam servers. /// </summary> /// <param name="file">The file to download, given from the manifest.</param> /// <param name="priority">The download priority.</param> /// <param name="cryptKey">The AES encryption key used for any encrypted files.</param> /// <returns>A byte array representing the file.</returns> public byte[] DownloadFile( Steam2Manifest.Node file, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null ) { using (var ms = new MemoryStream()) { DownloadFileToStream( file, ms, priority, cryptKey ); return ms.ToArray(); } }
byte[] DownloadFileParts(Steam2Manifest.Node file, uint filePart, uint numParts, DownloadPriority priority = DownloadPriority.Low, byte[] cryptKey = null) { this.SendCommand( 7, // download file this.StorageID, this.MessageID, file.FileID, filePart, numParts, ( byte )priority ); uint storId = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); uint msgId = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); byte hasFile = this.Socket.Reader.ReadByte(); uint numChunks = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); uint fileModeValue = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); FileMode fileMode = ( FileMode )fileModeValue; MemoryStream ms = new MemoryStream(); for (int x = 0; x < numChunks; ++x) { uint storId2 = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); uint msgId2 = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); uint chunkLen = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); uint storId3 = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); uint msgId3 = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); uint chunkLen2 = NetHelpers.EndianSwap(this.Socket.Reader.ReadUInt32()); if (chunkLen == 0) { continue; } byte[] chunk = null; int len = 0; if (fileMode == FileMode.Compressed) { chunk = this.Socket.Reader.ReadBytes(( int )chunkLen); len = DecompressFileChunk(ref chunk, ( int )file.Parent.BlockSize); } else if (fileMode == FileMode.Encrypted) { len = DecryptFileChunk(out chunk, ( int )chunkLen, cryptKey); } else if (fileMode == FileMode.EncryptedAndCompressed) { // Account for 2 integers before the encrypted data chunkLen -= 8; // Skip first integer (length of the encrypted data) this.Socket.Reader.ReadInt32(); // Length of decrypted and decompressed data int plainLen = this.Socket.Reader.ReadInt32(); DecryptFileChunk(out chunk, ( int )chunkLen, cryptKey); len = DecompressFileChunk(ref chunk, plainLen); } else if (fileMode == FileMode.None) { chunk = this.Socket.Reader.ReadBytes(( int )chunkLen); len = chunk.Length; } ms.Write(chunk, 0, len); } byte[] data = ms.ToArray(); this.MessageID++; return(data); }
public void Initalise() { state = AssetBundleDownloadState.Initialising; m_downloadPriority = DownloadPriority.Medium; m_overrideDownloadPriority = DownloadPriority.Medium; }