@@ -231,6 +231,10 @@ enum CryptType {
231231 RhapsodyCrypt {
232232 file_list_name : String ,
233233 } ,
234+ #[ serde( rename_all = "PascalCase" ) ]
235+ MadoCrypt {
236+ seed : u32 ,
237+ } ,
234238}
235239
236240#[ derive( Clone , Debug , Deserialize ) ]
@@ -359,6 +363,7 @@ impl Schema {
359363 & file_list_name,
360364 config. xp3_file_list_path . as_ref ( ) . map ( |s| s. as_str ( ) ) ,
361365 ) ?) ,
366+ CryptType :: MadoCrypt { seed } => Box :: new ( MadoCrypt :: new ( self . base . clone ( ) , * seed) ) ,
362367 } )
363368 }
364369}
@@ -543,6 +548,20 @@ macro_rules! base_schema_impl {
543548 } ;
544549}
545550
551+ macro_rules! base_schema2_impl {
552+ ( ) => {
553+ fn hash_after_crypt( & self ) -> bool {
554+ AsRef :: <BaseSchema >:: as_ref( self ) . hash_after_crypt
555+ }
556+ fn startup_tjs_not_encrypted( & self ) -> bool {
557+ AsRef :: <BaseSchema >:: as_ref( self ) . startup_tjs_not_encrypted
558+ }
559+ fn obfuscated_index( & self ) -> bool {
560+ AsRef :: <BaseSchema >:: as_ref( self ) . obfuscated_index
561+ }
562+ } ;
563+ }
564+
546565macro_rules! seek_crypt_base_impl {
547566 ( $crypt: ident, $reader: ident) => {
548567 #[ derive( Debug ) ]
@@ -1667,6 +1686,73 @@ impl<R: Read> Read for RhapsodyCryptReader<R> {
16671686 }
16681687}
16691688
1689+ #[ derive( Debug ) ]
1690+ pub struct MadoCrypt {
1691+ base : AkabeiCrypt ,
1692+ }
1693+
1694+ impl MadoCrypt {
1695+ pub fn new ( base : BaseSchema , seed : u32 ) -> Self {
1696+ Self {
1697+ base : AkabeiCrypt :: new ( base, seed) ,
1698+ }
1699+ }
1700+ }
1701+
1702+ impl AsRef < BaseSchema > for MadoCrypt {
1703+ fn as_ref ( & self ) -> & BaseSchema {
1704+ & self . base . base
1705+ }
1706+ }
1707+
1708+ impl Crypt for MadoCrypt {
1709+ base_schema2_impl ! ( ) ;
1710+ fn decrypt_supported ( & self ) -> bool {
1711+ true
1712+ }
1713+ fn decrypt_seek_supported ( & self ) -> bool {
1714+ true
1715+ }
1716+ fn decrypt < ' a > (
1717+ & self ,
1718+ entry : & Xp3Entry ,
1719+ cur_seg : & Segment ,
1720+ stream : Box < dyn Read + ' a > ,
1721+ ) -> Result < Box < dyn ReadDebug + ' a > > {
1722+ Ok ( Box :: new ( MadoCryptReader :: new (
1723+ stream,
1724+ cur_seg,
1725+ self . base . get_key ( entry. file_hash ) ,
1726+ ) ) )
1727+ }
1728+ fn decrypt_with_seek < ' a > (
1729+ & self ,
1730+ entry : & Xp3Entry ,
1731+ cur_seg : & Segment ,
1732+ stream : Box < dyn ReadSeek + ' a > ,
1733+ ) -> Result < Box < dyn ReadSeek + ' a > > {
1734+ Ok ( Box :: new ( MadoCryptReader :: new (
1735+ stream,
1736+ cur_seg,
1737+ self . base . get_key ( entry. file_hash ) ,
1738+ ) ) )
1739+ }
1740+ }
1741+
1742+ seek_reader_key_impl ! ( MadoCryptReader <T >, [ u8 ; 0x20 ] ) ;
1743+
1744+ impl < R : Read > Read for MadoCryptReader < R > {
1745+ fn read ( & mut self , buf : & mut [ u8 ] ) -> std:: io:: Result < usize > {
1746+ let readed = self . inner . read ( buf) ?;
1747+ for ( i, t) in ( & mut buf[ ..readed] ) . iter_mut ( ) . enumerate ( ) {
1748+ let offset = self . seg_start + self . pos + i as u64 ;
1749+ * t ^= self . key [ ( offset % 0x1F ) as usize ] ;
1750+ }
1751+ self . pos += readed as u64 ;
1752+ Ok ( readed)
1753+ }
1754+ }
1755+
16701756#[ test]
16711757fn test_deserialize_crypt ( ) {
16721758 for ( key, schema) in CRYPT_SCHEMA . iter ( ) {
0 commit comments