/// <summary> /// 资源更新器轮询。 /// </summary> /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param> /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param> public void Update(float elapseSeconds, float realElapseSeconds) { if (m_ApplyingResourcePackStream != null) { while (m_ApplyWaitingInfo.Count > 0) { ApplyInfo applyInfo = m_ApplyWaitingInfo[0]; m_ApplyWaitingInfo.RemoveAt(0); if (ApplyResource(applyInfo)) { return; } } Array.Clear(m_CachedBytes, 0, CachedBytesLength); string resourcePackPath = m_ApplyingResourcePackPath; m_ApplyingResourcePackPath = null; m_ApplyingResourcePackStream.Dispose(); m_ApplyingResourcePackStream = null; m_ResourceComponent.OnResourceApplyComplete(resourcePackPath, !m_FailureFlag, m_UpdateCandidateInfo.Count <= 0); } if (m_UpdateWaitingInfo.Count > 0) { if (m_DownloadComponent.FreeAgentCount > 0) { UpdateInfo updateInfo = m_UpdateWaitingInfo[0]; m_UpdateWaitingInfo.RemoveAt(0); string resourceFullNameWithCrc32 = updateInfo.ResourceName.Variant != null?Utility.Text.Format("{0}.{1}.{2:x8}.{3}", updateInfo.ResourceName.Name, updateInfo.ResourceName.Variant, updateInfo.HashCode, ResourceRation.DefaultExtension) : Utility.Text.Format("{0}.{1:x8}.{2}", updateInfo.ResourceName.Name, updateInfo.HashCode, ResourceRation.DefaultExtension); m_DownloadComponent.AddDownload(updateInfo.ResourcePath, Utility.Path.GetRemotePath(Path.Combine(m_ResourceComponent.UpdatePrefixUri, resourceFullNameWithCrc32)), updateInfo); m_UpdatingCount++; } return; } if (m_UpdatingResourceGroup != null && m_UpdatingCount <= 0) { ResourceGroup updatingResourceGroup = m_UpdatingResourceGroup; m_UpdatingResourceGroup = null; m_ResourceComponent.OnUpdaterResourceUpdateComplete(updatingResourceGroup, !m_FailureFlag, m_UpdateCandidateInfo.Count <= 0); return; } }
private bool ApplyResource(ApplyInfo applyInfo) { long position = m_ApplyingResourcePackStream.Position; try { bool zip = applyInfo.Length != applyInfo.ZipLength || applyInfo.HashCode != applyInfo.ZipHashCode; int bytesRead = 0; int bytesLeft = applyInfo.ZipLength; string directory = Path.GetDirectoryName(applyInfo.ResourcePath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } m_ApplyingResourcePackStream.Position += applyInfo.Offset; using (FileStream fileStream = new FileStream(applyInfo.ResourcePath, FileMode.Create, FileAccess.ReadWrite)) { while ((bytesRead = m_ApplyingResourcePackStream.Read(m_CachedBytes, 0, bytesLeft < CachedBytesLength ? bytesLeft : CachedBytesLength)) > 0) { bytesLeft -= bytesRead; fileStream.Write(m_CachedBytes, 0, bytesRead); } if (zip) { fileStream.Position = 0L; int hashCode = Utility.Verifier.GetCrc32(fileStream); if (hashCode != applyInfo.ZipHashCode) { string errorMessage = Utility.Text.Format("Resource zip hash code error, need '{0}', applied '{1}'.", applyInfo.ZipHashCode.ToString(), hashCode.ToString()); m_ResourceComponent.OnResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, errorMessage); return(false); } if (m_ResourceComponent.DecompressCachedStream == null) { m_ResourceComponent.DecompressCachedStream = new MemoryStream(); } fileStream.Position = 0L; m_ResourceComponent.DecompressCachedStream.Position = 0L; m_ResourceComponent.DecompressCachedStream.SetLength(0L); if (!Utility.Zip.Decompress(fileStream, m_ResourceComponent.DecompressCachedStream)) { string errorMessage = Utility.Text.Format("Unable to decompress resource '{0}'.", applyInfo.ResourcePath); m_ResourceComponent.OnResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, errorMessage); return(false); } fileStream.Position = 0L; fileStream.SetLength(0L); fileStream.Write(m_ResourceComponent.DecompressCachedStream.GetBuffer(), 0, (int)m_ResourceComponent.DecompressCachedStream.Length); } else { int hashCode = 0; fileStream.Position = 0L; if (applyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || applyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || applyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt || applyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) { Utility.Converter.GetBytes(applyInfo.HashCode, m_CachedHashBytes); if (applyInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt || applyInfo.LoadType == LoadType.LoadFromBinaryAndQuickDecrypt) { hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, Utility.Encryption.QuickEncryptLength); } else if (applyInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt || applyInfo.LoadType == LoadType.LoadFromBinaryAndDecrypt) { hashCode = Utility.Verifier.GetCrc32(fileStream, m_CachedHashBytes, applyInfo.Length); } Array.Clear(m_CachedHashBytes, 0, CachedHashBytesLength); } else { hashCode = Utility.Verifier.GetCrc32(fileStream); } if (hashCode != applyInfo.HashCode) { string errorMessage = Utility.Text.Format("Resource hash code error, need '{0}', applied '{1}'.", applyInfo.HashCode.ToString(), hashCode.ToString()); m_ResourceComponent.OnResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, errorMessage); return(false); } } } if (applyInfo.UseFileSystem) { IFileSystem fileSystem = m_ResourceComponent.GetFileSystem(applyInfo.FileSystemName, false); bool retVal = fileSystem.WriteFile(applyInfo.ResourceName.FullName, applyInfo.ResourcePath); if (File.Exists(applyInfo.ResourcePath)) { File.Delete(applyInfo.ResourcePath); } return(retVal); } m_UpdateCandidateInfo.Remove(applyInfo.ResourceName); m_ResourceComponent.ResourceInfoDic[applyInfo.ResourceName.AssetCategory][applyInfo.ResourceName].MarkReady(); m_ResourceComponent.ReadWriteResourceInfoDic[applyInfo.ResourceName.AssetCategory].Add(applyInfo.ResourceName, new ReadWriteResourceInfo(applyInfo.FileSystemName, applyInfo.LoadType, applyInfo.Length, applyInfo.HashCode)); m_ResourceComponent.OnResourceApplySuccess(applyInfo.ResourceName, applyInfo.ResourcePath, m_ApplyingResourcePackPath, applyInfo.Length, applyInfo.ZipLength); string downloadingResource = Utility.Text.Format("{0}.download", applyInfo.ResourcePath); if (File.Exists(downloadingResource)) { File.Delete(downloadingResource); } m_CurrentGenerateReadWriteVersionListLength += applyInfo.ZipLength; if (m_ApplyWaitingInfo.Count <= 0 || m_CurrentGenerateReadWriteVersionListLength >= m_GenerateReadWriteVersionListLength) { m_CurrentGenerateReadWriteVersionListLength = 0; GenerateReadWriteVersionList(); return(true); } return(false); } catch (Exception exception) { m_ResourceComponent.OnResourceApplyFailure(applyInfo.ResourceName, m_ApplyingResourcePackPath, exception.ToString()); return(false); } finally { m_ApplyingResourcePackStream.Position = position; } }