@@ -50,40 +50,48 @@ public MixFile(string filename, int priority)
50
50
s = FileSystem . Open ( filename ) ;
51
51
52
52
// Detect format type
53
+ s . Seek ( 0 , SeekOrigin . Begin ) ;
53
54
var reader = new BinaryReader ( s ) ;
54
55
var isCncMix = reader . ReadUInt16 ( ) != 0 ;
55
- var isEncrypted = false ;
56
56
57
57
// The C&C mix format doesn't contain any flags or encryption
58
- if ( isCncMix )
59
- s . Seek ( 0 , SeekOrigin . Begin ) ;
60
- else
58
+ var isEncrypted = false ;
59
+ if ( ! isCncMix )
61
60
isEncrypted = ( reader . ReadUInt16 ( ) & 0x2 ) != 0 ;
62
61
63
- var header = isEncrypted ? DecryptHeader ( s ) : s ;
64
- index = ParseHeader ( header ) . ToDictionaryWithConflictLog ( x => x . Hash ,
65
- "{0} ({1} format, Encrypted: {2})" . F ( filename , ( isCncMix ? "C&C" : "RA/TS/RA2" ) , isEncrypted ) ,
62
+ List < PackageEntry > entries ;
63
+ if ( isEncrypted )
64
+ {
65
+ long unused ;
66
+ entries = ParseHeader ( DecryptHeader ( s , 4 , out dataStart ) , 0 , out unused ) ;
67
+ }
68
+ else
69
+ entries = ParseHeader ( s , isCncMix ? 0 : 4 , out dataStart ) ;
70
+
71
+ index = entries . ToDictionaryWithConflictLog ( x => x . Hash ,
72
+ "{0} ({1} format, Encrypted: {2}, DataStart: {3})" . F ( filename , ( isCncMix ? "C&C" : "RA/TS/RA2" ) , isEncrypted , dataStart ) ,
66
73
null , x => "(offs={0}, len={1})" . F ( x . Offset , x . Length )
67
74
) ;
68
-
69
- dataStart = s . Position ;
70
75
}
71
76
72
- List < PackageEntry > ParseHeader ( Stream s )
77
+ List < PackageEntry > ParseHeader ( Stream s , long offset , out long headerEnd )
73
78
{
74
- var items = new List < PackageEntry > ( ) ;
79
+ s . Seek ( offset , SeekOrigin . Begin ) ;
75
80
var reader = new BinaryReader ( s ) ;
76
81
var numFiles = reader . ReadUInt16 ( ) ;
77
82
/*uint dataSize = */ reader . ReadUInt32 ( ) ;
78
83
84
+ var items = new List < PackageEntry > ( ) ;
79
85
for ( var i = 0 ; i < numFiles ; i ++ )
80
86
items . Add ( new PackageEntry ( reader ) ) ;
81
87
88
+ headerEnd = offset + 6 + numFiles * PackageEntry . Size ;
82
89
return items ;
83
90
}
84
91
85
- MemoryStream DecryptHeader ( Stream s )
92
+ MemoryStream DecryptHeader ( Stream s , long offset , out long headerEnd )
86
93
{
94
+ s . Seek ( offset , SeekOrigin . Begin ) ;
87
95
var reader = new BinaryReader ( s ) ;
88
96
89
97
// Decrypt blowfish key
@@ -92,13 +100,14 @@ MemoryStream DecryptHeader(Stream s)
92
100
var fish = new Blowfish ( blowfishKey ) ;
93
101
94
102
// Decrypt first block to work out the header length
95
- var headerStart = s . Position ;
96
- var ms = Decrypt ( ReadBlocks ( s , headerStart , 1 ) , fish ) ;
103
+ var ms = Decrypt ( ReadBlocks ( s , offset + 80 , 1 ) , fish ) ;
97
104
var numFiles = new BinaryReader ( ms ) . ReadUInt16 ( ) ;
98
105
99
106
// Decrypt the full header - round bytes up to a full block
100
107
var blockCount = ( 13 + numFiles * PackageEntry . Size ) / 8 ;
101
- return Decrypt ( ReadBlocks ( s , headerStart , blockCount ) , fish ) ;
108
+ headerEnd = offset + 80 + blockCount * 8 ;
109
+
110
+ return Decrypt ( ReadBlocks ( s , offset + 80 , blockCount ) , fish ) ;
102
111
}
103
112
104
113
static MemoryStream Decrypt ( uint [ ] h , Blowfish fish )
0 commit comments