@@ -42,6 +42,9 @@ public enum Compression
4242 Huffman ,
4343 Deflate ,
4444 DeflateOrNone ,
45+ None2 ,
46+ Zstd ,
47+ ZstdOrNone ,
4548 }
4649
4750 public class PacArchive : ArcFile
@@ -67,13 +70,16 @@ public class PacOpener : ArchiveFormat
6770 public PacOpener ( )
6871 {
6972 Signatures = new uint [ ] { 0x00434150 , 0 } ;
73+ Settings = new [ ] { PacEncoding } ;
7074 }
7175
76+ EncodingSetting PacEncoding = new EncodingSetting ( "NexasEncodingCP" , "DefaultEncoding" ) ;
77+
7278 public override ArcFile TryOpen ( ArcView file )
7379 {
7480 if ( ! file . View . AsciiEqual ( 0 , "PAC" ) || 'K' == file . View . ReadByte ( 3 ) )
7581 return null ;
76- var reader = new IndexReader ( file ) ;
82+ var reader = new IndexReader ( file , PacEncoding . Get < Encoding > ( ) ) ;
7783 var dir = reader . Read ( ) ;
7884 if ( null == dir )
7985 return null ;
@@ -88,16 +94,18 @@ internal sealed class IndexReader
8894 ArcView m_file ;
8995 int m_count ;
9096 int m_pack_type ;
97+ Encoding m_encoding ;
9198
9299 const int MaxNameLength = 0x40 ;
93100
94101 public Compression PackType { get { return ( Compression ) m_pack_type ; } }
95102
96- public IndexReader ( ArcView file )
103+ public IndexReader ( ArcView file , Encoding enc )
97104 {
98105 m_file = file ;
99106 m_count = file . View . ReadInt32 ( 4 ) ;
100107 m_pack_type = file . View . ReadInt32 ( 8 ) ;
108+ m_encoding = enc ;
101109 }
102110
103111 List < Entry > m_dir ;
@@ -151,7 +159,7 @@ bool ReadFromStream (IBinaryStream index, int name_length)
151159 m_dir . Clear ( ) ;
152160 for ( int i = 0 ; i < m_count ; ++ i )
153161 {
154- var name = index . ReadCString ( name_length ) ;
162+ var name = index . ReadCString ( name_length , m_encoding ) ;
155163 if ( string . IsNullOrWhiteSpace ( name ) )
156164 return false ;
157165 var entry = FormatCatalog . Instance . Create < PackedEntry > ( name ) ;
@@ -160,7 +168,23 @@ bool ReadFromStream (IBinaryStream index, int name_length)
160168 entry . Size = index . ReadUInt32 ( ) ;
161169 if ( ! entry . CheckPlacement ( m_file . MaxOffset ) )
162170 return false ;
163- entry . IsPacked = m_pack_type != 0 && ( m_pack_type != 4 || entry . Size != entry . UnpackedSize ) ;
171+ switch ( m_pack_type )
172+ {
173+ case 1 :
174+ case 2 :
175+ case 3 :
176+ case 6 :
177+ {
178+ entry . IsPacked = true ;
179+ break ;
180+ }
181+ case 4 :
182+ case 7 :
183+ {
184+ entry . IsPacked = entry . Size != entry . UnpackedSize ;
185+ break ;
186+ }
187+ }
164188 m_dir . Add ( entry ) ;
165189 }
166190 return true ;
@@ -188,8 +212,16 @@ public override Stream OpenEntry (ArcFile arc, Entry entry)
188212 return new BinMemoryStream ( unpacked , 0 , ( int ) pent . UnpackedSize , entry . Name ) ;
189213 }
190214 case Compression . Deflate :
191- default :
215+ case Compression . DeflateOrNone :
192216 return new ZLibStream ( input , CompressionMode . Decompress ) ;
217+ case Compression . Zstd :
218+ case Compression . ZstdOrNone :
219+ {
220+ var unpacked = ZstdDecompress ( input , pent . UnpackedSize ) ;
221+ return new BinMemoryStream ( unpacked , entry . Name ) ;
222+ }
223+ default :
224+ return input ;
193225 }
194226 }
195227
@@ -199,5 +231,15 @@ static private byte[] HuffmanDecode (byte[] packed, int unpacked_size)
199231 var decoder = new HuffmanDecoder ( packed , dst ) ;
200232 return decoder . Unpack ( ) ;
201233 }
234+
235+ static private byte [ ] ZstdDecompress ( Stream s , uint unpackedSize )
236+ {
237+ using ( var ds = new ZstdNet . DecompressionStream ( s ) )
238+ {
239+ var dst = new byte [ unpackedSize ] ;
240+ ds . Read ( dst , 0 , dst . Length ) ;
241+ return dst ;
242+ }
243+ }
202244 }
203245}
0 commit comments