From 886ecc43be1e02855df6f53c3f515cdff10a9627 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=99=9A=E9=A3=8E=E6=8B=82=E6=9F=B3=E9=A2=9C?=
<434857005@qq.com>
Date: Thu, 27 Feb 2025 20:58:06 +0800
Subject: [PATCH 1/5] =?UTF-8?q?fix:=20123=E5=92=8C=E6=8E=A8=E9=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
更新版本
---
README.md | 4 ++
docs/updateRecord.md | 7 ++++
js/push_agent.js | 52 +++++++++++++-------------
libs/drpyS.js | 13 +++++--
package.json | 2 +-
public/index.html | 2 +
utils/pan123.js | 89 +++++++++++++++++++++++++-------------------
7 files changed, 100 insertions(+), 69 deletions(-)
diff --git a/README.md b/README.md
index 96fd93a..8b3ba5d 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,10 @@ nodejs作为服务端的drpy实现。全面升级异步写法
## 更新记录
+### 20250227
+
+更新至V1.1.22
+
### 20250226
更新至V1.1.21
diff --git a/docs/updateRecord.md b/docs/updateRecord.md
index 5fea507..2c1f28e 100644
--- a/docs/updateRecord.md
+++ b/docs/updateRecord.md
@@ -1,5 +1,12 @@
# drpyS更新记录
+### 20250227
+
+更新至V1.1.22
+
+1. 优化123网盘的逻辑和推送示例
+2. 优化sqlite3库兼容装逼壳
+
### 20250226
更新至V1.1.21
diff --git a/js/push_agent.js b/js/push_agent.js
index 38acfae..d4b8167 100644
--- a/js/push_agent.js
+++ b/js/push_agent.js
@@ -25,8 +25,7 @@ var rule = {
let vod = {
vod_pic: icon,
vod_id: orId,
- vod_content: orId || '温馨提醒:宝子们,推送的时候记得确保ids存在哟~',
- vod_name: 'DS推送:道长&秋秋倾情打造',
+ vod_content: 'DS推送:道长&秋秋倾情打造',
}
let playPans = [];
if (/^[\[{]/.test(input.trim())) {
@@ -56,7 +55,7 @@ var rule = {
let list = input.split('@');
// log(list);
for (let i = 0; i < list.length; i++) {
- if (/pan.quark.cn|drive.uc.cn|www.alipan.com|www.aliyundrive.com|cloud.189.cn|yun.139.com|www.123684.com/.test(list[i])) {
+ if (/pan.quark.cn|drive.uc.cn|www.alipan.com|www.aliyundrive.com|cloud.189.cn|yun.139.com|www.123684.com|www.123865.com|www.123912.com|www.123pan.com|www.123pan.cn|www.123592.com/.test(list[i])) {
if (/pan.quark.cn/.test(list[i])) {
playPans.push(list[i]);
const shareData = Quark.getShareData(list[i]);
@@ -127,24 +126,24 @@ var rule = {
playurls.push(urls);
})
}
-
- if(/www.123684.com/.test(list[i])) {
+ if(/www.123684.com|www.123865.com|www.123912.com/.test(list[i])) {
playPans.push(list[i]);
- let shareData = Pan.getShareData(list[i])
+ let shareData = await Pan.getShareData(list[i])
let videos = await Pan.getFilesByShareUrl(shareData)
if (videos.length > 0) {
playform.push('Pan123-' + shareData);
- const urls = videos.map(item => item.FileName + "$" + [item.ShareKey, item.FileId, item.S3KeyFlag, item.Size, item.Etag].join('*')).join('#');
- playurls.push(urls);
+ playurls.push(videos.map((v) => {
+ const list = [v.ShareKey, v.FileId, v.S3KeyFlag, v.Size, v.Etag];
+ return v.FileName + '$' + list.join('*');
+ }).join('#'))
}
}
-
} else {
playform.push('推送');
playurls.push("推送" + '$' + list[i])
}
}
- } else if (/pan.quark.cn|drive.uc.cn|www.alipan.com|www.aliyundrive.com|cloud.189.cn|yun.139.com|www.123684.com/.test(input)) {
+ } else if (/pan.quark.cn|drive.uc.cn|www.alipan.com|www.aliyundrive.com|cloud.189.cn|yun.139.com|www.123684.com|www.123865.com|www.123912.com|www.123pan.com|www.123pan.cn|www.123592.com/.test(input)) {
if (/pan.quark.cn/.test(input)) {
playPans.push(input);
const shareData = Quark.getShareData(input);
@@ -184,6 +183,7 @@ var rule = {
const shareData = Ali.getShareData(input);
if (shareData) {
const videos = await Ali.getFilesByShareUrl(shareData);
+ log(videos);
if (videos.length > 0) {
playform.push('Ali-' + shareData.shareId);
playurls.push(videos.map((v) => {
@@ -214,16 +214,18 @@ var rule = {
playurls.push(urls);
})
}
-
- if(/www.123684.com/.test(input)) {
+ if(/www.123684.com|www.123865.com|www.123912.com|www.123pan.com|www.123pan.cn|www.123592.com/.test(input)) {
playPans.push(input);
- let shareData = Pan.getShareData(input)
+ let shareData = await Pan.getShareData(input)
let videos = await Pan.getFilesByShareUrl(shareData)
- if (videos.length > 0) {
- playform.push('Pan123-' + shareData);
- const urls = videos.map(item => item.FileName + "$" + [item.ShareKey, item.FileId, item.S3KeyFlag, item.Size, item.Etag].join('*')).join('#');
+ Object.keys(videos).forEach(it => {
+ playform.push('Pan123-' + it)
+ const urls = videos[it].map(v => {
+ const list = [v.ShareKey, v.FileId, v.S3KeyFlag, v.Size, v.Etag];
+ return v.FileName + '$' + list.join('*');
+ }).join('#');
playurls.push(urls);
- }
+ })
}
} else {
playform.push('推送');
@@ -328,23 +330,19 @@ var rule = {
}
if(flag.startsWith('Pan123-')) {
log('盘123解析开始')
- const url = await Pan.getDownload(ids[0], ids[1], ids[2], ids[3], ids[4])
- urls.push("原画", url + "#isVideo=true#")
- log('jj:',url)
- let data = await Pan.getLiveTranscoding(ids[0], ids[1], ids[2], ids[3], ids[4])
+ const url = await Pan.getDownload(ids[0],ids[1],ids[2],ids[3],ids[4])
+ urls.push("原画",url)
+ let data = await Pan.getLiveTranscoding(ids[0],ids[1],ids[2],ids[3],ids[4])
data.forEach((item) => {
- urls.push(item.name, item.url)
+ urls.push(item.name,item.url)
})
return {
parse: 0,
- url: urls,
- header: {
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
- }
+ url: urls
}
}
} else {
return input
}
},
-}
+}
\ No newline at end of file
diff --git a/libs/drpyS.js b/libs/drpyS.js
index 382b827..97cc42e 100644
--- a/libs/drpyS.js
+++ b/libs/drpyS.js
@@ -167,13 +167,20 @@ globalThis.simplecc = simplecc;
let DataBase = null;
let database = null;
try {
- const sqliteUtil = await import('../utils/database.js'); // 使用动态 import
- DataBase = sqliteUtil.DataBase;
- database = sqliteUtil.database;
+ if (typeof fetchByHiker !== 'undefined' && typeof globalThis.import === 'function') {
+ const sqliteUtil = await globalThis.import('../utils/database.js'); // 海阔放在globalThis里去动态引入
+ DataBase = sqliteUtil.DataBase;
+ database = sqliteUtil.database;
+ } else {
+ const sqliteUtil = await import('../utils/database.js'); // 使用动态 import
+ DataBase = sqliteUtil.DataBase;
+ database = sqliteUtil.database;
+ }
console.log('sqlite3 database imported successfully');
} catch (error) {
console.log(`Failed to import sqlite3:${error.message}`);
}
+
globalThis.DataBase = DataBase;
globalThis.database = database;
diff --git a/package.json b/package.json
index 08ca969..5f3a151 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "drpy-node",
- "version": "1.1.21",
+ "version": "1.1.22",
"main": "index.js",
"type": "module",
"scripts": {
diff --git a/public/index.html b/public/index.html
index c1b6ce5..9023688 100644
--- a/public/index.html
+++ b/public/index.html
@@ -24,6 +24,8 @@
drpyS(drpy-node)
在线猫ds源主页
更新记录
+20250227
+更新至V1.1.22
20250226
更新至V1.1.21
20250225
diff --git a/utils/pan123.js b/utils/pan123.js
index 3f2d300..ee04693 100644
--- a/utils/pan123.js
+++ b/utils/pan123.js
@@ -1,12 +1,14 @@
import axios from "axios";
import {ENV} from "./env.js";
+import {base64Decode} from "../libs_drpy/crypto-util.js";
class Pan123 {
constructor() {
- this.regex = /https:\/\/www.123684.com\/s\/([^\\/]+)/
+ this.regex = /https:\/\/(www.123684.com|www.123865.com|www.123912.com|www.123pan.com|www.123pan.cn|www.123592.com)\/s\/([^\\/]+)/
this.api = 'https://www.123684.com/b/api/share/';
this.loginUrl = 'https://login.123pan.com/api/user/sign_in';
+ this.cate = ''
}
async init() {
@@ -72,10 +74,10 @@ class Pan123 {
console.log(this.SharePwd)
}
if (matches) {
- if(matches[1].indexOf('?') > 0){
- return matches[1].split('?')[0]
+ if(matches[2].indexOf('?') > 0){
+ return matches[2].split('?')[0]
}else {
- return matches[1]
+ return matches[2].match(/www/g)?matches[1]:matches[2];
}
}
@@ -83,21 +85,40 @@ class Pan123 {
}
async getFilesByShareUrl(shareKey){
- return await this.getShareInfo(shareKey, this.SharePwd, 0, 0)
+ let file = {}
+ let cate = await this.getShareInfo(shareKey, this.SharePwd, 0, 0)
+ if(cate && Array.isArray(cate)){
+ await Promise.all(cate.map(async (item) => {
+ if (!(item.filename in file)) {
+ file[item.filename] = [];
+ }
+ const fileData = await this.getShareList(item.shareKey,item.SharePwd,item.next, item.fileId);
+ if (fileData && fileData.length > 0) {
+ file[item.filename].push(...fileData);
+ }
+ }));
+ }
+ // 过滤掉空数组
+ for (let key in file) {
+ if (file[key].length === 0) {
+ delete file[key];
+ }
+ }
+ return file;
}
async getShareInfo(shareKey,SharePwd,next,ParentFileId) {
- let filelist = []
+ let cate = []
let list = await axios.get(this.api+"get",{
headers: {},
params: {
"limit": "100",
- "next": "0",
+ "next": next,
"orderBy": "file_name",
"orderDirection": "asc",
"shareKey": shareKey,
"SharePwd": SharePwd,
- "ParentFileId": "0",
+ "ParentFileId": ParentFileId,
"Page": "1"
}
});
@@ -108,24 +129,20 @@ class Pan123 {
let info = list.data.data;
let next = info.Next;
let infoList = info.InfoList
- for (let i = 0; i < infoList.length; i++) {
- let data = infoList[i];
- if(data.Category === 2){
- filelist.push({
- ShareKey: shareKey,
- FileId: data.FileId,
- S3KeyFlag: data.S3KeyFlag,
- Size: data.Size,
- Etag: data.Etag,
- FileName: data.FileName,
- })
+ infoList.forEach(item => {
+ if(item.Category === 0){
+ cate.push({
+ filename:item.FileName,
+ shareKey:shareKey,
+ SharePwd:SharePwd,
+ next:next,
+ fileId:item.FileId
+ });
}
- let FileId = data.FileId
- let file = await this.getShareList(shareKey,SharePwd,next,FileId);
- filelist.push(...file)
- }
-
- return filelist;
+ })
+ let result = await Promise.all(cate.map(async (it)=> this.getShareInfo(shareKey,SharePwd,next, it.fileId)));
+ result = result.filter(item => item !== undefined && item !== null);
+ return [...cate,...result.flat()];
}
}
}
@@ -145,22 +162,18 @@ class Pan123 {
"Page": "1"
}
})).data.data.InfoList;
- for (let i = 0; i < infoList.length; i++) {
- let data = infoList[i];
- if(data.Category === 2){
+ infoList.forEach(it=>{
+ if(it.Category === 2){
video.push({
ShareKey: shareKey,
- FileId: data.FileId,
- S3KeyFlag: data.S3KeyFlag,
- Size: data.Size,
- Etag: data.Etag,
- FileName: data.FileName,
+ FileId: it.FileId,
+ S3KeyFlag: it.S3KeyFlag,
+ Size: it.Size,
+ Etag: it.Etag,
+ FileName: it.FileName,
})
- }else {
- let FileId = data.FileId
- return await this.getShareList(shareKey, SharePwd, next, FileId)
}
- }
+ })
return video;
}
@@ -185,7 +198,7 @@ class Pan123 {
data: data
};
let down = (await axios.request(config)).data.data
- return down.DownloadURL;
+ return base64Decode((new URL(down.DownloadURL)).searchParams.get('params'));
}
async getLiveTranscoding(shareKey,FileId,S3KeyFlag,Size,Etag){
From 705b1f55964b43b44e72e2cb4e546cebc954740b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=99=9A=E9=A3=8E=E6=8B=82=E6=9F=B3=E9=A2=9C?=
<434857005@qq.com>
Date: Mon, 10 Mar 2025 00:37:07 +0800
Subject: [PATCH 2/5] =?UTF-8?q?fix:=20=E7=95=AA=E8=8C=84=E5=B0=8F=E8=AF=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
更新版本
---
README.md | 6 +-
docs/updateRecord.md | 7 ++
...50\346\260\221\350\277\275\345\211\247.js" | 107 ++++++++++++++++++
...\345\260\217\350\257\264[\344\271\246].js" | 2 +-
...42\346\236\234\347\237\255\345\211\247.js" | 28 +++++
package.json | 2 +-
public/index.html | 4 +-
7 files changed, 152 insertions(+), 4 deletions(-)
create mode 100644 "js/\345\205\250\346\260\221\350\277\275\345\211\247.js"
create mode 100644 "js_dr2/\347\272\242\346\236\234\347\237\255\345\211\247.js"
diff --git a/README.md b/README.md
index 8b3ba5d..97a13b5 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# drpyS(drpy-node)
nodejs作为服务端的drpy实现。全面升级异步写法
-~~积极开发中,每日一更~~,当前进度 `48%`
+~~积极开发中,每日一更~~,当前进度 `49%`
找工作中,随缘更新
* [本地配置接口-动态本地](/config?pwd=)
@@ -19,6 +19,10 @@ nodejs作为服务端的drpy实现。全面升级异步写法
## 更新记录
+### 20250310
+
+更新至V1.1.23
+
### 20250227
更新至V1.1.22
diff --git a/docs/updateRecord.md b/docs/updateRecord.md
index 2c1f28e..1acf857 100644
--- a/docs/updateRecord.md
+++ b/docs/updateRecord.md
@@ -1,5 +1,12 @@
# drpyS更新记录
+### 20250310
+
+更新至V1.1.23
+
+1. 修复番茄小说
+2. 新增2个源
+
### 20250227
更新至V1.1.22
diff --git "a/js/\345\205\250\346\260\221\350\277\275\345\211\247.js" "b/js/\345\205\250\346\260\221\350\277\275\345\211\247.js"
new file mode 100644
index 0000000..b563217
--- /dev/null
+++ "b/js/\345\205\250\346\260\221\350\277\275\345\211\247.js"
@@ -0,0 +1,107 @@
+var rule = {
+ 类型:'影视',
+ title:'全民追剧',
+ desc:'不告诉你',
+ host:'https://jenzg.cn',
+ url: '/index.php/vod/showfyfilter.html[/index.php/vod/showfyclass.html]',
+ searchUrl: '/index.php/vod/search/page/fypage/wd/**.html',
+ searchable:1,quickSearch:1,double:false,timeout:5000,play_parse:true,filterable:1,invalid:true,
+ class_name:'电影&电视剧&综艺&动漫&短剧',
+ class_url:'/id/61&/id/79&/id/88&/id/93&/id/99',
+ filter_url:'{{fl.area}}{{fl.class}}{{fl.cateId}}/page/fypage{{fl.year}}',
+ filter_def:{'/id/61':{cateId:'/id/61'},'/id/79':{cateId:'/id/79'},'/id/88':{cateId:'/id/88'},'/id/93':{cateId:'/id/93'},'/id/99':{cateId:'/id/99'}},
+ 预处理: async () => {return []},
+ 推荐: async function (tid, pg, filter, extend) {
+ let homeFn = rule.一级.bind(this);
+ return await homeFn();
+ },
+ 一级: async function (tid, pg, filter, extend) {
+ let {input, pdfa, pdfh, pd} = this;
+ let html = await request(input);
+ let d = [];
+ let data = pdfa(html, '.module-items .module-item');
+ data.forEach((it) => {
+ d.push({
+ title: pdfh(it, 'a&&title'),
+ pic_url: pd(it, 'img&&data-src'),
+ desc: pdfh(it, '.module-item-text&&Text'),
+ url: pd(it, 'a&&href'),
+ })
+ });
+ return setResult(d)
+ },
+ 二级: async function (ids) {
+ let {input, pdfa, pdfh, pd} = this;
+ let html = await request(input);
+ let VOD = {};
+ VOD.vod_name = pdfh(html, 'h1&&Text');//名称
+ VOD.vod_actor = pdfh(html, '.video-info-items:eq(1)&&Text');//演员
+ VOD.vod_director = pdfh(html, '.video-info-items:eq(0)&&Text');//导演
+ VOD.vod_remarks = pdfh(html, '');//备注
+ VOD.vod_status = pdfh(html, '');//状态
+ VOD.vod_content = pdfh(html, '.video-info-content&&Text');//简介
+ let playlist = pdfa(html, '.module-list');
+ let tabs = pdfa(html, '.module-tab&&.module-tab-item.tab-item');
+ let playmap = {};
+ tabs.map((item, i) => {
+ const form = pdfh(item, 'span&&Text');
+ const list = playlist[i];
+ const a = pdfa(list, 'body&&a:not(:contains(排序))');
+ a.map((it) => {
+ let title = pdfh(it, 'a&&Text');
+ let urls = pd(it, 'a&&href', input);
+ if (!playmap.hasOwnProperty(form)) {
+ playmap[form] = [];
+ }
+ playmap[form].push(title + "$" + urls);
+ });
+ });
+ VOD.vod_play_from = Object.keys(playmap).join('$$$');
+ const urls = Object.values(playmap);
+ const playUrls = urls.map((urllist) => {
+ return urllist.join("#");
+ });
+ VOD.vod_play_url = playUrls.join('$$$');
+ return VOD;
+ },
+ 搜索: async function (wd, quick, pg) {
+ let {input, pdfa, pdfh, pd} = this;
+ let html = await request(input);
+ let d = [];
+ let data = pdfa(html, '.module-items .module-search-item');
+ data.forEach((it) => {
+ d.push({
+ title: pdfh(it, 'a&&title'),
+ pic_url: pd(it, 'img&&data-src'),
+ desc: pdfh(it, '.video-serial&&Text'),
+ url: pd(it, 'a&&href'),
+ content: pdfh(it, '.video-info-aux&&Text'),
+ })
+ });
+ return setResult(d);
+ },
+ lazy: async function (flag, id, flags) {
+ let {input, pdfa, pdfh, pd} = this;
+ let html = await request(input);
+ html = JSON.parse(html.match(/r player_.*?=(.*?))[1]);
+ let url = html.url;
+ if (html.encrypt == "1") {
+ url = unescape(url)
+ return {parse: 0, url: url}
+ } else if (html.encrypt == "2") {
+ url = unescape(base64Decode(url))
+ return {parse: 0, url: url}
+ }
+ if (/m3u8|mp4/.test(url)) {
+ input = url
+ return {parse: 0, url: input}
+ } else {
+ return {parse: 0, url: input}
+ }
+ },
+ filter: {"/id/61":[{"key":"class","name":"剧情","value":[{"n":"全部类型","v":""},{"n":"喜剧","v":"/class/喜剧"},{"n":"动作","v":"/class/动作"},{"n":"怪兽","v":"/class/怪兽"},{"n":"战争","v":"/class/战争"},{"n":"爱情","v":"/class/爱情"},{"n":"悬疑","v":"/class/悬疑"},{"n":"武侠","v":"/class/武侠"},{"n":"奇幻","v":"/class/奇幻"},{"n":"科幻","v":"/class/科幻"},{"n":"冒险","v":"/class/冒险"},{"n":"警匪","v":"/class/警匪"},{"n":"动画","v":"/class/动画"},{"n":"惊悚","v":"/class/惊悚"},{"n":"犯罪","v":"/class/犯罪"},{"n":"恐怖","v":"/class/恐怖"},{"n":"剧情","v":"/class/剧情"},{"n":"历史","v":"/class/历史"},{"n":"纪录片","v":"/class/纪录片"},{"n":"传记","v":"/class/传记"},{"n":"歌舞","v":"/class/歌舞"},{"n":"短片","v":"/class/短片"},{"n":"其他","v":"/class/其他"}]},{"key":"area","name":"地区","value":[{"n":"全部地区","v":""},{"n":"内地","v":"/area/内地"},{"n":"中国香港","v":"/area/中国香港"},{"n":"中国台湾","v":"/area/中国台湾"},{"n":"美国","v":"/area/美国"},{"n":"日本","v":"/area/日本"},{"n":"韩国","v":"/area/韩国"},{"n":"泰国","v":"/area/泰国"},{"n":"印度","v":"/area/印度"},{"n":"英国","v":"/area/英国"},{"n":"法国","v":"/area/法国"},{"n":"德国","v":"/area/德国"},{"n":"加拿大","v":"/area/加拿大"},{"n":"西班牙","v":"/area/西班牙"},{"n":"意大利","v":"/area/意大利"},{"n":"澳大利亚","v":"/area/澳大利亚"},{"n":"其它","v":"/area/其它"}]},{"key":"year","name":"年代","value":[{"n":"全部年代","v":""},{"n":"2025","v":"/year/2025"},{"n":"2024","v":"/year/2024"},{"n":"2023","v":"/year/2023"},{"n":"2022","v":"/year/2022"},{"n":"2021","v":"/year/2021"},{"n":"2020","v":"/year/2020"},{"n":"2019","v":"/year/2019"},{"n":"2018","v":"/year/2018"},{"n":"2017","v":"/year/2017"},{"n":"2016","v":"/year/2016"},{"n":"2015","v":"/year/2015"},{"n":"2014","v":"/year/2014"},{"n":"2013","v":"/year/2013"},{"n":"2012","v":"/year/2012"},{"n":"2011","v":"/year/2011"},{"n":"2010","v":"/year/2010"},{"n":"2009","v":"/year/2009"},{"n":"2008","v":"/year/2008"},{"n":"2007","v":"/year/2007"},{"n":"2006","v":"/year/2006"},{"n":"2005","v":"/year/2005"},{"n":"2004","v":"/year/2004"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"/by/time"},{"n":"人气","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}],
+ "/id/79":[{"key":"class","name":"类型","value":[{"n":"全部类型","v":""},{"n":"青春","v":"/class/青春"},{"n":"古装","v":"/class/古装"},{"n":"爱情","v":"/class/爱情"},{"n":"都市","v":"/class/都市"},{"n":"喜剧","v":"/class/喜剧"},{"n":"战争","v":"/class/战争"},{"n":"军旅","v":"/class/军旅"},{"n":"谍战","v":"/class/谍战"},{"n":"偶像","v":"/class/偶像"},{"n":"警匪","v":"/class/警匪"},{"n":"冒险","v":"/class/冒险"},{"n":"穿越","v":"/class/穿越"},{"n":"仙侠","v":"/class/仙侠"},{"n":"武侠","v":"/class/武侠"},{"n":"悬疑","v":"/class/悬疑"},{"n":"罪案","v":"/class/罪案"},{"n":"家庭","v":"/class/家庭"},{"n":"历史","v":"/class/历史"},{"n":"年代","v":"/class/年代"},{"n":"农村","v":"/class/农村"},{"n":"其他","v":"/class/其他"}]},{"key":"area","name":"地区","value":[{"n":"全部地区","v":""},{"n":"内地","v":"/area/内地"},{"n":"中国香港","v":"/area/中国香港"},{"n":"中国台湾","v":"/area/中国台湾"},{"n":"美国","v":"/area/美国"},{"n":"日本","v":"/area/日本"},{"n":"韩国","v":"/area/韩国"},{"n":"泰国","v":"/area/泰国"},{"n":"印度","v":"/area/印度"},{"n":"英国","v":"/area/英国"},{"n":"法国","v":"/area/法国"},{"n":"德国","v":"/area/德国"},{"n":"加拿大","v":"/area/加拿大"},{"n":"西班牙","v":"/area/西班牙"},{"n":"意大利","v":"/area/意大利"},{"n":"澳大利亚","v":"/area/澳大利亚"},{"n":"其它","v":"/area/其它"}]},{"key":"year","name":"年代","value":[{"n":"全部年代","v":""},{"n":"2025","v":"/year/2025"},{"n":"2024","v":"/year/2024"},{"n":"2023","v":"/year/2023"},{"n":"2022","v":"/year/2022"},{"n":"2021","v":"/year/2021"},{"n":"2020","v":"/year/2020"},{"n":"2019","v":"/year/2019"},{"n":"2018","v":"/year/2018"},{"n":"2017","v":"/year/2017"},{"n":"2016","v":"/year/2016"},{"n":"2015","v":"/year/2015"},{"n":"2014","v":"/year/2014"},{"n":"2013","v":"/year/2013"},{"n":"2012","v":"/year/2012"},{"n":"2011","v":"/year/2011"},{"n":"2010","v":"/year/2010"},{"n":"2009","v":"/year/2009"},{"n":"2008","v":"/year/2008"},{"n":"2007","v":"/year/2007"},{"n":"2006","v":"/year/2006"},{"n":"2005","v":"/year/2005"},{"n":"2004","v":"/year/2004"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"/by/time"},{"n":"人气","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}],
+ "/id/88":[{"key":"class","name":"类型","value":[{"n":"全部类型","v":""},{"n":"偶像","v":"/class/偶像"},{"n":"舞蹈","v":"/class/舞蹈"},{"n":"音乐","v":"/class/音乐"},{"n":"情感","v":"/class/情感"},{"n":"喜剧","v":"/class/喜剧"},{"n":"体育","v":"/class/体育"},{"n":"游戏","v":"/class/游戏"},{"n":"相声","v":"/class/相声"},{"n":"婚恋","v":"/class/婚恋"},{"n":"时尚","v":"/class/时尚"},{"n":"晚会","v":"/class/晚会"},{"n":"明星","v":"/class/明星"},{"n":"访谈","v":"/class/访谈"},{"n":"亲子","v":"/class/亲子"},{"n":"生活","v":"/class/生活"},{"n":"文化","v":"/class/文化"},{"n":"美食","v":"/class/美食"},{"n":"旅游","v":"/class/旅游"},{"n":"益智","v":"/class/益智"},{"n":"其他","v":"/class/其他"}]},{"key":"area","name":"地区","value":[{"n":"全部地区","v":""},{"n":"内地","v":"/area/内地"},{"n":"港台","v":"/area/港台"},{"n":"日韩","v":"/area/日韩"},{"n":"欧美","v":"/area/欧美"}]},{"key":"year","name":"年代","value":[{"n":"全部年代","v":""},{"n":"2025","v":"/year/2025"},{"n":"2024","v":"/year/2024"},{"n":"2023","v":"/year/2023"},{"n":"2022","v":"/year/2022"},{"n":"2021","v":"/year/2021"},{"n":"2020","v":"/year/2020"},{"n":"2019","v":"/year/2019"},{"n":"2018","v":"/year/2018"},{"n":"2017","v":"/year/2017"},{"n":"2016","v":"/year/2016"},{"n":"2015","v":"/year/2015"},{"n":"2014","v":"/year/2014"},{"n":"2013","v":"/year/2013"},{"n":"2012","v":"/year/2012"},{"n":"2011","v":"/year/2011"},{"n":"2010","v":"/year/2010"},{"n":"2009","v":"/year/2009"},{"n":"2008","v":"/year/2008"},{"n":"2007","v":"/year/2007"},{"n":"2006","v":"/year/2006"},{"n":"2005","v":"/year/2005"},{"n":"2004","v":"/year/2004"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"/by/time"},{"n":"人气","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}], "/id/93":[{"key":"class","name":"类型","value":[{"n":"全部类型","v":""},{"n":"玄幻","v":"/class/玄幻"},{"n":"科幻","v":"/class/科幻"},{"n":"武侠","v":"/class/武侠"},{"n":"冒险","v":"/class/冒险"},{"n":"战斗","v":"/class/战斗"},{"n":"搞笑","v":"/class/搞笑"},{"n":"恋爱","v":"/class/恋爱"},{"n":"魔幻","v":"/class/魔幻"},{"n":"竞技","v":"/class/竞技"},{"n":"悬疑","v":"/class/悬疑"},{"n":"日常","v":"/class/日常"},{"n":"校园","v":"/class/校园"},{"n":"真人","v":"/class/真人"},{"n":"推理","v":"/class/推理"},{"n":"历史","v":"/class/历史"},{"n":"经典","v":"/class/经典"},{"n":"其他","v":"/class/其他"}]},{"key":"area","name":"地区","value":[{"n":"全部地区","v":""},{"n":"国产","v":"/area/国产"},{"n":"日本","v":"/area/日本"},{"n":"欧美","v":"/area/欧美"},{"n":"其他","v":"/area/其他"}]},{"key":"year","name":"年代","value":[{"n":"全部年代","v":""},{"n":"2025","v":"/year/2025"},{"n":"2024","v":"/year/2024"},{"n":"2023","v":"/year/2023"},{"n":"2022","v":"/year/2022"},{"n":"2021","v":"/year/2021"},{"n":"2020","v":"/year/2020"},{"n":"2019","v":"/year/2019"},{"n":"2018","v":"/year/2018"},{"n":"2017","v":"/year/2017"},{"n":"2016","v":"/year/2016"},{"n":"2015","v":"/year/2015"},{"n":"2014","v":"/year/2014"},{"n":"2013","v":"/year/2013"},{"n":"2012","v":"/year/2012"},{"n":"2011","v":"/year/2011"},{"n":"2010","v":"/year/2010"},{"n":"2009","v":"/year/2009"},{"n":"2008","v":"/year/2008"},{"n":"2007","v":"/year/2007"},{"n":"2006","v":"/year/2006"},{"n":"2005","v":"/year/2005"},{"n":"2004","v":"/year/2004"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"/by/time"},{"n":"人气","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}],
+ "/id/99":[{"key":"class","name":"类型","value":[{"n":"全部类型","v":""},{"n":"青春","v":"/class/青春"},{"n":"古装","v":"/class/古装"},{"n":"爱情","v":"/class/爱情"},{"n":"都市","v":"/class/都市"},{"n":"喜剧","v":"/class/喜剧"},{"n":"战争","v":"/class/战争"},{"n":"军旅","v":"/class/军旅"},{"n":"谍战","v":"/class/谍战"},{"n":"偶像","v":"/class/偶像"},{"n":"警匪","v":"/class/警匪"},{"n":"冒险","v":"/class/冒险"},{"n":"穿越","v":"/class/穿越"},{"n":"仙侠","v":"/class/仙侠"},{"n":"武侠","v":"/class/武侠"},{"n":"悬疑","v":"/class/悬疑"},{"n":"罪案","v":"/class/罪案"},{"n":"家庭","v":"/class/家庭"},{"n":"历史","v":"/class/历史"},{"n":"年代","v":"/class/年代"},{"n":"农村","v":"/class/农村"},{"n":"其他","v":"/class/其他"}]},{"key":"year","name":"年代","value":[{"n":"全部年代","v":""},{"n":"2025","v":"/year/2025"},{"n":"2024","v":"/year/2024"},{"n":"2023","v":"/year/2023"},{"n":"2022","v":"/year/2022"},{"n":"2021","v":"/year/2021"},{"n":"2020","v":"/year/2020"},{"n":"2019","v":"/year/2019"},{"n":"2018","v":"/year/2018"},{"n":"2017","v":"/year/2017"},{"n":"2016","v":"/year/2016"},{"n":"2015","v":"/year/2015"},{"n":"2014","v":"/year/2014"},{"n":"2013","v":"/year/2013"},{"n":"2012","v":"/year/2012"},{"n":"2011","v":"/year/2011"},{"n":"2010","v":"/year/2010"},{"n":"2009","v":"/year/2009"},{"n":"2008","v":"/year/2008"},{"n":"2007","v":"/year/2007"},{"n":"2006","v":"/year/2006"},{"n":"2005","v":"/year/2005"},{"n":"2004","v":"/year/2004"}]},{"key":"by","name":"排序","value":[{"n":"时间","v":"/by/time"},{"n":"人气","v":"/by/hits"},{"n":"评分","v":"/by/score"}]}],
+ }
+}
diff --git "a/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" "b/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js"
index 27b20df..53cb4fe 100644
--- "a/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js"
+++ "b/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js"
@@ -157,7 +157,7 @@ var rule = {
content_url = `https://fanqienovel.com/reader/${input}?enter_from=reader`;
log(content_url);
let html = (await req(content_url, {headers: {Cookie: getFqCookie()}})).content;
- html = html.match(/window.__INITIAL_STATE__=(.+?});/)[1];
+ html = html.match(/window.__INITIAL_STATE__=(.+?});/)[1].replaceAll(':undefined,', ':"undefined",');
let json = JSON.parse(html).reader.chapterData;
title = json.title;
content = decodeText(json.content, 2);
diff --git "a/js_dr2/\347\272\242\346\236\234\347\237\255\345\211\247.js" "b/js_dr2/\347\272\242\346\236\234\347\237\255\345\211\247.js"
new file mode 100644
index 0000000..73c9b0c
--- /dev/null
+++ "b/js_dr2/\347\272\242\346\236\234\347\237\255\345\211\247.js"
@@ -0,0 +1,28 @@
+var rule = {
+ title: '红果短剧',
+ host: 'https://www.hongguodj.cc/',
+ url: '/show/fyclass--------fypage---.html',
+ searchUrl: '/search/**----------fypage---.html',
+ class_parse: '.nav li;a&&Text;a&&href;.*/(.*?).html',
+ searchable: 2,
+ quickSearch: 0,
+ filterable: 0,
+ headers: {
+ 'User-Agent': 'MOBILE_UA',
+ },
+ play_parse: true,
+ lazy: "js:\n let html = request(input);\n let hconf = html.match(/r player_.*?=(.*?))[1];\n let json = JSON5.parse(hconf);\n let url = json.url;\n if (json.encrypt == '1') {\n url = unescape(url);\n } else if (json.encrypt == '2') {\n url = unescape(base64Decode(url));\n }\n if (/\\.(m3u8|mp4|m4a|mp3)/.test(url)) {\n input = {\n parse: 0,\n jx: 0,\n url: url,\n };\n } else {\n input = url && url.startsWith('http') && tellIsJx(url) ? {parse:0,jx:1,url:url}:input;\n }",
+ limit: 6,
+ double: true,
+ 推荐: '.show&&ul;li;img&&alt;img&&data-src;.bg&&Text;a&&href',
+ 一级: '.list li;img&&alt;img&&data-src;.bg&&Text;a&&href',
+ 二级: {
+ title: 'h2&&Text;.info p:eq(2)&&a&&Text',
+ img: 'img&&src',
+ desc: '.info p:eq(2)&&a&&Text;.info p:eq(3)&&a&&Text;.info p:eq(4)&&a&&Text;.info p:eq(0)&&a&&Text;.info p:eq(1)&&a&&Text',
+ content: '#desc&&Text',
+ tabs: '.play.my-2 .title&&a',
+ lists: '.play-list:eq(#id)&&.rows li',
+ },
+ 搜索: '.show.rows li;img&&alt;img&&data-src;.bg&&Text;a&&href',
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 5f3a151..b38b7fe 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "drpy-node",
- "version": "1.1.22",
+ "version": "1.1.23",
"main": "index.js",
"type": "module",
"scripts": {
diff --git a/public/index.html b/public/index.html
index 9023688..b86b6e7 100644
--- a/public/index.html
+++ b/public/index.html
@@ -8,7 +8,7 @@
drpyS(drpy-node)
-nodejs作为服务端的drpy实现。全面升级异步写法
积极开发中,每日一更,当前进度 48%
找工作中,随缘更新
+nodejs作为服务端的drpy实现。全面升级异步写法
积极开发中,每日一更,当前进度 49%
找工作中,随缘更新
更新记录
+20250310
+更新至V1.1.23
20250227
更新至V1.1.22
20250226
From 344fc95d7464bab7774594954b2c2795cd7762d9 Mon Sep 17 00:00:00 2001
From: Hiram
Date: Thu, 10 Apr 2025 23:21:15 +0800
Subject: [PATCH 3/5] add: browser environment variable
---
libs/drpyS.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libs/drpyS.js b/libs/drpyS.js
index 97cc42e..fd5b1f8 100644
--- a/libs/drpyS.js
+++ b/libs/drpyS.js
@@ -342,6 +342,9 @@ export async function getSandbox(env = {}) {
setInterval,
clearTimeout,
clearInterval,
+ TextEncoder,
+ TextDecoder,
+ performance,
module: {}, // 模块支持
exports: {}, // 模块支持
rule: {}, // 用于存放导出的 rule 对象
From 9abcf02471061118f5bd0b4b30dd73fba9e9afce Mon Sep 17 00:00:00 2001
From: Hiram
Date: Thu, 10 Apr 2025 23:21:47 +0800
Subject: [PATCH 4/5] add: gaze
---
js/gaze.js | 601 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 601 insertions(+)
create mode 100644 js/gaze.js
diff --git a/js/gaze.js b/js/gaze.js
new file mode 100644
index 0000000..404b9fa
--- /dev/null
+++ b/js/gaze.js
@@ -0,0 +1,601 @@
+globalThis.window = globalThis.global = globalThis;
+
+class Go {
+ constructor() {
+ let s = new TextEncoder("utf-8"),
+ i = new TextDecoder("utf-8"),
+ r = new DataView(new ArrayBuffer(8));
+ var o = [];
+
+ this._callbackTimeouts = new Map();
+ this._nextCallbackTimeoutID = 1;
+ let e = () => new DataView(this._inst.exports.m.buffer);
+ let t = (e) => {
+ r.setBigInt64(0, e, !0);
+ let t = r.getFloat64(0, !0);
+ if (0 === t) return;
+ if (!isNaN(t)) return t;
+ let n = 4294967295n & e;
+ return this._values[n];
+ };
+ let n = (n) => {
+ let s = e().getBigUint64(n, !0);
+ return t(s);
+ };
+ let l = (e) => {
+ if ("number" == typeof e)
+ return isNaN(e)
+ ? 2146959360n << 32n
+ : 0 === e
+ ? (2146959360n << 32n) | 1n
+ : (r.setFloat64(0, e, !0), r.getBigInt64(0, !0));
+ switch (e) {
+ case void 0:
+ return 0n;
+ case null:
+ return (2146959360n << 32n) | 2n;
+ case !0:
+ return (2146959360n << 32n) | 3n;
+ case !1:
+ return (2146959360n << 32n) | 4n;
+ }
+ let t = this._ids.get(e);
+ void 0 === t &&
+ (void 0 === (t = this._idPool.pop()) &&
+ (t = BigInt(this._values.length)),
+ (this._values[t] = e),
+ (this._goRefCounts[t] = 0),
+ this._ids.set(e, t)),
+ this._goRefCounts[t]++;
+ let n = 1n;
+ switch (typeof e) {
+ case "string":
+ n = 2n;
+ break;
+ case "symbol":
+ n = 3n;
+ break;
+ case "function":
+ n = 4n;
+ }
+ return t | ((2146959360n | n) << 32n);
+ };
+ let a = (t, n) => {
+ let s = l(n);
+ e().setBigUint64(t, s, !0);
+ };
+ let c = (e, t, n) => new Uint8Array(this._inst.exports.m.buffer, e, t);
+ let $ = (e, t, s) => {
+ let i = Array(t);
+ for (let r = 0; r < t; r++) i[r] = n(e + 8 * r);
+ return i;
+ };
+ let d = (e, t) => i.decode(new DataView(this._inst.exports.m.buffer, e, t));
+ let u = Date.now() - performance.now();
+ this.importObject = {
+ wasi_snapshot_preview1: {
+ fd_write: function (t, n, s, r) {
+ let l = 0;
+ if (1 == t)
+ for (let a = 0; a < s; a++) {
+ let c = n + 8 * a,
+ $ = e().getUint32(c + 0, !0),
+ d = e().getUint32(c + 4, !0);
+ l += d;
+ for (let u = 0; u < d; u++) {
+ let f = e().getUint8($ + u);
+ if (13 == f);
+ else if (10 == f) {
+ let h = i.decode(new Uint8Array(o));
+ (o = []), console.log(h);
+ } else o.push(f);
+ }
+ }
+ else console.error("invalid file descriptor:", t);
+ return e().setUint32(r, l, !0), 0;
+ },
+ fd_close: () => 0,
+ fd_fdstat_get: () => 0,
+ fd_seek: () => 0,
+ proc_exit(e) {
+ if (globalThis.process) process.exit(e);
+ else throw "trying to exit with code " + e;
+ },
+ random_get: (e, t) => (crypto.getRandomValues(c(e, t)), 0),
+ },
+ a: {
+ "runtime.ticks": () => u + performance.now(),
+ "runtime.sleepTicks": (e) => {
+ setTimeout(this._inst.exports.t, e);
+ },
+ d(e) {
+ console.error("d not implemented");
+ },
+ e(e, t) {
+ let n = d(e, t);
+ return l(n);
+ },
+ a(e, n, s) {
+ let i = d(n, s),
+ r = t(e),
+ o = Reflect.get(r, i);
+ return l(o);
+ },
+ f(e, n, s, i) {
+ let r = t(e),
+ o = d(n, s),
+ l = t(i);
+ Reflect.set(r, o, l);
+ },
+ "syscall/js.valueDelete"(e, n, s) {
+ let i = t(e),
+ r = d(n, s);
+ Reflect.deleteProperty(i, r);
+ },
+ i: (e, n) => l(Reflect.get(t(e), n)),
+ fIndex(e, n, s) {
+ Reflect.set(t(e), n, t(s));
+ },
+ j(n, s, i, r, o, l, c) {
+ let u = t(s),
+ f = d(i, r),
+ h = $(o, l, c);
+ try {
+ let g = Reflect.get(u, f);
+ a(n, Reflect.apply(g, u, h)), e().setUint8(n + 8, 1);
+ } catch (p) {
+ a(n, p), e().setUint8(n + 8, 0);
+ }
+ },
+ "syscall/js.valueInvoke"(n, s, i, r, o) {
+ try {
+ let l = t(s),
+ c = $(i, r, o);
+ a(n, Reflect.apply(l, void 0, c)), e().setUint8(n + 8, 1);
+ } catch (d) {
+ a(n, d), e().setUint8(n + 8, 0);
+ }
+ },
+ g(n, s, i, r, o) {
+ let l = t(s),
+ c = $(i, r, o);
+ try {
+ a(n, Reflect.construct(l, c)), e().setUint8(n + 8, 1);
+ } catch (d) {
+ a(n, d), e().setUint8(n + 8, 0);
+ }
+ },
+ h: (e) => t(e).length,
+ b(n, i) {
+ let r = String(t(i)),
+ o = s.encode(r);
+ a(n, o), e().setInt32(n + 8, o.length, !0);
+ },
+ c(e, n, s, i) {
+ let r = t(e);
+ c(n, s, i).set(r);
+ },
+ "syscall/js.valueInstanceOf": (e, n) => t(e) instanceof t(n),
+ k(n, s, i, r, o) {
+ let l = n + 4,
+ a = c(s, i),
+ $ = t(o);
+ if (!($ instanceof Uint8Array || $ instanceof Uint8ClampedArray)) {
+ e().setUint8(l, 0);
+ return;
+ }
+ let d = $.subarray(0, a.length);
+ a.set(d), e().setUint32(n, d.length, !0), e().setUint8(l, 1);
+ },
+ l(n, s, i, r, o) {
+ let l = n + 4,
+ a = t(s),
+ $ = c(i, r);
+ if (!(a instanceof Uint8Array || a instanceof Uint8ClampedArray)) {
+ e().setUint8(l, 0);
+ return;
+ }
+ let d = $.subarray(0, a.length);
+ a.set(d), e().setUint32(n, d.length, !0), e().setUint8(l, 1);
+ },
+ },
+ };
+ this.importObject.env = this.importObject.a;
+ }
+ async run(instance) {
+ this._inst = instance;
+ this._values = [NaN, 0, null, true, false, globalThis, this];
+ this._goRefCounts = [];
+ this._ids = new Map();
+ this._idPool = [];
+ this.exited = false;
+ while (true) {
+ const resumePromise = new Promise((resolve) => {
+ this._resolveCallbackPromise = () => {
+ if (this.exited) {
+ throw new Error("bad callback: Go program has already exited");
+ }
+ setTimeout(resolve, 0);
+ };
+ });
+
+ this._inst.exports.r();
+ if (this.exited) break;
+
+ await resumePromise;
+ }
+ }
+ _resume() {
+ if (this.exited) {
+ throw new Error("Go program has already exited");
+ }
+ this._inst.exports.s();
+ if (this.exited) {
+ this._resolveExitPromise();
+ }
+ }
+ _makeFuncWrapper(funcId) {
+ const self = this;
+ console.log("正在绑定函数id:", funcId);
+ return function () {
+ console.log("执行函数id:", funcId);
+ console.log("函数参数:", Array.from(arguments));
+ const event = {
+ id: funcId,
+ this: this,
+ args: arguments,
+ };
+ self._pendingEvent = event;
+ self._resume();
+ const result = event.result;
+ console.log("函数结果:", result);
+ return result;
+ };
+ }
+}
+
+const decryptor = (() => {
+ let wasmInstance = null;
+ let go = new Go();
+
+ const pedanticAe = function (buffer) {
+ const decompressedSync = zlib.brotliDecompressSync(buffer);
+ return decompressedSync;
+ };
+ const initWASM = async (func) => {
+ const wasmBuffer = await fetchWASM();
+ const { instance } = await WebAssembly.instantiate(
+ wasmBuffer,
+ go.importObject
+ );
+ wasmInstance = instance;
+ go.run(instance);
+ };
+ const fetchWASM = async () => {
+ const response = await axios.get(
+ "https://temp-rs-1257790209.cos.ap-chengdu.myqcloud.com/IceDespair-V2.6.svg",
+ {
+ responseType: "arraybuffer",
+ headers: {
+ "Content-Type": "application/wasm",
+ },
+ }
+ );
+ return pedanticAe(new Uint8Array(response.data));
+ };
+ const parseUrlParams = (url) => {
+ const params = {};
+ const queryString = url.split("?")[1];
+ if (!queryString) return params;
+
+ queryString.split("-").forEach((pair) => {
+ const [key, value] = pair.split("=");
+ if (key && value) params[key] = decodeURIComponent(value);
+ });
+ return params;
+ };
+ const getWasmFunc = (name, mid, key) => {
+ return window[
+ bytesToString(window["DimGive"](name, mid, decodeURIComponent(key)))
+ ];
+ };
+ const decryptDataM3u = async (bytes, sign, mid, key) => {
+ if (!wasmInstance) await initWASM();
+ const result = getWasmFunc("nihilism", mid, key)(
+ bytes,
+ sign,
+ mid,
+ decodeURIComponent(key)
+ );
+ return bytesToString(pedanticAe(result));
+ };
+ const decryptData = async (data, mid, key) => {
+ if (!wasmInstance) await initWASM();
+ const result = getWasmFunc("8069", mid, key)(
+ data,
+ mid,
+ decodeURIComponent(key)
+ );
+ return bytesToString(result);
+ };
+ const decryptStream = async (data, mid, key, url) => {
+ const indexMa = url.split('/').at(-1);
+ if (!indexMa) return url;
+ const index = indexMa[1];
+ const istr = `${index}+gazes_v-@_info`;
+ console.log(istr);
+ const ungzipped = pako.ungzip(data, {
+ to: "string",
+ });
+ const bytes = processBytes(CryptoJS.enc.Base64.parse(ungzipped));
+ const sign = CryptoJS.MD5(
+ `${istr}- are we anti-socialists? against the government? spies? traitor? fresh blood? no, we are just weak, sick bystanders; we just need to rot little by little with formalism until we finally become food for new shoots. `
+ )
+ .toString()
+ .substring(8, 24);
+ return decryptDataM3u(bytes, sign, mid, key);
+ };
+ const processBytes = (base64Data) => {
+ return Uint8Array.from(
+ {
+ length: base64Data.sigBytes,
+ },
+ (_, i) => (base64Data.words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff
+ );
+ };
+ const bytesToString = (byteArray) => {
+ return String.fromCharCode.apply(null, byteArray);
+ };
+ const decryptPlay = async (playUrl, src) => {
+ const params = parseUrlParams(playUrl);
+ const encryptedSrc = src;
+ const decryptedLink = await decryptData(
+ Uint8Array.from(atob(encryptedSrc), (c) => c.charCodeAt(0)),
+ params.mid,
+ params[Object.keys(params).at(-1)]
+ );
+ return decryptedLink;
+ };
+ const decryptM3u8 = async (playUrl, src, decryptedLink) => {
+ const params = parseUrlParams(playUrl);
+ const encryptedSrc = src;
+ const { data } = await axios.get(decryptedLink, {
+ responseType: "arraybuffer",
+ });
+ const m3u8 = await decryptStream(
+ data,
+ params.mid,
+ params[Object.keys(params).at(-1)],
+ decryptedLink
+ );
+ return m3u8;
+ };
+ return {
+ decryptM3u8,
+ decryptPlay,
+ parseUrlParams,
+ };
+})();
+
+var rule = {
+ 类型: "影视",
+ title: "GAZE",
+ desc: "源动力+L佬+秋秋+嗷呜 联合出品",
+ host: "https://gaze.run",
+ url: "/filter_movielist",
+ searchUrl: "/filter_movielist",
+ searchable: 2,
+ quickSearch: 0,
+ timeout: 5000,
+ play_parse: true,
+ filterable: 0,
+ class_name: "电影&剧集&番剧&国漫",
+ class_url: "1&2&bangumi&chinese_cartoon",
+ headers: {
+ "User-Agent": PC_UA,
+ Origin: "https://gaze.run",
+ },
+ 预处理: async () => {
+ await rule.dealHeaders();
+ },
+ 推荐: async function (tid, pg, filter, extend) {
+ const { input, pdfa, pdfh, pd } = this;
+ const html = await request(input);
+ const d = [];
+ const data = pdfa(html, ".row .card");
+ data.forEach((it) => {
+ d.push({
+ title: pdfh(it, ".card-body .card-title&&Text"),
+ pic_url: pdfh(it, ".view img.load-imgs&&data-src"),
+ desc: pdfh(it, ".view .dbadge-box .badge-default&&Text"),
+ url: pdfh(it, ".view a&&href").replace("play/", ""),
+ });
+ });
+ return setResult(d);
+ },
+ 一级: async function (tid, pg, filter, extend) {
+ const { input } = this;
+ const html = await request(input, {
+ method: "POST",
+ headers: {
+ ...this.headers,
+ "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
+ },
+ data: {
+ mform: tid,
+ mcountry: "all",
+ "tag_arr[]": "all",
+ album: "all",
+ years: "all",
+ sort: "updatetime",
+ title: "",
+ page: pg,
+ },
+ });
+ const resp = JSON.parse(html);
+ const d = [];
+ resp.mlist.forEach((it) => {
+ d.push({
+ title: it.title,
+ pic_url: it.cover_img,
+ desc: `${it.grade}|${it.definition}`,
+ url: it.mid,
+ });
+ });
+ return setResult(d);
+ },
+ 二级: async function (ids) {
+ const { input, pdfa, pdfh, pd } = this;
+ const html = await request(`${this.host}/play/${ids[0]}`, {
+ headers: this.headers,
+ });
+ const vod = {
+ vod_id: ids[0],
+ vod_name: pdfh(html, ".row.p-2 img&&alt"),
+ vod_pic: pdfh(html, ".row.p-2 img&&src"),
+ type_name: pdfa(html, ".row.p-2 a")
+ .map((it) => pdfh(it, "a&&Text"))
+ .join("/"),
+ vod_remarks: pdfh(html, ".row.p-2 h5:eq(-1)&&Text"),
+ vod_year: pdfh(html, ".row.p-2 a:eq(-1)&&Text"),
+ vod_area: pdfh(html, ".row.p-2 a:eq(-2)&&Text"),
+ vod_content: pdfh(html, ".row.p-2 p&&Text"),
+ vod_play_from: "源动力偷的线路",
+ vod_play_url: pdfa(html, ".col-md-12&&.sbtn-block")
+ .map(
+ (it) =>
+ `${pdfh(it, "button--i&&Text").trim()}$${ids[0]}|${pdfh(
+ it,
+ "button&&data-src"
+ )}`
+ )
+ .join("#"),
+ };
+ return vod;
+ },
+ 搜索: async function (wd, quick, pg) {
+ const { input } = this;
+ const html = await request(input, {
+ method: "POST",
+ headers: {
+ ...this.headers,
+ "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
+ },
+ data: {
+ mform: "all",
+ mcountry: "all",
+ "tag_arr[]": "all",
+ album: "all",
+ years: "all",
+ sort: "updatetime",
+ title: wd,
+ page: pg,
+ },
+ });
+ const resp = JSON.parse(html);
+ const d = [];
+ resp.mlist.forEach((it) => {
+ d.push({
+ title: it.title,
+ pic_url: it.cover_img,
+ desc: `${it.grade}|${it.definition}`,
+ url: it.mid,
+ });
+ });
+ return setResult(d);
+ },
+ lazy: async function (flag, id, flags) {
+ const { pdfa, pdfh } = this;
+ const [data_id, data_src] = id.split("|");
+ const sourceReqUrl = `${this.host}/play/${data_id}`;
+ console.warn(data_id, data_src);
+ const source = await axios.get(sourceReqUrl, { headers: this.headers });
+ const script = pdfa(source.data, "script");
+ const scriptContent = script.filter((e) =>
+ e.includes("configs-n26.1.js")
+ )[0];
+ const sourceUrl = pdfh(scriptContent, "script&&src");
+ console.warn("sourceUrl", sourceUrl);
+
+ let play = await decryptor.decryptPlay(sourceUrl, data_src);
+
+ if (play.includes("gazes_v-@_info")) {
+ return {
+ parse: 0,
+ url:
+ getProxyUrl() +
+ "&playdata=" +
+ encodeURIComponent(JSON.stringify([sourceUrl, data_src, play])) +
+ "&t=0",
+ };
+ } else {
+ if (play.includes("cloud.189.cn")) {
+ let js_data = decryptor.parseUrlParams(sourceUrl);
+ const thirdKey = Object.keys(js_data)[2];
+
+ try {
+ const re_link = await axios.post(
+ `${this.host}/fetch_189c_murl`,
+ {
+ urls: play,
+ mid: js_data.mid,
+ },
+ {
+ headers: {
+ "Content-Type":
+ "application/x-www-form-urlencoded; charset=UTF-8",
+ Accept: "*/*",
+ Origin: this,
+ [thirdKey]: encodeURIComponent(js_data[thirdKey]),
+ Cookie: source.headers["set-cookie"]
+ .map((it) => it.split(";")[0])
+ .join(";"),
+ },
+ }
+ );
+ console.log("API Response:", re_link.data);
+ play = re_link.data?.url;
+ } catch (error) {
+ console.error("Request Failed:", error);
+ }
+ }
+ return {
+ parse: 0,
+ url: play,
+ };
+ }
+ },
+ proxy_rule: async function (params) {
+ try {
+ const segments = JSON.parse(decodeURIComponent(params.playdata));
+ let [sourceUrl, data_src, play] = segments;
+ console.log(segments);
+
+ let m3u8 = await decryptor.decryptM3u8(sourceUrl, data_src, play);
+ return [200, "text/text", m3u8];
+ } catch (e) {
+ console.log(e);
+ }
+ },
+ dealHeaders: async function () {
+ const resp = await axios.get(`${this.host}/filter`, {
+ headers: this.headers,
+ });
+
+ // cookie 处理
+ const headers = resp.headers;
+ const cookies = headers["set-cookie"];
+ const cookie = cookies.map((item) => item.split(";")[0]).join("; ");
+ this.headers.Cookie = cookie;
+
+ // 请求头处理
+ const html = resp.data;
+ const kv_macth = html.match(/'headers':({[^{}]*})/)[1];
+ const kv_headers = new Function(`return ${kv_macth}`)();
+ for (const key in kv_headers) {
+ this.headers[key] = kv_headers[key];
+ }
+
+ console.warn("headers", this.headers);
+ },
+};
From 1ff018c6eebd2514c25ddd03f902687738396c18 Mon Sep 17 00:00:00 2001
From: Hiram
Date: Thu, 10 Apr 2025 23:58:54 +0800
Subject: [PATCH 5/5] fix: gaze index error
---
js/gaze.js | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/js/gaze.js b/js/gaze.js
index 404b9fa..c210c0e 100644
--- a/js/gaze.js
+++ b/js/gaze.js
@@ -236,10 +236,7 @@ class Go {
}
_makeFuncWrapper(funcId) {
const self = this;
- console.log("正在绑定函数id:", funcId);
return function () {
- console.log("执行函数id:", funcId);
- console.log("函数参数:", Array.from(arguments));
const event = {
id: funcId,
this: this,
@@ -248,7 +245,6 @@ class Go {
self._pendingEvent = event;
self._resume();
const result = event.result;
- console.log("函数结果:", result);
return result;
};
}
@@ -319,11 +315,8 @@ const decryptor = (() => {
return bytesToString(result);
};
const decryptStream = async (data, mid, key, url) => {
- const indexMa = url.split('/').at(-1);
- if (!indexMa) return url;
- const index = indexMa[1];
- const istr = `${index}+gazes_v-@_info`;
- console.log(istr);
+ if (!url.includes("gazes_v-@_info")) return url;
+ const istr = url.split("/").at(-1);
const ungzipped = pako.ungzip(data, {
to: "string",
});
@@ -581,13 +574,11 @@ var rule = {
const resp = await axios.get(`${this.host}/filter`, {
headers: this.headers,
});
-
// cookie 处理
const headers = resp.headers;
const cookies = headers["set-cookie"];
const cookie = cookies.map((item) => item.split(";")[0]).join("; ");
this.headers.Cookie = cookie;
-
// 请求头处理
const html = resp.data;
const kv_macth = html.match(/'headers':({[^{}]*})/)[1];
@@ -595,7 +586,6 @@ var rule = {
for (const key in kv_headers) {
this.headers[key] = kv_headers[key];
}
-
console.warn("headers", this.headers);
},
};