├── .editorconfig ├── .gitignore ├── .npmrc ├── .prettierrc ├── README.md ├── hook-rules └── js-hook.js ├── package.json ├── src ├── CHERWING-CHERWIN_SCRIPTS.js ├── DeathNote.js ├── QLScriptPublic.js ├── ddgyToken.js ├── features │ ├── index.js │ └── m3u8-ts-cache.js ├── huluwa.js ├── imaotai.js ├── index.js ├── jd.js ├── lzwme.js ├── ohhh_QL-Script.js ├── t.js ├── vip │ ├── alipanCrack.js │ ├── baiduCloud.js │ ├── bilibiliHD.js │ ├── index.js │ ├── todo │ │ └── wps.js │ ├── xiaohongshu.js │ ├── ximalaya.js │ ├── xunlei.js │ └── zhihu.js └── youzan-liteapp.js └── whistle-rules ├── ad-block.txt ├── x.json └── zhihu.txt /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 140 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | 4 | # build dist 5 | .nyc_output 6 | *.log 7 | /dist/ 8 | /cjs/ 9 | /esm/ 10 | /release/ 11 | /debug/ 12 | /coverage/ 13 | /docs/ 14 | /tmp 15 | /cache 16 | /logs 17 | 18 | # manager 19 | npm-debug.log 20 | package-lock.json 21 | yarn.lock 22 | yarn-error.log 23 | pnpm-lock.yaml 24 | .pnpm-debug.log 25 | 26 | # config 27 | # .flh.config.js 28 | /env-config.sh 29 | /w2.x-scripts.config.js 30 | /w2.x-scripts.cache.json 31 | /test-* 32 | /local-x-scripts-rules 33 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | 2 | registry="https://registry.npmmirror.com" 3 | 4 | # for pnpm 5 | strict-peer-dependencies=false 6 | shamefully-hoist=true 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "singleQuote": true, 4 | "trailingComma": "es5", 5 | "proseWrap": "preserve", 6 | "semi": true, 7 | "bracketSpacing": true, 8 | "arrowParens": "avoid", 9 | "overrides": [ 10 | { 11 | "files": ".prettierrc", 12 | "options": { 13 | "parser": "json" 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | @lzwme/x-scripts-rules 2 | ======== 3 | 4 | [![node version][node-badge]][node-url] 5 | [![GitHub issues][issues-badge]][issues-url] 6 | [![GitHub forks][forks-badge]][forks-url] 7 | [![GitHub stars][stars-badge]][stars-url] 8 | 9 | 10 | 11 | 基于 [@lzwme/whistle.x-scripts](https://github.com/lzwme/whistle.x-scripts) 插件规范开发的规则脚本库。 12 | 13 | ## 免责说明 14 | 15 | - 本项目提供的内容用于个人对 web 程序逆向的兴趣研究学习,仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关。**请在学习研究完毕24小时内予以删除。** 16 | - 请自行评估使用本项目内容可能产生的安全风险。本人对使用本项目涉及的任何脚本引发的问题概不负责,包括但不限于由脚本错误引起的任何损失或损害。 17 | 18 | ## 快速开始 19 | 20 | ```bash 21 | npm i -g whistle @lzwme/whistle.x-scripts 22 | git clone https://mirror.ghporxy.com/github.com/lzwme/x-scripts-rules.git 23 | w2 ca 24 | w2 proxy 25 | w2 run 26 | ``` 27 | 28 | ## 安装与使用 29 | 30 | 请先了解 [@lzwme/whistle.x-scripts](https://github.com/lzwme/whistle.x-scripts) 项目的功能,并进行基本安装与配置。 31 | 32 | 应先全局安装 `whistle` 和 `@lzwme/whistle.x-scripts`: 33 | 34 | ```bash 35 | npm i -g whistle @lzwme/whistle.x-scripts 36 | ``` 37 | 38 | 然后拉取本仓库代码到本地路径(如:`/Users/lzwme/coding/x-scripts-rules`): 39 | 40 | ```bash 41 | git clone https://github.com/lzwme/x-scripts-rules.git 42 | ``` 43 | 44 | 接着在配置文件 `~/w2.x-scripts.config.js` 中的 `ruleDirs` 字段添加该仓库所在路径即可。示例: 45 | 46 | ```js 47 | module.exports = { 48 | ruleDirs: [ 49 | '/Users/lzwme/coding/x-scripts-rules/', // 按目录:加载全部规则 50 | '/Users/lzwme/coding/x-scripts-rules/src/jd.js', // 按文件:加载部分规则 51 | ], 52 | }; 53 | ``` 54 | 55 | 最后启动 `whistle`: 56 | 57 | ```bash 58 | # 安装根证书 59 | w2 ca 60 | # 开启全局代理模式(关闭: w2 proxy off) 61 | w2 proxy 62 | # 调试模式启动 63 | w2 run 64 | ``` 65 | 66 | ## License 67 | 68 | `@lzwme/x-scripts-rules` is released under the MIT license. 69 | 70 | 该插件由[志文工作室](https://lzw.me)开发和维护。 71 | 72 | 73 | [stars-badge]: https://img.shields.io/github/stars/lzwme/x-scripts-rules.svg 74 | [stars-url]: https://github.com/lzwme/x-scripts-rules/stargazers 75 | [forks-badge]: https://img.shields.io/github/forks/lzwme/x-scripts-rules.svg 76 | [forks-url]: https://github.com/lzwme/x-scripts-rules/network 77 | [issues-badge]: https://img.shields.io/github/issues/lzwme/x-scripts-rules.svg 78 | [issues-url]: https://github.com/lzwme/x-scripts-rules/issues 79 | [npm-badge]: https://img.shields.io/npm/v/@lzwme/x-scripts-rules.svg?style=flat-square 80 | [npm-url]: https://npmjs.org/package/@lzwme/x-scripts-rules 81 | [node-badge]: https://img.shields.io/badge/node.js-%3E=_16.15.0-green.svg?style=flat-square 82 | [node-url]: https://nodejs.org/download/ 83 | [download-badge]: https://img.shields.io/npm/dm/@lzwme/x-scripts-rules.svg?style=flat-square 84 | [download-url]: https://npmjs.org/package/@lzwme/x-scripts-rules 85 | [bundlephobia-url]: https://bundlephobia.com/result?p=@lzwme/x-scripts-rules@latest 86 | [bundlephobia-badge]: https://badgen.net/bundlephobia/minzip/@lzwme/x-scripts-rules@latest 87 | -------------------------------------------------------------------------------- /hook-rules/js-hook.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-03-17 14:12:30 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-03-17 15:17:13 6 | * @Description: 7 | */ 8 | 9 | // process.env.JS_HOOK_URL = 'qhres2.com,aigc.360.com,www.sou.com,qhimg.com'; 10 | 11 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 12 | module.exports = [ 13 | { 14 | disabled: !process.env.JS_HOOK_URL, 15 | on: 'res-body', 16 | ruleId: 'js-hook', 17 | desc: 'js-hook', 18 | method: '*', 19 | // mitm: 'game.xiaojukeji.com', 20 | url: process.env.JS_HOOK_URL?.split(','), 21 | handler({ resBody, headers, resHeaders, X, url }) { 22 | if (!resBody) return; 23 | 24 | const type = headers['content-type'] || ''; 25 | const rtype = resHeaders['content-type'] || ''; 26 | 27 | const isHtml = type.includes('html') || rtype.includes('html'); 28 | const isJs = type.includes('javascript') || rtype.includes('javascript') || url.includes('.js'); 29 | 30 | if (isHtml || isJs) { 31 | if (Buffer.isBuffer(resBody)) resBody = resBody.toString('utf8'); 32 | let hookCode = Object.values(jsHookList).join('\n'); 33 | if (isHtml) hookCode = ``; 34 | console.log('hook injected', X.FeUtils.color.gray(url)); 35 | if (resBody.includes('')) resBody = resBody.replace('', `\n${hookCode}`); 36 | else resBody = `${resBody}\n${hookCode}`; 37 | 38 | return { body: resBody }; 39 | } 40 | }, 41 | }, 42 | ]; 43 | 44 | const jsHookList = { 45 | json: `(function () { 46 | var my_stringify = JSON.stringify; 47 | JSON.stringify = function (params) { 48 | console.log('HOOK stringify', params); 49 | debugger; 50 | return my_stringify(params); 51 | }; 52 | var my_parse = JSON.parse; 53 | JSON.parse = function (params) { 54 | console.log('HOOK parse', params); 55 | debugger; 56 | return my_parse(params); 57 | }; 58 | })();`, 59 | cookie: `(function () { 60 | 'use strict'; 61 | let cookie_cache = ''; 62 | Object.defineProperty(document, 'cookie', { 63 | get: function () { 64 | //debugger; 65 | return cookie_cache; 66 | }, 67 | set: function (value) { 68 | console.log('Set cookie', value); 69 | debugger; 70 | cookie_cache = value; 71 | return value; 72 | }, 73 | }); 74 | })();`, 75 | searchDecode: `(function () { 76 | setTimeout(function () { 77 | for (var p in window) { 78 | var s = p.toLowerCase(); 79 | if (s.indexOf('encode') != -1 || s.indexOf('encry') != -1) { 80 | console.log('encode function.', window[p]); 81 | debugger; 82 | } 83 | if (s.indexOf('decode') != -1 || s.indexOf('decry') != -1) { 84 | console.log('decode function.', window[p]); 85 | debugger; 86 | } 87 | } 88 | }, 3000); 89 | })();`, 90 | debuggerFunc: `(() => { 91 | Function.prototype.__constructor = Function.prototype.constructor; 92 | Function.prototype.constructor = function() { 93 | if(arguments && typeof arguments[0]==='string') { 94 | if ("debugger"===arguments[0]) { 95 | console.trace('[Function]debugger 拦截'); 96 | return () => () => {}; 97 | } 98 | return Function.prototype.__constructor.apply(this,arguments); 99 | } 100 | } 101 | })();`, 102 | debuggerSetInterval: `(function() { 103 | globalThis._setInterval_ = globalThis.setInterval; 104 | globalThis.setInterval = function(a,b) { 105 | if (a.includes("debugger")) { 106 | console.trace('[setInterval] debugger 拦截') 107 | } else { 108 | return globalThis._setInterval_(a,b); 109 | } 110 | } 111 | });`, 112 | eval: `(function () { 113 | if (window.__cr_eval) return; 114 | window.__cr_eval = window.eval; 115 | var myeval = function (src) { 116 | console.log('==== eval begin: length=' + src.length + ',caller=' + (myeval.caller && myeval.caller.name) + ' ===='); 117 | console.log(src); 118 | console.log('==== eval end ===='); 119 | return window.__cr_eval(src); 120 | }; 121 | var _myeval = myeval.bind(null); 122 | _myeval.toString = window.__cr_eval.toString; 123 | Object.defineProperty(window, 'eval', { value: _myeval }); 124 | console.log('>>>> eval injected: ' + document.location + ' <<<<'); 125 | })();` 126 | }; 127 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "x-scripts-rules", 3 | "version": "1.0.0", 4 | "description": "基于 @lzwme/whistle.x-scripts 插件规范开发的规则脚本库", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@lzwme/whistle.x-scripts": "^0.0.5" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/CHERWING-CHERWIN_SCRIPTS.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 用于临时测试的一些例子 3 | * @type {import('@lzwme/whistle.x-scripts').RuleItem[]} 4 | */ 5 | module.exports = [ 6 | { 7 | on: 'req-header', 8 | ruleId: 'LSXDS', 9 | desc: '乐事心动社-小程序', 10 | url: 'https://campuscrm.pepsico.com.cn/web/**/*memberId=*', 11 | method: 'get', 12 | getCacheUid: ({ headers, X, url }) => { 13 | if (headers.authorization) { 14 | const q = X.FeUtils.getUrlParams(url); 15 | return { uid: q.memberId }; 16 | } 17 | }, 18 | handler: ({ cacheData: D }) => ({ 19 | envConfig: { value: D.map(d => `${d.headers.authorization.replace(/bearer /i, '')}@UID_${d.uid}`).join('&'), sep: '&' }, 20 | }), 21 | updateEnvValue: /@UID_(\d+)/, 22 | }, 23 | { 24 | on: 'res-body', 25 | ruleId: 'TBHYZX', 26 | desc: '特步会员中心-小程序', 27 | url: 'https://wxa-tp.ezrpro.com/myvip/Base/User/WxAppOnLoginNew', 28 | getCacheUid: ({ resBody: B }) => { 29 | if (B?.Result?.Fields) { 30 | const uid = B.Result.VipId; 31 | return { uid, data: `${B.Result.Fields}@UID_${uid}` }; 32 | } 33 | }, 34 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('&'), sep: '&' } }), 35 | updateEnvValue: /@UID_(\d+)/, 36 | }, 37 | { 38 | on: 'res-body', 39 | ruleId: 'AMX', 40 | desc: '安慕希-小程序', 41 | url: 'https://wx-amxshop.msxapi.digitalyili.com/api/user/getUser', 42 | method: 'get', 43 | getCacheUid: ({ headers, resBody: B }) => { 44 | if (headers.accesstoken) { 45 | const uid = B?.data?.user?.id; 46 | return { uid, data: `${headers.accesstoken}@UID_${uid}` }; 47 | } 48 | }, 49 | handler: ({ cacheData: D }) => ({ 50 | envConfig: { value: D.map(v => v.data).join('&'), sep: '&' }, 51 | }), 52 | updateEnvValue: /@UID_(\d+)/, 53 | }, 54 | ]; 55 | -------------------------------------------------------------------------------- /src/DeathNote.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-19 19:23:02 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-07-25 22:36:03 6 | * @Description: https://github.com/leafTheFish/DeathNote 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | { 12 | on: 'req-header', 13 | ruleId: 'meituanCookie', 14 | desc: '美团V3', 15 | method: 'POST', 16 | url: 'https://*.meituan.com*', 17 | // url: 'https://msp.meituan.com/api/**', 18 | getCacheUid: ({ cookieObj }) => ({ uid: cookieObj.userId || '_', data: `${cookieObj.token}#${cookieObj.uuid}` }), 19 | handler: ({ cacheData }) => ({ envConfig: { value: cacheData.map(d => d.data).join('\n') } }), 20 | }, 21 | { 22 | on: 'req-header', 23 | ruleId: 'TxStockCookie', 24 | desc: '腾讯自选股-单账号', 25 | tip: '先打开微信公众号,进福利中心,再打开APP,进个人中心', 26 | url: 'https://*.tenpay.com/cgi-bin/**', 27 | method: '*', 28 | data: {}, 29 | handler({ url, cookieObj, X }) { 30 | const obj = Object.assign(X.FeUtils.getUrlParams(url), cookieObj); 31 | const keys = ['openid', 'fskey', 'wzq_qlskey', 'wzq_qluin']; 32 | keys.forEach(key => { 33 | if (obj[key]) { 34 | if (!this.data[key]) console.log(`【腾讯自选股】已获取${key}: ${obj[key]}`); 35 | this.data[key] = obj[key]; 36 | } 37 | }); 38 | // console.log(obj, this.data); 39 | if (keys.every(key => this.data[key])) return { envConfig: { value: keys.map(key => `${key}=${this.data[key]}`).join('&') } }; 40 | }, 41 | }, 42 | { 43 | on: 'req-header', 44 | ruleId: 'elmCookie', 45 | desc: '饿了么', 46 | url: 'https://*.ele.me/h5/**', 47 | getCacheUid: ({ cookieObj: ck }) => ({ uid: ck.user_id, data: `SID=${ck.SID};cookie2=${ck.cookie2};grabCoupon=1` }), 48 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 49 | }, 50 | { 51 | on: 'req-header', 52 | ruleId: 'sfsyUrl', 53 | desc: '顺丰速运', 54 | method: 'get', 55 | url: 'https://mcs-mimp-web.sf-express.com/mcs-mimp/share/weChat/shareGiftReceiveRedirect?**', 56 | getCacheUid({ url, X }) { 57 | const p = X.FeUtils.getUrlParams(url); 58 | return { uid: p.mobile, data: url }; 59 | }, 60 | 61 | handler: ({ cacheData: D }) => { 62 | const value = D.map(d => d.data).join('\n'); 63 | return { 64 | envConfig: [ 65 | { value, ruleId: 'SFSY' }, 66 | { value, ruleId: 'sfsyUrl' }, 67 | ], 68 | }; 69 | }, 70 | }, 71 | { 72 | on: 'req-header', 73 | ruleId: 'xclxCookie', 74 | desc: '携程旅行', 75 | url: 'https://*m.ctrip.com/restapi/**', 76 | getCacheUid({ cookieObj: C }) { 77 | if (C.cticket) return { uid: C.login_uid, data: C.cticket }; 78 | }, 79 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 80 | }, 81 | { 82 | on: 'res-body', 83 | ruleId: 'tyqhCookie', 84 | desc: '统一茄皇三期', // 微信小程序: 统一快乐星球 -> 活动 -> 统一茄皇三期,点进页面即可 85 | url: 'https://qiehuang-apig.xiaoyisz.com/qiehuangsecond/ga/**', 86 | method: '*', 87 | cache: { 88 | tmp: {}, // 临时缓存,获取到 userId 后合并 89 | }, 90 | getCacheUid({ reqBody, resBody }) { 91 | if (reqBody?.thirdId && reqBody.wid) this.cache = reqBody; 92 | 93 | if (resBody?.data?.userId && this.cache.thirdId) { 94 | const D = this.cache; 95 | this.cache = {}; 96 | return { uid: resBody.data.userId, data: `${D.thirdId}#${D.wid}#${resBody.data.userId}` }; 97 | } 98 | }, 99 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 100 | updateEnvValue: /#(\d+)$/, 101 | }, 102 | { 103 | on: 'res-body', 104 | ruleId: 'bwcjCookie', 105 | desc: '霸王茶姬小程序签到', 106 | url: 'https://webapi*.qmai.cn/web/seller/oauth/flash-sale-login', 107 | method: 'post', 108 | getCacheUid: ({ resBody }) => { 109 | const uid = resBody?.data?.user?.id; 110 | if (uid) return { uid, data: `${resBody.data.token}` }; // #${uid} 111 | }, 112 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 113 | }, 114 | { 115 | on: 'res-body', 116 | ruleId: 'blackJSON', 117 | desc: '全球购骑士特权签到', 118 | url: 'https://{vip-member,pyp-api}.chuxingyouhui.com/{api,vip-member}/**', 119 | method: 'get', 120 | getCacheUid: ({ resBody, headers: H }) => { 121 | const uid = resBody?.data?.userId || resBody?.data?.userPointsResp?.userId; 122 | if (uid && H['black-token']) { 123 | const data = { 'black-token': H['black-token'], token: H.token, 'User-Agent': H['user-agent'], userId: uid }; 124 | return { uid, data: JSON.stringify(data) }; 125 | } 126 | }, 127 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 128 | updateEnvValue: /"userId":(\d+)/, 129 | }, 130 | { 131 | on: 'res-body', 132 | ruleId: 'jlzx', 133 | desc: '江铃智行小程序签到', 134 | url: 'https://superapp.jmc.com.cn/jmc-zx-app-owner/v1/user/userCenter', 135 | method: 'get', 136 | getCacheUid: ({ resBody: B, headers: H }) => ({ uid: B?.data.nickName, data: H['access-token'] }), 137 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 138 | }, 139 | { 140 | on: 'req-header', 141 | ruleId: 'paopaomate', 142 | desc: '微信小程序泡泡玛特', 143 | method: 'get', 144 | url: 'https://popvip.paquapp.com/miniapp/v2/wechat/getUserInfo/?user_id=*', 145 | getCacheUid({ url, X, headers }) { 146 | const p = X.FeUtils.getUrlParams(url); 147 | const uid = p.user_id; 148 | const openid = headers.identity_code || p.openid; 149 | if (uid && openid) return { uid, data: `${uid}#${openid}` }; 150 | }, 151 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 152 | }, 153 | { 154 | on: 'req-header', 155 | ruleId: 'hqcsh', 156 | desc: '好奇车生活-微信小程序', 157 | method: '*', 158 | url: 'https://channel.cheryfs.cn/archer/activity-api/**', 159 | getCacheUid: ({ headers }) => headers.accountid, 160 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.uid).join('\n') } }), 161 | }, 162 | { 163 | on: 'req-header', 164 | ruleId: 'fenxiang', 165 | desc: '粉象生活App', 166 | url: 'https://*api.fenxianglife.com/**', 167 | getCacheUid: ({ headers: H }) => ({ uid: H.finger, data: `${H.did}#${H.finger}#${H.token}#${H.oaid || ''}` }), 168 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 169 | }, 170 | { 171 | on: 'req-header', 172 | ruleId: 'lenovoAccessToken', 173 | desc: '联想App', 174 | url: 'https://mmembership.lenovo.com.cn/member*/**', 175 | getCacheUid: ({ headers: H, url }) => { 176 | // console.log(H.lenovoid, url, H.accesstoken); 177 | return { uid: H.lenovoid, data: `${H.accesstoken}#${H.lenovoid}` }; 178 | }, 179 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 180 | updateEnvValue: /#(\d+)$/i, 181 | }, 182 | ]; 183 | -------------------------------------------------------------------------------- /src/QLScriptPublic.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 2 | module.exports = [ 3 | { 4 | on: 'req-header', 5 | ruleId: 'hdl_data', 6 | method: '**', 7 | url: 'https://superapp-public.kiwa-tech.com/activity/wxapp/**', 8 | desc: '海底捞小程序签到 token', 9 | // getCacheUid: () => 'hdl', 10 | handler({ headers }) { 11 | // console.log('hdl', headers); 12 | if (headers['_haidilao_app_token']) { 13 | return { envConfig: { name: this.ruleId, value: headers['_haidilao_app_token'] } }; 14 | } 15 | }, 16 | }, 17 | { 18 | on: 'res-body', 19 | ruleId: 'mxbc_data', 20 | desc: '蜜雪冰城小程序 Access-Token', 21 | method: 'get', 22 | url: 'https://mxsa.mxbc.net/api/v1/customer/info*', 23 | getCacheUid: ({ resBody }) => resBody?.data?.customerId, 24 | handler({ allCacheData }) { 25 | const value = allCacheData.map(d => d.headers['access-token']).join('@'); 26 | if (value) return { envConfig: { name: this.ruleId, value } }; 27 | }, 28 | }, 29 | { 30 | on: 'req-header', 31 | ruleId: 'zbsxcx', 32 | desc: '植白说小程序 x-dts-token', 33 | method: 'get', 34 | url: 'https://www.kozbs.com/demo/wx/**/*?userId=**', 35 | getCacheUid: ({ url }) => /userId=(\d{5,})/.exec(url)?.[1], 36 | handler({ allCacheData }) { 37 | const value = allCacheData.map(d => d.headers['x-dts-token']).join('&'); 38 | if (value) return { envConfig: { name: this.ruleId, value } }; 39 | }, 40 | }, 41 | { 42 | on: 'res-body', 43 | ruleId: 'ylnn', 44 | desc: '伊利牛奶小程序', 45 | method: '*', 46 | url: 'https://msmarket.msx.digitalyili.com/gateway/api/auth/account/**', 47 | getCacheUid: ({ resBody, headers: H }) => { 48 | const uid = resBody?.data?.userId || resBody?.data?.userInfo?.userId; 49 | if (uid && H['access-token']) return uid; 50 | }, 51 | handler({ cacheData: C }) { 52 | const value = C.map(d => d.headers['access-token']).join('\n'); 53 | if (value) 54 | return { 55 | envConfig: [ 56 | { name: this.ruleId, value }, 57 | { name: 'YLXL', value: C.map(d => d.headers['access-token']).join('&'), sep: '&' }, // 伊利系列小程序 58 | ], 59 | }; 60 | }, 61 | }, 62 | { 63 | on: 'res-body', 64 | ruleId: 'lbvip', 65 | desc: '立白小白白会员俱乐部', 66 | method: 'get', 67 | url: 'https://clubwx.hm.liby.com.cn/b2cMiniApi/me/getUserData.htm', 68 | getCacheUid: ({ resBody }) => resBody?.data?.userName, 69 | handler({ allCacheData }) { 70 | const value = allCacheData.map(d => `${d.headers['unionid']}#${d.headers['x-wxde54fd27cb59db51-token']}`).join('\n'); 71 | if (value) return { envConfig: { name: this.ruleId, value } }; 72 | }, 73 | }, 74 | { 75 | on: 'req-header', 76 | ruleId: 'ddsy_songyao', 77 | desc: '叮当快药APP', 78 | method: 'get', 79 | url: 'https://xapi.ddky.com/mcp/weixin/rest.htm?sign=*', 80 | getCacheUid: ({ url, X }) => { 81 | const query = X.FeUtils.getUrlParams(url); 82 | return query.loginToken && query.userId ? { uid: query.userId, data: `${query.loginToken}&${query.userId}&${query.uDate}` } : ''; 83 | }, 84 | handler({ allCacheData }) { 85 | const value = allCacheData.map(d => d.data).join('@'); 86 | if (value) return { envConfig: { name: this.ruleId, value } }; 87 | }, 88 | }, 89 | { 90 | on: 'res-body', 91 | ruleId: 'jsbaxfls', 92 | desc: '杰士邦安心福利社', 93 | method: 'get', 94 | url: 'https://xh-vip-api.a-touchin.com/mp/user/info', 95 | getCacheUid: ({ resBody, headers }) => { 96 | const uid = resBody?.data?.userInfo?.user_id; 97 | if (uid) return { uid, data: `${headers['access-token']}##${uid}` }; 98 | }, 99 | handler({ allCacheData: D }) { 100 | return { envConfig: { value: D.map(d => d.data).join('\n') } }; 101 | }, 102 | }, 103 | { 104 | on: 'res-body', 105 | ruleId: 'hrjmwshg', 106 | desc: '好人家美味生活馆', 107 | method: 'post', 108 | url: 'https://xapi.weimob.com/api3/onecrm/user/center/usercenter/queryUserHeadElement', 109 | getCacheUid: ({ resBody }) => resBody?.data?.nickname, 110 | handler({ allCacheData }) { 111 | const value = allCacheData.map(d => d.headers['x-wx-token']).join('&'); 112 | if (value) return { envConfig: { name: this.ruleId, value } }; 113 | }, 114 | }, 115 | { 116 | on: 'req-body', 117 | ruleId: 'hxek', 118 | desc: '鸿星尔克签到', 119 | url: 'https://bury.demogic.com/api-bury-point/bury-point', 120 | getCacheUid: ({ reqBody, headers, req }) => { 121 | if (typeof reqBody?.userInfo === 'string') { 122 | const userInfo = JSON.parse(reqBody.userInfo); 123 | return { uid: userInfo.phoneNumber, data: userInfo.memberId }; 124 | } 125 | }, 126 | handler({ allCacheData }) { 127 | const value = allCacheData.map(d => d.data).join('@'); 128 | if (value) return { envConfig: { name: this.ruleId, value } }; 129 | }, 130 | }, 131 | { 132 | disabled: false, 133 | on: 'req-header', 134 | ruleId: 'wx_xlxyh', 135 | desc: '微信小程序_骁龙骁友会', 136 | url: 'https://qualcomm.growthideadata.com/qualcomm-app/**', 137 | getCacheUid: ({ headers }) => { 138 | return { uid: headers.userid, data: `${headers.sessionkey}#${headers.userid}` }; 139 | }, 140 | handler({ allCacheData }) { 141 | const value = allCacheData.map(d => d.data).join('&'); 142 | if (value) return { envConfig: { name: this.ruleId, value } }; 143 | }, 144 | }, 145 | { 146 | on: 'res-body', 147 | ruleId: 'ljfsjlbCookie', 148 | desc: '微信小程序_罗技粉丝俱乐部', 149 | url: 'https://api.wincheers.net/api/services/app/crmAccount/GetLGFanBuyerCenter', 150 | getCacheUid: ({ resBody, headers }) => { 151 | return { uid: resBody?.result?.buyerId, data: headers['authorization']?.replace('Bearer ', '') }; 152 | }, 153 | handler({ allCacheData }) { 154 | const value = allCacheData.map(d => d.data).join('&'); 155 | if (value) return { envConfig: { name: this.ruleId, value } }; 156 | }, 157 | }, 158 | { 159 | on: 'req-body', 160 | ruleId: 'ksd', 161 | desc: '卡萨帝-小程序', 162 | method: 'post', 163 | url: 'https://yx.jsh.com/customer/api/activityCenter/recordLog', 164 | getCacheUid: ({ reqBody, headers }) => ({ uid: reqBody?.userId, data: `${headers.authorization}#${reqBody.openId}` }), 165 | handler({ allCacheData }) { 166 | return { envConfig: { name: this.ruleId, value: allCacheData.map(d => d.data).join('&') } }; 167 | }, 168 | }, 169 | { 170 | on: 'req-header', 171 | ruleId: 'smart_car_plus', 172 | desc: 'smart汽车+-小程序,签到抽盲盒', 173 | url: 'https://app-api.smart.cn/**', 174 | getCacheUid: ({ headers }) => ({ uid: headers['x-user-id'], data: headers['id-token'] }), 175 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('&') } }), 176 | }, 177 | { 178 | on: 'req-header', 179 | ruleId: 'wx_gjjkpro_data', 180 | desc: '高济健康pro小程序签到', 181 | method: 'get', 182 | url: 'https://api.gaojihealth.cn/fund/api/**/*userId=*', 183 | getCacheUid: ({ headers, url }) => { 184 | const userId = /userId=(\d{10,})/.exec(url)?.[1]; 185 | if (userId) return { uid: userId, data: `${userId}&${headers['authorization']}` }; 186 | }, 187 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('\n') } }), 188 | }, 189 | { 190 | on: 'req-header', 191 | ruleId: 'gacmotorToken', 192 | desc: '广汽传祺 - 单账号', 193 | method: 'get', 194 | url: 'https://next.gacmotor.com/mall/**', 195 | getCacheUid: () => 'gacmotorToken', 196 | handler({ headers }) { 197 | if (headers.token) return { envConfig: { value: headers.token } }; 198 | }, 199 | }, 200 | { 201 | on: 'res-body', 202 | ruleId: 'nzqc', 203 | desc: '哪吒汽车_微信小程序_refresh_token', 204 | url: 'https://www.hozonauto.com/{user/miniProgramLoginNew,api_lottery/user_login}', 205 | getCacheUid: ({ resBody }) => { 206 | if (!resBody) return; 207 | const info = resBody.data?.info || resBody.data; 208 | if (info) return { uid: info.uuid, data: info.refresh_token }; 209 | }, 210 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('\n') } }), 211 | }, 212 | { 213 | on: 'res-body', 214 | ruleId: 'ruilanCar', 215 | desc: '睿蓝汽车_小程序_aid#rid', 216 | method: 'get', 217 | url: 'https://api-gateway.livanauto.com/app/v1.0/clientapi//common/user/info', 218 | getCacheUid: ({ resBody, headers }) => ({ uid: resBody?.data?.userId, data: `${headers.aid}#${headers.rid}` }), 219 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('\n') } }), 220 | }, 221 | { 222 | on: 'res-body', 223 | ruleId: 'leidaCarCookie', 224 | desc: '雷达汽车_小程序_aid#rid', 225 | method: 'get', 226 | url: 'https://mp.radar-ev.com/clientapi/{common/user/info,radaruser/api/user/home}', 227 | getCacheUid: ({ resBody, headers }) => ({ uid: resBody?.data?.userId, data: `${headers.rid}#${headers.rid}#${resBody?.data?.userId}` }), 228 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('\n') } }), 229 | }, 230 | { 231 | on: 'res-body', 232 | ruleId: 'kyqc', 233 | desc: '凯翼汽车_小程序', 234 | method: 'get', 235 | url: 'https://fdt-gateway-prod.dm.newcowin.com/customer/community-vip-user/exterior/user/getMe', 236 | getCacheUid: ({ resBody, headers }) => ({ uid: resBody?.data?.id, data: `${headers.devicesn}@@@${headers.cookie}` }), 237 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('\n') } }), 238 | }, 239 | { 240 | on: 'res-body', 241 | ruleId: 'xinxi', 242 | desc: '心喜_小程序', 243 | method: 'get', 244 | url: 'https://api.xinc818.com/mini/user', 245 | getCacheUid: ({ resBody, headers }) => ({ uid: resBody?.data?.id, data: `${headers.sso}##${resBody?.data?.id}` }), 246 | handler: ({ allCacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 247 | }, 248 | { 249 | on: 'req-body', 250 | ruleId: 'didi', 251 | desc: '滴滴领券&果园 - 单账号', 252 | method: 'POST', 253 | url: 'https://api.didi.cn/**', 254 | getCacheUid: () => 'lzwme', 255 | handler({ reqBody }) { 256 | if (reqBody?.token) return { envConfig: { value: reqBody.token + '#3' } }; 257 | }, 258 | }, 259 | { 260 | on: 'req-header', 261 | ruleId: 'heyeHealth', 262 | desc: '荷叶健康小程序-果园[免费领水果]', 263 | url: 'https://tuan.api.ybm100.com/miniapp/my/accountInfo', 264 | getCacheUid: ({ headers }) => ({ uid: headers.userid, data: `${headers.token}##${headers.userid}` }), 265 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('\n') } }), 266 | }, 267 | { 268 | on: 'req-header', 269 | ruleId: 'yyq_new', 270 | desc: '悦野圈-小程序', 271 | url: 'https://customer.yueyequan.cn/**', 272 | method: 'GET', 273 | getCacheUid: ({ cookieObj: C }) => ({ uid: C.userid, data: `${C.usersig}#${C.userid}` }), 274 | handler: ({ allCacheData }) => ({ envConfig: { value: allCacheData.map(d => d.data).join('\n') } }), 275 | updateEnvValue: /#(\d+)/, 276 | }, 277 | { 278 | on: 'res-body', 279 | ruleId: 'yuepaiToken', 280 | desc: '悦拜APP_小程序/app', 281 | method: 'POST', 282 | url: 'https://app.yuebuy.cn/api/user/{UserCenter,getUserInfo}', 283 | getCacheUid: ({ headers, resBody, url }) => { 284 | const uid = resBody?.data?.id || resBody?.data?.user?.id; 285 | if (uid) return { uid, data: `${resBody.data.token || resBody.data.user?.token || headers['x-auth-token']}##${uid}` }; 286 | }, 287 | handler: ({ allCacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 288 | }, 289 | { 290 | on: 'res-body', 291 | ruleId: 'hlToken', 292 | desc: '哈啰签到', 293 | method: 'POST', 294 | url: 'https://*.hellobike.com/api?*', 295 | getCacheUid: ({ resBody, reqBody, url }) => { 296 | try { 297 | const uid = findKeyValue(resBody, 'userNewId'); 298 | if (uid) { 299 | console.log('uid', uid, url); 300 | return { uid, data: `${reqBody.token}##${uid}` }; 301 | } 302 | } catch (e) { 303 | console.log(e); 304 | } 305 | }, 306 | handler: ({ allCacheData: D }) => ({ envConfig: { value: D.map(v => v.data).join('\n') } }), 307 | }, 308 | { 309 | on: 'req-header', 310 | ruleId: 'dewuSK', 311 | desc: '得物-心愿森林-单用户', 312 | method: 'POST', 313 | url: 'https://app.dewu.com/**', 314 | getCacheUid: ({ headers: H, cookieObj: C }) => { 315 | const dutoken = C.duToken || H.dutoken || H.cookietoken; 316 | if (dutoken) { 317 | // && H.sk 318 | const uid = dutoken.split('|')[1]; 319 | if (uid) { 320 | return { uid, data: `${H['x-auth-token'].replace(/Bearer /, '')}#${dutoken}` }; 321 | } 322 | } 323 | }, 324 | handler: ({ url, headers: H, allCacheData: D }) => { 325 | const ua = H['user-agent']; 326 | if (ua?.includes('Mozilla')) 327 | return { 328 | envConfig: [ 329 | { name: 'dewuCK', value: D.map(d => d.data).join('\n') }, 330 | { name: 'dewuSK', value: H.sk }, 331 | { name: 'dewuUA', value: ua }, 332 | ], 333 | }; 334 | }, 335 | }, 336 | { 337 | on: 'req-header', 338 | ruleId: 'tpyzkj', 339 | desc: '太平洋科技app签到', 340 | url: 'https://pccoin.pconline.com.cn/*/*', 341 | method: '*', 342 | getCacheUid: ({ headers: H, cookieObj: C }) => { 343 | if (!H.uid || !C.common_session_id) return; 344 | return { 345 | uid: H.uid, 346 | data: `${H.uid}#${H.appsession}#${H.cookie}#${H.version}#${H['pc-agent']}#${H.channel}#${H['user-agent']}`, 347 | }; 348 | }, 349 | handler: ({ allCacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 350 | }, 351 | { 352 | on: 'req-header', 353 | ruleId: 'bnmdhg', 354 | desc: '巴奴毛肚火锅小程序签到', 355 | url: 'https://cloud.banu.cn/api/member/*?member_id=*', 356 | method: 'GET', 357 | getCacheUid: ({ url, X }) => { 358 | const query = X.FeUtils.getUrlParams('?' + url.split('?')[1]); 359 | return { 360 | uid: query.member_id, 361 | data: query.member_id, 362 | }; 363 | }, 364 | handler: ({ allCacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 365 | }, 366 | { 367 | on: 'res-body', 368 | ruleId: 'qfxhd', // 请求头的x-ds-key&返回报文体中的id 369 | desc: '起飞线生活小程序', 370 | url: 'https://cluster.qifeixian.com/api/user/v1/center/info', 371 | getCacheUid: ({ resBody, headers }) => ({ uid: resBody?.data?.id, data: `${headers['x-ds-key']}&${resBody?.data?.id}` }), 372 | handler: ({ allCacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 373 | }, 374 | { 375 | on: 'req-header', 376 | ruleId: 'wx_midea', 377 | desc: '美的会员', 378 | url: 'https://mvip.midea.cn/next/*/*', 379 | method: 'GET', 380 | getCacheUid: ({ cookieObj }) => cookieObj.uid, 381 | handler: ({ allCacheData: D }) => ({ envConfig: { value: D.map(d => d.headers.cookie).join('\n') } }), 382 | }, 383 | ]; 384 | 385 | function findKeyValue(obj, key) { 386 | let val; 387 | 388 | try { 389 | if (!obj || !key || typeof obj !== 'object') return; 390 | 391 | if (Buffer.isBuffer(obj)) obj = JSON.parse(obj.toString()); 392 | 393 | if (Array.isArray(obj)) { 394 | for (const o of obj) { 395 | val = findKeyValue(o, key); 396 | if (val != null) break; 397 | } 398 | 399 | return val; 400 | } 401 | 402 | if (key in obj) return obj[key]; 403 | 404 | for (let k in obj) { 405 | val = findKeyValue(obj[k], key); 406 | if (val != null) return val; 407 | } 408 | } catch (e) { 409 | console.log('[findKeyValue][error]', e); 410 | } 411 | 412 | return val; 413 | } 414 | -------------------------------------------------------------------------------- /src/ddgyToken.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-06 11:25:49 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-02-23 11:52:29 6 | * @Description: 7 | */ 8 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 9 | module.exports = [ 10 | // https://raw.githubusercontent.com/leafTheFish/DeathNote/main/ddgy.js 11 | { 12 | on: 'res-body', 13 | ruleId: 'ddgyToken', 14 | desc: '滴滴果园', 15 | method: 'POST', 16 | mitm: 'game.xiaojukeji.com', 17 | url: 'https://game.xiaojukeji.com/api/game/plant/enter?*', 18 | getCacheUid: ({ reqBody, resBody }) => ({ uid: resBody?.data?.uid, data: { reqBody, uid: resBody?.data?.uid } }), 19 | handler({ allCacheData }) { 20 | const value = allCacheData.map(({ data: d }) => `${d.uid}&${d.reqBody.token}`).join('@'); 21 | if (value) 22 | return { 23 | envConfig: [ 24 | { name: this.ruleId, value }, 25 | { name: 'ddgyck', value: allCacheData.map(({ data: d }) => JSON.stringify(d.reqBody)).join('\n') }, 26 | ], 27 | }; 28 | }, 29 | }, 30 | ]; 31 | -------------------------------------------------------------------------------- /src/features/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | ...require('./m3u8-ts-cache'), 3 | ]; 4 | -------------------------------------------------------------------------------- /src/features/m3u8-ts-cache.js: -------------------------------------------------------------------------------- 1 | const fs = require('node:fs'); 2 | const { resolve } = require('node:path'); 3 | 4 | const cache = { 5 | /** ts 文件缓存的路径 */ 6 | cacheDir: process.env.M3U8_TS_CACHE_DIR || 'cache/ts', 7 | /** ts 文件最大缓存数量 */ 8 | maxSize: Math.max(process.env.M3U8_TS_CACHE_MAX_SIZE || 5000, 1000), 9 | FeUtils: null, 10 | lru: null, 11 | /** 最近一次请求的 m3u8 文件 url */ 12 | currentM3u8Url: '', 13 | tsDownloading: new Map(), 14 | clear(clearAll = false) { 15 | if (clearAll) return fs.rmSync(cache.cacheDir, { recursive: true }); 16 | }, 17 | init() { 18 | if (!fs.existsSync(cache.cacheDir)) { 19 | fs.mkdirSync(cache.cacheDir, { recursive: true }); 20 | } else { 21 | fs.readdirSync(cache.cacheDir) 22 | .filter(d => d.length >= 32) 23 | .map(filename => [filename, fs.statSync(resolve(this.cacheDir, filename)).atimeMs]) 24 | .sort(([a, b]) => b[1] - a[1]) 25 | .forEach(([filename], atimeMs) => cache.lru.set(filename, atimeMs)); 26 | } 27 | 28 | console.log('cache inited. ', cache.lru.info()); 29 | }, 30 | }; 31 | 32 | /** 33 | * 用法:设置环境变量: 34 | * process.env.M3U8_CACHE_ENABLE = '1'; // 开启 m3u8 文件解析缓存规则 35 | * process.env.M3U8_TS_CACHE_ENABLE = '1'; // 开启 ts 缓存下载规则 36 | * process.env.M3U8_TS_CACHE_DIR = 'cache/ts'; // 自定义缓存目录 37 | * process.env.M3U8_TS_CACHE_MAX_SIZE = 5000; // 自定义缓存文件最大数量 38 | * 39 | * @type {import('@lzwme/whistle.x-scripts').RuleItem[]} 40 | */ 41 | module.exports = [ 42 | { 43 | on: 'res-body', 44 | ruleId: 'm3u8-preload-cache', 45 | desc: '根据 m3u8 文件内容缓存TS', 46 | method: 'get', 47 | url: (process.env.M3U8_CACHE_URL || '**.m3u8').split(','), 48 | disabled: process.env.M3U8_CACHE_ENABLE != '1', 49 | handler: async ({ url, resBody, X: { FeUtils } }) => { 50 | if (!url.endsWith('.m3u8')) return; 51 | 52 | if (!cache.FeUtils) { 53 | cache.FeUtils = FeUtils; 54 | cache.logger = logger; 55 | } 56 | 57 | try { 58 | cache.currentM3u8Url = url; 59 | 60 | const color = FeUtils.color; 61 | const baseUrl = url.slice(0, url.lastIndexOf('/')); 62 | const tasks = resBody 63 | .toString('utf-8') 64 | .split('\n') 65 | .filter(line => line.includes('.ts')) 66 | .map(tsurl => { 67 | if (!tsurl.startsWith('http')) tsurl = new URL(tsurl, baseUrl).toString(); 68 | return () => cache.currentM3u8Url === url && downloadTs(tsurl); 69 | }); 70 | 71 | console.log(color.cyan(`> 获取 ts 文件 ${tasks.length} 个:`), color.gray(url)); 72 | FeUtils.concurrency(tasks, 8).then(d => console.log(color.green('[TS缓存下载完毕]'), d.length, color.gray(url))); 73 | } catch (e) { 74 | console.log(e); 75 | } 76 | }, 77 | }, 78 | { 79 | on: 'req-header', 80 | ruleId: 'm3u8-ts-cache', 81 | desc: 'm3u8 媒体的 ts 文件缓存', 82 | method: 'get', 83 | url: (process.env.M3U8_TS_CACHE_URL || '**.ts').split(','), 84 | disabled: process.env.M3U8_TS_CACHE_ENABLE != '1' && process.env.M3U8_CACHE_ENABLE != '1', 85 | handler: async ({ url, X: { FeUtils, logger } }) => { 86 | if (!cache.FeUtils) { 87 | cache.FeUtils = FeUtils; 88 | cache.logger = logger; 89 | } 90 | 91 | const filepath = await downloadTs(url); 92 | if (filepath) return { body: fs.readFileSync(filepath) }; 93 | }, 94 | }, 95 | ]; 96 | 97 | async function downloadTs(url) { 98 | if (!url.includes('.ts')) return; 99 | 100 | const FeUtils = cache.FeUtils; 101 | const color = FeUtils.color; 102 | const filename = FeUtils.md5(url); 103 | const filepath = resolve(cache.cacheDir, filename); 104 | 105 | if (!cache.lru) { 106 | cache.lru = new FeUtils.LRUCache({ 107 | max: cache.maxSize, 108 | updateAgeOnGet: true, 109 | dispose(_val, key, reason) { 110 | if (reason !== 'set') { 111 | FeUtils.rmrf(resolve(cache.cacheDir, key)); 112 | } 113 | }, 114 | }); 115 | 116 | cache.init(); 117 | } 118 | 119 | let barrier = cache.tsDownloading.get(filename); 120 | if (barrier) await barrier.wait(); 121 | 122 | if (!fs.existsSync(filepath)) { 123 | try { 124 | const timeKey = color.gray(filename); 125 | console.time(timeKey); 126 | console.log(color.cyanBright('- 开始缓存文件'), color.magenta(url)); 127 | 128 | barrier = new FeUtils.Barrier(); 129 | cache.tsDownloading.set(filename, barrier); 130 | setTimeout(() => barrier.open(), 60_000); // 超时 60s 131 | const r = await FeUtils.download({ url, filepath }); 132 | barrier.open(); 133 | cache.tsDownloading.delete(filename); 134 | 135 | console.log(color.green('[TS 已缓存]'), r.size / 1024, color.gray(filepath)); 136 | console.timeEnd(timeKey); 137 | } catch (error) { 138 | console.error('下载失败!', color.red(url), error); 139 | return; 140 | } 141 | } else { 142 | console.log(color.green('[取缓存]'), color.gray(url)); 143 | } 144 | 145 | if (fs.existsSync(filepath)) { 146 | cache.lru.set(filename, Date.now()); 147 | return filepath; 148 | } 149 | } 150 | 151 | // console.log(module.exports); 152 | -------------------------------------------------------------------------------- /src/huluwa.js: -------------------------------------------------------------------------------- 1 | const apps = { 2 | wxded2e7e6d60ac09d: { key: 'XLHG', channelId: '8', desc: '偲源惠购' }, 3 | wx61549642d715f361: { key: 'GLYP', channelId: '7', desc: '贵旅优品' }, 4 | wx613ba8ea6a002aa8: { key: 'KGLG', channelId: '2', desc: '空港乐购' }, 5 | wx936aa5357931e226: { key: 'HLQG', channelId: '6', desc: '航旅黔购' }, 6 | wx624149b74233c99a: { key: 'ZXCS', channelId: '5', desc: '遵航出山' }, 7 | wx5508e31ffe9366b8: { key: 'GYQP', channelId: '3', desc: '贵盐黔品' }, 8 | wx821fb4d8604ed4d6: { key: 'LLSC', channelId: '1', desc: '乐旅商城' }, 9 | wxee0ce83ab4b26f9c: { key: 'YLQX', channelId: '9', desc: '驿路黔寻' }, 10 | }; 11 | 12 | // 13 | const tokenCache = new Map(); 14 | 15 | /** 16 | * 葫芦娃 token 自动提取保存或上传至青龙 17 | * @type {import('@lzwme/whistle.x-scripts').RuleItem} 18 | */ 19 | module.exports = { 20 | on: 'res-body', 21 | ruleId: 'huluwa', 22 | desc: '葫芦娃 x-access-token 获取', 23 | url: 'https://gw.huiqunchina.com/front-manager/api/**', 24 | getCacheUid: ({ headers, reqBody, resBody }) => { 25 | const token = headers['x-access-token']; 26 | if (!token) return; 27 | 28 | const info = tokenCache.get(token) || { appid: '', uid: '', token }; 29 | if (resBody?.data?.phone) info.uid = resBody?.data?.phone; 30 | if (!info.appid) info.appid = /miniProgram\/(wx\w+)/.exec(headers['user-agent'])?.[1] || reqBody?.appId; 31 | tokenCache.set(token, info); 32 | 33 | if (info.uid && info.appid) return { uid: `${info.appid}_${info.uid}`, data: { token, appid: info.appid, uid: info.uid } }; 34 | }, 35 | handler: ({ allCacheData, headers, reqBody }) => { 36 | const info = tokenCache.get(headers['x-access-token']); 37 | if (!info) return; 38 | 39 | const allUserData = allCacheData.filter(d => d.data.appid === info.appid); 40 | 41 | if (allUserData.length) { 42 | const value = allUserData.map(d => `${d.data.token}##${d.data.uid || d.uid}`).join('\n'); 43 | const envConfig = { name: `${apps[info.appid].key}_COOKIE`, value, desc: apps[info.appid].desc + '-huluwa' }; 44 | return { envConfig }; 45 | } 46 | }, 47 | }; 48 | -------------------------------------------------------------------------------- /src/imaotai.js: -------------------------------------------------------------------------------- 1 | const cache = { 2 | userId: '', 3 | token: '', 4 | tokenWap: '', 5 | lng: '', 6 | lat: '', 7 | deviceId: '', 8 | }; 9 | 10 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem} */ 11 | module.exports = { 12 | on: 'res-body', 13 | ruleId: 'imaotai', 14 | desc: 'imaotai预约 token 获取', 15 | /** url 匹配规则 */ 16 | url: 'https://{h5,app}.moutai519.com.cn/**', 17 | /** 方法匹配 */ 18 | method: '**', 19 | /** 是否上传至 青龙 环境变量配置 */ 20 | toQL: true, 21 | /** 是否写入到环境变量配置文件中 */ 22 | toEnvFile: true, 23 | /** 是否合并不同请求的缓存数据。默认为覆盖 */ 24 | mergeCache: true, 25 | /** 获取当前用户唯一性的 uuid */ 26 | getCacheUid: ({ headers, cookieObj, resBody }) => { 27 | if (/^\d+$/.test(resBody?.data?.userId)) cache.userId = resBody.data.userId; 28 | if (!cache.userId) return; 29 | 30 | const deviceId = headers['mt-device-id'] || cookieObj['MT-Device-ID-Wap']; 31 | if (deviceId) cache.deviceId = deviceId; 32 | if (cookieObj['MT-Token-Wap']) cache.tokenWap = cookieObj['MT-Token-Wap']; 33 | if (headers['mt-lng']) cache.lng = headers['mt-lng']; 34 | if (headers['mt-lat']) cache.lat = headers['mt-lat']; 35 | if (headers['mt-token']) cache.token = headers['mt-token']; 36 | 37 | Object.entries(cache).forEach(([key, val]) => { 38 | if (val === 'undifined') cache[key] = ''; 39 | }); 40 | 41 | console.log('geuid:', cache) 42 | return { 43 | /** user 唯一性标记 */ 44 | uid: cache.userId, 45 | /** 保存至缓存中的自定义数据。是可选的,主要用于需组合多个请求数据的复杂场景 */ 46 | data: { ...cache }, 47 | }; 48 | }, 49 | handler: ({ allCacheData }) => { 50 | const allUserData = allCacheData.map(d => d.data).filter(d => d.token); 51 | if (allCacheData.length === 0) return; 52 | console.log('imaotai allUserData:', JSON.stringify(allUserData, null, 2)); 53 | // const value = allUserData.map(d => `deviceId=${d.deviceId};token=${d.token};tokenWap=${d.tokenWap};city=x市;province=x省`).join('&'); 54 | const value = allUserData.map(d => `userId=${d.userId};deviceId=${d.deviceId};token=${d.token};tokenWap=${d.tokenWap}`).join('\n'); 55 | 56 | return { envConfig: { name: 'QL_IMAOTAI', value, desc: 'imaotai cookie' } }; 57 | }, 58 | updateEnvValue: /userId=([^;]+)/, 59 | }; 60 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-01-22 14:00:13 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-02-28 11:56:25 6 | * @Description: 7 | */ 8 | module.exports = [ 9 | ...require('./features'), 10 | // ...require('./vip'), 11 | // ...require('./jd'), 12 | // ...require('./QLScriptPublic'), 13 | ]; 14 | -------------------------------------------------------------------------------- /src/jd.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | const cache = { 3 | uid: '', 4 | wskey: '', 5 | }; 6 | 7 | /** 8 | * 京东 cookie 自动获取上传至青龙面板 9 | * WAP登录: https://bean.m.jd.com/bean/signIndex.action 10 | * @type {import('@lzwme/whistle.x-scripts').RuleItem[]} 11 | */ 12 | module.exports = [ 13 | { 14 | disabled: false, 15 | /** 保存缓存数据ID,应唯一 */ 16 | ruleId: 'JD_COOKIE', 17 | desc: '京东 cookie 自动抓取并同步至青龙环境变量', 18 | /** url 匹配规则 */ 19 | url: 'https://*.jd.com/**', 20 | /** 请求方法匹配 */ 21 | method: '*', 22 | toQL: true, 23 | toEnvFile: true, 24 | mergeCache: true, 25 | /** 获取当前用户唯一性的 uid */ 26 | getCacheUid({ cookieObj, url }) { 27 | if (cookieObj.wskey) { 28 | cache.wskey = cookieObj.wskey; 29 | console.log('wskey', cache); 30 | } 31 | 32 | const uid = cookieObj.pt_pin || cookieObj.pin; 33 | 34 | if (uid && !uid.startsWith('netdiag') && !uid.startsWith('***')) { 35 | if (cache.uid && cache.uid !== uid) cache.wskey = ''; 36 | cache.uid = uid; 37 | if (cache.wskey) cookieObj.wskey = cache.wskey; 38 | 39 | return { uid, data: cookieObj }; 40 | } 41 | }, 42 | /** 规则处理并返回环境变量配置。可以数组的形式返回多个 */ 43 | handler({ cacheData, cookieObj, X }) { 44 | // console.log('handler-1', cookieObj.pt_pin, cookieObj.pin, this.mergeCache); 45 | // 生成环境变量配置 46 | const envConfig = [ 47 | { 48 | name: 'JD_COOKIE', 49 | value: cacheData 50 | .filter(d => d.data.pt_pin) 51 | .map(d => X.cookieStringfiy(d.data, { onlyKeys: ['pt_pin', 'pt_key'] }) + ';') 52 | .join('\n'), 53 | desc: '京东 cookie', 54 | sep: '\n', 55 | }, 56 | { 57 | name: 'JD_WSCK', 58 | value: cacheData 59 | .filter(d => d.data.wskey) 60 | .map(d => `pin=${encodeURIComponent(d.uid)};wskey=${d.data.wskey}`) 61 | .join('&'), 62 | desc: '京东 wskey', 63 | sep: '&', 64 | }, 65 | ].filter(d => d.value); 66 | 67 | return { envConfig }; 68 | }, 69 | /** 更新处理已存在的环境变量,返回合并后的结果。若无需修改则可返回空 */ 70 | updateEnvValue({ value, sep = '\n' }, oldValue = '', X) { 71 | if (!oldValue) console.trace('[JD][OLDVALUE为空!]', value, oldValue); 72 | 73 | oldValue.split(sep).forEach(cookie => { 74 | if (!cookie) return; 75 | const pin = cookie.match(/pin=[^;]+/)?.[0]; 76 | if (!pin || !value.includes(pin)) value += `${sep}${cookie}`; 77 | }); 78 | return value; 79 | }, 80 | }, 81 | { 82 | desc: '签到有礼超级无线-七天签到LZKJ_SEVENDAY', 83 | ruleId: 'LZKJ_SEVENDAY', 84 | method: 'get', 85 | url: 'https://lzkj-isv.isvjcloud.com/sign/sevenDay/signActivity?activityId=*', 86 | getCacheUid: ({ url }) => new URL(url).searchParams.get('activityId'), 87 | handler({ cacheData }) { 88 | return { envConfig: { value: cacheData.map(d => d.uid).join(','), name: 'LZKJ_SEVENDAY' } }; 89 | }, 90 | }, 91 | { 92 | desc: '签到有礼超级无线-CJHY_SEVENDAY', 93 | ruleId: 'CJHY_SEVENDAY', 94 | method: 'get', 95 | url: 'https://cjhy-isv.isvjcloud.com/sign/sevenDay/signActivity?activityId=*', 96 | getCacheUid: ({ url }) => new URL(url).searchParams.get('activityId'), 97 | handler: ({ cacheData: A }) => ({ value: A.map(d => d.uid).join(','), name: 'CJHY_SEVENDAY' }), // 可以直接返回 envConfig 98 | }, 99 | { 100 | desc: 'lzkj签到有礼-activityId', 101 | ruleId: 'jd_lzkj_signActivity2_ids', 102 | url: 'https://lzkj-isv.isvjcloud.com/sign/signActivity2?activityId=*', 103 | getCacheUid: ({ url }) => new URL(url).searchParams.get('activityId'), 104 | handler({ cacheData }) { 105 | return [ 106 | { value: cacheData.map(d => d.uid).join('&'), name: 'jd_lzkj_signActivity2_ids', desc: 'lzkj签到有礼' }, 107 | { value: cacheData.map(d => d.uid).join(','), name: 'LZKJ_SIGN', desc: '签到有礼超级无线-LZKJ_SIGN' }, 108 | ]; 109 | }, 110 | }, 111 | { 112 | desc: 'cjhy签到有礼-activityId', 113 | ruleId: 'jd_cjhy_signActivity_ids', 114 | url: 'https://cjhy-isv.isvjcloud.com/wxActionCommon/getUserInfo', 115 | method: 'post', 116 | getCacheUid: ({ headers }) => { 117 | if (headers.referer) return new URL(headers.referer).searchParams.get('activityId'); 118 | }, 119 | handler({ cacheData }) { 120 | return [ 121 | { value: cacheData.map(d => d.uid).join('&'), name: 'jd_cjhy_signActivity_ids', desc: 'cjhy签到有礼' }, 122 | { value: cacheData.map(d => d.uid).join(','), name: 'CJHY_SIGN', desc: '签到有礼超级无线-CJHY_SIGN' }, 123 | ]; 124 | }, 125 | }, 126 | ]; 127 | -------------------------------------------------------------------------------- /src/lzwme.js: -------------------------------------------------------------------------------- 1 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 2 | module.exports = [ 3 | // https://raw.githubusercontent.com/leafTheFish/DeathNote/main/ddgy.js 4 | { 5 | on: 'res-body', 6 | ruleId: 'ylhyencryptsessionid', 7 | desc: '伊利会员福利社', 8 | method: '*', 9 | url: 'https://wx-fulishe.msx.digitalyili.com/brandwxa/api/vip/getinfo*', 10 | getCacheUid: ({ reqBody, resBody }) => { 11 | // console.log('reqBody', reqBody); 12 | const uid = resBody?.data?.uid || (reqBody?.encryptsessionid ? resBody?.result?.vipcode : ''); 13 | if (uid) return { uid, data: `${reqBody.encryptsessionid}##${uid}` }; 14 | }, 15 | handler: ({ cacheData }) => ({ 16 | envConfig: { 17 | value: cacheData 18 | .filter(d => typeof d.data === 'string') 19 | .map(d => `${d.data}`) 20 | .join('\n'), 21 | }, 22 | }), 23 | }, 24 | { 25 | on: 'res-body', 26 | ruleId: 'sysxc', 27 | desc: '书亦烧仙草', 28 | method: '*', 29 | url: 'https://scrm-prod.shuyi.org.cn/saas-gateway/api/mini-app/v1/{member/mine,account/login}**', 30 | getCacheUid: ({ resBody, headers, url }) => { 31 | const data = { 32 | uid: resBody?.data?.user?.uid || resBody?.data?.member?.uid, 33 | data: headers.auth || resBody?.data?.auth, 34 | }; 35 | return data; 36 | }, 37 | handler({ cacheData }) { 38 | const value = cacheData.filter(d => d.data).map(d => `${d.data}##${d.uid}`); 39 | return { envConfig: { value: value.join('\n') } }; 40 | }, 41 | }, 42 | { 43 | on: 'res-body', 44 | ruleId: 'alyp', 45 | desc: '阿里云盘', 46 | url: 'https://auth.alipan.com/v2/account/token', 47 | getCacheUid: ({ resBody }) => ({ uid: resBody?.user_id, data: resBody?.refresh_token }), 48 | handler: ({ cacheData }) => ({ envConfig: { value: cacheData.map(d => `${d.data}##${d.uid}`).join('\n') } }), 49 | }, 50 | { 51 | on: 'req-header', 52 | ruleId: 'IQIYI_COOKIE', 53 | desc: '爱奇艺签到', 54 | url: 'https://*.iqiyi.com/*/api/**', 55 | method: '*', 56 | getCacheUid: ({ cookieObj: ck }) => ({ uid: ck.P00003, data: `P00003=${ck.P00003};P00001=${ck.P00001}` }), 57 | handler: ({ cacheData }) => ({ envConfig: { value: cacheData.map(d => `${d.data}`).join('\n') } }), 58 | updateEnvValue: /P00003=[^;]+/, 59 | }, 60 | { 61 | on: 'res-body', 62 | ruleId: 'xmly_cookie', 63 | desc: '喜马拉雅签到 cookie 获取', 64 | url: ['https://m.ximalaya.com/starwar/task/listen/serverTime', 'https://pc.ximalaya.com/pc-application-server/user/isNew', 'http://xmc.ximalaya.com/xmlymain-login-web/**'], 65 | method: '*', 66 | getCacheUid: ({ headers, resBody = {} }) => { 67 | const uid = resBody.context?.currentUser.id || resBody.data?.uid || resBody.data?.userId; 68 | if (uid && headers.cookie?.includes('token')) return { uid, data: `${headers.cookie.replace(/ XD=[^;]+;/, '')}##${uid}` }; 69 | }, 70 | handler: ({ cacheData: d }) => ({ envConfig: { value: d.map(d => `${d.data}`).join('\n'), sep: '\n' } }), 71 | updateEnvValue: /##(\d+)/, 72 | }, 73 | { 74 | disabled: true, // 脚本已废弃 75 | on: 'req-header', 76 | ruleId: 'dkl_token', 77 | desc: '迪卡侬签到-单账号', 78 | url: 'https://api-cn.decathlon.com.cn/**', 79 | method: '*', 80 | getCacheUid: () => 'default', 81 | handler: ({ headers }) => headers.authorization && { envConfig: { value: headers.authorization } }, 82 | }, 83 | { 84 | // 开代理时云闪付签到页面进不去;可以先关闭代理进入签到页面,再开代理后,随意点击签到页面的任意链接 85 | on: 'req-header', 86 | ruleId: 'ysfqd_data', 87 | desc: '云闪付签到-单账号', 88 | url: 'https://youhui.95516.com/newsign/**', 89 | method: '*', 90 | getCacheUid: () => 'default', 91 | handler: ({ headers }) => headers.authorization && { envConfig: { value: headers.authorization } }, 92 | }, 93 | { 94 | on: 'req-header', 95 | ruleId: 'ths_cookie', 96 | desc: '同花顺签到', 97 | url: 'https://eq.10jqka.com.cn/**', 98 | method: 'get', 99 | // getCacheUid: ({ cookieObj: C }) => C.userid, 100 | getCacheUid: ({ cookieObj: C }) => ({ uid: C.userid, data: `ticket=${C.ticket}; userid=${C.userid}; user=${C.user}` }), 101 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.data || d.headers.cookie}`).join('\n') } }), 102 | }, 103 | { 104 | on: 'res-body', 105 | ruleId: 'JJCookie', 106 | desc: '掘金签到', 107 | url: 'https://api.juejin.cn/user_api/v1/user/get**', 108 | method: 'get', 109 | getCacheUid({ headers, resBody: B }) { 110 | const uid = B?.data?.user_id || B?.data?.user_basic?.user_id; 111 | if (uid && headers.cookie) return { uid }; 112 | }, 113 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.cookie}##${d.uid}`).join('\n') } }), 114 | }, 115 | { 116 | ruleId: 'gujing', 117 | desc: '古井贡酒会员中心小程序', 118 | method: 'post', 119 | url: 'https://scrm.gujing.com/gujing_scrm/wxclient/login/info', 120 | on: 'req-body', 121 | getCacheUid: ({ reqBody: R }) => R?.memberId, 122 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers['access-token']}##${d.uid}`).join('\n') } }), 123 | }, 124 | { 125 | on: 'res-body', 126 | ruleId: 'aima', 127 | desc: '爱玛会员俱乐部-小程序', 128 | url: 'https://scrm.aimatech.com/aima/wxclient/member/IndexInfo', 129 | method: 'get', 130 | getCacheUid: ({ resBody: R, headers }) => (headers['access-token'] ? { uid: R?.content?.id } : nulll), 131 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers['access-token']}##${d.uid}`).join('\n') } }), 132 | // updateEnvValue: /&([\d\*]+)/, 133 | }, 134 | { 135 | on: 'res-body', 136 | ruleId: 'mypd', 137 | desc: '漫游胖达-小程序', 138 | url: 'https://pw.gzych.vip/ykb_huiyuan/api/v2/MemberMine/BasicInfo', 139 | method: 'get', 140 | getCacheUid: ({ resBody: R, headers }) => (headers['authorization'] ? { uid: R?.Data?.CardNo } : nulll), 141 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers['authorization']}##${d.uid}`).join('\n') } }), 142 | // updateEnvValue: /&([\d\*]+)/, 143 | }, 144 | { 145 | on: 'res-body', 146 | ruleId: 'aicnn_token', 147 | desc: 'AICNN签到 token 提取', 148 | source: 'https://github.com/lzwme/ql-scripts/blob/main/ql_aicnn.ts', 149 | url: 'https://api.aicnn.cn/app-api/system/auth/refresh-token*', 150 | method: 'post', 151 | getCacheUid: ({ resBody: R, headers }) => (R?.data?.userId ? { uid: R.data.userId, data: R.data.refreshToken } : nulll), 152 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.data}##${d.uid}`).join('\n') } }), 153 | }, 154 | ]; 155 | -------------------------------------------------------------------------------- /src/ohhh_QL-Script.js: -------------------------------------------------------------------------------- 1 | /** 2 | * yang7758258/ohhh_QL-Script 3 | * @type {import('@lzwme/whistle.x-scripts').RuleItem[]} 4 | */ 5 | module.exports = [ 6 | { 7 | on: 'req-body', 8 | ruleId: 'chmlck', 9 | desc: '长虹美菱小程序签到', 10 | url: 'https://hongke.changhong.com/gw/burying/burying/report*', 11 | method: 'post', 12 | getCacheUid: ({ reqBody: R }) => R?.props?.wx_user?.phone_number, 13 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.token}##${d.uid}`).join('\n') } }), 14 | }, 15 | { 16 | on: 'res-body', 17 | ruleId: 'qchyjlb', 18 | desc: '雀巢会员俱乐部-小程序签到', 19 | url: 'https://crm.nestlechinese.com/openapi/member/api/User/GetUserInfo', 20 | method: 'get', 21 | getCacheUid: ({ resBody: R }) => ({ uid: R?.data?.mobile }), 22 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n') } }), 23 | updateEnvValue: /&([\d\*]+)/, 24 | }, 25 | { 26 | on: 'res-body', 27 | ruleId: 'fsdlb', 28 | desc: '逢三得利吧-小程序签到', 29 | url: 'https://xiaodian.miyatech.com/api/user/member/info', 30 | method: 'post', 31 | getCacheUid: ({ resBody: R }) => ({ uid: R?.data?.memberId }), 32 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 33 | updateEnvValue: /&([\d\*]+)/, 34 | }, 35 | { 36 | on: 'res-body', 37 | ruleId: 'ywxspc', 38 | desc: '义乌小商品城会员-小程序签到', 39 | url: 'https://apiserver.chinagoods.com/ums/authentication/v1/userauthinfo', 40 | method: 'get', 41 | getCacheUid: ({ resBody: R, headers }) => headers.authorization && { uid: R?.data?.userinfo?.userId }, 42 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 43 | updateEnvValue: /&([\d\*]+)/, 44 | }, 45 | { 46 | on: 'res-body', 47 | ruleId: 'zippo', 48 | desc: 'zippo会员中心-小程序签到', 49 | url: 'https://wx-center.zippo.com.cn/api/users/profile', 50 | method: 'get', 51 | getCacheUid: ({ resBody: R, headers }) => headers.authorization && { uid: R?.phone }, 52 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 53 | updateEnvValue: /&([\d\*]+)/, 54 | }, 55 | { 56 | on: 'res-body', 57 | ruleId: 'ydxq', 58 | desc: '雅迪星球-小程序', 59 | url: 'https://planet-api.op.yadea.com.cn/user-api/app/user/getUsertoken', 60 | method: 'post', 61 | getCacheUid: ({ resBody: R, headers }) => headers.authorization && { uid: R?.object?.userinfo?.userid }, 62 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 63 | updateEnvValue: /&([\d\*]+)/, 64 | }, 65 | { 66 | on: 'res-body', 67 | ruleId: 'xpnc', 68 | desc: '兴攀农场-小程序', 69 | url: 'https://p.xpfarm.cn/treemp/user.PersonalCenter/getInfo', 70 | method: 'post', 71 | getCacheUid: ({ resBody: R, headers }) => headers.authorization && ({ uid: R?.data?.id }), 72 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 73 | updateEnvValue: /&.+/, 74 | }, 75 | { 76 | on: 'res-body', 77 | ruleId: 'dfjsck', 78 | desc: '东方棘市-小程序', 79 | url: 'https://ys.shajixueyuan.com/api/user/info', 80 | method: 'GET', 81 | getCacheUid: ({ resBody: R, headers }) => headers.token && ({ uid: R?.data?.id }), 82 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.token}#${d.uid}`).join('\n') } }), 83 | updateEnvValue: /#([\d\*]+)/, 84 | }, 85 | { 86 | on: 'res-body', 87 | ruleId: 'rqtyg', 88 | desc: '日清体验馆-小程序', 89 | url: 'https://prod-api.nissinfoodium.com.cn/gw-shop/app/v1/user-center/detail?type=1', 90 | method: 'GET', 91 | getCacheUid: ({ resBody: R, headers }) => headers.token && ({ uid: R?.data?.user_id }), 92 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.token}&${d.uid}`).join('\n'), sep: '\n' } }), 93 | updateEnvValue: /&([\d\*]+)/, 94 | }, 95 | { 96 | on: 'res-body', 97 | ruleId: 'emsyhzx', 98 | desc: 'EMS邮惠中心-小程序签到得优惠券', 99 | url: 'https://ump.ems.com.cn/memberCenterApiV2/member/findByOpenIdAppId', 100 | method: 'post', 101 | getCacheUid: ({ reqBody: Q, resBody: R }) => Q.openId && ({ uid: R?.data?.user_id, data: `${Q.openId}&${R.data?.user_id}` }), 102 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n'), sep: '\n' } }), 103 | updateEnvValue: /&([\da-z]+)/, 104 | }, 105 | { 106 | on: 'res-body', 107 | ruleId: 'tkzxbxCookie', 108 | desc: '泰康在线保险-小程序签到-单账号', 109 | url: 'https://m.tk.cn/member_api*', 110 | method: 'post', 111 | getCacheUid: ({ reqBody: Q, resBody: R, url }) => { 112 | if (typeof Q.params === 'string') Q = JSON.parse(Q.params); 113 | return { uid: Q.bindid, data: `${Q.bindid}` }; // &${R.data?.tkmid} 114 | }, 115 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n'), sep: '\n' } }), 116 | updateEnvValue: /&([\da-z]+)/, 117 | }, 118 | { 119 | on: 'res-body', 120 | ruleId: 'yshyjlb', 121 | desc: '仰韶会员俱乐部-小程序', 122 | url: 'https://hy.51pt.top/app/ys/mine/getMemberInfo', 123 | method: 'get', 124 | getCacheUid: ({ resBody: R }) => ({ uid: R?.data?.userId }), 125 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 126 | updateEnvValue: /&([\d\*]+)/, 127 | }, 128 | { 129 | on: 'res-body', 130 | ruleId: 'mswefls', 131 | desc: '麦斯威尔福利社-小程序', 132 | url: 'https://jde.mtbcpt.com/api/JDEMaxwellApi/QueryHomeInfo', 133 | method: 'post', 134 | getCacheUid: ({ resBody: R, reqBody: Q }) => { 135 | const uid = R?.data?.user?.Id; 136 | if (uid) return { uid, data: `${Q.openId}&${uid}` }; 137 | }, 138 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n'), sep: '\n' } }), 139 | updateEnvValue: /&([\d\*]+)/, 140 | }, 141 | { 142 | on: 'res-body', 143 | ruleId: 'hqcsh', 144 | desc: '好奇车生活-小程序', 145 | url: 'https://channel.cheryfs.cn', 146 | method: '*', 147 | getCacheUid: ({ resBody: R, reqBody: Q, headers }) => { 148 | if (headers.accountid) { 149 | console.log(url, R, Q); 150 | } 151 | // const uid = R?.data?.user?.Id; 152 | // if (uid) return { uid, data: `${Q.openId}&${uid}` }; 153 | }, 154 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.accountid}&${d.uid}`).join('\n'), sep: '\n' } }), 155 | updateEnvValue: /&([\d\*]+)/, 156 | }, 157 | { 158 | on: 'res-body', 159 | ruleId: 'gljj', 160 | desc: '国乐酱酒-小程序签到得酒', 161 | url: 'https://member.guoyuejiu.com/api/user/info', 162 | method: 'get', 163 | getCacheUid: ({ resBody: R , headers }) => headers.authorization && ({ uid: R?.data?.id }), 164 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 165 | updateEnvValue: /&([\d\*]+)/, 166 | }, 167 | { 168 | on: 'res-body', 169 | ruleId: 'babaycare', 170 | desc: 'Babaycare-小程序签到', 171 | url: 'https://api.bckid.com.cn/lightpay/front/user/balance/info', 172 | method: 'post', 173 | getCacheUid: ({ resBody: R , headers }) => headers.authorization && ({ uid: R?.body?.userId }), 174 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 175 | updateEnvValue: /&([\d\*]+)/, 176 | }, 177 | { 178 | on: 'res-body', 179 | ruleId: 'mpcbh', 180 | desc: '毛铺草本荟-小程序签到', 181 | url: 'https://mpb.jingjiu.com/proxy-he/api/BlzAppletIndex/levelPowerList', 182 | method: 'post', 183 | getCacheUid: ({ resBody: R, headers }) => headers.authorization && ({ uid: R?.data?.user?.user_id }), 184 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.authorization}&${d.uid}`).join('\n'), sep: '\n' } }), 185 | updateEnvValue: /&([\d\*]+)/, 186 | }, 187 | { 188 | on: 'res-body', 189 | ruleId: 'jdfls', 190 | desc: '健达福利社-小程序签到', 191 | url: 'https://mole.ferrero.com.cn/boss/boss/scrm/home/info/get', 192 | method: 'post', 193 | getCacheUid: ({ resBody: R }) => ({ uid: R?.data?.memberDetail?.memberId }), 194 | handler: ({ cacheData: D }) => ({ 195 | envConfig: { value: D.map(d => `${d.headers['kumi-token']}&${d.headers['project-id']}&${d.uid}`).join('\n'), sep: '\n' }, 196 | }), 197 | updateEnvValue: /&([a-z\d]+)$/, 198 | }, 199 | { 200 | on: 'res-body', 201 | ruleId: 'htmwg', 202 | desc: '海天美味馆-小程序签到', 203 | url: 'https://cmallapi.haday.cn/buyer-api/members', 204 | method: 'get', 205 | getCacheUid: ({ resBody: R, headers }) => headers.authorization && ({ uid: R?.member_id }), 206 | handler: ({ cacheData: D }) => ({ 207 | envConfig: { value: D.map(d => `${d.headers.authorization}&${d.headers.uuid}&${d.uid}`).join('\n'), sep: '\n' }, 208 | }), 209 | updateEnvValue: /&(\d+)$/, 210 | }, 211 | { 212 | on: 'res-body', 213 | ruleId: 'glg', 214 | desc: '格力高-小程序签到', 215 | url: 'https://crm.glico.cn/miniapp/member/profile', 216 | method: 'get', 217 | getCacheUid: ({ resBody: R, headers }) => headers['x-auth-token'] && ({ uid: R?.data?.id }), 218 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers['x-auth-token']}&${d.uid}`).join('\n'), sep: '\n' } }), 219 | updateEnvValue: /&(\d+)$/, 220 | }, 221 | { 222 | on: 'res-body', 223 | ruleId: 'fsinstax', 224 | desc: '富士instax玩拍由我俱乐部-小程序签到', 225 | url: 'https://instax.app.xcxd.net.cn/api/me', 226 | method: 'get', 227 | getCacheUid: ({ resBody: R, headers }) => headers.authorization && ({ uid: R?.data?.user_id || R?.data?.user?.id }), 228 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.uid}&${d.headers.authorization}`).join('\n'), sep: '\n' } }), 229 | updateEnvValue: /(\d+)&/, 230 | }, 231 | { 232 | on: 'req-header', 233 | ruleId: 'lslyg', 234 | desc: '冷酸灵牙膏小程序签到', 235 | url: 'https://consumer-api.quncrm.com/**', 236 | method: 'post', 237 | getCacheUid: ({ headers: H, url }) => ({ uid: H['x-account-id'] }), 238 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.uid}&${d.headers['x-access-token']}`).join('\n'), sep: '\n' } }), 239 | } 240 | ]; 241 | -------------------------------------------------------------------------------- /src/t.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 用于临时测试的一些例子 3 | * @type {import('@lzwme/whistle.x-scripts').RuleItem[]} 4 | */ 5 | module.exports = [ 6 | { 7 | on: 'req-header', 8 | ruleId: 'CITIC_COOKIE', 9 | disabled: true, 10 | desc: '中信银行签到', 11 | url: 'https://thbank.tianhongjijin.com.cn/api/hy/signArea/*', 12 | method: '*', 13 | getCacheUid: ({ cookieObj: C }) => C.current_user, 14 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers.cookie}##${d.uid}`).join('\n') } }), 15 | }, 16 | { 17 | on: 'res-body', 18 | ruleId: 'huangzuan_WX', 19 | desc: '媓钻_小程序签到', 20 | url: 'https://api.hzyxhfp.com/api/userRight/getUserRightDetail', 21 | method: 'post', 22 | getCacheUid: ({ resBody: R }) => ({ uid: R?.data?.phone }), 23 | handler: ({ cacheData: D }) => ({ 24 | envConfig: { 25 | value: D.filter(d => d.headers.authorization) 26 | .map(d => `${d.headers.authorization.replace('Bearer ', '')}`) 27 | .join('\n'), 28 | }, 29 | }), 30 | // updateEnvValue: /&([\d\*]+)/, 31 | }, 32 | { 33 | on: 'res-body', 34 | ruleId: 'gmjkck', 35 | desc: '敢迈健康+_小程序签到', 36 | url: 'https://api.digital4danone.com.cn/healthyaging/danone/wx/ha/haUser/info', 37 | method: 'get', 38 | getCacheUid: ({ resBody: R }) => ({ uid: R?.result?.userId }), 39 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => `${d.headers['x-access-token']}`).join('\n') } }), 40 | // updateEnvValue: /&([\d\*]+)/, 41 | }, 42 | { 43 | on: 'res-body', 44 | ruleId: 'this', 45 | desc: 'this官方商城-小程序签到', 46 | url: 'https://xcx.this.cn/api/user', 47 | method: 'get', 48 | getCacheUid: ({ resBody: R, headers }) => headers['authori-zation'] && { uid: R?.data?.uid }, 49 | handler: ({ cacheData: D }) => ({ 50 | envConfig: { value: D.map(d => `${d.headers['authori-zation'].replace('Bearer ', '')}`).join('\n'), sep: '\n' }, 51 | }), 52 | }, 53 | { 54 | on: 'req-body', 55 | ruleId: 'JDD', 56 | desc: '金杜丹-小程序签到-单账号', 57 | url: 'https://tianxin.jmd724.com/**', 58 | method: 'get', 59 | getCacheUid: ({ url, X }) => { 60 | const query = X.FeUtils.getUrlParams(url); 61 | if (query.access_token) return { uid: '_', data: query.access_token }; 62 | }, 63 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('@'), sep: '@' } }), 64 | }, 65 | { 66 | on: 'res-body', 67 | ruleId: 'dqdd', 68 | desc: 'DQ点单-小程序签到-单账号', 69 | url: 'https://wechat.dairyqueen.com.cn/**', 70 | method: 'post', 71 | getCacheUid: ({ resBody: R }) => '_', // ({ uid: R?.data?.uid }), 72 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.headers.cookie).join('\n'), sep: '\n' } }), 73 | }, 74 | { 75 | on: 'res-body', 76 | ruleId: 'LBDQ', 77 | desc: '老板电器服务微商城-小程序签到', 78 | url: 'https://vip.foxech.com/index.php/api/member/get_member_info', 79 | method: 'post', 80 | getCacheUid: ({ reqBody: Q, resBody: R }) => 81 | Q.openid && { uid: R?.data?.info?.nickname, data: `${Q.openid}@UID_${R?.data?.info?.nickname}` }, 82 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 83 | updateEnvValue: /@([\da-z]+)/i, 84 | }, 85 | { 86 | on: 'res-body', 87 | ruleId: 'mshy', 88 | desc: '慕思会员中心-小程序签到', 89 | url: 'https://atom.musiyoujia.com/member/wechatlogin/selectuserinfo', 90 | method: 'post', 91 | getCacheUid: ({ reqBody: Q, resBody: B, headers: H }) => { 92 | const uid = B?.data?.resMemberInfo?.userId; 93 | const openId = B?.data?.resMemberInfo?.openId || Q?.openId; 94 | if (uid && H.api_token && openId) { 95 | return { uid, data: `${H.api_token}#${openId}##${uid}` }; 96 | } 97 | }, 98 | handler: ({ cacheData: D }) => ({ envConfig: { value: D.map(d => d.data).join('\n') } }), 99 | updateEnvValue: /##(\d+)/i, 100 | }, 101 | { 102 | on: 'res-body', 103 | ruleId: 'wawo', 104 | desc: '所有女生会员中心-小程序', 105 | url: 'https://7.wawo.cc/api/account/wx/member/base', 106 | method: 'get', 107 | getCacheUid: ({ resBody: R, headers }) => (headers.authorization ? { uid: R?.data?.cardNo } : nulll), 108 | handler: ({ cacheData: D }) => ({ 109 | envConfig: { value: D.map(d => `${d.headers.authorization.replace(/bearer /i, '')}`).join('\n'), sep: '\n' }, 110 | }), 111 | // updateEnvValue: /&([\d\*]+)/, 112 | }, 113 | { 114 | on: 'res-body', 115 | desc: '广东/福建体彩服务号', 116 | ruleId: 'gdtc', 117 | url: 'https://pnup-hd.tcssyw.com/api/act/get_sign_use', 118 | getCacheUid({ url, reqBody: R,resBody: B = {}, headers: H, req, X }) { 119 | if (!R && req._readableState?.buffer) { 120 | R = X.FeUtils.getUrlParams(req._readableState.buffer.toString()); 121 | } 122 | 123 | if (R.uuid && R.accessToken && B.data?.memberId) { 124 | const uid = B.data.memberId; 125 | return { uid, data: `${R.uuid}&${R.accessToken}&${uid}` }; 126 | } 127 | }, 128 | handler: ({ cacheData: D }) => ({ envConfig: { sep: '\n', value: D.map(v => v.data).join('\n') } }), 129 | updateEnvValue: /^&(\d+)$/, 130 | }, 131 | ]; 132 | -------------------------------------------------------------------------------- /src/vip/alipanCrack.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-22 19:46:56 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-05-20 10:18:29 6 | * @Description: 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | // https://github.com/zqzess/rule_for_quantumultX/raw/master/js/debug/aDriveCrack/aDriveCrack_test.js 12 | { 13 | on: 'res-body', 14 | ruleId: 'alipanVip', 15 | desc: '阿里云盘解锁vip', 16 | method: '*', 17 | mitm: '(api|member).alipan.com', 18 | url: /^https:\/\/(api|member)\.(alipan|aliyundrive)\.com\/(adrive|v1|v2|business|databox)\/.+\/(me|vip|feature|info|get_personal_info|driveCapacityDetails|getUserCapacityInfo)/, 19 | handler({ resBody, url, X }) { 20 | if (typeof resBody === 'object') { 21 | const color = X.FeUtils.color; 22 | let modified = resBody; 23 | url = color.gray(url); 24 | 25 | if (modified.rightButtonText) { 26 | // body2 27 | console.log('修改会员有效期', url); 28 | modified = { 29 | ...resBody, 30 | rightButtonText: '立即续费', 31 | identity: 'svip', 32 | level: '8t', 33 | titleNotice: null, 34 | titleImage: 'https://gw.alicdn.com/imgextra/i1/O1CN01Z2Yv4u1jrJ5S5TYpo_!!6000000004601-2-tps-216-60.png', 35 | description: '有效期至2034-01-30', 36 | }; 37 | } else if (modified.dayDiscPrice) { 38 | // body6 39 | console.log('修改会员功能', url); 40 | modified.identity = 'svip'; 41 | let features = modified.features; 42 | features.forEach(function (i) { 43 | i.name === '限免' ? (i.name = 'VIP') : i.name; 44 | if (i.intercept) i.intercept = false; 45 | i.name === '会员' ? (i.name = 'VIP') : i.name; 46 | if (i.backgroundImage) 47 | i.backgroundImage = 'https://gw.alicdn.com/imgextra/i3/O1CN01E7Gm7E1ZHRsDrNlLa_!!6000000003169-2-tps-84-42.png'; 48 | if (i.features) { 49 | i.features.forEach(function (m) { 50 | m.intercept = false; 51 | }); 52 | } 53 | }); 54 | } else if (modified.personal_rights_info) { 55 | // body4 56 | console.log('修改用户账户信息和限制权限', url); 57 | modified.personal_rights_info.spu_id = 'svip'; 58 | modified.personal_rights_info.name = 'SVIP'; 59 | modified.personal_space_info.total_size = 43980465111040; // 40Tb 60 | } else if (modified.drive_capacity_details) { 61 | console.log('修改容量管理详情', url); 62 | 63 | modified.capacity_level_info = { 64 | capacity_type: 'svip', 65 | }; 66 | modified.drive_capacity_details.drive_total_size = 43980465111040; // 40Tb 67 | } else if (modified.drive_total_size && modified.default_drive_used_size) { 68 | // body5 69 | console.log('修改容量管理总容量', url); 70 | modified.drive_total_size = 43980465111040; // 40Tb 71 | } else if (modified.membershipIdentity && modified.userId) { 72 | // body7 73 | console.log('修改用户基础信息', url); 74 | modified.membershipIdentity = 'svip'; 75 | modified.membershipIcon = 'https://gw.alicdn.com/imgextra//i3//O1CN01iPKCuZ1urjDgiry5c_!!6000000006091-2-tps-60-60.png'; 76 | } else { 77 | // body1 78 | if (modified.vipList) { 79 | console.log('修改会员状态', url); 80 | modified = { 81 | ...modified, 82 | identity: 'svip', 83 | level: '8t', 84 | icon: 'https://gw.alicdn.com/imgextra/i3/O1CN01iPKCuZ1urjDgiry5c_!!6000000006091-2-tps-60-60.png', 85 | mediumIcon: 'https://gw.alicdn.com/imgextra/i4/O1CN01Mk916Y1c99aVBrgxM_!!6000000003557-2-tps-222-60.png', 86 | status: 'normal', 87 | vipCode: 'svip.8t', 88 | }; 89 | modified.vipList[0] = { 90 | name: '8TB超级会员', 91 | code: 'svip.8t', 92 | promotedAt: 1675599847, 93 | expire: 1906600189, 94 | }; 95 | } 96 | } 97 | 98 | return { body: modified }; 99 | } 100 | }, 101 | }, 102 | ]; 103 | -------------------------------------------------------------------------------- /src/vip/baiduCloud.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:08:29 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-03-06 13:16:12 6 | * @Description: 待验证 7 | * @see https://github.com/Yu9191/Rewrite/blob/b96c7975b2afee78cb3e1e69888dfc988c20ba6f/yikexiangce.js 8 | * @see https://raw.githubusercontent.com/ddgksf2013/Rewrite/master/Function/BaiduCloud.conf 9 | */ 10 | 11 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 12 | module.exports = [ 13 | { 14 | on: 'res-body', 15 | ruleId: 'baiduCloudVip', 16 | desc: '百度网盘_解锁在线视频倍率/清晰度', 17 | method: '*', 18 | mitm: 'pan.zhihu.com', 19 | url: /^https?:\/\/pan\.baidu\.com\/(youai\/(user\/.+\/getminfo|membership\/.+\/adswitch)|(rest\/.+\/membership\/user|act\/.+\/(bchannel|welfare)\/list)|api\/usercfg|api\/getsyscfg)/, 20 | // url: 'https://pan.baidu.com/rest/*/membership/user', 21 | handler({ resBody: body, url, X }) { 22 | if (typeof body !== 'object') return; 23 | const color = X.FeUtils.color; 24 | 25 | const yike = '/youai/user/v1/getminfo'; 26 | const ad = '/youai/membership/v1/adswitch'; 27 | const list = '/bchannel/list'; 28 | const hf = '/welfare/list'; 29 | const usercfg = '/api/usercfg'; 30 | let hit = 1; 31 | 32 | // 开屏广告过滤 33 | if (url.includes('api/getsyscfg')) { 34 | const propertiesToDelete = [ 35 | 'switch_config_area', 36 | 'splash_advertise_fetch_config_area', 37 | 'bdnc_commerce_video_ad_area_pad', 38 | 'thrid_ad_funads_service', 39 | 'my_person_service', 40 | 'thrid_ad_buads_service', 41 | 'splash_advertise_type_area', 42 | 'business_ad_config_area', 43 | 'new_user_card', 44 | ]; 45 | for (const prop of propertiesToDelete) { 46 | if (body[prop]) body[prop].cfg_list = []; 47 | } 48 | } 49 | // 会员权益 50 | else if (url.includes('membership/user')) { 51 | if (body.product_infos) { 52 | X.FeUtils.assign(body, { 53 | // request_id: 269895149694452300, 54 | product_infos: [ 55 | // { 56 | // product_id: '5310897792128633390', 57 | // start_time: 1617260485, 58 | // end_time: 2147483648, 59 | // buy_time: '1417260485', 60 | // cluster: 'offlinedl', 61 | // detail_cluster: 'offlinedl', 62 | // product_name: 'gz_telecom_exp', 63 | // }, 64 | { 65 | product_id: '5210897752128663390', // 5310897792128633390 66 | end_time: 4102415999, 67 | buy_time: '1384234467', 68 | cluster: 'offlinedl', 69 | status: '0', 70 | start_time: 1384234467, 71 | function_num: 2, 72 | buy_description: '离线下载套餐(永久)', 73 | product_description: '离线下载套餐(永久)', 74 | detail_cluster: 'offlinedl', 75 | product_name: 'offlinedl_permanent', 76 | }, 77 | { 78 | cur_svip_type: 'month', 79 | product_name: 'svip2_nd', 80 | product_description: '超级会员', 81 | function_num: 0, // 510004015 82 | start_time: 1688356160, 83 | buy_description: '', 84 | buy_time: 0, 85 | product_id: '', 86 | auto_upgrade_to_svip: 0, 87 | end_time: 4102415999, 88 | cluster: 'vip', 89 | detail_cluster: 'svip', 90 | status: 0, 91 | }, 92 | { 93 | product_name: 'contentvip_nd', 94 | product_description: '', 95 | function_num: 0, 96 | start_time: 1688356160, 97 | buy_description: '', 98 | buy_time: 0, 99 | product_id: '', 100 | auto_upgrade_to_svip: 0, 101 | end_time: 4102415999, 102 | cluster: 'contentvip', 103 | detail_cluster: 'contentvip', 104 | status: 0, 105 | }, 106 | ], 107 | center_skip_config: { 108 | action_type: 0, 109 | action_url: 'https://pan.baidu.com/buy/center?tag=8', 110 | }, 111 | last_privilege_card_v2: {}, 112 | current_privilege_card: [], 113 | current_product_v2: { 114 | product_id: '12187135090581539740', 115 | detail_cluster: 'svip', 116 | cluster: 'vip', 117 | product_type: 'vip2_1y_auto', 118 | }, 119 | current_privilege_card_v2: {}, 120 | up_product_infos: [], 121 | last_privilege_card: [], 122 | level_info: { 123 | history_value: 3470, 124 | current_level: 10, 125 | last_manual_collection_time: 0, 126 | current_value: 970, 127 | history_level: 3, 128 | v10_id: '', 129 | }, 130 | user_tag: 131 | '{\\"has_buy_record\\":1,\\"has_buy_vip_svip_record\\":1,\\"last_buy_record_creat_time\\":1688356106,\\"is_vip\\":0,\\"is_svip\\":1,\\"last_vip_type\\":1,\\"last_vip_svip_end_time\\":4102415999,\\"is_svip_sign\\":0,\\"notice_user_type\\":2,\\"notice_user_status\\":3,\\"is_first_act\\":0,\\"is_first_charge\\":0}', 132 | // currenttime: 1690687707, 133 | previous_product: [], 134 | current_mvip_v2: {}, 135 | current_product: { 136 | product_id: '12187135090581539740', 137 | detail_cluster: 'svip', 138 | cluster: 'vip', 139 | product_type: 'vip2_1y_auto', 140 | }, 141 | reminder: { 142 | reminderWithContent: { 143 | title: '已拥有超级会员', 144 | notice: '5T大空间、极速下载等特权已拥有~', 145 | }, 146 | advertiseContent: { 147 | url: 'https://yun.baidu.com/buy/center?tag=8&from=reminderpush1', 148 | title: '您的超级会员将于2099-12-31到期', 149 | notice: '5T大空间、极速下载等特权已拥有~', 150 | }, 151 | svip: { 152 | leftseconds: 390692, 153 | nextState: 'normal', 154 | }, 155 | }, 156 | current_mvip: [], 157 | previous_product_v2: {}, 158 | guide_data: { 159 | title: '超级会员 SVIP-Baby', 160 | content: '已拥有极速下载+视频倍速特权', 161 | button: { 162 | text: '会员中心', 163 | action_url: 'https://pan.baidu.com/wap/vip/user?from=myvip2#svip', 164 | }, 165 | }, 166 | }); 167 | } 168 | 169 | if (body.identity_icon) { 170 | X.FeUtils.assign(body, { 171 | vip: { 172 | emotional_tips_back: { 173 | first: '', 174 | daily: ['一起走过的每一天,我给了陪伴,而你给了我成长。'], 175 | }, 176 | emotional_tip_front: '陪你走过的每一天', 177 | guide_tip: ['墨鱼提醒:已享会员权限!'], 178 | expired_tip: '不再享有视频备份、在线解压等特权', 179 | expire_remind_tip: '将不再享有视频备份、在线解压等特权', 180 | status: 0, 181 | }, 182 | vipv2: { 183 | status: 1, 184 | }, 185 | identity_icon: { 186 | vip: 'https://internal-amis-res.cdn.bcebos.com/images/2019-8/1566452237582/78b88bf113b7.png', 187 | common: 'https://internal-amis-res.cdn.bcebos.com/images/2019-8/1566452539056/bf72cf66fae1.png', 188 | svip: 'https://internal-amis-res.cdn.bcebos.com/images/2019-8/1566452115696/38c1d743bfe9.png', 189 | contentvip: '', 190 | }, 191 | // request_id: 270055727479044860, 192 | svip: { 193 | emotional_tips_back: { 194 | first: '很高兴你在x年x月x日成为超级会员,愿美好时光与你相伴。', 195 | daily: ['据说超级会员,法力无边'], 196 | }, 197 | expire_remind_tip: '将不再享有极速下载、5T空间等特权', 198 | emotional_tip_front: '陪你走过的每一天', 199 | identity_icon_list: ['https://internal-amis-res.cdn.bcebos.com/images/2019-8/1566452115696/38c1d743bfe9.png', ''], 200 | status: 2, 201 | expired_tip: '不再享有极速下载、5T空间等特权', 202 | guide_tip: ['超级会员尊享5T空间和极速下载特权'], 203 | is_sign_user: false, 204 | }, 205 | error_code: 0, 206 | }); 207 | } 208 | 209 | if (body.tips_data_list) { 210 | X.FeUtils.assign(body, { 211 | tips_data_list: [], 212 | status_data: '超级会员至:2099-12-31', 213 | guide_data: { 214 | action_url: '', 215 | title: '超级会员SVIP', 216 | title_action_url: '', 217 | content: '已拥有极速下载+视频倍速等54项特权', 218 | button: { 219 | text: '等级提升', 220 | action_url: 'https://github.com/lzwme/x-scripts-rules/', 221 | }, 222 | }, 223 | user_status: 2, 224 | tips_data: {}, 225 | user_type: 'svip', 226 | request_id: 270614190566302800, 227 | level_info: { 228 | last_manual_collection_time: 0, 229 | current_max_points: 500, 230 | current_value: 1490, 231 | history_level: 3, 232 | accumulated_uncollected_points: 0, 233 | v10_id: '', 234 | daily_value: 0, 235 | accumulated_day: 0, 236 | history_value: 3470, 237 | current_level: 2, 238 | accumulated_lost_points: 0, 239 | default_daily_value: 5, 240 | }, 241 | v10_guide: { 242 | get_next_value_gap: true, 243 | tips: '升级还需要1510成长值,可享更多权益', 244 | button: { 245 | text: '立即加速', 246 | action_url: 'https://github.com/lzwme/x-scripts-rules/', 247 | }, 248 | ab_test: false, 249 | }, 250 | status_data_arr: ['超级会员至:2099-12-31'], 251 | new_guide_data: { 252 | action_url: '', 253 | title: 'SVIP V2', 254 | title_action_url: '', 255 | button: { 256 | text: '等级提升', 257 | action_url: 'https://github.com/lzwme/x-scripts-rules/', 258 | }, 259 | sub_card_list: [ 260 | { 261 | content: '已解锁倍速超清权益', 262 | icon_url: 'https://staticsns.cdn.bcebos.com/amis/2022-3/1646383463592/%E5%8A%A0%E9%80%9F%E5%8D%87%E7%BA%A7.png', 263 | action_url: 'https://github.com/lzwme/x-scripts-rules/', 264 | }, 265 | ], 266 | }, 267 | }); 268 | } 269 | 270 | hit = 1; 271 | } 272 | 273 | // 一刻相册 274 | else if (url.includes(yike)) { 275 | Object.assign(body, { 276 | // request_id: 342581654394297772, 277 | errno: 0, 278 | has_purchased: 1, 279 | has_buy_1m_auto_first: 0, 280 | can_buy_1m_auto_first: 0, 281 | can_buy_1m_auto_first_6: 0, 282 | has_received_7dfree: 1, 283 | product_tag: 3, 284 | sign_status: 1, 285 | sign_infos: [ 286 | { 287 | product_id: '12745849497343294855', 288 | order_no: '2203060931530010416', 289 | ctime: 1646537208, 290 | mtime: '2022-05-06 11:26:48', 291 | status: 1, 292 | sign_price: 1000, 293 | sign_channel: 0, 294 | }, 295 | ], 296 | vip_tags: ['album_vip'], 297 | product_infos: [ 298 | { 299 | product_id: '12745849497343294855', 300 | start_time: 1646534568, 301 | end_time: 4092599349, 302 | buy_time: 1649994533, 303 | tag: 'album_vip', 304 | order_no: '2203060931530010416', 305 | }, 306 | ], 307 | vip_infos: [ 308 | { 309 | tag: 'album_vip', 310 | start_time: 1646537208, 311 | end_time: 4092599349, 312 | }, 313 | ], 314 | expire_time: 0, 315 | }); 316 | hit = 1; 317 | } else if (url.includes(ad)) { 318 | body.switch = 'open'; 319 | hit = 1; 320 | } else if (url.indexOf(list) != -1) { 321 | body.data = [ 322 | { 323 | sub_title: '', 324 | id: 856, 325 | bg_icon: '', 326 | button_text: '', 327 | web_url: '', 328 | type: 3, 329 | name: '已解锁SVIP,未完整解锁', 330 | }, 331 | { 332 | sub_title: '', 333 | id: 460, 334 | bg_icon: '', 335 | button_text: '', 336 | web_url: '', 337 | type: 3, 338 | name: '已拥有极速下载+视频倍速特权', 339 | }, 340 | ]; 341 | 342 | hit = 1; 343 | } else if (url.indexOf(hf) != -1) { 344 | delete body.data; 345 | 346 | hit = 1; 347 | } else if (url.indexOf(usercfg) != -1) { 348 | body.user_new_define_cards = [ 349 | { 350 | card_id: '1', 351 | card_type: '4', 352 | card_area_name: '首页笔记-卡片', 353 | }, 354 | { 355 | is_manager: 1, 356 | card_area_name: '最近', 357 | card_id: '1', 358 | card_type: '7', 359 | }, 360 | { 361 | card_id: '1', 362 | card_type: '13', 363 | card_area_name: '卡片管理-卡片', 364 | }, 365 | ]; 366 | 367 | hit = 1; 368 | } 369 | 370 | if (hit) { 371 | console.log(`[${this.desc}]`, color.gray(url)); 372 | return { body }; 373 | } else { 374 | console.warn(`[${this.desc}][missed]`, color.gray(url)); 375 | } 376 | }, 377 | }, 378 | { 379 | on: 'req-header', 380 | ruleId: 'baiduCloudReject200', 381 | desc: '百度网盘广告过滤', 382 | method: '*', 383 | url: url => { 384 | const list = [ 385 | // # > 百度网盘_设置信息流 386 | /^https?:\/\/pan\.baidu\.com\/act\/v\d\/(bchannel|welfare)\/list/, 387 | // # > 百度网盘_通用广告 388 | /^https?:\/\/pan.baidu.com\/rest\/.*\/pcs\/ad/, 389 | // # > 百度网盘_活动推广 390 | /^https?:\/\/pan\.baidu\.com\/act\/api\/activityentry/, 391 | ]; 392 | 393 | for (const re of list) if (re.test(url)) return true; 394 | }, 395 | handler: () => ({ body: '' }), 396 | }, 397 | ]; 398 | -------------------------------------------------------------------------------- /src/vip/bilibiliHD.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:08:29 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-02-28 14:18:08 6 | * @Description: 待验证 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | { 12 | // 参考: https://raw.githubusercontent.com/itcast-l/shadowrocket-module/main/js/BiliBiliHD.js 13 | on: 'res-body', 14 | ruleId: 'bilibiliHD', 15 | desc: 'B站高清解锁去广告', 16 | method: '*', 17 | mitm: '*.bilibili.com', 18 | url: 'https://*.bilibili.com/x/v2/**', 19 | cache: { 20 | bilibili_story_aid: '', 21 | bilibili_feed_black: '', 22 | }, 23 | handler({ resBody: body, headers, url, X }) { 24 | if (!X.isText(headers) || Buffer.isBuffer(body) || typeof body !== 'object') return; 25 | 26 | // 更新时间:2023-01-29 27 | //Customize blacklist 28 | let blacklist = this.cache.bilibili_feed_black || []; 29 | let obj = body; 30 | let hit = 0; 31 | 32 | switch (true) { 33 | // 推荐去广告,最后问号不能去掉,以免匹配到story模式 34 | case /^https:\/\/app\.bilibili\.com\/x\/v2\/feed\/index\?/.test(url): 35 | try { 36 | let items = []; 37 | for (let item of obj['data']['items']) { 38 | if (item.hasOwnProperty('banner_item')) { 39 | let bannerItems = []; 40 | for (let banner of item['banner_item']) { 41 | if (banner['type'] === 'ad') { 42 | continue; 43 | } else if (banner['static_banner'] && banner['static_banner']['is_ad_loc'] != true) { 44 | bannerItems.push(banner); 45 | } 46 | } 47 | // 去除广告后,如果banner大于等于1个才添加到响应体 48 | if (bannerItems.length >= 1) { 49 | item['banner_item'] = bannerItems; 50 | items.push(item); 51 | } 52 | } else if ( 53 | !item.hasOwnProperty('ad_info') && 54 | !blacklist.includes(item['args']['up_name']) && 55 | item.card_goto.indexOf('ad') === -1 && 56 | (item['card_type'] === 'small_cover_v2' || 57 | item['card_type'] === 'large_cover_v1' || 58 | item['card_type'] === 'large_cover_single_v9') 59 | ) { 60 | items.push(item); 61 | } 62 | } 63 | obj['data']['items'] = items; 64 | hit = 1; 65 | } catch (err) { 66 | console.error(`[${this.desc}]推荐去广告出现异常:`, err); 67 | } 68 | break; 69 | // 匹配story模式,用于记录Story的aid 70 | case /^https:\/\/app\.bilibili\.com\/x\/v2\/feed\/index\/story\?/.test(url): 71 | try { 72 | let items = []; 73 | for (let item of obj['data']['items']) { 74 | if (!item.hasOwnProperty('ad_info') && item.card_goto.indexOf('ad') === -1) { 75 | items.push(item); 76 | } 77 | } 78 | obj['data']['items'] = items; 79 | hit = 1; 80 | } catch (err) { 81 | console.error(`[${this.desc}]记录Story的aid出现异常:`, err); 82 | } 83 | break; 84 | 85 | // 标签页处理,如去除会员购等等 86 | case /^https?:\/\/app\.bilibili\.com\/x\/resource\/show\/tab/.test(url): 87 | try { 88 | const tabList = new Set([39, 40, 41, 774, 857, 545, 151, 442, 99, 100, 101, 554, 556]); 89 | 90 | const topList = new Set([176, 107]); 91 | 92 | const bottomList = new Set([177, 178, 179, 181, 102, 104, 106, 486, 488, 489]); 93 | 94 | if (obj['data']['tab']) { 95 | let tab = obj['data']['tab'].filter(e => { 96 | return tabList.has(e.id); 97 | }); 98 | obj['data']['tab'] = tab; 99 | } 100 | // 将 id(222 & 107)调整为Story功能按钮 101 | let storyAid = this.cache.bilibili_story_aid || '246834163'; 102 | 103 | if (obj['data']['top']) { 104 | let top = obj['data']['top'].filter(e => { 105 | if (e.id === 222 || e.id === 107) { 106 | e.uri = `bilibili://story/${storyAid}`; 107 | e.icon = 'https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/bilibili/bilibili_icon.png'; 108 | e.tab_id = 'Story_Top'; 109 | e.name = 'Story'; 110 | } 111 | return topList.has(e.id); 112 | }); 113 | obj['data']['top'] = top; 114 | } 115 | if (obj['data']['bottom']) { 116 | let bottom = obj['data']['bottom'].filter(e => { 117 | return bottomList.has(e.id); 118 | }); 119 | obj['data']['bottom'] = bottom; 120 | } 121 | hit = 1; 122 | } catch (err) { 123 | console.error(`[${this.desc}]标签页处理出现异常:`, err); 124 | } 125 | break; 126 | // 我的页面处理,去除一些推广按钮 127 | case /^https?:\/\/app\.bilibili\.com\/x\/v2\/account\/mine/.test(url): 128 | try { 129 | const itemList = new Set([ 130 | 396, 397, 398, 399, 402, 404, 407, 410, 425, 426, 427, 428, 430, 432, 433, 434, 494, 495, 496, 497, 500, 501, 131 | ]); 132 | obj['data']['sections_v2'].forEach((element, index) => { 133 | element['items'].forEach(e => { 134 | if (e['id'] === 622) { 135 | e['title'] = '会员购'; 136 | e['uri'] = 'bilibili://mall/home'; 137 | } 138 | }); 139 | let items = element['items'].filter(e => { 140 | return itemList.has(e.id); 141 | }); 142 | obj['data']['sections_v2'][index].button = {}; 143 | delete obj['data']['sections_v2'][index].be_up_title; 144 | delete obj['data']['sections_v2'][index].tip_icon; 145 | delete obj['data']['sections_v2'][index].tip_title; 146 | //2022-02-16 add by ddgksf2013 147 | for (let ii = 0; ii < obj['data']['sections_v2'].length; ii++) { 148 | if (obj.data.sections_v2[ii].title == '推荐服务' || obj.data.sections_v2[ii].title == '推薦服務') { 149 | //obj.data.sections_v2[ii].items[0].title='\u516C\u773E\u865F'; 150 | //obj.data.sections_v2[ii].items[1].title='\u58A8\u9B5A\u624B\u8A18'; 151 | } 152 | if (obj.data.sections_v2[ii].title == '更多服務' || obj.data.sections_v2[ii].title == '更多服务') { 153 | if (obj.data.sections_v2[ii].items[0].id == 500) { 154 | //obj.data.sections_v2[ii].items[0].title='\u516C\u773E\u865F'; 155 | } 156 | if (obj.data.sections_v2[ii].items[1].id == 501) { 157 | //obj.data.sections_v2[ii].items[1].title='\u58A8\u9B5A\u624B\u8A18'; 158 | } 159 | } 160 | if (obj.data.sections_v2[ii].title == '创作中心' || obj.data.sections_v2[ii].title == '創作中心') { 161 | delete obj.data.sections_v2[ii].title; 162 | delete obj.data.sections_v2[ii].type; 163 | } 164 | } 165 | delete obj.data.vip_section_v2; 166 | delete obj.data.vip_section; 167 | obj['data']['sections_v2'][index]['items'] = items; 168 | //2022-03-05 add by ddgksf2013 169 | if (obj.data.hasOwnProperty('live_tip')) { 170 | obj['data']['live_tip'] = {}; 171 | } 172 | if (obj.data.hasOwnProperty('answer')) { 173 | obj['data']['answer'] = {}; 174 | } 175 | obj['data']['vip_type'] = 2; 176 | obj['data']['vip']['type'] = 2; 177 | obj['data']['vip']['status'] = 1; 178 | obj['data']['vip']['vip_pay_type'] = 1; 179 | obj['data']['vip']['due_date'] = 4669824160; 180 | }); 181 | hit = 1; 182 | } catch (err) { 183 | console.error(`[${this.desc}]我的页面处理出现异常:`, err); 184 | } 185 | break; 186 | // 直播去广告 187 | case /^https?:\/\/api\.live\.bilibili\.com\/xlive\/app-room\/v1\/index\/getInfoByRoom/.test(url): 188 | try { 189 | obj['data']['activity_banner_info'] = null; 190 | hit = 1; 191 | } catch (err) { 192 | console.error(`[${this.desc}]直播去广告出现异常:`, err); 193 | } 194 | break; 195 | //屏蔽热搜 196 | case /^https?:\/\/app\.bilibili\.com\/x\/v2\/search\/square/.test(url): 197 | try { 198 | obj.data = { 199 | type: 'history', 200 | title: '搜索历史', 201 | search_hotword_revision: 2, 202 | }; 203 | hit = 1; 204 | } catch (err) { 205 | console.error(`[${this.desc}]热搜去广告出现异常:`, err); 206 | } 207 | break; 208 | //2022-03-05 add by ddgksf2013 209 | case /https?:\/\/app\.bilibili\.com\/x\/v2\/account\/myinfo\?/.test(url): 210 | try { 211 | //magicJS.logInfo(`公众号墨鱼手记`); 212 | obj['data']['vip']['type'] = 2; 213 | obj['data']['vip']['status'] = 1; 214 | obj['data']['vip']['vip_pay_type'] = 1; 215 | obj['data']['vip']['due_date'] = 4669824160; 216 | hit = 1; 217 | } catch (err) { 218 | console.error(`[${this.desc}]1080P出现异常:`, err); 219 | } 220 | break; 221 | // 追番去广告 222 | case /pgc\/page\/bangumi/.test(url): 223 | try { 224 | obj.result.modules.forEach(module => { 225 | // 头部banner 226 | if (module.style.startsWith('banner')) { 227 | //i.source_content && i.source_content.ad_content 228 | module.items = module.items.filter(i => !(i.link.indexOf('play') == -1)); 229 | } 230 | if (module.style.startsWith('function')) { 231 | module.items = module.items.filter(i => i.blink.indexOf('www.bilibili.com') == -1); 232 | } 233 | if (module.style.startsWith('tip')) { 234 | module.items = null; 235 | } 236 | }); 237 | hit = 1; 238 | } catch (err) { 239 | console.error(`[${this.desc}]追番去广告出现异常:`, err); 240 | } 241 | break; 242 | // 观影页去广告 243 | case /pgc\/page\/cinema\/tab\?/.test(url): 244 | try { 245 | obj.result.modules.forEach(module => { 246 | // 头部banner 247 | if (module.style.startsWith('banner')) { 248 | module.items = module.items.filter(i => !(i.link.indexOf('play') == -1)); 249 | } 250 | if (module.style.startsWith('function')) { 251 | module.items = module.items.filter(i => i.blink.indexOf('www.bilibili.com') == -1); 252 | } 253 | if (module.style.startsWith('tip')) { 254 | module.items = null; 255 | } 256 | }); 257 | hit = 1; 258 | } catch (err) { 259 | console.error(`[${this.desc}]观影页去广告出现异常:`, err); 260 | } 261 | break; 262 | // 动态去广告 263 | case /^https?:\/\/api\.vc\.bilibili\.com\/dynamic_svr\/v1\/dynamic_svr\/dynamic_(history|new)\?/.test(url): 264 | try { 265 | let cards = []; 266 | obj.data.cards.forEach(element => { 267 | if (element.hasOwnProperty('display') && element.card.indexOf('ad_ctx') <= 0) { 268 | // 解决number类型精度问题导致B站动态中图片无法打开的问题 269 | element['desc']['dynamic_id'] = element['desc']['dynamic_id_str']; 270 | element['desc']['pre_dy_id'] = element['desc']['pre_dy_id_str']; 271 | element['desc']['orig_dy_id'] = element['desc']['orig_dy_id_str']; 272 | element['desc']['rid'] = element['desc']['rid_str']; 273 | cards.push(element); 274 | } 275 | }); 276 | obj.data.cards = cards; 277 | hit = 1; 278 | } catch (err) { 279 | console.error(`[${this.desc}]动态去广告出现异常:`, err); 280 | } 281 | break; 282 | // 去除统一设置的皮肤 283 | case /^https?:\/\/app\.bilibili\.com\/x\/resource\/show\/skin\?/.test(url): 284 | if (obj?.data?.common_equip?.package_url) { 285 | //obj["data"]["common_equip"]["package_url"] = ""; 286 | // hit = 1; 287 | } 288 | break; 289 | // 开屏广告(预加载)如果粗暴地关掉,那么就使用预加载的数据,就会导致关不掉 290 | case /^https:\/\/app\.bilibili\.com\/x\/v2\/splash\/list/.test(url): 291 | try { 292 | if (obj.data) { 293 | for (let item of obj['data']['list']) { 294 | item['duration'] = 0; // 显示时间 295 | // 2040 年 296 | item['begin_time'] = 2240150400; 297 | item['end_time'] = 2240150400; 298 | } 299 | } 300 | hit = 1; 301 | } catch (err) { 302 | console.error(`[${this.desc}]开屏广告(预加载)出现异常:`, err); 303 | } 304 | break; 305 | default: 306 | // console.warn('触发意外的请求处理,请确认脚本或复写配置正常。', url); 307 | return; 308 | } 309 | 310 | if (hit) { 311 | const color = X.FeUtils.color; 312 | console.log(`[${color.cyan(this.desc)}]`, color.gray(url)); 313 | return { body: obj }; 314 | } 315 | }, 316 | }, 317 | ]; 318 | -------------------------------------------------------------------------------- /src/vip/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:07:54 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-02-28 11:42:24 6 | * @Description: 7 | */ 8 | module.exports = [ 9 | ...require('./baiduCloud.js'), 10 | // ...require('./wps.js'), 11 | ...require('./xiaohongshu.js'), 12 | ...require('./xunlei.js'), 13 | ...require('./zhihu.js'), 14 | ]; 15 | -------------------------------------------------------------------------------- /src/vip/todo/wps.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:08:29 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-02-28 10:28:18 6 | * @Description: 待验证 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | { 12 | on: 'res-body', 13 | ruleId: 'wpsVipCrack', 14 | desc: 'WPS VIP', 15 | method: '*', 16 | mitm: /^https?:\/\/[a-z-]*account\.wps\.c(n|om)/, 17 | url: /^https?:\/\/[a-z-]*account\.wps\.c(n|om)(:\d+|)\/api\/users/, 18 | handler({ resBody : body, url, X }) { 19 | if (typeof body === 'object') { 20 | const color = X.FeUtils.color; 21 | console.log(`[${this.desc}]`, color.gray(url)); 22 | 23 | const privilege = [ 24 | { spid: "data_recover", times: 0, expire_time: 4133059437 }, 25 | { spid: "ocr", times: 0, expire_time: 4133059437 }, 26 | { spid: "pdf2doc", times: 0, expire_time: 4133059437 }, 27 | { spid: "pdf_merge", times: 0, expire_time: 4133059437 }, 28 | { spid: "pdf_sign", times: 0, expire_time: 4133059437 }, 29 | { spid: "pdf_split", times: 0, expire_time: 4133059437 } 30 | ]; 31 | const vip = { 32 | name: "超级会员", 33 | has_ad: 0, 34 | memberid: 40, 35 | expire_time: 4133059437, 36 | enabled: [ 37 | { memberid: 40, name: "超级会员", expire_time: 4133059437 }, 38 | { memberid: 20, name: "WPS会员", expire_time: 4133059437 }, 39 | { memberid: 12, name: "稻壳会员", expire_time: 4133059437 } 40 | ] 41 | }; 42 | 43 | Object.assign(body, { 44 | level: 5, 45 | exp: 999, 46 | privilege, 47 | vip, 48 | expire_time: 4133059437, 49 | total_cost: -30, 50 | }); 51 | 52 | if (body.data) { 53 | Object.assign(body.data, { 54 | level: 5, 55 | exp: 999, 56 | privilege, 57 | vip, 58 | expire_time: 4133059437, 59 | total_cost: -30, 60 | spaces_info: { 61 | "used": "0.10", 62 | "total": "1000.21", 63 | "unit": "T" 64 | } 65 | }); 66 | } 67 | 68 | return { body }; 69 | } 70 | }, 71 | }, 72 | ]; 73 | -------------------------------------------------------------------------------- /src/vip/xiaohongshu.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:08:29 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-03-04 16:26:10 6 | * @Description: 待验证 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | { 12 | on: 'res-body', 13 | ruleId: 'xiaohongshuVip', 14 | desc: '小红书去广告、解除下载限制、画质增强等', 15 | method: '*', 16 | mitm: '*.xiaohongshu.com', 17 | url: 'https://*.xiaohongshu.com/v{1,2,3,4,6,10}/**', 18 | handler({ resBody: body, url, X }) { 19 | if (!body || typeof body !== 'object') return; 20 | const color = X.FeUtils.color; 21 | console.log(`[${this.desc}]`, color.gray(url)); 22 | 23 | if (url.includes('/v1/search/banner_list')) { 24 | if (body.data) { 25 | body.data = {}; 26 | } 27 | } else if (url.includes('/v1/search/hot_list')) { 28 | // 热搜列表 29 | if (body.data?.items?.length > 0) { 30 | body.data.items = []; 31 | } 32 | } else if (url.includes('/v1/system_service/config')) { 33 | // 整体配置 34 | const item = ['app_theme', 'loading_img', 'splash', 'store']; 35 | if (body.data) { 36 | for (let i of item) { 37 | delete body.data[i]; 38 | } 39 | } 40 | } else if (url.includes('/v2/note/widgets')) { 41 | const item = ['generic']; 42 | if (body.data) { 43 | for (let i of item) { 44 | delete body.data[i]; 45 | } 46 | } 47 | } else if (url.includes('/v2/note/feed')) { 48 | // 信息流 图片 49 | if (body.data?.length > 0) { 50 | let data0 = body.data[0]; 51 | if (data0?.note_list?.length > 0) { 52 | for (let item of data0.note_list) { 53 | if (item?.media_save_config) { 54 | // 水印 55 | item.media_save_config.disable_save = false; 56 | item.media_save_config.disable_watermark = true; 57 | item.media_save_config.disable_weibo_cover = true; 58 | } 59 | if (item?.share_info?.function_entries?.length > 0) { 60 | // 下载限制 61 | const additem = { type: 'video_download' }; 62 | let func = item.share_info.function_entries[0]; 63 | if (func?.type !== 'video_download') { 64 | // 向数组开头添加对象 65 | item.share_info.function_entries.unshift(additem); 66 | } 67 | } 68 | } 69 | } 70 | } 71 | const images_list = body.data[0].note_list[0].images_list; 72 | body.data[0].note_list[0].images_list = imageEnhance(JSON.stringify(images_list)); 73 | 74 | // 保存无水印信息 75 | this['fmz200.xiaohongshu.feed.rsp'] = images_list; 76 | console.log('已存储无水印信息♻️'); 77 | } else if (url.includes('/v3/note/videofeed')) { 78 | // 信息流 视频 79 | if (body.data?.length > 0) { 80 | for (let item of body.data) { 81 | if (item?.media_save_config) { 82 | // 水印 83 | item.media_save_config.disable_save = false; 84 | item.media_save_config.disable_watermark = true; 85 | item.media_save_config.disable_weibo_cover = true; 86 | } 87 | if (item?.share_info?.function_entries?.length > 0) { 88 | // 下载限制 89 | const additem = { type: 'video_download' }; 90 | let func = item.share_info.function_entries[0]; 91 | if (func?.type !== 'video_download') { 92 | // 向数组开头添加对象 93 | item.share_info.function_entries.unshift(additem); 94 | } 95 | } 96 | } 97 | } 98 | } else if (url.includes('/v2/system_service/splash_config')) { 99 | // 开屏广告 100 | if (body.data?.ads_groups?.length > 0) { 101 | for (let i of body.data.ads_groups) { 102 | i.start_time = 2208960000; // Unix 时间戳 2040-01-01 00:00:00 103 | i.end_time = 2209046399; // Unix 时间戳 2040-01-01 23:59:59 104 | if (i?.ads?.length > 0) { 105 | for (let ii of i.ads) { 106 | ii.start_time = 2208960000; // Unix 时间戳 2040-01-01 00:00:00 107 | ii.end_time = 2209046399; // Unix 时间戳 2040-01-01 23:59:59 108 | } 109 | } 110 | } 111 | } 112 | } else if (url.includes('/v4/followfeed')) { 113 | // 关注列表 114 | if (body.data?.items?.length > 0) { 115 | // recommend_user 可能感兴趣的人 116 | body.data.items = body.data.items.filter(i => !['recommend_user'].includes(i.recommend_reason)); 117 | } 118 | } else if (url.includes('/v4/search/trending')) { 119 | // 搜索栏 120 | if (body.data?.queries?.length > 0) { 121 | body.data.queries = []; 122 | } 123 | if (body.data?.hint_word) { 124 | body.data.hint_word = {}; 125 | } 126 | } else if (url.includes('/v4/search/hint')) { 127 | // 搜索栏填充词 128 | if (body.data?.hint_words?.length > 0) { 129 | body.data.hint_words = []; 130 | } 131 | } else if (url.includes('/v6/homefeed')) { 132 | if (body.data?.length > 0) { 133 | // 信息流广告 134 | let newItems = []; 135 | for (let item of body.data) { 136 | if (item?.model_type === 'live_v2') { 137 | // 信息流-直播 138 | } else if (item?.hasOwnProperty('ads_info')) { 139 | // 信息流-赞助 140 | } else if (item?.hasOwnProperty('card_icon')) { 141 | // 信息流-带货 142 | } else if (item?.note_attributes?.includes('goods')) { 143 | // 信息流-商品 144 | } else { 145 | if (item?.related_ques) { 146 | delete item.related_ques; 147 | } 148 | newItems.push(item); 149 | } 150 | } 151 | body.data = newItems; 152 | } 153 | } else if (url.includes('/v10/search/notes')) { 154 | // 搜索结果 155 | if (body.data?.items?.length > 0) { 156 | body.data.items = body.data.items.filter(i => i.model_type === 'note'); 157 | } 158 | } else if (url.includes('/v1/note/live_photo/save')) { 159 | console.log('原body:' + rsp_body); 160 | const rsp = this['fmz200.xiaohongshu.feed.rsp']; 161 | console.log('读取缓存key:fmz200.xiaohongshu.feed.rsp'); 162 | // console.log("读取缓存val:" + rsp); 163 | if (rsp == null) { 164 | console.log('缓存无内容,返回原body'); 165 | return; 166 | } 167 | 168 | const cache_body = rsp; 169 | let new_data = []; 170 | for (const images of cache_body) { 171 | if (images.live_photo_file_id) { 172 | const item = { 173 | file_id: images.live_photo_file_id, 174 | video_id: images.live_photo.media.video_id, 175 | url: images.live_photo.media.stream.h265[0].master_url, 176 | }; 177 | new_data.push(item); 178 | } 179 | } 180 | if (body.data.datas) { 181 | replaceUrlContent(body.data.datas, new_data); 182 | } else { 183 | body = { code: 0, success: true, msg: '成功', data: { datas: new_data } }; 184 | } 185 | } 186 | 187 | return { body }; 188 | }, 189 | }, 190 | { 191 | on: 'res-body', 192 | ruleId: 'xiaohongshuVip', 193 | desc: '小红书去广告、解除下载限制、画质增强等', 194 | method: '*', 195 | mitm: '*.xiaohongshu.com', 196 | url: 'https://edith.xiaohongshu.com/api/sns/v*/{note,homefeed,system_service,search}**', 197 | handler({ resBody: body, url, X }) { 198 | // @see https://raw.githubusercontent.com/ddgksf2013/Scripts/master/redbook_json.js 199 | if (body) { 200 | switch (!0) { 201 | case /api\/sns\/v\d\/note\/widgets/.test(url): 202 | try { 203 | let e = body, 204 | t = ['goods_card_v2', 'note_next_step']; 205 | for (let a of t) e.data?.[a] && delete e.data[a]; 206 | } catch (s) { 207 | console.log('widgets: ' + s); 208 | } 209 | break; 210 | case /api\/sns\/v\d\/note\/redtube/.test(url): 211 | try { 212 | let o = body; 213 | for (let d of o.data.items) 214 | d.related_goods_num && (d.related_goods_num = 0), 215 | d.has_related_goods && (d.has_related_goods = !1), 216 | d.media_save_config && (d.media_save_config = { disable_save: !1, disable_watermark: !0, disable_weibo_cover: !0 }), 217 | d.share_info && 218 | (d.share_info.function_entries = [ 219 | { type: 'video_download' }, 220 | { type: 'generate_image' }, 221 | { type: 'copy_link' }, 222 | { type: 'native_voice' }, 223 | { type: 'video_speed' }, 224 | { type: 'dislike' }, 225 | { type: 'report' }, 226 | { type: 'video_feedback' }, 227 | ]); 228 | } catch (r) { 229 | console.log('redtube: ' + r); 230 | } 231 | break; 232 | case /api\/sns\/v\d\/note\/videofeed/.test(url): 233 | try { 234 | let i = body; 235 | for (let l of i.data) 236 | l.related_goods_num && (l.related_goods_num = 0), 237 | l.has_related_goods && (l.has_related_goods = !1), 238 | l.media_save_config && (l.media_save_config = { disable_save: !1, disable_watermark: !0, disable_weibo_cover: !0 }), 239 | l.share_info && 240 | (l.share_info.function_entries = [ 241 | { type: 'video_download' }, 242 | { type: 'generate_image' }, 243 | { type: 'copy_link' }, 244 | { type: 'native_voice' }, 245 | { type: 'video_speed' }, 246 | { type: 'dislike' }, 247 | { type: 'report' }, 248 | { type: 'video_feedback' }, 249 | ]); 250 | } catch (n) { 251 | console.log('videofeed: ' + n); 252 | } 253 | break; 254 | case /api\/sns\/v\d\/note\/feed/.test(url): 255 | try { 256 | let c = body; 257 | for (let y of c.data) 258 | if ((y.related_goods_num && (y.related_goods_num = 0), y.has_related_goods && (y.has_related_goods = !1), y.note_list)) 259 | for (let g of y.note_list) g.media_save_config = { disable_save: !1, disable_watermark: !0, disable_weibo_cover: !0 }; 260 | } catch (f) { 261 | console.log('feed: ' + f); 262 | } 263 | break; 264 | case /api\/sns\/v\d\/homefeed\/categories\?/.test(url): 265 | try { 266 | let b = body; 267 | b.data.categories = b.data.categories.filter(e => !('homefeed.shop' == e.oid || 'homefeed.live' == e.oid)); 268 | } catch (p) { 269 | console.log('categories: ' + p); 270 | } 271 | break; 272 | case /api\/sns\/v\d\/search\/hint/.test(url): 273 | try { 274 | let h = body; 275 | h.data?.hint_words && 276 | (h.data.hint_words = [{ title: '搜索笔记', type: 'firstEnterOther#itemCfRecWord#搜索笔记#1', search_word: '搜索笔记' }]); 277 | } catch (v) { 278 | console.log('hint: ' + v); 279 | } 280 | break; 281 | case /api\/sns\/v\d\/search\/hot_list/.test(url): 282 | try { 283 | let m = body; 284 | m.data = { scene: '', title: '', items: [], host: '', background_color: {}, word_request_id: '' }; 285 | } catch (u) { 286 | console.log('hot_list: ' + u); 287 | } 288 | break; 289 | case /api\/sns\/v\d\/search\/trending/.test(url): 290 | try { 291 | let k = body; 292 | k.data = { title: '', queries: [], type: '', word_request_id: '' }; 293 | } catch (e) { 294 | console.log('trending: ', e); 295 | } 296 | break; 297 | case /api\/sns\/v\d\/system_service\/splash_config/.test(url): 298 | try { 299 | let w = body; 300 | w.data.ads_groups.forEach(e => { 301 | (e.start_time = '2208963661'), 302 | (e.end_time = '2209050061'), 303 | e.ads && 304 | e.ads.forEach(e => { 305 | (e.start_time = '2208963661'), (e.end_time = '2209050061'); 306 | }); 307 | }); 308 | } catch (_) { 309 | console.log('splash_config: ' + _); 310 | } 311 | break; 312 | case /api\/sns\/v\d\/homefeed\?/.test(url): 313 | try { 314 | let q = body; 315 | q.data = q.data.filter(e => !e.is_ads); 316 | } catch (E) { 317 | console.log('homefeed: ' + E); 318 | } 319 | break; 320 | case /api\/sns\/v\d\/system_service\/config\?/.test(url): 321 | try { 322 | let x = body, 323 | C = ['store', 'splash', 'loading_img', 'app_theme', 'cmt_words', 'highlight_tab']; 324 | for (let O of C) x.data?.[O] && delete x.data[O]; 325 | } catch (R) { 326 | console.log('system_service: ' + R); 327 | } 328 | break; 329 | default: 330 | return; 331 | } 332 | return { body }; 333 | } 334 | }, 335 | }, 336 | ]; 337 | 338 | // 小红书画质增强:加载2K分辨率的图片 339 | function imageEnhance(jsonStr) { 340 | const regex1 = /imageView2\/2\/w\/\d+\/format/g; 341 | jsonStr = jsonStr.replace(regex1, `imageView2/2/w/2160/format`); 342 | 343 | const regex2 = /imageView2\/2\/h\/\d+\/format/g; 344 | jsonStr = jsonStr.replace(regex2, `imageView2/2/h/2160/format`); 345 | console.log('图片画质增强完成✅'); 346 | return JSON.parse(jsonStr); 347 | } 348 | 349 | function replaceUrlContent(collectionA, collectionB) { 350 | console.log('替换无水印的URL'); 351 | collectionA.forEach(itemA => { 352 | const matchingItemB = collectionB.find(itemB => itemB.file_id === itemA.file_id); 353 | if (matchingItemB) { 354 | itemA.url = itemA.url.replace(/(.*)\.mp4/, `${matchingItemB.url.match(/(.*)\.mp4/)[1]}.mp4`); 355 | itemA.author = '@renxia'; 356 | } 357 | }); 358 | } 359 | -------------------------------------------------------------------------------- /src/vip/ximalaya.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:08:29 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-09-30 11:27:14 6 | * @Description: 待验证 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | { 12 | // @see https://github.com/ddgksf2013/Scripts/raw/master/ximalaya_json.js 13 | on: 'res-body', 14 | ruleId: 'ximalayaADBlock', 15 | desc: '喜马拉雅去广告', 16 | method: '*', 17 | url: 'https://*.ximalaya.com/{focus-mobile,discovery-feed,discovery-category,mobile-user,mobile-playpage,starwar,mobile,product}/**', 18 | handler({ resBody: body, url, X }) { 19 | if (!body || Buffer.isBuffer(body)) return; 20 | if (typeof body === 'string') return; 21 | 22 | const color = X.FeUtils.color; 23 | console.log(`[${this.desc}]`, color.gray(url)); 24 | let hit = commModify(body); 25 | 26 | switch (!0) { 27 | case /discovery-category\/customCategories/.test(url): 28 | try { 29 | let e = body; 30 | if (e.customCategoryList) { 31 | e.customCategoryList = e.customCategoryList.filter( 32 | e => 33 | ('recommend' == e.itemType || 'template_category' == e.itemType || 'single_category' == e.itemType) && 34 | 1005 !== e.categoryId 35 | ); 36 | hit++; 37 | } 38 | if (e.defaultTabList) { 39 | e.defaultTabList = e.defaultTabList.filter( 40 | e => 41 | ('recommend' == e.itemType || 'template_category' == e.itemType || 'single_category' == e.itemType) && 42 | 1005 !== e.categoryId 43 | ); 44 | hit++; 45 | } 46 | } catch (t) { 47 | console.log('customCategories: ' + t); 48 | } 49 | break; 50 | case /discovery-category\/v\d\/category/.test(url): 51 | try { 52 | let a = body; 53 | if (a.focusImages && a.focusImages.data) { 54 | a.focusImages.data = a.focusImages.data.filter(e => -1 != e.realLink.indexOf('open') && !e.isAd); 55 | hit++; 56 | } 57 | } catch (r) { 58 | console.log('categories: ' + r); 59 | } 60 | break; 61 | case /focus-mobile\/focusPic/.test(url): 62 | try { 63 | let s = body; 64 | if (s.header && s.header.length <= 1) { 65 | s.header[0].item.list[0].data = s.header[0].item.list[0].data.filter(e => -1 != e.realLink.indexOf('open') && !e.isAd); 66 | hit++; 67 | } 68 | } catch (i) { 69 | console.log('discovery-feed' + i); 70 | } 71 | break; 72 | case /discovery-feed\/v\d\/mix/.test(url): 73 | try { 74 | if (body.header?.length == 2) { 75 | delete body.header[0]; 76 | body.body = body.body.filter(e => !(e.item?.adInfo || e.item?.moduleType == 'mix_ad' || 'bigCard' == e.displayClass)); 77 | hit++; 78 | } 79 | } catch (d) { 80 | console.log('discovery-feed:' + d); 81 | } 82 | break; 83 | case /mobile-user\/v\d\/homePage/.test(url): 84 | try { 85 | let c = new Set([210, 213, 215]), 86 | y = body; 87 | if (y.data.serviceModule.entrances) { 88 | let l = y.data.serviceModule.entrances.filter(e => c.has(e.id)); 89 | y.data.serviceModule.entrances = l; 90 | hit = 1; 91 | } 92 | } catch (g) { 93 | console.log('mobile-user:' + g); 94 | } 95 | break; 96 | default: 97 | break; 98 | } 99 | 100 | if (hit) { 101 | console.log(` - [updated][${color.green(this.desc)}]`, color.gray(url)); 102 | return { body }; 103 | } 104 | }, 105 | }, 106 | ]; 107 | 108 | function commModify(body) { 109 | let hit = 0; 110 | 111 | if (Array.isArray(body)) { 112 | body.forEach(item => commModify(item) && (hit = 1)); 113 | return hit; 114 | } 115 | 116 | if (!body || typeof body !== 'object') return hit; 117 | 118 | for (const [key, val] of Object.entries(body)) { 119 | switch (key) { 120 | case 'trackInfo': 121 | if (val && val.trackId) { 122 | Object.assign(val, { 123 | authorizedType: 0, 124 | permissionSource: '108', 125 | permissionExpireTime: 253402271999000, 126 | isVip: false, 127 | isVipFree: true, 128 | }); 129 | hit = 1; 130 | continue; 131 | } 132 | case 'picbook': 133 | continue; 134 | case 'expireTime': 135 | body[key] = 4073558400000; 136 | hit = 1; 137 | continue; 138 | case 'isFree': 139 | case 'isVip': 140 | case 'isEnglishVip': 141 | case 'isXiaoyaUser': 142 | case 'isVipFree': 143 | case 'isAuthorized': 144 | case 'isXimiUhqAuthorized': 145 | case 'hasShqAuthorized': 146 | case 'inThreeMonth': 147 | case 'canFreeListen': 148 | case 'havePurchased': 149 | case 'isShowEntrance': 150 | case 'isVerified': 151 | case 'isXimiUhqTrack': 152 | case 'currentUserIsCopyright': 153 | case 'hasCart': 154 | body[key] = true; 155 | hit = 1; 156 | continue; 157 | case 'hqNeedVip': 158 | body[key] = false; 159 | hit = 1; 160 | continue; 161 | case 'ximiFirstStatus': 162 | case 'vipFirstStatus': 163 | case 'paidType': 164 | case 'tailSkip': 165 | case 'childAlbumInWhiteList': 166 | case 'freeListenStatus': 167 | body[key] = 1; 168 | hit = 1; 169 | continue; 170 | case 'sampleDuration': 171 | body[key] = 1000000; 172 | hit = 1; 173 | default: 174 | if (commModify(val)) hit = 1; 175 | } 176 | } 177 | 178 | return hit; 179 | } 180 | -------------------------------------------------------------------------------- /src/vip/xunlei.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:08:29 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-03-04 16:37:08 6 | * @Description: 待验证 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | { 12 | on: 'res-body', 13 | ruleId: 'xunleiVipCrack', 14 | desc: '迅雷 VIP', 15 | method: '*', 16 | mitm: 'xluser-ssl.zhihu.com', 17 | url: "https://xluser-ssl.xunlei.com/xluser.core.login/v3/getuserinfo", 18 | handler({ resBody: body, url, X }) { 19 | if (typeof body === 'object') { 20 | const color = X.FeUtils.color; 21 | console.log(`[${this.desc}]`, color.gray(url)); 22 | 23 | body.vipList = [ 24 | { 25 | expireDate: '20290609', 26 | isAutoDeduct: '0', 27 | isVip: '1', 28 | isYear: '1', 29 | payId: '0', 30 | payName: '---', 31 | register: '0', 32 | vasid: '2', 33 | vasType: '5', 34 | vipDayGrow: '20', 35 | vipGrow: '840', 36 | vipLevel: '7', 37 | }, 38 | ]; 39 | 40 | return { body }; 41 | } 42 | }, 43 | }, 44 | ]; 45 | -------------------------------------------------------------------------------- /src/vip/zhihu.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-28 10:08:29 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-03-01 14:02:43 6 | * @Description: 待验证 7 | */ 8 | 9 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 10 | module.exports = [ 11 | { 12 | on: 'res-body', 13 | ruleId: 'zhihuFilter', 14 | desc: '知乎去广告', 15 | method: '*', 16 | url: 'https://{api,www,m-cloud,appcloud2}.zhihu.com/**', 17 | handler({ resBody: body, headers, url, X }) { 18 | if (!X.isText(headers) || Buffer.isBuffer(body) || typeof body !== 'object') return; 19 | 20 | let hit = 0; 21 | if ('svip_privileges' in body) { 22 | hit = 1; 23 | body.svip_privileges = true; 24 | } 25 | 26 | if (body.right?.ownership === false) { 27 | hit = 1; 28 | Object.assign(body, { 29 | ownership: true, 30 | purchased: true, 31 | anonymous: true, 32 | }); 33 | } 34 | 35 | if (!hit) { 36 | const regList = [ 37 | /^https:\/\/api\.zhihu\.com\/commercial_api\/app_float_layer/, 38 | /^https:\/\/api\.zhihu\.com\/feed\/render\/tab\/config/, 39 | /^https:\/\/api\.zhihu\.com\/(moments_v3|topstory\/hot-lists\/total|topstory\/recommend)/, 40 | /^https:\/\/api\.zhihu\.com\/v2\/topstory\/hot-lists\/everyone-seeing/, 41 | /^https:\/\/api\.zhihu\.com\/next-(bff|data|render)/, 42 | /^https:\/\/api\.zhihu\.com\/questions\/\d+(\/answers|\/feeds|\?include=)/, 43 | /^https:\/\/www\.zhihu\.com\/api\/v4\/(articles|answers)\/\d+\/recommendations?/, 44 | /^https:\/\/appcloud2\.zhihu\.com\/v3\/config/, 45 | /^https:\/\/m-cloud\.zhihu\.com\/api\/cloud\/config\/all/, 46 | /sku\/reversion_sku_ext/, 47 | /people\/self/, 48 | /unlimited\/go\/my_card/, 49 | /\/books\/\d+/, 50 | ]; 51 | if (!regList.some(reg => reg.test(url))) return; 52 | } 53 | 54 | const color = X.FeUtils.color; 55 | console.log(`[${this.desc}]`, color.gray(url)); 56 | 57 | // 参考: https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/zhihu.js 58 | // 2023-11-17 11:30 59 | 60 | let obj = body; 61 | let bodyStr = JSON.stringify(body); 62 | 63 | if (body.vip_info && url.indexOf('people/self') != -1) { 64 | X.FeUtils.assign(body, { 65 | vip_info: { 66 | is_vip: true, 67 | vip_type: 1, 68 | }, 69 | }); 70 | hit = 1; 71 | 72 | return { body }; 73 | } 74 | 75 | if (url.indexOf('unlimited/go/my_card') != -1) { 76 | X.FeUtils.assign(body, { 77 | button_text: '点击反馈', 78 | jump_url: 'https://github.com/lzwme/x-scripts-rules/issues', 79 | title: '2999-09-09到期', 80 | songNeedPay: 0, 81 | }); 82 | 83 | return { body }; 84 | } 85 | 86 | if (url.indexOf('sku/reversion_sku_ext') != -1) { 87 | body.data.center.buttons[1].sub_text = '无法观看?点击此处反馈!'; 88 | body.data.center.buttons[1].link_url = 'https://github.com/lzwme/x-scripts-rules/issues'; 89 | body.data.center.buttons[1].button_text = '已解锁该内容'; 90 | body.data.bottom.buttons[1].button_text = '立即阅读'; 91 | body.data.center.buttons[0].sub_text = '已解锁'; 92 | return { body }; 93 | } 94 | 95 | if (url.includes('/api/cloud/config/all')) { 96 | if (obj?.data?.configs) { 97 | obj.data.configs.forEach(i => { 98 | if (i.configKey === 'feed_gray_theme') { 99 | if (i.configValue) { 100 | i.configValue.start_time = '3818332800'; // Unix 时间戳 2090-12-31 00:00:00 101 | i.configValue.end_time = '3818419199'; // Unix 时间戳 2090-12-31 23:59:59 102 | i.status = false; 103 | } 104 | } else if (i.configKey === 'feed_top_res') { 105 | if (i.configValue) { 106 | i.configValue.start_time = '3818332800'; // Unix 时间戳 2090-12-31 00:00:00 107 | i.configValue.end_time = '3818419199'; // Unix 时间戳 2090-12-31 23:59:59 108 | i.status = false; 109 | } 110 | } 111 | }); 112 | } 113 | } else if (url.includes('/api/v4/answers')) { 114 | if (obj?.data) { 115 | delete obj.data; 116 | } 117 | if (obj?.paging) { 118 | delete obj.paging; 119 | } 120 | } else if (url.includes('/api/v4/articles')) { 121 | const item = ['ad_info', 'paging', 'recommend_info']; 122 | item.forEach(i => { 123 | delete obj[i]; 124 | }); 125 | } else if (url.includes('.zhihu.com/v3/config')) { 126 | if (obj?.config) { 127 | if (obj.config?.homepage_feed_tab) { 128 | obj.config.homepage_feed_tab.tab_infos = obj.config.homepage_feed_tab.tab_infos.filter(i => { 129 | if (i.tab_type === 'activity_tab') { 130 | i.start_time = '3818332800'; // Unix 时间戳 2090-12-31 00:00:00 131 | i.end_time = '3818419199'; // Unix 时间戳 2090-12-31 23:59:59 132 | return true; 133 | } else { 134 | return false; 135 | } 136 | }); 137 | } 138 | if (obj.config?.hp_channel_tab) { 139 | delete obj.config.hp_channel_tab; 140 | } 141 | if (obj.config?.zombie_conf) { 142 | obj.config.zombie_conf.zombieEnable = false; 143 | } 144 | if (obj.config?.gray_mode) { 145 | obj.config.gray_modeenable = false; 146 | obj.config.gray_mode.start_time = '3818332800'; // Unix 时间戳 2090-12-31 00:00:00 147 | obj.config.gray_mode.end_time = '3818419199'; // Unix 时间戳 2090-12-31 23:59:59 148 | } 149 | if (obj.config?.zhcnh_thread_sync) { 150 | obj.config.zhcnh_thread_sync.LocalDNSSetHostWhiteList = []; 151 | obj.config.zhcnh_thread_sync.isOpenLocalDNS = '0'; 152 | obj.config.zhcnh_thread_sync.ZHBackUpIP_Switch_Open = '0'; 153 | obj.config.zhcnh_thread_sync.dns_ip_detector_operation_lock = '1'; 154 | obj.config.zhcnh_thread_sync.ZHHTTPSessionManager_setupZHHTTPHeaderField = '1'; 155 | } 156 | obj.config.zvideo_max_number = 1; 157 | obj.config.is_show_followguide_alert = false; 158 | } 159 | } else if (url.includes('/commercial_api/app_float_layer')) { 160 | // 悬浮图标 161 | if ('feed_egg' in obj) { 162 | delete obj.feed_egg; 163 | } 164 | } else if (url.includes('/feed/render/tab/config')) { 165 | if (obj?.selected_sections?.length > 0) { 166 | // 首页顶部tab 167 | obj.selected_sections = obj.selected_sections.filter(i => !['activity', 'live']?.includes(i?.tab_type)); 168 | } 169 | } else if (url.includes('/moments_v3')) { 170 | if (obj?.data?.length > 0) { 171 | obj.data = obj.data.filter(i => !i?.title?.includes('为您推荐')); 172 | } 173 | } else if (url.includes('/next-bff')) { 174 | if (obj?.data?.length > 0) { 175 | obj.data = obj.data.filter( 176 | i => 177 | !( 178 | i?.origin_data?.type?.includes('ad') || 179 | i?.origin_data?.resource_type?.includes('ad') || 180 | i?.origin_data?.next_guide?.title?.includes('推荐') 181 | ) 182 | ); 183 | } 184 | } else if (url.includes('/next-data')) { 185 | if (obj?.data?.data?.length > 0) { 186 | obj.data.data = obj.data.data.filter(i => !(i?.type?.includes('ad') || i?.data?.answer_type?.includes('PAID'))); 187 | } 188 | } else if (url.includes('/next-render')) { 189 | if (obj?.data?.length > 0) { 190 | obj.data = obj.data.filter( 191 | i => 192 | !( 193 | i?.adjson || 194 | i?.biz_type_list?.includes('article') || 195 | i?.biz_type_list?.includes('content') || 196 | i?.business_type?.includes('paid') || 197 | i?.section_info || 198 | i?.tips || 199 | i?.type?.includes('ad') 200 | ) 201 | ); 202 | } 203 | } else if (url.includes('/questions/')) { 204 | // 问题回答列表 205 | if (obj?.data?.length > 0) { 206 | obj.data = obj.data.filter(i => !i?.target?.answer_type?.includes('paid')); 207 | } 208 | if (obj?.data?.ad_info) { 209 | delete obj.data.ad_info; 210 | } 211 | if (obj?.ad_info) { 212 | delete obj.ad_info; 213 | } 214 | if (obj?.query_info) { 215 | delete obj.query_info; 216 | } 217 | } else if (url.includes('/topstory/hot-lists/everyone-seeing')) { 218 | // 热榜信息流 219 | if (obj?.data?.data?.length > 0) { 220 | // 合作推广 221 | obj.data.data = obj.data.data.filter(i => !i.target?.metrics_area?.text?.includes('合作推广')); 222 | } 223 | } else if (url.includes('/topstory/hot-lists/total')) { 224 | // 热榜排行榜 225 | if (obj?.data?.length > 0) { 226 | // 品牌甄选 227 | obj.data = obj.data.filter(i => !i?.hasOwnProperty('ad')); 228 | } 229 | } else if (url.includes('/topstory/recommend')) { 230 | // 推荐信息流 231 | if (obj.data?.length > 0) { 232 | obj.data = obj.data.filter(i => { 233 | if (i.type === 'market_card' && i.fields?.header?.url && i.fields.body?.video?.id) { 234 | let videoID = getUrlParamValue(item.fields.header.url, 'videoID'); 235 | if (videoID) { 236 | i.fields.body.video.id = videoID; 237 | } 238 | } else if (i.type === 'common_card') { 239 | if (i.extra?.type === 'drama') { 240 | // 直播内容 241 | return false; 242 | } else if (i.extra?.type === 'zvideo') { 243 | // 推广视频 244 | let videoUrl = i.common_card.feed_content.video.customized_page_url; 245 | let videoID = getUrlParamValue(videoUrl, 'videoID'); 246 | if (videoID) { 247 | i.common_card.feed_content.video.id = videoID; 248 | } 249 | } else if (i.common_card?.feed_content?.video?.id) { 250 | let search = '"feed_content":{"video":{"id":'; 251 | let str = bodyStr.substring(bodyStr.indexOf(search) + search.length); 252 | let videoID = str.substring(0, str.indexOf(',')); 253 | i.common_card.feed_content.video.id = videoID; 254 | } else if (i.common_card?.footline?.elements?.[0]?.text?.panel_text?.includes('广告')) { 255 | return false; 256 | } else if (i.common_card?.feed_content?.source_line?.elements?.[1]?.text?.panel_text?.includes('盐选')) { 257 | return false; 258 | } else if (i?.promotion_extra) { 259 | // 营销信息 260 | return false; 261 | } 262 | return true; 263 | } else if (i.type.includes('aggregation_card')) { 264 | // 横排卡片 知乎热榜 265 | return false; 266 | } else if (i.type === 'feed_advert') { 267 | // 伪装成正常内容的卡片 268 | return false; 269 | } 270 | return true; 271 | }); 272 | fixPos(obj.data); 273 | } 274 | } 275 | 276 | return { body: obj }; 277 | }, 278 | }, 279 | ]; 280 | 281 | // 修复offset 282 | function fixPos(arr) { 283 | for (let i = 0; i < arr.length; i++) { 284 | arr[i].offset = i + 1; 285 | } 286 | } 287 | 288 | function getUrlParamValue(url, queryName) { 289 | return Object.fromEntries( 290 | url 291 | .substring(url.indexOf('?') + 1) 292 | .split('&') 293 | .map(pair => pair.split('=')) 294 | )[queryName]; 295 | } 296 | -------------------------------------------------------------------------------- /src/youzan-liteapp.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: renxia 3 | * @Date: 2024-02-06 11:25:49 4 | * @LastEditors: renxia 5 | * @LastEditTime: 2024-04-09 09:16:31 6 | * @Description: 7 | */ 8 | 9 | const pd_map = { 10 | 8: '韩都严选', 11 | 17: '极客农场与胡子叔的餐盘', 12 | 47: '植观微信旗舰店', 13 | 102: '榴芒一刻', 14 | 347: '乒乓生活商城', 15 | 379: '燕之坊五谷为养官方商城', 16 | 816: '名后官方旗舰店', 17 | 1220: '良品铺子官方商城', // 连续签到领优惠券 18 | 1380: '幸福西饼', 19 | 1579: '等蜂来天然蜂蜜旗舰店', 20 | 1612: '新疆万科广场店', 21 | 1631: '云南白药', 22 | 1700: '中粮-健康生活甄选', 23 | 2042: '物道生活', 24 | 2426: '钟薛高旗舰店', 25 | 2527: '米卡米卡蛋糕旗舰店', 26 | 2728: '小香真精油旗舰店', 27 | 2729: '相逢幸福 生日蛋糕 下午茶', 28 | 3124: '东鹏特饮微店', 29 | 3262: 'TOIs朵茜情调生活馆', 30 | 3821: '乐汁商城-素食更健康', 31 | 4345: '悦上美妆', 32 | 4744: '环球嗨购精选', 33 | 5054: '自然兰官方旗舰店', 34 | 5998: '森马集团官方商城', 35 | 7302: '暖家好物', 36 | 8249: '贝因美贝家商城', 37 | 8353: '润百颜护肤品商城', 38 | 8449: '中国原产递优选', 39 | 8887: '印趣严选', 40 | 9332: '三只松鼠旗舰店', 41 | 12307: 'colorkey珂拉琪旗舰店', 42 | 13546: '广缘唐海曹妃甸店', 43 | 13891: '潘达微信旗舰店', 44 | 13904: '小茶婆婆旗舰店', 45 | 13968: '圣牧有机官方商城', 46 | 16453: 'PMPM', 47 | 17273: '香气优选', 48 | 17666: '爱依服商城-总店', 49 | 18415: '得宝Tempo', 50 | 22432: '一封情酥', 51 | 1465878: '隅田川旗舰店', 52 | 1479428: 'ffit8', 53 | 1595664: '参半口腔护理', 54 | 1597464: 'Xbox俱乐部', 55 | 1876007: 'FLORTTE花洛莉亚', 56 | 1903120: 'KIMTRUE且初', 57 | 1985507: '肤漾FORYON', 58 | 2050884: '伯喜线上商城', 59 | 2081204: '果壳市集', 60 | 2176467: 'chillmore且悠', 61 | 2187565: '蜜蜂惊喜社', 62 | 2299510: '燕京啤酒电商旗舰店', 63 | 2386563: 'HBN品牌店', 64 | 2646845: '海贽医疗科技', 65 | 2692852: '老爹果园', 66 | 2713880: '莱克旗舰店', 67 | 2905214: '百事可乐', 68 | 2910869: 'ficcecode菲诗蔻官方旗舰店', 69 | 2923467: '红之旗舰店', 70 | 3010256: '燕子约官方旗舰店', 71 | 3014060: 'LAN蘭', 72 | 3347128: '松鲜鲜官方旗舰店', 73 | 3805112: '广州日报电商', 74 | }; 75 | 76 | /** @type {import('@lzwme/whistle.x-scripts').RuleItem[]} */ 77 | module.exports = [ 78 | { 79 | on: 'res-body', 80 | ruleId: 'youzan_le_data', 81 | desc: '有赞小程序签到', 82 | url: ['https://h5.youzan.com/wscump/checkin/*', 'https://h5.youzan.com/{wscuser,wscdeco}/**'], 83 | method: '*', 84 | cache: {}, // app_id: { checkinId, uid } 85 | getCacheUid({ url, X, headers, resBody }) { 86 | let { app_id, checkinId, buyerId } = X.FeUtils.getUrlParams('?' + url.split('?')[1]); 87 | if (!app_id) app_id = /\/(wx.+)\//.exec(headers['referer'])?.[1]; 88 | if (!app_id) return; 89 | 90 | const shopName = resBody?.data?.shopName || pd_map[checkinId] || ''; 91 | if (!this.cache[app_id]) this.cache[app_id] = {}; 92 | if (checkinId) this.cache[app_id].checkinId = checkinId; 93 | if (+buyerId) this.cache[app_id].uid = buyerId; 94 | if (shopName) this.cache[app_id].shopName = shopName; 95 | 96 | if (headers['extra-data']?.startsWith('{')) { 97 | const { checkinId, uid, shopName = '' } = this.cache[app_id]; 98 | if (checkinId && uid) { 99 | const edata = JSON.parse(headers['extra-data']); 100 | const sessionId = edata.sid; 101 | console.log(`'${checkinId}': '${shopName}',`, uid, sessionId); 102 | 103 | if (shopName && !pd_map[checkinId]) { 104 | pd_map[checkinId] = shopName; 105 | console.log(pd_map); 106 | } 107 | 108 | if (sessionId) { 109 | return { uid: `${checkinId}_${uid}`, data: `${checkinId}:${sessionId}##${uid}_${checkinId}${shopName ? `_${shopName}` : ''}` }; 110 | } 111 | } 112 | } 113 | }, 114 | handler: ({ allCacheData: d }) => ({ envConfig: { value: d.map(d => `${d.data}`).join('\n') } }), 115 | updateEnvValue: /##\d+_\d+/, 116 | }, 117 | ]; 118 | -------------------------------------------------------------------------------- /whistle-rules/ad-block.txt: -------------------------------------------------------------------------------- 1 | # 避免迅雷版权问题 2 | hub5idx.v6.shub.sandai.net statusCode://200 3 | hub5emu.v6.shub.sandai.net statusCode://200 4 | hub5btmain.v6.shub.sandai.net statusCode://200 5 | 6 | # 绕过 IOS 企业证书过期 7 | ocsp.apple.com statusCode://200 8 | 9 | # 百度地图 @see https://gist.githubusercontent.com/ddgksf2013/beec132ca0c3570ffa0cf331bce8f82a/raw/baidumap.adblock.conf 10 | ^https?:\/\/ugc\.map\.baidu\.com\/govui\/rich_content statusCode://200 11 | ^https?:\/\/newclient\.map\.baidu\.com\/client\/phpui.*qt=hw statusCode://200 12 | ^https?:\/\/newclient\.map\.baidu\.com\/client\/phpui2\/\?qt=ads statusCode://200 13 | # 百度地图_DNS处理 14 | ^https?:\/\/httpdns\.baidubce\.com statusCode://200 15 | ^https?:\/\/newclient\.map\.baidu\.com\/client\/crossmarketing statusCode://200 16 | ^https?:\/\/newclient\.map\.baidu\.com\/client\/usersystem\/home\/dynamic statusCode://200 17 | 18 | # 小红书 @see https://raw.githubusercontent.com/ddgksf2013/Rewrite/master/AdBlock/XiaoHongShu.conf 19 | # > 小红书_通用广告请求 20 | ^https?:\/\/www\.xiaohongshu\.com\/api\/sns\/v\d\/(tag\/)?ads statusCode://200 21 | # > 小红书_隐私屏蔽 22 | ^https?:\/\/referee\.xiaohongshu\.com\/v\d\/stateReport statusCode://200 23 | # > 小红书_Switches 24 | ^https?:\/\/pages\.xiaohongshu\.com\/data\/native\/matrix_switches statusCode://200 25 | # > 小红书_青少年请求 26 | ^https?:\/\/edith\.xiaohongshu\.com\/api\/sns\/v\d\/user\/teenager\/status statusCode://200 27 | # > 小红书_启动引导 28 | ^https?:\/\/edith\.xiaohongshu\.com\/api\/sns\/v\d\/guide\/home_guide statusCode://200 29 | 30 | # 喜马拉雅 31 | # ~ XiMaLaYa_喜马拉雅_修复轮播Ad失效Bug 32 | ^https?:\/\/.*\.xima.*\.com\/discovery-feed\/focus\/queryF statusCode://200 33 | # ~ XiMaLaYa_喜马拉雅_播放页_Live 34 | ^https?:\/\/.*\.xima.*\.com\/mobile-playpage\/view\/ statusCode://200 35 | # ~ XiMaLaYa_喜马拉雅_MyInfo红点提醒 36 | ^https?:\/\/.*\.xima.*\.com\/chaos-notice-web\/v1\/message\/preview\/list statusCode://200 37 | # ~ XiMaLaYa_喜马拉雅_屏蔽大红包Tips 38 | ^https?:\/\/.*\.xima.*\.com\/social-web\/bottomTabs\/dynamicEntrance\/status statusCode://200 39 | # ~ XiMaLaYa_喜马拉雅_屏蔽gif弹窗Ad 40 | ^https?:\/\/.*\.xmcdn\.com\/\w{8}\/\w{4}-\w{16}\/.+gif$ statusCode://200 41 | # ~ XiMaLaYa_喜马拉雅_gslb 42 | ^https?:\/\/gslb.*\.xima.*\.com\/ statusCode://200 43 | # ~ XiMaLaYa_喜马拉雅_屏蔽Aged请求 44 | ^https?:\/\/.*\.xima.*\.com\/(dog-portal\/checkOld|(child-mobile\/child|aged-mobile\/aged)\/mode\/query) statusCode://200 45 | # ~ XiMaLaYa_喜马拉雅_部分Tab弹窗 46 | ^https?:\/\/.*\.xima.*\.com\/discovery-feed\/isShowUserGiftPendant statusCode://200 47 | # ~ XiMaLaYa_喜马拉雅_屏蔽红点提示 48 | ^https?:\/\/.*\.xima.*\.com\/mobile-user\/unread statusCode://200 49 | # ~ XiMaLaYa_喜马拉雅_屏蔽minor请求 50 | ^https?:\/\/.*\.xima.*\.com/mobile-user/minorProtection/pop statusCode://200 51 | # ~ XiMaLaYa_喜马拉雅_屏蔽隐私搜集 52 | ^https?:\/\/.*\.xima.*\.com\/collector\/xl\/v\d statusCode://200 53 | # ~ XiMaLaYa_喜马拉雅_屏蔽版本更新 54 | ^https?:\/\/.*\.xima.*\.com\/butler-portal\/versionCheck statusCode://200 55 | # ~ XiMaLaYa_喜马拉雅_屏蔽开屏广告 56 | ^https?:\/\/(adse\.wsa|adse|adbehavior|xdcs-collector)\.xima.*\.com\/.* statusCode://200 57 | # ~ XiMaLaYa_喜马拉雅_屏蔽位置请求 58 | ^https?:\/\/.*\.xima.*\.com\/mobile\/discovery\/v\d\/location statusCode://200 59 | # ~ XiMaLaYa_喜马拉雅_屏蔽热搜词 60 | ^https?:\/\/.*\.xima.*\.com\/hotWord statusCode://200 61 | # ~ XiMaLaYa_喜马拉雅_屏蔽搜索框定时_Ad 62 | ^https?:\/\/.*\.xima.*\.com\/(hub)?guideWord statusCode://200 63 | # ~ XiMaLaYa_喜马拉雅_屏蔽实时Ad请求 64 | ^https?:\/\/.*\.xima.*\.com\/api\/v\d\/adRealTime statusCode://200 65 | # ~ XiMaLaYa_喜马拉雅_屏蔽ting_Ad 66 | ^https?:\/\/.*\.xima.*\.com\/ting\/(loading|feed|home)? statusCode://200 67 | -------------------------------------------------------------------------------- /whistle-rules/x.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | "www.zhihu.com ua://{iphoneUA}", 4 | "^https?://www\\.bing\\.com/(search|new|web) ua://{edgUA}" 5 | ], 6 | "values": { 7 | "iphoneUA": "osee2unifiedRelease/17634_osee2unifiedReleaseVersion/9.38.1_Mozilla/5.0_(iPhone;CPU_iPhone_OS 17_0_2_like_Mac_OS_X)_AppleWebKit/605.1.15_Mobile/15E148", 8 | "edgUA": "AppleWebKit/537.36 Chrome/110.0 Safari/537.36 Edg/110.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /whistle-rules/zhihu.txt: -------------------------------------------------------------------------------- 1 | # test: 知乎过滤 2 | ^https://www.zhihu.com/api/v4/questions/*/related-readings statusCode://200 3 | ^https://www.zhihu.com/api/v4/answers/*/related-readings statusCode://200 4 | https://www.zhihu.com/api/v4/hot_recommendation statusCode://200 5 | https://www.zhihu.com/commercial_api/banners_v3/mobile_banner statusCode://200 6 | ^https://zhuanlan.zhihu.com/api/articles/*/recommendation statusCode://200 7 | --------------------------------------------------------------------------------