├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── modules └── core │ ├── Env.js │ ├── Env.min.js │ ├── chavyleung.Env.js │ └── chavyleung.Env.min.js ├── platforms ├── Loon │ ├── BaiduCloud.plugin │ ├── BiliBili.plugin │ ├── BiliRegions.plugin │ ├── ChangeUA.plugin │ ├── Cookie.plugin │ ├── JD_wskey.plugin │ ├── KMUST.plugin │ ├── Leave.plugin │ ├── Location.plugin │ ├── Price.plugin │ ├── Script.plugin │ ├── Scriptable.plugin │ ├── TF-Download.plugin │ ├── TakeAway.plugin │ ├── Tasks.plugin │ ├── Unblock.plugin │ ├── WeiBoAds.plugin │ ├── YoutubeAds.plugin │ ├── leave_gdufe.plugin │ └── qndxx.plugin ├── Surge │ ├── AdvertisingScript.sgmodule │ ├── BaiduCloud.sgmodule │ ├── BiliBiliAds.6.74.0.sgmodule │ ├── Procuratorate.sgmodule │ ├── Script.sgmodule │ ├── Study.sgmodule │ ├── Task.sgmodule │ ├── Unblock.caiyun.sgmodule │ ├── YouTubeAds.18.49.3.sgmodule │ └── backup │ │ ├── Advertising.sgmodule │ │ ├── BiliRegions.sgmodule │ │ ├── CamScanner.sgmodule │ │ ├── ChangeUA.sgmodule │ │ ├── Cookie.sgmodule │ │ ├── JD_wskey.sgmodule │ │ ├── Leave.sgmodule │ │ ├── MGTV.sgmodule │ │ ├── Panel.sgmodule │ │ ├── RRTV_SVIP.sgmodule │ │ ├── Scriptable.sgmodule │ │ ├── TunOnly.sgmodule │ │ ├── Unblock.bak.sgmodule │ │ ├── Unblock.sgmodule │ │ ├── WeiboAds.sgmodule │ │ ├── YouTubeAds.17.16.4.sgmodule │ │ └── ZhiHuAds.sgmodule └── boxjs │ ├── backup │ └── chiupam.boxjs.json │ ├── chiupam.boxjs.json │ ├── chiupam.jpg │ └── icon │ ├── Exchange.jpg │ ├── For_Test.jpg │ ├── GitHub.jpg │ ├── Header.jpeg │ ├── JingDong.png │ ├── Location.jpeg │ ├── Location.png │ ├── NoNotify.jpeg │ ├── Notice.jpeg │ ├── Notify.jpg │ ├── Procuratorate.png │ ├── QQspeed.jpg │ ├── Scriptable.png │ ├── ShareCode.jpeg │ ├── YiBan.jpeg │ ├── gdufe.jpeg │ ├── jd.jpeg │ ├── kmmu.jpeg │ ├── kmmu.png │ ├── kmu.jpg │ ├── kmust.jpeg │ ├── kmust.png │ ├── me.png │ ├── qndxx.jpg │ ├── qndxx.png │ ├── setting.jpg │ ├── tieba.png │ ├── xmSport.jpeg │ └── zsfc.jpeg └── scripts ├── greasyfork ├── sppet.js └── ynsgbzx.js ├── javascript ├── BiliBili │ ├── BiliBili.js │ ├── BiliBiliAds.6.74.0.sgmodule │ └── reject-dict.json ├── TestFlight.js ├── Youtube │ ├── 17.16.4 │ │ ├── YouTubeAds.17.16.4.sgmodule │ │ ├── blank.txt │ │ ├── youtube.js │ │ └── youtube.scr.js │ ├── 18.49.3 │ │ ├── YouTubeAds.18.49.3.sgmodule │ │ ├── blank.txt │ │ ├── youtube.request.js │ │ └── youtube.response.js │ └── README.md ├── alipay.js ├── backup │ ├── Location.js │ ├── elm.js │ ├── epidemic_gdufe.js │ ├── epidemic_kmust.js │ ├── ksjsb.js │ ├── leave_gdufe.js │ ├── leave_kmmu.js │ ├── leave_kmu.js │ ├── mt.js │ ├── netease.docker.js │ ├── qndxx.js │ ├── wskey.js │ ├── xmSport.js │ ├── zsfc.js │ └── zsfc.shop.js ├── panel │ ├── network_info.js │ └── restriction_check.js ├── procuratorate.js ├── tieba.js ├── unblock │ ├── BaiduCloud.js │ ├── CamScanner_Pro.js │ ├── ColorfulClouds_SVIP.js │ ├── Mubu_SVIP.js │ ├── SYJZ_SVIP.js │ └── WPS_SVIP.js ├── xmSport.js ├── xxqg.js ├── zsfc.treasure.js ├── zsfc.v3.js └── zsfc.v4.js └── python └── zsfc ├── zsfc.py └── zsfc_login.py /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS系统文件 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | ._* 6 | 7 | # 缩略图 8 | .Trashes 9 | Thumbs.db 10 | ehthumbs.db 11 | 12 | # IDE文件 13 | .idea/ 14 | .vscode/ 15 | *.sublime-project 16 | *.sublime-workspace 17 | 18 | # 日志文件 19 | *.log 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | 24 | # 依赖目录 25 | node_modules/ 26 | 27 | # 排除src目录下除了obfuscator.js外的所有JavaScript源文件 28 | scripts/javascripts/src/**/*.js 29 | !scripts/javascripts/src/obfuscator.js 30 | 31 | # 忽略临时的更新脚本 32 | update_*.sh 33 | fix_*.sh 34 | 35 | # 常见系统文件 36 | .DS_Store 37 | Thumbs.db 38 | desktop.ini 39 | 40 | # 编辑器临时文件 41 | .vscode/ 42 | .idea/ 43 | *.swp 44 | *.swo 45 | *~ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "scripts/javascript/src"] 2 | path = scripts/javascript/src 3 | url = https://github.com/chiupam/obfuscatedSrc.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Chiupam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 |

4 | 自用脚本集合 5 |
6 | Surge & Loon 7 |

8 | 9 | # 简介 10 | 11 | 存放自己需要用到的各类脚本、模块和插件,包括Surge模块、Loon插件、油猴脚本和BoxJS配置等。 12 | 13 | # 部分项目介绍 14 | 15 | ### 去广告 16 | [![BiliBili去广告](https://img.shields.io/badge/Script-BiliBili去广告-red)](https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/BiliBili/BiliBili.js) 17 | [![YouTube去广告](https://img.shields.io/badge/Script-YouTube去广告-red)](https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube) 18 | 19 | ## Surge 模块(很久未更新,可能已经不适用) 20 | [![广告拦截](https://img.shields.io/badge/Surge-广告拦截-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/AdvertisingScript.sgmodule) 21 | [![百度网盘](https://img.shields.io/badge/Surge-百度网盘-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/BaiduCloud.sgmodule) 22 | [![哔哩哔哩去广告](https://img.shields.io/badge/Surge-哔哩哔哩去广告-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/BiliBiliAds.6.74.0.sgmodule) 23 | [![常用脚本合集](https://img.shields.io/badge/Surge-常用脚本合集-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/Script.sgmodule) 24 | [![学习强国提醒](https://img.shields.io/badge/Surge-学习相关-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/Study.sgmodule) 25 | [![定时任务](https://img.shields.io/badge/Surge-定时任务-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/Task.sgmodule) 26 | [![解锁彩云天气](https://img.shields.io/badge/Surge-解锁彩云天气-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/Unblock.caiyun.sgmodule) 27 | [![YouTube去广告](https://img.shields.io/badge/Surge-YouTube去广告-orange)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/YouTubeAds.18.49.3.sgmodule) 28 | 29 | ## 解锁与功能增强 30 | [![百度网盘](https://img.shields.io/badge/Loon-百度网盘-green)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Loon/BaiduCloud.plugin) 31 | [![B站区域解锁](https://img.shields.io/badge/Loon-B站区域解锁-green)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Loon/BiliRegions.plugin) 32 | [![更换UA](https://img.shields.io/badge/Loon-更换UA-green)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Loon/ChangeUA.plugin) 33 | [![定位相关](https://img.shields.io/badge/Loon-定位相关-green)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Loon/Location.plugin) 34 | [![比价工具](https://img.shields.io/badge/Loon-比价工具-green)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Loon/Price.plugin) 35 | [![解锁功能](https://img.shields.io/badge/Loon-解锁功能-green)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/Loon/Unblock.plugin) 36 | 37 | ## BoxJS 配置 38 | [![BoxJS配置](https://img.shields.io/badge/BoxJS-配置订阅-purple)](https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.boxjs.json) 39 | 40 | # 免责声明 41 | 42 | 本仓库中的脚本仅用于资源共享和学习研究,我不能保证其合法性、准确性、完整性和有效性,请根据情况自行判断。 43 | 44 | 间接使用脚本的任何用户,包括但不限于建立VPS或在某些行为违反国家/地区法律或相关法规的情况下进行传播,对于由此引起的任何隐私泄漏或其他后果概不负责。 45 | 46 | 请勿将本仓库内的任何内容用于商业或非法目的,否则后果自负。 47 | 48 | 如果任何单位或个人认为该项目的脚本可能涉嫌侵犯其权利,应及时通知并提供身份证明、所有权证明,我将在收到认证文件后删除相关脚本。 49 | 50 | 对任何本仓库中包含的脚本在使用中可能出现的问题概不负责,包括但不限于由任何脚本错误导致的任何损失或损害。 51 | 52 | 您必须在下载后的24小时内从计算机或手机中完全删除以上内容。 53 | 54 | 任何以任何方式查看此项目的人或直接或间接使用该项目的任何脚本的使用者都应仔细阅读此声明。我保留随时更改或补充此免责声明的权利。一旦使用并复制了任何本仓库相关脚本或其他内容,则视为您已接受此免责声明。 55 | -------------------------------------------------------------------------------- /modules/core/chavyleung.Env.min.js: -------------------------------------------------------------------------------- 1 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.encoding="utf-8",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`🔔${this.name}, 开始!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}isStash(){return"undefined"!=typeof $environment&&$environment["stash-version"]}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,n]=i.split("@"),a={url:`http://${n}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(a,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),n=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(n);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){if(t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status?s.status:s.statusCode,s.status=s.statusCode),e(t,s,i)});else if(this.isQuanX())this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t&&t.error||"UndefinedError"));else if(this.isNode()){let s=require("iconv-lite");this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:i,statusCode:r,headers:o,rawBody:n}=t,a=s.decode(n,this.encoding);e(null,{status:i,statusCode:r,headers:o,rawBody:n,body:a},a)},t=>{const{message:i,response:r}=t;e(i,r,r&&s.decode(r.rawBody,this.encoding))})}}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status?s.status:s.statusCode,s.status=s.statusCode),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t&&t.error||"UndefinedError"));else if(this.isNode()){let i=require("iconv-lite");this.initGotEnv(t);const{url:r,...o}=t;this.got[s](r,o).then(t=>{const{statusCode:s,statusCode:r,headers:o,rawBody:n}=t,a=i.decode(n,this.encoding);e(null,{status:s,statusCode:r,headers:o,rawBody:n,body:a},a)},t=>{const{message:s,response:r}=t;e(s,r,r&&i.decode(r.rawBody,this.encoding))})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}queryStr(t){let e="";for(const s in t){let i=t[s];null!=i&&""!==i&&("object"==typeof i&&(i=JSON.stringify(i)),e+=`${s}=${i}&`)}return e=e.substring(0,e.length-1),e}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl,i=t["update-pasteboard"]||t.updatePasteboard;return{"open-url":e,"media-url":s,"update-pasteboard":i}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),this.isSurge()||this.isQuanX()||this.isLoon()?$done(t):this.isNode()&&process.exit(1)}}(t,e)} -------------------------------------------------------------------------------- /platforms/Loon/BaiduCloud.plugin: -------------------------------------------------------------------------------- 1 | #!name= Unblock Baidu Netdisc Play Speed 2 | #!desc= This is a Loon plugin for unblock Baidu netdisc unlocks online video play speed. 3 | #!author= chiupam 4 | #!homepage= https://github.com/chiupam/surge/tree/main/Loon 5 | #!icon= https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/Color/Nfcloud.png 6 | 7 | [Script] 8 | http-response https:\/\/pan\.baidu\.com\/rest\/\d\.\d\/membership\/user script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/BaiduCloud.js, requires-body=true, timeout=60, tag=百度网盘解锁在线播放倍数, enable = true 9 | 10 | [Mitm] 11 | hostname = pan.baidu.com 12 | 13 | -------------------------------------------------------------------------------- /platforms/Loon/BiliBili.plugin: -------------------------------------------------------------------------------- 1 | #!name= BiliBili Plugin 2 | #!desc= This is a Loon plugin for BiliBili. 3 | #!author= chiupam 4 | #!homepage= https://github.com/chiupam/surge/tree/main/Loon 5 | #!icon= https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/Color/bilibili_3.png 6 | 7 | [Script] 8 | http-request ^https:\/\/app\.bilibili\.com\/x\/v\d\/search(\/type)?\?.+?%20(%E6%B8%AF|%E5%8F%B0|%E4%B8%AD)& script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/Bili_Auto_Regions.js, requires-body=true, timeout=10, tag=bilibili自动地区(搜索) 9 | http-response ^https:\/\/ap(p|i)\.bilibili\.com\/(pgc\/view\/(v\d\/)?app|x(\/v\d)?\/view\/video)\/(season|online)\?access_key script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/Bili_Auto_Regions.js, requires-body=true, timeout=10, tag=bilibili自动地区 10 | http-response ^https:\/\/app\.bilibili\.com\/x\/v2\/account\/myinfo script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Bilibili-DailyBonus/Manga.js, requires-body=true, timeout=10, tag=哔哩哔哩漫画cookie 11 | cron "0,05,10 0 12 * * *" script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Bilibili-DailyBonus/ExchangePoints.js, tag=哔哩哔哩抢券 12 | cron "0 9,20 * * *" script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Bilibili-DailyBonus/Manga.js, tag=哔哩哔哩漫画签到 13 | 14 | [MITM] 15 | hostname = app.bilibili.com,ap?.bili*i.com,ap?.bili*i.net 16 | -------------------------------------------------------------------------------- /platforms/Loon/BiliRegions.plugin: -------------------------------------------------------------------------------- 1 | #!name= Bilibili Region 2 | #!desc= This is a Loon plugin used to collect JaveScripts on Auto Change Bilibili Region. 3 | #!author= chiupam 4 | #!homepage= https://github.com/chiupam/surge/tree/main/Loon 5 | #!icon= https://raw.githubusercontent.com/Koolson/Qure/master/IconSet/Color/bilibili_3.png 6 | 7 | [Script] 8 | http-request ^https:\/\/ap(p|i)\.bili(bili|api)\.(com|net)\/x\/v\d\/search(\/type)?\?.+?%20(%E6%B8%AF|%E5%8F%B0|%E4%B8%AD)& script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/Bili_Auto_Regions.js, timeout=10, tag=B站(搜索), enable = true 9 | http-response ^https:\/\/ap(p|i)\.bili(bili|api)\.(com|net)\/(pgc\/view\/v\d\/app\/season|x\/v\d\/search\/defaultwords)\?access_key script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/Bili_Auto_Regions.js, requires-body=true, timeout=10, tag=B站(换区), enable = true 10 | 11 | [Mitm] 12 | hostname = ap?.bili*i.com,ap?.bili*i.net 13 | 14 | -------------------------------------------------------------------------------- /platforms/Loon/ChangeUA.plugin: -------------------------------------------------------------------------------- 1 | #!name= Change User-Agent 2 | #!desc= This is a Loon plugin used to change user-agent on Safari. 3 | #!author= chiupam 4 | #!homepage= https://github.com/chiupam/surge/tree/main/Loon 5 | #!icon= https://github.com/Koolson/Qure/raw/master/IconSet/Color/Server.png 6 | 7 | [URL Rewrite] 8 | ^https?:\/\/www\.zhihu\.com header-replace User-Agent .+iPhone.+ "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/16C50 Quark/604.1 T7/10.3 SearchCraft/2.6.3 (Baidu; P1 8.0.0)" 9 | ^https?:\/\/(?!d\.pcs).*(? 京东 7 | 京东(开屏去广告) = type=http-response, requires-body=1, script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/startup/startup.js, pattern=^https?:\/\/api\.m\.jd\.com\/client\.action\?functionId=start 8 | # > 微博下面的评论 9 | 微博(下面的评论) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/comments/build_comments\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_comment.js, script-update-interval=0, timeout=60 10 | # > 微博 推荐 热门/榜单/放映厅… https://api.weibo.cn/2/statuses/unread_hot_timeline? 11 | # > 微博 最新微博 https://api.weibo.cn/2/statuses/friends/timeline? 12 | # > 视频流(短视频上划,微博继续推荐新视频) https://api.weibo.cn/2/video/tiny_stream_video_list? 13 | # > 微博 全部关注 https://api.weibo.cn/2/statuses/unread_friends_timeline? 14 | 微博(推荐|最新微博|全部关注) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/(statuses/unread_hot_timeline|statuses/friends/timeline|video/tiny_stream_video_list|statuses/unread_friends_timeline)\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_statuses.js, script-update-interval=0, timeout=60 15 | # > 发现 搜索 https://api.weibo.cn/2/searchall? 16 | # > 超话 帖子/精华/官方 https://api.weibo.cn/2/page? 17 | 微博(发现|超话) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/(statuses/unread_hot_timeline|statuses/friends/timeline|video/tiny_stream_video_list|statuses/unread_friends_timeline)\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_cardlist.js, script-update-interval=0, timeout=60 18 | # > 发现 热点(这货特殊,有卡片广告) https://api.weibo.cn/2/cardlist? 19 | 微博(发现|超话) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/cardlist\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_cardlist_discover.js, script-update-interval=0, timeout=60 20 | # > 每条微博下面 创作者广告共享计划 21 | 微博(创作者广告共享计划) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/statuses/extend\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_statuses_extend.js, script-update-interval=0, timeout=60 22 | # > 开屏广告 23 | 微博(开屏广告) = type=http-response, requires-body=1, max-size=0, pattern=^https://sdkapp\.uve\.weibo\.com/interface/sdk/sdkad\.php$, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_sdkad.js, script-update-interval=0, timeout=60 24 | 25 | [MITM] 26 | hostname = %APPEND% api.m.jd.com, 103.41.167.236, 103.41.167.234, 103.41.167.235, 103.41.167.226, api.weibo.cn, mapi.weibo.com, sdkapp.uve.weibo.com -------------------------------------------------------------------------------- /platforms/Surge/BaiduCloud.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Unblock Baidu Netdisc Play Speed 2 | #!desc=This is a Surge module for unblock Baidu netdisc unlocks online video play speed. 3 | 4 | [Script] 5 | # > 百度网盘SVIP (pan.baidu.com) 6 | 百度网盘SVIP = type=http-response, pattern=^https?://pan\.baidu\.com/rest/\d\.\d/membership/user, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/BaiduCloud.js, script-update-interval=0, timeout=10 7 | 8 | [MITM] 9 | hostname = %APPEND% pan.baidu.com 10 | -------------------------------------------------------------------------------- /platforms/Surge/BiliBiliAds.6.74.0.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=BiliBili Ads 2 | #!desc=BiliBili Version: 6.74.0; Date: 2023-07-09; Verification: Ture 3 | 4 | [Rule] 5 | DOMAIN-SUFFIX, cm.bilibili.com, REJECT 6 | URL-REGEX, ^https?:\/\/api\.bilibili\.com\/x\/v2\/dm\/ad, REJECT 7 | # > 可能的一些推广(beta) 8 | URL-REGEX, ^https?:\/\/api\.bilibili\.com\/pgc\/season\/app\/related\/recommend\?, REJECT 9 | # > BiliBili漫画去广告 10 | URL-REGEX, ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.comic\/flash, REJECT 11 | 12 | [URL Rewrite] 13 | # > 去除搜索中的默认关键词 14 | ^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.interface\.v1\.Search\/DefaultWords$ - reject 15 | # > 去除搜索中的大家都在搜 16 | ^https?:\/\/api\.vc\.bilibili\.com\/search_svr\/v\d\/Search\/recommend_words - reject 17 | # > 去除动态中的话题 18 | ^https?:\/\/api\.vc\.bilibili\.com\/topic_svr\/v1\/topic_svr - reject 19 | # > 去除动态中的最常访问 20 | ^https?:\/\/api\.vc\.bilibili\.com\/dynamic_svr\/v1\/dynamic_svr\/mix_uplist - reject 21 | # > 可能的一些推广(beta) 22 | ^https?:\/\/api\.bilibili\.com\/pgc\/season\/app\/related\/recommend\? - reject 23 | # > BiliBili漫画去广告 24 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/Flash - reject 25 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/ListFlash - reject 26 | 27 | [Map Local] 28 | # > 去除搜索中的大家都在搜 29 | ^https?:\/\/api\.vc\.bilibili\.com\/search_svr\/v\d\/Search\/recommend_words data="https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/reject-dict.json" 30 | # > 去除动态中的话题 31 | ^https?:\/\/api\.vc\.bilibili\.com\/topic_svr\/v1\/topic_svr data="https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/reject-dict.json" 32 | # > 去除动态中的最常访问 33 | ^https?:\/\/api\.vc\.bilibili\.com\/dynamic_svr\/v1\/dynamic_svr\/mix_uplist data="https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/reject-dict.json" 34 | # > 可能的一些推广(beta) 35 | ^https?:\/\/api\.bili(bili\.com|api\.net)\/pgc\/season\/app\/related\/recommend\? data="https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/reject-dict.json" 36 | # > BiliBili漫画去广告 37 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/Flash data="https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/reject-dict.json" 38 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/ListFlash data="https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/reject-dict.json" 39 | ^https?:\/\/api\.live\.bilibili\.com\/xlive\/e-commerce-interface\/v1\/ecommerce-user\/get_shopping_info\? data="https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/reject-dict.json" 40 | 41 | [Script] 42 | # > BiliBili去广告 43 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/api\.live\.bilibili\.com\/xlive\/app-room\/v1\/index\/getInfoByRoom, requires-body=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/BiliBili/BiliBili.js 44 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/api\.bili(bili\.com|api\.net)\/pgc\/page\/(bangumi|cinema\/tab\?), requires-body=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/BiliBili/BiliBili.js 45 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/app\.bili(bili\.com|api\.net)\/x\/v2\/(splash\/(brand\/list|event\/list2|list|show)|feed\/index(\/story)?|search\/square), requires-body=1, script-path=https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/BiliBili.js 46 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.view\.v1\.View\/View$, requires-body=1, binary-body-mode=1, script-path=https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/BiliBili.js 47 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.dynamic\.v2\.Dynamic\/Dyn(All|Video)$, requires-body=1, binary-body-mode=1, script-path=https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/BiliBili.js 48 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.playurl\.v1\.PlayURL\/PlayView$, requires-body=1, binary-body-mode=1, script-path=https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/BiliBili.js 49 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.polymer\.app\.search\.v1\.Search\/SearchAll$, requires-body=1, binary-body-mode=1, script-path=https://github.com/chiupam/surge/raw/refs/heads/main/scripts/javascript/BiliBili/BiliBili.js 50 | 51 | [MITM] 52 | hostname = %APPEND% manga.bilibili.com, api.live.bilibili.com, api.vc.bilibili.com, app.bilibili.com, app.biliapi.net, api.bilibili.com, api.biliapi.net, grpc.biliapi.net -------------------------------------------------------------------------------- /platforms/Surge/Procuratorate.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Procuratorate Sign In 2 | #!desc=This is a Surge module used to work check in. 3 | 4 | 5 | [Script] 6 | # > 使用方法:打开工作打卡的小程序手动进行一次打卡即可。 7 | 工作打卡Cookie = type=http-request, pattern=^https?://zhcj\.kmcgjcy\.cn/AttendanceCard/SaveAttCheckinout$, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/procuratorate.js, script-update-interval=0, timeout=10 8 | 工作打卡 = type=cron, cronexp="1 47,52,57 8 * * *", wake-system=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/procuratorate.js, script-update-interval=0, timeout=300 9 | 工作打卡 = type=cron, cronexp="30 21,41 17 * * *", wake-system=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/procuratorate.js, script-update-interval=0, timeout=60 10 | 11 | [MITM] 12 | hostname = %APPEND% zhcj.kmcgjcy.cn 13 | -------------------------------------------------------------------------------- /platforms/Surge/Script.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Scripts Module 2 | #!desc=This is a Surge module used to collect JaveScripts on daily use. 3 | 4 | [General] 5 | skip-proxy = %APPEND% iosapps.itunes.apple.com 6 | 7 | [Script] 8 | # > BoxJs TF 9 | BoxJs(TF) = type=http-request, pattern=^https?://boxjs.net, requires-body=1, timeout=120, script-path=https://raw.githubusercontent.com/chavyleung/scripts/master/box/chavy.boxjs.js, script-update-interval=0, timeout=60 10 | 11 | # > TestFlight 12 | TestFlight = type=http-request, pattern=^https?:\/\/testflight\.apple\.com\/v\d\/accounts\/.+?\/install$, requires-body=1, script-update-interval=-1, max-size=0, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/TestFlight.js, script-update-interval=0, timeout=60 13 | 14 | [URL Rewrite] 15 | ^https://boxjs.net http://boxjs.net 302 16 | ^http://ww1.boxjs.net http://boxjs.net 302 17 | ^http://ww6.boxjs.net http://boxjs.net 302 18 | 19 | [MITM] 20 | hostname = %APPEND% boxjs.net, testflight.apple.com 21 | -------------------------------------------------------------------------------- /platforms/Surge/Study.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Study Module 2 | #!desc=This is a Surge module that collects scripts to assist in completing learning tasks for some learning apps. 3 | 4 | [Script] 5 | # > 学习强国app 6 | 计时器(视频) = type=http-request, pattern=^https?://boot-video2\.xuexi\.cn/video/.*.ts, requires-body=true, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/xxqg.js, script-update-interval=0, timeout=300 7 | 8 | [MITM] 9 | hostname = %APPEND% boot-video2.xuexi.cn 10 | -------------------------------------------------------------------------------- /platforms/Surge/Task.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Tasks Module 2 | #!desc=This is a Surge module used to collect JaveScripts on daily task. 3 | 4 | [Script] 5 | # > 百度贴吧app 6 | 百度贴吧BDUSS = type=http-request, pattern=^https?://info\.tuisong\.baidu.com/v2/setter$, requires-body=0, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/tieba.js, script-update-interval=0 7 | 百度贴吧签到 = type=cron, cronexp="1 0 * * *", wake-system=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/tieba.js, script-update-interval=0, timeout=60 8 | 9 | [MITM] 10 | hostname = %APPEND% info.tuisong.baidu.com 11 | -------------------------------------------------------------------------------- /platforms/Surge/Unblock.caiyun.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Caiyun App Module 2 | #!desc=This is a Surge module used to collect JaveScripts on hacking for Caiyuntianqi Applicaitons. 3 | 4 | [Script] 5 | 彩云天气 = type=http-request,pattern=^https?:\/\/(api|wrapper)\.(cyapi|caiyunapp)\.(cn|com)\/v\d\/(satellite|nafp\/origin_images),requires-body=1,max-size=0,binary-body-mode=0,script-path=https://raw.githubusercontent.com/chxm1023/Rewrite/main/caiyuntianqi.js ,script-update-interval=0 6 | 彩云天气 = type=http-response,pattern=^https?:\/\/(biz|wrapper|starplucker)\.(cyapi|caiyunapp)\.(cn|com)\/(.+\/(user\?app_name|activity\?app_name|visitors|operation\/banners|operation\/homefeatures|config)|p\/v\d\/(vip_info|user_info|entries|privileges|trial_card\/info)),requires-body=1,max-size=0,binary-body-mode=0,script-path=https://raw.githubusercontent.com/chxm1023/Rewrite/main/caiyuntianqi.js,script-update-interval=0 7 | 8 | [MITM] 9 | hostname = %APPEND% *.cyapi.cn, *.caiyunapp.com 10 | -------------------------------------------------------------------------------- /platforms/Surge/YouTubeAds.18.49.3.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=YouTube Ads 2 | #!desc=YouTube Version: 18.49.3; Date: 2023-12-21; Verification: Ture 3 | 4 | # > 源地址 5 | # https://raw.githubusercontent.com/Maasea/sgmodule/master/YoutubeAds.sgmodule 6 | 7 | [Rule] 8 | AND,((DOMAIN-SUFFIX,googlevideo.com), (PROTOCOL,UDP)),REJECT-NO-DROP 9 | 10 | [Script] 11 | YouTube(Request) = type=http-request,pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next|player|reel\/reel_watch_sequence),requires-body=1,max-size=-1,binary-body-mode=1,script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/18.49.3/youtube.request.js 12 | YouTube(Response) = type=http-response,pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next|player|search|reel\/reel_watch_sequence|guide|account\/get_setting),requires-body=1,max-size=-1,binary-body-mode=1,script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/18.49.3/youtube.response.js 13 | 14 | [Map Local] 15 | ^https?:\/\/[\w-]+\.googlevideo\.com\/initplayback.+&oad data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/18.49.3/blank.txt" 16 | 17 | [MITM] 18 | hostname = %APPEND% *.googlevideo.com, youtubei.googleapis.com 19 | -------------------------------------------------------------------------------- /platforms/Surge/backup/BiliRegions.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Bilibili Region 2 | #!desc=This is a Surge module used to collect JaveScripts on Auto Change Bilibili Region. 3 | #!system=ios 4 | 5 | [Script] 6 | B站(换区) = type=http-response, pattern=^https:\/\/ap(p|i)\.bili(bili|api)\.(com|net)\/(pgc\/view\/v\d\/app\/season|x\/v\d\/search\/defaultwords)\?access_key, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/Bili_Auto_Regions.js, script-update-interval=0, timeout=10 7 | B站(搜索) = type=http-request, pattern=^https:\/\/ap(p|i)\.bili(bili|api)\.(com|net)\/x\/v\d\/search(\/type)?\?.+?%20(%E6%B8%AF|%E5%8F%B0|%E4%B8%AD)&, script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/Bili_Auto_Regions.js, script-update-interval=0, timeout=10 8 | 9 | 10 | [MITM] 11 | hostname = %APPEND% ap?.bili*i.com, ap?.bili*i.net 12 | -------------------------------------------------------------------------------- /platforms/Surge/backup/CamScanner.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=CamScanner SVIP 2 | #!desc=This is a Surge module for hacking CamScanner affiliates. CamScanner Version: 5.30.1.xxxxxx 3 | 4 | [MITM] 5 | hostname = %APPEND% ap*.intsig.net 6 | 7 | [Script] 8 | 全能扫描王 SVIP = type=http-response, pattern=^https:\/\/(api|api-cs)\.intsig\.net\/purchase\/cs\/query_property\?, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/CamScanner.js 9 | -------------------------------------------------------------------------------- /platforms/Surge/backup/ChangeUA.sgmodule: -------------------------------------------------------------------------------- 1 | #!name= Change User-Agent 2 | #!desc= This is a Surge module used to change user-agent on Safari. 3 | 4 | [URL Rewrite] 5 | # > 知乎(部分替换为手机百度 Quark 的 User-Agent) 6 | http-request ^https?:\/\/www\.zhihu\.com header-replace-regex User-Agent .+iPhone.+ "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/16C50 Quark/604.1 T7/10.3 SearchCraft/2.6.3 (Baidu; P1 8.0.0)" 7 | # > 百度(全站替换为手机百度 Quark 的 User-Agent) 8 | http-request ^https?:\/\/(?!d\.pcs).*(? 使用方法:打开某东,然后点击右上角气泡(消息)按钮,等待数秒即可。 6 | # > 不推荐外人使用此模块,因为此模块如果没有配置正确,会直接发送 wskey 给我! 7 | # > 不希望懂技术的人员使用脚本攻击我的Telegram机器人,恳请各位技术人员手下留情! 8 | # 9 | # > 京东上传wskey 10 | # > api-dd.jd.com 11 | 京东上传wskey = type=http-request, argument=api=1185488678&H4FLgB6NklKaJNEDZ5t_6Pp-iux4DJnEU, pattern=^https?://api-dd\.jd\.com/client\.action\?functionId=getSessionLog, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/wskey.js, script-update-interval=0, timeout=10 12 | 13 | [MITM] 14 | hostname = %APPEND% api-dd.jd.com 15 | -------------------------------------------------------------------------------- /platforms/Surge/backup/Leave.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Mysterious Hacker 2 | #!desc=When you need to modify the leave information, open this module, and go to the BoxJs to modify the leave date. 3 | 4 | [Script] 5 | 神秘骇客 = type=http-response, pattern=^https?://xg\.kmmu\.edu\.cn/KmmcXG/webapi/api/(Leave/AllLeaveManage(_Edit)?|Student/GetStuHomePage|Student/GetStuPersonInfo)\?LoginStatus=.*, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/leave_kmmu.js, script-update-interval=0, timeout=60 6 | 7 | [MITM] 8 | hostname = %APPEND% xg.kmmu.edu.cn 9 | -------------------------------------------------------------------------------- /platforms/Surge/backup/MGTV.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Unblock MGTV SVIP 2 | #!desc=This is a Surge module used to collect JaveScripts on hacking for MGTV Applicaitons. 3 | #!source 4 | 5 | [URL Rewrite] 6 | # > 无用请求 7 | ^http://[\d\.]+:\d{5}/\?cmd=indexes - reject 8 | # > 芒果去广告(首页左上角推广) 9 | ^http://[\d\.]+/odin/c1/(channel/ads|skin/config)\? - reject 10 | # > 芒果去广告(底部TAB红点) 11 | ^https://damang\.api\.mgtv\.com/station/album/red/dot\? - reject 12 | # > 芒果去广告(播放器界面) 13 | ^https://hb-boom\.api\.mgtv\.com/release/pullReleaseInfo - reject 14 | # > 芒果去广告(升级弹窗) 15 | ^https://mobile\.api\.mgtv\.com/v2/mobile/checkUpdate\? - reject 16 | # > 芒果去广告(播放详情页) 17 | ^http://mobile-thor\.api\.mgtv\.com/v1/vod/cms/list\? - reject 18 | # > 芒果去广告(搜索框填充词) 19 | ^http://mobileso\.bz\.mgtv\.com/spotlight/search/v1\? - reject 20 | 21 | [Script] 22 | # > source: https://github.com/Yu9191/Rewrite/blob/main/MGTV.js 23 | 芒果SVIP(Request) = type=http-request, pattern=^http[s]?://mobile\.api\.mgtv\.com/v[0-9]/(playlist|video/album|video/relative|video/list).*$, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/Yu9191/Rewrite/main/mgtv1.js, script-update-interval=0 24 | 芒果SVIP(Request) = type=http-request, pattern=^https?://mobile-stream\.api\.mgtv\.com/v1/video/source?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/Yu9191/Rewrite/main/MGTV.js, script-update-interval=0 25 | 芒果SVIP(Response) = type=http-response, pattern=https://nuc.api.mgtv.com/GetUserInfo, requires-body=1, script-path=https://raw.githubusercontent.com/Yu9191/Rewrite/main/mgtv.js, script-update-interval=0, max-size=0 26 | 芒果SVIP(Response) = type=http-response, pattern=https://mobile-stream\.api\.mgtv\.com/v1/video/source?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/Yu9191/Rewrite/main/mgtv.js, script-update-interval=0 27 | 芒果SVIP(我的页面) = type=http-response, pattern=^https://me\.bz\.mgtv\.com/v3/module/list\?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/cnftp.js, script-update-interval=0 28 | 芒果SVIP(首页信息流) = type=http-response, pattern=^http://mob-st\.bz\.mgtv\.com/odin/c1/channel/index\?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/cnftp.js, script-update-interval=0 29 | 芒果SVIP(顶部TAB) = type=http-response, pattern=^https?://dc2?\.bz\.mgtv\.com/dynamic/v1/channel/(index|vrsList)/\w, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/cnftp.js, script-update-interval=0 30 | 芒果SVIP(底部TAB) = type=http-response, pattern=^https://mobile\.api\.mgtv\.com/mobile/config\?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/cnftp.js, script-update-interval=0 31 | 芒果SVIP(播放详情页) = type=http-response, pattern=^https://mobile\.api\.mgtv\.com/v10/video/info\?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/cnftp.js, script-update-interval=0 32 | 芒果SVIP(播放详情页) = type=http-response, pattern=^https://mobile-thor\.api\.mgtv\.com/v1/vod/info\?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/cnftp.js, script-update-interval=0 33 | 芒果SVIP(搜索框填充词) = type=http-response, pattern=^https?://mobileso\.bz\.mgtv\.com/mobile/recommend/v2\?, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/RuCu6/QuanX/main/Scripts/cnftp.js, script-update-interval=0 34 | 35 | [MITM] 36 | hostname = %APPEND% *.mgtv.com 37 | -------------------------------------------------------------------------------- /platforms/Surge/backup/Panel.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Surge Panel 2 | #!desc=This is a module that collects Surge panels. 3 | #!system=ios 4 | 5 | [Panel] 6 | Network-info = script-name=网络信息, title="", content="", style=info, update-interval=60 7 | 8 | [Script] 9 | 网络信息 = type=generic, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/panel/network_info.js, type=generic, timeout=30 10 | -------------------------------------------------------------------------------- /platforms/Surge/backup/RRTV_SVIP.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=RRTV Ads & SVIP 2 | #!desc=This is a Surge module used to collect JaveScripts on hacking RRTV and remove advertisings 3 | #!system=ios 4 | 5 | [Rule] 6 | AND, ((USER-AGENT, PUClient*), (NOT, ((DOMAIN-SUFFIX, rr.tv)))), REJECT 7 | URL-REGEX, ^https?:\/\/api\.rr\.tv\/(?:ad\/getAll$|storage/business/rootName/app/homePage), REJECT 8 | 9 | [Script] 10 | rrsp_video = type=http-response, requires-body=true, pattern=^https?:\/\/api\.rr\.tv\/watch\/v\d\/get_movie_info, script-path=https://Choler.github.io/Surge/Script/rrsp.js, script-update-interval=0, timeout=60 11 | rrsp_banner = type=http-response, requires-body=true, pattern=^https?:\/\/api\.rr\.tv\/v\dplus\/index\/channel, script-path=https://Choler.github.io/Surge/Script/rrsp.js, script-update-interval=0, timeout=60 12 | 13 | [MITM] 14 | hostname = %APPEND% api.rr.tv 15 | -------------------------------------------------------------------------------- /platforms/Surge/backup/Scriptable.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Scriptable Software 2 | #!desc=This is a Surge module used to collect JaveScripts on Scriptable App. 3 | 4 | [Script] 5 | # > 中国联通 (Scriptable) 6 | # > act.10010.com 7 | 中国联通(Scriptable) = type=http-request, pattern=^https?://act\.10010\.com/SigninApp/signin/querySigninActivity\.htm, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/scriptable/rewrite/10010.cookie.js, script-update-interval=0, timeout=60 8 | 9 | [MITM] 10 | hostname = %APPEND% act.10010.com 11 | -------------------------------------------------------------------------------- /platforms/Surge/backup/TunOnly.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Tun Only 2 | #!desc= Only enable the Surge module when you need to enable compatibility mode. 3 | 4 | [General] 5 | compatibility-mode = 3 6 | -------------------------------------------------------------------------------- /platforms/Surge/backup/Unblock.bak.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Unblock Module 2 | #!desc=This is a Surge module used to collect JaveScripts on hacking, and it will use local resources. 3 | 4 | [Script] 5 | # > 彩云天气 SVIP (biz.caiyunapp.com) 6 | 彩云天气 SVIP = type=http-response, pattern=https?:\/\/biz\.caiyunapp\.com\/(membership_rights|v2\/user), requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/ColorfulClouds_SVIP.js, script-update-interval=0, timeout=60 7 | # > 鲨鱼记账 SVIP (api.shayujizhang.com) 8 | 鲨鱼记账 SVIP = type=http-response, pattern=https:\/\/api\.shayujizhang\.com\/account\/grant\/detail\/info, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/SYJZ_SVIP.js, script-update-interval=0, timeout=60 9 | 10 | [MITM] 11 | hostname = %APPEND% biz.caiyunapp.com, api.shayujizhang.com 12 | -------------------------------------------------------------------------------- /platforms/Surge/backup/Unblock.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Unblock Module 2 | #!desc=This is a Surge module used to collect JaveScripts on hacking, and it will use local resources. 3 | 4 | [Script] 5 | # > 百度网盘 SVIP (pan.baidu.com) 6 | # > Unblock Baidu netdisc unlocks online video play speed. 7 | 百度网盘 SVIP = type=http-response, pattern=^https?://pan\.baidu\.com/rest/\d\.\d/membership/user, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/BaiduCloud.js, script-update-interval=0, timeout=10 8 | 9 | # > 全能扫描王 10 | # > Hacking CamScanner affiliates. CamScanner Version: 5.30.1.xxxxxx 11 | 全能扫描王 SVIP = type=http-response, pattern=^https:\/\/(api|api-cs)\.intsig\.net\/purchase\/cs\/query_property\?, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/NobyDa/Script/master/Surge/JS/CamScanner.js 12 | 13 | [MITM] 14 | hostname = %APPEND% pan.baidu.com, ap*.intsig.net 15 | -------------------------------------------------------------------------------- /platforms/Surge/backup/WeiboAds.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=Weibo Ads 2 | #!desc=This is a Surge module used to collect JaveScripts on Remove Weibo Ads. 3 | 4 | [Script] 5 | # > 微博下面的评论 6 | 微博(下面的评论) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/comments/build_comments\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_comment.js, script-update-interval=0, timeout=60 7 | # > 微博 推荐 热门/榜单/放映厅… https://api.weibo.cn/2/statuses/unread_hot_timeline? 8 | # > 微博 最新微博 https://api.weibo.cn/2/statuses/friends/timeline? 9 | # > 视频流(短视频上划,微博继续推荐新视频) https://api.weibo.cn/2/video/tiny_stream_video_list? 10 | # > 微博 全部关注 https://api.weibo.cn/2/statuses/unread_friends_timeline? 11 | 微博(推荐|最新微博|全部关注) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/(statuses/unread_hot_timeline|statuses/friends/timeline|video/tiny_stream_video_list|statuses/unread_friends_timeline)\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_statuses.js, script-update-interval=0, timeout=60 12 | # > 发现 搜索 https://api.weibo.cn/2/searchall? 13 | # > 超话 帖子/精华/官方 https://api.weibo.cn/2/page? 14 | 微博(发现|超话) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/(statuses/unread_hot_timeline|statuses/friends/timeline|video/tiny_stream_video_list|statuses/unread_friends_timeline)\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_cardlist.js, script-update-interval=0, timeout=60 15 | # > 发现 热点(这货特殊,有卡片广告) https://api.weibo.cn/2/cardlist? 16 | 微博(发现|超话) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/cardlist\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_cardlist_discover.js, script-update-interval=0, timeout=60 17 | # > 每条微博下面 创作者广告共享计划 18 | 微博(创作者广告共享计划) = type=http-response, requires-body=1, max-size=0, pattern=^https://(api\.weibo\.cn|mapi\.weibo\.com)/2/statuses/extend\?, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_statuses_extend.js, script-update-interval=0, timeout=60 19 | # > 开屏广告 20 | 微博(开屏广告) = type=http-response, requires-body=1, max-size=0, pattern=^https://sdkapp\.uve\.weibo\.com/interface/sdk/sdkad\.php$, script-path=https://raw.githubusercontent.com/yjqiang/surge_scripts/main/scripts/weibo/weibo_sdkad.js, script-update-interval=0, timeout=60 21 | 22 | [MITM] 23 | hostname = %APPEND% api.weibo.cn, mapi.weibo.com, sdkapp.uve.weibo.com 24 | -------------------------------------------------------------------------------- /platforms/Surge/backup/YouTubeAds.17.16.4.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=YouTube Ads 2 | #!desc=YouTube Version: 17.16.4; Date: 2023-06-16; Verification: Ture; Date: 2023-12-20; Verification: False 3 | 4 | # > Credit 5 | # @Choler & @DivineEngine & @app2smile 6 | # > Github 7 | # https://github.com/Maasea/sgmodule/tree/master 8 | # > Raw Javascript 9 | # https://raw.githubusercontent.com/Maasea/sgmodule/544affd72b002db4bcc0640f2fd5b18751f3d7a3/Script/Youtube/17.16.4/youtube.js 10 | # https://raw.githubusercontent.com/Maasea/sgmodule/544affd72b002db4bcc0640f2fd5b18751f3d7a3/Script/Youtube/17.16.4/youtube.src.js 11 | 12 | [MITM] 13 | hostname = %APPEND% *.googlevideo.com, youtubei.googleapis.com 14 | 15 | [Script] 16 | YouTube去广告 = type=http-response, pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next|player|search|reel\/reel_watch_sequence|guide|account\/get_setting)\?, requires-body=1, binary-body-mode=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/17.16.4/youtube.js 17 | 18 | [Map Local] 19 | ^https?:\/\/[\w-]+\.googlevideo\.com\/initplayback.+&oad data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/17.16.4/blank.txt" header="Content-Type: application/vnd.yt-ump" 20 | -------------------------------------------------------------------------------- /platforms/Surge/backup/ZhiHuAds.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=ZhiHu Ads 2 | #!desc=This is a Surge module used to collect JaveScripts on Remove ZhiHu Ads. ZhiHu Version: 6.60.0(2780) 3 | #!https://github.com/blackmatrix7/ios_rule_script/blob/master/script/zhihu/zhihu_plus.sgmodule 4 | 5 | [Rule] 6 | # > 屏蔽知乎8.3.0版本首页顶部的视频角标 7 | URL-REGEX,^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/explore\/entry\/tips,REJECT-TINYGIF 8 | # > 知乎广告拦截 9 | RULE-SET,https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu_remove_ads.list,REJECT-NO-DROP 10 | 11 | 12 | [URL Rewrite] 13 | # > 屏蔽知乎“我的”页面推荐开通会员的卡片 14 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/people\/self\/new_user_card - reject 15 | 16 | [Map Local] 17 | # > 屏蔽知乎下发的配置,如皮肤等 18 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/ab\/api\/v1\/products\/zhihu\/platforms\/ios\/config data="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/blank/blank_dict.json" header="Content-Type: application/x-protobuf" 19 | # > 知乎去除Tab页关注人头像 20 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/moments\/tab_v2 data="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/blank/blank_dict.json" 21 | # > 知乎去除最常访问 22 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/moments\/recent data="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/blank/blank_dict.json" 23 | # > 知乎其他广告拦截 24 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/(notifications\/v\d\/count|v\d\/package|me\/guides|drama\/living-info|ad|fringe|commercial|market\/popovers|.*featured-comment-ad|ad-style-service) data="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/blank/blank_dict.json" 25 | # > 屏蔽消息页面上拉的用户精选 26 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/moments/hybrid\? data="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/blank/blank_dict.json" 27 | # > 新人必看之类的入口 28 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/flow\/show_entrance data="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/blank/blank_dict.json" 29 | # > 疑似通知角标 30 | ^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/settings\/new\/notification data="https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/blank/blank_dict.json" 31 | 32 | [Script] 33 | 知乎(处理用户信息) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/people\/,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 34 | 知乎(信息流去广告) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/(moments|topstory)(\/|\?)?(recommend|action=|feed_type=)(?!\/people),script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 35 | 知乎(获取黑名单) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/settings\/blocked_users,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 36 | 知乎(官方消息去广告) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/notifications\/v3\/(message|timeline\/entry\/system_message),script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 37 | 知乎(预置关键词去广告) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/search\/preset_words\?,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 38 | 知乎(回答列表去广告) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/(v4\/)?questions\/\d+,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 39 | 知乎(回答内容优化) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(www\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/appview\/v2\/answer\/.*(entry=(?!(preload-topstory|preload-search|preload-subscription)))?,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 40 | 知乎(优化软件配置) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/appcloud2\.zhihu\.com\/v\d+\/config,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 41 | 知乎(热搜去广告) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/search\/top_search\/tabs\/hot\/items,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 42 | 知乎(热榜去广告) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/topstory\/hot-lists?(\?|\/),script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 43 | 知乎(评论去广告) = type=http-response,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/(comment_v5\/)?(answers|comments?|articles|pins)\/\d+\/(root_|child_)?comments?,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 44 | 知乎(解锁关键词屏蔽) = type=http-request,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/feed-root\/block,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 45 | 知乎(移除推荐页顶部项) = type=http-request,requires-body=1,max-size=0,pattern=^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/feed-root\/sections\/query\/v2,script-path=https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/script/zhihu/zhihu.js 46 | 47 | [MITM] 48 | hostname = %APPEND% www.zhihu.com,api.zhihu.com,zhuanlan.zhihu.com,appcloud2.zhihu.com,103.41.167.236,103.41.167.234,103.41.167.235,103.41.167.226 -------------------------------------------------------------------------------- /platforms/boxjs/chiupam.boxjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "chiupam.sub", 3 | "name": "chiupam 脚本订阅", 4 | "author": "@chiupam", 5 | "icon": "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.jpg", 6 | "repo": "https://github.com/chiupam/surge", 7 | "apps": [ 8 | { 9 | "id": "Procuratorate", 10 | "name": "工作打卡", 11 | "key": [], 12 | "descs_html": [ 13 | "

打开工作打卡的小程序手动进行一次打卡.

" 14 | ], 15 | "settings": [ 16 | { 17 | "id": "procuratorate_fast", 18 | "name": "快速签到", 19 | "val": false, 20 | "type": "boolean", 21 | "desc": "跳过节假日检测环节(默认关闭)" 22 | }, 23 | { 24 | "id": "procuratorate_cookie", 25 | "name": "签到cookie", 26 | "val": "", 27 | "type": "text", 28 | "desc": "上班打卡验证信息" 29 | }, 30 | { 31 | "id": "procuratorate_host", 32 | "name": "签到主机名", 33 | "val": "", 34 | "type": "text", 35 | "desc": "上班打卡的主机名" 36 | }, 37 | { 38 | "id": "procuratorate_agent", 39 | "name": "签到用户代理", 40 | "val": "", 41 | "type": "text", 42 | "desc": "上班打卡的用户代理" 43 | }, 44 | { 45 | "id": "procuratorate_userDepID", 46 | "name": "签到用户部门ID", 47 | "val": "", 48 | "type": "text", 49 | "desc": "上班打卡的用户部门ID" 50 | }, 51 | { 52 | "id": "procuratorate_userID", 53 | "name": "签到用户ID", 54 | "val": "", 55 | "type": "text", 56 | "desc": "上班打卡的用户ID" 57 | }, 58 | { 59 | "id": "procuratorate_address", 60 | "name": "签到地址", 61 | "val": "", 62 | "type": "text", 63 | "desc": "上班打卡的地址" 64 | } 65 | ], 66 | "author": "@chiupam", 67 | "repo": "https://github.com/chiupam/surge", 68 | "script": "https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/procuratorate.js", 69 | "icons": [ 70 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/Procuratorate.png", 71 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/Procuratorate.png" 72 | ] 73 | }, 74 | { 75 | "id": "zsfc", 76 | "name": "掌上飞车", 77 | "keys": [], 78 | "descs_html": [ 79 | "

掌飞签到:掌上飞车APP => 签到(每日福利)

", 80 | "

掌飞寻宝:掌上飞车APP => 寻宝(今日大吉)

", 81 | "

使用以上两种方式可以获取更全面的数据

", 82 | "

选做:掌上飞车APP => 下方游戏 => 掌飞商城

" 83 | ], 84 | "settings": [ 85 | { 86 | "id": "zsfc_shop", 87 | "name": "余额自动购买道具", 88 | "val": "false", 89 | "type": "boolean", 90 | "desc": "是否使用消费券和点券自动执行购买操作,默认不执行" 91 | }, 92 | { 93 | "id": "zsfc_bang_shopname", 94 | "name": "道具名称", 95 | "val": "", 96 | "type": "text", 97 | "desc": "掌上飞车APP的购买道具名称,仅支持在售的点券商品" 98 | }, 99 | { 100 | "id": "zsfc_shop_threshold", 101 | "name": "购物消耗点券选项", 102 | "val": "1", 103 | "type": "radios", 104 | "items": [ 105 | { 106 | "key": "1", 107 | "label": "就让这些剩余的消费券浪费掉" 108 | }, 109 | { 110 | "key": "1000000", 111 | "label": "只要有剩余消费券就消耗点券再买一个道具" 112 | }, 113 | { 114 | "key": "2", 115 | "label": "剩余消费券大于单个道具价格的一半才再买一个道具" 116 | } 117 | ], 118 | "desc": "购物完成后剩余的消费券是否需要彻底消耗掉,默认浪费掉" 119 | }, 120 | { 121 | "id": "zsfc_forcedConsumption", 122 | "name": "每周强制消费点券以完成每周任务", 123 | "val": "false", 124 | "type": "boolean", 125 | "desc": "是否每周强制消费点券以完成每周任务,默认不强制消费" 126 | }, 127 | { 128 | "id": "zsfc_upload_id", 129 | "name": "上传掌飞签到数据", 130 | "val": "true", 131 | "type": "boolean", 132 | "desc": "将获取到的掌飞签到数据上传到青龙面板" 133 | }, 134 | { 135 | "id": "zsfc_upload_config", 136 | "name": "上传掌飞寻宝和商店数据", 137 | "val": "false", 138 | "type": "boolean", 139 | "desc": "将获取到的掌飞寻宝和商店数据上传到青龙面板" 140 | } 141 | ], 142 | "author": "@chiupam", 143 | "repo": "https://github.com/chiupam/surge", 144 | "script": "https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.v3.js", 145 | "icons": [ 146 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/zsfc.jpeg", 147 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/zsfc.jpeg" 148 | ] 149 | }, 150 | { 151 | "id": "tieba", 152 | "name": "百度贴吧", 153 | "keys": [], 154 | "descs_html": [ 155 | "

百度贴吧签到:打开百度贴吧APP,稍等片刻即可

" 156 | ], 157 | "settings": [ 158 | { 159 | "id": "BDUSS", 160 | "name": "百度贴吧BDUSS的值(必须提供)", 161 | "val": "", 162 | "type": "textarea", 163 | "desc": "这里将显示百度贴吧获取到的BDUSS的值" 164 | }, 165 | { 166 | "id": "BD_maxRetries", 167 | "name": "最大重试次数(可选)", 168 | "val": "3", 169 | "type": "number", 170 | "desc": "签到失败时的最大重试次数" 171 | }, 172 | { 173 | "id": "BD_retryDelay", 174 | "name": "重试延迟时间(可选)", 175 | "val": "5000", 176 | "type": "number", 177 | "desc": "每次重试之间的延迟时间(毫秒)" 178 | }, 179 | { 180 | "id": "BD_batchSize", 181 | "name": "批量签到数量(可选)", 182 | "val": "20", 183 | "type": "number", 184 | "desc": "每次批量签到的贴吧数量" 185 | }, 186 | { 187 | "id": "BD_batchInterval", 188 | "name": "批量签到间隔(可选)", 189 | "val": "2000", 190 | "type": "number", 191 | "desc": "批量签到之间的间隔时间(毫秒)" 192 | }, 193 | { 194 | "id": "BD_notifyMode", 195 | "name": "通知模式(可选)", 196 | "val": "1", 197 | "type": "radios", 198 | "desc": "选择签到结果的通知方式", 199 | "items": [ 200 | { 201 | "key": "1", 202 | "label": "所有结果都通知" 203 | }, 204 | { 205 | "key": "2", 206 | "label": "仅失败时通知" 207 | }, 208 | { 209 | "key": "3", 210 | "label": "不通知" 211 | } 212 | ] 213 | }, 214 | { 215 | "id": "BD_timeout(可选)", 216 | "name": "请求超时时间", 217 | "val": "10000", 218 | "type": "number", 219 | "desc": "网络请求的超时时间(毫秒)" 220 | } 221 | ], 222 | "author": "@chiupam", 223 | "repo": "https://github.com/chiupam/surge", 224 | "script": "https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/tieba.js", 225 | "icons": [ 226 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/tieba.png", 227 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/tieba.png" 228 | ] 229 | }, 230 | { 231 | "id": "xmSports", 232 | "name": "小米运动", 233 | "keys": [], 234 | "descs_html": [ 235 | "

注意事项: 登录的 APP 名为 zepp life

", 236 | "

下载链接: iOS端 | Android端

" 237 | ], 238 | "settings": [ 239 | { 240 | "id": "xmSportPhone", 241 | "name": "登录手机号", 242 | "val": "", 243 | "type": "text", 244 | "desc": "小米运动登录时所使用的手机号码" 245 | }, 246 | { 247 | "id": "xmSportPassword", 248 | "name": "登录密码", 249 | "val": "", 250 | "type": "text", 251 | "desc": "小米运动登录时所所需的密码" 252 | }, 253 | { 254 | "id": "xmSportMinStep", 255 | "name": "最小运动步数", 256 | "val": "20000", 257 | "type": "radios", 258 | "desc": "选择需要修改最小的运动步数", 259 | "items": [ 260 | { 261 | "key": "20000", 262 | "label": "20000步" 263 | }, 264 | { 265 | "key": "30000", 266 | "label": "30000步" 267 | }, 268 | { 269 | "key": "40000", 270 | "label": "40000步" 271 | } 272 | ] 273 | }, 274 | { 275 | "id": "xmSportMaxStep", 276 | "name": "最大运动步数", 277 | "val": "22000", 278 | "type": "radios", 279 | "desc": "选择需要修改最大的运动步数", 280 | "items": [ 281 | { 282 | "key": "22000", 283 | "label": "22000步" 284 | }, 285 | { 286 | "key": "32000", 287 | "label": "32000步" 288 | }, 289 | { 290 | "key": "42000", 291 | "label": "42000步" 292 | }, 293 | { 294 | "key": "52000", 295 | "label": "52000步" 296 | } 297 | ] 298 | } 299 | ], 300 | "author": "@chiupam", 301 | "repo": "https://github.com/chiupam/surge", 302 | "script": "https://raw.githubusercontent.com/chiupam/surge/main/scripts/xmSport.js", 303 | "icons": [ 304 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/xmSport.jpeg", 305 | "https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/icon/xmSport.jpeg" 306 | ] 307 | }, 308 | { 309 | "id": "QLAPI", 310 | "name": "青龙API", 311 | "keys": [], 312 | "descs_html": [ 313 | "

青龙面板 => 系统设置 => 应用设置

", 314 | "

相应的应用必须拥有 “环境变量” 权限

" 315 | ], 316 | "settings": [ 317 | { 318 | "id": "ql_url", 319 | "name": "青龙面板地址", 320 | "val": "", 321 | "type": "text", 322 | "desc": "建议填写外网地址,任何时候都可以调用成功" 323 | }, 324 | { 325 | "id": "ql_client_id", 326 | "name": "青龙应用ClientID", 327 | "val": "", 328 | "type": "text", 329 | "desc": "青龙面板应用设置中的应用ID" 330 | }, 331 | { 332 | "id": "ql_client_secret", 333 | "name": "青龙应用ClientSecret", 334 | "val": "", 335 | "type": "text", 336 | "desc": "青龙面板应用设置中的应用Secret" 337 | } 338 | ], 339 | "author": "@chiupam", 340 | "repo": "https://github.com/chiupam/surge", 341 | "icons": [ 342 | "https://qn.whyour.cn/logo.png", 343 | "https://qn.whyour.cn/logo.png" 344 | ] 345 | } 346 | ] 347 | } 348 | -------------------------------------------------------------------------------- /platforms/boxjs/chiupam.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/chiupam.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/Exchange.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Exchange.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/For_Test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/For_Test.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/GitHub.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/GitHub.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/Header.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Header.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/JingDong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/JingDong.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/Location.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Location.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/Location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Location.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/NoNotify.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/NoNotify.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/Notice.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Notice.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/Notify.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Notify.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/Procuratorate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Procuratorate.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/QQspeed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/QQspeed.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/Scriptable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/Scriptable.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/ShareCode.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/ShareCode.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/YiBan.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/YiBan.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/gdufe.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/gdufe.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/jd.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/jd.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/kmmu.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/kmmu.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/kmmu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/kmmu.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/kmu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/kmu.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/kmust.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/kmust.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/kmust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/kmust.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/me.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/qndxx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/qndxx.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/qndxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/qndxx.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/setting.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/setting.jpg -------------------------------------------------------------------------------- /platforms/boxjs/icon/tieba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/tieba.png -------------------------------------------------------------------------------- /platforms/boxjs/icon/xmSport.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/xmSport.jpeg -------------------------------------------------------------------------------- /platforms/boxjs/icon/zsfc.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chiupam/surge/7eed8dfd6555f2208f4e7c61f16750e0345210f5/platforms/boxjs/icon/zsfc.jpeg -------------------------------------------------------------------------------- /scripts/greasyfork/sppet.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 中检网自动学习 3 | // @namespace https://github.com/chiupam 4 | // @version 1.6 5 | // @description 中国检察教育培训网络学院全自动学习课程,点击学习中心,然后进入班级,最后刷新页面即可。 6 | // @author chiupam 7 | // @match https://www.sppet.cn/portal/play.do* 8 | // @match https://www.sppet.cn/examine/index.html* 9 | // @icon https://www.sppet.cn/examine/data/imgs/favicon.ico 10 | // @grant none 11 | // @license GNU GPLv3 12 | // ==/UserScript== 13 | 14 | (async function () { 15 | 'use strict'; 16 | 17 | // 动态插入日志容器到页面 18 | function createLogContainer() { 19 | const logContainer = document.createElement('div'); 20 | logContainer.id = 'log-container'; 21 | logContainer.style.padding = '10px'; // 设置容器内部的边距为 10px 22 | logContainer.style.backgroundColor = '#333'; // 设置背景颜色为深灰色 23 | logContainer.style.color = '#fff'; // 设置文本颜色为白色 24 | logContainer.style.border = '1px solid #ddd'; // 设置边框为 1px 的浅灰色实线,以区分容器和背景 25 | logContainer.style.maxHeight = `${window.innerHeight / 3}px`; // 设置容器的最大高度为 200px 26 | logContainer.style.maxWidth = '400px'; // 设置容器的最大宽度为 400px 27 | logContainer.style.overflowY = 'auto'; // 当内容超过容器高度时,自动显示垂直滚动条 28 | logContainer.style.position = 'fixed'; // 固定位置,始终显示在页面上 29 | logContainer.style.top = `${window.innerHeight / 3}px`; // 设置容器顶部距离页面顶部三分之一窗口高度的位置 30 | logContainer.style.right = '10px'; // 距离页面右侧10px 31 | logContainer.style.zIndex = '1000'; // 确保在页面上层显示 32 | 33 | document.body.appendChild(logContainer); // 将日志容器添加到页面中 34 | 35 | return logContainer; 36 | } 37 | 38 | // 添加日志到日志容器 39 | function logPage(logContainer, message) { 40 | console.log(message); // 同时在控制台输出日志 41 | 42 | const logEntry = document.createElement('div'); 43 | logEntry.textContent = message; // 设置日志内容 44 | logEntry.style.whiteSpace = 'nowrap'; // 禁止换行 45 | logEntry.style.overflow = 'hidden'; // 超出部分隐藏 46 | logEntry.style.textOverflow = 'ellipsis'; // 超出部分显示省略号 47 | logContainer.appendChild(logEntry); // 将日志内容添加到日志容器中 48 | logContainer.scrollTop = logContainer.scrollHeight; // 自动滚动到容器底部 49 | } 50 | 51 | // 格式化日期 52 | function formatDate() { 53 | // 获取 UTC 时间的毫秒数,并加上 8 小时的毫秒数 (8 * 60 * 60 * 1000) 54 | const offsetMilliseconds = 8 * 60 * 60 * 1000; 55 | const beijingTime = new Date(new Date().getTime() + offsetMilliseconds); 56 | 57 | // 格式化为 YYYY-MM-DD HH:MM:SS 58 | return beijingTime.toISOString().replace('T', ' ').split('.')[0]; 59 | } 60 | 61 | // 格式化播放时长 62 | function formatTime(seconds) { 63 | const hours = Math.floor(seconds / 3600); // 1小时 = 3600秒 64 | const minutes = Math.floor((seconds % 3600) / 60); // 1分钟 = 60秒 65 | const secs = Math.floor(seconds % 60); // 余下的秒数 66 | 67 | // 使用padStart确保两位数格式,不足两位的补0 68 | const formattedHours = String(hours).padStart(2, '0'); 69 | const formattedMinutes = String(minutes).padStart(2, '0'); 70 | const formattedSeconds = String(secs).padStart(2, '0'); 71 | 72 | if (formattedHours === '00') { // 如果没有小时数,只显示分钟和秒数 73 | return `${formattedMinutes}:${formattedSeconds}`; 74 | } else { // 如果有小时数,显示小时、分钟和秒数 75 | return `${formattedHours}:${formattedMinutes}:${formattedSeconds}` 76 | } 77 | } 78 | 79 | const logContainer = createLogContainer(); // 创建日志容器 80 | logPage(logContainer, `程序执行时间: ${formatDate()}`); 81 | 82 | if (window.location.href.includes('stady_detail')) { // 在学习详情页面执行以下操作 83 | const intervalId = setInterval(function() { 84 | const study = document.querySelectorAll('.btn'); // 获取所有继续学习的按钮元素 85 | const timeElement = document.querySelectorAll('.text_iconTime span:first-child span'); // 获取所有课程时间的元素 86 | const progress = document.querySelectorAll('.el-progress__text'); // 获取所有进度条的元素 87 | const name = document.querySelectorAll('.text_title.oneEllipsis'); // 获取所有课程的名称 88 | 89 | if (progress.length === 0) location.reload(); // 如果 progress.length 等于0, 刷新页面 90 | 91 | let count = 0; // 用于计数已完成课程的数量 92 | progress.forEach(element => {if (parseFloat(element.textContent.trim()) === 100) count++}); // 如果课程进度为100,计数加1 93 | 94 | if (count < progress.length) { // 如果有未完成的课程 95 | const division = `${count}/${progress.length}` // 计算已完成课程的数量和总课程数量 96 | const percentage = `${(count / progress.length * 100).toFixed(2)}%`; // 计算已完成课程的百分比 97 | logPage(logContainer, `总课程完成进度: ${division} (${percentage})`); 98 | 99 | // 遍历所有课程,找到未完成的课程并点击继续学习按钮 100 | for (let i = 0; i < progress.length; i++) { 101 | let progressFloat = parseFloat(progress[i].textContent.trim()); // 课程进度,转换为浮点数 102 | logPage(logContainer, `${name[i].textContent.trim()}`); 103 | 104 | if (progressFloat < 100) { 105 | logPage(logContainer, `上述课程进度: ${progressFloat}%,${progressFloat === 0 ? '开始' : '继续'}学习`); 106 | logPage(logContainer, `若未弹出新窗口, 请检查是否被浏览器拦截`); // 新窗口有可能被拦截, 提示一下用户 107 | localStorage.setItem('progressFloat', progressFloat); // 将进度保存到 localStorage 108 | study[i].click(); // 点击继续学习按钮 109 | break; // 找到并点击按钮后,停止遍历 110 | } else { 111 | logPage(logContainer, `上述课程已学完, 跳过`); 112 | }; 113 | }; 114 | } else { 115 | logPage(logContainer, '所有课程已完成'); 116 | }; 117 | 118 | clearInterval(intervalId); // 停止轮询 119 | }, 3000); // 每隔3秒检查一次 120 | 121 | } else if (window.location.href.includes('play.do')) { // 在播放页面执行以下操作 122 | let percentage = parseFloat(localStorage.getItem('progressFloat')); // 获取进度百分比 123 | 124 | let video; // 声明视频变量 125 | const intervalVideo = setInterval(function() { 126 | // 延迟获取视频元素,确保页面加载完成 127 | if (!video) { 128 | video = document.querySelector('video'); // 获取第一个视频元素 129 | if (!video) { 130 | logPage(logContainer, '未找到视频, 等待加载...'); 131 | return; // 如果未找到视频元素,继续等待 132 | } else { 133 | clearInterval(intervalVideo); // 视频播放完毕, 停止循环 134 | logPage(logContainer, '找到视频, 开始监控学习进度'); 135 | video.muted = true; // 强制静音 136 | 137 | // 事件监听器:视频播放结束时自动刷新第一个页面并关闭当前窗口 138 | video.addEventListener('ended', () => {localStorage.setItem('refresh', 'true'); window.close();}); 139 | video.addEventListener('pause', () => {video.play()}); // 事件监听器:视频暂停时自动播放 140 | video.addEventListener('volumechange', () => {video.muted = true}); // 事件监听器:视频音量变化时强制静音 141 | } 142 | } 143 | 144 | // 轮询检查 "开始学习" 或 "继续学习" 按钮 145 | const intervalChoise = setInterval(function() { 146 | const choise = document.querySelector('.user_choise'); // 获取选项元素 147 | if (choise) { 148 | clearInterval(intervalChoise); // 停止轮询 149 | choise.click(); // 点击 "开始学习" 或 "继续学习" 按钮 150 | } 151 | }); 152 | 153 | // 轮询检查并设置视频播放进度 154 | const intervalProgress = setInterval(function() { 155 | if (video.play() && video.duration) { 156 | clearInterval(intervalProgress); // 停止轮询 157 | const percentageToFixed = percentage.toFixed(2); // 将进度百分比转换为字符串并保留两位小数 158 | percentage > 2 ? percentage -= 1.9 : percentage = 0; // 如果进度大于2,则减去2,否则设为0 159 | video.currentTime = video.duration * (percentage / 100); // 设置视频播放位置 160 | logPage(logContainer, `已学习: ${formatTime(video.currentTime)}(${percentageToFixed}%)`); // 输出当前播放时间 161 | } 162 | }) 163 | }, 1000); // 每1秒检查一次 164 | 165 | } else { // 在第一个页面执行以下操作 166 | logPage(logContainer, '首先请先登录'); 167 | logPage(logContainer, '接着点击学习中心'); 168 | logPage(logContainer, '然后点击进入班级'); 169 | logPage(logContainer, '最后刷新浏览器'); 170 | } 171 | })(); 172 | 173 | // 在第一个页面中,添加以下脚本用于检测 localStorage 变化并执行刷新 174 | if (window.location.href.includes('www.sppet.cn') && !window.location.href.includes('play.do')) { 175 | window.addEventListener('storage', function(event) { 176 | if (event.key === 'refresh' && event.newValue === 'true') { 177 | localStorage.removeItem('refresh'); 178 | location.reload(); 179 | } 180 | }); 181 | } -------------------------------------------------------------------------------- /scripts/javascript/BiliBili/BiliBiliAds.6.74.0.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=BiliBili Ads 2 | #!desc=BiliBili Version: 6.74.0; Date: 2023-07-09; Verification: Ture 3 | 4 | [Rule] 5 | DOMAIN-SUFFIX, cm.bilibili.com, REJECT 6 | URL-REGEX, ^https?:\/\/api\.bilibili\.com\/x\/v2\/dm\/ad, REJECT 7 | # > 可能的一些推广(beta) 8 | URL-REGEX, ^https?:\/\/api\.bilibili\.com\/pgc\/season\/app\/related\/recommend\?, REJECT 9 | # > BiliBili漫画去广告 10 | URL-REGEX, ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.comic\/flash, REJECT 11 | 12 | [URL Rewrite] 13 | # > 去除搜索中的默认关键词 14 | ^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.interface\.v1\.Search\/DefaultWords$ - reject 15 | # > 去除搜索中的大家都在搜 16 | ^https?:\/\/api\.vc\.bilibili\.com\/search_svr\/v\d\/Search\/recommend_words - reject 17 | # > 去除动态中的话题 18 | ^https?:\/\/api\.vc\.bilibili\.com\/topic_svr\/v1\/topic_svr - reject 19 | # > 去除动态中的最常访问 20 | ^https?:\/\/api\.vc\.bilibili\.com\/dynamic_svr\/v1\/dynamic_svr\/mix_uplist - reject 21 | # > 可能的一些推广(beta) 22 | ^https?:\/\/api\.bilibili\.com\/pgc\/season\/app\/related\/recommend\? - reject 23 | # > BiliBili漫画去广告 24 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/Flash - reject 25 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/ListFlash - reject 26 | 27 | [Map Local] 28 | # > 去除搜索中的大家都在搜 29 | ^https?:\/\/api\.vc\.bilibili\.com\/search_svr\/v\d\/Search\/recommend_words data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/reject-dict.json" 30 | # > 去除动态中的话题 31 | ^https?:\/\/api\.vc\.bilibili\.com\/topic_svr\/v1\/topic_svr data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/reject-dict.json" 32 | # > 去除动态中的最常访问 33 | ^https?:\/\/api\.vc\.bilibili\.com\/dynamic_svr\/v1\/dynamic_svr\/mix_uplist data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/reject-dict.json" 34 | # > 可能的一些推广(beta) 35 | ^https?:\/\/api\.bili(bili\.com|api\.net)\/pgc\/season\/app\/related\/recommend\? data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/reject-dict.json" 36 | # > BiliBili漫画去广告 37 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/Flash data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/reject-dict.json" 38 | ^https?:\/\/manga\.bilibili\.com\/twirp\/comic\.v\d\.Comic\/ListFlash data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/reject-dict.json" 39 | ^https?:\/\/api\.live\.bilibili\.com\/xlive\/e-commerce-interface\/v1\/ecommerce-user\/get_shopping_info\? data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/reject-dict.json" 40 | 41 | [Script] 42 | # > BiliBili去广告 43 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/api\.live\.bilibili\.com\/xlive\/app-room\/v1\/index\/getInfoByRoom, requires-body=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/BiliBili.js 44 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/api\.bili(bili\.com|api\.net)\/pgc\/page\/(bangumi|cinema\/tab\?), requires-body=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/BiliBili.js 45 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/app\.bili(bili\.com|api\.net)\/x\/v2\/(splash\/(brand\/list|event\/list2|list|show)|feed\/index(\/story)?|search\/square), requires-body=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/BiliBili.js 46 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.view\.v1\.View\/View$, requires-body=1, binary-body-mode=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/BiliBili.js 47 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.dynamic\.v2\.Dynamic\/Dyn(All|Video)$, requires-body=1, binary-body-mode=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/BiliBili.js 48 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.playurl\.v1\.PlayURL\/PlayView$, requires-body=1, binary-body-mode=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/BiliBili.js 49 | B站(推荐去广告) = type=http-response, pattern=^https?:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.polymer\.app\.search\.v1\.Search\/SearchAll$, requires-body=1, binary-body-mode=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/BiliBili/BiliBili.js 50 | 51 | [MITM] 52 | hostname = %APPEND% manga.bilibili.com, api.live.bilibili.com, api.vc.bilibili.com, app.bilibili.com, app.biliapi.net, api.bilibili.com, api.biliapi.net, grpc.biliapi.net -------------------------------------------------------------------------------- /scripts/javascript/BiliBili/reject-dict.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /scripts/javascript/TestFlight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 脚本说明:突破 TestFlight 下载限制,脚本搬运至 NobyDa 大佬。 4 | * 源地址:https://gist.githubusercontent.com/NobyDa/9be418b93afc5e9c8a8f4d28ae403cf2/raw/TF_Download.js 5 | * 6 | */ 7 | 8 | const $ = new Env('') 9 | 10 | let Body = $.toObj($request.body) 11 | Body.storefrontId = '143380-1,29' 12 | $.done({body: $.toStr(Body)}) 13 | 14 | function Env() { 15 | LN = typeof $loon != "undefined" 16 | SG = typeof $httpClient != "undefined" && !LN 17 | QX = typeof $task != "undefined" 18 | toObj = (str) => JSON.parse(str) 19 | toStr = (obj) => JSON.stringify(obj) 20 | done = (value = {}) => {$done(value)} 21 | return { toObj, toStr, done } 22 | } 23 | -------------------------------------------------------------------------------- /scripts/javascript/Youtube/17.16.4/YouTubeAds.17.16.4.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=YouTube Ads 2 | #!desc=YouTube Version: 17.16.4; Date: 2023-06-16; Verification: Ture 3 | 4 | # > Credit 5 | # @Choler & @DivineEngine & @app2smile 6 | # > Github 7 | # https://github.com/Maasea/sgmodule/tree/master 8 | # > Raw Javascript 9 | # https://raw.githubusercontent.com/Maasea/sgmodule/544affd72b002db4bcc0640f2fd5b18751f3d7a3/Script/Youtube/youtube.js 10 | # https://raw.githubusercontent.com/Maasea/sgmodule/544affd72b002db4bcc0640f2fd5b18751f3d7a3/Script/Youtube/youtube.src.js 11 | 12 | [MITM] 13 | hostname = %APPEND% *.googlevideo.com, youtubei.googleapis.com 14 | 15 | [Script] 16 | YouTube去广告 = type=http-response, pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next|player|search|reel\/reel_watch_sequence|guide|account\/get_setting)\?, requires-body=1, binary-body-mode=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/youtube.js 17 | 18 | [Map Local] 19 | ^https?:\/\/[\w-]+\.googlevideo\.com\/initplayback.+&oad data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/blank.txt" header="Content-Type: application/vnd.yt-ump" 20 | -------------------------------------------------------------------------------- /scripts/javascript/Youtube/17.16.4/blank.txt: -------------------------------------------------------------------------------- 1 | 0 -------------------------------------------------------------------------------- /scripts/javascript/Youtube/18.49.3/YouTubeAds.18.49.3.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=YouTube Ads 2 | #!desc=YouTube Version: 18.49.3; Date: 2023-12-21; Verification: Ture 3 | 4 | # > 源地址 5 | # https://raw.githubusercontent.com/Maasea/sgmodule/master/YoutubeAds.sgmodule 6 | 7 | [Rule] 8 | AND,((DOMAIN-SUFFIX,googlevideo.com), (PROTOCOL,UDP)),REJECT-NO-DROP 9 | 10 | [Script] 11 | YouTube(Request) = type=http-request,pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next|player|reel\/reel_watch_sequence),requires-body=1,max-size=-1,binary-body-mode=1,script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/18.49.3/youtube.request.js 12 | YouTube(Response) = type=http-response,pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next|player|search|reel\/reel_watch_sequence|guide|account\/get_setting),requires-body=1,max-size=-1,binary-body-mode=1,script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/18.49.3/youtube.response.js 13 | 14 | [Map Local] 15 | ^https?:\/\/[\w-]+\.googlevideo\.com\/initplayback.+&oad data="https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Youtube/18.49.3/blank.txt" 16 | 17 | [MITM] 18 | hostname = %APPEND% *.googlevideo.com, youtubei.googleapis.com 19 | -------------------------------------------------------------------------------- /scripts/javascript/Youtube/18.49.3/blank.txt: -------------------------------------------------------------------------------- 1 | 0 -------------------------------------------------------------------------------- /scripts/javascript/Youtube/README.md: -------------------------------------------------------------------------------- 1 | # YouTube去广告 2 | 3 | 历史说明 4 | 5 | ### Version 17.16.4 6 | 7 | - 于 2023年12月20日 强制更新,但是脚本是能用的,只是应用无法进入主页 8 | 9 | ### Version 18.49.3 10 | 11 | - 2023年12月21日 最新版本,脚本亦可用 12 | -------------------------------------------------------------------------------- /scripts/javascript/alipay.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 蚂蚁森林能量通知用户收取脚本 3 | */ 4 | 5 | // 创建Env对象 6 | const $ = new Env(`🌲 蚂蚁森林收能量`); 7 | 8 | // 发送通知 9 | $.notice( 10 | $.name, // 标题 11 | "", // 副标题 12 | "点击立马收取296g能量!", // 消息内容 13 | "alipay://platformapi/startapp?appId=60000002" // 跳转链接 14 | ); 15 | 16 | // 完成脚本 17 | $.done(); 18 | 19 | /** 20 | * 创建Env对象 21 | * @returns {Object} 包含notice和done方法的对象 22 | */ 23 | function Env(name) { 24 | // 判断运行环境 25 | LN = typeof $loon != "undefined"; // Loon 26 | SG = typeof $httpClient != "undefined" && !LN; // Surge 27 | QX = typeof $task != "undefined"; // Quantumult X 28 | 29 | // 发送通知 30 | notice = (title, subtitle, message, url) => { 31 | if (LN) $notification.post(title, subtitle, message, url); // Loon 32 | if (SG) $notification.post(title, subtitle, message, { url: url }); // Surge 33 | if (QX) $notify(title, subtitle, message, { "open-url": url }); // Quantumult X 34 | }; 35 | 36 | // 完成脚本 37 | done = (value = {}) => { 38 | $done(value); 39 | }; 40 | 41 | // 返回对象 42 | return { name, notice, done }; 43 | } 44 | -------------------------------------------------------------------------------- /scripts/javascript/backup/Location.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 使用方法:添加 Surge 模块后,打开 http://yibandw.kmmu.edu.cn/ 并完成登录即可。 4 | * 5 | * Surge's Moudule: https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/Location.sgmodule 6 | * 7 | * hostname: e.kmmu.edu.cn, yibandw.kmmu.edu.cn 8 | * 9 | * type: http-request 10 | * regex: ^https?://e\.kmmu\.edu\.cn/lyuapServer/v1/tickets$|^https?://yibandw\.kmmu\.edu\.cn/caswisedu/login\.htm$ 11 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/Location.js 12 | * requires-body: 1 | true 13 | * 14 | * type: http-response 15 | * regex: ^https?://yibandw\.kmmu\.edu\.cn/syt/other/index\.htm\?.* 16 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/Location.js 17 | * requires-body: 1 | true 18 | * 19 | * =============== Surge =============== 20 | * 易班定位签到 = type=http-request, pattern^https?://e\.kmmu\.edu\.cn/lyuapServer/v1/tickets$|^https?://yibandw\.kmmu\.edu\.cn/caswisedu/login\.htm$, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Location.js, script-update-interval=0, timeout=30 21 | * 易班定位签到 = type=http-response, pattern=^https?://yibandw\.kmmu\.edu\.cn/syt/other/index\.htm\?.*, requires-body=1, max-size=0, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/Location.js, script-update-interval=0, timeout=30 22 | * 23 | */ 24 | 25 | const $ = Env() 26 | const bark_token = $.read("BARK_PUSH") 27 | const fast = $.read("location_api_open") 28 | if (typeof $request !== 'undefined') set() 29 | 30 | 31 | async function set() { 32 | if ($request.url.indexOf("ticket") != -1) { 33 | body = $request.body 34 | username = body.match(/(username=[^&]*)/)[1].replace(/username=/, "") 35 | password = body.match(/(password=[^&]*)/)[1].replace(/password=/, "") 36 | config = `{"name": "my_name", "username": "${username}", "password": "${password}", "uid": "my_uid", "inschool": true}` 37 | $.write(config, "location_cache") 38 | } else if ($request.url.indexOf("login") != -1) { 39 | body = $request.body 40 | uid = decodeURIComponent(body.replace(/uid=/, "")) 41 | $.write($.read("location_cache").replace(/my_uid/, uid), "location_cache") 42 | } else { 43 | body = $response.body 44 | myname = body.match(/(姓名:[^<]*)/)[1].replace(/姓名:/, "") 45 | config = $.read("location_cache").replace(/my_name/, myname) 46 | if (bark_token) { 47 | if (fast == 'true') { 48 | $.write("undefined", "location") 49 | body = encodeURI(JSON.stringify(eval(("("+config+")")))) 50 | url = `${$.read("serverless_api")}Fast_Location/body?body=${body}` 51 | await BarkNotify("点击即可快捷签到!", url, url) 52 | } else { 53 | $.write(config, "location") 54 | await BarkNotify("长按或下拉复制!", config, "http://boxjs.net") 55 | } 56 | } else { 57 | $.notice("易班定位签到", "点击通知栏去复制!", config, "http://boxjs.net") 58 | } 59 | } 60 | $.done() 61 | } 62 | 63 | 64 | function BarkNotify(body, text, url) { 65 | $.log(text) 66 | return new Promise((resolve) => { 67 | const options = { 68 | url: `https://api.day.app/push`, 69 | headers: {'Content-Type': 'application/json; charset=utf-8'}, 70 | body: { 71 | "body": body, 72 | "device_key": bark_token, 73 | "title": '易班定位签到抓包结果', 74 | "autoCopy": '1', 75 | "copy": text, 76 | "url": url, 77 | "sound": 'mailsent' 78 | }, 79 | timeout: 5 80 | } 81 | $.post(options, (err, resp, data) => { 82 | try { 83 | if (err) { 84 | $.log('Bark APP发送通知调用API失败!!') 85 | $.log(err) 86 | } else { 87 | data = JSON.parse(data) 88 | if (data.code === 200) { 89 | $.log('Bark APP发送通知消息成功'); 90 | } else { 91 | $.log(`${data.message}`) 92 | } 93 | } 94 | } catch (e) { 95 | $.log(e) 96 | $.log(resp) 97 | } finally { 98 | resolve() 99 | } 100 | }) 101 | }) 102 | } 103 | 104 | 105 | function Env() { 106 | LN = typeof $loon != "undefined" 107 | SG = typeof $httpClient != "undefined" && !LN 108 | QX = typeof $task != "undefined" 109 | read = (key) => { 110 | if (LN || SG) return $persistentStore.read(key) 111 | if (QX) return $prefs.valueForKey(key) 112 | } 113 | write = (key, val) => { 114 | if (LN || SG) return $persistentStore.write(key, val); 115 | if (QX) return $prefs.setValueForKey(key, val) 116 | } 117 | notice = (title, subtitle, message, url) => { 118 | if (LN) $notification.post(title, subtitle, message, url) 119 | if (SG) $notification.post(title, subtitle, message, { url: url }) 120 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 121 | } 122 | get = (url, cb) => { 123 | if (LN || SG) {$httpClient.get(url, cb)} 124 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 125 | } 126 | post = (url, cb) => { 127 | if (LN || SG) {$httpClient.post(url, cb)} 128 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 129 | } 130 | put = (url, cb) => { 131 | if (LN || SG) {$httpClient.put(url, cb)} 132 | if (QX) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 133 | } 134 | log = (message) => console.log(message) 135 | done = (value = {}) => {$done(value)} 136 | return { LN, SG, QX, read, write, notice, get, post, put, log, done } 137 | } -------------------------------------------------------------------------------- /scripts/javascript/backup/elm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 使用方法:打开饿了么APP,点击我的,点击赚吃货豆即可。 4 | * 搭配脚本:https://raw.githubusercontent.com/leafTheFish/DeathNote/main/elm.js 5 | * 6 | * type: http-request 7 | * regex: ^https://h5\.ele\.me/restapi/biz.growth_finetune/v1/finetune/operate? 8 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/elm.js 9 | * requires-body: 1 | true 10 | * 11 | */ 12 | 13 | /* 14 | 使用方法:打开饿了么APP,点击我的,点击赚吃货豆即可。 15 | 搭配脚本:https://raw.githubusercontent.com/leafTheFish/DeathNote/main/elm.js 16 | 17 | type: http-request 18 | regex: ^https://h5\.ele\.me/restapi/biz.growth_finetune/v1/finetune/operate? 19 | script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/elm.js 20 | box: https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.boxjs.json 21 | 22 | ###### Surge ###### 23 | [Script] 24 | 饿了么Cookie = type=http-request, pattern=^https://h5\.ele\.me/restapi/biz.growth_finetune/v1/finetune/operate?, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/elm.js 25 | 26 | [MTIM] 27 | hostname = %APPEND% h5.ele.me 28 | 29 | ###### Loon ###### 30 | [Script] 31 | http-request ^https://h5\.ele\.me/restapi/biz.growth_finetune/v1/finetune/operate? script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/elm.js, requires-body=true, timeout=120, tag=饿了么Cookie 32 | 33 | [Mitm] 34 | hostname = h5.ele.me 35 | 36 | */ 37 | 38 | const $ = Env() 39 | const user_id = $.read("TG_USER_ID") || arg().split(`&`)[0] 40 | const bot_token = $.read("TG_BOT_TOKEN") || `5099904762:AA` + arg().split(`&`)[1] 41 | if (typeof $request !== 'undefined') {set()} 42 | 43 | 44 | function arg() { 45 | try {return $argument.match(/api=(.*)/)[1]} 46 | catch {return `none&none`} 47 | } 48 | 49 | 50 | async function set() { 51 | cookie = $request.headers.Cookie 52 | cookie = cookie.replace(/(; cookie2=[^;]*)/, "") 53 | if ($.read("ele_cookie") != cookie) { 54 | if (user_id && user_id != `none` && bot_token ) { 55 | await tgNotify(`elm ${cookie}`) 56 | } else { 57 | $.notice("饿了么", "前往boxjs中查看!", "查询键:ele_cookie", "http://boxjs.net") 58 | } 59 | $.write(cookie, "ele_cookie") 60 | } 61 | $.done() 62 | } 63 | 64 | 65 | function tgNotify(text) { 66 | $.log(text) 67 | return new Promise((resolve) => { 68 | const options = { 69 | url: `https://api.telegram.org/bot${bot_token}/sendMessage`, 70 | headers: {'Content-Type': 'application/x-www-form-urlencoded'}, 71 | body: `chat_id=${user_id}&text=${text}&disable_web_page_preview=true`, 72 | timeout: 30000 73 | } 74 | $.post(options, (err, resp, data) => { 75 | try { 76 | if (err) { 77 | $.log('Telegram Bot发送通知调用API失败!!') 78 | $.log(err) 79 | } else { 80 | data = JSON.parse(data) 81 | if (data.ok) { 82 | $.notice("【饿了么】", "Telegram Bot发送通知消息完成", text, "") 83 | } else { 84 | $.notice("【饿了么】", "Telegram Bot发送通知消息失败!", "手动前往boxjs中查询!数据键:ele_cookie\n或查看脚本运行日志", "") 85 | } 86 | } 87 | } catch (e) { 88 | $.log(e) 89 | $.log(resp) 90 | } finally { 91 | resolve() 92 | } 93 | }) 94 | }) 95 | } 96 | 97 | 98 | function Env() { 99 | LN = typeof $loon != "undefined" 100 | SG = typeof $httpClient != "undefined" && !LN 101 | QX = typeof $task != "undefined" 102 | read = (key) => { 103 | if (LN || SG) return $persistentStore.read(key) 104 | if (QX) return $prefs.valueForKey(key) 105 | } 106 | write = (key, val) => { 107 | if (LN || SG) return $persistentStore.write(key, val); 108 | if (QX) return $prefs.setValueForKey(key, val) 109 | } 110 | notice = (title, subtitle, message, url) => { 111 | if (LN) $notification.post(title, subtitle, message, url) 112 | if (SG) $notification.post(title, subtitle, message, { url: url }) 113 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 114 | } 115 | get = (url, cb) => { 116 | if (LN || SG) {$httpClient.get(url, cb)} 117 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 118 | } 119 | post = (url, cb) => { 120 | if (LN || SG) {$httpClient.post(url, cb)} 121 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 122 | } 123 | put = (url, cb) => { 124 | if (LN || SG) {$httpClient.put(url, cb)} 125 | if (QX) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 126 | } 127 | log = (message) => console.log(message) 128 | done = (value = {}) => {$done(value)} 129 | return { LN, SG, QX, read, write, notice, get, post, put, log, done } 130 | } 131 | -------------------------------------------------------------------------------- /scripts/javascript/backup/epidemic_kmust.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 使用方法:打开我在校园,点击日检日报即可。 4 | * 5 | * 备注:目前仅做了假期日常打卡,未清楚是否会有开学后的每日打卡。 6 | * 7 | * Surge's Moudule: https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/KMUST.sgmodule 8 | * BoxJs: https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.boxjs.json 9 | * 10 | * hostname: student.wozaixiaoyuan.com 11 | * 12 | * type: http-request 13 | * regex: ^https?://student\.wozaixiaoyuan\.com/heat/getTodayHeatList\.json 14 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/epidemic_kmust.js 15 | * requires-body: 1 | true 16 | * 17 | * type: cron 18 | * cron: 1 0 9,11 * * * 19 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/epidemic_kmust.js 20 | * 21 | * =============== Surge =============== 22 | * 昆工疫情SESSION = type=http-request, pattern=^https?://student\.wozaixiaoyuan\.com/heat/getTodayHeatList\.json, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/epidemic_kmust.js, script-update-interval=0, timeout=10 23 | * 昆工疫情签到 = type=cron, cronexp="1 0 9,11 * * *", wake-system=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/epidemic_kmust.js, script-update-interval=0, timeout=10 24 | * 25 | * =============== Loon =============== 26 | * http-request ^https?://student\.wozaixiaoyuan\.com/heat/getTodayHeatList\.json script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/epidemic_kmust.js, requires-body=true, timeout=10, tag=昆工疫情JWSESSION 27 | * cron "0 0 9,11 * * *" script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/epidemic_kmust.js, tag=昆工疫情签到 28 | * 29 | */ 30 | 31 | 32 | const $ = new Env('🌼 我在校园 🌼') 33 | 34 | const inSchool = $.toObj($.read("kmust_inSchool")) 35 | inSchool ? address = `云南省昆明市呈贡区致远路与郎溪街交叉口` : address = $.read("kmust_address") 36 | 37 | !(async () => { 38 | if (!typeof $request !== 'undefined') { 39 | jwsession = $.read(`kmust_JWSESSION`) 40 | list = await index(jwsession) 41 | // state 0: 未开启 1: 开启中 2: 已结束 42 | // type 0: 未打卡 1: 已打卡 43 | if (list.state == 0) { 44 | $.log(`⭕ ${period().t}未开启`) 45 | } else if (list.state == 1 && list.type == 1) { 46 | $.log(`⭕ ${period().t}已经完成`) 47 | } else if (list.state == 2) { 48 | $.log(`⭕ ${period().t}已经结束`) 49 | } else { 50 | address = await reverse(await geocoding(address)) 51 | await main(jwsession, list.id, address) 52 | } 53 | } else { 54 | let Method = $request.method 55 | if ((Method == "POST" || Method == "GET") && (!username && !passwd)) { 56 | if ($request.headers) { 57 | if (!$.read(`kmust_JWSESSION`)) { 58 | $.write($request.headers.JWSESSION, "kmust_JWSESSION") 59 | $.notice($.name, `✅`, `首次写入 JWSESSION 成功`) 60 | } else if ($request.headers.JWSESSION != $.read(`kmust_JWSESSION`)) { 61 | $.write($request.headers.JWSESSION, "kmust_JWSESSION") 62 | $.notice($.name, `✅`, `更新 JWSESSION 成功`) 63 | } 64 | } else { 65 | $.notice($.name, ``, `⭕ 无法读取请求头`) 66 | } 67 | } 68 | } 69 | })() 70 | .catch((e) => $.log(e)) 71 | .finally(() => $.done()) 72 | 73 | function period() { 74 | /** 75 | * 暂时注释以下部分代码,后期可能会有开学每日打卡 76 | */ 77 | // let nowHours = new Date().getHours() 78 | // if (nowHours < 10) { 79 | // i = 0, t = `晨检打卡` 80 | // } else if (nowHours < 15) { 81 | // i = 0, t = `午检打卡` 82 | // } else { 83 | // i = 0, t = `晚检打卡` 84 | // } 85 | // return {i, t} 86 | i = 0, t = `健康自测上报` 87 | return {i, t} 88 | } 89 | 90 | async function login(_username, _password) { 91 | return new Promise(resolve => { 92 | let options = { 93 | url: `https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/username?` + 94 | `username=${username}&password=${passwd}`, 95 | headers: {"Content-Type": "application/x-www-form-urlencoded"}, 96 | body: `` 97 | } 98 | $.post(options, (error, response, data) => { 99 | try { 100 | if (error) { 101 | $.log(`API请求失败, 请检查网路重试`) 102 | $.log($.toStr(error)) 103 | } else { 104 | if ($.toObj(data).code == 0) { 105 | cookie = response.headers.JWSESSION 106 | $.write(cookie, `kmust_JWSESSION`) 107 | } else { 108 | cookie = -10 109 | } 110 | } 111 | } catch (e) { 112 | $.log(`程序错误, 请检查代码`) 113 | $.log(e) 114 | } finally { 115 | resolve(cookie) 116 | } 117 | }) 118 | }) 119 | } 120 | 121 | async function index(_jwsession) { 122 | return new Promise(resolve => { 123 | let options = { 124 | url: `https://gw.wozaixiaoyuan.com/health/mobile/health/getBatch`, 125 | headers: { 126 | "Accept": "application/json, text/plain, */*", 127 | "Accept-Encoding": "gzip, deflate, br", 128 | "Accept-Language": "zh-CN,zh-Hans;q=0.9", 129 | "Content-Type": "application/json;charset=UTF-8", 130 | "Origin": "https://gw.wozaixiaoyuan.com", 131 | "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) " + 132 | "Mobile/15E148 MicroMessenger/8.0.32(0x18002030) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91", 133 | "Connection": "keep-alive", 134 | "Cookie": `JWSESSION=${_jwsession}; JWSESSION=${_jwsession}`, 135 | "JWSESSION": _jwsession 136 | } 137 | } 138 | $.log(`🧑‍💻 正在获取当天${period().t}情况`) 139 | $.post(options, (error, response, data) => { 140 | try { 141 | if (error) { 142 | $.log(`API请求失败, 请检查网路重试`) 143 | $.log($.toStr(error)) 144 | } else { 145 | $.log(`✅ 成功获取${period().t}任务`) 146 | list = $.toObj(data).data.list[period().i] 147 | } 148 | } catch (e) { 149 | $.log(`程序错误, 请检查代码`) 150 | $.log(e) 151 | } finally { 152 | resolve(list) 153 | } 154 | }) 155 | }) 156 | } 157 | 158 | async function geocoding(_address) { 159 | let location = 0 160 | return new Promise(resolve => { 161 | let options = { 162 | url: `https://apis.map.qq.com/ws/geocoder/v1/`, 163 | body: `address=${_address}&key=WOPBZ-NLJCX-NST4X-ZJHV3-7TUWH-2SBSU` 164 | } 165 | $.post(options, (error, response, data) => { 166 | try { 167 | if (error) { 168 | $.log(`API请求失败, 请检查网路重试`) 169 | $.log($.toStr(error)) 170 | } else { 171 | if (data) { 172 | data = $.toObj(data) 173 | location = data.result.location 174 | location = `${location.lat},${location.lng}` 175 | $.log(`📍 经纬度: ${location}`) 176 | } 177 | } 178 | } catch (e) { 179 | $.log(`程序错误, 请检查代码`) 180 | $.log(e) 181 | } finally { 182 | resolve(location) 183 | } 184 | }) 185 | }) 186 | } 187 | 188 | async function reverse(_location) { 189 | let address = `` 190 | return new Promise(resolve => { 191 | let options = { 192 | url: `https://apis.map.qq.com/ws/geocoder/v1/`, 193 | body: `location=${_location}&key=WOPBZ-NLJCX-NST4X-ZJHV3-7TUWH-2SBSU` 194 | } 195 | $.log(`🧑‍💻 正在通过经纬度转换出地址`) 196 | $.post(options, (error, response, data) => { 197 | try { 198 | if (error) { 199 | $.log(`API请求失败, 请检查网路重试`) 200 | $.log($.toStr(error)) 201 | } else { 202 | if (data) { 203 | $.log(`✅ 成功获取打卡封包`) 204 | data = $.toObj(data) 205 | data = { 206 | "country": data.result.address_component.nation, 207 | "province": data.result.address_component.province, 208 | "city": data.result.address_component.city, 209 | "district": data.result.address_component.district, 210 | "township": data.result.address_reference.town.title, 211 | "street": data.result.address_component.street, 212 | "nationcode": data.result.ad_info.nation_code, 213 | "areacode": data.result.ad_info.adcode, 214 | "citycode": data.result.ad_info.city_code, 215 | "towncode": data.result.address_reference.town.id, 216 | "latitude": data.result.location.lat, 217 | "longitude": data.result.location.lng 218 | } 219 | for (let key in data) address += `${data[key]}/` 220 | body = { 221 | "t1": "正常(37.3℃以下)", 222 | "t2": "否", 223 | "t3": "无下列情况,身体健康", 224 | "type": 0, 225 | "locationMode": 0, 226 | "location": address.slice(0, address.length - 1), 227 | "locationType": 0 228 | } 229 | $.write(body, `kmust_body`) 230 | } 231 | } 232 | } catch (e) { 233 | $.log(`程序错误, 请检查代码`) 234 | $.log(e) 235 | } finally { 236 | resolve(body) 237 | } 238 | }) 239 | }) 240 | } 241 | 242 | async function main(_jwsession, _batch, _body) { 243 | return new Promise(resolve => { 244 | let options = { 245 | url: `https://gw.wozaixiaoyuan.com/health/mobile/health/save?batch=${_batch}`, 246 | headers: { 247 | "Accept": "application/json, text/plain, */*", 248 | "Accept-Encoding": "gzip, deflate, br", 249 | "Accept-Language": "zh-CN,zh-Hans;q=0.9", 250 | "Content-Type": "application/json;charset=UTF-8", 251 | "Origin": "https://gw.wozaixiaoyuan.com", 252 | "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) " + 253 | "Mobile/15E148 MicroMessenger/8.0.32(0x18002030) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91", 254 | "Connection": "keep-alive", 255 | "Referer": `https://gw.wozaixiaoyuan.com/h5/mobile/health/0.3.7/health/detail?id=${_batch}`, 256 | "Cookie": `JWSESSION=${_jwsession}; JWSESSION=${_jwsession}`, 257 | "JWSESSION": _jwsession 258 | }, 259 | body: _body 260 | } 261 | $.log(`🧑‍💻 信息完成组装, 开始${period().t}`) 262 | $.post(options, (error, response, data) => { 263 | try { 264 | if (error) { 265 | $.log(`API请求失败, 请检查网路重试`) 266 | $.log($.toStr(error)) 267 | } else { 268 | data = $.toObj(data) 269 | if (data.code == 0) { 270 | $.log(`✅ ${period().t}成功`) 271 | // $.notice($.name, `✅ ${period().t}成功 ✅`, ``) 272 | } else { 273 | $.log(`❌ ${period().t}失败`) 274 | $.log($.toStr(data)) 275 | $.notice($.name, `❌ ${period().t}失败 ❌`, `📡 ${data.message}`) 276 | } 277 | } 278 | } catch (e) { 279 | $.log(`程序错误, 请检查代码`) 280 | $.log(e) 281 | } finally { 282 | resolve() 283 | } 284 | }) 285 | }) 286 | } 287 | 288 | function Env(name) { 289 | LN = typeof $loon != "undefined" 290 | SG = typeof $httpClient != "undefined" && !LN 291 | QX = typeof $task != "undefined" 292 | read = (key) => { 293 | if (LN || SG) return $persistentStore.read(key) 294 | if (QX) return $prefs.valueForKey(key) 295 | } 296 | write = (key, val) => { 297 | if (LN || SG) return $persistentStore.write(key, val); 298 | if (QX) return $prefs.setValueForKey(key, val) 299 | } 300 | notice = (title, subtitle, message, url) => { 301 | if (LN) $notification.post(title, subtitle, message, url) 302 | if (SG) $notification.post(title, subtitle, message, { url: url }) 303 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 304 | } 305 | get = (url, cb) => { 306 | if (LN || SG) {$httpClient.get(url, cb)} 307 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 308 | } 309 | post = (url, cb) => { 310 | if (LN || SG) {$httpClient.post(url, cb)} 311 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 312 | } 313 | put = (url, cb) => { 314 | if (LN || SG) {$httpClient.put(url, cb)} 315 | if (QX) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 316 | } 317 | toObj = (str) => JSON.parse(str) 318 | toStr = (obj) => JSON.stringify(obj) 319 | log = (message) => console.log(message) 320 | done = (value = {}) => {$done(value)} 321 | return { name, read, write, notice, get, post, put, toObj, toStr, log, done } 322 | } -------------------------------------------------------------------------------- /scripts/javascript/backup/ksjsb.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 使用方法:打开快手极速版APP,点击我的即可。 4 | 搭配脚本:https://raw.githubusercontent.com/leafTheFish/DeathNote/main/ksjsb.js 5 | 6 | type: http-request 7 | regex: ^https?://api\.kuaishouzt\.com/rest/zt/appsupport/reco/content/settings$ 8 | script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/ksjsb.js 9 | 10 | ###### Surge ###### 11 | [Script] 12 | 快手极速版Cookie = type=http-request, pattern=^https?://api\.kuaishouzt\.com/rest/zt/appsupport/reco/content/settings$, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/ksjsb.js 13 | 14 | [MTIM] 15 | hostname = %APPEND% api.kuaishouzt.com 16 | 17 | ###### Loon ###### 18 | [Script] 19 | http-request ^https?://api\.kuaishouzt\.com/rest/zt/appsupport/reco/content/settings$ script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/ksjsb.js, requires-body=true, timeout=120, tag=快手极速版Cookie 20 | 21 | [Mitm] 22 | hostname = api.kuaishouzt.com 23 | 24 | */ 25 | 26 | const $ = Env() 27 | const user_id = $.read("TG_USER_ID") || arg().split(`&`)[0] 28 | const bot_token = $.read("TG_BOT_TOKEN") || `5099904762:AA` + arg().split(`&`)[1] 29 | if (typeof $request !== 'undefined') {set()} 30 | 31 | 32 | function arg() { 33 | try {return $argument.match(/api=(.*)/)[1]} 34 | catch {return `none&none`} 35 | } 36 | 37 | 38 | async function set() { 39 | cookie = $request.headers.Cookie 40 | api_st = cookie.match(/(kuaishou.api_st=[^;]*)/)[1] + ";" 41 | did = cookie.match(/(did=[^;]*)/)[1] + ";" 42 | ksjsb_cookie = api_st + did 43 | if ($.read("ksjsb_cookie") != ksjsb_cookie) { 44 | if (user_id && user_id != `none` && bot_token ) { 45 | await tgNotify(`kuaishou ${ksjsb_cookie}`) 46 | } else { 47 | $.notice("快手极速版", "前往boxjs中查看!", "查询键:ksjsb_cookie", "http://boxjs.net") 48 | } 49 | $.write(ksjsb_cookie, "ksjsb_cookie") 50 | } 51 | $.done() 52 | } 53 | 54 | 55 | function tgNotify(text) { 56 | $.log(text) 57 | return new Promise((resolve) => { 58 | const options = { 59 | url: `https://api.telegram.org/bot${bot_token}/sendMessage`, 60 | headers: {'Content-Type': 'application/x-www-form-urlencoded'}, 61 | body: `chat_id=${user_id}&text=${text}&disable_web_page_preview=true`, 62 | timeout: 30000 63 | } 64 | $.post(options, (err, resp, data) => { 65 | try { 66 | if (err) { 67 | $.log('Telegram Bot发送通知调用API失败!!') 68 | $.log(err) 69 | } else { 70 | data = JSON.parse(data) 71 | if (data.ok) { 72 | $.notice("【快手极速版】", "Telegram Bot发送通知消息完成", text, "") 73 | } else { 74 | $.notice("【快手极速版】", "Telegram Bot发送通知消息失败!", "手动前往boxjs中查询!数据键:ksjsb_cookie\n或查看脚本运行日志", "") 75 | } 76 | } 77 | } catch (e) { 78 | $.log(e) 79 | $.log(resp) 80 | } finally { 81 | resolve() 82 | } 83 | }) 84 | }) 85 | } 86 | 87 | 88 | function Env() { 89 | LN = typeof $loon != "undefined" 90 | SG = typeof $httpClient != "undefined" && !LN 91 | QX = typeof $task != "undefined" 92 | read = (key) => { 93 | if (LN || SG) return $persistentStore.read(key) 94 | if (QX) return $prefs.valueForKey(key) 95 | } 96 | write = (key, val) => { 97 | if (LN || SG) return $persistentStore.write(key, val); 98 | if (QX) return $prefs.setValueForKey(key, val) 99 | } 100 | notice = (title, subtitle, message, url) => { 101 | if (LN) $notification.post(title, subtitle, message, url) 102 | if (SG) $notification.post(title, subtitle, message, { url: url }) 103 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 104 | } 105 | get = (url, cb) => { 106 | if (LN || SG) {$httpClient.get(url, cb)} 107 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 108 | } 109 | post = (url, cb) => { 110 | if (LN || SG) {$httpClient.post(url, cb)} 111 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 112 | } 113 | put = (url, cb) => { 114 | if (LN || SG) {$httpClient.put(url, cb)} 115 | if (QX) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 116 | } 117 | log = (message) => console.log(message) 118 | done = (value = {}) => {$done(value)} 119 | return { LN, SG, QX, read, write, notice, get, post, put, log, done } 120 | } 121 | -------------------------------------------------------------------------------- /scripts/javascript/backup/leave_kmmu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * hostname: xg.kmmu.edu.cn 4 | * 5 | * type: http-response 6 | * regex: ^https?://xg\.kmmu\.edu\.cn/KmmcXG/webapi/api/(Leave/AllLeaveManage(_Edit)?|Student/GetStuHomePage|Student/GetStuPersonInfo)\?LoginStatus=.* 7 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/leave_kmmu.js 8 | * 9 | * BoxJs: https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.boxjs.json 10 | * 11 | */ 12 | 13 | 14 | // 定义一个 Date 类型的格式化方法,用于将日期对象转换为指定格式的字符串 15 | Date.prototype.format = function(format) { 16 | // 定义一个对象,用于存储日期对象的各个部分 17 | var o = { 18 | "M+": this.getMonth() + 1, // 月份 19 | "d+": this.getDate(), // 日 20 | "h+": this.getHours(), // 小时 21 | "m+": this.getMinutes(), // 分钟 22 | "s+": this.getSeconds(), // 秒钟 23 | "q+": Math.floor((this.getMonth() + 3) / 3), // 季度 24 | "S": this.getMilliseconds() // 毫秒 25 | } 26 | // 将年份替换为指定格式的字符串 27 | if (/(y+)/.test(format)) format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)) 28 | // 遍历对象 o,将对象 o 中的各个部分替换为指定格式的字符串 29 | for (var k in o) if (new RegExp("(" + k + ")").test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)) 30 | // 返回指定格式的字符串 31 | return format 32 | } 33 | 34 | // 获取环境变量 35 | var $ = Env() 36 | 37 | // 获取当前时间,并将小时数减去 4,得到请假开始时间 38 | const Time = new Date() 39 | Time.setHours(Math.max(0, (Time.getHours() - 4))) 40 | const LeaveBeginTime = Time.format("hh") 41 | 42 | // 将时间加上 6 小时,得到请假结束时间 43 | Time.setHours(Math.min(23, (Time.getHours() + 6))) 44 | const LeaveEndTime = Time.format("hh") 45 | 46 | // 获取请假时间间隔和请假开始、结束日期 47 | const interval = $.read("interval") * 1 || 1 48 | const LeaveEndDate = Time.format("yyyy-MM-dd") 49 | Time.setDate(Time.getDate() - interval + 1) 50 | const LeaveBeginDate = Time.format("yyyy-MM-dd") 51 | 52 | // 计算请假天数 53 | const LeaveNumNo = ((LeaveEndTime - LeaveBeginTime) / 24 + interval - 1).toFixed(2) 54 | 55 | // 构造请假单 ID 56 | const ID = "452" + Time.getDate().toString().padStart(2, "0") 57 | 58 | // 解析响应体,并根据请求 URL 进行相应的修改 59 | var Body = $.toObj($response.body) 60 | if ($request.url.indexOf("Student/GetStu") != -1) { 61 | // 修改学生信息 62 | if ($request.url.indexOf("GetStuHomePage") != -1) { 63 | Body.UserInfo.Name = $.read("StudentName") || "" 64 | Body.UserInfo.UserId = $.read("StudentId") || "2022010001" 65 | Body.UserInfo.Photo = "" 66 | } else if ($request.url.indexOf("GetStuPersonInfo") != -1) { 67 | Body.Name = $.read("StudentName") || "" 68 | Body.CollegeName = $.read("CollegeName") || "第一临床学院" 69 | Body.StudentId = $.read("StudentId") || "2022010001" 70 | Body.Nation = "汉" 71 | Body.NativePlace = $.read("NativePlace") || "云南省昆明市盘龙区" 72 | Body.Polity = "共青团员" 73 | Body.IdCard = $.read("StudentIdCard") || "" 74 | Body.MoveTel = $.read("StudentTel") || "" 75 | Body.Photo = "" 76 | } 77 | } else { 78 | // 修改请假信息 79 | if ($.read("isLeave") != "false") { 80 | if ($request.url.indexOf("_Edit") == -1) { 81 | // 添加请假单 82 | Body.IsLeave = 1 83 | if (Body.AllLeaveManages.length > 0) { 84 | if (Body.AllLeaveManages[0].Status == "假期中") { 85 | LeaveManages = Body.AllLeaveManages[0] 86 | LeaveManages.LeaveEndTime = LeaveEndTime 87 | LeaveNumNoCache = (LeaveEndTime - LeaveManages.LeaveBeginTime * 1) / 24 88 | LeaveManages.LeaveNumNo = (LeaveNumNoCache + interval - 1).toFixed(2) 89 | } else { 90 | Body.AllLeaveManages.unshift(All()) 91 | } 92 | } else { 93 | Body.AllLeaveManages.push(All()) 94 | } 95 | } else if ($request.url.indexOf("_Edit") != -1 && Body.OverStatus == "1") { 96 | // 修改请假结束时间和返校时间 97 | Body.LeaveEndTime = LeaveEndTime 98 | Body.BackTime = LeaveEndTime 99 | } else if ($request.url.indexOf(ID) != -1) { 100 | // 获取指定 ID 的请假单 101 | Body = One() 102 | } 103 | } 104 | } 105 | 106 | // 返回修改后的响应体 107 | $.done({body: $.toStr(Body)}) 108 | 109 | // 定义一个用于构造请假单的函数 110 | function All() { 111 | return { 112 | "LeaveType": $.read("LeaveType") || "事假(含家人生病)", 113 | "WithNumNo": $.read("WithNumNo") || "0", 114 | "OutAddress": $.read("OutAddress") || "市区", 115 | "Status": "已通过", 116 | "StatusName": "辅导员审核通过", 117 | "ID": ID, 118 | "LeaveBeginDate": LeaveBeginDate, 119 | "LeaveBeginTime": LeaveBeginTime, 120 | "LeaveEndDate": LeaveEndDate, 121 | "LeaveEndTime": LeaveEndTime, 122 | "LeaveNumNo": LeaveNumNo 123 | } 124 | } 125 | 126 | // 定义一个用于获取指定 ID 的请假单的函数 127 | function One() { 128 | Note = All() 129 | Note.GoOutConfirmName = "是" 130 | Note.LeaveThing = $.read("LeaveThing") || "家中急事" 131 | Note.OutName = $.read("StudentName") || "" 132 | Note.OutMoveTel = $.read("StudentTel") || "" 133 | Note.Relation = "本人" 134 | Note.StuMoveTel = $.read("StudentTel") || "" 135 | Note.ParentContacts = $.read("ParentName") || "" 136 | Note.ParentTel = $.read("ParentTel") || "" 137 | Note.GoVehicle = $.read("Vehicle") || "汽车" 138 | Note.BackVehicle = $.read("Vehicle") || "汽车" 139 | Note.StuName = $.read("StudentName") || "" 140 | Note.GoOut = "1" 141 | Note.Inputdate = LeaveBeginDate 142 | Note.GoDate = LeaveBeginDate 143 | Note.BackDate = LeaveEndDate 144 | Note.GoTime = LeaveBeginTime 145 | Note.BackTime = LeaveEndTime 146 | return Note 147 | } 148 | 149 | // 定义一个用于获取环境变量的函数 150 | function Env() { 151 | // 判断当前运行环境,并返回相应的函数 152 | LN = typeof $loon != "undefined" 153 | SG = typeof $httpClient != "undefined" && !LN 154 | QX = typeof $task != "undefined" 155 | read = (key) => { 156 | if (LN || SG) return $persistentStore.read(key) 157 | if (QX) return $prefs.valueForKey(key) 158 | } 159 | toStr = (obj) => JSON.stringify(obj) 160 | toObj = (str) => JSON.parse(str) 161 | log = (message) => console.log(message) 162 | done = (value = {}) => {$done(value)} 163 | return { read, toStr, toObj, log, done } 164 | } 165 | -------------------------------------------------------------------------------- /scripts/javascript/backup/leave_kmu.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | [Script] 4 | # 今日校园假条(kmu.campusphere.net) 5 | 今日校园假条 = type=http-response, pattern=^https:\/\/kmu\.campusphere\.net\/wec-counselor-leave-apps\/leave\/stu\/.*, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/leave_kmu.js 6 | 7 | [Mitm] 8 | hostname = %APPEND% kmu.campusphere.net 9 | 10 | git: https://github.com/chiupam/surge/blob/main/scripts/leave_kmm.js 11 | raw: https://raw.githubusercontent.com/chiupam/surge/main/scripts/leave_kmm.js 12 | 13 | */ 14 | 15 | const $ = new Env() 16 | var Url = $request.url 17 | var Body = JSON.parse($response.body) 18 | const isLeave = $.read('isLeave') || 'true' 19 | if (isLeave == 'false') { 20 | Body = JSON.parse($response.body) 21 | } else { 22 | var newDate = new Date() 23 | var Month = newDate.getMonth() + 1 24 | var Day = newDate.getDate() 25 | var Hour = newDate.getHours() 26 | var hours = Hour + 1 27 | if (hours < 10) { 28 | hours = 8 29 | auto_end_date = Day + 1 30 | } else { 31 | if (hours >= 11) { 32 | auto_begin_hours = Hour - 3 33 | var auto_begin_hours = ('0' + auto_begin_hours).slice(-2) 34 | } 35 | auto_end_date = Day 36 | } 37 | var preset_begin_date = ('0' + Day).slice(-2) 38 | var preset_end_date = ('0' + auto_end_date).slice(-2) 39 | var current_hours = ('0' + hours).slice(-2) 40 | const leaveType = $.read('leaveType') || '其他' 41 | const leaveReason = $.read('leaveReason') || '外出购买生活用品' 42 | const destination = $.read('destination') || '' 43 | const studentInfo = $.read('studentInfo') || '' 44 | const urgencyMobile = $.read('urgencyMobile') || '' 45 | const approverName = $.read('approverName') || '' 46 | const begin_date = $.read('begin_date') || preset_begin_date 47 | const end_date = $.read('end_date') || preset_end_date 48 | const begin_hours = $.read('begin_hours') || auto_begin_hours || '08' 49 | const end_hours = $.read('end_hours') || current_hours 50 | if (parseInt(end_date) >= parseInt(begin_date)) { 51 | begin_month = Month 52 | end_month = Month 53 | if (parseInt(end_date) == parseInt(begin_date)) { 54 | between_day = parseInt(end_date) - parseInt(begin_date) 55 | between_hour = parseInt(end_hours) - parseInt(begin_hours) 56 | } else { 57 | if ( parseInt(end_hours) >= parseInt(begin_hours)) { 58 | between_day = parseInt(end_date) - parseInt(begin_date) 59 | between_hour = parseInt(end_hours) - parseInt(begin_hours) 60 | } else { 61 | between_day = parseInt(end_date) - parseInt(begin_date) - 1 62 | between_hour = parseInt(end_hours) - parseInt(begin_hours) + 24 63 | } 64 | } 65 | } else { 66 | begin_month = Month 67 | end_month = Month + 1 68 | var Year = newDate.getFullYear() 69 | between_day = parseInt(end_date) - parseInt(begin_date) + new Date(Year, Month, 0).getDate() 70 | if (parseInt(end_hours) >= parseInt(begin_hours)) { 71 | between_hour = parseInt(end_hours) - parseInt(begin_hours) 72 | } else { 73 | between_hour = parseInt(end_hours) - parseInt(begin_hours) + 24 74 | } 75 | } 76 | const BeginMonth = ('0' + begin_month).slice(-2) 77 | const EndMonth = ('0' + end_month).slice(-2) 78 | const createDate = ('0' + (parseInt(begin_date) - 1)).slice(-2) 79 | const approverDate = ('0' + (parseInt(begin_date) - 1)).slice(-2) 80 | const BeginDate = ('0' + begin_date).slice(-2) 81 | const EndDate = ('0' + end_date).slice(-2) 82 | const LeaveBeginTime = ('0' + begin_hours).slice(-2) 83 | const LeaveEndTime = ('0' + end_hours).slice(-2) 84 | const leaveTime = between_day + "天" + between_hour + "小时0分钟" 85 | const createTime = BeginMonth + "-" + createDate + " " + (begin_hours - 2).toString() + ":11" 86 | const approverTime = BeginMonth + "-" + approverDate + " " + (begin_hours - 2).toString() + ":28" 87 | const startTime = BeginMonth + "-" + BeginDate + " " + LeaveBeginTime + ":00" 88 | const endTime = EndMonth + "-" + EndDate + " " + LeaveEndTime + ":00" 89 | if (Url.indexOf('list') != -1) { 90 | Body= { 91 | "message": "success", 92 | "datas": { 93 | "rows": [{ 94 | "leaveType": leaveType, 95 | "status": "2", 96 | "createTime":createTime, 97 | "startTime": startTime, 98 | "endTime": endTime, 99 | "leaveTime": leaveTime 100 | }] 101 | }, 102 | "code": "0" 103 | } 104 | } else if (Url.indexOf('detail') != -1) { 105 | Body= { 106 | "message": "SUCCESS", 107 | "datas": { 108 | "detail": { 109 | "startTime": startTime, 110 | "approvers": [{ 111 | "status": "1", 112 | "handled": true, 113 | "approveNode": [{ 114 | "createTime": createTime, 115 | "approvers": [], 116 | "status": "1" 117 | }], 118 | "approver": {"userName": studentInfo.split(",")[0]}, 119 | "createTime": createTime 120 | },{ 121 | "status": "3", 122 | "handled": true, 123 | "approveNode": [{ 124 | "nodeType": "1", 125 | "nodeWid": "1003", 126 | "nodeName": "辅导员", 127 | "approvers": [] 128 | }], 129 | "approver": {"userName": approverName}, 130 | "level": "1", 131 | "approveOption": "同意批假,路上注意个人防护!", 132 | "createTime": approverTime 133 | }], 134 | "leaveReason": leaveReason, 135 | "urgencyMobile": urgencyMobile, 136 | "totalDays": leaveTime, 137 | "destination": destination.toString().replace(/,/g, "/"), 138 | "leaveType": leaveType, 139 | "endTime": endTime, 140 | "outStatus": true, 141 | "status": "2", 142 | "applyLocation": { 143 | "locationType": 0, 144 | "latitude": "24.982288", 145 | "longitude": "102.805404", 146 | "address": "中国云南省昆明市官渡区阿拉街道云大北路1号" 147 | }, 148 | "actStatus": "7", 149 | "disclaimers": "本人承诺填写的信息真实有效,并对本次提交请假申请的信息真实性负责。", 150 | }, 151 | "studentInfo": { 152 | "userName": studentInfo.split(",")[0], 153 | "userId": studentInfo.split(",")[1], 154 | "dept": studentInfo.split(",")[2], 155 | "grade": studentInfo.split(",")[3], 156 | "major": studentInfo.split(",")[4], 157 | "cls": studentInfo.split(",")[5] 158 | }, 159 | "recordStatus": "6", 160 | "notOutReport": { 161 | "setedNotOutReport": 1, 162 | "rule": 0, 163 | "operatorName": "李雄", 164 | "operatorDate": "2021-06-07 10:06:36" 165 | } 166 | }, 167 | "code": "0" 168 | } 169 | } else { 170 | var s = "" 171 | var qr = "" 172 | for (let i = 0; i < 9; i ++) { 173 | qr += (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) 174 | } 175 | Body = { 176 | "message": "SUCCESS", 177 | "datas": { 178 | "qr": qr, 179 | "currentTime": new Date().Format("yyyy-MM-dd hh:mm:ss") 180 | }, 181 | "code": "0" 182 | } 183 | } 184 | } 185 | $.done({body: JSON.stringify(Body)}) 186 | 187 | function Env() { 188 | // NE = typeof module && !!module.exports != "undefined" 189 | LN = typeof $loon != "undefined" 190 | SG = typeof $httpClient != "undefined" && !LN 191 | QX = typeof $task != "undefined" 192 | read = (key) => { 193 | if (LN || SG) return $persistentStore.read(key) 194 | if (QX) return $prefs.valueForKey(key) 195 | } 196 | write = (key, val) => { 197 | if (LN || SG) return $persistentStore.write(key, val); 198 | if (QX) return $prefs.setValueForKey(key, val) 199 | } 200 | notice = (title, subtitle, message, url) => { 201 | if (LN) $notification.post(title, subtitle, message, url) 202 | if (SG) $notification.post(title, subtitle, message, { url: url }) 203 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 204 | } 205 | get = (url, cb) => { 206 | if (LN || SG) {$httpClient.get(url, cb)} 207 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 208 | } 209 | post = (url, cb) => { 210 | if (LN || SG) {$httpClient.post(url, cb)} 211 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 212 | } 213 | put = (url, cb) => { 214 | if (LN || SG) {$httpClient.put(url, cb)} 215 | if (QX) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 216 | } 217 | log = (message) => console.log(message) 218 | done = (value = {}) => {$done(value)} 219 | return { LN, SG, QX, read, write, notice, get, post, put, log, done } 220 | } 221 | -------------------------------------------------------------------------------- /scripts/javascript/backup/mt.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 使用方法:打开微信,搜索美团团购小程序,进入小程序后即可。 4 | 搭配脚本:https://raw.githubusercontent.com/leafTheFish/DeathNote/main/meituan.js 5 | 6 | type: http-request 7 | regex: ^https://web\.meituan\.com/wechat/index$ 8 | script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/mt.js 9 | box: https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.boxjs.json 10 | 11 | ###### Surge ###### 12 | [Script] 13 | 美团Token = type=http-request, pattern=^https://web\.meituan\.com/wechat/index$, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/mt.js 14 | 15 | [MTIM] 16 | hostname = %APPEND% web.meituan.com 17 | 18 | ###### Loon ###### 19 | [Script] 20 | http-request ^https://web\.meituan\.com/wechat/index$ script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/mt.js, requires-body=true, timeout=120, tag=美团Token 21 | 22 | [Mitm] 23 | hostname = web.meituan.com 24 | 25 | */ 26 | 27 | const $ = Env() 28 | const user_id = $.read("TG_USER_ID") || arg().split(`&`)[0] 29 | const bot_token = $.read("TG_BOT_TOKEN") || `5099904762:AA` + arg().split(`&`)[1] 30 | if (typeof $request !== 'undefined') {set()} 31 | 32 | 33 | function arg() { 34 | try {return $argument.match(/api=(.*)/)[1]} 35 | catch {return `none&none`} 36 | } 37 | 38 | 39 | async function set() { 40 | token = $request.headers.token 41 | if ($.read("mt_token") != token) { 42 | if (user_id && user_id != `none` && bot_token ) { 43 | await tgNotify(`meituan token=${token}`) 44 | } else { 45 | $.notice("【美团】", "前往boxjs中查询!", "数据键:mt_token", "http://boxjs.net") 46 | } 47 | $.write(token, "mt_token") 48 | } 49 | $.done() 50 | } 51 | 52 | 53 | function tgNotify(text) { 54 | $.log(text) 55 | return new Promise((resolve) => { 56 | const options = { 57 | url: `https://api.telegram.org/bot${bot_token}/sendMessage`, 58 | headers: {'Content-Type': 'application/x-www-form-urlencoded'}, 59 | body: `chat_id=${user_id}&text=${text}&disable_web_page_preview=true`, 60 | timeout: 30000 61 | } 62 | $.post(options, (err, resp, data) => { 63 | try { 64 | if (err) { 65 | $.log('Telegram Bot发送通知调用API失败!!') 66 | $.log(err) 67 | } else { 68 | data = JSON.parse(data) 69 | if (data.ok) { 70 | $.notice("【美团】", "Telegram Bot发送通知消息完成", text, "") 71 | } else { 72 | $.notice("【美团】", "Telegram Bot发送通知消息失败!", "手动前往boxjs中查询!数据键:mt_token\n或查看脚本运行日志", "") 73 | } 74 | } 75 | } catch (e) { 76 | $.log(e) 77 | $.log(resp) 78 | } finally { 79 | resolve() 80 | } 81 | }) 82 | }) 83 | } 84 | 85 | 86 | function Env() { 87 | LN = typeof $loon != "undefined" 88 | SG = typeof $httpClient != "undefined" && !LN 89 | QX = typeof $task != "undefined" 90 | read = (key) => { 91 | if (LN || SG) return $persistentStore.read(key) 92 | if (QX) return $prefs.valueForKey(key) 93 | } 94 | write = (key, val) => { 95 | if (LN || SG) return $persistentStore.write(key, val); 96 | if (QX) return $prefs.setValueForKey(key, val) 97 | } 98 | notice = (title, subtitle, message, url) => { 99 | if (LN) $notification.post(title, subtitle, message, url) 100 | if (SG) $notification.post(title, subtitle, message, { url: url }) 101 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 102 | } 103 | get = (url, cb) => { 104 | if (LN || SG) {$httpClient.get(url, cb)} 105 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 106 | } 107 | post = (url, cb) => { 108 | if (LN || SG) {$httpClient.post(url, cb)} 109 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 110 | } 111 | put = (url, cb) => { 112 | if (LN || SG) {$httpClient.put(url, cb)} 113 | if (QX) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 114 | } 115 | log = (message) => console.log(message) 116 | done = (value = {}) => {$done(value)} 117 | return { LN, SG, QX, read, write, notice, get, post, put, log, done } 118 | } 119 | -------------------------------------------------------------------------------- /scripts/javascript/backup/netease.docker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 使用说明:抓包获取docker部署命令 4 | * 使用方法:打开QQ音乐APP,点击社区 5 | * 6 | * type: http-request 7 | * regex: ^https?://y\.qq\.com/v3/static/msg\.json\.z 8 | * script-paht: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/netease.docker.js 9 | * 10 | * =============== Surge =============== 11 | * 网易云节点部署命令 = type=http-request, pattern=^https?://y\.qq\.com/v3/static/msg\.json\.z, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/netease.docker.js, script-update-interval=0, timeout=10 12 | * 13 | */ 14 | 15 | const $ = Env() 16 | const user_id = $.read("TG_USER_ID") || arg().split(`&`)[0] 17 | const bot_token = $.read("TG_BOT_TOKEN") || `5099904762:AA` + arg().split(`&`)[1] 18 | const vps_ip = $.read("vps_ip") 19 | const vps_password = $.read("vps_password") 20 | if (typeof $request !== 'undefined') start() 21 | 22 | function arg() { 23 | try {return $argument.match(/api=(.*)/)[1]} 24 | catch {return `none&none`} 25 | } 26 | 27 | async function start() { 28 | cookie = $request.headers.Cookie 29 | try {qm_keyst = cookie.match(/qm_keyst=([^;]*)/)[1]} catch {qm_keyst = undefined} 30 | try {uin = cookie.match(/uin=([^;]*)/)[1]} catch {uin = undefined} 31 | if (qm_keyst && uin) { 32 | container = `docker run -dit --name netease --restart unless-stopped ` 33 | container_parameters = `-p 55555:8080 -e ENABLE_FLAC=true -e QQ_COOKIE="uin=${uin}; qm_keyst=${qm_keyst}" ` 34 | usering_images = `pan93412/unblock-netease-music-enhanced:latest ` 35 | incoming_parameters = `-o qq ` 36 | ios_parameters = `-s -e https://music.163.com` 37 | pc_command = container + container_parameters + usering_images + incoming_parameters 38 | ios_command = pc_command + ios_parameters 39 | command = `docker rm -f music netease; ${pc_command.replace(`netease`, `music`)}; ${ios_command.replace(`55555`, `55556`)}` 40 | await vps(command) 41 | } 42 | $.done() 43 | } 44 | 45 | function vps(text) { 46 | return new Promise(resolve => { 47 | const options = { 48 | url: `http://${vps_ip}/music`, 49 | body: `password=${vps_password}&command=${encodeURI(text)}` 50 | } 51 | $.post(options, (error, response, data) => { 52 | $.log(data) 53 | resolve() 54 | }) 55 | }) 56 | } 57 | 58 | function Env() { 59 | LN = typeof $loon != "undefined" 60 | SG = typeof $httpClient != "undefined" && !LN 61 | QX = typeof $task != "undefined" 62 | read = (key) => { 63 | if (LN || SG) return $persistentStore.read(key) 64 | if (QX) return $prefs.valueForKey(key) 65 | } 66 | get = (url, cb) => { 67 | if (LN || SG) {$httpClient.get(url, cb)} 68 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 69 | } 70 | post = (url, cb) => { 71 | if (LN || SG) {$httpClient.post(url, cb)} 72 | if (QX) {url.method = `POST`; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 73 | } 74 | toStr = (obj) => JSON.stringify(obj) 75 | log = (message) => console.log(message) 76 | done = (value = {}) => {$done(value)} 77 | return { read, get, post, toStr, log, done } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /scripts/javascript/backup/qndxx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 使用方法:打开云南共青团公众号,点击我的进入青年大学习,点击注册团员登录学习或进入主界面即可。 4 | * 5 | * Surge's Moudule: https://raw.githubusercontent.com/chiupam/surge/main/platforms/Surge/QNDXX.sgmodule 6 | * Loon's Plugin: https://raw.githubusercontent.com/chiupam/surge/main/platforms/Loon/qndxx.plugin 7 | * BoxJs: https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.boxjs.json 8 | * 9 | * hostname: home.yngqt.org.cn 10 | * 11 | * type: http-response 12 | * regex: ^http://home\.yngqt\.org\.cn/user/weixin_yngqt\.aspx\?getcode=.*|^https?://home\.yngqt\.org\.cn/qndxx/default\.aspx$ 13 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/qndxx.js 14 | * requires-body: 0 | false 15 | * 16 | * type: cron 17 | * cron: 13 13 13 * * * 18 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/qndxx.js 19 | * 20 | * =============== Surge =============== 21 | * 云南青年大学习Cookie = type=http-response, pattern=^http://home\.yngqt\.org\.cn/user/weixin_yngqt\.aspx\?getcode=.*|^https?://home\.yngqt\.org\.cn/qndxx/default\.aspx$, requires-body=0, timeout=5, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/qndxx.js, script-update-interval=0, timeout=5 22 | * 云南青年大学习 = type=cron, cronexp="13 13 13 * * *", wake-system=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/qndxx.js, script-update-interval=0, timeout=5 23 | * 24 | * =============== Loon =============== 25 | * http-response ^http://home\.yngqt\.org\.cn/user/weixin_yngqt\.aspx\?getcode=.*|^https?://home\.yngqt\.org\.cn/qndxx/default\.aspx$ script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/qndxx.js, requires-body=true, timeout=5, tag=云南青年大学习Cookie 26 | * cron "13 13 13 * * *" script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/qndxx.js, tag=云南青年大学习 27 | * 28 | */ 29 | 30 | const $ = new Env("👨‍🎓 云南大学习") 31 | const review = $.toObj($.read("qndxx_review")) 32 | const headers = { 33 | "Cookie": $.read("qndxx_cookie"), 34 | "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 " + 35 | "(KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.18(0x1800123f) NetType/4G Language/zh_CN" 36 | } 37 | const illustrate = `微信 => 通讯录 => 公众号 => 云南共青团 => 大学习 => 注册团员登录学习` 38 | typeof $request !== 'undefined' ? start() : main() 39 | 40 | function start() { 41 | if ($request.headers) { 42 | if ($request.url.indexOf(`weixin_yngqt`) != -1) { 43 | set_cookie = $response.headers["Set-Cookie"].match(/DianCMSUser(\S*)/)[1] 44 | set_cookie = "DianCMSUser" + set_cookie 45 | $.write(set_cookie, "qndxx_cookie") 46 | } else { 47 | set_cookie = $request.headers.Cookie 48 | $.write(set_cookie, "qndxx_cookie") 49 | } 50 | } else { 51 | $.notice($.name, ``, `⭕ 无法读取请求头,请检查配置`) 52 | } 53 | $.done() 54 | } 55 | 56 | async function main() { 57 | if ($.read("qndxx_cookie")) { 58 | if (await qiandao()) { 59 | await user() 60 | await txtid() 61 | if ($.txtid) await study($.txtid) 62 | if ($.txtid && review) await study($.txtid * 1 - 1) 63 | } else { 64 | $.notice($.name, `❌ Cookie已失效,请重新获取`, illustrate) 65 | } 66 | } else { 67 | $.notice($.name, `❌ Cookie为空,请先获取`, illustrate) 68 | } 69 | $.done() 70 | } 71 | 72 | function qiandao() { 73 | return new Promise((resolve) => { 74 | const options = { 75 | url: `http://home.yngqt.org.cn/qndxx/user/qiandao.ashx`, 76 | headers: headers, 77 | } 78 | $.log(`🧑‍💻 开始签到`) 79 | $.post(options, (error, response, data) => { 80 | if (data) { 81 | message = $.toObj(data).message 82 | if (message.indexOf(`登录`) != -1) { 83 | $.log(`❌ ${message}`) 84 | check = $.toObj(`false`) 85 | } else { 86 | $.log(`✅ ${message}`) 87 | check = $.toObj(`true`) 88 | } 89 | } else { 90 | $.log(`❌ 签到时发生错误`) 91 | $.log($.toStr(error)) 92 | } 93 | resolve(check) 94 | }) 95 | }) 96 | } 97 | 98 | function user() { 99 | return new Promise((resolve) => { 100 | const options = { 101 | url: `http://home.yngqt.org.cn/qndxx/user/`, 102 | headers: headers 103 | } 104 | $.log(`🧑‍💻 开始获取用户信息`) 105 | $.get(options, (error, response, data) => { 106 | if (data) { 107 | integral = data.match(/积分:(\d*)/)[1] 108 | $.log(`✅ 当前积分:${integral}`) 109 | } else { 110 | $.log(`❌ 访问 user 接口时发生错误`) 111 | $.log($.toStr(error)) 112 | } 113 | resolve() 114 | }) 115 | }) 116 | } 117 | 118 | function txtid() { 119 | return new Promise((resolve) => { 120 | const options = { 121 | url: `http://home.yngqt.org.cn/qndxx/default.aspx`, 122 | headers: headers 123 | } 124 | $.log(`🧑‍💻 开始获取青年大学习数据`) 125 | $.get(options, (error, response, data) => { 126 | if (data) { 127 | $.txtid = data.match(/study\((\d*)\)/)[1] * 1 128 | $.title = data.match(/习”(\S*)<\/p>

(\S*)<\/p>/) 129 | $.log(`✅ 最新一期期数:${$.title[1]}(${$.txtid})`) 130 | $.log(`✅ 最新一期名称:${$.title[2]}`) 131 | } else { 132 | $.txtid = $.toObj(`false`) 133 | $.log(`❌ 获取青年大学习时发生错误`) 134 | $.log($.toStr(error)) 135 | } 136 | resolve() 137 | }) 138 | }) 139 | } 140 | 141 | function study(id) { 142 | return new Promise((resolve) => { 143 | const options = { 144 | url: `http://home.yngqt.org.cn/qndxx/xuexi.ashx`, 145 | headers: headers, 146 | body: `{"txtid": ${id * 1}}` 147 | } 148 | $.log(`🧑‍💻 开始学习第${id}期青年大学习`) 149 | $.post(options, (error, response, data) => { 150 | if (data) { 151 | result = $.toObj(data).message 152 | $.log(`✅ ${result}`) 153 | } else { 154 | $.log(`❌ 学习第${id}期青年大学习时发生错误`) 155 | $.log($.toStr(error)) 156 | } 157 | resolve() 158 | }) 159 | }) 160 | } 161 | 162 | function Env(name) { 163 | LN = typeof $loon != "undefined" 164 | SG = typeof $httpClient != "undefined" && !LN 165 | QX = typeof $task != "undefined" 166 | read = (key) => { 167 | if (LN || SG) return $persistentStore.read(key) 168 | if (QX) return $prefs.valueForKey(key) 169 | } 170 | write = (key, val) => { 171 | if (LN || SG) return $persistentStore.write(key, val); 172 | if (QX) return $prefs.setValueForKey(key, val) 173 | } 174 | notice = (title, subtitle, message, url) => { 175 | if (LN) $notification.post(title, subtitle, message, url) 176 | if (SG) $notification.post(title, subtitle, message, { url: url }) 177 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 178 | } 179 | get = (url, cb) => { 180 | if (LN || SG) {$httpClient.get(url, cb)} 181 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 182 | } 183 | post = (url, cb) => { 184 | if (LN || SG) {$httpClient.post(url, cb)} 185 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 186 | } 187 | toObj = (str) => JSON.parse(str) 188 | toStr = (obj) => JSON.stringify(obj) 189 | log = (message) => console.log(message) 190 | done = (value = {}) => {$done(value)} 191 | return { name, read, write, notice, get, post, toObj, toStr, log, done } 192 | } 193 | -------------------------------------------------------------------------------- /scripts/javascript/backup/wskey.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 使用方法:打开某东,然后点击右上角气泡(消息)按钮,等待数秒即可。 4 | * 5 | * BoxJs: https://raw.githubusercontent.com/chiupam/surge/main/platforms/boxjs/chiupam.boxjs.json 6 | * 7 | * hostname: api-dd.jd.com 8 | * 9 | * type: http-request 10 | * regex: ^https?://api-dd\.jd\.com/client\.action\?functionId=getSessionLog 11 | * script-path: https://raw.githubusercontent.com/chiupam/scripts/master/jd/wskey.js 12 | * requires-body: 1 | true 13 | * 14 | * =============== Surge =============== 15 | * 京东获取wskey = type=http-request, pattern=^https?://api-dd\.jd\.com/client\.action\?functionId=getSessionLog, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/wskey.js, script-update-interval=0, timeout=10 16 | * 17 | * =============== Loon =============== 18 | * http-request ^https?://api-dd\.jd\.com/client\.action\?functionId=getSessionLog script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/wskey.js, requires-body=true, timeout=10, tag=京东获取wskey 19 | * 20 | * =============== Quan X =============== 21 | * ^https?://api-dd\.jd\.com/client\.action\?functionId=getSessionLog url script-request-header https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/wskey.js 22 | * 23 | */ 24 | 25 | const $ = Env() 26 | const user_id = $.read("TG_USER_ID") || arg().split(`&`)[0] 27 | const bot_token = $.read("TG_BOT_TOKEN") || `5099904762:AA` + arg().split(`&`)[1] 28 | if (typeof $request !== 'undefined') start() 29 | 30 | function arg() { 31 | try {return $argument.match(/api=(.*)/)[1]} 32 | catch {return `none&none`} 33 | } 34 | 35 | async function start() { 36 | if (!$.read("jd_time")) $.write((Date.parse(new Date())/1000 - 20).toString(), 'jd_time') 37 | if (Date.parse(new Date())/1000 - ($.read("jd_time") * 1) > 15) { 38 | cookie = $request.headers.Cookie 39 | pin = "pin=" + encodeURIComponent(cookie.match(/(pin=[^;]*)/)[1].replace("pin=", "")) + ";" 40 | jd_wskey = pin + cookie.match(/(wskey=[^;]*)/)[1] + ";" 41 | $.write((Date.parse(new Date())/1000).toString(), 'jd_time') 42 | if (user_id && user_id != `none` && bot_token) { 43 | await tgNotify(jd_wskey) 44 | $.write("undefined", "jd_wskey") 45 | } else { 46 | $.notice("【京东】", "前往boxjs中查询,或查看脚本运行日志!", `数据键:jd_wskey\n` + jd_wskey, "http://boxjs.net") 47 | $.write(jd_wskey, "jd_wskey") 48 | } 49 | } 50 | $.done() 51 | } 52 | 53 | function tgNotify(text) { 54 | $.log(text) 55 | return new Promise((resolve) => { 56 | const options = { 57 | url: `https://api.telegram.org/bot${bot_token}/sendMessage`, 58 | headers: {'Content-Type': 'application/x-www-form-urlencoded'}, 59 | body: `chat_id=${user_id}&text=${text}&disable_web_page_preview=true`, 60 | timeout: 30000 61 | } 62 | $.post(options, (err, resp, data) => { 63 | try { 64 | if (err) { 65 | $.log('Telegram Bot发送通知调用API失败!!') 66 | $.log(err) 67 | } else { 68 | data = JSON.parse(data) 69 | if (data.ok) { 70 | $.notice("【京东】", "Telegram Bot发送通知消息完成", jd_wskey, "") 71 | } else { 72 | $.notice("【京东】", "Telegram Bot发送通知消息失败!", "前往boxjs中查询,或查看脚本运行日志!\n数据键:jd_wskey", "http://boxjs.net") 73 | } 74 | } 75 | } catch (e) { 76 | $.log(e) 77 | $.log(resp) 78 | } finally { 79 | resolve() 80 | } 81 | }) 82 | }) 83 | } 84 | 85 | 86 | function Env() { 87 | LN = typeof $loon != "undefined" 88 | SG = typeof $httpClient != "undefined" && !LN 89 | QX = typeof $task != "undefined" 90 | read = (key) => { 91 | if (LN || SG) return $persistentStore.read(key) 92 | if (QX) return $prefs.valueForKey(key) 93 | } 94 | write = (key, val) => { 95 | if (LN || SG) return $persistentStore.write(key, val); 96 | if (QX) return $prefs.setValueForKey(key, val) 97 | } 98 | notice = (title, subtitle, message, url) => { 99 | if (LN) $notification.post(title, subtitle, message, url) 100 | if (SG) $notification.post(title, subtitle, message, { url: url }) 101 | if (QX) $notify(title, subtitle, message, { "open-url": url }) 102 | } 103 | get = (url, cb) => { 104 | if (LN || SG) {$httpClient.get(url, cb)} 105 | if (QX) {url.method = 'GET'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 106 | } 107 | post = (url, cb) => { 108 | if (LN || SG) {$httpClient.post(url, cb)} 109 | if (QX) {url.method = 'POST'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 110 | } 111 | put = (url, cb) => { 112 | if (LN || SG) {$httpClient.put(url, cb)} 113 | if (QX) {url.method = 'PUT'; $task.fetch(url).then((resp) => cb(null, {}, resp.body))} 114 | } 115 | log = (message) => console.log(message) 116 | done = (value = {}) => {$done(value)} 117 | return { LN, SG, QX, read, write, notice, get, post, put, log, done } 118 | } 119 | -------------------------------------------------------------------------------- /scripts/javascript/backup/xmSport.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 未完成,请勿使用! 3 | */ 4 | 5 | const $ = new Env('小米运动') 6 | const step = randomFriendPin($.getdata('xmMinStep') * 1, $.getdata('xmMaxStep') * 1) 7 | typeof $request != "undefined" ? set() : main() 8 | 9 | function set() { 10 | if ($response.body) { 11 | const body = JSON.parse($response.body) 12 | const loginToken = body.token_info.login_token 13 | $.setdata(loginToken, 'xmSportsToken') 14 | $.msg($.name, "", "【成功】写入 Token 成功!🎉") 15 | } else { 16 | $.msg($.name, "", "【失败】无法读取 response 啊,自查原因!🤦‍♂️") 17 | } 18 | $.done({}) 19 | } 20 | 21 | async function main() { 22 | login_token = $.getdata('xmSportsToken') 23 | if (login_token) { 24 | await get_dataJSON() 25 | await get_app_token(login_token) 26 | if ($.tokenInfo && $.tokenInfo.result === 'ok') { 27 | const {app_token, user_id} = $.tokenInfo.token_info 28 | await get_time() 29 | await change_step(app_token, user_id) 30 | if ($.changeStepRes && $.changeStepRes.code === 1) { 31 | $.log(`步数修改成功:${step}步`) 32 | $.msg($.name, `${step}步🏃修改成功`, `时间:${timeFormat(localtime())}‍`) 33 | } else { 34 | $.log(`修改运动步数失败`) 35 | } 36 | } else { 37 | $.msg($.name, '', "【失败】小米运动Token已失效,请重新登录获取!") 38 | } 39 | } else { 40 | $.msg($.name, '', "【失败】暂无小米运动Token,请登录获取!") 41 | $.log("【失败】暂无小米运动Token,请登录获取!") 42 | } 43 | $.done() 44 | } 45 | 46 | function get_dataJSON() { 47 | return new Promise(resolve => { 48 | $.get({ 49 | url: `https://raw.githubusercontent.com/chiupam/surge/main/scripts/xmSport.json`, 50 | headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44'} 51 | }, (err, resp, data) => { 52 | try { 53 | if (err) { 54 | $.log(JSON.stringify(err)) 55 | } else { 56 | if (data) { 57 | $.xmsportdata = JSON.parse(data).data 58 | } 59 | } 60 | } catch (e) { 61 | $.logErr(e, resp) 62 | } finally { 63 | resolve() 64 | } 65 | }) 66 | }) 67 | } 68 | 69 | async function change_step(app_token, user_id) { 70 | const date = $.xmsportdata.match(/.*?date%22%3A%22(.*?)%22%2C%22data.*?/)[1] 71 | const ttf = $.xmsportdata.match(/.*?ttl%5C%22%3A(.*?)%2C%5C%22dis.*?/)[1] 72 | dataJSON = $.xmsportdata.replace(date, timeFormat(localtime())) 73 | dataJSON = $.xmsportdata.replace(ttf, step.toString()) 74 | return new Promise(resolve => { 75 | const options = { 76 | "url": `https://api-mifit-cn.huami.com/v1/data/band_data.json?&t=${$.t}`, 77 | "body": `userid=${user_id.toString()}&last_sync_data_time=1597306380&device_type=0&last_deviceid=DA932FFFFE8816E7&data_json=${dataJSON}`, 78 | "headers": {"Content-Type": "application/x-www-form-urlencoded", "apptoken": app_token} 79 | } 80 | $.post(options, (err, resp, data) => { 81 | try { 82 | if (err) { 83 | $.log(JSON.stringify(err)) 84 | } else { 85 | $.log(`修改步数结果:${data}`) 86 | $.changeStepRes = JSON.parse(data) 87 | } 88 | } catch (e) { 89 | $.logErr(e, resp) 90 | } finally { 91 | resolve() 92 | } 93 | }) 94 | }) 95 | } 96 | 97 | function get_app_token(login_token) { 98 | return new Promise(resolve => { 99 | $.get({ 100 | url: `https://account-cn.huami.com/v1/client/app_tokens?app_name=com.xiaomi.hm.health&dn=api-user.huami.com%2Capi-mifit.huami.com%2Capp-analytics.huami.com&login_token=${login_token}`, 101 | headers: {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 9; MI 6 MIUI/20.6.18)'} 102 | }, (err, resp, data) => { 103 | try { 104 | if (err) { 105 | $.log(JSON.stringify(err)) 106 | } else { 107 | if (data) { 108 | $.tokenInfo = JSON.parse(data) 109 | } 110 | } 111 | } catch (e) { 112 | $.logErr(e, resp) 113 | } finally { 114 | resolve() 115 | } 116 | }) 117 | }) 118 | } 119 | 120 | function get_time() { 121 | return new Promise(resolve => { 122 | $.get({url: "http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp"}, (err, resp, data) => { 123 | try { 124 | if (err) { 125 | $.log(JSON.stringify(err)) 126 | } else { 127 | if (data) { 128 | $.t = JSON.parse(data).data.t 129 | } 130 | } 131 | } catch (e) { 132 | $.logErr(e, resp) 133 | } finally { 134 | resolve(data) 135 | } 136 | }) 137 | }) 138 | } 139 | 140 | function localtime() {return new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000} 141 | 142 | function timeFormat(time) { 143 | let date 144 | if (time) {date = new Date(time)} else {date = new Date()} 145 | return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()) 146 | } 147 | 148 | function randomFriendPin(m,n) { 149 | return Math.round(Math.random()*(n - m) + m) 150 | } 151 | 152 | // prettier-ignore 153 | function Env(t,e){"undefined"!=typeof process&&JSON.stringify(process.env).indexOf("GITHUB")>-1&&process.exit(0);class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`🔔${this.name}, 开始!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 154 | -------------------------------------------------------------------------------- /scripts/javascript/backup/zsfc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 使用方法:打开掌上飞车APP, 点击下方发现, 点击每日签到, 点击签到即可。 4 | * 5 | * hostname: mwegame.qq.com 6 | * 7 | * type: http-request 8 | * regex: ^https://mwegame\.qq\.com/ams/sign/doSign/month 9 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js 10 | * requests-body: 1 11 | * 12 | * type: cron 13 | * cron: 0 10 0 * * * 14 | * script-path: https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js 15 | * 16 | * =============== Surge =============== 17 | * 掌上飞车Cookie = type=http-request, pattern=^https://mwegame\.qq\.com/ams/sign/doSign/month, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js, script-update-interval=0, timeout=5 18 | * 掌上飞车 =type=cron, cronexp="0 10 0 * * *", wake-system=1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js, script-update-interval=0, timeout=5 19 | * 20 | * =============== Loon =============== 21 | * http-request ^https://mwegame\.qq\.com/ams/sign/doSign/month script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js, requires-body=true, timeout=10, tag=掌上飞车Cookie 22 | * cron "0 10 0 * * *" script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js, tag=掌上飞车 23 | * 24 | * =============== Quan X =============== 25 | * ^https://mwegame\.qq\.com/ams/sign/doSign/month url script-request-body https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js 26 | * 0 10 0 * * * https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/zsfc.js, tag=掌上飞车, enabled=true 27 | * 28 | */ 29 | 30 | /** 31 | * 创建一个名为 $ 的环境变量实例,用于处理掌上飞车相关操作 32 | */ 33 | const $ = new Env(`🏎️ 掌上飞车`) 34 | 35 | /** 36 | * 检查是否为请求阶段 37 | */ 38 | const isreq = typeof $request !== 'undefined'; 39 | 40 | /** 41 | * 主函数,用于执行打卡操作或设置请求数据 42 | */ 43 | (async () => { 44 | if (isreq) { 45 | // 请求阶段,设置请求数据 46 | if (!$request.url || !$request.headers) { 47 | // 无法读取请求头,显示配置错误通知 48 | $.notice($.name, '', '⭕ 无法读取请求头, 请检查配置'); 49 | return; 50 | } 51 | 52 | // 提取请求数据 53 | const url = $request.url.replace(/&gift_id=\d+/, ''); 54 | const headers = $.toStr($request.headers); 55 | const query = [ 56 | `userId=${matchParam(url, 'userId')}`, 57 | `areaId=${matchParam(url, 'areaId')}`, 58 | `roleId=${matchParam(url, 'roleId')}`, 59 | `token=${matchParam(url, 'token')}`, 60 | `uin=${matchParam(url, 'uin')}`, 61 | ].join('&'); 62 | 63 | // 将请求数据写入内存 64 | $.write(url, 'zsfc_url'); 65 | $.write(headers, 'zsfc_headers'); 66 | $.write(query, 'zsfc_query'); 67 | 68 | $.notice($.name, '✅ 获取签到数据成功!', '请不要再次打开掌上飞车APP, 否则 Cookie 将失效!'); 69 | } else { 70 | // 执行打卡操作阶段 71 | const url = $.read('zsfc_url'); 72 | const query = $.read('zsfc_query'); 73 | const illustrate = `掌上飞车APP => 发现 => 每日签到 => 点击签到`; 74 | 75 | if (!url) { 76 | // Cookie 为空,显示获取Cookie错误通知 77 | $.notice($.name, '❌ 当前 Cookie 为空, 请先获取', illustrate); 78 | return; 79 | } 80 | 81 | if (query.indexOf('&areaId=&') !== -1) { 82 | // Cookie 错误,显示重新获取Cookie错误通知 83 | $.notice($.name, '❌ 当前 Cookie 错误, 请重新获取', illustrate); 84 | return; 85 | } 86 | 87 | // 获取连续签到的礼物ID 88 | const successiveGiftId = await getSuccessiveGiftId(); 89 | // 进行连续签到 90 | const isSuccessiveCheckin = await dailyCheckin(successiveGiftId); 91 | 92 | if (!isSuccessiveCheckin) { 93 | // Cookie 失效,显示重新获取Cookie错误通知 94 | $.notice($.name, '❌ 当前 Cookie 已失效, 请重新获取', illustrate); 95 | return; 96 | } 97 | 98 | // 获取签到信息数组 99 | signInInfoArray = await getSignInInfo(); 100 | if (signInInfoArray.length) { 101 | $.log(`🎉 共有 ${signInInfoArray.length} 个礼包待领取`) 102 | } 103 | 104 | // 遍历签到信息数组,领取每日礼物 105 | for (let signInInfo of signInInfoArray) { 106 | let { code, title } = signInInfo; 107 | await claimGift(code, title); 108 | } 109 | 110 | // 显示签到结果通知 111 | $.notice($.name, $.subtitle, $.message, ``) 112 | 113 | } 114 | })() 115 | .catch((e) => $.notice($.name, '❌ 未知错误无法打卡', e, '')) 116 | .finally(() => $.done()); 117 | 118 | /** 119 | * 匹配 URL 参数 120 | * @param {string} url - URL 字符串 121 | * @param {string} key - 参数名 122 | * @returns {string} 123 | */ 124 | function matchParam(url, key) { 125 | const match = url.match(new RegExp(`${key}=([^&]+)`)); 126 | return match ? match[1] : ''; 127 | } 128 | 129 | /** 130 | * 获取连续签到的礼物 ID 131 | * @returns {Promise} 返回连续签到的礼物 ID 132 | */ 133 | async function getSuccessiveGiftId() { 134 | // 用于保存连续签到的礼物 ID 135 | let giftid; 136 | 137 | // 构造请求参数 138 | const options = { 139 | url: `https://mwegame.qq.com/ams/sign/month/speed?${$.read(`zsfc_query`)}`, 140 | headers: $.toObj($.read(`zsfc_headers`)) 141 | }; 142 | 143 | // 发送 GET 请求,获取签到页面信息 144 | return new Promise(resolve => { 145 | $.get(options, (err, resp, data) => { 146 | if (data) { 147 | // 解析响应数据,提取礼物 ID 148 | giftid = data.match(/giftid="([^"]+)"/g)[0].match(/(\d+)/)[1]; 149 | } 150 | resolve(giftid); 151 | }); 152 | }); 153 | } 154 | 155 | /** 156 | * 每日签到函数 157 | * @param {string} giftId 礼物 ID 158 | * @returns {Promise} 返回签到结果,true 表示签到成功,false 表示签到失败 159 | */ 160 | async function dailyCheckin(giftId) { 161 | // 初始化签到结果为 false 162 | let result = false; 163 | 164 | // 构造请求参数 165 | const options = { 166 | url: `${$.read("zsfc_url")}&gift_id=${giftId}`, 167 | headers: $.toObj($.read(`zsfc_headers`)) 168 | }; 169 | 170 | // 输出日志,开始每日签到 171 | $.log(`🧑‍💻 开始每日签到`); 172 | 173 | // 发送 GET 请求,进行签到 174 | return new Promise(resolve => { 175 | $.get(options, (err, resp, data) => { 176 | if (data) { 177 | // 解析响应数据 178 | let body = $.toObj(data.replace(/\r|\n/ig, ``)); 179 | let message = body.message; 180 | 181 | if (message.indexOf(`重试`) > -1) { 182 | // Cookie 失效,签到失败 183 | $.log(`❌ 当前 Cookie 已失效, 请重新获取`); 184 | $.message = ``; 185 | } else if (message.indexOf(`已经`) > -1) { 186 | // Cookie 有效,再次签到 187 | result = true; 188 | $.log(`⭕ 签到结果: ${message}`); 189 | $.message = `签到结果: ${message}`; 190 | } else { 191 | // Cookie 有效,签到成功 192 | result = true; 193 | $.log(`✅ ${body.send_result.sMsg.replace(":", ":")}`); 194 | $.message = body.send_result.sMsg.replace(":", ":"); 195 | } 196 | } else { 197 | // 发生错误,签到失败 198 | $.log(`❌ 进行每日签到时发生错误`); 199 | $.log($.toStr(err)); 200 | } 201 | resolve(result); 202 | }); 203 | }); 204 | } 205 | 206 | /** 207 | * @description 获取签到信息,并返回签到礼物列表 208 | * @returns {Promise} 一个返回包含签到礼物的数组的 Promise。 209 | */ 210 | async function getSignInInfo() { 211 | // 获取当前时间 212 | const date = new Date(); 213 | 214 | // 设置请求参数 215 | const options = { 216 | url: `https://mwegame.qq.com/ams/sign/month/speed?${$.read(`zsfc_query`)}`, 217 | headers: $.toObj($.read(`zsfc_headers`)) 218 | } 219 | 220 | // 输出日志,开始获取累计签到天数 221 | $.log(`🧑‍💻 开始获取累计签到天数`); 222 | 223 | // 初始化 signInGifts 为空列表 224 | let signInGifts = []; 225 | 226 | // 发送 GET 请求,获取签到信息 227 | return new Promise(resolve => { 228 | $.get(options, (err, resp, data) => { 229 | if (data) { 230 | // 定义一个数组,用于将累计签到天数映射到礼物编号 231 | const giftIndexByDay = [ 232 | 0, // 占位,第一个元素不是第一天 233 | 1, 2, 3, 0, 4, 0, 5, 0, 6, 7, 234 | 8, 0, 9, 0, 10, 11, 0, 12, 13, 0, 235 | 14, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0 236 | ]; 237 | 238 | // 使用正则表达式获取累计签到天数 239 | const totalSignInDays = Number(data.match(/(\d+)<\/span>/)?.[1]); 240 | const missedDays = new Date().getDate() - totalSignInDays; 241 | const missedDaysText = missedDays !== 0 ? `(漏签 ${missedDays} 天)` : ``; 242 | $.subtitle = `✅ 累计签到 ${totalSignInDays} 天${missedDaysText}`; 243 | $.log($.subtitle); 244 | 245 | // 根据累计签到天数获取礼物编号,并将其添加到 signInGifts 中 246 | const giftIndex = giftIndexByDay[totalSignInDays]; 247 | const giftCode = giftIndex ? data.match(/giftid="([^"]+)"/g)[giftIndex].match(/(\d+)/)[1] : null; 248 | if (giftIndex && giftCode) signInGifts.push({ code: giftCode, title: `第 ${giftIndexByDay.indexOf(giftIndex)} 天奖励` }); 249 | 250 | // 获取当前日期的日数,并检查是否为每月的第 X 天,如果是则将礼物编号添加到 signInGifts 中 251 | const [matchMonthDay] = data.match(/月(\d+)日/g) || []; 252 | const [, day] = matchMonthDay?.match(/(\d+)/) || []; 253 | if (day && Number(day) === date.getDate()) { 254 | const giftDays = data.match(/"giftdays([^"]+)"/g)[0].match(/(\d+)/)[1]; 255 | const dayWelfare = `${date.getMonth() + 1}月${date.getDate()}日`; 256 | signInGifts.push({ code: giftDays, title: ` ${dayWelfare} 特别福利` }); 257 | } 258 | 259 | } else { 260 | // 发生错误,输出错误日志 261 | $.log(`❌ 获取累计签到天数时发生错误`); 262 | $.log($.toStr(err)); 263 | } 264 | // 将 signInGifts 作为 Promise 的返回值,以便在调用方使用 265 | resolve(signInGifts); 266 | }); 267 | }); 268 | } 269 | 270 | /** 271 | * 领取礼物函数 272 | * @param {string} giftId 礼物 ID 273 | * @param {string} giftName 礼物名称 274 | */ 275 | async function claimGift(giftId, giftName) { 276 | // 设置请求参数 277 | const options = { 278 | url: `https://mwegame.qq.com/ams/send/handle`, 279 | headers: $.toObj($.read(`zsfc_headers`)), 280 | body: `${$.read(`zsfc_query`)}&gift_id=${giftId}` 281 | }; 282 | 283 | // 输出日志,开始领取礼物 284 | $.log(`🧑‍💻 开始领取${giftName}`); 285 | 286 | // 发送 POST 请求,领取礼物 287 | return new Promise(resolve => { 288 | $.post(options, (err, resp, data) => { 289 | if (data) { 290 | let result = $.toObj(data.replace(/\r|\n/ig, ``)); 291 | if (result.data.indexOf(`成功`) != -1) { 292 | // 领取成功,获取礼物名称并记录日志 293 | const sPackageName = result.send_result.sPackageName; 294 | $.log(`✅ 领取结果: 获得${sPackageName}`); 295 | $.message += `, ${sPackageName}`; 296 | } else { 297 | // 领取失败,记录错误信息日志 298 | $.log(`⭕ 领取结果: ${result.message}`); 299 | } 300 | } else { 301 | // 发生错误,输出错误日志 302 | $.log(`❌ 开始领取${giftName}时发生错误`); 303 | $.log($.toStr(err)); 304 | } 305 | resolve(); 306 | }); 307 | }) 308 | } 309 | 310 | /** 311 | * 创建一个名为 Env 的构造函数,用于处理环境相关操作。 312 | * @param {string} name - 环境名称 313 | */ 314 | function Env(name) { 315 | // 判断当前环境是否为 Loon 316 | const isLoon = typeof $loon !== "undefined"; 317 | // 判断当前环境是否为 Surge 318 | const isSurge = typeof $httpClient !== "undefined" && !isLoon; 319 | // 判断当前环境是否为 QuantumultX 320 | const isQX = typeof $task !== "undefined"; 321 | 322 | // 定义 read 方法,用于读取数据 323 | const read = (key) => { 324 | if (isLoon || isSurge) return $persistentStore.read(key); 325 | if (isQX) return $prefs.valueForKey(key); 326 | }; 327 | 328 | // 定义 write 方法,用于写入数据 329 | const write = (key, value) => { 330 | if (isLoon || isSurge) return $persistentStore.write(key, value); 331 | if (isQX) return $prefs.setValueForKey(key, value); 332 | }; 333 | 334 | // 定义 notice 方法,用于发送通知 335 | const notice = (title, subtitle, message, url) => { 336 | if (isLoon) $notification.post(title, subtitle, message, url); 337 | if (isSurge) $notification.post(title, subtitle, message, { url }); 338 | if (isQX) $notify(title, subtitle, message, { "open-url": url }); 339 | }; 340 | 341 | // 定义 get 方法,用于发送 GET 请求 342 | const get = (url, callback) => { 343 | if (isLoon || isSurge) $httpClient.get(url, callback); 344 | if (isQX) {url.method = `GET`; $task.fetch(url).then((resp) => callback(null, {}, resp.body))}; 345 | }; 346 | 347 | // 定义 post 方法,用于发送 POST 请求 348 | const post = (url, callback) => { 349 | if (isLoon || isSurge) $httpClient.post(url, callback); 350 | if (isQX) {url.method = `POST`; $task.fetch(url).then((resp) => callback(null, {}, resp.body))}; 351 | }; 352 | 353 | // 定义 put 方法,用于发送 PUT 请求 354 | const put = (url, callback) => { 355 | if (isLoon || isSurge) $httpClient.put(url, callback) 356 | if (isQX) {url.method = 'PUT'; $task.fetch(url).then((resp) => callback(null, {}, resp.body))}; 357 | }; 358 | 359 | // 定义 toObj 方法,用于将字符串转为对象 360 | const toObj = (str) => JSON.parse(str); 361 | 362 | // 定义 toStr 方法,用于将对象转为字符串 363 | const toStr = (obj) => JSON.stringify(obj); 364 | 365 | // 定义 log 方法,用于输出日志 366 | const log = (message) => console.log(message); 367 | 368 | // 定义 done 方法,用于结束任务 369 | const done = (value = {}) => $done(value); 370 | 371 | // 返回包含所有方法的对象 372 | return { name, read, write, notice, get, post, put, toObj, toStr, log, done }; 373 | } -------------------------------------------------------------------------------- /scripts/javascript/panel/network_info.js: -------------------------------------------------------------------------------- 1 | /** 2 | * form: https://raw.githubusercontent.com/Rabbit-Spec/Surge/Master/Panel/Network-Info/Network-Info.js 3 | */ 4 | 5 | class httpMethod { 6 | /** 7 | * 回调函数 8 | * @param {*} resolve 9 | * @param {*} reject 10 | * @param {*} error 11 | * @param {*} response 12 | * @param {*} data 13 | */ 14 | static _httpRequestCallback(resolve, reject, error, response, data) { 15 | if (error) { 16 | reject(error); 17 | } else { 18 | resolve(Object.assign(response, { data })); 19 | } 20 | } 21 | 22 | /** 23 | * HTTP GET 24 | * @param {Object} option 选项 25 | * @returns 26 | */ 27 | static get(option = {}) { 28 | return new Promise((resolve, reject) => { 29 | $httpClient.get(option, (error, response, data) => { 30 | this._httpRequestCallback(resolve, reject, error, response, data); 31 | }); 32 | }); 33 | } 34 | 35 | /** 36 | * HTTP POST 37 | * @param {Object} option 选项 38 | * @returns 39 | */ 40 | static post(option = {}) { 41 | return new Promise((resolve, reject) => { 42 | $httpClient.post(option, (error, response, data) => { 43 | this._httpRequestCallback(resolve, reject, error, response, data); 44 | }); 45 | }); 46 | } 47 | } 48 | 49 | class logger { 50 | static id = randomString(); 51 | 52 | static log(message) { 53 | message = `[${this.id}] [ LOG ] ${message}`; 54 | // console.log(message); // 无谓的log 55 | } 56 | 57 | static error(message) { 58 | message = `[${this.id}] [ERROR] ${message}`; 59 | console.log(message); 60 | } 61 | } 62 | 63 | function randomString(e = 6) { 64 | var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678", 65 | a = t.length, 66 | n = ""; 67 | for (i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a)); 68 | return n; 69 | } 70 | 71 | function getFlagEmoji(countryCode) { 72 | const codePoints = countryCode 73 | .toUpperCase() 74 | .split('') 75 | .map((char) => 127397 + char.charCodeAt()); 76 | return String.fromCodePoint(...codePoints); 77 | } 78 | 79 | function loadCarrierNames() { 80 | //整理逻辑:前三码相同->后两码相同运营商->剩下的 81 | return { 82 | //台湾运营商 Taiwan 83 | '466-11': '中華電信', '466-92': '中華電信', 84 | '466-01': '遠傳電信', '466-03': '遠傳電信', 85 | '466-97': '台灣大哥大', '466-89': '台灣之星', '466-05': 'GT', 86 | //大陆运营商 China 87 | '460-03': '中国电信', '460-05': '中国电信', '460-11': '中国电信', 88 | '460-01': '中国联通', '460-06': '中国联通', '460-09': '中国联通', 89 | '460-00': '中国移动', '460-02': '中国移动', '460-04': '中国移动', '460-07': '中国移动', '460-08': '中国移动', 90 | '460-15': '中国广电', '460-20': '中移铁通', 91 | //香港运营商 HongKong 92 | '454-00': 'CSL', '454-02': 'CSL', '454-10': 'CSL', '454-18': 'CSL', 93 | '454-03': '3', '454-04': '3', '454-05': '3', 94 | '454-06': 'SMC HK', '454-15': 'SMC HK', '454-17': 'SMC HK', 95 | '454-09': 'CMHK', '454-12': 'CMHK', '454-13': 'CMHK', '454-28': 'CMHK', '454-31': 'CMHK', 96 | '454-16': 'csl.', '454-19': 'csl.', '454-20': 'csl.', '454-29': 'csl.', 97 | '454-01': '中信國際電訊', '454-07': 'UNICOM HK', '454-08': 'Truphone', '454-11': 'CHKTL', '454-23': 'Lycamobile', 98 | }; 99 | } 100 | 101 | //获取手机运营商信息(通过内置的 API 调用设备信息) 102 | function getCellularInfo() { 103 | const radioGeneration = { 104 | 'GPRS': '2.5G', 105 | 'CDMA1x': '2.5G', 106 | 'EDGE': '2.75G', 107 | 'WCDMA': '3G', 108 | 'HSDPA': '3.5G', 109 | 'CDMAEVDORev0': '3.5G', 110 | 'CDMAEVDORevA': '3.5G', 111 | 'CDMAEVDORevB': '3.75G', 112 | 'HSUPA': '3.75G', 113 | 'eHRPD': '3.9G', 114 | 'LTE': '4G', 115 | 'NRNSA': '5G', 116 | 'NR': '5G', 117 | }; 118 | 119 | let cellularInfo = ''; 120 | const carrierNames = loadCarrierNames(); 121 | if ($network['cellular-data']) { 122 | const carrierId = $network['cellular-data'].carrier; 123 | const radio = $network['cellular-data'].radio; 124 | if (carrierId && radio) { 125 | cellularInfo = carrierNames[carrierId] ? 126 | carrierNames[carrierId] + ' | ' + radioGeneration[radio] + ' - ' + radio : 127 | '蜂窝数据 | ' + radioGeneration[radio] + ' - ' + radio; 128 | } 129 | } 130 | return cellularInfo; 131 | } 132 | 133 | function getSSID() { 134 | return $network.wifi?.ssid; 135 | } 136 | 137 | function getIP() { 138 | const { v4 } = $network; 139 | let info = []; 140 | if (!v4) { 141 | info = ['网路可能中断', '请手动刷新以重新获取 IP']; 142 | } else { 143 | if (v4?.primaryRouter && getSSID()) info.push(`网关IP:${v4?.primaryRouter}`); 144 | if (v4?.primaryAddress) info.push(`设备IP:${v4?.primaryAddress}`); 145 | } 146 | info = info.join("\n"); 147 | return info + "\n"; 148 | } 149 | 150 | /** 151 | * 获取 IP 信息 152 | * @param {*} retryTimes // 重试次数 153 | * @param {*} retryInterval // 重试间隔 ms 154 | */ 155 | function getNetworkInfo(retryTimes = 5, retryInterval = 1000) { 156 | // 发送网络请求 157 | httpMethod.get('http://ip-api.com/json/?lang=zh-CN').then(response => { 158 | if (Number(response.status) > 300) { 159 | throw new Error(`Request error with http status code: ${response.status}\n${response.data}`); 160 | } 161 | const info = JSON.parse(response.data); 162 | $done({ 163 | title: getSSID() ?? getCellularInfo(), 164 | content: 165 | getIP() + 166 | `节点IP:${info.query}\n` + 167 | `节点ISP:${info.isp}\n` + 168 | `节点位置:${getFlagEmoji(info.countryCode)} ${info.country} - ${info.city}`, 169 | icon: getSSID() ? 'wifi' : 'simcard', 170 | 'icon-color': getSSID() ? '#5A9AF9' : '#8AB8DD', 171 | }); 172 | }).catch(error => { 173 | // 网络切换 174 | if (String(error).startsWith("Network changed")) { 175 | if (getSSID()) { 176 | $network.wifi = undefined; 177 | $network.v4 = undefined; 178 | } 179 | } 180 | // 判断是否还有重试机会 181 | if (retryTimes > 0) { 182 | logger.error(error); 183 | logger.log(`Retry after ${retryInterval}ms`); 184 | // retryInterval 时间后再次执行该函数 185 | setTimeout(() => getNetworkInfo(--retryTimes, retryInterval), retryInterval); 186 | } else { 187 | // 打印日志 188 | logger.error(error); 189 | $done({ 190 | title: '发生错误', 191 | content: '无法获取当前网络信息\n请检查网络状态后重试', 192 | icon: 'wifi.exclamationmark', 193 | 'icon-color': '#CB1B45', 194 | }); 195 | } 196 | }); 197 | } 198 | 199 | /** 200 | * 主要逻辑,程序入口 201 | */ 202 | (() => { 203 | const retryTimes = 5; 204 | const retryInterval = 1000; 205 | // Surge 脚本超时时间设置为 30s 206 | // 提前 500ms 手动结束进程 207 | const surgeMaxTimeout = 29500; 208 | // 脚本超时时间 209 | // retryTimes * 5000 为每次网络请求超时时间(Surge 网络请求超时为 5s) 210 | const scriptTimeout = retryTimes * 5000 + retryTimes * retryInterval; 211 | setTimeout(() => { 212 | logger.log("Script timeout"); 213 | $done({ 214 | title: "请求超时", 215 | content: "连接请求超时\n请检查网络状态后重试", 216 | icon: 'wifi.exclamationmark', 217 | 'icon-color': '#CB1B45', 218 | }); 219 | }, scriptTimeout > surgeMaxTimeout ? surgeMaxTimeout : scriptTimeout); 220 | 221 | // 获取网络信息 222 | logger.log("Script start"); 223 | getNetworkInfo(retryTimes, retryInterval); 224 | })(); 225 | -------------------------------------------------------------------------------- /scripts/javascript/panel/restriction_check.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Form: https://raw.githubusercontent.com/LucaLin233/Luca_Conf/main/Surge/JS/stream-all.js 3 | */ 4 | 5 | // 即将登陆 6 | const STATUS_COMING = 2 7 | // 支持解锁 8 | const STATUS_AVAILABLE = 1 9 | // 不支持解锁 10 | const STATUS_NOT_AVAILABLE = 0 11 | // 检测超时 12 | const STATUS_TIMEOUT = -1 13 | // 检测异常 14 | const STATUS_ERROR = -2 15 | 16 | const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36' 17 | 18 | ;(async () => { 19 | let panel_result = { 20 | title: '流媒体解锁检测', 21 | content: '请刷新面板', 22 | icon: 'play.tv.fill', 23 | 'icon-color': '#FF2D55', 24 | } 25 | let [{ region, status }] = await Promise.all([testDisneyPlus()]) 26 | await Promise.all([check_youtube_premium(),check_netflix()]) 27 | .then((result) => { 28 | console.log(result) 29 | let disney_result="" 30 | if (status==STATUS_COMING) { 31 | //console.log(1) 32 | disney_result="Disney+: 即将登陆~"+region.toUpperCase() 33 | } else if (status==STATUS_AVAILABLE){ 34 | //console.log(2) 35 | console.log(region) 36 | disney_result="Disney+: 已解锁 ➟ "+region.toUpperCase() 37 | // console.log(result["Disney"]) 38 | } else if (status==STATUS_NOT_AVAILABLE) { 39 | //console.log(3) 40 | disney_result="Disney+: 未支持 🚫 " 41 | } else if (status==STATUS_TIMEOUT) { 42 | disney_result="Disney+: 检测超时 🚦" 43 | } 44 | result.push(disney_result) 45 | console.log(result) 46 | let content = result.join('\n') 47 | console.log(content) 48 | 49 | panel_result['content'] = content 50 | }) 51 | .finally(() => { 52 | $done(panel_result) 53 | }) 54 | })() 55 | async function check_youtube_premium() { 56 | let inner_check = () => { 57 | return new Promise((resolve, reject) => { 58 | let option = { 59 | url: 'https://www.youtube.com/premium', 60 | headers: { 61 | 'User-Agent': UA, 62 | 'Accept-Language': 'en', 63 | }, 64 | } 65 | $httpClient.get(option, function (error, response, data) { 66 | if (error != null || response.status !== 200) { 67 | reject('Error') 68 | return 69 | } 70 | 71 | if (data.indexOf('Premium is not available in your country') !== -1) { 72 | resolve('Not Available') 73 | return 74 | } 75 | 76 | let region = '' 77 | let re = new RegExp('"countryCode":"(.*?)"', 'gm') 78 | let result = re.exec(data) 79 | if (result != null && result.length === 2) { 80 | region = result[1] 81 | } else if (data.indexOf('www.google.cn') !== -1) { 82 | region = 'CN' 83 | } else { 84 | region = 'US' 85 | } 86 | resolve(region) 87 | }) 88 | }) 89 | } 90 | 91 | let youtube_check_result = 'YouTube: ' 92 | 93 | await inner_check() 94 | .then((code) => { 95 | if (code === 'Not Available') { 96 | youtube_check_result += '不支持解锁' 97 | } else { 98 | youtube_check_result += '已解锁 ➟ ' + code.toUpperCase() 99 | } 100 | }) 101 | .catch((error) => { 102 | youtube_check_result += '检测失败,请刷新面板' 103 | }) 104 | 105 | return youtube_check_result 106 | } 107 | 108 | async function check_netflix() { 109 | let inner_check = (filmId) => { 110 | return new Promise((resolve, reject) => { 111 | let option = { 112 | url: 'https://www.netflix.com/title/' + filmId, 113 | headers: { 114 | 'User-Agent': UA, 115 | 'Accept-Language': 'en', 116 | }, 117 | } 118 | $httpClient.get(option, function (error, response, data) { 119 | if (error != null) { 120 | reject('Error') 121 | return 122 | } 123 | 124 | if (response.status === 403) { 125 | reject('Not Available') 126 | return 127 | } 128 | 129 | if (response.status === 404) { 130 | resolve('Not Found') 131 | return 132 | } 133 | 134 | if (response.status === 200) { 135 | let url = response.headers['x-originating-url'] 136 | let region = url.split('/')[3] 137 | region = region.split('-')[0] 138 | if (region == 'title') { 139 | region = 'us' 140 | } 141 | resolve(region) 142 | return 143 | } 144 | 145 | reject('Error') 146 | }) 147 | }) 148 | } 149 | 150 | let netflix_check_result = 'Netflix: ' 151 | 152 | await inner_check(81215567) 153 | .then((code) => { 154 | if (code === 'Not Found') { 155 | return inner_check(80018499) 156 | } 157 | netflix_check_result += '已完整解锁 ➟ ' + code.toUpperCase() 158 | return Promise.reject('BreakSignal') 159 | }) 160 | .then((code) => { 161 | if (code === 'Not Found') { 162 | return Promise.reject('Not Available') 163 | } 164 | 165 | netflix_check_result += '仅解锁自制剧 ➟ ' + code.toUpperCase() 166 | return Promise.reject('BreakSignal') 167 | }) 168 | .catch((error) => { 169 | if (error === 'BreakSignal') { 170 | return 171 | } 172 | if (error === 'Not Available') { 173 | netflix_check_result += '该节点不支持解锁' 174 | return 175 | } 176 | netflix_check_result += '检测失败,请刷新面板' 177 | }) 178 | 179 | return netflix_check_result 180 | } 181 | 182 | async function testDisneyPlus() { 183 | try { 184 | let { region, cnbl } = await Promise.race([testHomePage(), timeout(7000)]) 185 | console.log(`homepage: region=${region}, cnbl=${cnbl}`) 186 | let { countryCode, inSupportedLocation } = await Promise.race([getLocationInfo(), timeout(7000)]) 187 | console.log(`getLocationInfo: countryCode=${countryCode}, inSupportedLocation=${inSupportedLocation}`) 188 | region = countryCode ?? region 189 | console.log( "region:"+region) 190 | // 即将登陆 191 | if (inSupportedLocation === false || inSupportedLocation === 'false') { 192 | return { region, status: STATUS_COMING } 193 | } else { 194 | // 支持解锁 195 | return { region, status: STATUS_AVAILABLE } 196 | } 197 | } catch (error) { 198 | console.log("error:"+error) 199 | // 不支持解锁 200 | if (error === 'Not Available') { 201 | console.log("不支持") 202 | return { status: STATUS_NOT_AVAILABLE } 203 | } 204 | // 检测超时 205 | if (error === 'Timeout') { 206 | return { status: STATUS_TIMEOUT } 207 | } 208 | return { status: STATUS_ERROR } 209 | } 210 | } 211 | 212 | function getLocationInfo() { 213 | return new Promise((resolve, reject) => { 214 | let opts = { 215 | url: 'https://disney.api.edge.bamgrid.com/graph/v1/device/graphql', 216 | headers: { 217 | 'Accept-Language': 'en', 218 | Authorization: 'ZGlzbmV5JmJyb3dzZXImMS4wLjA.Cu56AgSfBTDag5NiRA81oLHkDZfu5L3CKadnefEAY84', 219 | 'Content-Type': 'application/json', 220 | 'User-Agent': UA, 221 | }, 222 | body: JSON.stringify({ 223 | query: 'mutation registerDevice($input: RegisterDeviceInput!) { registerDevice(registerDevice: $input) { grant { grantType assertion } } }', 224 | variables: { 225 | input: { 226 | applicationRuntime: 'chrome', 227 | attributes: { 228 | browserName: 'chrome', 229 | browserVersion: '94.0.4606', 230 | manufacturer: 'apple', 231 | model: null, 232 | operatingSystem: 'macintosh', 233 | operatingSystemVersion: '10.15.7', 234 | osDeviceIds: [], 235 | }, 236 | deviceFamily: 'browser', 237 | deviceLanguage: 'en', 238 | deviceProfile: 'macosx', 239 | }, 240 | }, 241 | }), 242 | } 243 | 244 | $httpClient.post(opts, function (error, response, data) { 245 | if (error) { 246 | reject('Error') 247 | return 248 | } 249 | 250 | if (response.status !== 200) { 251 | console.log('getLocationInfo: ' + data) 252 | reject('Not Available') 253 | return 254 | } 255 | 256 | data = JSON.parse(data) 257 | if(data?.errors){ 258 | console.log('getLocationInfo: ' + data) 259 | reject('Not Available') 260 | return 261 | } 262 | 263 | let { 264 | token: { accessToken }, 265 | session: { 266 | inSupportedLocation, 267 | location: { countryCode }, 268 | }, 269 | } = data?.extensions?.sdk 270 | resolve({ inSupportedLocation, countryCode, accessToken }) 271 | }) 272 | }) 273 | } 274 | 275 | function testHomePage() { 276 | return new Promise((resolve, reject) => { 277 | let opts = { 278 | url: 'https://www.disneyplus.com/', 279 | headers: { 280 | 'Accept-Language': 'en', 281 | 'User-Agent': UA, 282 | }, 283 | } 284 | 285 | $httpClient.get(opts, function (error, response, data) { 286 | if (error) { 287 | reject('Error') 288 | return 289 | } 290 | if (response.status !== 200 || data.indexOf('unavailable') !== -1) { 291 | reject('Not Available') 292 | return 293 | } 294 | 295 | let match = data.match(/Region: ([A-Za-z]{2})[\s\S]*?CNBL: ([12])/) 296 | if (!match) { 297 | resolve({ region: '', cnbl: '' }) 298 | return 299 | } 300 | 301 | let region = match[1] 302 | let cnbl = match[2] 303 | resolve({ region, cnbl }) 304 | }) 305 | }) 306 | } 307 | 308 | function timeout(delay = 5000) { 309 | return new Promise((resolve, reject) => { 310 | setTimeout(() => { 311 | reject('Timeout') 312 | }, delay) 313 | }) 314 | } -------------------------------------------------------------------------------- /scripts/javascript/unblock/BaiduCloud.js: -------------------------------------------------------------------------------- 1 | // 获取环境变量 2 | const $ = Env() 3 | 4 | // 设置请求体 5 | var Body = { 6 | "product_infos": [ 7 | { 8 | "product_id": "5210897752128663390", 9 | "start_time": 1405674945, 10 | "end_time": 2147483648, 11 | "buy_time": "1405674945", 12 | "cluster": "offlinedl", 13 | "detail_cluster": "offlinedl", 14 | "product_name": "offlinedl_permanent" 15 | }, 16 | { 17 | "product_name": "contentvip_nd", 18 | "product_description": "超级会员", 19 | "function_num": 0, 20 | "start_time": 1655518919, 21 | "buy_description": "", 22 | "buy_time": 0, 23 | "product_id": "1", 24 | "auto_upgrade_to_svip": 0, 25 | "end_time": 1687103999, 26 | "cluster": "vip", 27 | "detail_cluster": "svip", 28 | "status": 0 29 | } 30 | ], 31 | "currenttime": 1655745382, 32 | "reminder": { 33 | "reminderWithContent": [], 34 | "advertiseContent": [] 35 | }, 36 | "request_id": 508438507580862691 37 | } 38 | 39 | // 返回请求结果 40 | $.done({ body: $.toStr(Body) }) 41 | 42 | // 环境变量函数 43 | function Env() { 44 | // 判断运行环境 45 | LN = typeof $loon != "undefined"; // Loon 46 | SG = typeof $httpClient != "undefined" && !LN; // Surge 47 | QX = typeof $task != "undefined"; // Quantumult X 48 | 49 | // 定义toStr函数,将对象转换为字符串 50 | toStr = (obj) => JSON.stringify(obj) 51 | 52 | // 定义done函数,返回请求结果 53 | done = (value = {}) => { $done(value) } 54 | 55 | // 返回环境变量对象 56 | return { toStr, done } 57 | } 58 | -------------------------------------------------------------------------------- /scripts/javascript/unblock/CamScanner_Pro.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | [Script] 4 | # > 全能扫描王 SVIP (ap*.intsig.net) 5 | 全能扫描王 SVIP = type=http-response, pattern=^https:\/\/(api|api-cs)\.intsig\.net\/purchase\/cs\/query_property\?, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/CamScanner_Pro.js 6 | 7 | [MITM] 8 | hostname = %APPEND% ap*.intsig.net 9 | 10 | */ 11 | 12 | let obj = JSON.parse($response.body); 13 | obj = {"data":{"psnl_vip_property":{"expiry":"1643731200"}}}; 14 | $done({body: JSON.stringify(obj)}); 15 | -------------------------------------------------------------------------------- /scripts/javascript/unblock/Mubu_SVIP.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | [Script] 4 | # > 幕布 SVIP (api2.mubu.com) 5 | 幕布 SVIP = type=http-response, pattern=https?:\/\/api2\.mubu\.com\/v3\/api\/user\/current_user, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/Mubu_SVIP.js 6 | 7 | [MITM] 8 | hostname = %APPEND% api2.mubu.com 9 | 10 | */ 11 | 12 | var url = $request.url; 13 | const path = "/v3/api/user/current_user"; 14 | if (url.indexOf(path) != -1) { 15 | let obj = JSON.parse($response.body); 16 | obj.data.vipEndDate = "20330912"; 17 | body = JSON.stringify(obj); 18 | } 19 | $done({body}); 20 | 21 | /* 22 | var obj = JSON.parse($response.body); 23 | obj={ 24 | "code": 0, 25 | "msg": null, 26 | "data": { 27 | "facebookId": "", 28 | "facebookName": "", 29 | "province": "", 30 | "encryptPassword": null, 31 | "passSecure": false, 32 | "qqId": "", 33 | "updateTime": 1602941084029, 34 | "sort": "time", 35 | "googleName": "", 36 | "vipEndDate": "20330912", 37 | "city": "", 38 | "year": "", 39 | "agreeTermService": false, 40 | "name": "嘤嘤嘤", 41 | "appleName": "", 42 | "id": 4960640, 43 | "gender": "", 44 | "level": 2, 45 | "email": "", 46 | "wxId": "", 47 | "wxName": "", 48 | "phone": null, 49 | "toutiaoId": "", 50 | "appleId": "", 51 | "qqName": "", 52 | "view": "grid", 53 | "larkId": "", 54 | "googleId": "", 55 | "photo": "", 56 | "remark": "", 57 | "createTime": 1592534977160, 58 | "anonymUserFlag": 0 59 | } 60 | }; 61 | $done({body: JSON.stringify(obj)}); 62 | */ 63 | -------------------------------------------------------------------------------- /scripts/javascript/unblock/SYJZ_SVIP.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | [Script] 4 | # > 鲨鱼记账 SVIP (api.shayujizhang.com) 5 | 鲨鱼记账 SVIP = type=http-response, pattern=https:\/\/api\.shayujizhang\.com\/account\/grant\/detail\/info, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/SYJZ_SVIP.js 6 | 7 | [MITM] 8 | hostname = %APPEND% api.shayujizhang.com 9 | 10 | */ 11 | 12 | var body = $response.body; 13 | var url = $request.url; 14 | const path1 = "/account/grant/detail/info/"; 15 | if (url.indexOf(path1) != -1) { 16 | let obj = JSON.parse(body); 17 | obj.data.vip = {"isvip": 1,"days": 999}; 18 | body = JSON.stringify(obj); 19 | } 20 | $done({body}); 21 | -------------------------------------------------------------------------------- /scripts/javascript/unblock/WPS_SVIP.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | [Script] 4 | # > WPS SVIP (account.wps.cn) 5 | WPS SVIP = type=http-response, pattern=^https?:\/\/account\.wps\.cn\/api\/users, requires-body=1, max-size=-1, script-path=https://raw.githubusercontent.com/chiupam/surge/main/scripts/javascript/unblock/WPS_SVIP.js 6 | 7 | [MITM] 8 | hostname = %APPEND% account.wps.cn 9 | 10 | */ 11 | 12 | var obj = JSON.parse($response.body); 13 | 14 | var id = obj.userid; 15 | 16 | obj = { 17 | exp: 0, 18 | level: 3, 19 | privilege: [ 20 | { spid: "data_recover", times: 0, expire_time: 2524579199 }, 21 | { spid: "ocr", times: 0, expire_time: 2524579199 }, 22 | { spid: "pdf2doc", times: 0, expire_time: 2524579199 }, 23 | { spid: "pdf_merge", times: 0, expire_time: 2524579199 }, 24 | { spid: "pdf_sign", times: 0, expire_time: 2524579199 }, 25 | { spid: "pdf_split", times: 0, expire_time: 2524579199 } 26 | ], 27 | result: "ok", 28 | total_buy: 0, 29 | total_cost: -30, 30 | userid: 0000, 31 | vip: { 32 | name: "超级会员", 33 | has_ad: 0, 34 | memberid: 40, 35 | expire_time: 2524579199, 36 | enabled: [ 37 | { memberid: 40, name: "超级会员", expire_time: 2524579199 }, 38 | { memberid: 20, name: "WPS会员", expire_time: 2524579199 }, 39 | { memberid: 12, name: "稻壳会员", expire_time: 2524579199 } 40 | ] 41 | }, 42 | wealth: 0, 43 | expire_time: 2524579199 44 | }; 45 | 46 | obj.userid = id; 47 | 48 | $done({ body: JSON.stringify(obj) }); 49 | -------------------------------------------------------------------------------- /scripts/python/zsfc/zsfc_login.py: -------------------------------------------------------------------------------- 1 | """ 2 | 青龙面板识别内容: 3 | new Env("掌飞登录") 4 | 1 0 * * * zsfc_login.py 5 | 6 | 脚本说明: 7 | 目前仅支持 Surge 抓包使用 8 | 9 | 部署步骤: 10 | 1. Surge 添加 MitM 主机名 api2.helper.qq.com; 11 | 2. 开启抓取流量功能,打开掌上飞车APP,进入后及关闭抓取流量功能; 12 | 3. 从抓包请求中找到链接为 https://api2.helper.qq.com/user/login 的包,导出为HAR发送到电脑; 13 | 4. 使用浏览器打开 .HAR 的文件,将文件内容全部复制; 14 | 5. 青龙面板添加一个名为 ZSFC_LOGIN 的环境变量,值为 .HAR 的文件内容; 15 | 6. 自行添加脚本进入青龙面板,定时运行脚本即可。 16 | """ 17 | 18 | from base64 import b64decode 19 | from json import loads, decoder 20 | from os import environ as env 21 | from re import search 22 | from time import sleep 23 | 24 | import requests 25 | 26 | 27 | def fetchMapData(): 28 | url = "https://bang.qq.com/app/speed/treasure/index" 29 | params = { 30 | "roleId": roleId if roleId else userData['zsfc_roleId'], 31 | "uin": uin if uin else userData['zsfc_uin'], 32 | "areaId": areaId if areaId else userData['zsfc_areaId'] 33 | } 34 | 35 | response = session.get(url, params=params) 36 | responseHtml = response.text 37 | c = int(search(r'"todaycanTimes":(\d+)', responseHtml).group(1)) 38 | 39 | return True if c >= 3 else False 40 | 41 | 42 | def userLogin(): 43 | def s(x, j=0): 44 | returnList = [e["value"] for e in h if e["name"].lower() == x] 45 | return "; ".join(returnList) if j else returnList[0] 46 | 47 | url = "https://api2.helper.qq.com/user/login" 48 | headers = { 49 | "authority": "api2.helper.qq.com", 50 | "accept": s("accept"), 51 | "content-type": s("content-type"), 52 | "cookie": s("cookie", j=1), 53 | "content-length": s("content-length"), 54 | "x-request-id": s("x-request-id"), 55 | "gh-header": s("gh-header"), 56 | "user-agent": s("user-agent"), 57 | "accept-language": s("accept-language"), 58 | "accept-encoding": s("accept-encoding"), 59 | } 60 | 61 | session.post(url, headers=headers, data=b64decode(postData)) 62 | sleep(2.5) 63 | 64 | 65 | if __name__ == '__main__': 66 | session = requests.session() 67 | 68 | loginJson = {} 69 | 70 | if env.get("HOSTNAME"): 71 | userData = loads(env.get('ZSFC_CONFIG') if env.get('ZSFC_CONFIG') else "{}") 72 | loginData = env.get('ZSFC_LOGIN') 73 | else: 74 | userData = {} 75 | if env.get('ZSFC_LOGIN'): 76 | loginData = env.get('ZSFC_LOGIN') 77 | else: 78 | loginData = r"" 79 | 80 | p = search(r'"text":"([^"]+)"', loginData).group(1) 81 | postData = p.replace("\\", "/") if env.get("HOSTNAME") else p.replace("\\/", "/") 82 | 83 | roleId, uin, areaId = "", "", "" 84 | if not roleId and not uin and not areaId: 85 | if env.get("ZSFC_USER"): 86 | roleId, uin, areaId = env.get("ZSFC_USER").split("/") 87 | else: 88 | roleId = loads(env.get("ZSFC_CONFIG") if env.get('ZSFC_CONFIG') else '{"zsfc_roleId":""}')['zsfc_roleId'] 89 | uin = loads(env.get("ZSFC_CONFIG") if env.get('ZSFC_CONFIG') else '{"zsfc_uin":""}')['zsfc_uin'] 90 | areaId = loads(env.get("ZSFC_CONFIG") if env.get('ZSFC_CONFIG') else '{"zsfc_areaId":""}')['zsfc_areaId'] 91 | 92 | try: 93 | loginJson = loads(loginData.replace("\\", "")) 94 | except decoder.JSONDecodeError: 95 | loginJson = loads(loginData.replace("\\/", "/")) 96 | finally: 97 | h = loginJson["log"]['entries'][0]['request']['headers'] 98 | 99 | if roleId and uin and areaId: 100 | print("🏎️ 检测今日是否已登录") 101 | if fetchMapData(): 102 | print("⭕ 今天已登录") 103 | else: 104 | print("💻 今日未登录,开始登录") 105 | userLogin() 106 | print(f"✅ 登陆成功" if fetchMapData() else "❌ 登录失败") 107 | else: 108 | print("⭕ 不检测登录状态") 109 | userLogin() 110 | --------------------------------------------------------------------------------