1+ var rule = {
2+ 类型 : '小说' ,
3+ author : 'EylinSir' ,
4+ title : '阅读助手[书]' ,
5+ desc : '阅读助手小说源' ,
6+ host : 'https://api-bc.wtzw.com' ,
7+ homeUrl : 'https://api-bc.wtzw.com' ,
8+ url : '/api/v4/category/get-list?gender=fyclass&category_id=fyfilter&need_filters=1&page=fypage&need_category=1' ,
9+ class_name : '男生&女生&出版' ,
10+ class_url : '1&2&3' ,
11+ searchUrl : '/api/v5/search/words?gender=3&imei_ip=2937357107&page=fypage&wd=**' ,
12+ searchable : 2 ,
13+ quickSearch : 0 ,
14+ filterable : 1 ,
15+ filter : {
16+ "1" : [ { key : "type" , name : "类型" , value : [ { "n" :"玄幻奇幻" , "v" :"202" } , { "n" :"都市人生" , "v" :"203" } , { "n" :"武侠仙侠" , "v" :"205" } , { "n" :"历史军事" , "v" :"56" } , { "n" :"科幻末世" , "v" :"64" } , { "n" :"游戏竞技" , "v" :"75" } , { "n" :"体育赛事" , "v" :"206" } , { "n" :"奇闻异事" , "v" :"204" } ] } ] ,
17+ "2" : [ { key : "type" , name : "类型" , value : [ { "n" :"现代言情" , "v" :"1" } , { "n" :"古代言情" , "v" :"2" } , { "n" :"幻想言情" , "v" :"4" } , { "n" :"宫闱宅斗" , "v" :"209" } ] } ] ,
18+ "3" : [ { key : "type" , name : "类型" , value : [ { "n" :"悬疑推理" , "v" :"262" } , { "n" :"文学艺术" , "v" :"240" } , { "n" :"历史传记" , "v" :"264" } ] } ]
19+ } ,
20+ filter_url : "{{fl.type}}" ,
21+ filter_def : { } ,
22+ headers : { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36' } ,
23+ sign_headers : {
24+ "app-version" : "51110" , "platform" : "android" , "reg" : "0" , "AUTHORIZATION" : "" ,
25+ "application-id" : "com.****.reader" , "net-env" : "1" , "channel" : "unknown" , "qm-params" : ""
26+ } ,
27+ timeout : 10000 ,
28+ play_parse : true ,
29+
30+ request : async function ( url , obj ) {
31+ obj = obj || { } ;
32+ const response = await _fetch ( url , {
33+ method : obj . method || 'GET' ,
34+ headers : obj . headers || this . headers
35+ } ) ;
36+ return response . text ( ) ;
37+ } ,
38+
39+ 预处理 : async function ( ) {
40+ this . sign_headers . sign = getSignStr ( this . sign_headers ) ;
41+ } ,
42+
43+ 一级 : async function ( tid , pg , filter , extend ) {
44+ let d = [ ] ;
45+ const cateMap = { '1' :'202' , '2' :'1' , '3' :'262' } ;
46+ let gender = tid !== '-1' ? tid : '2' ;
47+ let category_id = cateMap [ gender ] ;
48+ const validSubTypes = [ '202' , '203' , '205' , '56' , '64' , '75' , '206' , '204' , '1' , '2' , '4' , '209' , '262' , '240' , '264' ] ;
49+ if ( extend ?. type && validSubTypes . includes ( extend . type ) ) {
50+ category_id = extend . type ;
51+ } else if ( filter && validSubTypes . includes ( filter ) ) {
52+ category_id = filter ;
53+ }
54+ let params = {
55+ gender : gender ,
56+ category_id : category_id ,
57+ need_filters : '1' ,
58+ page : pg || '1' ,
59+ need_category : '1' ,
60+ imei_ip : '2937357107'
61+ } ;
62+ params . sign = getSignStr ( params ) ;
63+ let html = await this . request ( buildUrl ( `${ this . host } /api/v4/category/get-list` , params ) , { headers : this . sign_headers } ) ;
64+ let json = JSON . parse ( html ) ;
65+ if ( json ?. data ?. books ) {
66+ d = json . data . books . map ( it => ( {
67+ title : it . title ,
68+ url : `${ this . host } /api/v4/book/detail?id=${ it . id } ` ,
69+ desc : it . author ,
70+ pic_url : it . image_link ,
71+ content : it . intro
72+ } ) ) ;
73+ }
74+ return setResult ( d ) ;
75+ } ,
76+
77+ 二级 : async function ( ) {
78+ let VOD = { } ;
79+ let bookId = this . input . match ( / i d = ( \d + ) / ) [ 1 ] ;
80+ let detailParams = { id : bookId , imei_ip : '2937357107' , teeny_mode : '0' } ;
81+ detailParams . sign = getSignStr ( detailParams ) ;
82+ let detailHtml = await this . request ( buildUrl ( `${ this . host } /api/v4/book/detail` , detailParams ) , { headers : this . sign_headers } ) ;
83+ let detailJson = JSON . parse ( detailHtml ) ;
84+ if ( detailJson ?. data ?. book ) {
85+ let book = detailJson . data . book ;
86+ VOD = {
87+ vod_name : book . title ,
88+ type_name : book . book_tag_list ?. map ( tag => tag . title ) . join ( ',' ) || '' ,
89+ vod_pic : book . image_link ,
90+ vod_content : book . intro ,
91+ vod_remarks : book . latest_chapter_title ,
92+ vod_year : '' , vod_area : '' ,
93+ vod_actor : book . author , vod_director : book . author ,
94+ vod_play_from : '阅读助手'
95+ } ;
96+ let tocParams = { id : book . id } ;
97+ tocParams . sign = getSignStr ( tocParams ) ;
98+ let tocHtml = await this . request ( buildUrl ( 'https://api-ks.wtzw.com/api/v1/chapter/chapter-list' , tocParams ) , { headers : this . sign_headers } ) ;
99+ let tocJson = JSON . parse ( tocHtml ) ;
100+ if ( tocJson ?. data ?. chapter_lists ) {
101+ VOD . vod_play_url = tocJson . data . chapter_lists . map ( chapter =>
102+ `${ chapter . title } $${ book . id } @@${ chapter . id } @@${ chapter . title } `
103+ ) . join ( '#' ) ;
104+ }
105+ }
106+ return VOD ;
107+ } ,
108+
109+ 搜索 : async function ( ) {
110+ let d = [ ] ;
111+ let params = {
112+ gender : '3' , imei_ip : '2937357107' ,
113+ page : this . MY_PAGE , wd : this . KEY
114+ } ;
115+ params . sign = getSignStr ( params ) ;
116+ let html = await this . request ( buildUrl ( `${ this . host } /api/v5/search/words` , params ) , { headers : this . sign_headers } ) ;
117+ let json = JSON . parse ( html ) ;
118+ if ( json ?. data ?. books ) {
119+ d = json . data . books . map ( it => ( {
120+ title : it . original_title ,
121+ desc : it . author ,
122+ pic_url : it . image_link ,
123+ url : `${ this . host } /api/v4/book/detail?id=${ it . id } ` ,
124+ content : it . intro
125+ } ) ) ;
126+ }
127+ return setResult ( d ) ;
128+ } ,
129+
130+ lazy : async function ( ) {
131+ let [ bookId , chapterId , title ] = this . input . split ( '@@' ) ;
132+ let content = '内容加载失败' ;
133+ let params = { id : bookId , chapterId} ;
134+ params . sign = getSignStr ( params ) ;
135+ let html = await this . request ( buildUrl ( 'https://api-ks.wtzw.com/api/v1/chapter/content' , params ) , { headers : this . sign_headers } ) ;
136+ let json = JSON . parse ( html ) ;
137+ if ( json ?. data ?. content ) content = decodeContent ( json . data . content ) ;
138+ return {
139+ parse : 0 ,
140+ url : `novel://${ JSON . stringify ( { title, content} ) } ` ,
141+ js : ''
142+ } ;
143+ }
144+ } ;
145+
146+ function getSignStr ( params ) {
147+ const sign_key = "d3dGiJc651gSQ8w1" ;
148+ return md5 ( Object . keys ( params ) . sort ( ) . reduce ( ( pre , n ) => pre + n + "=" + params [ n ] , "" ) + sign_key ) ;
149+ }
150+
151+ function decodeContent ( content ) {
152+ let key = CryptoJS . enc . Utf8 . parse ( "242ccb8230d709e1" ) ;
153+ let ivEncData = CryptoJS . enc . Base64 . parse ( content ) ;
154+ let iv = CryptoJS . lib . WordArray . create ( ivEncData . words . slice ( 0 , 4 ) ) ;
155+ let encrypted = CryptoJS . lib . WordArray . create ( ivEncData . words . slice ( 4 ) ) ;
156+ let decrypted = CryptoJS . AES . decrypt ( { ciphertext : encrypted } , key , {
157+ iv, mode : CryptoJS . mode . CBC , padding : CryptoJS . pad . Pkcs7
158+ } ) ;
159+ return decrypted . toString ( CryptoJS . enc . Utf8 ) ;
160+ }
0 commit comments