@@ -118,9 +118,9 @@ public static bool IsArk(Stream s)
118
118
return version <= 6 && version >= 3 ;
119
119
}
120
120
121
- public static ArkPackage OpenFile ( string filename )
121
+ public static ArkPackage OpenFile ( IFile f )
122
122
{
123
- return new ArkPackage ( filename ) ;
123
+ return new ArkPackage ( f ) ;
124
124
}
125
125
126
126
public static ArkPackage FromStream ( Stream fs )
@@ -133,10 +133,10 @@ public static ArkPackage FromStream(Stream fs)
133
133
/// Note: will check for data files and throw exception if they're not found.
134
134
/// </summary>
135
135
/// <param name="pathToHdr">Full path to .hdr file</param>
136
- public ArkPackage ( string pathToHdr )
136
+ public ArkPackage ( IFile hdrFile )
137
137
{
138
- FileName = pathToHdr ;
139
- using ( var hdr = new FileStream ( pathToHdr , FileMode . Open , FileAccess . Read ) )
138
+ FileName = hdrFile . Name ;
139
+ using ( var hdr = hdrFile . GetStream ( ) )
140
140
{
141
141
Stream actualHdr = hdr ;
142
142
uint version = hdr . ReadUInt32LE ( ) ;
@@ -151,11 +151,11 @@ public ArkPackage(string pathToHdr)
151
151
}
152
152
version = actualHdr . ReadUInt32LE ( ) ;
153
153
}
154
- readHeader ( actualHdr , pathToHdr , version ) ;
154
+ readHeader ( actualHdr , hdrFile , version ) ;
155
155
}
156
156
}
157
157
158
- private void readHeader ( Stream header , string headerPath , uint version )
158
+ private void readHeader ( Stream header , IFile hdrFile , uint version , bool brokenv5 = false )
159
159
{
160
160
if ( version == 6 ) // Version 6 has some sort of hash/key at the beginning?
161
161
{
@@ -174,6 +174,13 @@ private void readHeader(Stream header, string headerPath, uint version)
174
174
{
175
175
// All versions except 4 use 32-bit file sizes.
176
176
arkFileSizes [ i ] = ( version == 4 ? header . ReadInt64LE ( ) : header . ReadInt32LE ( ) ) ;
177
+ if ( version == 4 && arkFileSizes [ i ] > UInt32 . MaxValue )
178
+ {
179
+ // RB TrackPack Classic has a broken v4, really a v5 mixed with v3
180
+ header . Position = 4 ;
181
+ readHeader ( header , hdrFile , 5 , true ) ;
182
+ return ;
183
+ }
177
184
totalArkFileSizes += arkFileSizes [ i ] ;
178
185
}
179
186
@@ -188,9 +195,8 @@ private void readHeader(Stream header, string headerPath, uint version)
188
195
contentFiles = new Stream [ numArks ] ;
189
196
for ( var i = 0 ; i < numArkPaths ; i ++ )
190
197
{
191
- string filePath = Path . Combine ( Path . GetDirectoryName ( headerPath ) ,
192
- header . ReadLengthUTF8 ( ) . Split ( '/' ) . Last ( ) ) ;
193
- contentFiles [ i ] = new FileStream ( filePath , FileMode . Open , FileAccess . Read ) ;
198
+ IFile arkFile = hdrFile . Parent . GetFile ( header . ReadLengthUTF8 ( ) . Split ( '/' ) . Last ( ) ) ;
199
+ contentFiles [ i ] = arkFile . GetStream ( ) ;
194
200
}
195
201
196
202
// Version 6: appears to checksums or something for each content file
@@ -205,9 +211,8 @@ private void readHeader(Stream header, string headerPath, uint version)
205
211
contentFiles = new Stream [ numArks ] ;
206
212
for ( var i = 0 ; i < numArks2 ; i ++ )
207
213
{
208
- string filePath = Path . Combine ( Path . GetDirectoryName ( headerPath ) ,
209
- Path . GetFileNameWithoutExtension ( headerPath ) ) + "_" + i + ".ark" ;
210
- contentFiles [ i ] = new FileStream ( filePath , FileMode . Open , FileAccess . Read ) ;
214
+ IFile arkFile = hdrFile . Parent . GetFile ( hdrFile . Name . Substring ( 0 , hdrFile . Name . Length - 4 ) + "_" + i + ".ark" ) ;
215
+ contentFiles [ i ] = arkFile . GetStream ( ) ;
211
216
}
212
217
}
213
218
@@ -258,7 +263,7 @@ private void readHeader(Stream header, string headerPath, uint version)
258
263
for ( var i = 0 ; i < numFiles ; i ++ )
259
264
{
260
265
// Version 3 uses 32-bit file offsets
261
- long arkFileOffset = ( version == 3 ? header . ReadUInt32LE ( ) : header . ReadInt64LE ( ) ) ;
266
+ long arkFileOffset = ( brokenv5 || version == 3 ? header . ReadUInt32LE ( ) : header . ReadInt64LE ( ) ) ;
262
267
int filenameStringId = header . ReadInt32LE ( ) ;
263
268
uint dirStringId = header . ReadUInt32LE ( ) ;
264
269
uint size = header . ReadUInt32LE ( ) ;
0 commit comments