diff --git a/proxy.ts b/proxy.ts index 2807ff4a7..4a25bc633 100644 --- a/proxy.ts +++ b/proxy.ts @@ -18,7 +18,13 @@ const settings: ServerSetting = { 'sec-fetch-dest', 'pragma', ], - disAllowResponseHeaders: ['link', 'set-cookie', 'set-cookie2'], + disAllowResponseHeaders: [ + 'link', + 'set-cookie', + 'set-cookie2', + 'content-encoding', + 'content-length', + ], useUserAgent: true, }; @@ -160,10 +166,15 @@ const proxyRequest: Connect.SimpleHandleFunction = (req, res) => { fetch(_url.href, { headers: headers, }) - .then(res2 => res2.text()) - .then(res2 => { - res.statusCode = 200; - res.write(res2); + .then(async res2 => [res2, await res2.text()] as const) + .then(([res2, text]) => { + res.statusCode = res2.status; + res2.headers.forEach((val, key) => { + if (!settings.disAllowResponseHeaders.includes(key)) { + res.setHeader(key, val); + } + }); + res.write(text); res.end(); }) .catch(err => { diff --git a/src/plugins/english/mvlempyr.ts b/src/plugins/english/mvlempyr.ts index 8d5e2c4d0..775d83c88 100644 --- a/src/plugins/english/mvlempyr.ts +++ b/src/plugins/english/mvlempyr.ts @@ -29,9 +29,9 @@ class MVLEMPYRPlugin implements Plugin.PluginBase { name = 'MVLEMPYR'; icon = 'src/en/mvlempyr/icon.png'; site = 'https://www.mvlempyr.com/'; - version = '1.0.5'; + version = '1.0.6'; - _chapSite = 'https://chp.mvlempyr.net/'; + _chapSite = 'https://chap.mvlempyr.net/'; _allNovels: (Plugin.NovelItem & ExtraNovelData)[] | undefined; _allNovelsPromise: Promise<(Plugin.NovelItem & ExtraNovelData)[]> | undefined; @@ -294,6 +294,19 @@ class MVLEMPYRPlugin implements Plugin.PluginBase { return this.parseNovels(loadedCheerio, nextPageConsumer); } + convertNovelId(e: bigint) { + let t = 1999999997n; + let u = 1n, + c = 7n % t, + d = e; + for ( + ; + d > 0; + (1n & d) === 1n && (u = (u * c) % t), c = (c * c) % t, d >>= 1n + ); + return u; + } + async parseNovel(novelPath: string): Promise { const url = this.site + novelPath; const result = await fetchApi(url); @@ -304,39 +317,47 @@ class MVLEMPYRPlugin implements Plugin.PluginBase { this.checkCaptcha(loadedCheerio); const code = loadedCheerio('#novel-code').text(); - const tags = ( - await fetchApi(this._chapSite + 'wp-json/wp/v2/tags?slug=' + code, { + const newNovelId = this.convertNovelId(BigInt(parseInt(code))); + const firstPostsReq = await fetchApi( + this._chapSite + + 'wp-json/wp/v2/posts?tags=' + + newNovelId + + '&per_page=500&page=1', + { headers: { origin2: this.site.replace(/\/$/, ''), origin: this.site.replace(/\/$/, ''), + Referer: 'https://www.mvlempyr.com/', }, - }).then(res => res.json()) - )[0]; + }, + ); - const posts = ( - await Promise.all( - new Array(Math.ceil(tags.count / 500)) + const pages = parseInt(firstPostsReq.headers.get('x-wp-totalpages')); + + const posts = [ + await firstPostsReq.json(), + ...(await Promise.all( + new Array(pages - 1) .fill(0) - .map((_, i) => i + 1) + .map((_, i) => i + 2) .map(page => fetchApi( this._chapSite + 'wp-json/wp/v2/posts?tags=' + - tags.id + + newNovelId + '&per_page=500&page=' + page, { headers: { origin2: this.site.replace(/\/$/, ''), origin: this.site.replace(/\/$/, ''), + Referer: 'https://www.mvlempyr.com/', }, }, ).then(res => res.json()), ), - ) - ) - .flat() - .sort((a, b) => a.acf.chapter_number - b.acf.chapter_number); + )), + ].flat(); return { path: novelPath, @@ -350,12 +371,15 @@ class MVLEMPYRPlugin implements Plugin.PluginBase { summary: loadedCheerio('.novelpaewrapper div.synopsis.w-richtext') .text() .trim(), - chapters: posts.map(chap => ({ - name: chap.acf.ch_name, - path: 'chapter/' + chap.acf.novel_code + '-' + chap.acf.chapter_number, - releaseTime: chap.date, - chapterNumber: chap.acf.chapter_number, - })), + chapters: posts + .map(chap => ({ + name: chap.acf.ch_name, + path: + 'chapter/' + chap.acf.novel_code + '-' + chap.acf.chapter_number, + releaseTime: chap.date, + chapterNumber: chap.acf.chapter_number, + })) + .reverse(), status: loadedCheerio( '.novelpaewrapper div.novelstatustextmedium', ).text(),