diff --git a/Rewrite/AdBlock/Cainiao.adblock b/Rewrite/AdBlock/Cainiao.adblock
new file mode 100644
index 0000000..f01937e
--- /dev/null
+++ b/Rewrite/AdBlock/Cainiao.adblock
@@ -0,0 +1,31 @@
+// ==UserScript==
+// @ScriptName 菜鸟[菜鸟裹裹]☆净化
+// @Author @ddgksf2013
+// @ForHelp 若有屏蔽广告的需求,可公众号后台回复APP名称
+// @WechatID 公众号墨鱼手记
+// @TgChannel https://t.me/ddgksf2021
+// @Contribute https://t.me/ddgksf2013_bot
+// @Feedback 📮 ddgksf2013@163.com 📮
+// @UpdateTime 2023-02-03
+// @Suitable 自行观看“# > ”注释内容
+// @Attention 使用前请卸载菜鸟APP,挂载脚本然后使用
+// @Attention 如需引用请注明出处,谢谢合作!
+// @Version V1.0.4
+// @ScriptURL https://github.com/ddgksf2013/Rewrite/raw/master/AdBlock/Cainiao.conf
+// ==/UserScript==
+
+
+hostname=cn-acs.m.cainiao.com
+
+
+# > 菜鸟裹裹_请自行添加本地分流@ddgksf2013
+;host, amdc.m.taobao.com, reject
+
+# > 菜鸟裹裹_首页中部的惊喜福利推广@ddgksf2013
+^https?:\/\/cn-acs\.m\.cainiao\.com\/gw\/mtop\.cainiao\.nbpresentation\.protocol\.homepage\.get\.cn url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Other/Cainiao.js
+# > 菜鸟裹裹_搜索框下方今日好物推荐@ddgksf2013
+^https?:\/\/cn-acs\.m\.cainiao\.com\/gw\/mtop\.cainiao\.adkeyword url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Other/Cainiao.js
+# > 菜鸟裹裹_首页底部商品推广@ddgksf2013
+^https?:\/\/cn-acs\.m\.cainiao\.com\/gw\/mtop\.cainiao\.guoguo\.nbnetflow\.ads\.index\.cn url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Other/Cainiao.js
+# > 菜鸟裹裹_通用广告请求@ddgksf2013
+^https?:\/\/cn-acs\.m\.cainiao\.com\/gw\/mtop\.cainiao\.guoguo\.nbnetflow\.ads\.(show|mshow)\.cn url reject-200
\ No newline at end of file
diff --git a/Rewrite/AdBlock/Netease.adblock b/Rewrite/AdBlock/Netease.adblock
new file mode 100644
index 0000000..407f928
--- /dev/null
+++ b/Rewrite/AdBlock/Netease.adblock
@@ -0,0 +1,56 @@
+// ==UserScript==
+// @ScriptName 网易云音乐
+// @Author @ddgksf2013
+// @ForHelp 若有屏蔽广告的需求,可公众号后台回复APP名称
+// @WechatID 公众号墨鱼手记
+// @TgChannel https://t.me/ddgksf2021
+// @Contribute https://t.me/ddgksf2013_bot
+// @Feedback 📮 ddgksf2013@163.com 📮
+// @UpdateTime 2023-02-07
+// @Suitable 自行观看“# > ”注释内容
+// @Attention 如需引用请注明出处,谢谢合作!
+// @Version V1.0.18
+// @ScriptURL https://github.com/ddgksf2013/Rewrite/raw/master/AdBlock/Netease.conf
+// ==/UserScript==
+
+// 墨鱼建议:
+// 1、进入【设置】,然后点击【底部导航自定义】,进入后可移除网易云APP下方的【播客】与【社区】tab
+// 2、首页滑到最底部,点击【自定义排序】,可移除【顶部横幅】card,顶部横幅里包含广告,作用也不大
+// 3、设置网易云音乐为青少年模式,会减少一些广告的请求,点击左上角,下滑即可看到【青少年模式】
+
+hostname = interface*.music.163.com
+
+# > 网易云_通用广告请求
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/ad\/ url reject-dict
+# > 网易云_不知道是个啥
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/sp\/flow url reject-dict
+# > 网易云_屏蔽更新
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/ios\/upgrade url reject-dict
+# > 网易云_LIKE音乐上方推广
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/link\/position\/show\/resource url reject-dict
+# > 网易云_歌单上方推广
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?eapi\/resource-exposure\/config url reject-dict
+# > 网易云_搜索框专词
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/search\/specialkeyword url reject-dict
+# > 网易云_首页右上角激励图标
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/link\/scene\/show\/resource url reject-dict
+# > 网易云_搜索框推荐
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/search\/default url reject-dict
+# > 网易云_评论区下方广告
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/comment\/feed\/inserted url reject-dict
+# > 网易云_评论回复区广告
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/v1\/content\/exposure\/comment url reject-dict
+# > 网易云_搜索页猜你喜欢[卸载重装]
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/search\/rcmd\/keyword url reject-dict
+# > 网易云_搜索框填词
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/search\/default\/keyword url reject-dict
+# > 网易云_评论区右上角
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/comment\/hotcomment\/collect url reject-dict
+# > 网易云_活动推广1
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/middle\/clientcfg\/config url reject-dict
+# > 网易云_活动推广2
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/resource-exposure\/activity\/config url reject-dict
+# > 网易云_VIP歌曲提醒框
+^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/vipcenter/tspopup\/get url reject-dict
+# > 网易云_搜索页下方热搜CARD[自行启用]
+; ^https?:\/\/interface(\d)?\.music\.163\.com\/w?e?api\/search\/chart url reject-dict
\ No newline at end of file
diff --git a/Rewrite/AdBlock/StartUp.conf b/Rewrite/AdBlock/StartUp.conf
index 5899e2d..523163a 100644
--- a/Rewrite/AdBlock/StartUp.conf
+++ b/Rewrite/AdBlock/StartUp.conf
@@ -4,7 +4,7 @@
// @TgChannel https://t.me/ddgksf2021
// @TgBot https://t.me/ddgksf2013_bot
// @WechatID 公众号墨鱼手记
-// @UpdateTime 2023-01-31
+// @UpdateTime 2023-02-08
// @Please 如需引用请注明出处,谢谢合作!
// @Function 去除APP首页启动广告和部分应用内广告,如果有需要的去除广告的APP,可以公众号后台直接回复
// @ExtraTxt Only provide the removal of open-screen advertisements for personally used apps
@@ -14,12 +14,12 @@
// @ScriptURL https://github.com/ddgksf2013/Rewrite/raw/master/AdBlock/StartUp.conf
// ==/UserScript==
-hostname = p0.pipi.cn, app.homeinns.com, uapi.huolala.cn, cdn-evone-ceph.echargenet.com, mlol.qt.qq.com, gg.caixin.com, app-gw.csdn.net, api.gameplus.qq.com, mrobot.pconline.com.cn, djcapp.game.qq.com, mxsa.mxbc.net, cn-acs.m.cainiao.com, zjdr666.com, api.caiyunapp.com, api.ahmobile.cn, gx.10086.cn, emdcadvertise.eastmoney.com, acs.m.taobao.com, router-app-api.jdcloud.com, api-sams.walmartmobile.cn, creditcardapp.bankcomm.cn, webappcfg.paas.cmbchina.com, m.creditcard.ecitic.com, lban.spdb.com.cn, adapi.izuiyou.com, i.ys7.com, apps.api.ke.com, api.yonghuivip.com, access.mypikpak.com, gateway.shouqiev.com, res.pizzahut.com.cn, api.caijingmobile.com, 3g.csair.com, client-api.oray.com, bgw.xinyue.qq.com, api-new.app.acfun.cn, m.client.10010.com, open.fitdays.cn, gd.10086.cn, gha.ghac.cn, ap.dongqiudi.com, sh-gateway.shihuo.cn, wcprd.hilton.com, ad.12306.cn, 103.91.210.141, adx-cn.anythinktech.com, js-ad.ayximgs.com, api.dangdang.com, pzoap.moedot.com, pipi.4kya.com, vip7.fzwdyy.cn, sdk.alibaba.com.ailbaba.me, tft-app.cdtft.cn, bgw.xinyue.qq.com, pan.baidu.com, yunbusiness.ccb.com, client.app.coc.10086.cn, t1.market.xiaomi.com, api.m.mi.com, app.zhuanzhuan.com, api.cloud.189.cn, appwk.baidu.com, us.l.qq.com, open.e.kuaishou.com, mi.gdt.qq.com, emdcadvertise.eastmoney.com, adm.10jqka.com, a.qiumibao.com, api.tipsoon.com, b.appsimg.com, ios.sspai.com, zconfig.alibabausercontent.com, api.touker.com, mpcs.suning.com, api.pinduoduo.com, api.yangkeduo.com, easyreadfs.nosdn.127.net, sp.kaola.com, gw.kaola.com, mime.baidu.com, learn.chaoxing.com, mapi.dangdang.com, api.dangdang.com, open.e.kuaishou.com, client.qunar.com, mpos-pic.helipay.com, dili.bdatu.com, wap.ngchina.cn, ih2.ireader.com, adpai.thepaper.cn, api.haohaozhu.cn, list-app-m.i4.cn, api.xiachufang.com, jdread-api.jd.com, peisongapi.meituan.com, *gaoqingdianshi.com, *.kakamobi.cn, api.jxedt.com, slapi.oray.net, r.inews.qq.com, app.yinxiang.com, mapi.appvipshop.com, syh.zybang.com, cdn.cmgadx.com, api.internetofcity.cn, img.meituan.net, lcen.xiaote.net, venus.yhd.com, api.shenyin.name, mage*.if.qidian.com, god.gameyw.netease.com, m.ibuscloud.com, e.dangdang.com, app2.autoimg.cn, adproxy.autohome.com.cn, discardrp.umetrip.com, startup.umetrip.com, bp-api.bestv.com.cn, explorer.tratao.com, overseas.weico.cc, 118.178.214.118, dapis.mting.info, acs.m.taobao.com, open3.vistastory.com, ssp.dzh.com.cn, api-access.pangolin-sdk-toutiao.com, maicai.api.ddxq.mobi, www.meituan.com, client.mail.163.com, api.izuiyou.com, appapi.huazhu.com, api.wfdata.club, interface*.music.163.com, api.psy-1.com, res.kfc.com.cn, mp.weixin.qq.com, security.wechat.com, weixin110.qq.com, cdn.*.chelaileapp.cn, api.coolapk.com, app3.qdaily.com, daoyu.sdo.com, img.jiemian.com, ccsp-egmas.sf-express.com, *.laichon.com, app.ap.d3yuiw4.com, www.i3zh.com, api.yikaobang.com.cn, api-ad-product.huxiu.com, jad-api.jin10.com, mob.mddcloud.com.cn, appactive.1234567.com.cn, rtbapi.douyucdn.cn, service.busi.inke.cn, gab.122.gov.cn, dispatcher.camera360.com, app.api.versa-ai.com, open.taou.com, api.taou.com, track.mm.taou.com, app.dewu.com, data-collector.soulapp.cn, api.gamer.com.tw, beta-api.crunchyroll.com, api.vistopia.com.cn, pss.txffp.com, m.sd.10086.cn, helper.2bulu.com, 47.100.65.202, api.weibo.cn, mapi.weibo.com, *.uve.weibo.com, new.vip.weibo.cn, wap.js.10086.cn, tagit.hyhuo.com, top-widgets-api.xiaozujian.com, tel.mangaapi.manhuaren.com, apis.lifeweek.com.cn, support.you.163.com, yanxuan.nosdn.127.net, *.peopleapp.com, new-app-api.ylyk.com, gw.aihuishou.com, *.58cdn.com.cn, app.58.com, static.zhihu.com, creditcardapp.bankcomm.com, res.xiaojukeji.com, 116.85.2.15, 116.85.2.14, lchttpapi.xczim.com, business.msstatic.com, mangaapi.manhuaren.com, api.kkmh.com, *.chelaile.net.cn, api.jr.mi.com, api.m.mi.com, guanyu.longfor.com, elemecdn.com, fuss10.elemecdn.com, www1.elecfans.com, m.tuniu.com, mapi.mafengwo.cn, api.xiaoyi.com, api.douban.com, otheve.beacon.qq.com, mapi.sfbest.com, api.mwee.cn, sso.ifanr.com, s3plus.meituan.net, flowplus.meituan.net, p*.meituan.net, testflight.apple.com, ms.jr.jd.com, wmapi.meituan.com, appconf.mail.163.com, dl-cu-hz.lechange.cn, bdsp-x.jd.com, dsp-x.jd.com, api.m.jd.com, fbchina.flipchina.cn, zone.guiderank-app.com, homefront.qunar.com, afd.baidu.com, *.bdstatic.com, j-image.missfresh.cn, ma-adx.ctrip.com, m.ctrip.com, mbd.baidu.com, img.rr.tv, api.rr.tv, capis.didapinche.com, capis*.didapinche.com, *.hoopchina.com, goblin.hupu.com, spclient.wg.spotify.com
+hostname = gateway-api.dushu365.com, p0.pipi.cn, jdread-api.jd.com, ms.jr.jd.com, bdsp-x.jd.com, dsp-x.jd.com, api.m.jd.com, router-app-api.jdcloud.com, app.homeinns.com, uapi.huolala.cn, cdn-evone-ceph.echargenet.com, mlol.qt.qq.com, gg.caixin.com, app-gw.csdn.net, api.gameplus.qq.com, mrobot.pconline.com.cn, djcapp.game.qq.com, mxsa.mxbc.net, cn-acs.m.cainiao.com, zjdr666.com, api.caiyunapp.com, api.ahmobile.cn, gx.10086.cn, emdcadvertise.eastmoney.com, acs.m.taobao.com, api-sams.walmartmobile.cn, creditcardapp.bankcomm.cn, webappcfg.paas.cmbchina.com, m.creditcard.ecitic.com, lban.spdb.com.cn, adapi.izuiyou.com, i.ys7.com, apps.api.ke.com, api.yonghuivip.com, access.mypikpak.com, gateway.shouqiev.com, res.pizzahut.com.cn, api.caijingmobile.com, 3g.csair.com, client-api.oray.com, bgw.xinyue.qq.com, api-new.app.acfun.cn, m.client.10010.com, open.fitdays.cn, gd.10086.cn, gha.ghac.cn, ap.dongqiudi.com, sh-gateway.shihuo.cn, wcprd.hilton.com, ad.12306.cn, 103.91.210.141, adx-cn.anythinktech.com, js-ad.ayximgs.com, api.dangdang.com, pzoap.moedot.com, pipi.4kya.com, vip7.fzwdyy.cn, sdk.alibaba.com.ailbaba.me, tft-app.cdtft.cn, bgw.xinyue.qq.com, pan.baidu.com, yunbusiness.ccb.com, client.app.coc.10086.cn, t1.market.xiaomi.com, api.m.mi.com, app.zhuanzhuan.com, api.cloud.189.cn, appwk.baidu.com, us.l.qq.com, open.e.kuaishou.com, mi.gdt.qq.com, emdcadvertise.eastmoney.com, adm.10jqka.com, a.qiumibao.com, api.tipsoon.com, b.appsimg.com, ios.sspai.com, zconfig.alibabausercontent.com, api.touker.com, mpcs.suning.com, api.pinduoduo.com, api.yangkeduo.com, easyreadfs.nosdn.127.net, sp.kaola.com, gw.kaola.com, mime.baidu.com, learn.chaoxing.com, mapi.dangdang.com, api.dangdang.com, open.e.kuaishou.com, client.qunar.com, mpos-pic.helipay.com, dili.bdatu.com, wap.ngchina.cn, ih2.ireader.com, adpai.thepaper.cn, api.haohaozhu.cn, list-app-m.i4.cn, api.xiachufang.com, peisongapi.meituan.com, *gaoqingdianshi.com, *.kakamobi.cn, api.jxedt.com, slapi.oray.net, r.inews.qq.com, app.yinxiang.com, mapi.appvipshop.com, syh.zybang.com, cdn.cmgadx.com, api.internetofcity.cn, img.meituan.net, lcen.xiaote.net, venus.yhd.com, api.shenyin.name, mage*.if.qidian.com, god.gameyw.netease.com, m.ibuscloud.com, e.dangdang.com, app2.autoimg.cn, adproxy.autohome.com.cn, discardrp.umetrip.com, startup.umetrip.com, bp-api.bestv.com.cn, explorer.tratao.com, overseas.weico.cc, 118.178.214.118, dapis.mting.info, acs.m.taobao.com, open3.vistastory.com, ssp.dzh.com.cn, api-access.pangolin-sdk-toutiao.com, maicai.api.ddxq.mobi, www.meituan.com, client.mail.163.com, api.izuiyou.com, appapi.huazhu.com, api.wfdata.club, interface*.music.163.com, api.psy-1.com, res.kfc.com.cn, mp.weixin.qq.com, security.wechat.com, weixin110.qq.com, cdn.*.chelaileapp.cn, api.coolapk.com, app3.qdaily.com, daoyu.sdo.com, img.jiemian.com, ccsp-egmas.sf-express.com, *.laichon.com, app.ap.d3yuiw4.com, www.i3zh.com, api.yikaobang.com.cn, api-ad-product.huxiu.com, jad-api.jin10.com, mob.mddcloud.com.cn, appactive.1234567.com.cn, rtbapi.douyucdn.cn, service.busi.inke.cn, gab.122.gov.cn, dispatcher.camera360.com, app.api.versa-ai.com, open.taou.com, api.taou.com, track.mm.taou.com, app.dewu.com, data-collector.soulapp.cn, api.gamer.com.tw, beta-api.crunchyroll.com, api.vistopia.com.cn, pss.txffp.com, m.sd.10086.cn, helper.2bulu.com, 47.100.65.202, api.weibo.cn, mapi.weibo.com, *.uve.weibo.com, new.vip.weibo.cn, wap.js.10086.cn, tagit.hyhuo.com, top-widgets-api.xiaozujian.com, tel.mangaapi.manhuaren.com, apis.lifeweek.com.cn, support.you.163.com, yanxuan.nosdn.127.net, *.peopleapp.com, new-app-api.ylyk.com, gw.aihuishou.com, *.58cdn.com.cn, app.58.com, static.zhihu.com, creditcardapp.bankcomm.com, res.xiaojukeji.com, 116.85.2.15, 116.85.2.14, lchttpapi.xczim.com, business.msstatic.com, mangaapi.manhuaren.com, api.kkmh.com, *.chelaile.net.cn, api.jr.mi.com, api.m.mi.com, guanyu.longfor.com, elemecdn.com, fuss10.elemecdn.com, www1.elecfans.com, m.tuniu.com, mapi.mafengwo.cn, api.xiaoyi.com, api.douban.com, otheve.beacon.qq.com, mapi.sfbest.com, api.mwee.cn, sso.ifanr.com, s3plus.meituan.net, flowplus.meituan.net, p*.meituan.net, testflight.apple.com, wmapi.meituan.com, appconf.mail.163.com, dl-cu-hz.lechange.cn, fbchina.flipchina.cn, zone.guiderank-app.com, homefront.qunar.com, afd.baidu.com, *.bdstatic.com, j-image.missfresh.cn, ma-adx.ctrip.com, m.ctrip.com, mbd.baidu.com, img.rr.tv, api.rr.tv, capis.didapinche.com, capis*.didapinche.com, *.hoopchina.com, goblin.hupu.com, spclient.wg.spotify.com
# ======= 0~9 ======= #
# > version
-^https?:\/\/2023.01.31\/v2.0.250 url reject
+^https?:\/\/2023.02.08\/v2.0.254 url reject
# > 58
^https?:\/\/app\.58\.com\/api\/home\/(advertising|appadv) url reject
# > 555
@@ -149,6 +149,8 @@ https?:\/\/res\.xiaojukeji\.com\/resapi\/activity\/get(Ruled|Preload|PasMultiNot
# ======= F ======= #
+# > fandengdushu
+^https?:\/\/gateway-api\.dushu365\.com\/chief-orch\/config\/config\/v100\/appConfig url reject
# > feizhu
^https:\/\/acs\.m\.taobao\.com\/gw\/mtop\.fliggy\.crm\.screen\.allresource url reject
# > feikechaguan
@@ -156,7 +158,6 @@ https?:\/\/res\.xiaojukeji\.com\/resapi\/activity\/get(Ruled|Preload|PasMultiNot
^https?:\/\/47\.100\.65\.202\/api\/mobile\/index\.php\?version=\d&mobile=yes&module=basicdata&type=forumlist url response-body adv response-body ddgksf2013
^https?:\/\/47\.100\.65\.202\/source\/plugin\/mobile\/mobile\.php\?module=threadpost&.+?&page=1 url script-response-body https://cdn.jsdelivr.net/gh/ddgksf2013/Scripts@master/fly.js
-
# ======= G ======= #
# > gongshijilu
@@ -217,24 +218,24 @@ https://fbchina.flipchina.cn/v2/ad/query/* url reject
# ======= J ======= #
-# > jianxun
-^https?:\/\/api\.tipsoon\.com\/api\/v\d\/top\/ad url reject
# > jingdongdushu
-https://jdread-api.jd.com/jdread/api/channel/module/opens url reject
-https://jdread-api.jd.com/jdread/api/popup url reject
+^https?:\/\/jdread-api\.jd\.com\/jdread\/api\/channel\/module\/opens url reject-200
+^https?:\/\/jdread-api\.jd\.com\/jdread\/api\/popup url reject-200
# > jingxi
-^https?:\/\/api\.m\.jd\.com\/api\?functionId=delivery_show url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/JD/jx_startup.js
+^https?:\/\/api\.m\.jd\.com\/api\?functionId=delivery_show url script-response-body https://github.com/ddgksf2013/Scripts/raw/master/startup.js
# > jingdong
-^https?:\/\/api\.m\.jd\.com\/client\.action\?functionId=(start|queryMaterialAdverts) url reject
-^https?:\/\/(bdsp-x|dsp-x)\.jd\.com\/adx\/ url reject
+^https?:\/\/api\.m\.jd\.com\/client\.action\?functionId=(start|queryMaterialAdverts) url reject-200
+^https?:\/\/(bdsp-x|dsp-x)\.jd\.com\/adx\/ url reject-200
^https?:\/\/api\.m\.jd\.com\/client\.action\?functionId=(hotWords|hotSearchTerms) url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/JD/jd_search_json.js
# > jingdongjinrong
-^https?:\/\/ms\.jr\.jd\.com\/gw\/generic\/aladdin\/(new)?na\/m\/getLoadingPicture url reject
+^https?:\/\/ms\.jr\.jd\.com\/gw\/generic\/aladdin\/(new)?na\/m\/getLoadingPicture url reject-200
# > jingdonglite
^https?:\/\/api\.m\.jd\.com\/client\.action\?functionId=lite_advertising url response-body jdLiteAdvertisingVO response-body null
^https?:\/\/api\.m\.jd\.com\/client\.action\?functionId=lite_SmartPush url response-body pushData response-body null
# > jingdongyun
-^https:\/\/router-app-api\.jdcloud\.com\/v\d\/board\/routerAppSplash url reject
+^https:\/\/router-app-api\.jdcloud\.com\/v\d\/board\/routerAppSplash url reject-200
+# > jianxun
+^https?:\/\/api\.tipsoon\.com\/api\/v\d\/top\/ad url reject-200
# > jiaohangmaidanba
^https?:\/\/creditcardapp\.bankcomm\.com\/mapp\/common\/(queryGuidePageAds|getPopAds)\.do$ url reject
# > jiemianxinwen
@@ -501,12 +502,12 @@ https:\/\/yanxuan.nosdn.127.net\/.*\.mp4 url reject
^https?:\/\/edith\.xiaohongshu\.com\/api\/sns\/v\d\/system_service\/config\? url script-response-body https://cdn.jsdelivr.net/gh/ddgksf2013/Scripts@master/xiaohongshu.js
^https?:\/\/edith\.xiaohongshu\.com\/api\/sns\/v\d\/search\/hot_list url response-body items":\[.+\] response-body items":[]
^https?:\/\/edith\.xiaohongshu\.com\/api\/sns\/v\d\/search\/trending url response-body queries":\[.+\] response-body queries":[]
-^https?:\/\/www\.xiaohongshu\.com\/api\/sns\/v\d\/tag\/ads_engage url reject
-^https?:\/\/www\.xiaohongshu\.com\/api\/sns\/v\d\/ads\/apple\/record url reject
-^https?:\/\/www\.xiaohongshu\.com\/api\/sns\/v\d\/ads\/resource url reject
-^https?:\/\/referee\.xiaohongshu\.com\/v\d\/stateReport url reject
-^https?:\/\/pages\.xiaohongshu\.com\/data\/native\/matrix_switches url reject
-^https?:\/\/edith\.xiaohongshu\.com\/api\/sns\/v\d\/user\/teenager\/status url reject
+^https?:\/\/www\.xiaohongshu\.com\/api\/sns\/v\d\/tag\/ads_engage url reject-200
+^https?:\/\/www\.xiaohongshu\.com\/api\/sns\/v\d\/ads\/apple\/record url reject-200
+^https?:\/\/www\.xiaohongshu\.com\/api\/sns\/v\d\/ads\/resource url reject-200
+^https?:\/\/referee\.xiaohongshu\.com\/v\d\/stateReport url reject-200
+^https?:\/\/pages\.xiaohongshu\.com\/data\/native\/matrix_switches url reject-200
+^https?:\/\/edith\.xiaohongshu\.com\/api\/sns\/v\d\/user\/teenager\/status url reject-200
# > XiaoTe
^https?:\/\/lcen\.xiaote\.net\/api\/graphql url response-body screenSplashAd response-body ddgksf2013
# > XiaoShuiMian
diff --git a/Rewrite/AdBlock/Weibo.conf b/Rewrite/AdBlock/Weibo.conf
index 80d9a84..5c3295a 100644
--- a/Rewrite/AdBlock/Weibo.conf
+++ b/Rewrite/AdBlock/Weibo.conf
@@ -6,12 +6,12 @@
// @TgChannel https://t.me/ddgksf2021
// @Contribute https://t.me/ddgksf2013_bot
// @Feedback 📮 ddgksf2013@163.com 📮
-// @UpdateTime 2023-01-24
+// @UpdateTime 2023-02-08
// @Attention 微博、微博国际版净化,现已二合一,使用中若有问题请发邮件!
// @Function 让你更加愉悦的刷微博
// @Suitable 自行观看“# > ”注释内容
// @Attention 如需引用请注明出处,谢谢合作!
-// @Version V2.0.56
+// @Version V2.0.58
// @ScriptURL https://github.com/ddgksf2013/Rewrite/raw/master/AdBlock/Weibo.conf
// ==/UserScript==
@@ -66,7 +66,8 @@
# [+]2023-01-18 47、屏蔽微博客户端首页左上角每日的弹窗tips
# [+]2023-01-22 48、去除微博热搜对应某关键词下信息流中的遗留广告
# [+]2023-01-24 49、去除微博底部超话栏表层浮icon及tips
-
+# [+]2023-02-03 50、解决微博用户置顶博文消失的bug,同时新增去除搜索框下方的猜你想搜条目
+# [+]2023-02-08 51、修复首页‘可能感兴趣的人’card失效bug,同时去除搜索页面中部比较窄的‘热门微博’字样的CARD,使信息流保持一致
hostname = *api.weibo*, *uve.weibo.com, new.vip.weibo.cn
diff --git a/Rewrite/AdBlock/Zhihu.adblock b/Rewrite/AdBlock/Zhihu.adblock
new file mode 100644
index 0000000..9bcd2a4
--- /dev/null
+++ b/Rewrite/AdBlock/Zhihu.adblock
@@ -0,0 +1,104 @@
+
+hostname = 118.89.204.198,103.41.167.237,2402:4e00:1200:ed00:0:9089:6dac:96b6,www.zhihu.com,api.zhihu.com,zhuanlan.zhihu.com,appcloud2.zhihu.com,m-cloud.zhihu.com,103.41.167.236,103.41.167.234,103.41.167.235,103.41.167.226
+
+# 拦截DNS解析
+^https?:\/\/118\.89\.204\.198 url reject-dict
+^https?:\/\/103\.41\.167\.237 url reject-dict
+^https?:\/\/2402:4e00:1200:ed00:0:9089:6dac:96b6 url reject-200
+
+# 屏蔽下发的配置,如皮肤等
+^https?:\/\/api\.zhihu\.com\/ab\/api\/v1\/products\/zhihu\/platforms\/ios\/config url reject
+
+# 屏蔽我的页面开通会员的卡片
+# ^https?:\/\/api\.zhihu\.com\/unlimited\/go\/my_card url reject
+
+# 拦截开屏广告
+^https?:\/\/api\.zhihu\.com\/commercial_api\/launch_v2\? url reject-dict
+^https?:\/\/api\.zhihu\.com\/commercial_api\/real_time_launch_v2\? url reject-dict
+
+# 拦截品牌提问广告
+^https?:\/\/api\.zhihu\.com\/brand\/question\/\d+/card\? url reject-dict
+^https?:\/\/www\.zhihu\.com\/api\/v\d+\/brand\/question/\d+/card\? url reject-dict
+
+# 去除底部标签页关注人角标
+^https?:\/\/api\.zhihu\.com\/moments\/tab_v2 url reject-dict
+
+# 去除消息通知角标
+^https?:\/\/api\.zhihu\.com\/(notifications\/v\d\/count) url reject-dict
+
+# 拦截回答下的卡片广告
+^https?:\/\/www\.zhihu\.com\/api\/v\d\/answers\/\d+\/recommendations url reject-dict
+
+# 拦截应用内弹窗
+^https?:\/\/api\.zhihu\.com\/me\/guides url reject-dict
+
+# 去除关注页最常访问
+^https?:\/\/api\.zhihu\.com\/moments\/recent url reject-dict
+
+# 拦截推荐页顶部广告
+^https?:\/\/api\.zhihu\.com\/api\/v4\/ecom_data\/config url reject-dict
+
+# 底栏加号的广告
+^https?:\/\/api\.zhihu\.com\/content-distribution-core\/bubble\/common\/settings url reject-dict
+
+# 推荐页搜索栏左侧图标
+^https?:\/\/api\.zhihu\.com\/feed\/render\/revisit\/current_reading url reject-dict
+
+# 疑似推荐页内容更新红点
+^https?:\/\/api\.zhihu\.com\/feed\/render\/revisit\/tag_config url reject-dict
+
+# 暂不清楚作用
+^https?:\/\/api\.zhihu\.com\/commercial_api\/banners_v3\/app_topstory_banner url reject-dict
+
+# 获取用户信息 - 隔离用户数据,开启本地会员等
+^https?:\/\/api\.zhihu\.com\/people\/ url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 关键词屏蔽 - 解锁本地的关键词屏蔽功能,需要开启本地VIP
+^https?:\/\/api\.zhihu\.com\/feed-root\/block url script-analyze-echo-response https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 优化软件配置 - 优化下发的配置文件来实现某些效果
+^https?:\/\/m-cloud\.zhihu\.com\/api\/cloud\/config\/all\? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+^https?:\/\/appcloud2\.zhihu\.com\/v\d+\/config url script-analyze-echo-response https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 用户信息 - 修改用户盐值
+^https?:\/\/api\.zhihu\.com\/user-credit\/basis url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 关注页 - 内容优化及屏蔽转发的黑名单用户想法
+^https?:\/\/api\.zhihu\.com\/moments_v3\? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 推荐页 - 移除黑名单用户发布的文章、去除广告,及自定义一些屏蔽项目
+^https:\/\/api\.zhihu\.com\/topstory\/recommend url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 黑名单页 - 同步黑名单数据
+^https?:\/\/api\.zhihu\.com\/settings\/blocked_users url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 问题的回答列表 - 移除黑名单用户的回答、去除广告
+^https?:\/\/api\.zhihu\.com\/(v4\/)?questions\/\d+ url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 回答信息流 - 移除黑名单用户的回答、去除广告
+^https?:\/\/api\.zhihu\.com\/next-data url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 回答页底部评论摘要 - 移除黑名单用户发表的评论
+^https?:\/\/www\.zhihu\.com\/api\/v4\/comment_v5\/answers\/\d+\/abstract_comment\? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 评论页及子页面 - 去除黑名单用户发表的评论
+^https?:\/\/api\.zhihu\.com\/(comment_v5\/)?(answers|comments?|articles|pins)\/\d+\/(root_|child_)?comments? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 消息页 - 折叠官方消息、屏蔽营销消息
+^https?:\/\/api\.zhihu\.com\/notifications\/v3\/(message|timeline\/entry\/system_message) url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 回答页 - 内容优化,付费、营销、推广内容文首提醒
+^https?:\/\/www\.zhihu\.com\/appview\/v2\/answer\/.*(entry=(?!(preload-topstory|preload-search|preload-subscription)))? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 回答页 - 屏蔽下翻出现的黑名单用户的回答
+^https?:\/\/api\.zhihu\.com\/next\? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 文章页 - 去除底部广告
+^https?:\/\/www\.zhihu\.com\/api\/v\d\/articles\/\d+\/recommendation\? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 热榜页 - 去除广告
+^https?:\/\/api\.zhihu\.com\/topstory\/hot-lists?(\?|\/) url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
+# 搜索页 - 去除预置广告
+^https?:\/\/api\.zhihu\.com\/search\/preset_words\? url script-response-body https://cdn.jsdelivr.net/gh/sve1r/Rules-For-Quantumult-X@develop/Scripts/AdBlock/Zhihu/Zhihu.js
+
diff --git a/Scripts/AdBlock/Other/Cainiao.js b/Scripts/AdBlock/Other/Cainiao.js
new file mode 100644
index 0000000..0c734f2
--- /dev/null
+++ b/Scripts/AdBlock/Other/Cainiao.js
@@ -0,0 +1,16 @@
+const version = "V1.0.16";
+
+var respBody = JSON.parse($response.body);
+-1 !=
+$request.url.indexOf("mtop.cainiao.nbpresentation.protocol.homepage.get.cn")
+ ? respBody.data?.result?.dataList?.length > 0 &&
+ (respBody.data.result.dataList = respBody.data.result.dataList.filter(
+ (d) => "big_banner_area_v870" != d.type
+ ))
+ : -1 != $request.url.indexOf("mtop.cainiao.guoguo.nbnetflow.ads.index.cn")
+ ? respBody.data?.result && (respBody.data.result = [])
+ : -1 != $request.url.indexOf("mtop.cainiao.adkeyword") &&
+ respBody.data?.result?.adHotKeywords &&
+ (respBody.data.result.adHotKeywords = []);
+var body = JSON.stringify(respBody);
+$done({ body });
diff --git a/Scripts/AdBlock/Weibo/weibo_json.js b/Scripts/AdBlock/Weibo/weibo_json.js
index 9f4eb61..9da9cc2 100644
--- a/Scripts/AdBlock/Weibo/weibo_json.js
+++ b/Scripts/AdBlock/Weibo/weibo_json.js
@@ -2,7 +2,7 @@
> 应用名称:墨鱼自用微博&微博国际版净化脚本
> 脚本作者:@Zmqcherish, @ddgksf2013
> 微信账号:墨鱼手记
-> 更新时间:2022-01-22
+> 更新时间:2022-02-07
> 通知频道:https://t.me/ddgksf2021
> 贡献投稿:https://t.me/ddgksf2013_bot
> 原作者库:https://github.com/zmqcherish
@@ -12,7 +12,7 @@
> 脚本声明:若有侵犯原作者权利,请邮箱联系删除
***********************************************/
-const version = "V2.0.91";
+const version = "V2.0.95";
const mainConfig = {
isDebug: !1,
@@ -179,7 +179,11 @@ function removeMainTab(e) {
for (let o of e.items)
isAd(o.data) ||
(o.data?.common_struct && delete o.data.common_struct,
- o.category ? "group" != o.category && t.push(o) : t.push(o));
+ o.category
+ ? "group" != o.category
+ ? t.push(o)
+ : -1 != JSON.stringify(o.items).indexOf("profile_top") && t.push(o)
+ : t.push(o));
return (e.items = t), log("removeMainTab success"), e;
}
function removeMain(e) {
@@ -274,6 +278,7 @@ function checkSearchWindow(e) {
e.data?.itemid == "more_frame" ||
e.data?.card_type == 208 ||
e.data?.card_type == 217 ||
+ e.data?.card_type == 101 ||
e.data?.card_type == 19 ||
e.data?.mblog?.page_info?.actionlog?.source?.includes("ad"))
);
@@ -325,6 +330,7 @@ function removeCards(e) {
if ((e.hotwords && (e.hotwords = []), !e.cards)) return;
let t = [];
for (let o of e.cards) {
+ if (17 == o.card_type || 58 == o.card_type) continue;
let i = o.card_group;
if (i && i.length > 0) {
let n = [];
diff --git a/Scripts/AdBlock/Zhihu/Zhihu.js b/Scripts/AdBlock/Zhihu/Zhihu.js
index e76ca94..16da55c 100644
--- a/Scripts/AdBlock/Zhihu/Zhihu.js
+++ b/Scripts/AdBlock/Zhihu/Zhihu.js
@@ -1,1288 +1,1376 @@
-const scriptName = "知乎助手";
+const scriptName = "哲也同学";
const blockedUsersKey = "zhihu_blocked_users";
const currentUserInfoKey = "zhihu_current_userinfo";
const keywordBlockKey = "zhihu_keyword_block";
+const blackAnswersIdKey = "zhihu_black_answers";
+const userCreditScore = "zhihu_credit_score";
// 默认屏蔽推荐列表的用户,通常不是真实用户,无法通过加入黑名单屏蔽
-const defaultAnswerBlockedUsers = ["会员推荐"];
+const defaultAnswerBlockedUsers = ["会员推荐", "盐选推荐"];
const keywordMaxCount = 1000; // 允许设置的关键词数量
const $ = MagicJS(scriptName, "INFO");
-(() => {
- let response = null;
- if ($.isResponse) {
- switch (true) {
- // 知乎8.3.0移除推荐页顶部项
- case $.data.read("zhihu_settings_remove_sections", false) === true &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/feed-root\/sections\/query\/v2/.test(
- $.request.url
- ):
- response = removeFeedSections();
- break;
- // 回答内容优化
- case $.data.read("zhihu_settings_answer_tip", true) === true &&
- /^https?:\/\/(www\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/appview\/v2\/answer\/.*(entry=(?!(preload-topstory|preload-search|preload-subscription)))?/.test(
- $.request.url
- ):
- response = modifyAnswer();
- break;
- // 处理登录用户信息
- case /^https:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/people\/self$/.test(
- $.request.url
- ):
- response = processUserInfo();
- break;
- // 黑名单增强 - 浏览黑名单用户信息时自动加入脚本黑名单
- case $.data.read("zhihu_settings_blocked_users", true) === true &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/people\/((?!self).)*$/.test(
- $.request.url
- ):
- response = autoInsertBlackList();
- break;
- // 推荐去广告与黑名单增强
- case /^https:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/topstory\/recommend\?/.test(
- $.request.url
- ):
- response = removeRecommendAds();
- break;
- // 关注列表去广告
- case /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/moments(\/|\?)?(recommend|action=|feed_type=)(?!\/people)/.test(
- $.request.url
- ):
- response = removeMomentsAds();
- break;
- // 回答列表去广告与黑名单增强
- case /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/(v4\/)?questions\/\d+/.test(
- $.request.url
- ):
- response = removeQuestionsAds();
- break;
- // 知乎V5版本评论去广告及黑名单增强
- case /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/comment_v5\/(answers|pins|comments?|articles)\/\d+\/(root|child)_comment/.test(
- $.request.url
- ):
- response = removeCommentV5Ads();
- break;
- // 知乎旧版回答中的评论黑名单增强
- case /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/(answers|pins|comments?|articles)\/\d+\/(root|child)_comments/.test(
- $.request.url
- ):
- response = removeCommentAds();
- break;
- // 知乎热榜去广告
- case $.data.read("zhihu_settings_hot_list", true) === true &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/topstory\/hot-lists?(\?|\/)/.test(
- $.request.url
- ):
- response = removeHotListAds();
- break;
- // 拦截官方账号推广消息
- case $.data.read("zhihu_settings_sys_msg", true) === true &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/notifications\/v3\/timeline\/entry\/system_message/.test(
- $.request.url
- ):
- response = removeSysMsgAds();
- break;
- // 屏蔽官方营销消息
- case $.data.read("zhihu_settings_sys_msg", true) != false &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/notifications\/v3\/message/.test(
- $.request.url
- ):
- response = removeMarketingMsg();
- break;
- // 去除预置关键字广告
- case $.data.read("zhihu_settings_preset_words", false) == true &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/search\/preset_words\?/.test(
- $.request.url
- ):
- response = removeKeywordAds();
- break;
- // 优化知乎软件配置
- case $.data.read("zhihu_settings_app_conf") == true &&
- /^https?:\/\/appcloud2\.zhihu\.com\/v\d+\/config/.test($.request.url):
- response = modifyAppConfig();
- break;
- // 知乎热搜去广告
- case $.data.read("zhihu_settings_hot_search") == true &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/search\/top_search\/tabs\/hot\/items/.test(
- $.request.url
- ):
- response = removeHotSearchAds();
- break;
- // 黑名单管理
- case $.data.read("zhihu_settings_blocked_users") != false &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/settings\/blocked_users/.test(
- $.request.url
- ):
- manageBlackUser();
- break;
- default:
- break;
- }
- } else if ($.isRequest) {
- // 知乎屏蔽关键词解锁
- if (
- $.data.read("zhihu_settings_blocked_keywords") != false &&
- /^https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/feed-root\/block/.test(
- $.request.url
- ) === true
- ) {
- response = unlockBlockedKeywords(response);
- }
+/**
+ * @description: 获取用户信息
+ * @return {*}
+ */
+function getUserInfo() {
+ let defaultUserInfo = { id: "default", is_vip: false };
+ try {
+ let userInfo = $.data.read(currentUserInfoKey);
+ if (typeof userInfo === "string") userInfo = JSON.parse(userInfo);
+ if (!!userInfo && userInfo.hasOwnProperty("id")) {
+ return userInfo;
} else {
- $.data.del(currentUserInfoKey);
- $.data.del(blockedUsersKey);
- $.data.del(keywordBlockKey);
- $.notification.post("知乎助手数据清理完毕");
+ return defaultUserInfo;
}
- if (response) {
- $.done(response);
- } else {
- $.done();
- }
-})();
-
-/**
- * 屏蔽官方营销消息
- *
- * @param {*}
- * @return {*}
- */
-function removeMarketingMsg() {
- let response = null;
- try {
- let obj = JSON.parse($.response.body);
- let newItems = [];
- for (let item of obj["data"]) {
- if (item["detail_title"] === "官方帐号消息") {
- let unread_count = item["unread_count"];
- if (unread_count > 0) {
- item["content"]["text"] = "未读消息" + unread_count + "条";
- } else {
- item["content"]["text"] = "全部消息已读";
- }
- item["is_read"] = true;
- item["unread_count"] = 0;
- newItems.push(item);
- } else if (item["detail_title"] !== "知乎活动助手") {
- newItems.push(item);
- }
- }
- obj["data"] = newItems;
- response = { body: JSON.stringify(obj) };
- } catch (err) {
- $.logger.error(`知乎屏蔽官方营销消息出现异常:${err}`);
- }
- return response;
+ } catch (err) {
+ $.logger.error(`获取用户信息出现异常:${err}`);
+ return defaultUserInfo;
+ }
}
/**
- * 知乎屏蔽关键词解锁
- *
- * @param {*}
- * @return {*}
- */
-function unlockBlockedKeywords() {
- let response = null;
- try {
- const userInfo = getUserInfo();
- // 获取屏蔽关键词列表
- if ($.request.method === "GET") {
- let keywords = $.data.read(keywordBlockKey, null, userInfo.id);
- if (!keywords) {
- keywords = [];
- }
- let headers = {
- "Cache-Control":
- "no-cache, no-store, must-revalidate, private, max-age=0",
- Connection: "keep-alive",
- "Content-Type": "application/json;charset=utf-8",
- Pragma: "no-cache",
- "Referrer-Policy": "no-referrer-when-downgrade",
- Server: "CLOUD ELB 1.0.0",
- Vary: "Accept-Encoding",
- "X-Cache-Lookup": "Cache Miss",
- "x-cdn-provider": "tencent",
- };
- let body = JSON.stringify({
- success: true,
- is_vip: true,
- kw_min_length: 2,
- kw_max_length: 100,
- kw_max_count: keywordMaxCount,
- data: keywords,
- });
- if ($.env.isQuanX) {
- response = { body: body, headers: headers, status: "HTTP/1.1 200 OK" };
- } else {
- response = { response: { body: body, headers: headers, status: 200 } };
- }
- $.logger.debug(`获取本地脚本屏蔽关键词:\n${keywords.join("、")}`);
- }
-
- // 添加屏蔽关键词
- else if ($.request.method === "POST") {
- if (!!$.request.body) {
- // 构造 response headers
- let headers = {
- "Cache-Control":
- "no-cache, no-store, must-revalidate, private, max-age=0",
- Connection: "keep-alive",
- "Content-Type": "application/json;charset=utf-8",
- Pragma: "no-cache",
- "Referrer-Policy": "no-referrer-when-downgrade",
- Server: "CLOUD ELB 1.0.0",
- Vary: "Accept-Encoding",
- "X-Cache-Lookup": "Cache Miss",
- "x-cdn-provider": "tencent",
- };
- // 读取关键词
- let keyword = decodeURIComponent($.request.body).match(
- /keyword=(.*)/
- )[1];
- let keywords = $.data.read(keywordBlockKey, null, userInfo.id);
- if (!keywords) {
- keywords = [];
- }
- // 判断关键词是否存在
- let keywordExists = false;
- for (let i = 0; i < keywords.length; i++) {
- if (keyword === keywords[i]) {
- keywordExists = true;
- break;
- }
- }
- // 不存在添加,存在返回异常
- if (keywordExists === false) {
- keywords.push(keyword);
- $.data.write(keywordBlockKey, keywords, userInfo.id);
- let body = JSON.stringify({ success: true });
- if ($.env.isQuanX) {
- response = {
- body: body,
- headers: headers,
- status: "HTTP/1.1 200 OK",
- };
- } else {
- response = {
- response: { body: body, headers: headers, status: 200 },
- };
- }
- $.logger.debug(`添加本地脚本屏蔽关键词“${keyword}”`);
- } else {
- let body = JSON.stringify({
- error: {
- message: "关键词已存在",
- code: 100002,
- },
- });
- if ($.env.isQuanX) {
- response = {
- body: body,
- headers: headers,
- status: "HTTP/1.1 400 Bad Request",
- };
- } else {
- response = {
- response: { body: body, headers: headers, status: 400 },
- };
- }
- }
- }
- }
-
- // 删除屏蔽关键词
- else if ($.request.method === "DELETE") {
- let keyword = decodeURIComponent($.request.url).match(/keyword=(.*)/)[1];
- let keywords = $.data.read(keywordBlockKey, null, userInfo.id);
- if (!keywords) {
- keywords = [];
- }
- keywords = keywords.filter((e) => {
- return e !== keyword;
- });
- $.data.write(keywordBlockKey, keywords, userInfo.id);
- let headers = {
- "Cache-Control":
- "no-cache, no-store, must-revalidate, private, max-age=0",
- Connection: "keep-alive",
- "Content-Type": "application/json;charset=utf-8",
- Pragma: "no-cache",
- "Referrer-Policy": "no-referrer-when-downgrade",
- Server: "CLOUD ELB 1.0.0",
- Vary: "Accept-Encoding",
- "X-Cache-Lookup": "Cache Miss",
- "x-cdn-provider": "tencent",
- };
- let body = JSON.stringify({ success: true });
- if ($.env.isQuanX) {
- response = { body: body, headers: headers, status: "HTTP/1.1 200 OK" };
- } else {
- response = { response: { body: body, headers: headers, status: 200 } };
- }
- $.logger.debug(`删除本地脚本屏蔽关键词:“${keyword}”`);
- }
- } catch (err) {
- $.logger.debug(`知乎关键词屏蔽操作出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 知乎热搜去广告
- *
- * @param {*}
- * @return {*}
- */
-function removeHotSearchAds() {
- let response = null;
- try {
- if (!!$.response.body) {
- let obj = JSON.parse($.response.body);
- obj["commercial_data"] = [];
- response = { body: JSON.stringify(obj) };
- }
- } catch (err) {
- $.logger.error(`去除知乎热搜广告出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 优化知乎软件配置
- *
- * @param {*}
+ * 优化软件配置
* @return {*}
*/
function modifyAppConfig() {
- let response = null;
- try {
- if (!!$.response.body) {
- let obj = JSON.parse($.response.body);
- let tab_infos = obj["config"]["homepage_feed_tab"]["tab_infos"].filter(
- (e) => {
- if (e.tab_type === "activity_tab") {
- e.end_time = (Date.parse(new Date()) - 120000)
- .toString()
- .substr(0, 10);
- return true;
- } else {
- return false;
- }
- }
- );
- obj["config"]["homepage_feed_tab"]["tab_infos"] = tab_infos;
- obj["config"]["zvideo_max_number"] = 1;
- // 试着去除一些配置,效果待验证
- delete obj["config"]["soso_des"];
- delete obj["config"]["cronet"];
- // 屏蔽知乎8.X版本以上本地DNS解析,以下修改不清楚哪些是有效的,暂时全部保留
- if (obj["config"].hasOwnProperty("zhcnh_thread_sync")) {
- $.logger.debug(JSON.stringify(obj["config"]["zhcnh_thread_sync"]));
- obj["config"]["zhcnh_thread_sync"]["LocalDNSSetHostWhiteList"] = [];
- obj["config"]["zhcnh_thread_sync"]["isOpenLocalDNS"] = "0";
- obj["config"]["zhcnh_thread_sync"]["ZHBackUpIP_Switch_Open"] = "0";
- obj["config"]["zhcnh_thread_sync"]["dns_ip_detector_operation_lock"] =
- "1";
- obj["config"]["zhcnh_thread_sync"][
- "ZHHTTPSessionManager_setupZHHTTPHeaderField"
- ] = "1";
- }
- response = { body: JSON.stringify(obj) };
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ let obj = JSON.parse($.response.body);
+ obj["config"]["homepage_feed_tab"]["tab_infos"] = obj["config"][
+ "homepage_feed_tab"
+ ]["tab_infos"].filter((e) => {
+ // 将活动标签设置为已过期
+ if (e["tab_type"] === "activity_tab") {
+ e["end_time"] = (new Date() - 120000).toString().slice(0, 10);
+ return true;
+ } else {
+ return false;
}
- } catch (err) {
- $.logger.error(`优化知乎软件配置出现异常:${err}`);
+ });
+ obj["config"]["zvideo_max_number"] = 1;
+ // 似乎是控制内部弹窗
+ obj["config"]["is_show_followguide_alert"] = false;
+ // 似乎是某个地方的标签,待定
+ delete obj["config"]["hp_channel_tab"];
+ // 灰色模式
+ if (obj["config"]["zombie_conf"]) {
+ obj["config"]["zombie_conf"]["zombieEnable"] = false;
+ }
+ if (obj["config"]["gray_mode"]) {
+ obj["config"]["gray_mode"]["enable"] = false;
+ obj["config"]["gray_mode"]["start_time"] = "4092566400";
+ obj["config"]["gray_mode"]["end_time"] = "4092566400";
+ }
+ // 屏蔽8.X版本以上本地DNS解析,以下修改不清楚哪些是有效的,暂时全部保留
+ if (obj["config"].hasOwnProperty("zhcnh_thread_sync")) {
+ $.logger.debug(JSON.stringify(obj["config"]["zhcnh_thread_sync"]));
+ obj["config"]["zhcnh_thread_sync"]["LocalDNSSetHostWhiteList"] = [];
+ obj["config"]["zhcnh_thread_sync"]["isOpenLocalDNS"] = "0";
+ obj["config"]["zhcnh_thread_sync"]["ZHBackUpIP_Switch_Open"] = "0";
+ obj["config"]["zhcnh_thread_sync"]["dns_ip_detector_operation_lock"] =
+ "1";
+ obj["config"]["zhcnh_thread_sync"][
+ "ZHHTTPSessionManager_setupZHHTTPHeaderField"
+ ] = "1";
+ }
+ response = { body: JSON.stringify(obj) };
}
- return response;
+ } catch (err) {
+ $.logger.error(`优化软件配置出现异常:${err}`);
+ }
+ return response;
}
/**
- * 去除预置关键字广告
- *
- * @param {*}
+ * 修改云端下发的配置
* @return {*}
*/
-function removeKeywordAds() {
- let response = null;
- try {
- if (!!$.response.body) {
- $.logger.debug(`预置关键字返回:${$.response.body}`);
- let obj = JSON.parse($.response.body);
- if (obj.hasOwnProperty("preset_words") && obj["preset_words"]["words"]) {
- let words = obj["preset_words"]["words"].filter((element) => {
- return element["type"] !== "ad";
- });
- obj["preset_words"]["words"] = words;
- response = { body: JSON.stringify(obj) };
- }
- }
- } catch (err) {
- $.logger.error(`知乎去除预置关键字广告出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 拦截官方账号推广消息
- *
- * @param {*}
- * @return {*}
- */
-function removeSysMsgAds() {
- let response = null;
- try {
- const sysmsg_blacklist = [
- "知乎小伙伴",
- "知乎视频",
- "知乎团队",
- "知乎礼券",
- "知乎读书会团队",
- ];
- let obj = JSON.parse($.response.body);
- let data = obj["data"].filter((element) => {
- return sysmsg_blacklist.indexOf(element["content"]["title"]) < 0;
+function modifyMCloudConfig() {
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ let obj = JSON.parse($.response.body);
+ if (obj.data && obj.data["configs"]) {
+ // 去除灰色主题
+ obj.data["configs"].forEach((element) => {
+ if (element["configKey"] === "feed_gray_theme") {
+ element["configValue"].start_time = "1669824000";
+ element["configValue"].end_time = "1669824001";
+ element.status = false;
+ }
});
- obj["data"] = data;
- response = { body: JSON.stringify(obj) };
- } catch (err) {
- $.logger.error(`知乎拦截官方账号推广消息出现异常:${err}`);
+ }
+ const body = JSON.stringify(obj);
+ $.logger.debug(body);
+ response = { body: body };
}
- return response;
+ } catch (err) {
+ $.logger.error(`优化软件配置出现异常:${err}`);
+ }
+ return response;
}
/**
- * 知乎热榜去广告
- *
- * @param {*}
+ * 屏蔽关键词解锁
* @return {*}
*/
-function removeHotListAds() {
- let response = null;
- try {
- if (!!$.response.body) {
- let obj = JSON.parse($.response.body);
- if ("data" in obj) {
- let data = obj["data"].filter((e) => {
- return (
- e["type"] === "hot_list_feed" || e["type"] === "hot_list_feed_video"
- );
- });
- obj["data"] = data;
- }
- response = { body: JSON.stringify(obj) };
- }
- } catch (err) {
- $.logger.error(`去除知乎热榜广告出现异常:${err}`);
+function unlockBlockedKeywords() {
+ let response = null;
+ try {
+ const userInfo = getUserInfo();
+ // 获取屏蔽关键词列表
+ if ($.request.method === "GET") {
+ let keywords = $.data.read(keywordBlockKey, null, userInfo.id);
+ if (!keywords) {
+ keywords = [];
+ }
+ let headers = {
+ "Cache-Control":
+ "no-cache, no-store, must-revalidate, private, max-age=0",
+ Connection: "keep-alive",
+ "Content-Type": "application/json;charset=utf-8",
+ Pragma: "no-cache",
+ "Referrer-Policy": "no-referrer-when-downgrade",
+ Server: "CLOUD ELB 1.0.0",
+ Vary: "Accept-Encoding",
+ "X-Cache-Lookup": "Cache Miss",
+ "x-cdn-provider": "tencent",
+ };
+ let body = JSON.stringify({
+ success: true,
+ is_vip: true,
+ kw_min_length: 2,
+ kw_max_length: 100,
+ kw_max_count: keywordMaxCount,
+ data: keywords,
+ });
+ if ($.env.isQuanX) {
+ response = { body: body, headers: headers, status: "HTTP/1.1 200 OK" };
+ } else {
+ response = { response: { body: body, headers: headers, status: 200 } };
+ }
+ $.logger.debug(`获取本地脚本屏蔽关键词:\n${keywords.join("、")}`);
}
- return response;
-}
-/**
- * 知乎旧版回答中的评论黑名单增强
- *
- * @param {*}
- * @return {*}
- */
-function removeCommentAds() {
- let response = null;
- try {
- if (!!$.response.body) {
- // 评论区去广告
- let obj = JSON.parse($.response.body);
- if ($.data.read("zhihu_settings_blocked_users") != false) {
- // 屏蔽黑名单用户
- let user_info = getUserInfo();
- let customBlockedUsers = $.data.read(blockedUsersKey, "", user_info.id);
- let newData = [];
- obj.data.forEach((comment) => {
- // 评论人昵称
- let commentUserName = comment.author.member.name;
- // 回复哪个人的评论(仅适用于独立子评论页面请求)
- let replyUserName = "";
- if (
- comment.reply_to_author &&
- comment.reply_to_author.member &&
- comment.reply_to_author.member.name
- ) {
- replyUserName = comment.reply_to_author.member.name;
- }
- if (
- customBlockedUsers[commentUserName] ||
- customBlockedUsers[replyUserName]
- ) {
- if (
- customBlockedUsers[commentUserName] &&
- !replyUserName &&
- $.request.url.indexOf("root_comment") > 0
- ) {
- $.notification.debug(
- `屏蔽黑名单用户“${commentUserName}”的主评论。`
- );
- } else if (
- customBlockedUsers[commentUserName] &&
- !replyUserName &&
- $.request.url.indexOf("child_comment") > 0
- ) {
- $.notification.debug(
- `屏蔽黑名单用户“${commentUserName}”的子评论。`
- );
- } else if (
- customBlockedUsers[commentUserName] &&
- replyUserName &&
- $.request.url.indexOf("child_comment") > 0
- ) {
- $.notification.debug(
- `屏蔽黑名单用户“${commentUserName}”回复“${replyUserName}”的子评论。`
- );
- } else {
- $.notification.debug(
- `屏蔽“${commentUserName}”回复黑名单用户“${replyUserName}”的子评论。`
- );
- }
- // 减少主评论页面中的评论总数(仅适用于独立的主评论页面请求)
- if (obj.common_counts) {
- obj.common_counts -= 1;
- }
- // 减少子评论页面中的评论总数(仅适用于独立子评论页面请求)
- if (obj.paging && obj.paging.totals) {
- obj.paging.totals -= 1;
- }
- } else {
- // 屏蔽子评论中的黑名单用户(仅适用于独立的主评论页面请求)
- if (comment.child_comments) {
- let newChildComments = [];
- comment.child_comments.forEach((childComment) => {
- if (
- customBlockedUsers[childComment.author.member.name] ||
- customBlockedUsers[childComment.reply_to_author.member.name]
- ) {
- if (customBlockedUsers[childComment.author.member.name]) {
- $.notification.debug(
- `屏蔽黑名单用户“${childComment.author.member.name}”的主评论。`
- );
- } else {
- $.notification.debug(
- `屏蔽“${childComment.author.member.name}”回复黑名单用户“${childComment.reply_to_author.member.name}”的子评论。`
- );
- }
- comment.child_comment_count -= 1;
- } else {
- newChildComments.push(childComment);
- }
- });
- comment.child_comments = newChildComments;
- }
- newData.push(comment);
- }
- });
- obj.data = newData;
- }
- response = { body: JSON.stringify(obj) };
- }
- } catch (err) {
- $.logger.error(`去除知乎评论广告出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 知乎V5版本评论去广告及黑名单增强
- *
- * @param {*}
- * @return {*}
- */
-function removeCommentV5Ads() {
- let response = null;
- try {
- if (!!$.response.body) {
- let obj = JSON.parse($.response.body);
- obj["ad_info"] = {};
- // 屏蔽黑名单用户
- if ($.data.read("zhihu_settings_blocked_users") != false) {
- let user_info = getUserInfo();
- let customBlockedUsers = $.data.read(blockedUsersKey, "", user_info.id);
- customBlockedUsers = !!customBlockedUsers ? customBlockedUsers : {};
- let newComments = [];
- let blockCommentIdObj = {};
- obj.data.forEach((comment) => {
- // 评论人昵称
- let commentUserName = comment.author.name;
- // 回复哪个人的评论(仅适用于独立子评论页面请求)
- let replyUserName = "";
- if (
- comment.reply_to_author &&
- comment.reply_to_author &&
- comment.reply_to_author.name
- ) {
- replyUserName = comment.reply_to_author.name;
- }
- if (
- customBlockedUsers[commentUserName] ||
- customBlockedUsers[replyUserName]
- ) {
- if (
- customBlockedUsers[commentUserName] &&
- !replyUserName &&
- $.request.url.indexOf("root_comment") > 0
- ) {
- $.notification.debug(
- `屏蔽黑名单用户“${commentUserName}”的主评论。`
- );
- } else if (
- customBlockedUsers[commentUserName] &&
- !replyUserName &&
- $.request.url.indexOf("child_comment") > 0
- ) {
- $.notification.debug(
- `屏蔽黑名单用户“${commentUserName}”的子评论。`
- );
- } else if (
- customBlockedUsers[commentUserName] &&
- replyUserName &&
- $.request.url.indexOf("child_comment") > 0
- ) {
- $.notification.debug(
- `屏蔽黑名单用户“${commentUserName}”回复“${replyUserName}”的子评论。`
- );
- } else {
- $.notification.debug(
- `屏蔽“${commentUserName}”回复黑名单用户“${replyUserName}”的子评论。`
- );
- }
- blockCommentIdObj[comment.id] = commentUserName;
- // 主评论数量-1,仅适用于root_comment主评论页面请求
- if (obj.counts && obj.counts.total_counts) {
- obj.counts.total_counts -= 1;
- }
- // 子评论数量-1,仅适用于child_comment子评论页面请求
- if (obj.paging && obj.paging.totals) {
- obj.paging.totals -= 1;
- }
- if (obj.root && obj.root.child_comment_count) {
- obj.root.child_comment_count -= 1;
- }
- } else {
- if (comment.child_comments) {
- let newChildComments = [];
- comment.child_comments.forEach((childComment) => {
- let childCommentUserName = childComment.author.name;
- if (
- customBlockedUsers[childCommentUserName] ||
- blockCommentIdObj[childComment.reply_comment_id]
- ) {
- if (customBlockedUsers[childCommentUserName]) {
- $.notification.debug(
- `屏蔽黑名单用户“${childCommentUserName}”的子评论。`
- );
- blockCommentIdObj[childComment.id] = childCommentUserName;
- } else {
- $.notification.debug(
- `屏蔽“${childCommentUserName}”回复黑名单用户“${
- blockCommentIdObj[childComment.reply_comment_id]
- }”的子评论。`
- );
- }
- comment.child_comment_count -= 1;
- } else {
- newChildComments.push(childComment);
- }
- });
- comment.child_comments = newChildComments;
- }
- newComments.push(comment);
- }
- });
- obj.data = newComments;
- }
- response = { body: JSON.stringify(obj) };
- }
- } catch (err) {
- $.logger.error(`去除知乎评论广告出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 回答列表去广告与黑名单增强
- *
- * @param {*}
- * @return {*}
- */
-function removeQuestionsAds() {
- let response = null;
- try {
- const userInfo = getUserInfo();
- let customBlockedUsers = $.data.read(blockedUsersKey, "", userInfo.id);
- customBlockedUsers = !!customBlockedUsers ? customBlockedUsers : {};
- let obj = JSON.parse($.response.body);
- $.logger.debug(`当前黑名单列表: ${JSON.stringify(customBlockedUsers)}`);
- delete obj["ad_info"];
- delete obj["roundtable_info"];
- // 去除回答列表中的黑名单用户
- if ("data" in obj) {
- delete obj["data"]["ad_info"];
- let data = obj.data["data"] || obj.data;
- data = data.filter((element) => {
- let blackUserName = "";
- try {
- if ("author" in element) {
- blackUserName = element["author"]["name"];
- } else if ("target" in element) {
- blackUserName = element["target"]["author"]["name"];
- }
- } catch (ex) {
- $.logger.error(`获取回答列表用户名出现异常:${err}`);
- }
- return blackUserName == "" || !customBlockedUsers[blackUserName];
- });
- if (obj.data.hasOwnProperty("data")) {
- obj.data["data"] = data;
- } else {
- obj["data"] = data;
- }
- }
- let body = JSON.stringify(obj);
- $.logger.debug(`修改后的回答列表数据:${body}`);
- response = { body: body };
- } catch (err) {
- $.logger.error(`知乎回答列表去广告出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 关注列表去广告
- *
- * @param {*}
- * @return {*}
- */
-function removeMomentsAds() {
- let response = null;
- try {
- let obj = JSON.parse(
- $.response.body.replace(/(\w+"+\s?):\s?(\d{15,})/g, '$1:"$2"')
- );
- const user_info = getUserInfo();
- let customBlockedUsers = $.data.read(blockedUsersKey, "", user_info.id);
- customBlockedUsers = !!customBlockedUsers ? customBlockedUsers : {};
- let data = [];
-
- const settings_moments_stream =
- $.data.read("zhihu_settings_moments_stream") == true;
- const settings_blocked_users =
- $.data.read("zhihu_settings_blocked_users") != false;
-
- for (let i = 0; i < obj["data"].length; i++) {
- // let element = targetIdFix(obj["data"][i]);
- let element = obj["data"][i];
- if (!element["ad"] && !element["adjson"] && !element["ad_list"]) {
- // 判断转发的想法是否含有黑名单用户
- if (
- settings_blocked_users &&
- element.target &&
- element.target.origin_pin &&
- element.target.origin_pin.author &&
- customBlockedUsers[element.target.origin_pin.author.name]
- ) {
- $.notification.debug(
- `屏蔽“${element.target.author.name}”转发黑名单用户“${element.target.origin_pin.author.name}”的想法。`
- );
- }
-
- // 屏蔽关注页的“最新视频”
- else if (!settings_moments_stream || element["type"] != "videos") {
- data.push(element);
- }
- }
- }
- obj["data"] = data;
- response = { body: JSON.stringify(obj) };
- } catch (err) {
- $.logger.error(`知乎关注列表去广告出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 推荐去广告与黑名单增强
- *
- * @param {*}
- * @return {*}
- */
-function removeRecommendAds() {
- let response = null;
- try {
- const settings_remove_yanxuan =
- $.data.read("zhihu_settings_remove_yanxuan") == true;
- const settings_recommend_stream =
- $.data.read("zhihu_settings_recommend_stream") == true;
- const settings_remove_article =
- $.data.read("zhihu_settings_remove_article") == true;
- // 默认开启
- const settings_blocked_keywords =
- $.data.read("zhihu_settings_blocked_keywords") != false;
- const settings_blocked_users =
- $.data.read("zhihu_settings_blocked_users") != false;
- const user_info = getUserInfo();
-
- let keywords = $.data.read(keywordBlockKey, "", user_info.id);
- keywords = settings_blocked_keywords && !!keywords ? keywords : [];
- let customBlockedUsers = $.data.read(blockedUsersKey, "", user_info.id);
- customBlockedUsers =
- settings_blocked_users && !!customBlockedUsers ? customBlockedUsers : {};
-
- const dataFilter = (element) => {
- let elementStr = JSON.stringify(element);
- // 是否为广告
- let isAd =
- element["card_type"] === "slot_event_card" ||
- element["card_type"] === "slot_video_event_card" ||
- element.hasOwnProperty("ad") ||
- // 知乎训练营
- (element["extra"] && element["extra"]["type"] === "Training");
- // 是否为流媒体
- let isStream =
- isAd != true &&
- elementStr.search(
- /"(type|style)+"\s?:\s?"(drama|zvideo|Video|BIG_IMAGE)+"/i
- ) >= 0;
- let removeStream = isStream && settings_recommend_stream;
- // 是否为文章
- let isArticle =
- elementStr.search(/"(type|style)+"\s?:\s?"article"/i) >= 0;
- let removeArticle = isArticle && settings_remove_article;
- // 是否匹配脚本关键词过滤
- let matchKeyword = false;
- if (isStream != true && settings_blocked_keywords) {
- for (let i = 0; i < keywords.length; i++) {
- if (elementStr.search(keywords[i]) >= 0) {
- if ($.isDebug) {
- let elementTitle =
- element.common_card.feed_content.title.panel_text;
- let elementContent =
- element.common_card.feed_content.content.panel_text;
- let actionUrl = "";
- try {
- actionUrl =
- element.common_card.feed_content.title.action.intent_url;
- } catch {}
- $.logger.debug(
- `匹配关键字:\n${keywords[i]}\n标题:\n${elementTitle}\n内容:\n${elementContent}`
- );
- $.notification.debug(
- scriptName,
- `关键字:${keywords[i]}`,
- `${elementTitle}\n${elementContent}`,
- actionUrl
- );
- }
- matchKeyword = true;
- break;
- }
- }
- }
- // 是否为黑名单用户
- let isBlockedUser = false;
- try {
- isBlockedUser =
- matchKeyword != true &&
- settings_blocked_users &&
- customBlockedUsers &&
- element["common_card"]["feed_content"]["source_line"]["elements"][1][
- "text"
- ]["panel_text"] in customBlockedUsers;
- } catch {
- isBlockedUser = false;
- }
- return !(
- isAd ||
- removeStream ||
- matchKeyword ||
- isBlockedUser ||
- removeArticle
- );
+ // 添加屏蔽关键词
+ else if ($.request.method === "POST") {
+ if (!!$.request.body) {
+ // 构造 response headers
+ let headers = {
+ "Cache-Control":
+ "no-cache, no-store, must-revalidate, private, max-age=0",
+ Connection: "keep-alive",
+ "Content-Type": "application/json;charset=utf-8",
+ Pragma: "no-cache",
+ "Referrer-Policy": "no-referrer-when-downgrade",
+ Server: "CLOUD ELB 1.0.0",
+ Vary: "Accept-Encoding",
+ "X-Cache-Lookup": "Cache Miss",
+ "x-cdn-provider": "tencent",
};
-
- // 修复number类型精度丢失
- let obj = JSON.parse(
- $.response.body.replace(/(\w+"+\s?):\s?(\d{15,})/g, '$1:"$2"')
- );
- obj["data"] = obj["data"].filter(dataFilter);
- response = { body: JSON.stringify(obj) };
- } catch (err) {
- $.logger.error(`知乎推荐列表去广告出现异常:${err}`);
- }
- return response;
-}
-
-/**
- * 黑名单增强 - 浏览黑名单用户信息时自动加入脚本黑名单
- *
- * @param {*}
- * @return {*}
- */
-function autoInsertBlackList() {
- let response = null;
- try {
- let obj = JSON.parse($.response.body);
- // 删除MCN信息
- delete obj["mcn_user_info"];
- response = { body: JSON.stringify(obj) };
- // 如已是黑名单用户,但不在脚本黑名单中,则自动加入
- if (obj.name && obj.id && obj.is_blocking === true) {
- const userInfo = getUserInfo();
- let customBlockedUsers = $.data.read(blockedUsersKey, "", userInfo.id);
- customBlockedUsers =
- typeof customBlockedUsers === "object" && !!customBlockedUsers
- ? customBlockedUsers
- : {};
- if (!customBlockedUsers[obj.name]) {
- $.logger.debug(
- `当前需要加入黑名单的用户Id:${obj["id"]},用户名:${obj["name"]}`
- );
- customBlockedUsers[obj["name"]] = obj["id"];
- $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
- $.logger.debug(
- `${
- obj["name"]
- }写入脚本黑名单成功,当前脚本黑名单数据:${JSON.stringify(
- customBlockedUsers
- )}`
- );
- $.notification.post(`已自动将用户“${obj["name"]}”写入脚本黑名单。`);
- }
+ // 读取关键词
+ let keyword = decodeURIComponent($.request.body).match(
+ /keyword=(.*)/
+ )[1];
+ let keywords = $.data.read(keywordBlockKey, null, userInfo.id);
+ if (!keywords) {
+ keywords = [];
}
- } catch (err) {
- $.logger.error(`知乎去除MCN信息出现异常:${err}`);
+ // 判断关键词是否存在
+ let keywordExists = false;
+ for (let i = 0; i < keywords.length; i++) {
+ if (keyword === keywords[i]) {
+ keywordExists = true;
+ break;
+ }
+ }
+ // 不存在添加,存在返回异常
+ if (keywordExists === false) {
+ keywords.push(keyword);
+ $.data.write(keywordBlockKey, keywords, userInfo.id);
+ let body = JSON.stringify({ success: true });
+ if ($.env.isQuanX) {
+ response = {
+ body: body,
+ headers: headers,
+ status: "HTTP/1.1 200 OK",
+ };
+ } else {
+ response = {
+ response: { body: body, headers: headers, status: 200 },
+ };
+ }
+ $.logger.debug(`添加本地脚本屏蔽关键词“${keyword}”`);
+ } else {
+ let body = JSON.stringify({
+ error: {
+ message: "关键词已存在",
+ code: 100002,
+ },
+ });
+ if ($.env.isQuanX) {
+ response = {
+ body: body,
+ headers: headers,
+ status: "HTTP/1.1 400 Bad Request",
+ };
+ } else {
+ response = {
+ response: { body: body, headers: headers, status: 400 },
+ };
+ }
+ }
+ }
}
- return response;
+
+ // 删除屏蔽关键词
+ else if ($.request.method === "DELETE") {
+ let keyword = decodeURIComponent($.request.url).match(/keyword=(.*)/)[1];
+ let keywords = $.data.read(keywordBlockKey, null, userInfo.id);
+ if (!keywords) {
+ keywords = [];
+ }
+ keywords = keywords.filter((e) => {
+ return e !== keyword;
+ });
+ $.data.write(keywordBlockKey, keywords, userInfo.id);
+ let headers = {
+ "Cache-Control":
+ "no-cache, no-store, must-revalidate, private, max-age=0",
+ Connection: "keep-alive",
+ "Content-Type": "application/json;charset=utf-8",
+ Pragma: "no-cache",
+ "Referrer-Policy": "no-referrer-when-downgrade",
+ Server: "CLOUD ELB 1.0.0",
+ Vary: "Accept-Encoding",
+ "X-Cache-Lookup": "Cache Miss",
+ "x-cdn-provider": "tencent",
+ };
+ let body = JSON.stringify({ success: true });
+ if ($.env.isQuanX) {
+ response = { body: body, headers: headers, status: "HTTP/1.1 200 OK" };
+ } else {
+ response = { response: { body: body, headers: headers, status: 200 } };
+ }
+ $.logger.debug(`删除本地脚本屏蔽关键词:“${keyword}”`);
+ }
+ } catch (err) {
+ $.logger.debug(`关键词屏蔽操作出现异常:${err}`);
+ }
+ return response;
}
/**
* 处理登录用户信息
*
- * @param {*}
* @return {*}
*/
function processUserInfo() {
- let response = null;
- try {
- let obj = JSON.parse($.response.body);
- $.logger.debug(`用户登录用户信息,接口响应:${$.response.body}`);
- if (
- obj &&
- obj["id"] &&
- obj.hasOwnProperty("vip_info") &&
- obj["vip_info"].hasOwnProperty("is_vip")
- ) {
- const userInfo = {
- id: obj["id"],
- is_vip: obj["vip_info"]["is_vip"]
- ? obj["vip_info"]["is_vip"] !== undefined
- : false,
- };
- $.logger.debug(
- `当前用户id:${obj["id"]},是否为VIP:${obj["vip_info"]["is_vip"]}`
- );
- $.data.write(currentUserInfoKey, userInfo);
- // 在知乎APP显示VIP,仅自己可见,打开后才能使用屏蔽关键词解锁
- if (
- $.data.read("zhihu_settings_fake_vip") != false &&
- obj["vip_info"]["is_vip"] === false
- ) {
- obj["vip_info"]["is_vip"] = true;
- obj["vip_info"]["vip_icon"] = {
- url: "https://pic1.zhimg.com/v2-4812630bc27d642f7cafcd6cdeca3d7a_r.png",
- night_mode_url:
- "https://pic1.zhimg.com/v2-c9686ff064ea3579730756ac6c289978_r.png",
- };
- obj["vip_info"]["entrance"] = {
- icon: {
- url: "https://pic1.zhimg.com/v2-5b7012c8c22fd520f5677305e1e551bf.png",
- night_mode_url:
- "https://pic1.zhimg.com/v2-e51e3252d7a2cb016a70879defd5da0b.png",
- },
- title: "我的盐选会员",
- expires_day: "2033-12-24",
- sub_title: null,
- button_text: "你好,知乎!",
- jump_url: "zhihu://vip/purchase",
- button_jump_url: "zhihu://vip/purchase",
- sub_title_new: null,
- identity: "svip",
- };
- obj["vip_info"]["entrance_new"] = {
- left_button: {
- title: "精选会员内容",
- description: "为您严选好内容",
- jump_url: "zhihu://market/home",
- },
- right_button: {
- title: "我的盐选会员",
- description: "畅享 10w+ 优质内容",
- jump_url: "zhihu://vip/my",
- },
- };
- obj["vip_info"]["entrance_v2"] = {
- title: "我的盐选会员",
- sub_title: "畅享 10w+ 优质内容",
- jump_url: "zhihu://vip/my",
- button_text: "查看权益",
- };
- response = { body: JSON.stringify(obj) };
- }
- } else {
- $.logger.warning(
- `没有获取到本次登录用户信息,如未对功能造成影响,请忽略此日志。`
- );
- }
- } catch (err) {
- $.logger.error(`知乎获取当前用户信息出现异常:${err}`);
+ let response = null;
+ try {
+ let obj = JSON.parse($.response.body);
+ $.data.write(blackAnswersIdKey, []);
+ $.logger.debug(`用户登录用户信息,接口响应:${$.response.body}`);
+ if (
+ obj &&
+ obj["id"] &&
+ obj.hasOwnProperty("vip_info") &&
+ obj["vip_info"].hasOwnProperty("is_vip")
+ ) {
+ const userInfo = {
+ id: obj["id"],
+ is_vip: obj["vip_info"]["is_vip"]
+ ? obj["vip_info"]["is_vip"] !== undefined
+ : false,
+ };
+ $.logger.debug(
+ `当前用户id:${obj["id"]},是否为VIP:${obj["vip_info"]["is_vip"]}`
+ );
+ $.data.write(currentUserInfoKey, userInfo);
+ // 在APP显示VIP,仅自己可见,打开后才能使用屏蔽关键词解锁
+ if (
+ $.data.read("zhihu_settings_fake_vip") !== false &&
+ obj["vip_info"]["is_vip"] === false
+ ) {
+ obj["vip_info"]["is_vip"] = true;
+ obj["vip_info"]["vip_type"] = 2;
+ obj["vip_info"]["vip_icon"] = {
+ url: "https://picx.zhimg.com/v2-aa8a1823abfc46f14136f01d55224925.jpg?source=88ceefae",
+ night_mode_url:
+ "https://picx.zhimg.com/v2-aa8a1823abfc46f14136f01d55224925.jpg?source=88ceefae",
+ };
+ obj["vip_info"]["vip_icon_v2"] = {
+ url: "https://picx.zhimg.com/v2-aa8a1823abfc46f14136f01d55224925.jpg?source=88ceefae",
+ night_mode_url:
+ "https://picx.zhimg.com/v2-aa8a1823abfc46f14136f01d55224925.jpg?source=88ceefae",
+ };
+ obj["vip_info"]["entrance"] = {
+ icon: {
+ url: "https://pic3.zhimg.com/v2-5b7012c8c22fd520f5677305e1e551bf.png",
+ night_mode_url:
+ "https://pic4.zhimg.com/v2-e51e3252d7a2cb016a70879defd5da0b.png",
+ },
+ title: "盐选会员 为你严选好内容",
+ expires_day: "2099-12-31",
+ sub_title: null,
+ button_text: "首月 9 元",
+ jump_url: "zhihu://vip/purchase",
+ button_jump_url: "zhihu://vip/purchase",
+ sub_title_new: null,
+ identity: "super_svip",
+ };
+ obj["vip_info"]["entrance_new"] = {
+ left_button: {
+ title: "精选会员内容",
+ description: "为您严选好内容",
+ jump_url: "zhihu://market/home",
+ },
+ right_button: {
+ title: "开通盐选会员",
+ description: "畅享 10w+ 场优质内容等特权",
+ jump_url: "zhihu://vip/purchase",
+ },
+ };
+ obj["vip_info"]["entrance_v2"] = {
+ title: "我的超级盐选会员",
+ sub_title: "畅享 5000W+ 优质内容",
+ jump_url: "zhihu://market/home",
+ button_text: "查看会员",
+ sub_title_color: "#F8E2C4",
+ sub_title_list: ["畅享 5000W+ 优质内容"],
+ card_jump_url: "zhihu://market/home",
+ };
+ $.logger.debug("设置用户为本地盐选会员");
+ response = { body: JSON.stringify(obj) };
+ }
+ } else {
+ $.logger.warning(
+ `没有获取到本次登录用户信息,如未对功能造成影响,请忽略此日志。`
+ );
}
- return response;
+ } catch (err) {
+ $.logger.error(`获取当前用户信息出现异常:${err}`);
+ }
+ return response;
+}
+
+/**
+ * @description: 黑名单管理
+ * @return {*}
+ */
+function manageBlackUser() {
+ const userInfo = getUserInfo();
+ let defaultBlockedUsers = {};
+ let customBlockedUsers = $.data.read(blockedUsersKey, "", userInfo.id);
+ customBlockedUsers =
+ typeof customBlockedUsers === "object" && !!customBlockedUsers
+ ? customBlockedUsers
+ : {};
+ defaultAnswerBlockedUsers.forEach((element) => {
+ customBlockedUsers[element] = "00000000000000000000000000000000";
+ defaultBlockedUsers[element] = "00000000000000000000000000000000";
+ });
+ $.logger.debug(
+ `当前用户id:${userInfo.id},脚本黑名单:${JSON.stringify(
+ customBlockedUsers
+ )}`
+ );
+ // 获取黑名单
+ if ($.request.method === "GET") {
+ try {
+ // 加载黑名单首页时,清空历史黑名单,仅保留脚本默认黑名单
+ if ($.request.url.indexOf("offset") < 0) {
+ customBlockedUsers = defaultBlockedUsers;
+ $.logger.debug(
+ "脚本黑名单已清空,请滑动至黑名单末尾保证重新获取完成。"
+ );
+ $.notification.post(
+ "开始同步黑名单数据,请滑动至黑名单末尾,直至弹出“同步成功”的通知。"
+ );
+ }
+ let obj = JSON.parse($.response.body);
+ if (!!obj["data"]) {
+ $.logger.debug(
+ `本次滑动获取的黑名单信息:${JSON.stringify(obj["data"])}`
+ );
+ obj["data"].forEach((element) => {
+ if (element["name"] !== "[已重置]") {
+ customBlockedUsers[element["name"]] = element["id"];
+ }
+ });
+ $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
+ if (obj["paging"]["is_end"] === true) {
+ $.notification.post(
+ `同步黑名单数据成功!当前黑名单共${
+ Object.keys(customBlockedUsers).length -
+ defaultAnswerBlockedUsers.length
+ }人。\n脚本内置黑名单${defaultAnswerBlockedUsers.length}人。`
+ );
+ $.logger.debug(
+ `脚本黑名单内容:${JSON.stringify(customBlockedUsers)}。`
+ );
+ }
+ } else {
+ $.logger.warning(`获取黑名单失败,接口响应不合法:${$.response.body}`);
+ }
+ } catch (err) {
+ $.data.del(blockedUsersKey);
+ $.logger.error(`获取黑名单失败,异常信息:${err}`);
+ $.notification.post("获取黑名单失败,执行异常,已清空黑名单。");
+ }
+ }
+ // 写入黑名单
+ else if ($.request.method === "POST") {
+ try {
+ let obj = JSON.parse($.response.body);
+ if (obj.hasOwnProperty("name") && obj.hasOwnProperty("id")) {
+ $.logger.debug(
+ `当前需要加入黑名单的用户Id:${obj["id"]},用户名:${obj["name"]}`
+ );
+ if (obj["id"]) {
+ customBlockedUsers[obj["name"]] = obj["id"];
+ $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
+ $.logger.debug(
+ `${
+ obj["name"]
+ }写入脚本黑名单成功,当前脚本黑名单数据:${JSON.stringify(
+ customBlockedUsers
+ )}`
+ );
+ $.notification.post(`已将用户“${obj["name"]}”写入脚本黑名单。`);
+ } else {
+ $.logger.error(
+ `${obj["name"]}写入脚本黑名单失败,没有获取到用户Id。`
+ );
+ $.notification.post(`将用户“${obj["name"]}”写入脚本黑名单失败!`);
+ }
+ } else {
+ $.logger.warning(`写入黑名单失败,接口响应不合法:${$.response.body}`);
+ $.notification.post("写入脚本黑名单失败,接口返回不合法。");
+ }
+ } catch (err) {
+ $.logger.error(`写入黑名单失败,异常信息:${err}`);
+ $.notification.post("写入脚本黑名单失败,执行异常,请查阅日志。");
+ }
+ }
+ // 移出黑名单
+ else if ($.request.method === "DELETE") {
+ try {
+ let obj = JSON.parse($.response.body);
+ if (obj.success) {
+ let user_id = $.request.url.match(
+ /^https?:\/\/api\.zhihu\.com\/settings\/blocked_users\/([0-9a-zA-Z]*)/
+ )[1];
+ if (user_id) {
+ $.logger.debug(`当前需要移出黑名单的用户Id:${user_id}`);
+ for (let username in customBlockedUsers) {
+ if (customBlockedUsers[username] === user_id) {
+ delete customBlockedUsers[username];
+ $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
+ $.logger.debug(
+ `${username}移出脚本黑名单成功,当前脚本黑名单数据:${JSON.stringify(
+ customBlockedUsers
+ )}`
+ );
+ $.notification.post(`已将用户“${username}”移出脚本黑名单!`);
+ break;
+ }
+ }
+ } else {
+ $.logger.error(
+ "将用户移出脚本黑名单失败!\n建议从设置中刷新黑名单数据。"
+ );
+ $.notification.post(
+ `将用户移出脚本黑名单失败,没有获取到用户Id。\n建议从设置中刷新黑名单数据。`
+ );
+ }
+ } else {
+ $.logger.warning(`移出黑名单失败,接口响应不合法:${$.response.body}`);
+ $.notification.post("移出脚本黑名单失败,接口返回不合法。");
+ }
+ } catch (err) {
+ $.logger.error(`移出黑名单失败,异常信息:${err}`);
+ $.notification.post("移出脚本黑名单失败,执行异常,请查阅日志。");
+ }
+ }
+}
+
+/**
+ * 黑名单增强 - 浏览黑名单用户信息时自动加入脚本黑名单
+ * @return {*}
+ */
+function autoInsertBlackList() {
+ let response = null;
+ try {
+ let obj = JSON.parse($.response.body);
+ // 删除MCN信息
+ delete obj["mcn_user_info"];
+ response = { body: JSON.stringify(obj) };
+ // 如已是黑名单用户,但不在脚本黑名单中,则自动加入
+ if (obj.name && obj.id && obj["is_blocking"] === true) {
+ const userInfo = getUserInfo();
+ let customBlockedUsers = $.data.read(blockedUsersKey, "", userInfo.id);
+ customBlockedUsers =
+ typeof customBlockedUsers === "object" && !!customBlockedUsers
+ ? customBlockedUsers
+ : {};
+ if (!customBlockedUsers[obj.name]) {
+ $.logger.debug(
+ `当前需要加入黑名单的用户Id:${obj["id"]},用户名:${obj["name"]}`
+ );
+ customBlockedUsers[obj["name"]] = obj["id"];
+ $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
+ $.logger.debug(
+ `${
+ obj["name"]
+ }写入脚本黑名单成功,当前脚本黑名单数据:${JSON.stringify(
+ customBlockedUsers
+ )}`
+ );
+ $.notification.post(`已自动将用户“${obj["name"]}”写入脚本黑名单。`);
+ }
+ }
+ } catch (err) {
+ $.logger.error(`去除MCN信息出现异常:${err}`);
+ }
+ return response;
+}
+
+/**
+ * 关注列表去广告
+ *
+ * @return {*}
+ */
+function removeMoments() {
+ let response = null;
+ try {
+ let obj = JSON.parse(
+ $.response.body.replace(/(\w+"+\s?):\s?(\d{15,})/g, '$1:"$2"')
+ );
+ const user_info = getUserInfo();
+ let customBlockedUsers = $.data.read(blockedUsersKey, "", user_info.id);
+ customBlockedUsers = !!customBlockedUsers ? customBlockedUsers : {};
+ let data;
+
+ const settings_remove_stream = $.data.read(
+ "zhihu_settings_moments_stream",
+ false
+ );
+ const settings_remove_recommend = $.data.read(
+ "zhihu_settings_moments_recommend",
+ false
+ );
+ const settings_remove_activity = $.data.read(
+ "zhihu_settings_moments_activity",
+ false
+ );
+ const settings_blocked_users = $.data.read(
+ "zhihu_settings_blocked_users",
+ false
+ );
+
+ data = obj.data.filter((item) => {
+ // 转发的想法是否含有黑名单用户
+ const isBlackUserPin =
+ settings_blocked_users &&
+ item.target &&
+ item.target["origin_pin"] &&
+ item.target["origin_pin"].author &&
+ typeof customBlockedUsers[item.target["origin_pin"].author.name] !=
+ "undefined";
+ // 是否为流媒体
+ const isStream =
+ settings_remove_stream && item["target_type"] === "zvideo";
+ // 是否为推荐关注用户
+ const isRecommend =
+ settings_remove_recommend && item.type === "recommend_user_card_list";
+ // 是否为关注的问题有新动态
+ const isActivity =
+ settings_remove_activity && item.type === "message_activity_card";
+ return !(isBlackUserPin || isStream || isRecommend || isActivity);
+ });
+ obj["data"] = data;
+ response = { body: JSON.stringify(obj) };
+ } catch (err) {
+ $.logger.error(`关注列表去广告出现异常:${err}`);
+ }
+ return response;
+}
+
+/**
+ * 推荐去广告与黑名单增强
+ *
+ * @return {*}
+ */
+function removeRecommend() {
+ let response = null;
+ try {
+ // 移除推荐列表中的想法
+ const settings_remove_pin = $.data.read(
+ "zhihu_settings_recommend_pin",
+ false
+ );
+ // 移除推荐列表的流媒体
+ const settings_recommend_stream = $.data.read(
+ "zhihu_settings_recommend_stream",
+ false
+ );
+ // 移除推荐列表的文章
+ const settings_remove_article = $.data.read(
+ "zhihu_settings_remove_article",
+ false
+ );
+ // 屏蔽黑名单用户
+ const settings_blocked_users = $.data.read(
+ "zhihu_settings_blocked_users",
+ false
+ );
+ // 屏蔽关键词内容
+ const settings_blocked_keywords = $.data.read(
+ "zhihu_settings_blocked_keywords",
+ true
+ );
+ // 获取用户信息
+ const user_info = getUserInfo();
+
+ let keywords = $.data.read(keywordBlockKey, "", user_info.id);
+ keywords = settings_blocked_keywords && !!keywords ? keywords : [];
+ let customBlockedUsers = $.data.read(blockedUsersKey, "", user_info.id);
+ customBlockedUsers =
+ settings_blocked_users && !!customBlockedUsers ? customBlockedUsers : {};
+
+ const newData = (element) => {
+ const elementStr = JSON.stringify(element);
+ // 是否为广告
+ const isAd =
+ element["card_type"] === "slot_event_card" ||
+ element["card_type"] === "slot_video_event_card" ||
+ element.hasOwnProperty("ad") ||
+ // 非常恶心伪装成普通内容的广告
+ (element["brief"] && element["brief"].indexOf("slot_card") >= 0) ||
+ // 训练营
+ (element["extra"] && element["extra"]["type"] === "Training");
+ // 是否为流媒体
+ const isStream =
+ isAd !== true &&
+ elementStr.search(
+ /"(type|style)+"\s?:\s?"(drama|zvideo|Video|BIG_IMAGE)+"/i
+ ) >= 0;
+ const removeStream = isStream && settings_recommend_stream;
+ // 是否为想法
+ const isPin =
+ isStream !== true &&
+ elementStr.search(/"(type|style)+"\s?:\s?"pin"/i) >= 0;
+ const removePin = isPin && settings_remove_pin;
+ // 是否为文章
+ const isArticle =
+ elementStr.search(/"(type|style)+"\s?:\s?"article"/i) >= 0;
+ const removeArticle = isArticle && settings_remove_article;
+ // 是否匹配脚本关键词过滤
+ let matchKeyword = false;
+ if (isStream !== true && settings_blocked_keywords) {
+ for (let i = 0; i < keywords.length; i++) {
+ if (elementStr.search(keywords[i]) >= 0) {
+ if ($.isDebug) {
+ let elementTitle =
+ element["common_card"]["feed_content"]["title"]["panel_text"];
+ let elementContent =
+ element["common_card"]["feed_content"]["content"]["panel_text"];
+ let actionUrl = "";
+ try {
+ actionUrl =
+ element["common_card"]["feed_content"]["title"]["action"][
+ "intent_url"
+ ];
+ } catch {}
+ $.logger.debug(
+ `匹配关键字:\n${keywords[i]}\n标题:\n${elementTitle}\n内容:\n${elementContent}`
+ );
+ $.notification.debug(
+ scriptName,
+ `关键字:${keywords[i]}`,
+ `${elementTitle}\n${elementContent}`,
+ actionUrl
+ );
+ }
+ matchKeyword = true;
+ break;
+ }
+ }
+ }
+ // 是否为黑名单用户
+ let isBlockedUser;
+ try {
+ isBlockedUser =
+ matchKeyword !== true &&
+ settings_blocked_users &&
+ customBlockedUsers &&
+ element["common_card"]["feed_content"]["source_line"]["elements"][1][
+ "text"
+ ]["panel_text"] in customBlockedUsers;
+ } catch {
+ isBlockedUser = false;
+ }
+ return !(
+ isAd ||
+ removePin ||
+ removeArticle ||
+ removeStream ||
+ matchKeyword ||
+ isBlockedUser
+ );
+ };
+
+ // 修复number类型精度丢失
+ let obj = JSON.parse(
+ $.response.body.replace(/(\w+"+\s?):\s?(\d{15,})/g, '$1:"$2"')
+ );
+
+ if (obj["data"].length > 0 && newData.length === 0) {
+ $.notification.post("所有推荐内容都已被过滤,建议调整脚本过滤配置。");
+ }
+ obj["data"] = obj["data"].filter(newData);
+ response = { body: JSON.stringify(obj) };
+ } catch (err) {
+ $.logger.error(`推荐列表去广告出现异常:${err}`);
+ }
+ return response;
+}
+
+/**
+ * 回答列表去广告与黑名单增强
+ *
+ * @return {*}
+ */
+function removeQuestions() {
+ let response = null;
+ try {
+ const userInfo = getUserInfo();
+ let customBlockedUsers = $.data.read(blockedUsersKey, "", userInfo.id);
+ customBlockedUsers = !!customBlockedUsers ? customBlockedUsers : {};
+ let obj = JSON.parse($.response.body);
+ const settingsBlockedUsers = $.data.read(
+ "zhihu_settings_blocked_users",
+ false
+ );
+ $.logger.debug(`当前黑名单列表: ${JSON.stringify(customBlockedUsers)}`);
+ // 黑名单用户的回答Id
+ let blackUserAnswersId = $.data.read(blackAnswersIdKey, []);
+ // 去除广告
+ delete obj["ad_info"];
+ // 去除回答列表中的黑名单用户
+ if (obj["data"]) {
+ let newData = [];
+ for (let element of obj.data) {
+ let blackUserName = "";
+ const answerId = element.target.id.toString();
+ try {
+ if ("target" in element) {
+ blackUserName = element["target"]["author"]["name"];
+ }
+ } catch (ex) {
+ $.logger.error(`获取回答列表用户名出现异常:${ex}`);
+ }
+ const isBlackUser =
+ typeof customBlockedUsers[blackUserName] != "undefined";
+ const removeBlackUserAnswer = settingsBlockedUsers && isBlackUser;
+ // 显示仅作者自己可见的回答,允许复制
+ if ("target" in element) {
+ element["target"]["visible_only_to_author"] = false;
+ element["target"]["is_visible"] = true;
+ element["target"]["is_copyable"] = true;
+ }
+ if (!removeBlackUserAnswer) {
+ newData.push(element);
+ } else if (
+ removeBlackUserAnswer === true &&
+ blackUserAnswersId.includes(answerId) === false
+ ) {
+ blackUserAnswersId.push(answerId);
+ $.notification.debug(
+ `记录黑名单用户${blackUserName}的回答Id:${answerId}`
+ );
+ }
+ }
+ obj.data = newData;
+ }
+ $.data.write(blackAnswersIdKey, blackUserAnswersId);
+ const body = JSON.stringify(obj);
+ $.logger.debug(`修改后的回答列表数据:${body}`);
+ response = { body: body };
+ } catch (err) {
+ $.logger.error(`回答列表去广告出现异常:${err}`);
+ }
+ return response;
}
/**
* 回答内容优化
*
- * @param {*}
* @return {*}
*/
function modifyAnswer() {
- let response = null;
- try {
- let html = $.response.body;
- // 付费内容提醒
- if (
- (html.indexOf("查看完整内容") >= 0 ||
- html.indexOf("查看全部章节") >= 0) &&
- html.indexOf("paid") >= 0
- ) {
- let matchStr = html.match(/(richText[^<]*>)(.)/)[1];
- let start = html.lastIndexOf(matchStr) + matchStr.length;
- let insertText =
- '';
- response = {
- body: html.slice(0, start) + insertText + html.slice(start),
- };
- }
+ let response = null;
+ try {
+ let html = $.response.body;
+ let insertText = "";
- // 营销推广提醒
- else if (
- html.indexOf("ad-link-card") >= 0 ||
- html.indexOf("xg.zhihu.com") >= 0 ||
- html.indexOf("知乎营销平台") >= 0
- ) {
- let matchStr = html.match(/(richText[^<]*>)(.)/)[1];
- let start = html.lastIndexOf(matchStr) + matchStr.length;
- let insertText =
- '';
- response = {
- body: html.slice(0, start) + insertText + html.slice(start),
- };
- }
-
- // 购物推广提醒
- else if (html.indexOf("mcn-link-card") >= 0) {
- let matchStr = html.match(/(richText[^<]*>)(.)/)[1];
- let start = html.lastIndexOf(matchStr) + matchStr.length;
- let insertText =
- '';
- response = {
- body: html.slice(0, start) + insertText + html.slice(start),
- };
- }
-
- // 彩蛋
- else if (Math.floor(Math.random() * 200) == 7) {
- let matchStr = html.match(/(richText[^<]*>)(.)/)[1];
- let start = html.lastIndexOf(matchStr) + matchStr.length;
- let insertText =
- '';
- response = {
- body: html.slice(0, start) + insertText + html.slice(start),
- };
- }
- } catch (err) {
- $.logger.error(`知乎付费内容提醒出现异常:${err}`);
+ // 付费内容提醒
+ if (
+ (html.indexOf("查看完整内容") >= 0 ||
+ html.indexOf("查看全部章节") >= 0) &&
+ html.indexOf("paid") >= 0
+ ) {
+ insertText =
+ '';
}
- return response;
+
+ // 营销推广提醒
+ else if (
+ html.indexOf("ad-link-card") >= 0 ||
+ html.indexOf("xg.zhihu.com") >= 0 ||
+ html.indexOf("营销平台") >= 0
+ ) {
+ insertText =
+ '';
+ }
+
+ // 购物推广提醒
+ else if (html.indexOf("mcn-link-card") >= 0) {
+ insertText =
+ '';
+ }
+
+ // 彩蛋
+ else if (Math.floor(Math.random() * 200) === 7) {
+ insertText =
+ '';
+ }
+
+ if (insertText !== "") {
+ const matchStr = html.match(/(richText[^<]*>)(.)/)[1];
+ const start = html.lastIndexOf(matchStr) + matchStr.length;
+ response = {
+ body: html.slice(0, start) + insertText + html.slice(start),
+ };
+ }
+ } catch (err) {
+ $.logger.error(`付费内容提醒出现异常:${err}`);
+ }
+ return response;
}
/**
- * @description: 黑名单管理
- * @param {*}
+ * 评论去广告及黑名单增强
+ *
* @return {*}
*/
-function manageBlackUser() {
- const userInfo = getUserInfo();
- let defaultBlockedUsers = {};
- let customBlockedUsers = $.data.read(blockedUsersKey, "", userInfo.id);
- customBlockedUsers =
- typeof customBlockedUsers === "object" && !!customBlockedUsers
- ? customBlockedUsers
- : {};
- defaultAnswerBlockedUsers.forEach((element) => {
- customBlockedUsers[element] = "00000000000000000000000000000000";
- defaultBlockedUsers[element] = "00000000000000000000000000000000";
- });
- $.logger.debug(
- `当前用户id:${userInfo.id},脚本黑名单:${JSON.stringify(
- customBlockedUsers
- )}`
- );
- // 获取黑名单
- if ($.request.method == "GET") {
- try {
- // 加载黑名单首页时,清空历史黑名单,仅保留脚本默认黑名单
- if ($.request.url.indexOf("offset") < 0) {
- customBlockedUsers = defaultBlockedUsers;
- $.logger.debug("脚本黑名单已清空,请滑动至黑名单末尾保证重新获取完成。");
- $.notification.post(
- "脚本黑名单已清空,请滑动至黑名单末尾保证重新获取完成。"
- );
- }
- let obj = JSON.parse($.response.body);
- if (!!obj["data"]) {
- $.logger.debug(`本次滑动获取的黑名单信息:${JSON.stringify(obj["data"])}`);
- obj["data"].forEach((element) => {
- if (element["name"] != "[已重置]") {
- customBlockedUsers[element["name"]] = element["id"];
- }
- });
- $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
- if (obj["paging"]["is_end"] == true) {
- $.notification.post(
- `获取脚本黑名单结束,当前黑名单共${
- Object.keys(customBlockedUsers).length -
- defaultAnswerBlockedUsers.length
- }人。\n脚本内置黑名单${defaultAnswerBlockedUsers.length}人。`
- );
- $.logger.debug(`脚本黑名单内容:${JSON.stringify(customBlockedUsers)}。`);
- }
- } else {
- $.logger.warning(`获取黑名单失败,接口响应不合法:${$.response.body}`);
- }
- } catch (err) {
- $.data.del(blockedUsersKey);
- $.logger.error(`获取黑名单失败,异常信息:${err}`);
- $.notification.post("获取黑名单失败,执行异常,已清空黑名单。");
+function removeComment() {
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ let obj = JSON.parse($.response.body);
+ obj["ad_info"] = {};
+ // 屏蔽黑名单用户
+ if ($.data.read("zhihu_settings_blocked_users", false) === true) {
+ let user_info = getUserInfo();
+ let customBlockedUsers = $.data.read(blockedUsersKey, "", user_info.id);
+ customBlockedUsers = !!customBlockedUsers ? customBlockedUsers : {};
+ let newComments = [];
+ let blockCommentIdObj = {};
+ if (typeof obj.root != "undefined") {
+ // 屏蔽黑名单用户的评论
+ const rootUserName = obj.root.author.name;
+ const isBlackRootUser =
+ typeof customBlockedUsers[rootUserName] != "undefined";
+ if (isBlackRootUser === true) {
+ obj.root.is_delete = true;
+ obj.root.can_reply = false;
+ obj.root.can_like = false;
+ obj.root.author.name = "黑名单用户";
+ obj.root.author.avatar_url =
+ "https://picx.zhimg.com/v2-abed1a8c04700ba7d72b45195223e0ff_xll.jpg";
+ }
}
- }
- // 写入黑名单
- else if ($.request.method == "POST") {
- try {
- let obj = JSON.parse($.response.body);
- if (obj.hasOwnProperty("name") && obj.hasOwnProperty("id")) {
- $.logger.debug(
- `当前需要加入黑名单的用户Id:${obj["id"]},用户名:${obj["name"]}`
+
+ if (typeof obj.data != "undefined") {
+ obj.data.forEach((comment) => {
+ // 屏蔽黑名单用户的评论
+ // 评论人昵称
+ const commentUserName = comment.author.name;
+ // 回复哪个人的评论(仅适用于独立子评论页面请求)
+ let replyUserName = "";
+ if (comment["reply_to_author"] && comment["reply_to_author"].name) {
+ replyUserName = comment["reply_to_author"].name;
+ }
+ const isSubComment = replyUserName !== "";
+ const isBlackCommentUser =
+ typeof customBlockedUsers[commentUserName] != "undefined";
+ const isBlackReplyUser =
+ typeof customBlockedUsers[replyUserName] != "undefined";
+ if (isBlackCommentUser === true || isBlackReplyUser === true) {
+ if (
+ isBlackCommentUser &&
+ !isSubComment &&
+ $.request.url.indexOf("root_comment") > 0
+ ) {
+ $.notification.debug(
+ `屏蔽黑名单用户“${commentUserName}”的主评论。`
);
- if (obj["id"]) {
- customBlockedUsers[obj["name"]] = obj["id"];
- $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
+ } else if (
+ !isBlackCommentUser &&
+ isSubComment &&
+ !isBlackReplyUser &&
+ $.request.url.indexOf("child_comment") > 0
+ ) {
+ $.notification.debug(
+ `屏蔽黑名单用户“${commentUserName}”的子评论。`
+ );
+ } else if (
+ isBlackCommentUser &&
+ !isBlackReplyUser &&
+ $.request.url.indexOf("child_comment") > 0
+ ) {
+ $.notification.debug(
+ `屏蔽黑名单用户“${commentUserName}”回复“${replyUserName}”的子评论。`
+ );
+ } else if (
+ isBlackCommentUser &&
+ isBlackReplyUser &&
+ $.request.url.indexOf("child_comment") > 0
+ ) {
+ $.notification.debug(
+ `屏蔽黑名单用户“${commentUserName}”回复黑名单用户“${replyUserName}”的子评论。`
+ );
+ }
+ blockCommentIdObj[comment.id] = commentUserName;
+ if (isBlackCommentUser) {
+ comment.is_delete = true;
+ comment.can_reply = false;
+ comment.can_like = false;
+ comment.author.exposed_medal = {};
+ comment.author.name = "[黑名单用户]";
+ comment.author.avatar_url =
+ "https://picx.zhimg.com/v2-abed1a8c04700ba7d72b45195223e0ff_xll.jpg";
+ }
+ if (isBlackReplyUser) {
+ comment["reply_to_author"].name = "[黑名单用户]";
+ comment["reply_to_author"].exposed_medal = {};
+ comment["reply_to_author"].avatar_url =
+ "https://picx.zhimg.com/v2-abed1a8c04700ba7d72b45195223e0ff_xll.jpg";
+ }
+ }
+ if (comment.child_comments) {
+ let newChildComments = [];
+ comment.child_comments.forEach((childComment) => {
+ // 屏蔽黑名单用户的评论
+ const childCommentUserName = childComment.author.name;
+ const childCommentReplyUserName =
+ typeof childComment["reply_to_author"] != "undefined"
+ ? childComment["reply_to_author"].name
+ : "";
+ const isChildBlackCommentUser =
+ typeof customBlockedUsers[childCommentUserName] !=
+ "undefined";
+ const isChildBlackReplyUser =
+ typeof customBlockedUsers[childCommentReplyUserName] !=
+ "undefined";
+ if (isChildBlackCommentUser || isChildBlackReplyUser) {
+ if (isChildBlackCommentUser === true) {
+ $.notification.debug(
+ `屏蔽黑名单用户“${childCommentUserName}”的子评论。`
+ );
+ blockCommentIdObj[childComment.id] = childCommentUserName;
+ childComment.is_delete = true;
+ childComment.can_reply = false;
+ childComment.can_like = false;
+ childComment.author.name = "[黑名单用户]";
+ childComment.author.exposed_medal = {};
+ childComment.author.avatar_url =
+ "https://picx.zhimg.com/v2-abed1a8c04700ba7d72b45195223e0ff_xll.jpg";
+ }
+
+ if (isChildBlackReplyUser === true) {
$.logger.debug(
- `${
- obj["name"]
- }写入脚本黑名单成功,当前脚本黑名单数据:${JSON.stringify(
- customBlockedUsers
- )}`
+ `修改前的子评论数据:\n${JSON.stringify(childComment)}`
);
- $.notification.post(`已将用户“${obj["name"]}”写入脚本黑名单。`);
- } else {
- $.logger.error(`${obj["name"]}写入脚本黑名单失败,没有获取到用户Id。`);
- $.notification.post(`将用户“${obj["name"]}”写入脚本黑名单失败!`);
+ childComment["reply_to_author"].name = "[黑名单用户]";
+ childComment["reply_to_author"].exposed_medal = {};
+ childComment["reply_to_author"].avatar_url =
+ "https://picx.zhimg.com/v2-abed1a8c04700ba7d72b45195223e0ff_xll.jpg";
+ $.notification.debug(
+ `隐藏“${childCommentUserName}”回复黑名单用户“${childCommentReplyUserName}”的名称与头像。`
+ );
+ $.logger.debug(
+ `修改后的子评论数据:\n${JSON.stringify(childComment)}`
+ );
+ }
}
- } else {
- $.logger.warning(`写入黑名单失败,接口响应不合法:${$.response.body}`);
- $.notification.post("写入脚本黑名单失败,接口返回不合法。");
+ newChildComments.push(childComment);
+ });
+ comment.child_comments = newChildComments;
}
- } catch (err) {
- $.logger.error(`写入黑名单失败,异常信息:${err}`);
- $.notification.post("写入脚本黑名单失败,执行异常,请查阅日志。");
- }
- }
- // 移出黑名单
- else if ($.request.method == "DELETE") {
- try {
- let obj = JSON.parse($.response.body);
- if (obj.success) {
- let user_id = $.request.url.match(
- /https?:\/\/(api\.zhihu\.com|(103\.41\.167\.(226|234|235|236)))\/settings\/blocked_users\/([0-9a-zA-Z]*)/
- )[1];
- if (user_id) {
- $.logger.debug(`当前需要移出黑名单的用户Id:${user_id}`);
- for (let username in customBlockedUsers) {
- if (customBlockedUsers[username] == user_id) {
- delete customBlockedUsers[username];
- $.data.write(blockedUsersKey, customBlockedUsers, userInfo.id);
- $.logger.debug(
- `${username}移出脚本黑名单成功,当前脚本黑名单数据:${JSON.stringify(
- customBlockedUsers
- )}`
- );
- $.notification.post(`已将用户“${username}”移出脚本黑名单!`);
- break;
- }
- }
- } else {
- $.logger.error(
- "将用户移出脚本黑名单失败!\n建议从设置中刷新黑名单数据。"
- );
- $.notification.post(
- `将用户移出脚本黑名单失败,没有获取到用户Id。\n建议从设置中刷新黑名单数据。`
- );
- }
- } else {
- $.logger.warning(`移出黑名单失败,接口响应不合法:${$.response.body}`);
- $.notification.post("移出脚本黑名单失败,接口返回不合法。");
- }
- } catch (err) {
- $.logger.error(`移出黑名单失败,异常信息:${err}`);
- $.notification.post("移出脚本黑名单失败,执行异常,请查阅日志。");
+ newComments.push(comment);
+ });
}
+ obj.data = newComments;
+ }
+ const body = JSON.stringify(obj);
+ $.logger.debug(`过滤后的评论数据:\n${body}`);
+ response = { body: body };
}
+ } catch (err) {
+ $.logger.error(`去除评论广告出现异常:${err}`);
+ }
+ return response;
}
/**
- * @description: 获取用户信息
- * @param {*}
+ * 移除文章页面的广告
* @return {*}
*/
-function getUserInfo() {
- let defaultUserInfo = { id: "default", is_vip: false };
- try {
- const userInfo = $.data.read(currentUserInfoKey);
- if (typeof userInfo === "string")
- userInfo = JSON.parse(userInfo);
- if (!!userInfo && userInfo.hasOwnProperty("id")) {
- return userInfo;
+function removeArticleAd() {
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ let obj = JSON.parse($.response.body);
+ obj["ad_info"] = {};
+ const body = JSON.stringify(obj);
+ $.logger.debug(`过滤后的文章数据:\n${body}`);
+ response = { body: body };
+ }
+ } catch (err) {
+ $.logger.error(`去除文章广告出现异常:${err}`);
+ }
+ return response;
+}
+
+/**
+ * 屏蔽官方营销消息
+ *
+ * @return {*}
+ */
+function removeMarketingMsg() {
+ let response = null;
+ try {
+ let obj = JSON.parse($.response.body);
+ let newItems = [];
+ for (let item of obj["data"]) {
+ if (item["detail_title"] === "官方帐号消息") {
+ let unread_count = item["unread_count"];
+ if (unread_count > 0) {
+ item["content"]["text"] = "未读消息" + unread_count + "条";
} else {
- return defaultUserInfo;
+ item["content"]["text"] = "全部消息已读";
}
- } catch (err) {
- $.logger.error(`获取用户信息出现异常:${err}`);
- return defaultUserInfo;
+ item["is_read"] = true;
+ item["unread_count"] = 0;
+ newItems.push(item);
+ } else if (item["detail_title"] !== "活动助手") {
+ newItems.push(item);
+ }
}
+ obj["data"] = newItems;
+ response = { body: JSON.stringify(obj) };
+ } catch (err) {
+ $.logger.error(`屏蔽官方营销消息出现异常:${err}`);
+ }
+ return response;
}
/**
- * @description: 知乎8.3.0移除推荐页顶部项
- * @param {*}
+ * 热榜去广告
+ *
* @return {*}
*/
-function removeFeedSections() {
- let response = null;
- try {
- let obj = JSON.parse($.response.body);
- obj.guess_like_sections = [];
- obj.selected_sections = [];
- obj.more_sections = [];
- response = { body: JSON.stringify(obj) };
- } catch (err) {
- $.logger.error(`知乎移除推荐页顶部项出现异常:${err}`);
+function removeHotListAds() {
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ let obj = JSON.parse($.response.body);
+ if ("data" in obj) {
+ obj["data"] = obj["data"].filter((e) => {
+ return (
+ e["type"] === "hot_list_feed" || e["type"] === "hot_list_feed_video"
+ );
+ });
+ }
+ response = { body: JSON.stringify(obj) };
}
- return response;
+ } catch (err) {
+ $.logger.error(`去除热榜广告出现异常:${err}`);
+ }
+ return response;
}
+/**
+ * 去除预置关键字广告
+ *
+ * @return {*}
+ */
+function removeKeywordAds() {
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ $.logger.debug(`预置关键字返回:${$.response.body}`);
+ let obj = JSON.parse($.response.body);
+ if (obj.hasOwnProperty("preset_words") && obj["preset_words"]["words"]) {
+ obj["preset_words"]["words"] = obj["preset_words"]["words"].filter(
+ (element) => {
+ return element["type"] !== "ad";
+ }
+ );
+ response = { body: JSON.stringify(obj) };
+ }
+ }
+ } catch (err) {
+ $.logger.error(`去除预置关键字广告出现异常:${err}`);
+ }
+ return response;
+}
+
+/**
+ * 移除回答翻页时出现的黑名单用户的回答
+ * 小概率会移除失败
+ * @return {*}
+ */
+function removeNextBlackUserAnswer() {
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ let obj = JSON.parse($.response.body);
+ const blackUserAnswersId = $.data.read(blackAnswersIdKey, []);
+ if (blackUserAnswersId.length > 0) {
+ let newData = [];
+ obj.data.forEach((element) => {
+ const tag = blackUserAnswersId.includes(element.id.toString());
+ if (tag === false) {
+ // 去除可能的广告
+ element.ad_info = { data: "" };
+ newData.push(element);
+ } else {
+ $.notification.debug(
+ `屏蔽翻页过程中出现的黑名单用户回答Id:${element.id}`
+ );
+ }
+ });
+ // 重新为答案排序
+ for (let i = 0; i < newData.length; i++) {
+ if (newData[i]["extra"] && newData[i]["extra"]["question_index"]) {
+ newData[i]["extra"]["question_index"] = i + 1;
+ }
+ if (newData[i]["strategy_info"]) {
+ newData[i]["strategy_info"]["global_index"] = i + 1;
+ newData[i]["strategy_info"]["strategy_index"] = i + 1;
+ }
+ }
+ obj.data = newData;
+ }
+ response = { body: JSON.stringify(obj) };
+ }
+ } catch (err) {
+ $.logger.error(`屏蔽下翻黑名单用户的回答出现异常:${err}`);
+ }
+ return response;
+}
+
+function modifyAnswersNextData() {
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ let obj = JSON.parse($.response.body);
+ let user_info = getUserInfo();
+ let customBlockedUsers = $.data.read(blockedUsersKey, {}, user_info.id);
+ $.logger.debug(`脚本黑名单用户:\n${JSON.stringify(customBlockedUsers)}`);
+ let newData = [];
+ obj.data.data.forEach((element) => {
+ element["ad_info"] = { data: "" };
+ const isBlackUser =
+ typeof customBlockedUsers[element.data.author.name] != "undefined";
+ $.logger.debug(
+ `用户${element.data.author.name}是否在黑名单中:${isBlackUser}`
+ );
+ if (
+ $.data.read("zhihu_settings_blocked_users", false) === false ||
+ isBlackUser === false
+ ) {
+ newData.push(element);
+ }
+ });
+ obj.data.data = newData;
+ response = { body: JSON.stringify(obj) };
+ }
+ } catch (err) {
+ $.logger.error(`屏蔽回答信息流黑名单用户及广告:${err}`);
+ }
+ return response;
+}
+
+/**
+ * 修改盐值
+ *
+ * @return {*}
+ */
+function changeUserCredit() {
+ $.notification.debug("开始修改用户盐值");
+ let response = null;
+ try {
+ if (!!$.response.body) {
+ // 自定义盐值
+ const score = parseInt($.data.read(userCreditScore, 780));
+ $.logger.debug(`准备修改用户盐值为${score}`);
+ let obj = JSON.parse($.response.body);
+ if (obj["credit_basis"].total_score < score) {
+ obj["credit_basis"].total_score = score;
+ $.logger.debug(`已修改用户盐值为:${score}`);
+ }
+ response = { body: JSON.stringify(obj) };
+ }
+ } catch (err) {
+ $.logger.error(`修改用户盐值出现异常:${err}`);
+ }
+ return response;
+}
+
+(() => {
+ let response = null;
+ if ($.isResponse) {
+ switch (true) {
+ // 获取用户信息 - 隔离用户数据,开启本地盐选会员等
+ case /^https:\/\/api\.zhihu\.com\/people\/self$/.test($.request.url):
+ response = processUserInfo();
+ break;
+ // 优化软件配置 - 优化下发的配置文件来实现某些效果
+ case $.data.read("zhihu_settings_app_conf", false) === true &&
+ /^https?:\/\/appcloud2\.zhihu\.com\/v\d+\/config/.test($.request.url):
+ response = modifyAppConfig();
+ break;
+ case $.data.read("zhihu_settings_app_conf", false) === true &&
+ /^https?:\/\/m-cloud\.zhihu\.com\/api\/cloud\/config\/all\?/.test(
+ $.request.url
+ ):
+ response = modifyMCloudConfig();
+ break;
+ // 修改用户盐值 - 仅当自定义盐值大于真实盐值时生效
+ case /^https?:\/\/api\.zhihu\.com\/user-credit\/basis/.test(
+ $.request.url
+ ):
+ $.notification.debug("准备修改用户盐值");
+ response = changeUserCredit();
+ break;
+ // 推荐页 - 移除黑名单用户发布的文章、去除广告,及自定义一些屏蔽项目
+ case /^https:\/\/api\.zhihu\.com\/topstory\/recommend/.test(
+ $.request.url
+ ):
+ response = removeRecommend();
+ break;
+ // 问题的回答列表 - 移除黑名单用户的回答、去除广告
+ case /^https?:\/\/api\.zhihu\.com\/(v4\/)?questions\/\d+/.test(
+ $.request.url
+ ):
+ response = removeQuestions();
+ break;
+ // 回答信息流 - 移除黑名单用户的回答、去除广告
+ case /^https?:\/\/api\.zhihu\.com\/next-data\?/.test($.request.url):
+ response = modifyAnswersNextData();
+ break;
+ // 消息页 - 折叠官方消息、屏蔽营销消息
+ case $.data.read("zhihu_settings_sys_msg", true) !== false &&
+ /^https?:\/\/api\.zhihu\.com\/notifications\/v3\/message/.test(
+ $.request.url
+ ):
+ response = removeMarketingMsg();
+ break;
+ // 评论页及子页面 - 去除黑名单用户发表的评论
+ case /^https?:\/\/api\.zhihu\.com\/comment_v5\/(answers|pins|comments?|articles)\/\d+\/(root|child)_comment/.test(
+ $.request.url
+ ):
+ response = removeComment();
+ break;
+ // 文章页 - 去除底部卡片广告
+ case /^https?:\/\/www\.zhihu\.com\/api\/v\d\/articles\/\d+\/recommendation\?/.test(
+ $.request.url
+ ):
+ response = removeArticleAd();
+ break;
+ // 回答页底部评论摘要 - 移除黑名单用户发表的评论
+ case /^https?:\/\/www\.zhihu\.com\/api\/v4\/comment_v5\/answers\/\d+\/abstract_comment\?/.test(
+ $.request.url
+ ):
+ response = removeComment();
+ break;
+ // 回答内容优化 - 付费、营销、推广内容文首提醒
+ case $.data.read("zhihu_settings_answer_tip", true) === true &&
+ /^https?:\/\/www\.zhihu\.com\/appview\/v2\/answer\/.*(entry=(?!(preload-topstory|preload-search|preload-subscription)))?/.test(
+ $.request.url
+ ):
+ response = modifyAnswer();
+ break;
+ // 回答页 - 屏蔽下翻出现的黑名单用户
+ case $.data.read("zhihu_settings_blocked_users", false) !== false &&
+ /^https?:\/\/api\.zhihu\.com\/next\?/.test($.request.url):
+ response = removeNextBlackUserAnswer();
+ break;
+ // 黑名单增强 - 浏览黑名单用户信息时自动加入脚本黑名单
+ case $.data.read("zhihu_settings_blocked_users", true) === true &&
+ /^https?:\/\/api\.zhihu\.com\/people\/((?!self).)*$/.test(
+ $.request.url
+ ):
+ response = autoInsertBlackList();
+ break;
+ // 关注页 - 去广告
+ case /^https?:\/\/api\.zhihu\.com\/moments_v3\?/.test($.request.url):
+ response = removeMoments();
+ break;
+ // 热榜页 - 去广告
+ case $.data.read("zhihu_settings_hot_list", true) === true &&
+ /^https?:\/\/api\.zhihu\.com\/topstory\/hot-lists(\?|\/)/.test(
+ $.request.url
+ ):
+ response = removeHotListAds();
+ break;
+ // 搜索页 - 去除预置广告
+ case $.data.read("zhihu_settings_preset_words", true) === true &&
+ /^https?:\/\/api\.zhihu\.com\/search\/preset_words\?/.test(
+ $.request.url
+ ):
+ response = removeKeywordAds();
+ break;
+ // 黑名单页 - 同步黑名单数据
+ case $.data.read("zhihu_settings_blocked_users", false) !== false &&
+ /^https?:\/\/api\.zhihu\.com\/settings\/blocked_users/.test(
+ $.request.url
+ ):
+ manageBlackUser();
+ break;
+ default:
+ $.logger.debug("没有匹配到任何请求,请确认配置正确。");
+ break;
+ }
+ } else if ($.isRequest) {
+ // 屏蔽关键词解锁
+ if (
+ $.data.read("zhihu_settings_blocked_keywords", false) !== false &&
+ /^https?:\/\/api\.zhihu\.com\/feed-root\/block/.test($.request.url) ===
+ true
+ ) {
+ response = unlockBlockedKeywords(response);
+ }
+ } else {
+ $.data.del(currentUserInfoKey);
+ $.data.del(blockedUsersKey);
+ $.data.del(keywordBlockKey);
+ $.notification.post("哲也同学数据清理完毕");
+ }
+ if (response) {
+ $.done(response);
+ } else {
+ $.done();
+ }
+})();
+
// prettier-ignore
/**
*
@@ -1299,9 +1387,408 @@ function removeFeedSections() {
* \______/
*
*/
-// prettier-ignore
-function MagicJS(e="MagicJS",t="INFO"){const i=()=>{const e=typeof $loon!=="undefined";const t=typeof $task!=="undefined";const n=typeof module!=="undefined";const i=typeof $httpClient!=="undefined"&&!e;const s=typeof $storm!=="undefined";const r=typeof $environment!=="undefined"&&typeof $environment["stash-build"]!=="undefined";const o=i||e||s||r;const u=typeof importModule!=="undefined";return{isLoon:e,isQuanX:t,isNode:n,isSurge:i,isStorm:s,isStash:r,isSurgeLike:o,isScriptable:u,get name(){if(e){return"Loon"}else if(t){return"QuantumultX"}else if(n){return"NodeJS"}else if(i){return"Surge"}else if(u){return"Scriptable"}else{return"unknown"}},get build(){if(i){return $environment["surge-build"]}else if(r){return $environment["stash-build"]}else if(s){return $storm.buildVersion}},get language(){if(i||r){return $environment["language"]}},get version(){if(i){return $environment["surge-version"]}else if(r){return $environment["stash-version"]}else if(s){return $storm.appVersion}else if(n){return process.version}},get system(){if(i){return $environment["system"]}else if(n){return process.platform}},get systemVersion(){if(s){return $storm.systemVersion}},get deviceName(){if(s){return $storm.deviceName}}}};const s=(n,e="INFO")=>{let i=e;const s={SNIFFER:6,DEBUG:5,INFO:4,NOTIFY:3,WARNING:2,ERROR:1,CRITICAL:0,NONE:-1};const r={SNIFFER:"",DEBUG:"",INFO:"",NOTIFY:"",WARNING:"❗ ",ERROR:"❌ ",CRITICAL:"❌ ",NONE:""};const t=(e,t="INFO")=>{if(!(s[i]{i=e};return{setLevel:o,sniffer:e=>{t(e,"SNIFFER")},debug:e=>{t(e,"DEBUG")},info:e=>{t(e,"INFO")},notify:e=>{t(e,"NOTIFY")},warning:e=>{t(e,"WARNING")},error:e=>{t(e,"ERROR")},retry:e=>{t(e,"RETRY")}}};return new class{constructor(e,t){this._startTime=Date.now();this.version="3.0.0";this.scriptName=e;this.env=i();this.logger=s(e,t);this.http=typeof MagicHttp==="function"?MagicHttp(this.env,this.logger):undefined;this.data=typeof MagicData==="function"?MagicData(this.env,this.logger):undefined;this.notification=typeof MagicNotification==="function"?MagicNotification(this.scriptName,this.env,this.logger):undefined;this.utils=typeof MagicUtils==="function"?MagicUtils(this.env,this.logger):undefined;this.qinglong=typeof MagicQingLong==="function"?MagicQingLong(this.env,this.data,this.logger):undefined;if(typeof this.data!=="undefined"){let e=this.data.read("magic_loglevel");const n=this.data.read("magic_bark_url");if(e){this.logger.setLevel(e.toUpperCase())}if(n){this.notification.setBark(n)}}}get isRequest(){return typeof $request!=="undefined"&&typeof $response==="undefined"}get isResponse(){return typeof $response!=="undefined"}get isDebug(){return this.logger.level==="DEBUG"}get request(){if(typeof $request!=="undefined"){this.logger.sniffer(`RESPONSE:\n${JSON.stringify($request)}`);return $request}}get response(){if(typeof $response!=="undefined"){if($response.hasOwnProperty("status"))$response["statusCode"]=$response["status"];if($response.hasOwnProperty("statusCode"))$response["status"]=$response["statusCode"];this.logger.sniffer(`RESPONSE:\n${JSON.stringify($response)}`);return $response}else{return undefined}}done=(e={})=>{this._endTime=Date.now();let t=(this._endTime-this._startTime)/1e3;this.logger.info(`SCRIPT COMPLETED: ${t} S.`);if(typeof $done!=="undefined"){$done(e)}}}(e,t)}
-// prettier-ignore
-function MagicNotification(r,f,l){let s=null;let u=null;const c=typeof MagicHttp==="function"?MagicHttp(f,l):undefined;const e=t=>{try{let e=t.replace(/\/+$/g,"");s=`${/^https?:\/\/([^/]*)/.exec(e)[0]}/push`;u=/\/([^\/]+)\/?$/.exec(e)[1]}catch(e){l.error(`Bark url error: ${e}.`)}};function t(e=r,t="",i="",o=""){const n=i=>{try{let t={};if(typeof i==="string"){if(f.isLoon)t={openUrl:i};else if(f.isQuanX)t={"open-url":i};else if(f.isSurge)t={url:i}}else if(typeof i==="object"){if(f.isLoon){t["openUrl"]=!!i["open-url"]?i["open-url"]:"";t["mediaUrl"]=!!i["media-url"]?i["media-url"]:""}else if(f.isQuanX){t=!!i["open-url"]||!!i["media-url"]?i:{}}else if(f.isSurge){let e=i["open-url"]||i["openUrl"];t=e?{url:e}:{}}}return t}catch(e){l.error(`Failed to convert notification option, ${e}`)}return i};o=n(o);if(arguments.length==1){e=r;t="",i=arguments[0]}l.notify(`title:${e}\nsubTitle:${t}\nbody:${i}\noptions:${typeof o==="object"?JSON.stringify(o):o}`);if(f.isSurge){$notification.post(e,t,i,o)}else if(f.isLoon){if(!!o)$notification.post(e,t,i,o);else $notification.post(e,t,i)}else if(f.isQuanX){$notify(e,t,i,o)}if(s&&u&&typeof c!=="undefined"){p(e,t,i)}}function i(e=r,t="",i="",o=""){if(l.level==="DEBUG"){if(arguments.length==1){e=r;t="",i=arguments[0]}this.notify(e,t,i,o)}}function p(e=r,t="",i="",o=""){if(typeof c==="undefined"||typeof c.post==="undefined"){throw"Bark notification needs to import MagicHttp module."}let n={url:s,headers:{"Content-Type":"application/json; charset=utf-8"},body:{title:e,body:t?`${t}\n${i}`:i,device_key:u}};c.post(n).catch(e=>{l.error(`Bark notify error: ${e}`)})}return{post:t,debug:i,bark:p,setBark:e}}
-// prettier-ignore
-function MagicData(l,f){let u={fs:undefined,data:{}};if(l.isNode){u.fs=require("fs");try{u.fs.accessSync("./magic.json",u.fs.constants.R_OK|u.fs.constants.W_OK)}catch(e){u.fs.writeFileSync("./magic.json","{}",{encoding:"utf8"})}u.data=require("./magic.json")}const o=(e,t)=>{if(typeof t==="object"){return false}else{return e===t}};const a=e=>{if(e==="true"){return true}else if(e==="false"){return false}else if(typeof e==="undefined"){return null}else{return e}};const c=(e,t,r,s)=>{if(r){try{if(typeof e==="string")e=JSON.parse(e);if(e["magic_session"]===true){e=e[r]}else{e=null}}catch{e=null}}if(typeof e==="string"&&e!=="null"){try{e=JSON.parse(e)}catch{}}if(s===false&&!!e&&e["magic_session"]===true){e=null}if((e===null||typeof e==="undefined")&&t!==null&&typeof t!=="undefined"){e=t}e=a(e);return e};const i=t=>{if(typeof t==="string"){let e={};try{e=JSON.parse(t);const r=typeof e;if(r!=="object"||e instanceof Array||r==="bool"||e===null){e={}}}catch{}return e}else if(t instanceof Array||t===null||typeof t==="undefined"||t!==t||typeof t==="boolean"){return{}}else{return t}};const y=(e,t=null,r="",s=false,n=null)=>{let i=n||u.data;if(!!i&&typeof i[e]!=="undefined"&&i[e]!==null){val=i[e]}else{val=!!r?{}:null}val=c(val,t,r,s);return val};const d=(e,t=null,r="",s=false,n=null)=>{let i="";if(n||l.isNode){i=y(e,t,r,s,n)}else{if(l.isSurgeLike){i=$persistentStore.read(e)}else if(l.isQuanX){i=$prefs.valueForKey(e)}i=c(i,t,r,s)}f.debug(`READ DATA [${e}]${!!r?`[${r}]`:""} <${typeof i}>\n${JSON.stringify(i)}`);return i};const p=(t,r,s="",e=null)=>{let n=e||u.data;n=i(n);if(!!s){let e=i(n[t]);e["magic_session"]=true;e[s]=r;n[t]=e}else{n[t]=r}if(e!==null){e=n}return n};const g=(e,t,r="",s=null)=>{if(typeof t==="undefined"||t!==t){return false}if(!l.isNode&&(typeof t==="boolean"||typeof t==="number")){t=String(t)}let n="";if(s||l.isNode){n=p(e,t,r,s)}else{if(!r){n=t}else{if(l.isSurgeLike){n=!!$persistentStore.read(e)?$persistentStore.read(e):n}else if(l.isQuanX){n=!!$prefs.valueForKey(e)?$prefs.valueForKey(e):n}n=i(n);n["magic_session"]=true;n[r]=t}}if(!!n&&typeof n==="object"){n=JSON.stringify(n,"","\t")}f.debug(`WRITE DATA [${e}]${r?`[${r}]`:""} <${typeof t}>\n${JSON.stringify(t)}`);if(!s){if(l.isSurgeLike){return $persistentStore.write(n,e)}else if(l.isQuanX){return $prefs.setValueForKey(n,e)}else if(l.isNode){try{u.fs.writeFileSync("./magic.json",n);return true}catch(e){f.error(e);return false}}}return true};const e=(t,r,s,n=o,i=null)=>{r=a(r);const e=d(t,null,s,false,i);if(n(e,r)===true){return false}else{const l=g(t,r,s,i);let e=d(t,null,s,false,i);if(n===o&&typeof e==="object"){return l}return n(r,e)}};const S=(e,t,r)=>{let s=r||u.data;s=i(s);if(!!t){obj=i(s[e]);delete obj[t];s[e]=obj}else{delete s[e]}if(!!r){r=s}return s};const t=(e,t="",r=null)=>{let s={};if(r||l.isNode){s=S(e,t,r);if(!r){u.fs.writeFileSync("./magic.json",JSON.stringify(s))}else{r=s}}else{if(!t){if(l.isStorm){return $persistentStore.remove(e)}else if(l.isSurgeLike){return $persistentStore.write(null,e)}else if(l.isQuanX){return $prefs.removeValueForKey(e)}}else{if(l.isSurgeLike){s=$persistentStore.read(e)}else if(l.isQuanX){s=$prefs.valueForKey(e)}s=i(s);delete s[t];const n=JSON.stringify(s);g(e,n)}}f.debug(`DELETE KEY [${e}]${!!t?`[${t}]`:""}`)};const r=(e,t=null)=>{let r=[];let s=d(e,null,null,true,t);s=i(s);if(s["magic_session"]!==true){r=[]}else{r=Object.keys(s).filter(e=>e!=="magic_session")}f.debug(`READ ALL SESSIONS [${e}] <${typeof r}>\n${JSON.stringify(r)}`);return r};return{read:d,write:g,del:t,update:e,allSessions:r,defaultValueComparator:o,convertToObject:i}}
\ No newline at end of file
+// @formatter:off
+function MagicJS(scriptName="MagicJS",logLevel="INFO"){const MagicEnvironment=()=>{const isLoon=typeof $loon!=="undefined";const isQuanX=typeof $task!=="undefined";const isNode=typeof module!=="undefined";const isSurge=typeof $httpClient!=="undefined"&&!isLoon;const isStorm=typeof $storm!=="undefined";const isStash=typeof $environment!=="undefined"&&typeof $environment["stash-build"]!=="undefined";const isSurgeLike=isSurge||isLoon||isStorm||isStash;const isScriptable=typeof importModule!=="undefined";return{isLoon:isLoon,isQuanX:isQuanX,isNode:isNode,isSurge:isSurge,isStorm:isStorm,isStash:isStash,isSurgeLike:isSurgeLike,isScriptable:isScriptable,get name(){if(isLoon){return"Loon"}else if(isQuanX){return"QuantumultX"}else if(isNode){return"NodeJS"}else if(isSurge){return"Surge"}else if(isScriptable){return"Scriptable"}else{return"unknown"}},get build(){if(isSurge){return $environment["surge-build"]}else if(isStash){return $environment["stash-build"]}else if(isStorm){return $storm.buildVersion}},get language(){if(isSurge||isStash){return $environment["language"]}},get version(){if(isSurge){return $environment["surge-version"]}else if(isStash){return $environment["stash-version"]}else if(isStorm){return $storm.appVersion}else if(isNode){return process.version}},get system(){if(isSurge){return $environment["system"]}else if(isNode){return process.platform}},get systemVersion(){if(isStorm){return $storm.systemVersion}},get deviceName(){if(isStorm){return $storm.deviceName}}}};const MagicLogger=(scriptName,logLevel="INFO")=>{let _level=logLevel;const logLevels={SNIFFER:6,DEBUG:5,INFO:4,NOTIFY:3,WARNING:2,ERROR:1,CRITICAL:0,NONE:-1};const logEmoji={SNIFFER:"",DEBUG:"",INFO:"",NOTIFY:"",WARNING:"❗ ",ERROR:"❌ ",CRITICAL:"❌ ",NONE:""};const _log=(msg,level="INFO")=>{if(!(logLevels[_level]{_level=logLevel};return{getLevel:()=>{return _level},setLevel:setLevel,sniffer:msg=>{_log(msg,"SNIFFER")},debug:msg=>{_log(msg,"DEBUG")},info:msg=>{_log(msg,"INFO")},notify:msg=>{_log(msg,"NOTIFY")},warning:msg=>{_log(msg,"WARNING")},error:msg=>{_log(msg,"ERROR")},retry:msg=>{_log(msg,"RETRY")}}};return new class{constructor(scriptName,logLevel){this._startTime=Date.now();this.version="3.0.0";this.scriptName=scriptName;this.env=MagicEnvironment();this.logger=MagicLogger(scriptName,logLevel);this.http=typeof MagicHttp==="function"?MagicHttp(this.env,this.logger):undefined;this.data=typeof MagicData==="function"?MagicData(this.env,this.logger):undefined;this.notification=typeof MagicNotification==="function"?MagicNotification(this.scriptName,this.env,this.logger,this.http):undefined;this.utils=typeof MagicUtils==="function"?MagicUtils(this.env,this.logger):undefined;this.qinglong=typeof MagicQingLong==="function"?MagicQingLong(this.env,this.data,this.logger):undefined;if(typeof this.data!=="undefined"){let magicLoglevel=this.data.read("magic_loglevel");const barkUrl=this.data.read("magic_bark_url");if(magicLoglevel){this.logger.setLevel(magicLoglevel.toUpperCase())}if(barkUrl){this.notification.setBark(barkUrl)}}}get isRequest(){return typeof $request!=="undefined"&&typeof $response==="undefined"}get isResponse(){return typeof $response!=="undefined"}get isDebug(){return this.logger.level==="DEBUG"}get request(){return typeof $request!=="undefined"?$request:undefined}get response(){if(typeof $response!=="undefined"){if($response.hasOwnProperty("status"))$response["statusCode"]=$response["status"];if($response.hasOwnProperty("statusCode"))$response["status"]=$response["statusCode"];return $response}else{return undefined}}done=(value={})=>{this._endTime=Date.now();let span=(this._endTime-this._startTime)/1e3;this.logger.debug(`SCRIPT COMPLETED: ${span} S.`);if(typeof $done!=="undefined"){$done(value)}}}(scriptName,logLevel)}
+function MagicNotification(scriptName, env, logger, http) {
+ let _barkUrl = null;
+ let _barkKey = null;
+ const setBark = (url) => {
+ try {
+ let _url = url.replace(/\/+$/g, "");
+ _barkUrl = `${/^https?:\/\/([^/]*)/.exec(_url)[0]}/push`;
+ _barkKey = /\/([^\/]+)\/?$/.exec(_url)[1];
+ } catch (ex) {
+ logger.error(`Bark url error: ${ex}.`);
+ }
+ };
+ function post(title = scriptName, subTitle = "", body = "", opts = "") {
+ const _adaptOpts = (_opts) => {
+ try {
+ let newOpts = {};
+ if (typeof _opts === "string") {
+ if (env.isLoon) newOpts = { openUrl: _opts };
+ else if (env.isQuanX) newOpts = { "open-url": _opts };
+ else if (env.isSurge) newOpts = { url: _opts };
+ } else if (typeof _opts === "object") {
+ if (env.isLoon) {
+ newOpts["openUrl"] = !!_opts["open-url"] ? _opts["open-url"] : "";
+ newOpts["mediaUrl"] = !!_opts["media-url"]
+ ? _opts["media-url"]
+ : "";
+ } else if (env.isQuanX) {
+ newOpts = !!_opts["open-url"] || !!_opts["media-url"] ? _opts : {};
+ } else if (env.isSurge) {
+ let openUrl = _opts["open-url"] || _opts["openUrl"];
+ newOpts = openUrl ? { url: openUrl } : {};
+ }
+ }
+ return newOpts;
+ } catch (err) {
+ logger.error(`通知选项转换失败${err}`);
+ }
+ return _opts;
+ };
+ opts = _adaptOpts(opts);
+ if (arguments.length === 1) {
+ title = scriptName;
+ (subTitle = ""), (body = arguments[0]);
+ }
+ logger.notify(
+ `title:${title}\nsubTitle:${subTitle}\nbody:${body}\noptions:${
+ typeof opts === "object" ? JSON.stringify(opts) : opts
+ }`
+ );
+ if (env.isSurge) {
+ $notification.post(title, subTitle, body, opts);
+ } else if (env.isLoon) {
+ if (!!opts) $notification.post(title, subTitle, body, opts);
+ else $notification.post(title, subTitle, body);
+ } else if (env.isQuanX) {
+ $notify(title, subTitle, body, opts);
+ }
+ if (_barkUrl && _barkKey) {
+ bark(title, subTitle, body);
+ }
+ }
+ function debug(title = scriptName, subTitle = "", body = "", opts = "") {
+ if (logger.getLevel() === "DEBUG") {
+ if (arguments.length === 1) {
+ title = scriptName;
+ subTitle = "";
+ body = arguments[0];
+ }
+ this.post(title, subTitle, body, opts);
+ }
+ }
+ function bark(title = scriptName, subTitle = "", body = "", opts = "") {
+ if (typeof http === "undefined" || typeof http.post === "undefined") {
+ throw "Bark notification needs to import MagicHttp module.";
+ }
+ let options = {
+ url: _barkUrl,
+ headers: { "content-type": "application/json; charset=utf-8" },
+ body: {
+ title: title,
+ body: subTitle ? `${subTitle}\n${body}` : body,
+ device_key: _barkKey,
+ },
+ };
+ http.post(options).catch((ex) => {
+ logger.error(`Bark notify error: ${ex}`);
+ });
+ }
+ return { post: post, debug: debug, bark: bark, setBark: setBark };
+}
+function MagicData(env, logger) {
+ let node = { fs: undefined, data: {} };
+ if (env.isNode) {
+ node.fs = require("fs");
+ try {
+ node.fs.accessSync(
+ "./magic.json",
+ node.fs.constants.R_OK | node.fs.constants.W_OK
+ );
+ } catch (err) {
+ node.fs.writeFileSync("./magic.json", "{}", { encoding: "utf8" });
+ }
+ node.data = require("./magic.json");
+ }
+ const defaultValueComparator = (oldVal, newVal) => {
+ if (typeof newVal === "object") {
+ return false;
+ } else {
+ return oldVal === newVal;
+ }
+ };
+ const _typeConvertor = (val) => {
+ if (val === "true") {
+ return true;
+ } else if (val === "false") {
+ return false;
+ } else if (typeof val === "undefined") {
+ return null;
+ } else {
+ return val;
+ }
+ };
+ const _valConvertor = (val, default_, session, read_no_session) => {
+ if (session) {
+ try {
+ if (typeof val === "string") val = JSON.parse(val);
+ if (val["magic_session"] === true) {
+ val = val[session];
+ } else {
+ val = null;
+ }
+ } catch {
+ val = null;
+ }
+ }
+ if (typeof val === "string" && val !== "null") {
+ try {
+ val = JSON.parse(val);
+ } catch {}
+ }
+ if (read_no_session === false && !!val && val["magic_session"] === true) {
+ val = null;
+ }
+ if (
+ (val === null || typeof val === "undefined") &&
+ default_ !== null &&
+ typeof default_ !== "undefined"
+ ) {
+ val = default_;
+ }
+ val = _typeConvertor(val);
+ return val;
+ };
+ const convertToObject = (obj) => {
+ if (typeof obj === "string") {
+ let data = {};
+ try {
+ data = JSON.parse(obj);
+ const type = typeof data;
+ if (
+ type !== "object" ||
+ data instanceof Array ||
+ type === "bool" ||
+ data === null
+ ) {
+ data = {};
+ }
+ } catch {}
+ return data;
+ } else if (
+ obj instanceof Array ||
+ obj === null ||
+ typeof obj === "undefined" ||
+ obj !== obj ||
+ typeof obj === "boolean"
+ ) {
+ return {};
+ } else {
+ return obj;
+ }
+ };
+ const readForNode = (
+ key,
+ default_ = null,
+ session = "",
+ read_no_session = false,
+ externalData = null
+ ) => {
+ let data = externalData || node.data;
+ if (!!data && typeof data[key] !== "undefined" && data[key] !== null) {
+ val = data[key];
+ } else {
+ val = !!session ? {} : null;
+ }
+ val = _valConvertor(val, default_, session, read_no_session);
+ return val;
+ };
+ const read = (
+ key,
+ default_ = null,
+ session = "",
+ read_no_session = false,
+ externalData = null
+ ) => {
+ let val = "";
+ if (externalData || env.isNode) {
+ val = readForNode(key, default_, session, read_no_session, externalData);
+ } else {
+ if (env.isSurgeLike) {
+ val = $persistentStore.read(key);
+ } else if (env.isQuanX) {
+ val = $prefs.valueForKey(key);
+ }
+ val = _valConvertor(val, default_, session, read_no_session);
+ }
+ logger.debug(
+ `READ DATA [${key}]${
+ !!session ? `[${session}]` : ""
+ } <${typeof val}>\n${JSON.stringify(val)}`
+ );
+ return val;
+ };
+ const writeForNode = (key, val, session = "", externalData = null) => {
+ let data = externalData || node.data;
+ data = convertToObject(data);
+ if (!!session) {
+ let obj = convertToObject(data[key]);
+ obj["magic_session"] = true;
+ obj[session] = val;
+ data[key] = obj;
+ } else {
+ data[key] = val;
+ }
+ if (externalData !== null) {
+ externalData = data;
+ }
+ return data;
+ };
+ const write = (key, val, session = "", externalData = null) => {
+ if (typeof val === "undefined" || val !== val) {
+ return false;
+ }
+ if (!env.isNode && (typeof val === "boolean" || typeof val === "number")) {
+ val = String(val);
+ }
+ let data = "";
+ if (externalData || env.isNode) {
+ data = writeForNode(key, val, session, externalData);
+ } else {
+ if (!session) {
+ data = val;
+ } else {
+ if (env.isSurgeLike) {
+ data = !!$persistentStore.read(key)
+ ? $persistentStore.read(key)
+ : data;
+ } else if (env.isQuanX) {
+ data = !!$prefs.valueForKey(key) ? $prefs.valueForKey(key) : data;
+ }
+ data = convertToObject(data);
+ data["magic_session"] = true;
+ data[session] = val;
+ }
+ }
+ if (!!data && typeof data === "object") {
+ data = JSON.stringify(data, null, 4);
+ }
+ logger.debug(
+ `WRITE DATA [${key}]${
+ session ? `[${session}]` : ""
+ } <${typeof val}>\n${JSON.stringify(val)}`
+ );
+ if (!externalData) {
+ if (env.isSurgeLike) {
+ return $persistentStore.write(data, key);
+ } else if (env.isQuanX) {
+ return $prefs.setValueForKey(data, key);
+ } else if (env.isNode) {
+ try {
+ node.fs.writeFileSync("./magic.json", data);
+ return true;
+ } catch (err) {
+ logger.error(err);
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+ const update = (
+ key,
+ val,
+ session,
+ comparator = defaultValueComparator,
+ externalData = null
+ ) => {
+ val = _typeConvertor(val);
+ const oldValue = read(key, null, session, false, externalData);
+ if (comparator(oldValue, val) === true) {
+ return false;
+ } else {
+ const result = write(key, val, session, externalData);
+ let newVal = read(key, null, session, false, externalData);
+ if (comparator === defaultValueComparator && typeof newVal === "object") {
+ return result;
+ }
+ return comparator(val, newVal);
+ }
+ };
+ const delForNode = (key, session, externalData) => {
+ let data = externalData || node.data;
+ data = convertToObject(data);
+ if (!!session) {
+ obj = convertToObject(data[key]);
+ delete obj[session];
+ data[key] = obj;
+ } else {
+ delete data[key];
+ }
+ if (!!externalData) {
+ externalData = data;
+ }
+ return data;
+ };
+ const del = (key, session = "", externalData = null) => {
+ let data = {};
+ if (externalData || env.isNode) {
+ data = delForNode(key, session, externalData);
+ if (!externalData) {
+ node.fs.writeFileSync("./magic.json", JSON.stringify(data, null, 4));
+ } else {
+ externalData = data;
+ }
+ } else {
+ if (!session) {
+ if (env.isStorm) {
+ return $persistentStore.remove(key);
+ } else if (env.isSurgeLike) {
+ return $persistentStore.write(null, key);
+ } else if (env.isQuanX) {
+ return $prefs.removeValueForKey(key);
+ }
+ } else {
+ if (env.isSurgeLike) {
+ data = $persistentStore.read(key);
+ } else if (env.isQuanX) {
+ data = $prefs.valueForKey(key);
+ }
+ data = convertToObject(data);
+ delete data[session];
+ const json = JSON.stringify(data, null, 4);
+ write(key, json);
+ }
+ }
+ logger.debug(`DELETE KEY [${key}]${!!session ? `[${session}]` : ""}`);
+ };
+ const allSessionNames = (key, externalData = null) => {
+ let _sessions = [];
+ let data = read(key, null, null, true, externalData);
+ data = convertToObject(data);
+ if (data["magic_session"] !== true) {
+ _sessions = [];
+ } else {
+ _sessions = Object.keys(data).filter((key) => key !== "magic_session");
+ }
+ logger.debug(
+ `READ ALL SESSIONS [${key}] <${typeof _sessions}>\n${JSON.stringify(
+ _sessions,
+ null,
+ 4
+ )}`
+ );
+ return _sessions;
+ };
+ const allSessions = (key, externalData = null) => {
+ let _sessions = {};
+ let data = read(key, null, null, true, externalData);
+ data = convertToObject(data);
+ if (data["magic_session"] === true) {
+ _sessions = { ...data };
+ delete _sessions["magic_session"];
+ }
+ logger.debug(
+ `READ ALL SESSIONS [${key}] <${typeof _sessions}>\n${JSON.stringify(
+ _sessions,
+ null,
+ 4
+ )}`
+ );
+ return _sessions;
+ };
+ return {
+ read: read,
+ write: write,
+ del: del,
+ update: update,
+ allSessions: allSessions,
+ allSessionNames: allSessionNames,
+ defaultValueComparator: defaultValueComparator,
+ convertToObject: convertToObject,
+ };
+}
+// @formatter:on