/// <summary> /// 序列化可更新模式版本资源列表(版本 0)回调函数。 /// </summary> /// <param name="stream">目标流。</param> /// <param name="versionList">要序列化的可更新模式版本资源列表(版本 0)。</param> /// <returns>是否序列化可更新模式版本资源列表(版本 0)成功。</returns> public static bool UpdatableVersionListSerializeCallback_V0(Stream stream, UpdatableVersionList versionList) { if (!versionList.IsValid) { return(false); } Utility.Random.GetRandomBytes(s_CachedHashBytes); using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.UTF8)) { binaryWriter.Write(s_CachedHashBytes); binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); binaryWriter.Write(versionList.InternalResourceVersion); UpdatableVersionList.Asset[] assets = versionList.GetAssets(); binaryWriter.Write(assets.Length); UpdatableVersionList.Resource[] resources = versionList.GetResources(); binaryWriter.Write(resources.Length); foreach (UpdatableVersionList.Resource resource in resources) { binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); binaryWriter.Write(resource.LoadType); binaryWriter.Write(resource.Length); binaryWriter.Write(resource.HashCode); binaryWriter.Write(resource.ZipLength); binaryWriter.Write(resource.ZipHashCode); int[] assetIndexes = resource.GetAssetIndexes(); binaryWriter.Write(assetIndexes.Length); byte[] hashBytes = new byte[CachedHashBytesLength]; foreach (int assetIndex in assetIndexes) { Utility.Converter.GetBytes(resource.HashCode, hashBytes); UpdatableVersionList.Asset asset = assets[assetIndex]; binaryWriter.WriteEncryptedString(asset.Name, hashBytes); int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); binaryWriter.Write(dependencyAssetIndexes.Length); foreach (int dependencyAssetIndex in dependencyAssetIndexes) { binaryWriter.WriteEncryptedString(assets[dependencyAssetIndex].Name, hashBytes); } } } UpdatableVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); binaryWriter.Write(resourceGroups.Length); foreach (UpdatableVersionList.ResourceGroup resourceGroup in resourceGroups) { binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); int[] resourceIndexes = resourceGroup.GetResourceIndexes(); binaryWriter.Write(resourceIndexes.Length); foreach (ushort resourceIndex in resourceIndexes) { binaryWriter.Write(resourceIndex); } } } Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); return(true); }
public bool BuildResourcePack(string sourceVersion, string targetVersion) { if (!Directory.Exists(OutputPath)) { Directory.CreateDirectory(OutputPath); } string defaultResourcePackName = Path.Combine(OutputPath, Utility.Text.Format("{0}.{1}", DefaultResourcePackName, DefaultExtension)); if (File.Exists(defaultResourcePackName)) { File.Delete(defaultResourcePackName); } UpdatableVersionList sourceUpdatableVersionList = default(UpdatableVersionList); if (sourceVersion != null) { DirectoryInfo sourceDirectoryInfo = new DirectoryInfo(Path.Combine(Path.Combine(SourcePath, sourceVersion), Platform.ToString())); FileInfo[] sourceVersionListFiles = sourceDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly); byte[] sourceVersionListBytes = File.ReadAllBytes(sourceVersionListFiles[0].FullName); sourceVersionListBytes = Utility.Zip.Decompress(sourceVersionListBytes); using (Stream stream = new MemoryStream(sourceVersionListBytes)) { sourceUpdatableVersionList = m_UpdatableVersionListSerializer.Deserialize(stream); } } UpdatableVersionList targetUpdatableVersionList = default(UpdatableVersionList); DirectoryInfo targetDirectoryInfo = new DirectoryInfo(Path.Combine(Path.Combine(SourcePath, targetVersion), Platform.ToString())); FileInfo[] targetVersionListFiles = targetDirectoryInfo.GetFiles("GameFrameworkVersion.*.dat", SearchOption.TopDirectoryOnly); byte[] targetVersionListBytes = File.ReadAllBytes(targetVersionListFiles[0].FullName); targetVersionListBytes = Utility.Zip.Decompress(targetVersionListBytes); using (Stream stream = new MemoryStream(targetVersionListBytes)) { targetUpdatableVersionList = m_UpdatableVersionListSerializer.Deserialize(stream); } List <ResourcePackVersionList.Resource> resources = new List <ResourcePackVersionList.Resource>(); UpdatableVersionList.Resource[] sourceResources = sourceUpdatableVersionList.IsValid ? sourceUpdatableVersionList.GetResources() : EmptyResourceArray; UpdatableVersionList.Resource[] targetResources = targetUpdatableVersionList.GetResources(); long offset = 0L; foreach (UpdatableVersionList.Resource targetResource in targetResources) { bool ready = false; foreach (UpdatableVersionList.Resource sourceResource in sourceResources) { if (sourceResource.Name != targetResource.Name || sourceResource.Variant != targetResource.Variant || sourceResource.Extension != targetResource.Extension) { continue; } if (sourceResource.LoadType == targetResource.LoadType && sourceResource.Length == targetResource.Length && sourceResource.HashCode == targetResource.HashCode) { ready = true; } break; } if (!ready) { resources.Add(new ResourcePackVersionList.Resource(targetResource.Name, targetResource.Variant, targetResource.Extension, targetResource.LoadType, offset, targetResource.Length, targetResource.HashCode, targetResource.ZipLength, targetResource.ZipHashCode)); offset += targetResource.ZipLength; } } ResourcePackVersionList.Resource[] resourceArray = resources.ToArray(); using (FileStream fileStream = new FileStream(defaultResourcePackName, FileMode.Create, FileAccess.Write)) { if (!m_ResourcePackVersionListSerializer.Serialize(fileStream, new ResourcePackVersionList(0, 0L, 0, resourceArray))) { return(false); } } int position = 0; int hashCode = 0; string targetDirectoryPath = targetDirectoryInfo.FullName; using (FileStream fileStream = new FileStream(defaultResourcePackName, FileMode.Open, FileAccess.ReadWrite)) { position = (int)fileStream.Length; fileStream.Position = position; foreach (ResourcePackVersionList.Resource resource in resourceArray) { string resourcePath = Path.Combine(targetDirectoryPath, GetResourceFullName(resource.Name, resource.Variant, resource.HashCode)); if (!File.Exists(resourcePath)) { return(false); } byte[] resourceBytes = File.ReadAllBytes(resourcePath); fileStream.Write(resourceBytes, 0, resourceBytes.Length); } if (fileStream.Position - position != offset) { return(false); } fileStream.Position = position; hashCode = Utility.Verifier.GetCrc32(fileStream); fileStream.Position = 0L; if (!m_ResourcePackVersionListSerializer.Serialize(fileStream, new ResourcePackVersionList(position, offset, hashCode, resourceArray))) { return(false); } } string targetResourcePackName = Path.Combine(OutputPath, Utility.Text.Format("{0}-{1}-{2}.{3:x8}.{4}", DefaultResourcePackName, sourceVersion ?? GetNoneVersion(targetVersion), targetVersion, hashCode, DefaultExtension)); if (File.Exists(targetResourcePackName)) { File.Delete(targetResourcePackName); } File.Move(defaultResourcePackName, targetResourcePackName); return(true); }
/// <summary> /// 序列化可更新模式版本资源列表(版本 1)回调函数。 /// </summary> /// <param name="binaryWriter">目标流。</param> /// <param name="versionList">要序列化的可更新模式版本资源列表(版本 1)。</param> /// <returns>序列化可更新模式版本资源列表(版本 1)是否成功。</returns> public static bool SerializeUpdatableVersionListCallback_V1(BinaryWriter binaryWriter, UpdatableVersionList versionList) { if (!versionList.IsValid) { return(false); } Utility.Random.GetRandomBytes(s_CachedHashBytes); binaryWriter.Write(s_CachedHashBytes); binaryWriter.WriteEncryptedString(versionList.ApplicableGameVersion, s_CachedHashBytes); binaryWriter.Write7BitEncodedInt32(versionList.InternalResourceVersion); UpdatableVersionList.Asset[] assets = versionList.GetAssets(); binaryWriter.Write7BitEncodedInt32(assets.Length); foreach (UpdatableVersionList.Asset asset in assets) { binaryWriter.WriteEncryptedString(asset.Name, s_CachedHashBytes); int[] dependencyAssetIndexes = asset.GetDependencyAssetIndexes(); binaryWriter.Write7BitEncodedInt32(dependencyAssetIndexes.Length); foreach (int dependencyAssetIndex in dependencyAssetIndexes) { binaryWriter.Write7BitEncodedInt32(dependencyAssetIndex); } } UpdatableVersionList.Resource[] resources = versionList.GetResources(); binaryWriter.Write7BitEncodedInt32(resources.Length); foreach (UpdatableVersionList.Resource resource in resources) { binaryWriter.WriteEncryptedString(resource.Name, s_CachedHashBytes); binaryWriter.WriteEncryptedString(resource.Variant, s_CachedHashBytes); binaryWriter.WriteEncryptedString(resource.Extension != DefaultExtension ? resource.Extension : null, s_CachedHashBytes); binaryWriter.Write(resource.LoadType); binaryWriter.Write7BitEncodedInt32(resource.Length); binaryWriter.Write(resource.HashCode); binaryWriter.Write7BitEncodedInt32(resource.ZipLength); binaryWriter.Write(resource.ZipHashCode); int[] assetIndexes = resource.GetAssetIndexes(); binaryWriter.Write7BitEncodedInt32(assetIndexes.Length); foreach (int assetIndex in assetIndexes) { binaryWriter.Write7BitEncodedInt32(assetIndex); } } UpdatableVersionList.ResourceGroup[] resourceGroups = versionList.GetResourceGroups(); binaryWriter.Write7BitEncodedInt32(resourceGroups.Length); foreach (UpdatableVersionList.ResourceGroup resourceGroup in resourceGroups) { binaryWriter.WriteEncryptedString(resourceGroup.Name, s_CachedHashBytes); int[] resourceIndexes = resourceGroup.GetResourceIndexes(); binaryWriter.Write7BitEncodedInt32(resourceIndexes.Length); foreach (int resourceIndex in resourceIndexes) { binaryWriter.Write7BitEncodedInt32(resourceIndex); } } Array.Clear(s_CachedHashBytes, 0, CachedHashBytesLength); return(true); }