├── .gitignore ├── LICENSE.md ├── README.md ├── js ├── adsense.js ├── baidu-no-redirect.js ├── baidumap.js ├── bilibili-json.js ├── bilibili-proto-test.js ├── bilibili-proto.js ├── qidian.js ├── qq-news.js ├── spotify-json.js ├── spotify-lyric-test.js ├── spotify-lyric.js ├── spotify-proto.js ├── spotify-qx-header.js ├── tieba-json.js ├── tieba-json2.js ├── tieba-proto-bak.js ├── tieba-proto.js ├── tieba-proto2.js ├── vgtime.js ├── youtube.js └── zhihu.js ├── module ├── adsense.conf ├── adsense.sgmodule ├── baidu-no-redirect.sgmodule ├── baidumap.sgmodule ├── bilibili-qx.conf ├── bilibili-test.sgmodule ├── bilibili.sgmodule ├── bilibili.stoverride ├── mitm.sgmodule ├── qidian.conf ├── qidian.sgmodule ├── qqnews.conf ├── qqnews.sgmodule ├── spotify.conf ├── spotify.module ├── spotify.stoverride ├── tieba-mini.sgmodule ├── tieba-qx.conf ├── tieba-test.sgmodule ├── tieba.sgmodule ├── tieba.stoverride ├── vgtime.conf ├── vgtime.sgmodule ├── youtube-qx.conf ├── youtube.sgmodule ├── zhihu.conf └── zhihu.sgmodule ├── plugin ├── adsense.plugin ├── baidu-no-redirect.plugin ├── bilibili.plugin ├── qidian.plugin ├── qqnews.plugin ├── spotify.plugin ├── tieba.plugin ├── vgtime.plugin ├── youtube.plugin └── zhihu.plugin └── rule ├── ad.list ├── bilibili-ad-qx.list ├── bilibili-ad.list ├── tieba-ad-qx.list ├── tieba-ad.list ├── zhihu-ad-qx.list └── zhihu-ad.list /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | ### NetBeans ### 22 | /nbproject/private/ 23 | /nbbuild/ 24 | /dist/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | build/ 28 | !**/src/main/**/build/ 29 | !**/src/test/**/build/ 30 | 31 | ### VS Code ### 32 | .vscode/ 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 app2smile 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 | # 目录 2 | - [起点](#起点) 3 | - [Spotify](#spotify) 4 | - [Spotify歌词翻译](#spotify歌词翻译) 5 | - [哔哩哔哩](#哔哩哔哩) 6 | - [贴吧](#贴吧) 7 | 8 | **_点击下方各自链接,查看能去哪些广告_** 9 | 10 | ## 起点 11 | > Loon和Surge均支持对tcp链接进行解密,可以完美去广告 12 | > qx目前不支持对TCP链接进行MITM,需全程开启代理软件 13 | 14 | qx去广告无效的解决办法: 15 | 16 | 目前只能删除起点app,重新下载安装使用 17 | 18 | | 软件 | 链接 | 19 | | :-----| :---- | 20 | | Surge | https://raw.githubusercontent.com/app2smile/rules/master/module/qidian.sgmodule | 21 | | Loon | https://raw.githubusercontent.com/app2smile/rules/master/plugin/qidian.plugin | 22 | | qx | Rewrite:https://raw.githubusercontent.com/app2smile/rules/master/module/qidian.conf | 23 | 24 | 25 | ## Spotify 26 | > 需要系统版本>=iOS15 27 | > Spotify音质不能设置为超高 28 | 29 | | 软件 | 链接 | 30 | | :-----| :---- | 31 | | Surge | https://raw.githubusercontent.com/app2smile/rules/master/module/spotify.module | 32 | | Loon | https://raw.githubusercontent.com/app2smile/rules/master/plugin/spotify.plugin | 33 | | qx | Rewrite:https://raw.githubusercontent.com/app2smile/rules/master/module/spotify.conf | 34 | 35 | 36 | ## Spotify歌词翻译 37 | > https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-lyric.js 38 | 39 | 40 | ## 哔哩哔哩 41 | > 需要系统版本>=iOS15 42 | 43 | | 软件 | 链接 | 44 | | :-----| :---- | 45 | | Surge | https://raw.githubusercontent.com/app2smile/rules/master/module/bilibili.sgmodule | 46 | | Loon | https://raw.githubusercontent.com/app2smile/rules/master/plugin/bilibili.plugin | 47 | | qx | Filter:https://raw.githubusercontent.com/app2smile/rules/master/rule/bilibili-ad-qx.list
Rewrite:https://raw.githubusercontent.com/app2smile/rules/master/module/bilibili-qx.conf | 48 | 49 | 50 | ## 贴吧 51 | > 需要系统版本>=iOS15 52 | 53 | | 软件 | 链接 | 54 | | :-----| :---- | 55 | | Surge | https://raw.githubusercontent.com/app2smile/rules/master/module/tieba.sgmodule | 56 | | Loon | https://raw.githubusercontent.com/app2smile/rules/master/plugin/tieba.plugin | 57 | | qx | Filter:https://raw.githubusercontent.com/app2smile/rules/master/rule/tieba-ad-qx.list
Rewrite:https://raw.githubusercontent.com/app2smile/rules/master/module/tieba-qx.conf | 58 | -------------------------------------------------------------------------------- /js/adsense.js: -------------------------------------------------------------------------------- 1 | const url = $request.url; 2 | const method = $request.method; 3 | if (!$response.body) { 4 | // 穿山甲有概率会有此情况 5 | console.log('$response.body为空'); 6 | $done({}); 7 | } 8 | let body = JSON.parse($response.body); 9 | 10 | const getMethod = "GET"; 11 | const postMethod = "POST"; 12 | const noticeTitle = "广告联盟"; 13 | 14 | if ((url.includes("api-access.pangolin-sdk-toutiao.com/api/ad/union/sdk") 15 | || url.includes("is.snssdk.com/api/ad/union/sdk")) 16 | && method === postMethod) { 17 | console.log('穿山甲-get_ads'); 18 | if (!body.message) { 19 | console.log(`body:${$response.body}`); 20 | // 错误码 https://www.csjplatform.com/supportcenter/5421 21 | if (!('status_code' in body)) { 22 | $notification.post(noticeTitle, "穿山甲", "message/status_code字段错误"); 23 | } else { 24 | console.log('广告为空'); 25 | } 26 | } else { 27 | console.log(Object.keys(body)); 28 | body = { 29 | "request_id": 'F5617E54-3FF4-4052-9B09-4227D09B5105', 30 | "status_code": 20001, 31 | "reason": 112, 32 | "desc": "该代码位请求量过大且消耗过低,因此填充率控制在10%以内,该策略每日生效,如果当天该代码位的消耗上涨或请求量小于5000,则次日不会命中该策略" 33 | }; 34 | console.log('成功'); 35 | } 36 | } else if (url.includes('mi.gdt.qq.com') && method === getMethod) { 37 | console.log('优量汇'); 38 | if ('ret' in body) { 39 | if (body.ret === 0) { 40 | // https://developers.adnet.qq.com/doc/android/union/union_debug#sdk%20%E9%94%99%E8%AF%AF%E7%A0%81 41 | body.ret = 102006; 42 | console.log('修改ret成功'); 43 | } else { 44 | console.log(`ret不为0,不处理`); 45 | } 46 | } else { 47 | console.log(`body:${$response.body}`); 48 | $notification.post(noticeTitle, "优量汇", "无ret"); 49 | } 50 | } else if (url.includes('open.e.kuaishou.com') && method === postMethod) { 51 | console.log('快手联盟'); 52 | if (body.result === 1) { 53 | // 错误码: https://u.kuaishou.com/home/detail/1158 54 | body.result = 40003; 55 | console.log('修改result成功'); 56 | } else { 57 | console.log('无需修改result'); 58 | } 59 | } else { 60 | $notification.post(noticeTitle, "路径/请求方法匹配错误:", method + "," + url); 61 | } 62 | 63 | body = JSON.stringify(body); 64 | 65 | $done({ 66 | body 67 | }); 68 | -------------------------------------------------------------------------------- /js/baidu-no-redirect.js: -------------------------------------------------------------------------------- 1 | const method = $request.method; 2 | const url = $request.url; 3 | const status = $response.status; 4 | let headers = $response.headers; 5 | const notifiTitle = "百度搜索防跳转AppStore错误"; 6 | 7 | if (method !== "GET" || status !== 302 || !headers.hasOwnProperty('Location')) { 8 | console.log(`method:${method},status:${status},url:${url}`); 9 | $notification.post(notifiTitle, "百度防跳转AppStore", "method/status有误"); 10 | } else { 11 | if (headers.Location.indexOf('.apple.com') !== -1) { 12 | let tokenData = getUrlParamValue(url, 'tokenData'); 13 | if (tokenData == null) { 14 | console.log(`未获取到tokenData,url:${url}`); 15 | $notification.post(notifiTitle, "getUrlParamValue", "未获取到tokenData"); 16 | } else { 17 | let tokenDataObj = JSON.parse(decodeURIComponent(tokenData)); 18 | headers.Location = tokenDataObj.url; 19 | console.log('成功'); 20 | } 21 | } else { 22 | console.log('无需修改Location'); 23 | } 24 | } 25 | $done({ 26 | headers 27 | }); 28 | 29 | function getUrlParamValue(url, queryName) { 30 | return Object.fromEntries(url.substring(url.indexOf("?") + 1) 31 | .split("&") 32 | .map(pair => pair.split("=")) 33 | )[queryName]; 34 | } 35 | -------------------------------------------------------------------------------- /js/bilibili-json.js: -------------------------------------------------------------------------------- 1 | const url = $request.url; 2 | const method = $request.method; 3 | const notifyTitle = "bilibili-json"; 4 | console.log(`b站json-2023.10.22`); 5 | if (!$response.body) { 6 | // 有undefined的情况 7 | console.log(`$response.body为undefined:${url}`); 8 | $done({}); 9 | } 10 | if (method !== "GET") { 11 | $notification.post(notifyTitle, "method错误:", method); 12 | } 13 | let body = JSON.parse($response.body); 14 | 15 | 16 | if (!body.data) { 17 | console.log(url); 18 | console.log(`body:${$response.body}`); 19 | $notification.post(notifyTitle, url, "data字段错误"); 20 | } else { 21 | if (url.includes("x/v2/splash")) { 22 | console.log('开屏页' + (url.includes("splash/show") ? 'show' : 'list')); 23 | if (!body.data.show) { 24 | // 有时候返回的数据没有show字段 25 | console.log('数据无show字段'); 26 | } else { 27 | delete body.data.show; 28 | console.log('成功'); 29 | } 30 | } else if (url.includes("resource/show/tab/v2")) { 31 | console.log('tab修改'); 32 | // 顶部右上角 33 | if (!body.data.top) { 34 | console.log(`body:${$response.body}`); 35 | $notification.post(notifyTitle, 'tab', "top字段错误"); 36 | } else { 37 | body.data.top = body.data.top.filter(item => { 38 | if (item.name === '游戏中心') { 39 | console.log('去除右上角游戏中心'); 40 | return false; 41 | } 42 | return true; 43 | }); 44 | fixPos(body.data.top); 45 | } 46 | // 底部tab栏 47 | if (!body.data.bottom) { 48 | console.log(`body:${$response.body}`); 49 | $notification.post(notifyTitle, 'tab', "bottom字段错误"); 50 | } else { 51 | body.data.bottom = body.data.bottom.filter(item => { 52 | if (item.name === '发布') { 53 | console.log('去除发布'); 54 | return false; 55 | } else if (item.name === '会员购' || item.tab_id === '会员购Bottom') { 56 | console.log('去除会员购'); 57 | return false; 58 | } 59 | return true; 60 | }); 61 | fixPos(body.data.bottom); 62 | } 63 | } else if (url.includes("x/v2/feed/index")) { 64 | console.log('推荐页'); 65 | if (!body.data.items?.length) { 66 | console.log(`body:${$response.body}`); 67 | $notification.post(notifyTitle, '推荐页', "items字段错误"); 68 | } else { 69 | body.data.items = body.data.items.filter(i => { 70 | const {card_type: cardType, card_goto: cardGoto} = i; 71 | if (cardType && cardGoto) { 72 | if (cardType === 'banner_v8' && cardGoto === 'banner') { 73 | if (!i.banner_item) { 74 | console.log(`body:${$response.body}`); 75 | $notification.post(notifyTitle, '推荐页', "banner_item错误"); 76 | } else { 77 | for (const v of i.banner_item) { 78 | if (!v.type) { 79 | console.log(`body:${$response.body}`); 80 | $notification.post(notifyTitle, '推荐页', "type错误"); 81 | } else { 82 | if (v.type === 'ad') { 83 | console.log('banner广告'); 84 | return false; 85 | } 86 | } 87 | } 88 | } 89 | } else if (cardType === 'cm_v2' && ['ad_web_s', 'ad_av', 'ad_web_gif', 'ad_player', 'ad_inline_3d', 'ad_inline_eggs'].includes(cardGoto)) { 90 | // ad_player大视频广告 ad_web_gif大gif广告 ad_web_s普通小广告 ad_av创作推广广告 ad_inline_3d 上方大的视频3d广告 ad_inline_eggs 上方大的视频广告 91 | console.log(`${cardGoto}广告去除)`); 92 | return false; 93 | } else if (cardType === 'small_cover_v10' && cardGoto === 'game') { 94 | console.log('游戏广告去除'); 95 | return false; 96 | } else if (cardType === 'cm_double_v9' && cardGoto === 'ad_inline_av') { 97 | console.log('创作推广-大视频广告'); 98 | return false; 99 | } 100 | } else { 101 | console.log(`body:${$response.body}`); 102 | $notification.post(notifyTitle, '推荐页', "无card_type/card_goto"); 103 | } 104 | return true; 105 | }); 106 | } 107 | } else { 108 | $notification.post(notifyTitle, "路径匹配错误:", url); 109 | } 110 | } 111 | 112 | body = JSON.stringify(body); 113 | $done({ 114 | body 115 | }); 116 | 117 | 118 | function fixPos(arr) { 119 | for (let i = 0; i < arr.length; i++) { 120 | // 修复pos 121 | arr[i].pos = i + 1; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /js/qidian.js: -------------------------------------------------------------------------------- 1 | let url = $request.url; 2 | let method = $request.method; 3 | if (!$response.body) { 4 | console.log(`$response.body为undefined:${url}`); 5 | $done({}); 6 | } 7 | 8 | let body = JSON.parse($response.body); 9 | 10 | const noticeTitle = "起点App脚本错误"; 11 | const getMethod = "GET"; 12 | const postMethod = "POST"; 13 | 14 | if (!body.Data) { 15 | console.log(`body:${$response.body}`); 16 | $notification.post(noticeTitle, "起点", "Data为空"); 17 | } else { 18 | if (url.includes("v4/client/getsplashscreen") && method === getMethod) { 19 | console.log('起点-开屏页'); 20 | if (!body.Data.List) { 21 | console.log(`body:${$response.body}`); 22 | $notification.post(noticeTitle, "起点", "List字段空"); 23 | } else { 24 | body.Data.List = null; 25 | console.log('List成功'); 26 | } 27 | if ('EnableGDT' in body.Data) { 28 | if (body.Data.EnableGDT === 1) { 29 | body.Data.EnableGDT = 0; 30 | console.log('EnableGDT成功'); 31 | } else { 32 | console.log('无需修改EnableGDT'); 33 | } 34 | } else { 35 | console.log(`body:${$response.body}`); 36 | $notification.post(noticeTitle, "起点", "EnableGDT字段为空"); 37 | } 38 | 39 | } else if (url.includes("v2/deeplink/geturl") && method === getMethod) { 40 | console.log(`起点-不跳转精选页:${body.Data.ActionUrl}`); 41 | if (body.Data.ActionUrl) { 42 | // QDReader://Bookstore 43 | // QDReader://Bookstore?query={"abGroupId": "b", "lastReadBarEnabled": "1"} 44 | console.log('成功'); 45 | body.Data.ActionUrl = ''; 46 | } else { 47 | console.log('无需处理'); 48 | } 49 | } else if (url.includes("v1/adv/getadvlistbatch?positions=iOS_tab") && method === getMethod) { 50 | console.log('起点-iOS_tab'); 51 | if (!body.Data.iOS_tab) { 52 | console.log(`body:${$response.body}`); 53 | $notification.post(noticeTitle, "起点-iOS_tab", "iOS_tab字段为空"); 54 | } else { 55 | if (body.Data.iOS_tab.length === 0) { 56 | console.log('返回配置空'); 57 | } else { 58 | body.Data.iOS_tab = []; 59 | console.log('成功'); 60 | } 61 | } 62 | } else if (url.includes("v2/dailyrecommend/getdailyrecommend") && method === getMethod) { 63 | console.log('起点-每日导读'); 64 | if (body.Data.Items?.length) { 65 | body.Data.Items = []; 66 | console.log('成功'); 67 | } else { 68 | console.log('每日导读无数据'); 69 | } 70 | } else if (url.includes("v1/bookshelf/getHoverAdv") && method === getMethod) { 71 | console.log('起点-书架悬浮广告'); 72 | if (body.Data.ItemList?.length) { 73 | console.log('成功' + body.Data.ItemList.length); 74 | body.Data.ItemList = []; 75 | } else { 76 | console.log('无需处理'); 77 | } 78 | } else if (url.includes("v1/client/getconf") && method === postMethod) { 79 | console.log('起点-client/getconf'); 80 | // 精选 和 发现 中间的活动配置 81 | if (!body.Data.ActivityPopup?.Data) { 82 | console.log(`body:${$response.body}`); 83 | $notification.post(noticeTitle, "起点-getconf", "ActivityPopup/Data字段为空"); 84 | } else { 85 | body.Data.ActivityPopup = null; 86 | console.log('ActivityPopup(活动弹窗)成功'); 87 | } 88 | if (body.Data.WolfEye === 1) { 89 | // 使5.9.196版本 tcp强制走https 90 | console.log('WolfEye修改为0'); 91 | body.Data.WolfEye = 0; 92 | } else { 93 | console.log(`无需修改WolfEye:${body.Data.WolfEye}`); 94 | } 95 | if(body.Data.CloudSetting?.TeenShowFreq === '1'){ 96 | body.Data.CloudSetting.TeenShowFreq = '0'; 97 | console.log('去除青少年模式弹框'); 98 | } 99 | // QDReader://Bookshelf 书架右下角悬浮活动 100 | if (body.Data.ActivityIcon?.Type !== 0) { 101 | console.log(`body:${$response.body}`); 102 | $notification.post(noticeTitle, "起点-getconf", "ActivityIcon/Type字段错误"); 103 | } else { 104 | // 无活动icon的情况下为{"EndTime":0,"StartTime":0,"Type":0} 105 | if (body.Data.ActivityIcon.EndTime === 0) { 106 | console.log('无ActivityIcon配置'); 107 | } else { 108 | body.Data.ActivityIcon.StartTime = 0; 109 | body.Data.ActivityIcon.EndTime = 0; 110 | delete body.Data.ActivityIcon.Actionurl; 111 | delete body.Data.ActivityIcon.Icon; 112 | console.log('ActivityIcon成功'); 113 | } 114 | } 115 | 116 | // 功能增强:搜索页可以搜索用户 117 | if (body.Data.EnableSearchUser === "1") { 118 | console.log(`无需修改搜索用户配置`); 119 | } else { 120 | body.Data.EnableSearchUser = "1"; 121 | console.log(`允许搜索用户成功:${body.Data.EnableSearchUser}`); 122 | } 123 | 124 | // if (body.Data.hasOwnProperty('EnableClipboardReading')) { 125 | // if (body.Data.EnableClipboardReading === 1) { 126 | // body.Data.EnableClipboardReading = 0; 127 | // console.log('不允许读取剪切板'); 128 | // } else { 129 | // console.log('无需修改剪切板配置'); 130 | // } 131 | // } else { 132 | // console.log("body:" + $response.body); 133 | // $notification.post(notifiTitle, "起点-getconf", "EnableClipboardReading字段错误"); 134 | // } 135 | // QDReader://UserCenter 我 136 | // QDReader://Bookshelf 书架 137 | // QDReader://Bookstore 精选 138 | } else { 139 | $notification.post(noticeTitle, "起点App路径/请求方法匹配错误:", method + "," + url); 140 | } 141 | } 142 | body = JSON.stringify(body); 143 | 144 | $done({ 145 | body 146 | }); 147 | 148 | -------------------------------------------------------------------------------- /js/qq-news.js: -------------------------------------------------------------------------------- 1 | let url = $request.url; 2 | let method = $request.method; 3 | if (!$response.body) { 4 | console.log(`$response.body为undefined:${url}`); 5 | $done({}); 6 | } 7 | 8 | let body = JSON.parse($response.body); 9 | 10 | if (method !== "POST") { 11 | $notification.post("腾讯新闻App脚本错误", "method错误:", method); 12 | } 13 | 14 | if (url.includes("r.inews.qq.com/gw/page/event_detail")) { 15 | removeAdList('event_detail'); 16 | } else if (url.includes("r.inews.qq.com/gw/page/channel_feed")) { 17 | removeAdList('channel_feed'); 18 | } else { 19 | let name = ""; 20 | if (url.includes("news.ssp.qq.com/app")) { 21 | name = '开屏页'; 22 | } else if (url.includes("r.inews.qq.com/getQQNewsUnreadList")) { 23 | // 是否弃用,还需要验证 24 | name = '要闻/财经等'; 25 | } else if (url.includes("r.inews.qq.com/news_feed/hot_module_list")) { 26 | name = '财经精选-更多'; 27 | } else if (url.includes("r.inews.qq.com/gw/event/list")) { 28 | // 弃用 29 | name = '专题gw/event/list'; 30 | } else if (url.includes("r.inews.qq.com/getTwentyFourHourNews")) { 31 | // 弃用 32 | name = '热点精选getTwentyFourHourNews'; 33 | } else if (url.includes("r.inews.qq.com/getQQNewsListItems")) { 34 | // 弃用 35 | name = '热点精选getQQNewsListItems'; 36 | } else if (url.includes("r.inews.qq.com/getTagFeedList")) { 37 | // 如地方专区下的 XX旅游 XX美食列表广告 38 | name = 'getTagFeedList'; 39 | } else { 40 | $notification.post('腾讯新闻App脚本错误', "路径匹配错误:", url); 41 | } 42 | console.log(name); 43 | if (!body.adList) { 44 | // 部分专题列表无广告,没有adList字段 45 | console.log('无广告'); 46 | } else { 47 | body.adList = null; 48 | console.log('成功'); 49 | } 50 | } 51 | 52 | body = JSON.stringify(body); 53 | 54 | $done({ 55 | body 56 | }); 57 | 58 | function removeAdList(name) { 59 | console.log(`gw/page/${name}`); 60 | if (body.data.widget_list) { 61 | body.data.widget_list = body.data.widget_list.filter(item => { 62 | if (item.widget_type === 'ad_list') { 63 | console.log('去除ad_list广告'); 64 | return false; 65 | } 66 | return true; 67 | }); 68 | } else { 69 | console.log($response.body); 70 | $notification.post('腾讯新闻App脚本错误', name, '无widget_list字段'); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /js/spotify-json.js: -------------------------------------------------------------------------------- 1 | console.log(`spotify-json-2023.06.13`); 2 | let url = $request.url; 3 | // console.log(`原始url:${url}`); 4 | if (url.includes('platform=iphone')) { 5 | url = url.replace(/platform=iphone/, 'platform=ipad'); 6 | // console.log(`替换platform:${url}`); 7 | } else { 8 | console.log('无需处理'); 9 | } 10 | $done({ 11 | url 12 | }); 13 | -------------------------------------------------------------------------------- /js/spotify-lyric-test.js: -------------------------------------------------------------------------------- 1 | /* 2 | Spotify非中文歌词翻译 Surge和Loon需要>=iOS15 (仓库地址: https://github.com/app2smile/rules) 3 | 采用百度翻译接口进行翻译,需要先免费申请百度翻译api的id和密钥,然后根据不同软件进行不同配置 4 | 5 | -----------申请百度翻译(有标准版和高级版 建议申请高级版)api-------------- 6 | 标准版(很可能不够用):单次最长请求1000字符,免费调用量5万字符/月,QPS=1 7 | 高级版:单次最长请求6000字符,免费调用量100万字符/月,QPS=10 8 | 9 | 注册百度翻译个人开发者: http://api.fanyi.baidu.com/register 10 | 注册后如果需要认证可自行选择是否实人认证(高级版需要验证) 11 | 开通(通用翻译)API服务: https://fanyi-api.baidu.com/choose 12 | 成功后即可看到自己的appid和密钥(不要泄露给任何人): http://api.fanyi.baidu.com/manage/developer 13 | 14 | ------------软件配置(在文本模式下,填入下方内容)-------------- 15 | 如果软件已经加载过Spotify解锁脚本(https://github.com/app2smile/rules#spotify),可不配置MITM域名 16 | 1.Surge: 17 | [MITM] 18 | hostname = %APPEND% spclient.wg.spotify.com 19 | [Script] 20 | # 修改下方argument中的appid和securityKey,填入自己的appid和密钥 21 | spotify歌词翻译 = type=http-response,pattern=^https:\/\/spclient\.wg\.spotify\.com\/color-lyrics\/v2\/track\/,requires-body=1,binary-body-mode=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-lyric.js,argument=appid=111&securityKey=xxx 22 | 23 | 2.Loon: 24 | [Mitm] 25 | hostname =spclient.wg.spotify.com 26 | [Script] 27 | # 修改下方argument中的appid和securityKey,填入自己的appid和密钥 28 | http-response ^https:\/\/spclient\.wg\.spotify\.com\/color-lyrics\/v2\/track\/ script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-lyric.js, requires-body=true, binary-body-mode=true, timeout=10, tag=Spotify歌词翻译, argument=appid=111&securityKey=xxx 29 | 30 | 3.qx: 31 | - 自行配置MITM域名: spclient.wg.spotify.com 32 | - 手动修改填入下方的appid和securityKey密钥, 并配置重写,类型为script-response-body, 33 | 正则填入^https:\/\/spclient\.wg\.spotify\.com\/color-lyrics\/v2\/track\/ 34 | */ 35 | // 注意: QX用户需要手动填入appid和securityKey密钥, Surge和Loon用户无需填入!!!! 36 | const options = { 37 | appid: '', 38 | securityKey: '' 39 | }; 40 | // text-decoder 41 | !function(i){"use strict";function _(n,e,i){return e<=n&&n<=i}"undefined"!=typeof module&&module.exports&&!i["encoding-indexes"]&&(i["encoding-indexes"]=require("./encoding-indexes.js")["encoding-indexes"]);var l=Math.floor;function s(n){if(void 0===n)return{};if(n===Object(n))return n;throw TypeError("Could not convert argument to dictionary")}function u(n){return 0<=n&&n<=127}var a=u,b=-1;function c(n){this.tokens=[].slice.call(n),this.tokens.reverse()}c.prototype={endOfStream:function(){return!this.tokens.length},read:function(){return this.tokens.length?this.tokens.pop():b},prepend:function(n){if(Array.isArray(n))for(var e=n;e.length;)this.tokens.push(e.pop());else this.tokens.push(n)},push:function(n){if(Array.isArray(n))for(var e=n;e.length;)this.tokens.unshift(e.shift());else this.tokens.unshift(n)}};var w=-1;function m(n,e){if(n)throw TypeError("Decoder error");return e||65533}function f(n){throw TypeError("The code point "+n+" could not be encoded.")}function r(n){return n=String(n).trim().toLowerCase(),Object.prototype.hasOwnProperty.call(d,n)?d[n]:null}var t,o,n=[{encodings:[{labels:["unicode-1-1-utf-8","utf-8","utf8"],name:"UTF-8"}],heading:"The Encoding"},{encodings:[{labels:["866","cp866","csibm866","ibm866"],name:"IBM866"},{labels:["csisolatin2","iso-8859-2","iso-ir-101","iso8859-2","iso88592","iso_8859-2","iso_8859-2:1987","l2","latin2"],name:"ISO-8859-2"},{labels:["csisolatin3","iso-8859-3","iso-ir-109","iso8859-3","iso88593","iso_8859-3","iso_8859-3:1988","l3","latin3"],name:"ISO-8859-3"},{labels:["csisolatin4","iso-8859-4","iso-ir-110","iso8859-4","iso88594","iso_8859-4","iso_8859-4:1988","l4","latin4"],name:"ISO-8859-4"},{labels:["csisolatincyrillic","cyrillic","iso-8859-5","iso-ir-144","iso8859-5","iso88595","iso_8859-5","iso_8859-5:1988"],name:"ISO-8859-5"},{labels:["arabic","asmo-708","csiso88596e","csiso88596i","csisolatinarabic","ecma-114","iso-8859-6","iso-8859-6-e","iso-8859-6-i","iso-ir-127","iso8859-6","iso88596","iso_8859-6","iso_8859-6:1987"],name:"ISO-8859-6"},{labels:["csisolatingreek","ecma-118","elot_928","greek","greek8","iso-8859-7","iso-ir-126","iso8859-7","iso88597","iso_8859-7","iso_8859-7:1987","sun_eu_greek"],name:"ISO-8859-7"},{labels:["csiso88598e","csisolatinhebrew","hebrew","iso-8859-8","iso-8859-8-e","iso-ir-138","iso8859-8","iso88598","iso_8859-8","iso_8859-8:1988","visual"],name:"ISO-8859-8"},{labels:["csiso88598i","iso-8859-8-i","logical"],name:"ISO-8859-8-I"},{labels:["csisolatin6","iso-8859-10","iso-ir-157","iso8859-10","iso885910","l6","latin6"],name:"ISO-8859-10"},{labels:["iso-8859-13","iso8859-13","iso885913"],name:"ISO-8859-13"},{labels:["iso-8859-14","iso8859-14","iso885914"],name:"ISO-8859-14"},{labels:["csisolatin9","iso-8859-15","iso8859-15","iso885915","iso_8859-15","l9"],name:"ISO-8859-15"},{labels:["iso-8859-16"],name:"ISO-8859-16"},{labels:["cskoi8r","koi","koi8","koi8-r","koi8_r"],name:"KOI8-R"},{labels:["koi8-ru","koi8-u"],name:"KOI8-U"},{labels:["csmacintosh","mac","macintosh","x-mac-roman"],name:"macintosh"},{labels:["dos-874","iso-8859-11","iso8859-11","iso885911","tis-620","windows-874"],name:"windows-874"},{labels:["cp1250","windows-1250","x-cp1250"],name:"windows-1250"},{labels:["cp1251","windows-1251","x-cp1251"],name:"windows-1251"},{labels:["ansi_x3.4-1968","ascii","cp1252","cp819","csisolatin1","ibm819","iso-8859-1","iso-ir-100","iso8859-1","iso88591","iso_8859-1","iso_8859-1:1987","l1","latin1","us-ascii","windows-1252","x-cp1252"],name:"windows-1252"},{labels:["cp1253","windows-1253","x-cp1253"],name:"windows-1253"},{labels:["cp1254","csisolatin5","iso-8859-9","iso-ir-148","iso8859-9","iso88599","iso_8859-9","iso_8859-9:1989","l5","latin5","windows-1254","x-cp1254"],name:"windows-1254"},{labels:["cp1255","windows-1255","x-cp1255"],name:"windows-1255"},{labels:["cp1256","windows-1256","x-cp1256"],name:"windows-1256"},{labels:["cp1257","windows-1257","x-cp1257"],name:"windows-1257"},{labels:["cp1258","windows-1258","x-cp1258"],name:"windows-1258"},{labels:["x-mac-cyrillic","x-mac-ukrainian"],name:"x-mac-cyrillic"}],heading:"Legacy single-byte encodings"},{encodings:[{labels:["chinese","csgb2312","csiso58gb231280","gb2312","gb_2312","gb_2312-80","gbk","iso-ir-58","x-gbk"],name:"GBK"},{labels:["gb18030"],name:"gb18030"}],heading:"Legacy multi-byte Chinese (simplified) encodings"},{encodings:[{labels:["big5","big5-hkscs","cn-big5","csbig5","x-x-big5"],name:"Big5"}],heading:"Legacy multi-byte Chinese (traditional) encodings"},{encodings:[{labels:["cseucpkdfmtjapanese","euc-jp","x-euc-jp"],name:"EUC-JP"},{labels:["csiso2022jp","iso-2022-jp"],name:"ISO-2022-JP"},{labels:["csshiftjis","ms932","ms_kanji","shift-jis","shift_jis","sjis","windows-31j","x-sjis"],name:"Shift_JIS"}],heading:"Legacy multi-byte Japanese encodings"},{encodings:[{labels:["cseuckr","csksc56011987","euc-kr","iso-ir-149","korean","ks_c_5601-1987","ks_c_5601-1989","ksc5601","ksc_5601","windows-949"],name:"EUC-KR"}],heading:"Legacy multi-byte Korean encodings"},{encodings:[{labels:["csiso2022kr","hz-gb-2312","iso-2022-cn","iso-2022-cn-ext","iso-2022-kr"],name:"replacement"},{labels:["utf-16be"],name:"UTF-16BE"},{labels:["utf-16","utf-16le"],name:"UTF-16LE"},{labels:["x-user-defined"],name:"x-user-defined"}],heading:"Legacy miscellaneous encodings"}],d={},h=(n.forEach(function(n){n.encodings.forEach(function(e){e.labels.forEach(function(n){d[n]=e})})}),{}),g={};function y(n,e){return e&&e[n]||null}function p(n,e){e=e.indexOf(n);return-1===e?null:e}function v(n){if("encoding-indexes"in i)return i["encoding-indexes"][n];throw Error("Indexes missing. Did you forget to include encoding-indexes.js first?")}var x="utf-8";function O(n,e){if(!(this instanceof O))throw TypeError("Called as a function. Did you forget 'new'?");n=void 0!==n?String(n):x,e=s(e),this._encoding=null,this._decoder=null,this._ignoreBOM=!1,this._BOMseen=!1,this._error_mode="replacement",this._do_not_flush=!1;var i=r(n);if(null===i||"replacement"===i.name)throw RangeError("Unknown encoding: "+n);if(g[i.name])return(n=this)._encoding=i,Boolean(e.fatal)&&(n._error_mode="fatal"),Boolean(e.ignoreBOM)&&(n._ignoreBOM=!0),Object.defineProperty||(this.encoding=n._encoding.name.toLowerCase(),this.fatal="fatal"===n._error_mode,this.ignoreBOM=n._ignoreBOM),n;throw Error("Decoder not present. Did you forget to include encoding-indexes.js first?")}function k(n,e){if(!(this instanceof k))throw TypeError("Called as a function. Did you forget 'new'?");e=s(e),this._encoding=null,this._encoder=null,this._do_not_flush=!1,this._fatal=Boolean(e.fatal)?"fatal":"replacement";if(Boolean(e.NONSTANDARD_allowLegacyEncoding)){e=r(n=void 0!==n?String(n):x);if(null===e||"replacement"===e.name)throw RangeError("Unknown encoding: "+n);if(!h[e.name])throw Error("Encoder not present. Did you forget to include encoding-indexes.js first?");this._encoding=e}else this._encoding=r("utf-8"),void 0!==n&&"console"in i&&console.warn("TextEncoder constructor called with encoding label, which is ignored.");return Object.defineProperty||(this.encoding=this._encoding.name.toLowerCase()),this}function e(n){var r=n.fatal,t=0,o=0,s=0,l=128,a=191;this.handler=function(n,e){if(e===b&&0!==s)return s=0,m(r);if(e===b)return w;if(0===s){if(_(e,0,127))return e;if(_(e,194,223))s=1,t=31&e;else if(_(e,224,239))224===e&&(l=160),237===e&&(a=159),s=2,t=15&e;else{if(!_(e,240,244))return m(r);240===e&&(l=144),244===e&&(a=143),s=3,t=7&e}return null}var i;return _(e,l,a)?(l=128,a=191,t=t<<6|63&e,(o+=1)!==s?null:(i=t,t=s=o=0,i)):(t=s=o=0,l=128,a=191,n.prepend(e),m(r))}}function E(n){n.fatal;this.handler=function(n,e){if(e===b)return w;if(a(e))return e;_(e,128,2047)?(i=1,r=192):_(e,2048,65535)?(i=2,r=224):_(e,65536,1114111)&&(i=3,r=240);for(var i,r,t=[(e>>6*i)+r];0>6*(i-1)),--i;return t}}function j(i,n){var r=n.fatal;this.handler=function(n,e){return e===b?w:u(e)?e:null===(e=i[e-128])?m(r):e}}function B(r,n){n.fatal;this.handler=function(n,e){var i;return e===b?w:a(e)?e:(null===(i=p(e,r))&&f(e),i+128)}}function S(n){var o=n.fatal,s=0,l=0,a=0;this.handler=function(n,e){var i,r,t;return e===b&&0===s&&0===l&&0===a?w:(e!==b||0===s&&0===l&&0===a||(a=l=s=0,m(o)),0!==a?(i=null,_(e,48,57)&&(i=function(n){if(39419>8,n=255&n;return e?[i,n]:[n,i]}function L(r,n){var t=n.fatal,o=null,s=null;this.handler=function(n,e){var i;return e!==b||null===o&&null===s?e===b&&null===o&&null===s?w:null===o?(o=e,null):(e=r?(o<<8)+e:(e<<8)+o,(o=null)!==s?(i=s,s=null,_(e,56320,57343)?65536+1024*(i-55296)+(e-56320):(n.prepend(A(e,r)),m(t))):_(e,55296,56319)?(s=e,null):_(e,56320,57343)?m(t):e):m(t)}}function M(r,n){n.fatal;this.handler=function(n,e){var i;return e===b?w:_(e,0,65535)?A(e,r):(i=A(55296+(e-65536>>10),r),e=A(56320+(e-65536&1023),r),i.concat(e))}}function N(n){n.fatal;this.handler=function(n,e){return e===b?w:u(e)?e:63360+e-128}}function q(n){n.fatal;this.handler=function(n,e){return e===b?w:a(e)?e:_(e,63360,63487)?e-63360+128:f(e)}}Object.defineProperty&&(Object.defineProperty(O.prototype,"encoding",{get:function(){return this._encoding.name.toLowerCase()}}),Object.defineProperty(O.prototype,"fatal",{get:function(){return"fatal"===this._error_mode}}),Object.defineProperty(O.prototype,"ignoreBOM",{get:function(){return this._ignoreBOM}})),O.prototype.decode=function(n,e){n="object"==typeof n&&n instanceof ArrayBuffer?new Uint8Array(n):"object"==typeof n&&"buffer"in n&&n.buffer instanceof ArrayBuffer?new Uint8Array(n.buffer,n.byteOffset,n.byteLength):new Uint8Array(0);e=s(e),this._do_not_flush||(this._decoder=g[this._encoding.name]({fatal:"fatal"===this._error_mode}),this._BOMseen=!1),this._do_not_flush=Boolean(e.stream);for(var i,r=new c(n),t=[];;){var o=r.read();if(o===b)break;if((i=this._decoder.handler(r,o))===w)break;null!==i&&(Array.isArray(i)?t.push.apply(t,i):t.push(i))}if(!this._do_not_flush){for(;(i=this._decoder.handler(r,r.read()))!==w&&(null!==i&&(Array.isArray(i)?t.push.apply(t,i):t.push(i)),!r.endOfStream()););this._decoder=null}return function(n){e=["UTF-8","UTF-16LE","UTF-16BE"],i=this._encoding.name,-1===e.indexOf(i)||this._ignoreBOM||this._BOMseen||(0>10),56320+(1023&s)))}return t}.call(this,t)},Object.defineProperty&&Object.defineProperty(k.prototype,"encoding",{get:function(){return this._encoding.name.toLowerCase()}}),k.prototype.encode=function(n,e){n=void 0===n?"":String(n),e=s(e),this._do_not_flush||(this._encoder=h[this._encoding.name]({fatal:"fatal"===this._fatal})),this._do_not_flush=Boolean(e.stream);for(var i,r=new c(function(n){for(var e=String(n),i=e.length,r=0,t=[];r{i.symbol=Symbol.for("protobuf-ts/unknown"),i.onRead=(e,r,t,a,n)=>{(s(r)?r[i.symbol]:r[i.symbol]=[]).push({no:t,wireType:a,data:n})},i.onWrite=(e,r,t)=>{for(var{no:a,wireType:n,data:s}of i.list(r))t.tag(a,n).raw(s)},i.list=(e,r)=>{return s(e)?(e=e[i.symbol],r?e.filter(e=>e.no==r):e):[]},i.last=(e,r)=>(0,i.list)(e,r).slice(-1)[0];const s=e=>e&&Array.isArray(e[i.symbol])})(UnknownFieldHandler=UnknownFieldHandler||{});var UnknownFieldHandler,WireType=(e=>(e[e.Varint=0]="Varint",e[e.Bit64=1]="Bit64",e[e.LengthDelimited=2]="LengthDelimited",e[e.StartGroup=3]="StartGroup",e[e.EndGroup=4]="EndGroup",e[e.Bit32=5]="Bit32",e))(WireType||{});const MESSAGE_TYPE=Symbol.for("protobuf-ts/message-type");function lowerCamelCase(r){let t=!1;var a=[];for(let e=0;e(e[e.DOUBLE=1]="DOUBLE",e[e.FLOAT=2]="FLOAT",e[e.INT64=3]="INT64",e[e.UINT64=4]="UINT64",e[e.INT32=5]="INT32",e[e.FIXED64=6]="FIXED64",e[e.FIXED32=7]="FIXED32",e[e.BOOL=8]="BOOL",e[e.STRING=9]="STRING",e[e.BYTES=12]="BYTES",e[e.UINT32=13]="UINT32",e[e.SFIXED32=15]="SFIXED32",e[e.SFIXED64=16]="SFIXED64",e[e.SINT32=17]="SINT32",e[e.SINT64=18]="SINT64",e))(ScalarType||{}),LongType=(e=>(e[e.BIGINT=0]="BIGINT",e[e.STRING=1]="STRING",e[e.NUMBER=2]="NUMBER",e))(LongType||{}),RepeatType=(e=>(e[e.NO=0]="NO",e[e.PACKED=1]="PACKED",e[e.UNPACKED=2]="UNPACKED",e))(RepeatType||{});function normalizeFieldInfo(e){return e.localName=e.localName??lowerCamelCase(e.name),e.jsonName=e.jsonName??lowerCamelCase(e.name),e.repeat=e.repeat??0,e.opt=e.opt??(!e.repeat&&(!e.oneof&&"message"==e.kind)),e}function isOneofGroup(e){if("object"!=typeof e||null===e||!e.hasOwnProperty("oneofKind"))return!1;switch(typeof e.oneofKind){case"string":return void 0===e[e.oneofKind]?!1:2==Object.keys(e).length;case"undefined":return 1==Object.keys(e).length;default:return!1}}class ReflectionTypeCheck{constructor(e){this.fields=e.fields??[]}prepare(){if(!this.data){var e,r=[],t=[],a=[];for(e of this.fields)if(e.oneof)a.includes(e.oneof)||(a.push(e.oneof),r.push(e.oneof),t.push(e.oneof));else switch(t.push(e.localName),e.kind){case"scalar":case"enum":e.opt&&!e.repeat||r.push(e.localName);break;case"message":e.repeat&&r.push(e.localName);break;case"map":r.push(e.localName)}this.data={req:r,known:t,oneofs:Object.values(a)}}}is(e,a,n=!1){if(!(a<0)){if(null==e||"object"!=typeof e)return!1;this.prepare();let r=Object.keys(e),t=this.data;if(r.length!r.includes(e)))return!1;if(!n&&r.some(e=>!t.known.includes(e)))return!1;if(!(a<1)){for(const i of t.oneofs){const o=e[i];if(!isOneofGroup(o))return!1;if(void 0!==o.oneofKind){var s=this.fields.find(e=>e.localName===o.oneofKind);if(!s)return!1;if(!this.field(o[o.oneofKind],s,n,a))return!1}}for(const l of this.fields)if(void 0===l.oneof&&!this.field(e[l.localName],l,n,a))return!1}}return!0}field(e,r,t,a){var n=r.repeat;switch(r.kind){case"scalar":return void 0===e?r.opt:n?this.scalars(e,r.T,a,r.L):this.scalar(e,r.T,r.L);case"enum":return void 0===e?r.opt:n?this.scalars(e,ScalarType.INT32,a):this.scalar(e,ScalarType.INT32);case"message":return void 0===e?!0:n?this.messages(e,r.T(),t,a):this.message(e,r.T(),t,a);case"map":if("object"!=typeof e||null===e)return!1;if(a<2)return!0;if(!this.mapKeys(e,r.K,a))return!1;switch(r.V.kind){case"scalar":return this.scalars(Object.values(e),r.V.T,a,r.V.L);case"enum":return this.scalars(Object.values(e),ScalarType.INT32,a);case"message":return this.messages(Object.values(e),r.V.T(),t,a)}}return!0}message(e,r,t,a){return t?r.isAssignable(e,a):r.is(e,a)}messages(r,t,e,a){if(!Array.isArray(r))return!1;if(!(a<2))if(e){for(let e=0;eparseInt(e)),r,t);case ScalarType.BOOL:return this.scalars(a.slice(0,t).map(e=>"true"==e||"false"!=e&&e),r,t);default:return this.scalars(a,r,t,LongType.STRING)}}}function typeofJsonValue(e){var r=typeof e;if("object"==r){if(Array.isArray(e))return"array";if(null===e)return"null"}return r}function isJsonObject(e){return null!==e&&"object"==typeof e&&!Array.isArray(e)}let encTable="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),decTable=[];for(let e=0;e>4,i=s,n=2;break;case 2:t[a++]=(15&i)<<4|(60&s)>>2,i=s,n=3;break;case 3:t[a++]=(3&i)<<6|s,n=0}}if(1==n)throw Error("invalid base64 string.");return t.subarray(0,a)}function base64encode(r){let t="",a=0,n,s=0;for(let e=0;e>2],s=(3&n)<<4,a=1;break;case 1:t+=encTable[s|n>>4],s=(15&n)<<2,a=2;break;case 2:t=(t+=encTable[s|n>>6])+encTable[63&n],a=0}return a&&(t=t+encTable[s]+"=",1==a&&(t+="=")),t}function varint64read(){let r=0,t=0;for(let e=0;e<28;e+=7){var a=this.buf[this.pos++];if(r|=(127&a)<>4,0==(128&e))return this.assertBounds(),[r,t];for(let e=3;e<=31;e+=7){var n=this.buf[this.pos++];if(t|=(127&n)<>>e,s=!(n>>>7==0&&0==t);if(a.push(255&(s?128|n:n)),!s)return}var e=r>>>28&15|(7&t)<<4,i=!(t>>3==0);if(a.push(255&(i?128|e:e)),i){for(let e=3;e<31;e+=7){var o=t>>>e,l=!(o>>>7==0);if(a.push(255&(l?128|o:o)),!l)return}a.push(t>>>31&1)}}decTable["-".charCodeAt(0)]=encTable.indexOf("+"),decTable["_".charCodeAt(0)]=encTable.indexOf("/");const TWO_PWR_32_DBL$1=4294967296;function int64fromString(t){var e="-"==t[0];e&&(t=t.slice(1));let a=0,n=0;function r(e,r){e=Number(t.slice(e,r));n*=1e6,(a=1e6*a+e)>=TWO_PWR_32_DBL$1&&(n+=a/TWO_PWR_32_DBL$1|0,a%=TWO_PWR_32_DBL$1)}return r(-24,-18),r(-18,-12),r(-12,-6),r(-6),[e,a,n]}function int64toString(e,r){if(r<=2097151)return""+(TWO_PWR_32_DBL$1*r+(e>>>0));var t=(e>>>24|r<<8)>>>0&16777215,r=r>>16&65535;let a=(16777215&e)+6777216*t+6710656*r,n=t+8147497*r,s=2*r;function i(e,r){e=e?String(e):"";return r?"0000000".slice(e.length)+e:e}return 1e7<=a&&(n+=Math.floor(a/1e7),a%=1e7),1e7<=n&&(s+=Math.floor(n/1e7),n%=1e7),i(s,0)+i(n,s)+i(a,1)}function varint32write(r,t){if(0<=r){for(;127>>=7;t.push(r)}else{for(let e=0;e<9;e++)t.push(127&r|128),r>>=7;t.push(1)}}function varint32read(){let r=this.buf[this.pos++];var e=127&r;if(0==(128&r))return this.assertBounds(),e;if(e|=(127&(r=this.buf[this.pos++]))<<7,0==(128&r))return this.assertBounds(),e;if(e|=(127&(r=this.buf[this.pos++]))<<14,0==(128&r))return this.assertBounds(),e;if(e|=(127&(r=this.buf[this.pos++]))<<21,0==(128&r))return this.assertBounds(),e;e|=(15&(r=this.buf[this.pos++]))<<28;for(let e=5;0!=(128&r)&&e<10;e++)r=this.buf[this.pos++];if(0!=(128&r))throw new Error("invalid varint");return this.assertBounds(),e>>>0}function detectBi(){var e=new DataView(new ArrayBuffer(8));return void 0!==globalThis.BigInt&&"function"==typeof e.getBigInt64&&"function"==typeof e.getBigUint64&&"function"==typeof e.setBigInt64&&"function"==typeof e.setBigUint64?{MIN:BigInt("-9223372036854775808"),MAX:BigInt("9223372036854775807"),UMIN:BigInt("0"),UMAX:BigInt("18446744073709551615"),C:BigInt,V:e}:void 0}const BI=detectBi();function assertBi(e){if(!e)throw new Error("BigInt unavailable, see https://github.com/timostamm/protobuf-ts/blob/v1.0.8/MANUAL.md#bigint-support")}const RE_DECIMAL_STR=/^-?[0-9]+$/,TWO_PWR_32_DBL=4294967296;class SharedPbLong{constructor(e,r){this.lo=0|e,this.hi=0|r}isZero(){return 0==this.lo&&0==this.hi}toNumber(){var e=this.hi*TWO_PWR_32_DBL+(this.lo>>>0);if(Number.isSafeInteger(e))return e;throw new Error("cannot convert to safe number")}}const _PbULong=class extends SharedPbLong{static from(e){if(BI)switch(typeof e){case"string":if("0"==e)return this.ZERO;if(""==e)throw new Error("string is no integer");e=BI.C(e);case"number":if(0===e)return this.ZERO;e=BI.C(e);case"bigint":if(!e)return this.ZERO;if(eBI.UMAX)throw new Error("ulong too large");return BI.V.setBigUint64(0,e,!0),new _PbULong(BI.V.getInt32(0,!0),BI.V.getInt32(4,!0))}else switch(typeof e){case"string":if("0"==e)return this.ZERO;if(e=e.trim(),!RE_DECIMAL_STR.test(e))throw new Error("string is no integer");var[r,t,a]=int64fromString(e);if(r)throw new Error("signed value");return new _PbULong(t,a);case"number":if(0==e)return this.ZERO;if(!Number.isSafeInteger(e))throw new Error("number is no integer");if(e<0)throw new Error("signed value for ulong");return new _PbULong(e,e/TWO_PWR_32_DBL)}throw new Error("unknown value "+typeof e)}toString(){return BI?this.toBigInt().toString():int64toString(this.lo,this.hi)}toBigInt(){return assertBi(BI),BI.V.setInt32(0,this.lo,!0),BI.V.setInt32(4,this.hi,!0),BI.V.getBigUint64(0,!0)}};let PbULong=_PbULong;PbULong.ZERO=new _PbULong(0,0);const _PbLong=class extends SharedPbLong{static from(e){if(BI)switch(typeof e){case"string":if("0"==e)return this.ZERO;if(""==e)throw new Error("string is no integer");e=BI.C(e);case"number":if(0===e)return this.ZERO;e=BI.C(e);case"bigint":if(!e)return this.ZERO;if(eBI.MAX)throw new Error("ulong too large");return BI.V.setBigInt64(0,e,!0),new _PbLong(BI.V.getInt32(0,!0),BI.V.getInt32(4,!0))}else switch(typeof e){case"string":if("0"==e)return this.ZERO;var r,t,a;if(e=e.trim(),RE_DECIMAL_STR.test(e))return[r,a,t]=int64fromString(e),a=new _PbLong(a,t),r?a.negate():a;throw new Error("string is no integer");case"number":if(0==e)return this.ZERO;if(Number.isSafeInteger(e))return 0INT32_MAX||eUINT32_MAX||e<0)throw new Error("invalid uint 32: "+e)}function assertFloat32(e){if("number"!=typeof e)throw new Error("invalid float 32: "+typeof e);if(Number.isFinite(e)&&(e>FLOAT32_MAX||e[e.no,e])))}read(a,n,s,e){this.prepare();for(var r=void 0===e?a.len:a.pos+e;a.pose.no-r.no))}write(n,s,i){this.prepare();for(const u of this.fields){let e,r,t=u.repeat,a=u.localName;if(u.oneof){var o=n[u.oneof];if(o.oneofKind!==a)continue;e=o[a],r=!0}else e=n[a],r=!1;switch(u.kind){case"scalar":case"enum":var l="enum"==u.kind?ScalarType.INT32:u.T;if(t)if(assert(Array.isArray(e)),t==RepeatType.PACKED)this.packed(s,l,u.no,e);else for(const h of e)this.scalar(s,l,u.no,h,!0);else void 0===e?assert(u.opt):this.scalar(s,l,u.no,e,r||u.opt);break;case"message":if(t){assert(Array.isArray(e));for(const p of e)this.message(s,i,u.T(),u.no,p)}else this.message(s,i,u.T(),u.no,e);break;case"map":assert("object"==typeof e&&null!==e);for(var[c,f]of Object.entries(e))this.mapEntry(s,i,u,c,f)}}var e=i.writeUnknownFields;!1!==e&&(!0===e?UnknownFieldHandler.onWrite:e)(this.info.typeName,n,s)}mapEntry(e,r,t,a,n){e.tag(t.no,WireType.LengthDelimited),e.fork();let s=a;switch(t.K){case ScalarType.INT32:case ScalarType.FIXED32:case ScalarType.UINT32:case ScalarType.SFIXED32:case ScalarType.SINT32:s=Number.parseInt(a);break;case ScalarType.BOOL:assert("true"==a||"false"==a),s="true"==a}switch(this.scalar(e,t.K,1,s,!0),t.V.kind){case"scalar":this.scalar(e,t.V.T,2,n,!0);break;case"enum":this.scalar(e,ScalarType.INT32,2,n,!0);break;case"message":this.message(e,r,t.V.T(),2,n)}e.join()}message(e,r,t,a,n){void 0!==n&&(t.internalBinaryWrite(n,e.tag(a,WireType.LengthDelimited).fork(),r),e.join())}scalar(e,r,t,a,n){var[r,s,i]=this.scalarInfo(r,a);i&&!n||(e.tag(t,r),e[s](a))}packed(r,e,t,a){if(a.length){assert(e!==ScalarType.BYTES&&e!==ScalarType.STRING),r.tag(t,WireType.LengthDelimited),r.fork();var[,n]=this.scalarInfo(e);for(let e=0;enew BinaryWriter};function binaryWriteOptions(e){return e?{...defaultsWrite,...e}:defaultsWrite}class BinaryWriter{constructor(e){this.stack=[],this.textEncoder=e??new TextEncoder,this.chunks=[],this.buf=[]}finish(){this.chunks.push(new Uint8Array(this.buf));let r=0;for(let e=0;e>>0)}raw(e){return this.buf.length&&(this.chunks.push(new Uint8Array(this.buf)),this.buf=[]),this.chunks.push(e),this}uint32(e){for(assertUInt32(e);127>>=7;return this.buf.push(e),this}int32(e){return assertInt32(e),varint32write(e,this.buf),this}bool(e){return this.buf.push(e?1:0),this}bytes(e){return this.uint32(e.byteLength),this.raw(e)}string(e){e=this.textEncoder.encode(e);return this.uint32(e.byteLength),this.raw(e)}float(e){assertFloat32(e);var r=new Uint8Array(4);return new DataView(r.buffer).setFloat32(0,e,!0),this.raw(r)}double(e){var r=new Uint8Array(8);return new DataView(r.buffer).setFloat64(0,e,!0),this.raw(r)}fixed32(e){assertUInt32(e);var r=new Uint8Array(4);return new DataView(r.buffer).setUint32(0,e,!0),this.raw(r)}sfixed32(e){assertInt32(e);var r=new Uint8Array(4);return new DataView(r.buffer).setInt32(0,e,!0),this.raw(r)}sint32(e){return assertInt32(e),varint32write(e=(e<<1^e>>31)>>>0,this.buf),this}sfixed64(e){var r=new Uint8Array(8),t=new DataView(r.buffer),e=PbLong.from(e);return t.setInt32(0,e.lo,!0),t.setInt32(4,e.hi,!0),this.raw(r)}fixed64(e){var r=new Uint8Array(8),t=new DataView(r.buffer),e=PbULong.from(e);return t.setInt32(0,e.lo,!0),t.setInt32(4,e.hi,!0),this.raw(r)}int64(e){e=PbLong.from(e);return varint64write(e.lo,e.hi,this.buf),this}sint64(e){var e=PbLong.from(e),r=e.hi>>31;return varint64write(e.lo<<1^r,(e.hi<<1|e.lo>>>31)^r,this.buf),this}uint64(e){e=PbULong.from(e);return varint64write(e.lo,e.hi,this.buf),this}}const defaultsRead={readUnknownField:!0,readerFactory:e=>new BinaryReader(e)};function binaryReadOptions(e){return e?{...defaultsRead,...e}:defaultsRead}class BinaryReader{constructor(e,r){this.varint64=varint64read,this.uint32=varint32read,this.buf=e,this.len=e.length,this.pos=0,this.view=new DataView(e.buffer,e.byteOffset,e.byteLength),this.textDecoder=r??new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0})}tag(){var e=this.uint32(),r=e>>>3,e=7&e;if(r<=0||e<0||5this.len)throw new RangeError("premature EOF")}int32(){return 0|this.uint32()}sint32(){var e=this.uint32();return e>>>1^-(1&e)}int64(){return new PbLong(...this.varint64())}uint64(){return new PbULong(...this.varint64())}sint64(){var[e,r]=this.varint64(),t=-(1&e),e=(e>>>1|(1&r)<<31)^t,r=r>>>1^t;return new PbLong(e,r)}bool(){var[e,r]=this.varint64();return 0!==e||0!==r}fixed32(){return this.view.getUint32((this.pos+=4)-4,!0)}sfixed32(){return this.view.getInt32((this.pos+=4)-4,!0)}fixed64(){return new PbULong(this.sfixed32(),this.sfixed32())}sfixed64(){return new PbLong(this.sfixed32(),this.sfixed32())}float(){return this.view.getFloat32((this.pos+=4)-4,!0)}double(){return this.view.getFloat64((this.pos+=8)-8,!0)}bytes(){var e=this.uint32(),r=this.pos;return this.pos+=e,this.assertBounds(),this.buf.subarray(r,r+e)}string(){return this.textDecoder.decode(this.bytes())}}class MessageType{constructor(e,r,t){this.defaultCheckDepth=16,this.typeName=e,this.fields=r.map(normalizeFieldInfo),this.options=t??{},this.refTypeCheck=new ReflectionTypeCheck(this),this.refJsonReader=new ReflectionJsonReader(this),this.refJsonWriter=new ReflectionJsonWriter(this),this.refBinReader=new ReflectionBinaryReader(this),this.refBinWriter=new ReflectionBinaryWriter(this)}create(e){var r=reflectionCreate(this);return void 0!==e&&reflectionMergePartial(this,r,e),r}clone(e){var r=this.create();return reflectionMergePartial(this,r,e),r}equals(e,r){return reflectionEquals(this,e,r)}is(e,r=this.defaultCheckDepth){return this.refTypeCheck.is(e,r,!1)}isAssignable(e,r=this.defaultCheckDepth){return this.refTypeCheck.is(e,r,!0)}mergePartial(e,r){reflectionMergePartial(this,e,r)}fromBinary(e,r){r=binaryReadOptions(r);return this.internalBinaryRead(r.readerFactory(e),e.byteLength,r)}fromJson(e,r){return this.internalJsonRead(e,jsonReadOptions(r))}fromJsonString(e,r){e=JSON.parse(e);return this.fromJson(e,r)}toJson(e,r){return this.internalJsonWrite(e,jsonWriteOptions(r))}toJsonString(e,r){e=this.toJson(e,r);return JSON.stringify(e,null,(null==r?void 0:r.prettySpaces)??0)}toBinary(e,r){r=binaryWriteOptions(r);return this.internalBinaryWrite(e,r.writerFactory(),r).finish()}internalJsonRead(e,r,t){if(null===e||"object"!=typeof e||Array.isArray(e))throw new Error(`Unable to parse message ${this.typeName} from JSON ${typeofJsonValue(e)}.`);return t=t??this.create(),this.refJsonReader.read(e,t,r),t}internalJsonWrite(e,r){return this.refJsonWriter.write(e,r)}internalBinaryWrite(e,r,t){return this.refBinWriter.write(e,r,t),r}internalBinaryRead(e,r,t,a){a=a??this.create();return this.refBinReader.read(e,a,t,r),a}} 44 | // https://github.com/emn178/js-md5 md5=i.md5=_ 45 | let md5;!function(){"use strict";function t(t){if(t)d[0]=d[16]=d[1]=d[2]=d[3]=d[4]=d[5]=d[6]=d[7]=d[8]=d[9]=d[10]=d[11]=d[12]=d[13]=d[14]=d[15]=0,this.blocks=d,this.buffer8=l;else if(a){var r=new ArrayBuffer(68);this.buffer8=new Uint8Array(r),this.blocks=new Uint32Array(r)}else this.blocks=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];this.h0=this.h1=this.h2=this.h3=this.start=this.bytes=this.hBytes=0,this.finalized=this.hashed=!1,this.first=!0}var r="input is invalid type",e="object"==typeof window,i=e?window:{};i.JS_MD5_NO_WINDOW&&(e=!1);var s=!e&&"object"==typeof self,h=!i.JS_MD5_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;h?i=global:s&&(i=self);var f=!i.JS_MD5_NO_COMMON_JS&&"object"==typeof module&&module.exports,o="function"==typeof define&&define.amd,a=!i.JS_MD5_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,n="0123456789abcdef".split(""),u=[128,32768,8388608,-2147483648],y=[0,8,16,24],c=["hex","array","digest","buffer","arrayBuffer","base64"],p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),d=[],l;if(a){var A=new ArrayBuffer(68);l=new Uint8Array(A),d=new Uint32Array(A)}!i.JS_MD5_NO_NODE_JS&&Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),!a||!i.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW&&ArrayBuffer.isView||(ArrayBuffer.isView=function(t){return"object"==typeof t&&t.buffer&&t.buffer.constructor===ArrayBuffer});var b=function(r){return function(e){return new t(!0).update(e)[r]()}},v=function(){var r=b("hex");h&&(r=w(r)),r.create=function(){return new t},r.update=function(t){return r.create().update(t)};for(var e=0;e>2]|=t[f]<>6,u[h++]=128|63&s):s<55296||s>=57344?(u[h++]=224|s>>12,u[h++]=128|s>>6&63,u[h++]=128|63&s):(s=65536+((1023&s)<<10|1023&t.charCodeAt(++f)),u[h++]=240|s>>18,u[h++]=128|s>>12&63,u[h++]=128|s>>6&63,u[h++]=128|63&s);else for(h=this.start;f>2]|=s<>2]|=(192|s>>6)<>2]|=(128|63&s)<=57344?(n[h>>2]|=(224|s>>12)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<>2]|=(240|s>>18)<>2]|=(128|s>>12&63)<>2]|=(128|s>>6&63)<>2]|=(128|63&s)<=64?(this.start=h-64,this.hash(),this.hashed=!0):this.start=h}return this.bytes>4294967295&&(this.hBytes+=this.bytes/4294967296<<0,this.bytes=this.bytes%4294967296),this}},t.prototype.finalize=function(){if(!this.finalized){this.finalized=!0;var t=this.blocks,r=this.lastByteIndex;t[r>>2]|=u[3&r],r>=56&&(this.hashed||this.hash(),t[0]=t[16],t[16]=t[1]=t[2]=t[3]=t[4]=t[5]=t[6]=t[7]=t[8]=t[9]=t[10]=t[11]=t[12]=t[13]=t[14]=t[15]=0),t[14]=this.bytes<<3,t[15]=this.hBytes<<3|this.bytes>>>29,this.hash()}},t.prototype.hash=function(){var t,r,e,i,s,h,f=this.blocks;this.first?r=((r=((t=((t=f[0]-680876937)<<7|t>>>25)-271733879<<0)^(e=((e=(-271733879^(i=((i=(-1732584194^2004318071&t)+f[1]-117830708)<<12|i>>>20)+t<<0)&(-271733879^t))+f[2]-1126478375)<<17|e>>>15)+i<<0)&(i^t))+f[3]-1316259209)<<22|r>>>10)+e<<0:(t=this.h0,r=this.h1,e=this.h2,r=((r+=((t=((t+=((i=this.h3)^r&(e^i))+f[0]-680876936)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[1]-389564586)<<12|i>>>20)+t<<0)&(t^r))+f[2]+606105819)<<17|e>>>15)+i<<0)&(i^t))+f[3]-1044525330)<<22|r>>>10)+e<<0),r=((r+=((t=((t+=(i^r&(e^i))+f[4]-176418897)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[5]+1200080426)<<12|i>>>20)+t<<0)&(t^r))+f[6]-1473231341)<<17|e>>>15)+i<<0)&(i^t))+f[7]-45705983)<<22|r>>>10)+e<<0,r=((r+=((t=((t+=(i^r&(e^i))+f[8]+1770035416)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[9]-1958414417)<<12|i>>>20)+t<<0)&(t^r))+f[10]-42063)<<17|e>>>15)+i<<0)&(i^t))+f[11]-1990404162)<<22|r>>>10)+e<<0,r=((r+=((t=((t+=(i^r&(e^i))+f[12]+1804603682)<<7|t>>>25)+r<<0)^(e=((e+=(r^(i=((i+=(e^t&(r^e))+f[13]-40341101)<<12|i>>>20)+t<<0)&(t^r))+f[14]-1502002290)<<17|e>>>15)+i<<0)&(i^t))+f[15]+1236535329)<<22|r>>>10)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[1]-165796510)<<5|t>>>27)+r<<0)^r))+f[6]-1069501632)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[11]+643717713)<<14|e>>>18)+i<<0)^i))+f[0]-373897302)<<20|r>>>12)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[5]-701558691)<<5|t>>>27)+r<<0)^r))+f[10]+38016083)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[15]-660478335)<<14|e>>>18)+i<<0)^i))+f[4]-405537848)<<20|r>>>12)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[9]+568446438)<<5|t>>>27)+r<<0)^r))+f[14]-1019803690)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[3]-187363961)<<14|e>>>18)+i<<0)^i))+f[8]+1163531501)<<20|r>>>12)+e<<0,r=((r+=((i=((i+=(r^e&((t=((t+=(e^i&(r^e))+f[13]-1444681467)<<5|t>>>27)+r<<0)^r))+f[2]-51403784)<<9|i>>>23)+t<<0)^t&((e=((e+=(t^r&(i^t))+f[7]+1735328473)<<14|e>>>18)+i<<0)^i))+f[12]-1926607734)<<20|r>>>12)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[5]-378558)<<4|t>>>28)+r<<0))+f[8]-2022574463)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[11]+1839030562)<<16|e>>>16)+i<<0))+f[14]-35309556)<<23|r>>>9)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[1]-1530992060)<<4|t>>>28)+r<<0))+f[4]+1272893353)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[7]-155497632)<<16|e>>>16)+i<<0))+f[10]-1094730640)<<23|r>>>9)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[13]+681279174)<<4|t>>>28)+r<<0))+f[0]-358537222)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[3]-722521979)<<16|e>>>16)+i<<0))+f[6]+76029189)<<23|r>>>9)+e<<0,r=((r+=((h=(i=((i+=((s=r^e)^(t=((t+=(s^i)+f[9]-640364487)<<4|t>>>28)+r<<0))+f[12]-421815835)<<11|i>>>21)+t<<0)^t)^(e=((e+=(h^r)+f[15]+530742520)<<16|e>>>16)+i<<0))+f[2]-995338651)<<23|r>>>9)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[0]-198630844)<<6|t>>>26)+r<<0)|~e))+f[7]+1126891415)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[14]-1416354905)<<15|e>>>17)+i<<0)|~t))+f[5]-57434055)<<21|r>>>11)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[12]+1700485571)<<6|t>>>26)+r<<0)|~e))+f[3]-1894986606)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[10]-1051523)<<15|e>>>17)+i<<0)|~t))+f[1]-2054922799)<<21|r>>>11)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[8]+1873313359)<<6|t>>>26)+r<<0)|~e))+f[15]-30611744)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[6]-1560198380)<<15|e>>>17)+i<<0)|~t))+f[13]+1309151649)<<21|r>>>11)+e<<0,r=((r+=((i=((i+=(r^((t=((t+=(e^(r|~i))+f[4]-145523070)<<6|t>>>26)+r<<0)|~e))+f[11]-1120210379)<<10|i>>>22)+t<<0)^((e=((e+=(t^(i|~r))+f[2]+718787259)<<15|e>>>17)+i<<0)|~t))+f[9]-343485551)<<21|r>>>11)+e<<0,this.first?(this.h0=t+1732584193<<0,this.h1=r-271733879<<0,this.h2=e-1732584194<<0,this.h3=i+271733878<<0,this.first=!1):(this.h0=this.h0+t<<0,this.h1=this.h1+r<<0,this.h2=this.h2+e<<0,this.h3=this.h3+i<<0)},t.prototype.hex=function(){this.finalize();var t=this.h0,r=this.h1,e=this.h2,i=this.h3;return n[t>>4&15]+n[15&t]+n[t>>12&15]+n[t>>8&15]+n[t>>20&15]+n[t>>16&15]+n[t>>28&15]+n[t>>24&15]+n[r>>4&15]+n[15&r]+n[r>>12&15]+n[r>>8&15]+n[r>>20&15]+n[r>>16&15]+n[r>>28&15]+n[r>>24&15]+n[e>>4&15]+n[15&e]+n[e>>12&15]+n[e>>8&15]+n[e>>20&15]+n[e>>16&15]+n[e>>28&15]+n[e>>24&15]+n[i>>4&15]+n[15&i]+n[i>>12&15]+n[i>>8&15]+n[i>>20&15]+n[i>>16&15]+n[i>>28&15]+n[i>>24&15]},t.prototype.toString=t.prototype.hex,t.prototype.digest=function(){this.finalize();var t=this.h0,r=this.h1,e=this.h2,i=this.h3;return[255&t,t>>8&255,t>>16&255,t>>24&255,255&r,r>>8&255,r>>16&255,r>>24&255,255&e,e>>8&255,e>>16&255,e>>24&255,255&i,i>>8&255,i>>16&255,i>>24&255]},t.prototype.array=t.prototype.digest,t.prototype.arrayBuffer=function(){this.finalize();var t=new ArrayBuffer(16),r=new Uint32Array(t);return r[0]=this.h0,r[1]=this.h1,r[2]=this.h2,r[3]=this.h3,t},t.prototype.buffer=t.prototype.arrayBuffer,t.prototype.base64=function(){for(var t,r,e,i="",s=this.array(),h=0;h<15;)t=s[h++],r=s[h++],e=s[h++],i+=p[t>>>2]+p[63&(t<<4|r>>>4)]+p[63&(r<<2|e>>>6)]+p[63&e];return t=s[h],i+=p[t>>>2]+p[t<<4&63]+"=="};var _=v();f?module.exports=_:(md5=i.md5=_,o&&define(function(){return _}))}(); 46 | class ColorLyricsResponse$Type extends MessageType{constructor(){super("ColorLyricsResponse",[{no:1,name:"lyrics",kind:"message",T:()=>LyricsResponse}])}create(e){var n={};return globalThis.Object.defineProperty(n,MESSAGE_TYPE,{enumerable:!1,value:this}),void 0!==e&&reflectionMergePartial(this,n,e),n}internalBinaryRead(e,n,r,i){for(var a=null!=i?i:this.create(),t=e.pos+n;e.posLyricsLine},{no:9,name:"alternatives",kind:"message",repeat:1,T:()=>Alternative},{no:10,name:"language",kind:"scalar",T:9}])}create(e){var n={lines:[],alternatives:[],language:""};return globalThis.Object.defineProperty(n,MESSAGE_TYPE,{enumerable:!1,value:this}),void 0!==e&&reflectionMergePartial(this,n,e),n}internalBinaryRead(e,n,r,i){for(var a=null!=i?i:this.create(),t=e.pos+n;e.pos item.split('='))); 60 | Object.assign(options, params); 61 | } catch (error) { 62 | commonApi.msg(notifyName, '$argument解析失败', $argument); 63 | } 64 | } 65 | const {appid, securityKey} = options; 66 | //console.log(`appid:${appid},securityKey:${securityKey}`); 67 | 68 | const query = colorLyricsResponseObj.lyrics.lines 69 | .map(x => x.words) 70 | .filter(words => words && words !== '♪') 71 | .filter((v, i, a) => a.indexOf(v) === i) 72 | .join('\n'); 73 | const salt = Date.now(); 74 | const queryObj = { 75 | q: query, 76 | from: 'auto', 77 | to: 'zh', 78 | appid, 79 | salt, 80 | sign: md5(appid + query + salt + securityKey) 81 | } 82 | const requestBody = Object.entries(queryObj) 83 | .map(([k, v]) => `${k}=${encodeURIComponent(v)}`) 84 | .join('&'); 85 | 86 | // 调用翻译 87 | commonApi.post({ 88 | url: "https://fanyi-api.baidu.com/api/trans/vip/translate", 89 | body: requestBody, 90 | headers: { 91 | 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' 92 | }, 93 | }, (error, response, data) => { 94 | if(error){ 95 | commonApi.msg(notifyName, '百度翻译', `error错误${error}`); 96 | $done({}); 97 | } else if(response.status !== 200){ 98 | commonApi.msg(notifyName, '百度翻译', `响应不为200:${response.status}`); 99 | $done({}); 100 | } else { 101 | const baiduResult = JSON.parse(data); 102 | if(baiduResult.error_code){ 103 | commonApi.msg(notifyName, '百度翻译', `翻译错误,请检查appid和密钥配置:"${data}`); 104 | $done({}); 105 | } else { 106 | console.log('翻译成功'); 107 | // 因为采用了批量翻译,如果歌词为多种语言,只会翻译其中的一种语言 108 | const transArr = baiduResult.trans_result.filter(trans => trans.src !== trans.dst) 109 | .map(trans => [trans.src, trans.dst]); 110 | const transMap = new Map(transArr); 111 | colorLyricsResponseObj.lyrics.alternatives = [{ 112 | "language" : "z1", 113 | "lines" : colorLyricsResponseObj.lyrics.lines.map(line => line.words) 114 | .map(word => transMap.get(word) || word || '') 115 | }]; 116 | // 构造新数据 117 | const body = ColorLyricsResponse.toBinary(colorLyricsResponseObj); 118 | if(isQX){ 119 | $done({bodyBytes: body.buffer.slice(body.byteOffset, body.byteLength + body.byteOffset)}); 120 | } else { 121 | $done({body}); 122 | } 123 | } 124 | } 125 | }); 126 | } else { 127 | console.log('歌词为中文,无需翻译'); 128 | $done({}); 129 | } 130 | // https://github.com/chavyleung/scripts/blob/master/Env.min.js 131 | 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)} 132 | -------------------------------------------------------------------------------- /js/spotify-proto.js: -------------------------------------------------------------------------------- 1 | let protobuf;!function(g){"use strict";!function(r,e,t){var i=function t(i){var n=e[i];return n||r[i][0].call(n=e[i]={exports:{}},t,n,n.exports),n.exports}(t[0]);protobuf=i.util.global.protobuf=i,"function"==typeof define&&define.amd&&define(["long"],function(t){return t&&t.isLong&&(i.util.Long=t,i.configure()),i}),"object"==typeof module&&module&&module.exports&&(module.exports=i)}({1:[function(t,i,n){i.exports=function(t,i){var n=Array(arguments.length-1),s=0,r=2,u=!0;for(;r>2],r=(3&h)<<4,o=1;break;case 1:s[u++]=f[r|h>>4],r=(15&h)<<2,o=2;break;case 2:s[u++]=f[r|h>>6],s[u++]=f[63&h],o=0}8191>4,r=o,s=2;break;case 2:i[n++]=(15&r)<<4|(60&o)>>2,r=o,s=3;break;case 3:i[n++]=(3&r)<<6|o,s=0}}if(1===s)throw Error(c);return n-e},n.test=function(t){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(t)}},{}],3:[function(t,i,n){function a(i,n){"string"==typeof i&&(n=i,i=g);var h=[];function f(t){if("string"!=typeof t){var i=c();if(a.verbose&&console.log("codegen: "+i),i="return "+i,t){for(var n=Object.keys(t),r=Array(n.length+1),e=Array(n.length),s=0;s>>0:i<11754943508222875e-54?(e<<31|Math.round(i/1401298464324817e-60))>>>0:(e<<31|127+(t=Math.floor(Math.log(i)/Math.LN2))<<23|8388607&Math.round(i*Math.pow(2,-t)*8388608))>>>0,n,r)}function n(t,i,n){t=t(i,n),i=2*(t>>31)+1,n=t>>>23&255,t&=8388607;return 255==n?t?NaN:1/0*i:0==n?1401298464324817e-60*i*t:i*Math.pow(2,n-150)*(8388608+t)}function r(t,i,n){o[0]=t,i[n]=h[0],i[n+1]=h[1],i[n+2]=h[2],i[n+3]=h[3]}function e(t,i,n){o[0]=t,i[n]=h[3],i[n+1]=h[2],i[n+2]=h[1],i[n+3]=h[0]}function s(t,i){return h[0]=t[i],h[1]=t[i+1],h[2]=t[i+2],h[3]=t[i+3],o[0]}function u(t,i){return h[3]=t[i],h[2]=t[i+1],h[1]=t[i+2],h[0]=t[i+3],o[0]}var o,h,f,c,a;function l(t,i,n,r,e,s){var u,o=r<0?1:0;0===(r=o?-r:r)?(t(0,e,s+i),t(0<1/r?0:2147483648,e,s+n)):isNaN(r)?(t(0,e,s+i),t(2146959360,e,s+n)):17976931348623157e292>>0,e,s+n)):r<22250738585072014e-324?(t((u=r/5e-324)>>>0,e,s+i),t((o<<31|u/4294967296)>>>0,e,s+n)):(t(4503599627370496*(u=r*Math.pow(2,-(r=1024===(r=Math.floor(Math.log(r)/Math.LN2))?1023:r)))>>>0,e,s+i),t((o<<31|r+1023<<20|1048576*u&1048575)>>>0,e,s+n))}function d(t,i,n,r,e){i=t(r,e+i),t=t(r,e+n),r=2*(t>>31)+1,e=t>>>20&2047,n=4294967296*(1048575&t)+i;return 2047==e?n?NaN:1/0*r:0==e?5e-324*r*n:r*Math.pow(2,e-1075)*(n+4503599627370496)}function v(t,i,n){f[0]=t,i[n]=c[0],i[n+1]=c[1],i[n+2]=c[2],i[n+3]=c[3],i[n+4]=c[4],i[n+5]=c[5],i[n+6]=c[6],i[n+7]=c[7]}function b(t,i,n){f[0]=t,i[n]=c[7],i[n+1]=c[6],i[n+2]=c[5],i[n+3]=c[4],i[n+4]=c[3],i[n+5]=c[2],i[n+6]=c[1],i[n+7]=c[0]}function p(t,i){return c[0]=t[i],c[1]=t[i+1],c[2]=t[i+2],c[3]=t[i+3],c[4]=t[i+4],c[5]=t[i+5],c[6]=t[i+6],c[7]=t[i+7],f[0]}function y(t,i){return c[7]=t[i],c[6]=t[i+1],c[5]=t[i+2],c[4]=t[i+3],c[3]=t[i+4],c[2]=t[i+5],c[1]=t[i+6],c[0]=t[i+7],f[0]}return"undefined"!=typeof Float32Array?(o=new Float32Array([-0]),h=new Uint8Array(o.buffer),a=128===h[3],t.writeFloatLE=a?r:e,t.writeFloatBE=a?e:r,t.readFloatLE=a?s:u,t.readFloatBE=a?u:s):(t.writeFloatLE=i.bind(null,m),t.writeFloatBE=i.bind(null,w),t.readFloatLE=n.bind(null,g),t.readFloatBE=n.bind(null,j)),"undefined"!=typeof Float64Array?(f=new Float64Array([-0]),c=new Uint8Array(f.buffer),a=128===c[7],t.writeDoubleLE=a?v:b,t.writeDoubleBE=a?b:v,t.readDoubleLE=a?p:y,t.readDoubleBE=a?y:p):(t.writeDoubleLE=l.bind(null,m,0,4),t.writeDoubleBE=l.bind(null,w,4,0),t.readDoubleLE=d.bind(null,g,0,4),t.readDoubleBE=d.bind(null,j,4,0)),t}function m(t,i,n){i[n]=255&t,i[n+1]=t>>>8&255,i[n+2]=t>>>16&255,i[n+3]=t>>>24}function w(t,i,n){i[n]=t>>>24,i[n+1]=t>>>16&255,i[n+2]=t>>>8&255,i[n+3]=255&t}function g(t,i){return(t[i]|t[i+1]<<8|t[i+2]<<16|t[i+3]<<24)>>>0}function j(t,i){return(t[i]<<24|t[i+1]<<16|t[i+2]<<8|t[i+3])>>>0}i.exports=r(r)},{}],7:[function(t,i,n){function r(t){try{var i=eval("require")(t);if(i&&(i.length||Object.keys(i).length))return i}catch(t){}return null}i.exports=r},{}],8:[function(t,i,n){var e=n.isAbsolute=function(t){return/^(?:\/|\w+:)/.test(t)},r=n.normalize=function(t){var i=(t=t.replace(/\\/g,"/").replace(/\/{2,}/g,"/")).split("/"),n=e(t),t="";n&&(t=i.shift()+"/");for(var r=0;r>>1,s=null,u=r;return function(t){if(t<1||e>10),s[u++]=56320+(1023&r)):s[u++]=(15&r)<<12|(63&t[i++])<<6|63&t[i++],8191>6|192:(55296==(64512&r)&&56320==(64512&(e=t.charCodeAt(u+1)))?(++u,i[n++]=(r=65536+((1023&r)<<10)+(1023&e))>>18|240,i[n++]=r>>12&63|128):i[n++]=r>>12|224,i[n++]=r>>6&63|128),i[n++]=63&r|128);return n-s}},{}],11:[function(t,i,n){var l=t(14),d=t(33);function u(t,i,n,r){var e=!1;if(i.resolvedType)if(i.resolvedType instanceof l){t("switch(d%s){",r);for(var s=i.resolvedType.values,u=Object.keys(s),o=0;o>>0",r,r);break;case"int32":case"sint32":case"sfixed32":t("m%s=d%s|0",r,r);break;case"uint64":h=!0;case"int64":case"sint64":case"fixed64":case"sfixed64":t("if(util.Long)")("(m%s=util.Long.fromValue(d%s)).unsigned=%j",r,r,h)('else if(typeof d%s==="string")',r)("m%s=parseInt(d%s,10)",r,r)('else if(typeof d%s==="number")',r)("m%s=d%s",r,r)('else if(typeof d%s==="object")',r)("m%s=new util.LongBits(d%s.low>>>0,d%s.high>>>0).toNumber(%s)",r,r,r,h?"true":"");break;case"bytes":t('if(typeof d%s==="string")',r)("util.base64.decode(d%s,m%s=util.newBuffer(util.base64.length(d%s)),0)",r,r,r)("else if(d%s.length >= 0)",r)("m%s=d%s",r,r);break;case"string":t("m%s=String(d%s)",r,r);break;case"bool":t("m%s=Boolean(d%s)",r,r)}}return t}function v(t,i,n,r){if(i.resolvedType)i.resolvedType instanceof l?t("d%s=o.enums===String?(types[%i].values[m%s]===undefined?m%s:types[%i].values[m%s]):m%s",r,n,r,r,n,r,r):t("d%s=types[%i].toObject(m%s,o)",r,n,r);else{var e=!1;switch(i.type){case"double":case"float":t("d%s=o.json&&!isFinite(m%s)?String(m%s):m%s",r,r,r,r);break;case"uint64":e=!0;case"int64":case"sint64":case"fixed64":case"sfixed64":t('if(typeof m%s==="number")',r)("d%s=o.longs===String?String(m%s):m%s",r,r,r)("else")("d%s=o.longs===String?util.Long.prototype.toString.call(m%s):o.longs===Number?new util.LongBits(m%s.low>>>0,m%s.high>>>0).toNumber(%s):m%s",r,r,r,r,e?"true":"",r);break;case"bytes":t("d%s=o.bytes===String?util.base64.encode(m%s,0,m%s.length):o.bytes===Array?Array.prototype.slice.call(m%s):m%s",r,r,r,r,r);break;default:t("d%s=m%s",r,r)}}return t}n.fromObject=function(t){var i=t.fieldsArray,n=d.codegen(["d"],t.name+"$fromObject")("if(d instanceof this.ctor)")("return d");if(!i.length)return n("return new this.ctor");n("var m=new this.ctor");for(var r=0;r>>3){");for(var n=0;n>>3){")("case 1: k=r.%s(); break",r.keyType)("case 2:"),h.basic[e]===g?i("value=types[%i].decode(r,r.uint32())",n):i("value=r.%s()",e),i("break")("default:")("r.skipType(tag2&7)")("break")("}")("}"),h.long[r.keyType]!==g?i('%s[typeof k==="object"?util.longToHash(k):k]=value',s):i("%s[k]=value",s)):r.repeated?(i("if(!(%s&&%s.length))",s,s)("%s=[]",s),h.packed[e]!==g&&i("if((t&7)===2){")("var c2=r.uint32()+r.pos")("while(r.pos>>0,8|c.mapKey[s.keyType],s.keyType),h===g?n("types[%i].encode(%s[ks[i]],w.uint32(18).fork()).ldelim().ldelim()",u,i):n(".uint32(%i).%s(%s[ks[i]]).ldelim()",16|h,o,i),n("}")("}")):s.repeated?(n("if(%s!=null&&%s.length){",i,i),s.packed&&c.packed[o]!==g?n("w.uint32(%i).fork()",(s.id<<3|2)>>>0)("for(var i=0;i<%s.length;++i)",i)("w.%s(%s[i])",o,i)("w.ldelim()"):(n("for(var i=0;i<%s.length;++i)",i),h===g?l(n,s,u,i+"[i]"):n("w.uint32(%i).%s(%s[i])",(s.id<<3|h)>>>0,o,i)),n("}")):(s.optional&&n("if(%s!=null&&Object.hasOwnProperty.call(m,%j))",i,s.name),h===g?l(n,s,u,i):n("w.uint32(%i).%s(%s)",(s.id<<3|h)>>>0,o,i))}return n("return w")};var f=t(14),c=t(32),a=t(33);function l(t,i,n,r){i.resolvedType.group?t("types[%i].encode(%s,w.uint32(%i)).uint32(%i)",n,r,(i.id<<3|3)>>>0,(i.id<<3|4)>>>0):t("types[%i].encode(%s,w.uint32(%i).fork()).ldelim()",n,r,(i.id<<3|2)>>>0)}},{14:14,32:32,33:33}],14:[function(t,i,n){i.exports=s;var h=t(22),r=(((s.prototype=Object.create(h.prototype)).constructor=s).className="Enum",t(21)),e=t(33);function s(t,i,n,r,e,s){if(h.call(this,t,n),i&&"object"!=typeof i)throw TypeError("values must be an object");if(this.valuesById={},this.values=Object.create(this.valuesById),this.comment=r,this.comments=e||{},this.valuesOptions=s,this.reserved=g,i)for(var u=Object.keys(i),o=0;oi)return!0;return!1},a.isReservedName=function(t,i){if(t)for(var n=0;n "+t.len)}function h(t){this.buf=t,this.pos=0,this.len=t.length}function f(){return e.Buffer?function(t){return(h.create=function(t){return e.Buffer.isBuffer(t)?new r(t):a(t)})(t)}:a}var c,a="undefined"!=typeof Uint8Array?function(t){if(t instanceof Uint8Array||Array.isArray(t))return new h(t);throw Error("illegal buffer")}:function(t){if(Array.isArray(t))return new h(t);throw Error("illegal buffer")};function l(){var t=new s(0,0),i=0;if(!(4=this.len)throw o(this);if(t.lo=(t.lo|(127&this.buf[this.pos])<<7*i)>>>0,this.buf[this.pos++]<128)return t}return t.lo=(t.lo|(127&this.buf[this.pos++])<<7*i)>>>0,t}for(;i<4;++i)if(t.lo=(t.lo|(127&this.buf[this.pos])<<7*i)>>>0,this.buf[this.pos++]<128)return t;if(t.lo=(t.lo|(127&this.buf[this.pos])<<28)>>>0,t.hi=(t.hi|(127&this.buf[this.pos])>>4)>>>0,this.buf[this.pos++]<128)return t;if(i=0,4>>0,this.buf[this.pos++]<128)return t}else for(;i<5;++i){if(this.pos>=this.len)throw o(this);if(t.hi=(t.hi|(127&this.buf[this.pos])<<7*i+3)>>>0,this.buf[this.pos++]<128)return t}throw Error("invalid varint encoding")}function d(t,i){return(t[i-4]|t[i-3]<<8|t[i-2]<<16|t[i-1]<<24)>>>0}function v(){if(this.pos+8>this.len)throw o(this,8);return new s(d(this.buf,this.pos+=4),d(this.buf,this.pos+=4))}h.create=f(),h.prototype.h=e.Array.prototype.subarray||e.Array.prototype.slice,h.prototype.uint32=(c=4294967295,function(){if(c=(127&this.buf[this.pos])>>>0,this.buf[this.pos++]<128||(c=(c|(127&this.buf[this.pos])<<7)>>>0,this.buf[this.pos++]<128||(c=(c|(127&this.buf[this.pos])<<14)>>>0,this.buf[this.pos++]<128||(c=(c|(127&this.buf[this.pos])<<21)>>>0,this.buf[this.pos++]<128||(c=(c|(15&this.buf[this.pos])<<28)>>>0,this.buf[this.pos++]<128||!((this.pos+=5)>this.len))))))return c;throw this.pos=this.len,o(this,10)}),h.prototype.int32=function(){return 0|this.uint32()},h.prototype.sint32=function(){var t=this.uint32();return t>>>1^-(1&t)|0},h.prototype.bool=function(){return 0!==this.uint32()},h.prototype.fixed32=function(){if(this.pos+4>this.len)throw o(this,4);return d(this.buf,this.pos+=4)},h.prototype.sfixed32=function(){if(this.pos+4>this.len)throw o(this,4);return 0|d(this.buf,this.pos+=4)},h.prototype.float=function(){if(this.pos+4>this.len)throw o(this,4);var t=e.float.readFloatLE(this.buf,this.pos);return this.pos+=4,t},h.prototype.double=function(){if(this.pos+8>this.len)throw o(this,4);var t=e.float.readDoubleLE(this.buf,this.pos);return this.pos+=8,t},h.prototype.bytes=function(){var t=this.uint32(),i=this.pos,n=this.pos+t;if(n>this.len)throw o(this,t);return this.pos+=t,Array.isArray(this.buf)?this.buf.slice(i,n):i===n?new this.buf.constructor(0):this.h.call(this.buf,i,n)},h.prototype.string=function(){var t=this.bytes();return u.read(t,0,t.length)},h.prototype.skip=function(t){if("number"==typeof t){if(this.pos+t>this.len)throw o(this,t);this.pos+=t}else do{if(this.pos>=this.len)throw o(this)}while(128&this.buf[this.pos++]);return this},h.prototype.skipType=function(t){switch(t){case 0:this.skip();break;case 1:this.skip(8);break;case 2:this.skip(this.uint32());break;case 3:for(;4!=(t=7&this.uint32());)this.skipType(t);break;case 5:this.skip(4);break;default:throw Error("invalid wire type "+t+" at offset "+this.pos)}return this},h.r=function(t){r=t,h.create=f(),r.r();var i=e.Long?"toLong":"toNumber";e.merge(h.prototype,{int64:function(){return l.call(this)[i](!1)},uint64:function(){return l.call(this)[i](!0)},sint64:function(){return l.call(this).zzDecode()[i](!1)},fixed64:function(){return v.call(this)[i](!0)},sfixed64:function(){return v.call(this)[i](!1)}})}},{35:35}],25:[function(t,i,n){i.exports=s;var r=t(24),e=((s.prototype=Object.create(r.prototype)).constructor=s,t(35));function s(t){r.call(this,t)}s.r=function(){e.Buffer&&(s.prototype.h=e.Buffer.prototype.slice)},s.prototype.string=function(){var t=this.uint32();return this.buf.utf8Slice?this.buf.utf8Slice(this.pos,this.pos=Math.min(this.pos+t,this.len)):this.buf.toString("utf-8",this.pos,this.pos=Math.min(this.pos+t,this.len))},s.r()},{24:24,35:35}],26:[function(t,i,n){i.exports=h;var r,d,v,e=t(21),s=(((h.prototype=Object.create(e.prototype)).constructor=h).className="Root",t(15)),u=t(14),o=t(23),b=t(33);function h(t){e.call(this,"",t),this.deferred=[],this.files=[]}function p(){}h.fromJSON=function(t,i){return i=i||new h,t.options&&i.setOptions(t.options),i.addJSON(t.nested)},h.prototype.resolvePath=b.path.resolve,h.prototype.fetch=b.fetch,h.prototype.load=function t(i,s,e){"function"==typeof s&&(e=s,s=g);var u=this;if(!e)return b.asPromise(t,u,i,s);var o=e===p;function h(t,i){if(e){var n=e;if(e=null,o)throw t;n(t,i)}}function f(t){var i=t.lastIndexOf("google/protobuf/");if(-1>>0,this.hi=i>>>0}var s=e.zero=new e(0,0),u=(s.toNumber=function(){return 0},s.zzEncode=s.zzDecode=function(){return this},s.length=function(){return 1},e.zeroHash="\0\0\0\0\0\0\0\0",e.fromNumber=function(t){var i,n;return 0===t?s:(n=(t=(i=t<0)?-t:t)>>>0,t=(t-n)/4294967296>>>0,i&&(t=~t>>>0,n=~n>>>0,4294967295<++n&&(n=0,4294967295<++t&&(t=0))),new e(n,t))},e.from=function(t){if("number"==typeof t)return e.fromNumber(t);if(r.isString(t)){if(!r.Long)return e.fromNumber(parseInt(t,10));t=r.Long.fromString(t)}return t.low||t.high?new e(t.low>>>0,t.high>>>0):s},e.prototype.toNumber=function(t){var i;return!t&&this.hi>>>31?(t=1+~this.lo>>>0,i=~this.hi>>>0,-(t+4294967296*(i=t?i:i+1>>>0))):this.lo+4294967296*this.hi},e.prototype.toLong=function(t){return r.Long?new r.Long(0|this.lo,0|this.hi,!!t):{low:0|this.lo,high:0|this.hi,unsigned:!!t}},String.prototype.charCodeAt);e.fromHash=function(t){return"\0\0\0\0\0\0\0\0"===t?s:new e((u.call(t,0)|u.call(t,1)<<8|u.call(t,2)<<16|u.call(t,3)<<24)>>>0,(u.call(t,4)|u.call(t,5)<<8|u.call(t,6)<<16|u.call(t,7)<<24)>>>0)},e.prototype.toHash=function(){return String.fromCharCode(255&this.lo,this.lo>>>8&255,this.lo>>>16&255,this.lo>>>24,255&this.hi,this.hi>>>8&255,this.hi>>>16&255,this.hi>>>24)},e.prototype.zzEncode=function(){var t=this.hi>>31;return this.hi=((this.hi<<1|this.lo>>>31)^t)>>>0,this.lo=(this.lo<<1^t)>>>0,this},e.prototype.zzDecode=function(){var t=-(1&this.lo);return this.lo=((this.lo>>>1|this.hi<<31)^t)>>>0,this.hi=(this.hi>>>1^t)>>>0,this},e.prototype.length=function(){var t=this.lo,i=(this.lo>>>28|this.hi<<4)>>>0,n=this.hi>>>24;return 0==n?0==i?t<16384?t<128?1:2:t<2097152?3:4:i<16384?i<128?5:6:i<2097152?7:8:n<128?9:10}},{35:35}],35:[function(t,i,n){var r=n;function e(t,i,n){for(var r=Object.keys(i),e=0;e>>7|t.hi<<25)>>>0,t.hi>>>=7;for(;127>>7;i[n++]=t.lo}function p(t,i,n){i[n]=255&t,i[n+1]=t>>>8&255,i[n+2]=t>>>16&255,i[n+3]=t>>>24}a.create=l(),a.alloc=function(t){return new e.Array(t)},e.Array!==Array&&(a.alloc=e.pool(a.alloc,e.Array.prototype.subarray)),a.prototype.p=function(t,i,n){return this.tail=this.tail.next=new h(t,i,n),this.len+=i,this},(v.prototype=Object.create(h.prototype)).fn=function(t,i,n){for(;127>>=7;i[n]=t},a.prototype.uint32=function(t){return this.len+=(this.tail=this.tail.next=new v((t>>>=0)<128?1:t<16384?2:t<2097152?3:t<268435456?4:5,t)).len,this},a.prototype.int32=function(t){return t<0?this.p(b,10,s.fromNumber(t)):this.uint32(t)},a.prototype.sint32=function(t){return this.uint32((t<<1^t>>31)>>>0)},a.prototype.int64=a.prototype.uint64=function(t){t=s.from(t);return this.p(b,t.length(),t)},a.prototype.sint64=function(t){t=s.from(t).zzEncode();return this.p(b,t.length(),t)},a.prototype.bool=function(t){return this.p(d,1,t?1:0)},a.prototype.sfixed32=a.prototype.fixed32=function(t){return this.p(p,4,t>>>0)},a.prototype.sfixed64=a.prototype.fixed64=function(t){t=s.from(t);return this.p(p,4,t.lo).p(p,4,t.hi)},a.prototype.float=function(t){return this.p(e.float.writeFloatLE,4,t)},a.prototype.double=function(t){return this.p(e.float.writeDoubleLE,8,t)};var y=e.Array.prototype.set?function(t,i,n){i.set(t,n)}:function(t,i,n){for(var r=0;r>>0;return n?(e.isString(t)&&(i=a.alloc(n=u.length(t)),u.decode(t,i,0),t=i),this.uint32(n).p(y,n,t)):this.p(d,1,0)},a.prototype.string=function(t){var i=o.length(t);return i?this.uint32(i).p(o.write,i,t):this.p(d,1,0)},a.prototype.fork=function(){return this.states=new c(this),this.head=this.tail=new h(f,0,0),this.len=0,this},a.prototype.reset=function(){return this.states?(this.head=this.states.head,this.tail=this.states.tail,this.len=this.states.len,this.states=this.states.next):(this.head=this.tail=new h(f,0,0),this.len=0),this},a.prototype.ldelim=function(){var t=this.head,i=this.tail,n=this.len;return this.reset().uint32(n),n&&(this.tail.next=t.next,this.tail=i,this.len+=n),this},a.prototype.finish=function(){for(var t=this.head.next,i=this.constructor.alloc(this.len),n=0;t;)t.fn(t.val,i,n),n+=t.len,t=t.next;return i},a.r=function(t){r=t,a.create=l(),r.r()}},{35:35}],39:[function(t,i,n){i.exports=s;var r=t(38),e=((s.prototype=Object.create(r.prototype)).constructor=s,t(35));function s(){r.call(this)}function u(t,i,n){t.length<40?e.utf8.write(t,i,n):i.utf8Write?i.utf8Write(t,n):i.write(t,n)}s.r=function(){s.alloc=e.b,s.writeBytesBuffer=e.Buffer&&e.Buffer.prototype instanceof Uint8Array&&"set"===e.Buffer.prototype.set.name?function(t,i,n){i.set(t,n)}:function(t,i,n){if(t.copy)t.copy(i,n,0,t.length);else for(var r=0;r>>0;return this.uint32(i),i&&this.p(s.writeBytesBuffer,i,t),this},s.prototype.string=function(t){var i=e.Buffer.byteLength(t);return this.uint32(i),i&&this.p(u,i,t),this},s.r()},{35:35,38:38}]},{},[16])}(); 2 | const spotifyJson = {"options":{"java_package":"com.smile.spotify.model"},"nested":{"BootstrapResponse":{"oneofs":{"ucsResponse":{"oneof":["ucsResponseV0","trialsFacadeResponseV1"]}},"fields":{"ucsResponseV0":{"type":"UcsResponseWrapperV0","id":2},"trialsFacadeResponseV1":{"type":"TrialsFacadeResponseWrapperV1","id":3}}},"UcsResponseWrapperV0":{"oneofs":{"result":{"oneof":["success","error"]}},"fields":{"success":{"type":"UcsResponseWrapperSuccess","id":1},"error":{"type":"UcsResponseWrapperError","id":2}}},"UcsResponseWrapperSuccess":{"fields":{"customization":{"type":"UcsResponseWrapper","id":1}}},"UcsResponseWrapperError":{"fields":{"errorCode":{"type":"int32","id":1},"message":{"type":"string","id":2},"logId":{"type":"string","id":3}}},"TrialsFacadeResponseWrapperV1":{"oneofs":{"result":{"oneof":["success","error"]}},"fields":{"success":{"type":"TrialsFacadeResponseWrapperSuccess","id":1},"error":{"type":"TrialsFacadeResponseWrapperError","id":2}}},"TrialsFacadeResponseWrapperError":{"fields":{"errorCode":{"type":"int32","id":1},"message":{"type":"string","id":2},"logId":{"type":"string","id":3}}},"TrialsFacadeResponseWrapperSuccess":{"fields":{"field1":{"type":"int32","id":1}}},"UcsResponseWrapper":{"oneofs":{"result":{"oneof":["success","error"]}},"fields":{"success":{"type":"UcsResponse","id":1},"error":{"type":"Error","id":2}}},"UcsResponse":{"oneofs":{"resolveResult":{"oneof":["resolveSuccess","resolveError"]},"accountAttributesResult":{"oneof":["accountAttributesSuccess","accountAttributesError"]}},"fields":{"resolveSuccess":{"type":"ResolveResponse","id":1},"resolveError":{"type":"Error","id":2},"accountAttributesSuccess":{"type":"AccountAttributesResponse","id":3},"accountAttributesError":{"type":"Error","id":4},"fetchTimeMillis":{"type":"int64","id":5}}},"ResolveResponse":{"fields":{"configuration":{"type":"Configuration","id":1}}},"Configuration":{"fields":{"configurationAssignmentId":{"type":"string","id":1},"fetchTimeMillis":{"type":"int64","id":2},"assignedValues":{"rule":"repeated","type":"AssignedValue","id":3},"policySnapshotId":{"type":"int64","id":4}}},"AssignedValue":{"oneofs":{"structuredValue":{"oneof":["boolValue","intValue","enumValue"]}},"fields":{"propertyId":{"type":"Identifier","id":1},"metadata":{"type":"Metadata","id":2},"boolValue":{"type":"BoolValue","id":3},"intValue":{"type":"IntValue","id":4},"enumValue":{"type":"EnumValue","id":5}}},"Identifier":{"fields":{"scope":{"type":"string","id":1},"name":{"type":"string","id":2}}},"Metadata":{"fields":{"policyId":{"type":"int64","id":1},"externalRealm":{"type":"string","id":2},"externalRealmId":{"type":"int64","id":3}}},"BoolValue":{"fields":{"value":{"type":"bool","id":1}}},"EnumValue":{"fields":{"value":{"type":"string","id":1}}},"IntValue":{"fields":{"value":{"type":"int32","id":1}}},"AccountAttributesResponse":{"fields":{"accountAttributes":{"keyType":"string","type":"AccountAttribute","id":1}}},"AccountAttribute":{"oneofs":{"value":{"oneof":["boolValue","longValue","stringValue"]}},"fields":{"boolValue":{"type":"bool","id":2},"longValue":{"type":"int64","id":3},"stringValue":{"type":"string","id":4}}},"Error":{"fields":{"errorCode":{"type":"int32","id":1},"errorMessage":{"type":"string","id":2}}}}}; 3 | 4 | console.log(`2024-06-13`); 5 | const resStatus = $response.status ? $response.status : $response.statusCode; 6 | if(resStatus !== 200) { 7 | console.log(`$response.status不为200:${resStatus}`); 8 | $done({}); 9 | } else { 10 | const url = $request.url; 11 | const method = $request.method; 12 | const postMethod = "POST"; 13 | const isQuanX = typeof $task !== "undefined"; 14 | const binaryBody = isQuanX ? new Uint8Array($response.bodyBytes) : $response.body; 15 | let accountAttributesMapObj; 16 | let body; 17 | if(url.includes("bootstrap/v1/bootstrap") && method === postMethod){ 18 | let bootstrapResponseType = protobuf.Root.fromJSON(spotifyJson).lookupType("BootstrapResponse"); 19 | let bootstrapResponseObj = bootstrapResponseType.decode(binaryBody); 20 | accountAttributesMapObj = bootstrapResponseObj.ucsResponseV0.success.customization.success.accountAttributesSuccess.accountAttributes; 21 | processMapObj(accountAttributesMapObj); 22 | body = bootstrapResponseType.encode(bootstrapResponseObj).finish(); 23 | console.log('bootstrap'); 24 | } else if(url.includes("user-customization-service/v1/customize") && method === postMethod){ 25 | let ucsResponseWrapperType = protobuf.Root.fromJSON(spotifyJson).lookupType("UcsResponseWrapper"); 26 | let ucsResponseWrapperMessage = ucsResponseWrapperType.decode(binaryBody); 27 | accountAttributesMapObj = ucsResponseWrapperMessage.success.accountAttributesSuccess.accountAttributes; 28 | processMapObj(accountAttributesMapObj); 29 | body = ucsResponseWrapperType.encode(ucsResponseWrapperMessage).finish(); 30 | console.log('customize'); 31 | } else { 32 | $notification.post('spotify解锁premium', "路径/请求方法匹配错误:", method + "," + url); 33 | } 34 | // console.log(`${body.byteLength}---${body.buffer.byteLength}`); 35 | if(isQuanX){ 36 | $done({bodyBytes: body.buffer.slice(body.byteOffset, body.byteLength + body.byteOffset)}); 37 | } else { 38 | $done({body}); 39 | } 40 | } 41 | 42 | function processMapObj(accountAttributesMapObj){ 43 | accountAttributesMapObj['player-license'] = {stringValue : 'premium'}; 44 | accountAttributesMapObj['mobile'] = {boolValue : true}; 45 | accountAttributesMapObj['streaming-rules'] = {stringValue : ''}; 46 | accountAttributesMapObj['financial-product'] = {stringValue : 'pr:premium,tc:0'}; 47 | accountAttributesMapObj['license-acceptance-grace-days'] = {longValue : 30}; 48 | accountAttributesMapObj['mobile-login'] = {boolValue : true}; 49 | accountAttributesMapObj['name'] = {stringValue : 'Spotify Premium'}; 50 | accountAttributesMapObj['on-demand'] = {boolValue : true}; 51 | accountAttributesMapObj['ads'] = {boolValue : false}; 52 | accountAttributesMapObj['catalogue'] = {stringValue : 'premium'}; 53 | accountAttributesMapObj['high-bitrate'] = {boolValue : true}; 54 | accountAttributesMapObj['libspotify'] = {boolValue : true}; 55 | // 主页右下角的会员广告tab 56 | accountAttributesMapObj['nft-disabled'] = {stringValue : '1'}; 57 | accountAttributesMapObj['shuffle'] = {boolValue : false}; 58 | accountAttributesMapObj['audio-quality'] = {stringValue : '1'}; 59 | accountAttributesMapObj['offline'] = {boolValue : true}; 60 | accountAttributesMapObj['pause-after'] = {longValue : 0}; 61 | accountAttributesMapObj['can_use_superbird'] = {boolValue : true}; 62 | accountAttributesMapObj['type'] = {stringValue : 'premium'}; 63 | 64 | // vip新增的 65 | accountAttributesMapObj['loudness-levels'] = {stringValue : '1:-9.0,0.0,3.0:-2.0'}; 66 | accountAttributesMapObj['payments-initial-campaign'] = {stringValue : 'web'}; 67 | accountAttributesMapObj['shuffle-eligible'] = {boolValue : true}; 68 | accountAttributesMapObj['unrestricted'] = {boolValue : true}; 69 | // 儿童不宜 70 | // accountAttributesMapObj['filter-explicit-content'] = {boolValue : true}; 71 | // 决定customize是否有效 有的用户没有此属性 72 | accountAttributesMapObj['com.spotify.madprops.use.ucs.product.state'] = {boolValue : true}; 73 | 74 | delete accountAttributesMapObj['ad-use-adlogic']; 75 | delete accountAttributesMapObj['ad-catalogues']; 76 | 77 | // ab test 78 | // accountAttributesMapObj['ab-test-group'] = {longValue : 67}; 79 | // accountAttributesMapObj['ab-mobile-discover'] = {longValue : 0}; 80 | // accountAttributesMapObj['ab-navigation-menu'] = {longValue : 17}; 81 | // accountAttributesMapObj['ab-sugarpills-sanity-check'] = {stringValue : '0'}; 82 | // accountAttributesMapObj['ab-nft-navigation-menu'] = {stringValue : '3'}; 83 | // accountAttributesMapObj['ab-desktop-hide-follow'] = {boolValue : false}; 84 | 85 | // 不确定的字段 86 | // accountAttributesMapObj['social-session'] = {boolValue : true}; 87 | // accountAttributesMapObj['head-files-url'] = {stringValue : 'https://heads-fa.scdn.co/head/{file_id}'}; 88 | // accountAttributesMapObj['publish-playlist'] = {boolValue : true}; 89 | } 90 | -------------------------------------------------------------------------------- /js/spotify-qx-header.js: -------------------------------------------------------------------------------- 1 | let headers = $request.headers; 2 | delete headers['If-None-Match']; 3 | console.log('2025.03.20-qx-spotify删除请求头') 4 | $done({headers}); 5 | -------------------------------------------------------------------------------- /js/tieba-json.js: -------------------------------------------------------------------------------- 1 | const url = $request.url; 2 | const method = $request.method; 3 | const postMethod = "POST"; 4 | const notifyTitle = "贴吧json脚本错误"; 5 | console.log(`贴吧json-2024.10.20`); 6 | 7 | let body = JSON.parse($response.body); 8 | // 直接全局搜索 @Modify( 9 | if (url.includes("tiebaads/commonbatch") && method === postMethod) { 10 | // 看图模式下的广告 11 | let adCmd = getUrlParamValue(url, "adcmd"); 12 | if (!adCmd) { 13 | console.log(`url:${url}`); 14 | $notification.post(notifyTitle, "贴吧-tiebaads/commonbatch", "adCmd参数不存在"); 15 | } else { 16 | console.log(`commonbatch:${adCmd}`); 17 | if (body.error_code === 0) { 18 | if (!body.res.ad?.length) { 19 | console.log('ad字段为空'); 20 | } else { 21 | body.res.ad = []; 22 | // 即使ad有内容 也不一定显示广告 23 | // 因为如果服务器下发的数据少了一些字段同样是无广告的 24 | console.log('成功'); 25 | } 26 | } else { 27 | console.log('error_code不为0:' + body.error_code); 28 | } 29 | } 30 | } else if (url.includes('c/f/pb/picpage')) { 31 | console.log(`picpage`); 32 | const liveLength = body.recom_live_list?.length; 33 | if (liveLength) { 34 | console.log(`去除直播:${liveLength}`); 35 | body.recom_live_list = []; 36 | } 37 | } else if (url.includes('c/s/sync')) { 38 | // get post(贴吧使用了post)均可访问 39 | console.log('贴吧-sync'); 40 | if ('floating_icon' in body) { 41 | console.log('右下角悬浮icon'); 42 | if (body.floating_icon) { 43 | if (body.floating_icon.homepage?.icon_url) { 44 | console.log('homepage悬浮去除'); 45 | } else { 46 | console.log('无需去除homepage悬浮'); 47 | } 48 | if (body.floating_icon.pb?.icon_url) { 49 | console.log('pb悬浮去除'); 50 | } else { 51 | console.log('无需去除pb悬浮'); 52 | } 53 | body.floating_icon = null; 54 | } else { 55 | console.log('无需修改floating_icon字段值'); 56 | } 57 | } else { 58 | console.log(`body:${$response.body}`); 59 | $notification.post(notifyTitle, "贴吧-sync", "无floating_icon字段"); 60 | } 61 | 62 | // 回帖栏的广告 63 | if ('advertisement_config' in body) { 64 | if (!body.advertisement_config?.advertisement_str) { 65 | console.log('无需处理advertisement_config'); 66 | } else { 67 | console.log(`advertisement_str:${body.advertisement_config.advertisement_str}`); 68 | body.advertisement_config = null; 69 | } 70 | } else { 71 | console.log(`body:${$response.body}`); 72 | $notification.post(notifyTitle, "贴吧-sync", "无advertisement_config字段"); 73 | } 74 | 75 | if ('config' in body) { 76 | if (body.config?.switch) { 77 | for (const item of body.config.switch) { 78 | // 穿山甲/广点通/快手 79 | if (['platform_csj_init', 'platform_ks_init', 'platform_gdt_init', 80 | 'platform_baidu_bqt_init', 'platform_jy_init'].includes(item.name)) { 81 | if (item.type !== '0') { 82 | item.type = '0'; 83 | console.log(`禁止初始化${item.name}`); 84 | } 85 | } 86 | } 87 | } 88 | } else { 89 | console.log(`body:${$response.body}`); 90 | $notification.post(notifyTitle, "贴吧-sync", "无config字段"); 91 | } 92 | 93 | if ('screen_fill_data_result' in body) { 94 | if (body.screen_fill_data_result.screen_fill_advertisement_bear_switch === "1") { 95 | body.screen_fill_data_result.screen_fill_advertisement_bear_switch = '0'; 96 | console.log('开屏不展示小熊广告'); 97 | } else { 98 | console.log('无需修改screen_fill_advertisement_bear_switch'); 99 | } 100 | if (body.screen_fill_data_result.screen_fill_advertisement_plj_cpc_switch === "1") { 101 | body.screen_fill_data_result.screen_fill_advertisement_plj_cpc_switch = '0'; 102 | console.log('开屏不展示序章CPC'); 103 | } else { 104 | console.log('无需修改screen_fill_advertisement_plj_cpc_switch'); 105 | } 106 | if (body.screen_fill_data_result.screen_fill_advertisement_plj_switch === "1") { 107 | body.screen_fill_data_result.screen_fill_advertisement_plj_switch = '0'; 108 | console.log('开屏不展示序章'); 109 | } else { 110 | console.log('无需修改screen_fill_advertisement_plj_switch'); 111 | } 112 | } else { 113 | console.log(`body:${$response.body}`); 114 | $notification.post(notifyTitle, "贴吧-sync", "无screen_fill_data_result字段"); 115 | } 116 | 117 | if ('ad_stlog_switch' in body) { 118 | if (body.ad_stlog_switch === '1') { 119 | body.ad_stlog_switch = '0'; 120 | console.log('修改ad_stlog_switch'); 121 | } else { 122 | console.log('无需修改ad_stlog_switch'); 123 | } 124 | } else { 125 | console.log(`body:${$response.body}`); 126 | $notification.post(notifyTitle, "贴吧-sync", "无ad_stlog_switch字段"); 127 | } 128 | 129 | if ('lcs_strategy' in body) { 130 | // 控制长连接开关 开启时帖子会走socket 131 | if (body.lcs_strategy.conn_conf === '0') { 132 | // 关闭 133 | body.lcs_strategy.conn_conf = '1'; 134 | console.log('修改conn_conf'); 135 | } else { 136 | console.log('无需修改conn_conf'); 137 | } 138 | } else { 139 | console.log(`body:${$response.body}`); 140 | $notification.post(notifyTitle, "贴吧-sync", "无lcs_strategy字段"); 141 | } 142 | } else if (url.includes("c/f/frs/page")) { 143 | console.log('贴吧-FrsPage'); 144 | if (body.live_fuse_forum?.length) { 145 | body.live_fuse_forum = []; 146 | console.log(`去除吧头直播`); 147 | } else { 148 | console.log(`无需处理吧头直播`); 149 | } 150 | 151 | if (body.activityhead?.is_ad) { 152 | body.activityhead = {}; 153 | console.log('去除吧内header图片广告'); 154 | } else { 155 | console.log('无需处理activityhead'); 156 | } 157 | body.thread_list = removeLive(body.thread_list); 158 | removeGoodsInfo(body.forum?.banner_list?.app); 159 | } else if (url.includes("c/f/frs/threadlist")) { 160 | console.log('贴吧-threadlist'); 161 | removeGoodsInfo(body.banner_list?.app); 162 | } else if (url.includes("c/f/pb/page")) { 163 | console.log('贴吧-PbPage'); 164 | if (body.recom_ala_info?.live_id) { 165 | console.log('帖子详情页推荐的直播广告去除'); 166 | body.recom_ala_info = null; 167 | } else { 168 | console.log('帖子详情页无直播广告'); 169 | } 170 | 171 | if (body.post_list?.length) { 172 | for (const post of body.post_list) { 173 | if (post.outer_item) { 174 | console.log('outer_item去除'); 175 | post.outer_item = null; 176 | } 177 | } 178 | } else { 179 | console.log('无需处理postList中的outer_item'); 180 | } 181 | removeGoodsInfo(body.banner_list?.app); 182 | const bannerGoodsInfoLength = body.banner_list?.pb_banner_ad?.goods_info?.length; 183 | if (bannerGoodsInfoLength) { 184 | console.log(`去除pb_banner_ad的goods_info:${bannerGoodsInfoLength}`) 185 | body.banner_list.pb_banner_ad.goods_info = [] 186 | } 187 | } else if (url.includes("c/f/excellent/personalized")) { 188 | console.log('贴吧-personalized'); 189 | removeGoodsInfo(body.banner_list?.app); 190 | body.thread_list = removeLive(body.thread_list); 191 | if (body.live_answer) { 192 | console.log('去除推荐页上方的banner广告'); 193 | body.live_answer = null; 194 | } else { 195 | console.log('推荐页无banner广告'); 196 | } 197 | } else if (url.includes("c/f/frs/generalTabList")) { 198 | console.log('贴吧-generalTabList'); 199 | removeGoodsInfo(body.app_list); 200 | } else { 201 | $notification.post(notifyTitle, "路径/请求方法匹配错误:", method + "," + url); 202 | } 203 | 204 | body = JSON.stringify(body); 205 | 206 | $done({ 207 | body 208 | }); 209 | 210 | 211 | function getUrlParamValue(url, queryName) { 212 | return Object.fromEntries(url.substring(url.indexOf("?") + 1) 213 | .split("&") 214 | .map(pair => pair.split("=")) 215 | )[queryName]; 216 | } 217 | 218 | function removeGoodsInfo(app) { 219 | if (app?.length) { 220 | let goodsInfoSize = 0; 221 | app.forEach(item => { 222 | if (item.goods_info?.length) { 223 | goodsInfoSize++; 224 | item.goods_info = []; 225 | } 226 | }) 227 | if (goodsInfoSize) { 228 | console.log(`去除goods_info:${goodsInfoSize}`); 229 | } else { 230 | console.log(`app内无goods_info`) 231 | } 232 | 233 | } else { 234 | console.log(`app为空,无需处理`); 235 | } 236 | } 237 | 238 | function removeLive(threadList) { 239 | let newThreadList = threadList; 240 | const beforeLength = threadList?.length; 241 | if (beforeLength) { 242 | newThreadList = threadList.filter(item => { 243 | if (item.ala_info) { 244 | console.log('去除推荐的直播帖子'); 245 | return false; 246 | } 247 | return true; 248 | }); 249 | if (beforeLength === newThreadList.length) { 250 | console.log("无推荐的直播帖子"); 251 | } 252 | } else { 253 | console.log('无需处理threadList'); 254 | } 255 | return newThreadList; 256 | } 257 | -------------------------------------------------------------------------------- /js/tieba-json2.js: -------------------------------------------------------------------------------- 1 | const url = $request.url; 2 | const method = $request.method; 3 | const postMethod = "POST"; 4 | const notifyTitle = "贴吧json脚本错误"; 5 | console.log(`贴吧json-2024.06.08.2`); 6 | 7 | let body = JSON.parse($response.body); 8 | // 直接全局搜索 @Modify( 9 | if (url.includes("tiebaads/commonbatch") && method === postMethod) { 10 | // 看图模式下的广告 11 | let adCmd = getUrlParamValue(url, "adcmd"); 12 | if (!adCmd) { 13 | console.log(`url:${url}`); 14 | $notification.post(notifyTitle, "贴吧-tiebaads/commonbatch", "adCmd参数不存在"); 15 | } else { 16 | console.log(`commonbatch:${adCmd}`); 17 | if (body.error_code === 0) { 18 | if (!body.res.ad?.length) { 19 | console.log('ad字段为空'); 20 | } else { 21 | body.res.ad = []; 22 | // 即使ad有内容 也不一定显示广告 23 | // 因为如果服务器下发的数据少了一些字段同样是无广告的 24 | console.log('成功'); 25 | } 26 | } else { 27 | console.log('error_code不为0:' + body.error_code); 28 | } 29 | } 30 | } else if (url.includes('c/f/pb/picpage')) { 31 | console.log(`picpage`); 32 | const liveLength = body.recom_live_list?.length; 33 | if (liveLength) { 34 | console.log(`去除直播:${liveLength}`); 35 | body.recom_live_list = []; 36 | } 37 | } else if (url.includes('c/s/sync')) { 38 | // get post(贴吧使用了post)均可访问 39 | console.log('贴吧-sync'); 40 | if ('floating_icon' in body) { 41 | console.log('右下角悬浮icon'); 42 | if (body.floating_icon) { 43 | if (body.floating_icon.homepage?.icon_url) { 44 | console.log('homepage悬浮去除'); 45 | } else { 46 | console.log('无需去除homepage悬浮'); 47 | } 48 | if (body.floating_icon.pb?.icon_url) { 49 | console.log('pb悬浮去除'); 50 | } else { 51 | console.log('无需去除pb悬浮'); 52 | } 53 | body.floating_icon = null; 54 | } else { 55 | console.log('无需修改floating_icon字段值'); 56 | } 57 | } else { 58 | console.log(`body:${$response.body}`); 59 | $notification.post(notifyTitle, "贴吧-sync", "无floating_icon字段"); 60 | } 61 | 62 | // 回帖栏的广告 63 | if ('advertisement_config' in body) { 64 | if (!body.advertisement_config?.advertisement_str) { 65 | console.log('无需处理advertisement_config'); 66 | } else { 67 | console.log(`advertisement_str:${body.advertisement_config.advertisement_str}`); 68 | body.advertisement_config = null; 69 | } 70 | } else { 71 | console.log(`body:${$response.body}`); 72 | $notification.post(notifyTitle, "贴吧-sync", "无advertisement_config字段"); 73 | } 74 | 75 | if ('config' in body) { 76 | if (body.config?.switch) { 77 | for (const item of body.config.switch) { 78 | // 穿山甲/广点通/快手 79 | if (['platform_csj_init', 'platform_ks_init', 'platform_gdt_init'].includes(item.name)) { 80 | if (item.type !== '0'){ 81 | item.type = '0'; 82 | console.log(`禁止初始化${item.name}`); 83 | } 84 | } 85 | } 86 | } 87 | } else { 88 | console.log(`body:${$response.body}`); 89 | $notification.post(notifyTitle, "贴吧-sync", "无config字段"); 90 | } 91 | 92 | if ('screen_fill_data_result' in body) { 93 | if (body.screen_fill_data_result.screen_fill_advertisement_bear_switch === "1") { 94 | body.screen_fill_data_result.screen_fill_advertisement_bear_switch = '0'; 95 | console.log('开屏不展示小熊广告'); 96 | } else { 97 | console.log('无需修改screen_fill_advertisement_bear_switch'); 98 | } 99 | if (body.screen_fill_data_result.screen_fill_advertisement_plj_cpc_switch === "1") { 100 | body.screen_fill_data_result.screen_fill_advertisement_plj_cpc_switch = '0'; 101 | console.log('开屏不展示序章CPC'); 102 | } else { 103 | console.log('无需修改screen_fill_advertisement_plj_cpc_switch'); 104 | } 105 | if (body.screen_fill_data_result.screen_fill_advertisement_plj_switch === "1") { 106 | body.screen_fill_data_result.screen_fill_advertisement_plj_switch = '0'; 107 | console.log('开屏不展示序章'); 108 | } else { 109 | console.log('无需修改screen_fill_advertisement_plj_switch'); 110 | } 111 | } else { 112 | console.log(`body:${$response.body}`); 113 | $notification.post(notifyTitle, "贴吧-sync", "无screen_fill_data_result字段"); 114 | } 115 | 116 | if ('ad_stlog_switch' in body) { 117 | if (body.ad_stlog_switch === '1') { 118 | body.ad_stlog_switch = '0'; 119 | console.log('修改ad_stlog_switch'); 120 | } else { 121 | console.log('无需修改ad_stlog_switch'); 122 | } 123 | } else { 124 | console.log(`body:${$response.body}`); 125 | $notification.post(notifyTitle, "贴吧-sync", "无ad_stlog_switch字段"); 126 | } 127 | 128 | if ('lcs_strategy' in body) { 129 | // 控制长连接开关 开启时帖子会走socket 130 | if (body.lcs_strategy.conn_conf === '0') { 131 | // 关闭 132 | body.lcs_strategy.conn_conf = '1'; 133 | console.log('修改conn_conf'); 134 | } else { 135 | console.log('无需修改conn_conf'); 136 | } 137 | } else { 138 | console.log(`body:${$response.body}`); 139 | $notification.post(notifyTitle, "贴吧-sync", "无lcs_strategy字段"); 140 | } 141 | } else if (url.includes("c/f/frs/page")) { 142 | console.log('贴吧-FrsPage'); 143 | if (body.live_fuse_forum?.length) { 144 | body.live_fuse_forum = []; 145 | console.log(`去除吧头直播`); 146 | } else { 147 | console.log(`无需处理吧头直播`); 148 | } 149 | 150 | if (body.activityhead?.is_ad) { 151 | body.activityhead = {}; 152 | console.log('去除吧内header图片广告'); 153 | } else { 154 | console.log('无需处理activityhead'); 155 | } 156 | body.thread_list = removeLive(body.thread_list); 157 | removeGoodsInfo(body.forum?.banner_list?.app); 158 | } else if (url.includes("c/f/frs/threadlist")) { 159 | console.log('贴吧-threadlist'); 160 | removeGoodsInfo(body.banner_list?.app); 161 | } else if (url.includes("c/f/pb/page")) { 162 | console.log('贴吧-PbPage'); 163 | if (body.recom_ala_info?.live_id) { 164 | console.log('帖子详情页推荐的直播广告去除'); 165 | body.recom_ala_info = null; 166 | } else { 167 | console.log('帖子详情页无直播广告'); 168 | } 169 | 170 | if (body.post_list?.length) { 171 | for (const post of body.post_list) { 172 | if (post.outer_item) { 173 | console.log('outer_item去除'); 174 | post.outer_item = null; 175 | } 176 | } 177 | } else { 178 | console.log('无需处理postList中的outer_item'); 179 | } 180 | removeGoodsInfo(body.banner_list?.app); 181 | const bannerGoodsInfoLength = body.banner_list?.pb_banner_ad?.goods_info?.length; 182 | if (bannerGoodsInfoLength) { 183 | console.log(`去除pb_banner_ad的goods_info:${bannerGoodsInfoLength}`) 184 | body.banner_list.pb_banner_ad.goods_info = [] 185 | } 186 | } else if (url.includes("c/f/excellent/personalized")) { 187 | console.log('贴吧-personalized'); 188 | removeGoodsInfo(body.banner_list?.app); 189 | body.thread_list = removeLive(body.thread_list); 190 | if(body.live_answer){ 191 | console.log('去除推荐页上方的banner广告'); 192 | body.live_answer = null; 193 | } else { 194 | console.log('推荐页无banner广告'); 195 | } 196 | } else if (url.includes("c/f/frs/generalTabList")) { 197 | console.log('贴吧-generalTabList'); 198 | removeGoodsInfo(body.app_list); 199 | } else { 200 | $notification.post(notifyTitle, "路径/请求方法匹配错误:", method + "," + url); 201 | } 202 | 203 | body = JSON.stringify(body); 204 | 205 | $done({ 206 | body 207 | }); 208 | 209 | 210 | function getUrlParamValue(url, queryName) { 211 | return Object.fromEntries(url.substring(url.indexOf("?") + 1) 212 | .split("&") 213 | .map(pair => pair.split("=")) 214 | )[queryName]; 215 | } 216 | 217 | function removeGoodsInfo(app) { 218 | if (app?.length) { 219 | let goodsInfoSize = 0; 220 | app.forEach(item => { 221 | if (item.goods_info?.length) { 222 | goodsInfoSize++; 223 | item.goods_info = []; 224 | } 225 | }) 226 | if (goodsInfoSize) { 227 | console.log(`去除goods_info:${goodsInfoSize}`); 228 | } else { 229 | console.log(`app内无goods_info`) 230 | } 231 | 232 | } else { 233 | console.log(`app为空,无需处理`); 234 | } 235 | } 236 | 237 | function removeLive(threadList) { 238 | let newThreadList = threadList; 239 | const beforeLength = threadList?.length; 240 | if (beforeLength) { 241 | newThreadList = threadList.filter(item => { 242 | if (item.ala_info) { 243 | console.log('去除推荐的直播帖子'); 244 | return false; 245 | } 246 | return true; 247 | }); 248 | if (beforeLength === newThreadList.length) { 249 | console.log("无推荐的直播帖子"); 250 | } 251 | } else { 252 | console.log('无需处理threadList'); 253 | } 254 | return newThreadList; 255 | } 256 | -------------------------------------------------------------------------------- /js/vgtime.js: -------------------------------------------------------------------------------- 1 | console.log('vgtime-开屏页'); 2 | let body = JSON.parse($response.body); 3 | if (!body.data?.ad) { 4 | console.log('data/ad字段为空'); 5 | console.log(`body:${$response.body}`); 6 | } else { 7 | body.data.ad = null; 8 | console.log('成功'); 9 | } 10 | body = JSON.stringify(body); 11 | 12 | $done({ 13 | body 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /js/zhihu.js: -------------------------------------------------------------------------------- 1 | const url = $request.url; 2 | const method = $request.method; 3 | if (!$response.body) { 4 | console.log(`$response.body为undefined:${url}`); 5 | $done({}); 6 | } 7 | console.log(`2022-12.6`) 8 | 9 | const noticeTitle = "知乎去广告脚本错误"; 10 | let body = JSON.parse($response.body); 11 | 12 | if (method !== "GET") { 13 | console.log(url); 14 | $notification.post(noticeTitle, "method错误:", method); 15 | } 16 | 17 | if (url.includes("api.zhihu.com/commercial_api/real_time_launch_v2")) { 18 | console.log('知乎-开屏页'); 19 | if (!body.launch) { 20 | console.log(`body:${$response.body}`); 21 | $notification.post(noticeTitle, name, "launch字段为空"); 22 | } 23 | let launch = JSON.parse(body.launch); 24 | if (!launch.ads) { 25 | // ads字段有时候为空,有时候没有ads字段 26 | console.log(`body:${$response.body}`); 27 | // $notification.post(noticeTitle, name, "launch-ads字段为空"); 28 | } else { 29 | launch.ads = []; 30 | console.log('成功'); 31 | } 32 | body.launch = JSON.stringify(launch); 33 | } else if (url.includes("api.zhihu.com/topstory/recommend")) { 34 | console.log('知乎-推荐列表'); 35 | let dataArr = body.data; 36 | if (!dataArr) { 37 | console.log(`body:${$response.body}`); 38 | $notification.post(noticeTitle, "知乎推荐", "data字段为空"); 39 | } else { 40 | body.data = dataArr.filter(item => { 41 | if (item.extra?.type === "zvideo") { 42 | let videoUrl = item.common_card.feed_content.video.customized_page_url; 43 | let videoID = getUrlParamValue(videoUrl, "videoID"); 44 | if (!videoID) { 45 | console.log('zvideo未获取到videoID'); 46 | console.log(`body:${$response.body}`); 47 | // 部分获取不到videoId并且视频可以播放 48 | } else { 49 | console.log(`videoID处理成功,原始:${item.common_card.feed_content.video.id},修改为:${videoID}`); 50 | item.common_card.feed_content.video.id = videoID; 51 | } 52 | } else if (item.type === 'market_card' && item.fields?.header?.url && item.fields.body?.video?.id) { 53 | let videoID = getUrlParamValue(item.fields.header.url, "videoID"); 54 | if (!videoID) { 55 | console.log(`body:${$response.body}`); 56 | $notification.post(noticeTitle, "知乎推荐列表视频", "videoID获取错误"); 57 | } else { 58 | console.log(`market_card-videoID处理成功,原始:${item.fields.body.video.id},修改为:${videoID}`); 59 | item.fields.body.video.id = videoID; 60 | } 61 | } else if (item.common_card?.feed_content?.video?.id) { 62 | let search = '"feed_content":{"video":{"id":'; 63 | let str = $response.body.substring($response.body.indexOf(search) + search.length); 64 | let videoID = str.substring(0, str.indexOf(',')); 65 | console.log(`其他-videoID处理成功,原始:${item.common_card.feed_content.video.id},修改为:${videoID}`); 66 | item.common_card.feed_content.video.id = videoID; 67 | } 68 | return item.type !== 'feed_advert'; 69 | }); 70 | if (body.data.length === dataArr.length) { 71 | console.log('列表数据无广告'); 72 | } else { 73 | console.log('成功'); 74 | } 75 | } 76 | } else if (url.includes("api.zhihu.com/questions") || url.includes("api.zhihu.com/v4/questions")) { 77 | if (url.includes("v4/questions")) { 78 | console.log('v4/questions'); 79 | } else { 80 | console.log('questions'); 81 | } 82 | console.log('知乎-问题回答列表'); 83 | if (!body.data.ad_info && !body.ad_info) { 84 | // 个别问题回答列表无广告 85 | console.log("问题回答列表无广告"); 86 | } else { 87 | body.data.ad_info = null; 88 | body.ad_info = null; 89 | console.log('成功'); 90 | } 91 | } else if (url.includes("www.zhihu.com/api/v4/answers")) { 92 | console.log('知乎-回答下的广告'); 93 | if (!body.paging || !body.data) { 94 | console.log(`body:${$response.body}`); 95 | $notification.post(noticeTitle, '知乎回答下广告', "paging/data字段为空"); 96 | } else { 97 | body.paging = null; 98 | body.data = null; 99 | console.log('成功'); 100 | } 101 | } else if (url.includes("www.zhihu.com/api/v4/articles/")) { 102 | console.log('知乎-文章articles回答下广告'); 103 | if (!body.ad_info) { 104 | console.log(`body:${$response.body}`); 105 | $notification.post(noticeTitle, name, "articles-ad_info字段为undefined"); 106 | } else { 107 | body.ad_info = null; 108 | console.log('成功'); 109 | } 110 | } else if (url.includes("appcloud2.zhihu.com/v3/config")) { 111 | console.log('知乎-appcloud2 config配置'); 112 | if (body.config?.zhcnh_thread_sync?.ZHBackUpIP_Switch_Open === '1') { 113 | body.config.zhcnh_thread_sync.ZHBackUpIP_Switch_Open = '0'; 114 | console.log('ZHBackUpIP_Switch_Open改为0'); 115 | } else { 116 | console.log('无需更改ZHBackUpIP_Switch_Open'); 117 | console.log(`body:${$response.body}`); 118 | } 119 | } else if (url.includes("api.zhihu.com/commercial_api/app_float_layer")) { 120 | console.log('知乎-首页右下角悬浮框'); 121 | if ('feed_egg' in body) { 122 | console.log('成功'); 123 | body = {}; 124 | } else { 125 | console.log('无需处理'); 126 | } 127 | } else { 128 | $notification.post(noticeTitle, "路径匹配错误:", url); 129 | } 130 | 131 | body = JSON.stringify(body); 132 | 133 | $done({ 134 | body 135 | }); 136 | 137 | 138 | function getUrlParamValue(url, queryName) { 139 | return Object.fromEntries(url.substring(url.indexOf("?") + 1) 140 | .split("&") 141 | .map(pair => pair.split("=")) 142 | )[queryName]; 143 | } 144 | -------------------------------------------------------------------------------- /module/adsense.conf: -------------------------------------------------------------------------------- 1 | # qx广告联盟去广告 2 | # 仓库地址 https://github.com/app2smile/rules 3 | # 快手联盟,优量汇,穿山甲 4 | 5 | hostname = api-access.pangolin-sdk-toutiao.com, mi.gdt.qq.com, open.e.kuaishou.com 6 | ^https:\/\/(api-access\.pangolin-sdk-toutiao\.com\/api\/ad\/union\/sdk\/get_ads|open\.e\.kuaishou\.com\/rest\/e\/v3\/open\/univ$|mi\.gdt\.qq\.com\/gdt_mview\.fcg\?) url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/adsense.js -------------------------------------------------------------------------------- /module/adsense.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=广告联盟去广告 2 | #!desc=快手联盟,优量汇,穿山甲 3 | # 仓库地址 https://github.com/app2smile/rules 4 | 5 | [MITM] 6 | hostname = %APPEND% api-access.pangolin-sdk-toutiao.com, is.snssdk.com, mi.gdt.qq.com, open.e.kuaishou.com 7 | 8 | [Script] 9 | 广告联盟json = type=http-response,pattern=^https:\/\/((api-access\.pangolin-sdk-toutiao|is\.snssdk)\.com\/api\/ad\/union\/sdk\/get_ads|open\.e\.kuaishou\.com\/rest\/e\/v3\/open\/univ$|mi\.gdt\.qq\.com\/gdt_mview\.fcg\?),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/adsense.js 10 | -------------------------------------------------------------------------------- /module/baidu-no-redirect.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=百度搜索防跳转AppStore 2 | #!desc=使用网页版百度搜索,在搜索结果中点击关键词时防跳转AppStore 3 | 4 | 5 | [MITM] 6 | hostname = %APPEND% boxer.baidu.com 7 | 8 | [Script] 9 | 百度防跳转 = type=http-response,pattern=^https:\/\/boxer\.baidu\.com\/scheme\?scheme,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/baidu-no-redirect.js 10 | -------------------------------------------------------------------------------- /module/baidumap.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=百度地图去广告(>=iOS15) 2 | #!desc=测试中,贴吧模块的afd也适用于百度地图的开屏广告? 3 | 4 | [MITM] 5 | hostname = %APPEND% newclient.map.baidu.com 6 | 7 | [Script] 8 | 百度地图proto = type=http-response,pattern=^https:\/\/newclient\.map\.baidu\.com\/client\/phpui2\/\?qt=ads,requires-body=1,binary-body-mode=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/baidumap.js 9 | -------------------------------------------------------------------------------- /module/bilibili-qx.conf: -------------------------------------------------------------------------------- 1 | # bilibili去广告8.13(>=iOS15) 2 | # 仓库地址 https://github.com/app2smile/rules 3 | # 开屏页广告,推荐页广告,动态(最常访问/推荐话题/列表广告),视频播放页面(up主推荐广告) 4 | hostname = app.bilibili.com, grpc.biliapi.net 5 | ^https:\/\/app\.bilibili\.com\/x\/(v2\/(splash\/(list|show)|feed\/index\?)|resource\/show\/tab\/v2) url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-json.js 6 | ^https:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.(viewunite\.v1\.View\/View|dynamic\.v2\.Dynamic\/DynAll)$ url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-proto.js 7 | -------------------------------------------------------------------------------- /module/bilibili-test.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=bilibilitest 2 | 3 | [MITM] 4 | hostname = %APPEND% app.bilibili.com, grpc.biliapi.net 5 | 6 | [Script] 7 | bili-json = type=http-response,pattern=^https:\/\/app\.bilibili\.com\/x\/(v2\/(splash\/(list|show)|feed\/index\?)|resource\/show\/tab\/v2),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-json.js,script-update-interval=0 8 | bili-proto = type=http-response,pattern=^https:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.(viewunite\.v1\.View\/View|dynamic\.v2\.Dynamic\/DynAll)$,requires-body=1,binary-body-mode=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-proto-test.js,script-update-interval=0 9 | -------------------------------------------------------------------------------- /module/bilibili.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=bilibili去广告8.13(>=iOS15) 2 | #!desc=开屏页广告,推荐页广告,动态(最常访问/推荐话题/列表广告),视频播放页面(up主推荐广告) 3 | # 仓库地址 https://github.com/app2smile/rules 4 | # h2下走grpc.biliapi.net(Surge TF2332以上版本可正常解析) h1时走app.bilibili.com 5 | 6 | [MITM] 7 | hostname = %APPEND% app.bilibili.com, grpc.biliapi.net 8 | 9 | [Script] 10 | bili-json = type=http-response,pattern=^https:\/\/app\.bilibili\.com\/x\/(v2\/(splash\/(list|show)|feed\/index\?)|resource\/show\/tab\/v2),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-json.js,script-update-interval=0 11 | bili-proto = type=http-response,pattern=^https:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.(viewunite\.v1\.View\/View|dynamic\.v2\.Dynamic\/DynAll)$,requires-body=1,binary-body-mode=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-proto.js,script-update-interval=0 12 | -------------------------------------------------------------------------------- /module/bilibili.stoverride: -------------------------------------------------------------------------------- 1 | name: bilibili去广告8.13(>=iOS15) 2 | desc: 开屏页广告,推荐页广告,动态(最常访问/推荐话题/列表广告),视频播放页面(up主推荐广告) 3 | 4 | http: 5 | mitm: 6 | - 'app.bilibili.com' 7 | - 'grpc.biliapi.net' 8 | script: 9 | - match: ^https:\/\/app\.bilibili\.com\/x\/(v2\/(splash\/(list|show)|feed\/index\?)|resource\/show\/tab\/v2) 10 | name: smile_bili_json 11 | type: response 12 | require-body: true 13 | timeout: 10 14 | - match: ^https:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.(viewunite\.v1\.View\/View|dynamic\.v2\.Dynamic\/DynAll)$ 15 | name: smile_bili_proto 16 | type: response 17 | require-body: true 18 | binary-mode: true 19 | timeout: 10 20 | 21 | script-providers: 22 | smile_bili_json: 23 | url: https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-json.js 24 | interval: 86400 25 | smile_bili_proto: 26 | url: https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-proto.js 27 | interval: 86400 -------------------------------------------------------------------------------- /module/mitm.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=MitM All 2 | #!desc=443端口,已排除部分域名 3 | 4 | [MITM] 5 | hostname = -*.apple.com, -*.icloud.com, -*.mzstatic.com, -*.facebook.com, -*.instagram.com, -*.ap.spotify.com, * 6 | -------------------------------------------------------------------------------- /module/qidian.conf: -------------------------------------------------------------------------------- 1 | # 起点App去广告 2 | # 仓库地址 https://github.com/app2smile/rules 3 | # 需要qx保持全程开启状态,如果去广告无效,请点开插件链接查看解决办法 4 | # 目前支持: 5 | # 开屏页广告,每日导读去除(需全新应用),冷启动强制跳转精选页去除,去除发现页弹出的活动弹窗, 6 | # 去除下方(精选 发现 中间的)活动时的tab,去除书架右下角的活动/广告的悬浮icon,搜索页可以搜索用户 7 | 8 | # 无法去广告的解决办法: 9 | # 开启代理软件的情况下,删除起点app,重新下载安装使用 10 | # 原因:(因起点版本更新,原https接口会走tcp链接, 若在使用起点App的过程中代理软件没有始终开启,容易出现起点去广告失效的情况) 11 | 12 | hostname = magev6.if.qidian.com 13 | ^https:\/\/magev6\.if\.qidian\.com\/argus\/api\/(v4\/client\/getsplashscreen|v2\/(deeplink\/geturl|dailyrecommend\/getdailyrecommend)|v1\/(client\/getconf$|bookshelf\/getHoverAdv|adv\/getadvlistbatch\?positions=iOS_tab)) url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/qidian.js 14 | -------------------------------------------------------------------------------- /module/qidian.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=起点App去广告 2 | #!desc=Surge和Loon可以完美去广告.但qx需全程开启代理软件才可以去广告 3 | # 仓库地址 https://github.com/app2smile/rules 4 | # 目前支持: 5 | # 开屏页广告,每日导读去除(需全新应用),冷启动强制跳转精选页去除,去除点击发现页弹出的活动弹窗,去除青少年模式弹框 6 | # 去除下方(精选 发现 中间的)活动时的tab,去除书架右下角的活动/广告的悬浮icon,搜索页可以搜索用户 7 | # 8 | # loon和surge可以完美去广告,但qx使用不当时会出现无法去广告情况(因起点版本更新,原https接口会走tcp链接, 若在使用起点App的过程中qx软件没有始终开启,容易出现起点去广告失效的情况): 9 | # qx解决办法:删除起点app,重新下载安装使用 10 | 11 | [MITM] 12 | hostname = %APPEND% magev6.if.qidian.com 13 | 14 | [Script] 15 | 起点json = type=http-response,pattern=^https:\/\/magev6\.if\.qidian\.com\/argus\/api\/(v4\/client\/getsplashscreen|v2\/(deeplink\/geturl|dailyrecommend\/getdailyrecommend)|v1\/(client\/getconf$|bookshelf\/getHoverAdv|adv\/getadvlistbatch\?positions=iOS_tab)),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/qidian.js 16 | -------------------------------------------------------------------------------- /module/qqnews.conf: -------------------------------------------------------------------------------- 1 | # 腾讯新闻App去广告 2 | # 仓库地址 https://github.com/app2smile/rules 3 | # 开屏广告(须全新应用),新闻列表(要闻/财经等),xx旅游列表等广告去除 4 | 5 | hostname = news.ssp.qq.com, r.inews.qq.com 6 | ^https:\/\/(news\.ssp\.qq\.com\/app|r\.inews\.qq\.com\/(get(QQNewsUnreadList|TagFeedList)|gw\/page\/(channel_feed|event_detail)|news_feed\/hot_module_list)) url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/qq-news.js -------------------------------------------------------------------------------- /module/qqnews.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=腾讯新闻App去广告 2 | #!desc=开屏页广告有缓存,需要全新应用 3 | # 腾讯新闻开屏广告(须全新应用),新闻列表(要闻/财经等),专题广告,xx旅游列表等广告去除 4 | # 仓库地址 https://github.com/app2smile/rules 5 | 6 | [MITM] 7 | hostname = %APPEND% news.ssp.qq.com, r.inews.qq.com 8 | 9 | [Script] 10 | 腾讯新闻json = type=http-response,pattern=^https:\/\/(news\.ssp\.qq\.com\/app|r\.inews\.qq\.com\/(get(QQNewsUnreadList|TagFeedList)|gw\/page\/(channel_feed|event_detail)|news_feed\/hot_module_list)),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/qq-news.js 11 | -------------------------------------------------------------------------------- /module/spotify.conf: -------------------------------------------------------------------------------- 1 | # 2025.3.20 部分解锁premium,音质不能设置为超高(建议登录后再打开脚本,重启app等待脚本生效) 2 | # 仓库地址 https://github.com/app2smile/rules 3 | # 功能: 1.去除播放广告 2.歌手/专辑列表正常展示 3.去除随机播放 4 | hostname = spclient.wg.spotify.com 5 | ^https:\/\/spclient\.wg\.spotify\.com\/user-customization-service\/v1\/customize$ url script-request-header https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-qx-header.js 6 | ^https:\/\/spclient\.wg\.spotify\.com\/(bootstrap\/v1\/bootstrap|user-customization-service\/v1\/customize)$ url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-proto.js 7 | ^https:\/\/spclient\.wg\.spotify\.com\/(artistview\/v1\/artist|album-entity-view\/v2\/album)\/ url script-request-header https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-json.js 8 | -------------------------------------------------------------------------------- /module/spotify.module: -------------------------------------------------------------------------------- 1 | #!name=Spotify(>=iOS15) 2 | #!desc=2024.05.27 部分解锁premium,音质不能设置为超高(建议登录后再打开脚本,重启app等待脚本生效) 3 | # 仓库地址 https://github.com/app2smile/rules 4 | # 功能: 1.去除播放广告 2.歌手/专辑列表正常展示 3.去除随机播放 5 | 6 | [Header Rewrite] 7 | # if-none-match返回304状态码 8 | http-request ^https:\/\/spclient\.wg\.spotify\.com\/user-customization-service\/v1\/customize$ header-del if-none-match 9 | 10 | [MITM] 11 | hostname = %APPEND% spclient.wg.spotify.com 12 | 13 | [Script] 14 | spotify-json = type=http-request,pattern=^https:\/\/spclient\.wg\.spotify\.com\/(artistview\/v1\/artist|album-entity-view\/v2\/album)\/,requires-body=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-json.js 15 | spotify-proto = type=http-response,pattern=^https:\/\/spclient\.wg\.spotify\.com\/(bootstrap\/v1\/bootstrap|user-customization-service\/v1\/customize)$,requires-body=1,binary-body-mode=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-proto.js,script-update-interval=0 16 | -------------------------------------------------------------------------------- /module/spotify.stoverride: -------------------------------------------------------------------------------- 1 | name: Spotify解锁(>=iOS15) 2 | desc: 2023.10.04部分解锁premium,音质不能设置为超高(建议登录后再打开脚本,重启app等待脚本生效) 3 | 4 | http: 5 | mitm: 6 | - 'spclient.wg.spotify.com' 7 | script: 8 | - match: ^https:\/\/spclient\.wg\.spotify\.com\/(bootstrap\/v1\/bootstrap|user-customization-service\/v1\/customize)$ 9 | name: smile_spotify 10 | type: response 11 | require-body: true 12 | binary-mode: true 13 | timeout: 10 14 | - match: ^https:\/\/spclient\.wg\.spotify\.com\/(artistview\/v1\/artist|album-entity-view\/v2\/album)\/ 15 | name: smile_spotify_json 16 | type: request 17 | timeout: 10 18 | 19 | script-providers: 20 | smile_spotify: 21 | url: https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-proto.js 22 | interval: 86400 23 | smile_spotify_json: 24 | url: https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-json.js 25 | interval: 86400 -------------------------------------------------------------------------------- /module/tieba-mini.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=贴吧部分去广告 2 | #!desc=1.开屏页广告 2.帖子看图模式广告去除 3.首页/帖子详情页右下角悬浮广告去除 3 | 4 | [MITM] 5 | hostname = %APPEND% tiebac.baidu.com 6 | 7 | [Script] 8 | 贴吧json = type=http-response,pattern=^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/(c\/(s\/sync|f\/(frs\/(page|threadlist|generalTabList)|pb\/(pic)?page|excellent\/personalized))$|tiebaads\/commonbatch\?),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-json2.js,script-update-interval=0 9 | 10 | -------------------------------------------------------------------------------- /module/tieba-qx.conf: -------------------------------------------------------------------------------- 1 | # 贴吧去广告-qx(>=iOS15) 2 | # qx加载本重写前,须同时加载对应的贴吧分流,否则不能完全去广告 3 | # 仓库地址 https://github.com/app2smile/rules 4 | # 开屏广告;推荐和吧内帖子列表的直播及广告;详情页直播/关联商品/广告;看图模式广告;首页和帖子详情页右下角悬浮广告;部分吧内的置顶/最新中间的广告/head图片广告/head直播 5 | 6 | hostname = tiebac.baidu.com 7 | ^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/(c\/f\/(frs\/(page|threadlist|generalTabList)|pb\/page|excellent\/personalized)$|tiebaads\/commonbatch|c\/s\/sync$) url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-json.js 8 | ^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/c\/f\/(frs\/(page|threadlist|generalTabList)|pb\/page|excellent\/personalized)\?cmd url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-proto.js 9 | -------------------------------------------------------------------------------- /module/tieba-test.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=贴吧Test 2 | #!arguments=per_filter_video:0 3 | #!arguments-desc=per_filter_video:设置为1则推荐页不展示视频贴 4 | 5 | [Rule] 6 | RULE-SET,https://raw.githubusercontent.com/app2smile/rules/master/rule/tieba-ad.list,REJECT-DROP 7 | 8 | [MITM] 9 | hostname = %APPEND% tiebac.baidu.com 10 | 11 | [Script] 12 | 贴吧json = type=http-response,pattern=^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/(c\/(s\/sync|f\/(frs\/(page|threadlist|generalTabList)|pb\/(pic)?page|excellent\/personalized))$|tiebaads\/commonbatch\?),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-json.js,script-update-interval=0 13 | 贴吧proto = type=http-response,pattern=^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/c\/f\/(frs\/(page|threadlist|generalTabList)|pb\/page|excellent\/personalized)\?cmd,requires-body=1,binary-body-mode=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-proto2.js,argument=per_filter_video_thread={{{per_filter_video}}} 14 | 15 | 16 | -------------------------------------------------------------------------------- /module/tieba.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=贴吧去广告(>=iOS15) 2 | #!desc=开屏广告;推荐和吧内帖子列表的直播及广告;详情页直播/关联商品/广告;看图模式广告;首页和帖子详情页右下角悬浮广告;部分吧内的置顶/最新中间的广告/head图片广告/head直播 3 | #!arguments=per_filter_video:0 4 | #!arguments-desc=per_filter_video:设置为1则推荐页不展示视频贴 5 | # 仓库地址 https://github.com/app2smile/rules 6 | 7 | [Rule] 8 | RULE-SET,https://raw.githubusercontent.com/app2smile/rules/master/rule/tieba-ad.list,REJECT-DROP 9 | 10 | [MITM] 11 | hostname = %APPEND% tiebac.baidu.com 12 | 13 | [Script] 14 | 贴吧json = type=http-response,pattern=^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/(c\/(s\/sync|f\/(frs\/(page|threadlist|generalTabList)|pb\/(pic)?page|excellent\/personalized))$|tiebaads\/commonbatch\?),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-json.js,script-update-interval=0 15 | 贴吧proto = type=http-response,pattern=^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/c\/f\/(frs\/(page|threadlist|generalTabList)|pb\/page|excellent\/personalized)\?cmd,requires-body=1,binary-body-mode=1,max-size=-1,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-proto.js,argument=per_filter_video_thread={{{per_filter_video}}} 16 | 17 | 18 | -------------------------------------------------------------------------------- /module/tieba.stoverride: -------------------------------------------------------------------------------- 1 | name: 贴吧去广告(>=iOS15) 2 | desc: 开屏广告;推荐和吧内帖子列表的直播及广告;详情页直播/关联商品/广告;看图模式广告;首页和帖子详情页右下角悬浮广告;部分吧内的置顶/最新中间的广告/head图片广告/head直播 3 | 4 | http: 5 | mitm: 6 | - 'tiebac.baidu.com' 7 | script: 8 | - match: ^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/(c\/(s\/sync|f\/(frs\/(page|threadlist|generalTabList)|pb\/(pic)?page|excellent\/personalized))$|tiebaads\/commonbatch\?) 9 | name: smile_tieba_json 10 | type: response 11 | require-body: true 12 | timeout: 10 13 | - match: ^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/c\/f\/(frs\/(page|threadlist|generalTabList)|pb\/page|excellent\/personalized)\?cmd 14 | name: smile_tieba_proto 15 | type: response 16 | require-body: true 17 | binary-mode: true 18 | timeout: 10 19 | 20 | script-providers: 21 | smile_tieba_json: 22 | url: https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-json.js 23 | interval: 86400 24 | smile_tieba_proto: 25 | url: https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-proto.js 26 | interval: 86400 -------------------------------------------------------------------------------- /module/vgtime.conf: -------------------------------------------------------------------------------- 1 | # vgTimeApp去广告 2 | # 去开屏广告(需全新应用). 若要去新闻列表广告需要搭配广告联盟模块 3 | # 仓库地址 https://github.com/app2smile/rules 4 | 5 | ^http:\/\/app02\.vgtime\.com:8080\/vgtime-app\/api\/v2\/init\/ad\.json url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/vgtime.js -------------------------------------------------------------------------------- /module/vgtime.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=vgTimeApp去广告 2 | #!desc=去开屏广告(需全新应用). 若要去新闻列表广告需要搭配广告联盟模块 3 | # 仓库地址 https://github.com/app2smile/rules 4 | 5 | [Script] 6 | vgTime = type=http-response,pattern=^http:\/\/app02\.vgtime\.com:8080\/vgtime-app\/api\/v2\/init\/ad\.json,requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/vgtime.js 7 | -------------------------------------------------------------------------------- /module/youtube-qx.conf: -------------------------------------------------------------------------------- 1 | # YouTube去广告-qx(>=iOS15) 2 | # 去首页瀑布流广告/播放页推荐列表广告(非贴片广告) 3 | # 仓库地址 https://github.com/app2smile/rules 4 | 5 | hostname = youtubei.googleapis.com 6 | ^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next) url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/youtube.js 7 | -------------------------------------------------------------------------------- /module/youtube.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=YouTube去广告(>=iOS15) 2 | #!desc=去首页瀑布流广告/播放页推荐列表广告(非贴片广告) 3 | # 仓库地址 https://github.com/app2smile/rules 4 | 5 | [MITM] 6 | hostname = %APPEND% youtubei.googleapis.com 7 | 8 | [Script] 9 | youtube-proto = type=http-response,pattern=^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next),requires-body=1,binary-body-mode=1,max-size=2097152,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/youtube.js 10 | -------------------------------------------------------------------------------- /module/zhihu.conf: -------------------------------------------------------------------------------- 1 | # qx知乎App去广告 2 | # 仓库地址 https://github.com/app2smile/rules 3 | # 开屏页广告,首页右下角悬浮框,推荐列表广告,问题回答列表广告,具体回答下广告 4 | hostname = api.zhihu.com, www.zhihu.com, appcloud2.zhihu.com 5 | ^https:\/\/(appcloud2\.zhihu\.com\/v3\/config$|www\.zhihu\.com\/api\/v4\/(answers\/\d+\/recommendations|articles\/\d+\/recommendation)|api\.zhihu\.com\/(topstory\/recommend|commercial_api\/(real_time_launch_v2|app_float_layer$)|questions\/\d+\/feeds\?|v4\/questions\/\d+\/answers\?)) url script-response-body https://raw.githubusercontent.com/app2smile/rules/master/js/zhihu.js -------------------------------------------------------------------------------- /module/zhihu.sgmodule: -------------------------------------------------------------------------------- 1 | #!name=知乎App去广告 2 | #!desc=开屏页广告,首页右下角悬浮框,推荐列表广告,问题回答列表广告,具体回答下广告 3 | # 仓库地址 https://github.com/app2smile/rules 4 | 5 | [Rule] 6 | RULE-SET,https://raw.githubusercontent.com/app2smile/rules/master/rule/zhihu-ad.list,REJECT-DROP 7 | 8 | [MITM] 9 | hostname = %APPEND% api.zhihu.com, www.zhihu.com, appcloud2.zhihu.com 10 | 11 | [Script] 12 | 知乎json = type=http-response,pattern=^https:\/\/(appcloud2\.zhihu\.com\/v3\/config$|www\.zhihu\.com\/api\/v4\/(answers\/\d+\/recommendations|articles\/\d+\/recommendation)|api\.zhihu\.com\/(topstory\/recommend|commercial_api\/(real_time_launch_v2|app_float_layer$)|questions\/\d+\/feeds\?|v4\/questions\/\d+\/answers\?)),requires-body=1,max-size=0,script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/zhihu.js 13 | -------------------------------------------------------------------------------- /plugin/adsense.plugin: -------------------------------------------------------------------------------- 1 | #!name=广告联盟去广告 2 | #!desc=快手联盟,优量汇,穿山甲 3 | #!openUrl=https://github.com/app2smile/rules 4 | 5 | [Mitm] 6 | hostname = api-access.pangolin-sdk-toutiao.com, mi.gdt.qq.com, open.e.kuaishou.com 7 | 8 | [Script] 9 | http-response ^https:\/\/(api-access\.pangolin-sdk-toutiao\.com\/api\/ad\/union\/sdk\/get_ads|open\.e\.kuaishou\.com\/rest\/e\/v3\/open\/univ$|mi\.gdt\.qq\.com\/gdt_mview\.fcg\?) script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/adsense.js, requires-body=true, timeout=10, tag=广告联盟json 10 | -------------------------------------------------------------------------------- /plugin/baidu-no-redirect.plugin: -------------------------------------------------------------------------------- 1 | # 使用网页版百度搜索,在搜索结果中点击关键词时防跳转AppStore 2 | [Mitm] 3 | hostname = boxer.baidu.com 4 | 5 | [Script] 6 | http-response ^https:\/\/boxer\.baidu\.com\/scheme\?scheme script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/baidu-no-redirect.js, timeout=10, tag=百度防跳转 7 | -------------------------------------------------------------------------------- /plugin/bilibili.plugin: -------------------------------------------------------------------------------- 1 | #!name=bilibili去广告(>=iOS15) 2 | #!desc=解除部分视频后台限制,开屏页广告,推荐页广告,动态(最常访问/推荐话题/列表广告),视频播放页面(up主推荐广告,相关推荐广告) 3 | #!openUrl=https://github.com/app2smile/rules 4 | 5 | [Mitm] 6 | hostname = app.bilibili.com, grpc.biliapi.net 7 | 8 | [Script] 9 | http-response ^https:\/\/app\.bilibili\.com\/x\/(v2\/(splash\/(list|show)|feed\/index\?)|resource\/show\/tab\/v2) script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-json.js, requires-body=true, timeout=10, tag=bili-json 10 | http-response ^https:\/\/(grpc\.biliapi\.net|app\.bilibili\.com)\/bilibili\.app\.(view\.v1\.View\/View|dynamic\.v2\.Dynamic\/DynAll|playurl\.v1\.PlayURL\/PlayView)$ script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/bilibili-proto.js, requires-body=true, binary-body-mode=true, timeout=10, tag=bili-proto 11 | -------------------------------------------------------------------------------- /plugin/qidian.plugin: -------------------------------------------------------------------------------- 1 | #!name=起点App去广告 2 | #!desc=Loon已支持tcp mitm,可以完美去广告 3 | #!openUrl=https://github.com/app2smile/rules 4 | # 目前支持: 5 | # 开屏页广告,每日导读去除(需全新应用),冷启动强制跳转精选页去除,去除发现页弹出的活动弹窗, 6 | # 去除下方(精选 发现 中间的)活动时的tab,去除书架右下角的活动/广告的悬浮icon,搜索页可以搜索用户 7 | 8 | [Mitm] 9 | hostname = magev6.if.qidian.com 10 | 11 | [Script] 12 | http-response ^https:\/\/magev6\.if\.qidian\.com\/argus\/api\/(v4\/client\/getsplashscreen|v2\/(deeplink\/geturl|dailyrecommend\/getdailyrecommend)|v1\/(client\/getconf$|bookshelf\/getHoverAdv|adv\/getadvlistbatch\?positions=iOS_tab)) script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/qidian.js, requires-body=true, timeout=10, tag=起点json 13 | -------------------------------------------------------------------------------- /plugin/qqnews.plugin: -------------------------------------------------------------------------------- 1 | #!name=腾讯新闻App去广告 2 | #!desc=开屏页广告有缓存,需要全新应用 3 | #!openUrl=https://github.com/app2smile/rules 4 | # 腾讯新闻开屏广告(须全新应用),新闻列表(要闻/财经等),专题广告,xx旅游列表等广告去除 5 | 6 | [Mitm] 7 | hostname = news.ssp.qq.com, r.inews.qq.com 8 | 9 | [Script] 10 | http-response ^https:\/\/(news\.ssp\.qq\.com\/app|r\.inews\.qq\.com\/(get(QQNewsUnreadList|TagFeedList)|gw\/page\/(channel_feed|event_detail)|news_feed\/hot_module_list)) script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/qq-news.js, requires-body=true, timeout=10, tag=腾讯新闻json 11 | -------------------------------------------------------------------------------- /plugin/spotify.plugin: -------------------------------------------------------------------------------- 1 | #!name=Spotify(>=iOS15) 2 | #!desc=2024.05.27 部分解锁premium,音质不能设置为超高(建议登录后再打开脚本,重启app等待脚本生效) 3 | #!openUrl=https://github.com/app2smile/rules 4 | # 功能: 1.去除播放广告 2.歌手/专辑列表正常展示 3.去除随机播放 5 | 6 | [Rewrite] 7 | ^https:\/\/spclient\.wg\.spotify\.com\/user-customization-service\/v1\/customize$ header-del if-none-match 8 | 9 | [Mitm] 10 | hostname =spclient.wg.spotify.com 11 | 12 | [Script] 13 | http-request ^https:\/\/spclient\.wg\.spotify\.com\/(artistview\/v1\/artist|album-entity-view\/v2\/album)\/ script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-json.js, timeout=10, tag=spotifyJson 14 | http-response ^https:\/\/spclient\.wg\.spotify\.com\/(bootstrap\/v1\/bootstrap|user-customization-service\/v1\/customize)$ script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/spotify-proto.js, requires-body=true, binary-body-mode=true, timeout=10, tag=spotifyProto 15 | -------------------------------------------------------------------------------- /plugin/tieba.plugin: -------------------------------------------------------------------------------- 1 | #!name=贴吧去广告(>=iOS15) 2 | #!desc=开屏广告;推荐和吧内帖子列表的直播及广告;详情页直播/关联商品/广告;看图模式广告;首页和帖子详情页右下角悬浮广告;部分吧内的置顶/最新中间的广告/head图片广告/head直播 3 | #!openUrl=https://github.com/app2smile/rules 4 | [Rule] 5 | DOMAIN,180.76.76.200,REJECT 6 | # no-resolve需在最后 7 | IP-CIDR,180.76.76.200/32,REJECT,no-resolve 8 | 9 | [Mitm] 10 | hostname = tiebac.baidu.com 11 | 12 | [Script] 13 | http-response ^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/(c\/f\/(frs\/(page|threadlist|generalTabList)|pb\/page|excellent\/personalized)$|tiebaads\/commonbatch|c\/s\/sync$) script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-json.js, requires-body=true, timeout=10, tag=贴吧json 14 | http-response ^http(s:\/\/tiebac|:\/\/c\.tieba)\.baidu\.com\/c\/f\/(frs\/(page|threadlist|generalTabList)|pb\/page|excellent\/personalized)\?cmd script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/tieba-proto.js, requires-body=true, binary-body-mode=true, timeout=10, tag=贴吧proto 15 | -------------------------------------------------------------------------------- /plugin/vgtime.plugin: -------------------------------------------------------------------------------- 1 | #!name=vgTimeApp去广告 2 | #!desc=去开屏广告(需全新应用). 若要去新闻列表广告需要搭配广告联盟模块 3 | #!openUrl=https://github.com/app2smile/rules 4 | 5 | [Script] 6 | http-response ^http:\/\/app02\.vgtime\.com:8080\/vgtime-app\/api\/v2\/init\/ad\.json script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/vgtime.js, requires-body=true, timeout=10, tag=vgTime 7 | -------------------------------------------------------------------------------- /plugin/youtube.plugin: -------------------------------------------------------------------------------- 1 | #!name=YouTube去广告(>=iOS15) 2 | #!desc=去首页瀑布流广告/播放页推荐列表广告(非贴片广告) 3 | #!openUrl=https://github.com/app2smile/rules 4 | 5 | [Mitm] 6 | hostname = youtubei.googleapis.com 7 | 8 | [Script] 9 | http-response ^https:\/\/youtubei\.googleapis\.com\/youtubei\/v1\/(browse|next) script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/youtube.js, requires-body=true, binary-body-mode=true, timeout=10, tag=youtube-proto 10 | -------------------------------------------------------------------------------- /plugin/zhihu.plugin: -------------------------------------------------------------------------------- 1 | #!name=知乎App去广告 2 | #!desc=开屏页广告,首页右下角悬浮框,推荐列表广告,问题回答列表广告,具体回答下广告 3 | #!openUrl=https://github.com/app2smile/rules 4 | 5 | [Rule] 6 | DOMAIN,118.89.204.198,REJECT 7 | IP-CIDR,118.89.204.198/32,REJECT,no-resolve 8 | IP-CIDR6,2402:4e00:1200:ed00:0:9089:6dac:96b6/128,REJECT,no-resolve 9 | 10 | [Mitm] 11 | hostname = api.zhihu.com, www.zhihu.com, appcloud2.zhihu.com 12 | 13 | [Script] 14 | http-response ^https:\/\/(appcloud2\.zhihu\.com\/v3\/config$|www\.zhihu\.com\/api\/v4\/(answers\/\d+\/recommendations|articles\/\d+\/recommendation)|api\.zhihu\.com\/(topstory\/recommend|commercial_api\/(real_time_launch_v2|app_float_layer$)|questions\/\d+\/feeds\?|v4\/questions\/\d+\/answers\?)) script-path=https://raw.githubusercontent.com/app2smile/rules/master/js/zhihu.js, requires-body=true, timeout=10, tag=知乎json 15 | -------------------------------------------------------------------------------- /rule/ad.list: -------------------------------------------------------------------------------- 1 | # 知乎屏蔽域名dns查询 2 | DOMAIN,118.89.204.198 3 | IP-CIDR,118.89.204.198/32,no-resolve 4 | IP-CIDR6,2402:4e00:1200:ed00:0:9089:6dac:96b6/128,no-resolve 5 | -------------------------------------------------------------------------------- /rule/bilibili-ad-qx.list: -------------------------------------------------------------------------------- 1 | # h2下会请求这个,但请求会很慢发出 2 | HOST,grpc.biliapi.net,REJECT -------------------------------------------------------------------------------- /rule/bilibili-ad.list: -------------------------------------------------------------------------------- 1 | # h2下会请求这个,但请求会很慢发出 2 | DOMAIN,grpc.biliapi.net -------------------------------------------------------------------------------- /rule/tieba-ad-qx.list: -------------------------------------------------------------------------------- 1 | # 贴吧屏蔽域名dns查询 2 | IP-CIDR,180.76.76.200/32,REJECT -------------------------------------------------------------------------------- /rule/tieba-ad.list: -------------------------------------------------------------------------------- 1 | # 贴吧屏蔽域名dns查询 2 | DOMAIN,180.76.76.200 3 | IP-CIDR,180.76.76.200/32,no-resolve -------------------------------------------------------------------------------- /rule/zhihu-ad-qx.list: -------------------------------------------------------------------------------- 1 | IP-CIDR,118.89.204.198/32,REJECT 2 | IP6-CIDR,2402:4e00:1200:ed00:0:9089:6dac:96b6/128,REJECT -------------------------------------------------------------------------------- /rule/zhihu-ad.list: -------------------------------------------------------------------------------- 1 | # 知乎屏蔽域名dns查询 2 | DOMAIN,118.89.204.198 3 | IP-CIDR,118.89.204.198/32,no-resolve 4 | IP-CIDR6,2402:4e00:1200:ed00:0:9089:6dac:96b6/128,no-resolve --------------------------------------------------------------------------------