diff --git a/SteamKit2/SteamKit2/Types/DepotManifest.cs b/SteamKit2/SteamKit2/Types/DepotManifest.cs index 83ee80f03..f44ab9930 100644 --- a/SteamKit2/SteamKit2/Types/DepotManifest.cs +++ b/SteamKit2/SteamKit2/Types/DepotManifest.cs @@ -219,25 +219,6 @@ public bool DecryptFilenames(byte[] encryptionKey) return true; } - /// - /// Serializes depot manifest and saves the output to a file. - /// - /// Output file name. - /// true if serialization was successful; otherwise, false. - public bool SaveToFile( string filename ) - { - using var fs = File.Open( filename, FileMode.Create ); - using var bw = new BinaryWriter( fs ); - var data = Serialize(); - if ( data != null ) - { - bw.Write( data ); - return true; - } - - return false; - } - /// /// Loads binary manifest from a file and deserializes it. /// @@ -371,12 +352,34 @@ void ParseProtobufManifestMetadata(ContentManifestMetadata metadata) EncryptedCRC = metadata.crc_encrypted; } - byte[]? Serialize() + class ChunkIdComparer : IEqualityComparer + { + public bool Equals( byte[]? x, byte[]? y ) + { + if ( ReferenceEquals( x, y ) ) return true; + if ( x == null || y == null ) return false; + return x.SequenceEqual( y ); + } + + public int GetHashCode( byte[] obj ) + { + ArgumentNullException.ThrowIfNull( obj ); + + // ChunkID is SHA-1, so we can just use the first 4 bytes + return BitConverter.ToInt32( obj, 0 ); + } + } + + /// + /// Serializes the depot manifest into the provided output stream. + /// + /// The stream to which the serialized depot manifest will be written. + public void Serialize( Stream output ) { DebugLog.Assert( Files != null, nameof( DepotManifest ), "Files was null when attempting to serialize manifest." ); var payload = new ContentManifestPayload(); - var uniqueChunks = new List(); + var uniqueChunks = new HashSet( new ChunkIdComparer() ); foreach ( var file in Files ) { @@ -409,10 +412,7 @@ void ParseProtobufManifestMetadata(ContentManifestMetadata metadata) protochunk.cb_compressed = chunk.CompressedLength; protofile.chunks.Add( protochunk ); - if ( !uniqueChunks.Exists( x => x.SequenceEqual( chunk.ChunkID! ) ) ) - { - uniqueChunks.Add( chunk.ChunkID! ); - } + uniqueChunks.Add( chunk.ChunkID! ); } payload.mappings.Add( protofile ); @@ -450,8 +450,7 @@ void ParseProtobufManifestMetadata(ContentManifestMetadata metadata) } } - using var ms = new MemoryStream(); - using var bw = new BinaryWriter( ms ); + using var bw = new BinaryWriter( output, Encoding.Default, true ); // Write Protobuf payload using ( var ms_payload = new MemoryStream() ) @@ -477,8 +476,6 @@ void ParseProtobufManifestMetadata(ContentManifestMetadata metadata) // Write EOF marker bw.Write( DepotManifest.PROTOBUF_ENDOFMANIFEST_MAGIC ); - - return ms.ToArray(); } } }