@@ -55,7 +55,7 @@ public override long Position
5555 private uint FileSizeBeforeWholeFileHash ;
5656
5757 /// <summary>
58- /// Gets the size in bytes of the whole file before <see cref="ArchiveMD5Entries "/>.
58+ /// Gets the size in bytes of the whole file before <see cref="AccessPackFileHashes "/>.
5959 /// </summary>
6060 private uint FileSizeBeforeArchiveMD5Entries ;
6161
@@ -105,60 +105,84 @@ public void VerifyHashes()
105105 }
106106
107107 /// <summary>
108- /// Verify MD5 hashes of individual chunk files provided in the VPK.
108+ /// Verify hashes of individual chunk files provided in the VPK.
109109 /// </summary>
110110 /// <param name="progressReporter">If provided, will report a string with the current verification progress.</param>
111111 public void VerifyChunkHashes ( IProgress < string > ? progressReporter = null )
112112 {
113113 Stream ? stream = null ;
114- var lastArchiveIndex = uint . MaxValue ;
114+ var lastArchiveIndex = ushort . MaxValue ;
115115
116116 // When created by Valve, entries are sorted, and are 1MB chunks
117- var allEntries = ArchiveMD5Entries
117+ var allEntries = AccessPackFileHashes
118118 . OrderBy ( file => file . Offset )
119119 . GroupBy ( file => file . ArchiveIndex )
120120 . OrderBy ( x => x . Key )
121121 . SelectMany ( x => x ) ;
122122
123+ Span < byte > hash = stackalloc byte [ 16 ] ;
124+
123125 try
124126 {
125127 foreach ( var entry in allEntries )
126128 {
127- if ( entry . ArchiveIndex > short . MaxValue )
129+ var hashTypeName = entry . HashType switch
128130 {
129- throw new InvalidDataException ( "Unexpected archive index" ) ;
130- }
131+ EHashType . Blake3 => "Blake3" ,
132+ EHashType . MD5 => "MD5" ,
133+ _ => string . Empty ,
134+ } ;
131135
132- progressReporter ? . Report ( $ "Verifying MD5 hash at offset { entry . Offset } in archive { entry . ArchiveIndex } .") ;
136+ progressReporter ? . Report ( $ "Verifying { hashTypeName } hash at offset { entry . Offset } in archive { entry . ArchiveIndex } .") ;
133137
134- if ( lastArchiveIndex != entry . ArchiveIndex )
138+ if ( stream == null || lastArchiveIndex != entry . ArchiveIndex )
135139 {
136140 if ( lastArchiveIndex != 0x7FFF )
137141 {
138142 stream ? . Close ( ) ;
139143 }
140144
141- stream = GetFileStream ( ( ushort ) entry . ArchiveIndex ) ;
145+ stream = GetFileStream ( entry . ArchiveIndex ) ;
142146 lastArchiveIndex = entry . ArchiveIndex ;
143147 }
144148 else
145149 {
146- Debug . Assert ( stream != null ) ; // what's actually happening here? did we miss assigning stream to Reader.BaseStream?
147-
148150 var offset = entry . ArchiveIndex == 0x7FFF ? HeaderSize + TreeSize : 0 ;
149151 stream . Seek ( offset , SeekOrigin . Begin ) ;
150152 }
151153
152154 using var subStream = new SubStream ( stream , stream . Position + entry . Offset , entry . Length ) ;
153- var hash = MD5 . HashData ( subStream ) ;
155+
156+ switch ( entry . HashType )
157+ {
158+ case EHashType . Blake3 :
159+ using ( var hasher = Blake3 . Hasher . New ( ) )
160+ {
161+ var buffer = new byte [ 8192 ] ; // TODO: Fix this alloc
162+ int bytesRead ;
163+ while ( ( bytesRead = subStream . Read ( buffer , 0 , buffer . Length ) ) > 0 )
164+ {
165+ hasher . UpdateWithJoin ( buffer . AsSpan ( 0 , bytesRead ) ) ;
166+ }
167+ hasher . Finalize ( hash ) ;
168+ }
169+ break ;
170+
171+ case EHashType . MD5 :
172+ MD5 . HashData ( subStream , hash ) ;
173+ break ;
174+
175+ default :
176+ throw new InvalidDataException ( $ "Unrecognized hash type: { entry . HashType } ({ ( ushort ) entry . HashType } )") ;
177+ }
154178
155179 if ( ! hash . SequenceEqual ( entry . Checksum ) )
156180 {
157- throw new InvalidDataException ( $ "Package checksum mismatch in archive { entry . ArchiveIndex } at { entry . Offset } ({ BitConverter . ToString ( hash ) } != expected { BitConverter . ToString ( entry . Checksum ) } )") ;
181+ throw new InvalidDataException ( $ "Package checksum mismatch ( { hashTypeName } ) in archive { entry . ArchiveIndex } at { entry . Offset } ({ Convert . ToHexString ( hash ) } != expected { Convert . ToHexString ( entry . Checksum ) } )") ;
158182 }
159183 }
160184
161- progressReporter ? . Report ( "Successfully verified archive MD5 hashes." ) ;
185+ progressReporter ? . Report ( "Successfully verified archive hashes." ) ;
162186 }
163187 finally
164188 {
0 commit comments