// ==UserScript==
// @name b站屏蔽增强器
// @namespace http://tampermonkey.net/
// @license MIT
// @version 1.1.52
// @description 支持动态屏蔽、评论区过滤屏蔽,视频屏蔽(标题、用户、uid等)、蔽根据用户名、uid、视频关键词、言论关键词和视频时长进行屏蔽和精简处理(详情看脚本主页描述),针对github站内所有的链接都从新的标签页打开,而不从当前页面打开
// @author byhgz
// @exclude *://message.bilibili.com/pages/nav/header_sync
// @exclude *://message.bilibili.com/pages/nav/index_new_pc_sync
// @exclude *://live.bilibili.com/blackboard/dropdown-menu.html
// @exclude *://live.bilibili.com/p/html/live-web-mng/*
// @exclude *://www.bilibili.com/correspond/*
// @match https://www.bilibili.com/v/channel/*?tab=multiple
// @match *://search.bilibili.com/*
// @match *://www.bilibili.com/v/food/*
// @match *://www.bilibili.com/v/channel/*
// @match *://message.bilibili.com/*
// @match *://www.bilibili.com/read/*
// @match *://www.bilibili.com/v/topic/detail/?topic_id=*
// @match *://www.bilibili.com/v/kichiku/*
// @match *://t.bilibili.com/*
// @match *://space.bilibili.com/*
// @match *://www.bilibili.com/video/*
// @match *://live.bilibili.com/?spm_id_from=*
// @match *://live.bilibili.com/p/eden/area-tags?*
// @match *://live.bilibili.com/*
// @match *://www.bilibili.com/opus/*
// @match *://www.bilibili.com/*
// @match *://www.youtube.com/*
// @match *://github.com/*
// @require https://code.jquery.com/jquery-3.5.1.min.js
// @require https://greasyfork.org/scripts/462234-message/code/Message.js?version=1170653
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\util\Util.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\util\HttpUtil.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\Layout.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\LocalData.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\Perf_observer.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\AccountCenter.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\FrequencyChannel.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\Live.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\Trends.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\Bilibili.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\BilibiliOne.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\RuleList.js
// @require https://hangexi.gitee.io/bibibspuservideomonkeyscript\other\Github.js
// @icon https://static.hdslb.com/images/favicon.ico
// @connect bilibili.com
// @connect vip.mikuchase.ltd
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_addValueChangeListener
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// ==/UserScript==
const Rule = {
ruleLength: function () {
function setText(arr, id) {
if (arr !== undefined && arr !== null) {
$(id).text(arr.length);
}
}
setText(LocalData.getArrName(), "#textUserName");
setText(LocalData.getArrNameKey(), "#textUserNameKey");
setText(LocalData.getArrUID(), "#textUserUID");
setText(LocalData.getArrWhiteUID(), "#textUserBName");
setText(LocalData.getArrTitle(), "#textUserTitle");
setText(LocalData.getArrTitleKeyCanonical(), "#textUserTitleCanonical");
setText(Util.getData("commentOnKeyArr"), "#textContentOn");
setText(LocalData.getArrContentOnKeyCanonicalArr(), "#textContentOnCanonical");
setText(LocalData.getFanCardArr(), "#textFanCard");
setText(LocalData.getContentColumnKeyArr(), "#textColumn");
setText(LocalData.getDynamicArr(), "#textDynamicArr");
},
showInfo: function () {
const isDShielPanel = Util.getData("isDShielPanel");
const isAutoPlay = Util.getData("autoPlay");
const dShielPanel = $("#DShielPanel");
const autoPlayCheckbox = $("#autoPlayCheckbox");
if (isDShielPanel === null || isDShielPanel === undefined) {
dShielPanel.attr("checked", false);
} else {
dShielPanel.attr("checked", isDShielPanel);
}
if (isAutoPlay === null || isAutoPlay === undefined) {
autoPlayCheckbox.attr("checked", false);
} else {
autoPlayCheckbox.attr("checked", isAutoPlay);
}
const pushTypeSelect = $("#pushTypeSelect");
const videoZoneSelect = $("#video_zoneSelect");
const pushType = Home.getPushType();
pushTypeSelect.val(pushType);
switch (pushType) {
case "频道":
const tempSortTypeSelect = $("#sort_typeSelect");
const tempSortType = frequencyChannel.getSort_type();
loadChannel();
videoZoneSelect.val(frequencyChannel.getChannel_id());
tempSortTypeSelect.val(tempSortType);
tempSortTypeSelect.css("display", "inline")
break;
default:
loadPartition();
videoZoneSelect.val(LocalData.getVideo_zone());
break;
}
$("#delVideoCommentSectionsCheackBox").prop('checked', LocalData.getDelVideoCommentSections());//设置
$("#openPrivacyModeCheckbox").prop("checked", LocalData.getPrivacyMode());
},
//视频参数
videoData: {
//是否移除播放页右侧的的布局,其中包括【视频作者】【弹幕列表】【视频列表】和右侧相关的广告
isRhgthlayout: false,
//是否要移除右侧播放页的视频列表
isrigthVideoList: false,
//是否移除视频页播放器下面的标签,也就是Tag
isTag: false,
//是否移除视频页播放器下面的简介
isDesc: false,
//是否移除视频播放完之后的,推荐视频
isVideoEndRecommend: true,
//是否取消对播放页右侧列表的视频内容过滤屏蔽处理,如果播放页出现,加载不出页面图片,情况建议开启该功能
isRightVideo: false,
//是否点击了水平翻转
flipHorizontal: false,
//是否点击了垂直翻转
flipVertical: false
},
//动态相关配置信息
trendsData: {
//是否移除顶栏
isTop: false,
//是否移除右侧布局
isRightLayout: false,
//是覅移除话题布局上面的公告栏
isBiliDynBanner: true,
},
/**
*直播间的相关配置信息
*/
liveData: {
//是否移除直播间底部的全部信息,包括动态和主播公告和简介及荣誉
bottomElement: true,
//是否移除直播间顶部的信息(包括顶部标题栏)
topElement: true,
//是否移除直播间播放器头部的用户信息以及直播间基础信息
isheadInfoVm: true,
//是否移除直播间右侧的聊天布局
isRightChatLayout: false,
//是否移除直播间右侧的聊天内容
isChatHistoryPanel: false,
//是否移除右侧的聊天内容中的红色的系统提示
isSystemRedTip: true,
//是否移除右侧聊天内容中的用户进入房间提示
isEnterLiveRoomTip: true,
//是否移除左上角的b站直播logo
topLeftLogo: true,
//是否移除左上角的首页项目
topLeftHomeTitle: true,
//是否移除直播间底部的的简介和主播荣誉
bottomIntroduction: false,
//是否移除直播间的主播公告布局
container: false,
//是否移除直播首页右侧的悬浮按钮
rightSuspendButton: true,
//是否移除提示购物车
isShoppingCartTip: true,
//是否移除购物车
isShoppingCart: true,
//是否移除直播间的背景图
isDelbackground: true,
/**
* 是否屏蔽直播间底部动态
*/
liveFeed: false,
//要移除顶部左侧的选项(不包括右侧),但必须要有该选项,比如下面例子的,赛事,就移除其,如需要添加别的在该数组后面添加即可,如["赛事","生活"]
topLeftBar: ["赛事", "购物", "知识", "生活", "电台", "娱乐"],
//是否移除礼物栏
delGiftLayout: true,
//是否移除立即上舰
isEmbark: true,
//是否移除礼物栏的的礼物部分
isGift: true,
//直播分区时屏蔽的类型,比如在手游直播界面里的全部中,会屏蔽对应的类型房间号
classify: ["和平精英"],
//是否移除悬浮的233娘
is233Ma: true,
//是否移除右侧悬浮靠边按钮-如实验-关注
isRightSuspenBotton: true,
//是否移除直播水印
isLiveRoomWatermark: true
}
}
const Home = {
//首页下拉底部时依次加载视频的个数
videoIndex: 20,
background: {//主面板背景颜色及透明度
r: 92,
g: 80,
b: 80,
a: 1
},
data: {
//分区rid对应的类型
video_zoneList: JSON.parse(`{"1":"动画(主分区)","3":"音乐(主分区)","4":"游戏(主分区)","5":"娱乐(主分区)","11":"电视剧(主分区)","13":"番剧(主分区)","17":"单机游戏","19":"Mugen","20":"宅舞","21":"日常","22":"鬼畜调教","23":"电影(主分区)","24":"MAD·AMV","25":"MMD·3D","26":"音MAD","27":"综合","28":"原创音乐","29":"音乐现场","30":"VOCALOID·UTAU","31":"翻唱","32":"完结动画","33":"连载动画","36":"知识(主分区)","37":"人文·历史","47":"短片·手书·配音","51":"资讯","59":"演奏","65":"网络游戏","71":"综艺","75":"动物综合","76":"美食制作( 原[生活]->[美食圈] )","83":"其他国家","85":"小剧场","86":"特摄","95":"数码( 原手机平板 )","119":"鬼畜(主分区)","121":"GMV","122":"野生技术协会","124":"社科·法律·心理( 原社科人文、原趣味科普人文 )","126":"人力VOCALOID","127":"教程演示","129":"舞蹈(主分区)","130":"音乐综合","136":"音游","137":"明星综合","138":"搞笑","145":"欧美电影","146":"日本电影","147":"华语电影","152":"官方延伸","153":"国产动画","154":"舞蹈综合","155":"时尚(主分区)","156":"舞蹈教程","157":"美妆护肤","158":"穿搭","159":"时尚潮流","160":"生活(主分区)","161":"手工","162":"绘画","164":"健身","167":"国创(主分区)","168":"国产原创相关","169":"布袋戏","170":"资讯","171":"电子竞技","172":"手机游戏","173":"桌游棋牌","176":"汽车生活","177":"纪录片(主分区)","178":"科学·探索·自然","179":"军事","180":"社会·美食·旅行","181":"影视(主分区)","182":"影视杂谈","183":"影视剪辑","184":"预告·资讯","185":"国产剧","187":"海外剧","188":"科技(主分区)","193":"MV","195":"动态漫·广播剧","198":"街舞","199":"明星舞蹈","200":"中国舞","201":"科学科普","202":"资讯(主分区)","203":"热点","204":"环球","205":"社会","206":"综合","207":"财经商业","208":"校园学习","209":"职业职场","210":"手办·模玩","211":"美食(主分区)","212":"美食侦探","213":"美食测评","214":"田园美食","215":"美食记录","216":"鬼畜剧场","217":"动物圈(主分区)","218":"喵星人","219":"汪星人","220":"大熊猫","221":"野生动物","222":"爬宠","223":"汽车(主分区)","227":"购车攻略","228":"人文历史","229":"设计·创意","230":"软件应用","231":"计算机技术","232":"科工机械 ( 原工业·工程·机械 )","233":"极客DIY","234":"运动(主分区)","235":"篮球","236":"竞技体育","237":"运动文化","238":"运动综合","239":"家居房产","240":"摩托车","241":"娱乐杂谈","242":"粉丝创作","243":"乐评盘点","244":"音乐教学","245":"赛车","246":"改装玩车","247":"新能源车","248":"房车","249":"足球","250":"出行","251":"三农","252":"仿妆cos","253":"动漫杂谈"}`)
},
//是否隐藏了面板
myidClickIndex: true,
//是否初次点击了规则中心按钮
isFirstRuleCenterLayoutClick: false,
/**
*
* @return {string}
*/
getPushType: function () {
const data = Util.getData("pushType");
if (data === null || data === undefined) {
return "分区";
}
return data;
},
setPushType: function (key) {
Util.setData("pushType", key);
},
getBackgroundStr: function () {
return Util.getRGBA(this.background.r, this.background.g, this.background.b, this.background.a);
},
//调整首页样式
stypeBody: function () {
document.querySelector(".bili-header__banner").remove()//删除首页顶部的图片位置的布局
const interval = setInterval(() => {
try {
const headerChannelE = document.getElementsByClassName("bili-header__channel")[0];
headerChannelE.style.padding = 0;//调整-首页header按钮栏
headerChannelE.style.height = "auto";//调整其与下面控件的距离
document.getElementsByClassName("bili-feed4-layout")[0].style.padding = 0;//调整视频列表左右边距为0
document.querySelector("#i_cecream > div.bili-feed4 > div.bili-header.large-header > div.bili-header__bar").style.position = "inherit";//调整顶栏样式
document.querySelector("#i_cecream > div.bili-feed4 > div.header-channel").remove();//调整往下滑动之后顶部的悬浮栏
clearInterval(interval)
} catch (e) {
Print.ln("样式修改失败")
}
}, 500);
},
/**
* 屏蔽首页对应的视频
* @param {String} str 首页视频元素
*/
startShieldMainVideo: function (str) {
const interval = setInterval(() => {
let list = document.querySelectorAll(str);
if (list.length === 0) {
return;
}
while (true) {
const tempLength = list.length;
for (let v of list) {
let videoInfo, title, upName, upSpatialAddress, videoTime, playbackVolume;//可以一排定义
try {
videoInfo = v.querySelector(".bili-video-card__info--right");
//视频标题
title = videoInfo.querySelector(".bili-video-card__info--tit").getAttribute("title");
//用户名
upName = videoInfo.querySelector(".bili-video-card__info--author").getAttribute("title");
//用户空间地址
upSpatialAddress = videoInfo.querySelector(".bili-video-card__info--owner").getAttribute("href");
videoTime = v.querySelector(".bili-video-card__stats__duration").textContent;//视频的时间
const topInfo = v.querySelectorAll(".bili-video-card__stats--left .bili-video-card__stats--item");//1播放量2弹幕数
playbackVolume = topInfo[0].textContent;
} catch (e) {
v.remove();
Qmsg.info("清理异常元素");
// console.log("获取元素中,获取失败,下一行是该值的html");
// console.log(v)
continue;
}
let id = parseInt(upSpatialAddress.substring(upSpatialAddress.lastIndexOf("/") + 1));
if (isNaN(id)) {
v.remove();
Qmsg.info("清理非正常视频样式");
continue;
}
if (shieldVideo_userName_uid_title(v, upName, id, title, null, videoTime, playbackVolume)) {
Qmsg.info("屏蔽视频!");
continue;
}
const jqE = $(v);
if (Util.isEventJq(jqE, "mouseover")) {
continue;
}
jqE.mouseenter((e) => {
const domElement = e.delegateTarget;//dom对象
const info = domElement.querySelector(".bili-video-card__info--right");
const videoTitle = info.querySelectorAll("[title]")[0].textContent;
const userName = info.querySelectorAll("[title]")[1].textContent;
let href = info.querySelector(".bili-video-card__info--owner").href;
href = href.substring(href.lastIndexOf("/") + 1);
Util.showSDPanel(e, userName, href, videoTitle);
});
}
list = document.getElementsByClassName(str);//删除完对应元素之后再检测一次,如果没有了就结束循环并结束定时器
if (list.length !== tempLength) {//如果执行完之后关键元素长度还是没有变化,说明不需要在执行了
continue;
}
clearInterval(interval);
return;
}
}, 1000);
},
hideDisplayHomeLaylout: function () {//隐藏显示面板
const home_layout = document.getElementById("home_layout");
if (Home.myidClickIndex) {
home_layout.style.display = "block";
Home.myidClickIndex = false;
return;
}
home_layout.style.display = "none";
Home.myidClickIndex = true;
},
homePrefecture: function () {//针对于分区的广告页脚信息屏蔽
Util.circulateID("biliMainFooter", 2000, "已移除底部信息");
Util.circulateClassName("primary-btn feedback visible", 2000, "已移除右侧悬浮按钮");
for (let v of document.querySelectorAll(".eva-banner")) {
v.remove();
console.log("已移除界面中的横幅广告");
}
},
openTab: function (e) {// 点击标签时执行此函数
// 获取所有标签布局
const tabs = document.getElementsByClassName("tab");
// 循环遍历每个标签布局
for (let i = 0; i < tabs.length; i++) {
// 从所有标签布局中删除“active”类,使它们不可见
tabs[i].classList.remove("active");
}
// 将指定的标签布局添加到“active”类,使它可见
const tempId = document.getElementById(e);
tempId.classList.add("active");
}
}
//判断内容是否匹配上元素
const Shield = {
/**
* 根据用户提供的网页元素和对应的数组及key,精确匹配数组某个元素
* @param arr 数组
* @param key 唯一key
* @returns {boolean}
*/
arrKey: function (arr, key) {
if (arr === null || arr === undefined) {
return false;
}
return arr.includes(key);
},
/**
* 根据用户提供的字符串集合,当content某个字符包含了了集合中的某个字符则返回对应的字符,模糊匹配
* 反之返回null
* @param {string[]}arr 字符串数组
* @param {string}content 内容
* @returns {null|string}
*/
arrContent: function (arr, content) {
if (arr === null || arr === undefined) {
return null;
}
try {
for (let str of arr) {
if (content.toLowerCase().includes(str)) {//将内容中的字母转成小写进行比较
return str;
}
}
} catch (e) {
return null;
}
return null;
},
/**
* 根据用户提供的字符串集合,与指定内容进行比较,当content某个字符包含了了集合中的某个正则匹配则返回对应的字符,正则匹配
* 反之返回null
* @param {string[]}arr 字符串数组
* @param {string}content 内容
* @return {null|string}
*/
arrContentCanonical: function (arr, content) {
if (arr === null || arr === undefined) {
return null;
}
try {
for (let str of arr) {
if (content.search(str) === -1) {
continue;
}
return str;
}
} catch (e) {
return null;
}
return null;
}
}
//针对内容符合规则的删除元素并返回状态值
const Remove = {
//是否是白名单用户
isWhiteUserUID: function (uid) {
const tempArr = LocalData.getArrWhiteUID();
if (tempArr === null || tempArr === undefined) {
return false;
}
return tempArr.includes(uid);
},
/**
* 根据用户uid屏蔽元素
* @param element
* @param uid
* @returns {boolean}
*/
uid: function (element, uid) {
if (Shield.arrKey(LocalData.getArrUID(), parseInt(uid))) {
element.remove();
return true;
}
return false;
}
,
/**
* 根据用户名屏蔽元素,当用户名完全匹配规则时屏蔽
* @param element
* @param name
* @returns {boolean}
*/
name: function (element, name) {
if (Shield.arrKey(LocalData.getArrName(), name)) {
element.remove();
return true;
}
return false;
},
/**
* 根据用户名规则,当用规则字符包含用户名时返回对应的规则字符,反之null
* @param element
* @param name
* @returns {String|null}
*/
nameKey: function (element, name) {
const shieldArrContent = Shield.arrContent(LocalData.getArrNameKey(), name);
if (shieldArrContent !== null) {
element.remove();
}
return shieldArrContent;
}
,
/**
* 根据标题屏蔽元素
* @param element
* @param title
* @returns {String|null}
*/
titleKey: function (element, title) {
const shieldArrContent = Shield.arrContent(LocalData.getArrTitle(), title);
if (shieldArrContent !== null) {
element.remove();
}
return shieldArrContent;
},
/**
* 根据标题屏蔽元素
* 正则表达式匹配模式
* @param element
* @param title
* @return {string|null}
*/
titleKeyCanonical: function (element, title) {
const canonical = Shield.arrContentCanonical(LocalData.getArrTitleKeyCanonical(), title);
if (canonical !== null) {
element.remove();
}
return canonical;
},
/**
* 根据用户言论屏蔽元素
* @param element
* @param content
* @returns {String|null}
*/
contentKey: function (element, content) {
const shieldArrContent = Shield.arrContent(Util.getData("commentOnKeyArr"), content);
if (shieldArrContent !== null) {
element.remove();
}
return shieldArrContent;
},
/**
* 根据用户专栏内容关键词屏蔽元素
* @param element
* @param content
* @returns {String|null}
*/
columnContentKey: function (element, content) {
const shieldArrContent = Shield.arrContent(element, LocalData.getContentColumnKeyArr(), content);
if (shieldArrContent !== null) {
element.remove();
}
return shieldArrContent;
},
/**
* 根据用户粉丝牌进行屏蔽
* @param element
* @param key
* @returns {boolean}
*/
fanCard: function (element, key) {
if (Shield.arrKey(LocalData.getFanCardArr(), key)) {
element.remove();
return true;
}
return false;
},
/**
* 限制的视频时长最小值,低于该值的都屏蔽
* 根据视频时长,过滤指定时长内的视频
* @param element
* @param {Number}key 秒数
* @returns {boolean}
*/
videoMinFilterS: function (element, key) {
const min = LocalData.video.getFilterSMin();
if (min === null) {
return false;
}
if (min > key) {
element.remove();
return true;
}
return false;
},
/**
* 限制可展示的视频时长最大值,高于该值的都屏蔽
* @param element
* @param {Number}key 秒数
* @returns {boolean}
*/
videoMaxFilterS: function (element, key) {
const max = LocalData.video.getfilterSMax();
if (max === 0 || max < LocalData.video.getFilterSMin() || max === null) {//如果最大值为0,则不需要执行了,和当最小值大于最大值也不执行
return false;
}
if (max < key) {
element.remove();
return true;
}
return false;
},
/**
* 限制视频播放量最小值,低于该值的都屏蔽
* 根据视频播放量,过滤低于指定播放量的视频
* @param element
* @param {number}key 播放量纯数字
* @returns {boolean}
*/
videoMinPlaybackVolume: function (element, key) {
const min = LocalData.video.getBroadcastMin();
if (min === null) {
return false;
}
if (min > key) {
element.remove();
return true;
}
return false;
},
/**
* 限制视频播放量最大值,高于该值的都屏蔽
* 根据视频播放量,过滤高于指定播放量的视频
* @param element
* @param {number}key 播放量纯数字
* @returns {boolean}
*/
videoMaxPlaybackVolume: function (element, key) {
const max = LocalData.video.getBroadcastMax();
if (max === 0 || max < LocalData.video.getBroadcastMin() || max === null) {//如果最大值为0,则不需要执行了,和当最小值大于最大值也不执行
return false;
}
if (max < key) {
element.remove();
return true;
}
return false;
},
/**
* 限制可暂时的视频弹幕量最小值,低于该值的都屏蔽
* 根据视频弹幕量,过滤低于指定弹幕量的视频
* @param element
* @param {number}key 弹幕数量
* @returns {boolean}
*/
videoMinBarrageQuantity: function (element, key) {
if (LocalData.video.getBarrageQuantityMin() > key) {
element.remove();
return true;
}
return false;
},
/**
* 限制可暂时的视频弹幕量最大值,高于该值的都屏蔽
* 根据视频弹幕量,过滤高于指定弹幕量的视频
* @param element
* @param {number}key 弹幕数量
* @returns {boolean}
*/
videoMaxBarrageQuantity: function (element, key) {
const max = LocalData.video.getBarrageQuantityMax();
if (max === 0 || LocalData.video.getBarrageQuantityMin() > max) {
return false;
}
if (max > key) {
element.remove();
return true;
}
return false;
}
}
/**
* 根据规则删除专栏和动态的评论区
* 针对于专栏和动态内容下面的评论区
*/
function delDReplay() {
const interval = setInterval(() => {
const list = document.querySelectorAll(".comment-list.has-limit>*");
if (list.length === 0) {
return;
}
clearInterval(interval);
for (let v of list) {
const rootUserinfo = v.querySelector(".user>.name");
const rootName = rootUserinfo.textContent;
const rootUid = rootUserinfo.getAttribute("data-usercard-mid");
const rootContent = v.querySelector(".text").textContent;
if (startPrintShieldNameOrUIDOrContent(v, rootName, parseInt(rootUid), rootContent)) {
Qmsg.info("屏蔽了言论!!");
continue;
}
const jqE = $(rootUserinfo);
if (!Util.isEventJq(jqE, "mouseover")) {
jqE.mouseenter((e) => {
const domElement = e.delegateTarget;//dom对象
const name = domElement.textContent;
const uid = domElement.getAttribute("data-usercard-mid");
Util.showSDPanel(e, name, uid);
});
}
const replyItem = v.querySelectorAll(".reply-box>.reply-item.reply-wrap");//楼层成员
if (replyItem.length === 0) {
continue;
}
for (let j of replyItem) {
const subUserInfo = j.querySelector(".user>.name");
const subName = subUserInfo.textContent;
const subUid = subUserInfo.getAttribute("data-usercard-mid");
const subContent = j.querySelector(".text-con").textContent;
if (startPrintShieldNameOrUIDOrContent(j, subName, parseInt(subUid), subContent)) {
Qmsg.info("屏蔽了言论!!");
continue;
}
const jqE = $(j);
if (Util.isEventJq(jqE, "mouseover")) {
continue;
}
jqE.mouseenter((e) => {
const domElement = e.delegateTarget;//dom对象
const name = domElement.querySelector(".name").textContent;
const uid = domElement.querySelector("a").getAttribute("data-usercard-mid");
Util.showSDPanel(e, name, uid);
});
}
}
}, 60);
}
const HtmlStr = {
/**
*返回用户卡片基础信息面板布局
* @param uid{number} uid
* @param userName{string} 用户名
* @param level 用户等级
* @param sign{string} 签名
* @param image{string} 头像
* @param gz{string} 关注量
* @param fs{string} 粉丝数量
* @param hz {string} 获赞
* @return {string}
*/
getUserCard: function (uid, userName, level, sign, image, gz, fs, hz) {
return `
`;
},
/**
* 获取直播列表布局
*/
getLiveList: function (typeTitle) {
return $(``);
},
/**
*
* @param name 用户名
* @param uid 用户UID
* @param liveID 用户直播间房号
* @param image 用户头像
* @param title 直播间标题
* @returns {string}
*/
getLiveItem: function (name, uid, liveID, image, title) {
return $(` `);
}
}
const Print = {
ln: function (content) {
Util.printElement("#outputInfo", `${content}`);
},
video: function (color, content, name, uid, title, videoHref) {
Util.printElement("#outputInfo", `
${Util.toTimeString()}${content}屏蔽用户【${name}】uid=【${uid}】标题【${title}】
`);
}, commentOn: function (color, content, name, uid, primaryContent) {
Util.printElement("#outputInfo", `
${Util.toTimeString()}${content} 屏蔽用户【${name}】uid=【${uid}】
原言论=【${primaryContent}】
`);
}
};
const HoverBlockList = {
/**
*匹配符合条件的数组
* @param arr 数组
* @param key 匹配元素键中的key
* @param search 符合上面参数,且包含该关键字的匹配
* @returns Array
*/
searchAndInitList: function (arr, key, search = '') {
const searchStr = search.toString().toLowerCase();
const result = [];
function omitKey(obj, key, search) {
const newItem = Object.assign({}, obj);
delete newItem[key];
newItem[key] = search;
return newItem;
}
for (let i = 0, len = arr.length; i < len; i++) {
const item = arr[i];
if (item.hasOwnProperty(key) && item[key].toString().toLowerCase().includes(searchStr)) {
const existingItemIndex = result.findIndex(r => r.uid === item.uid);
if (existingItemIndex === -1) {
const newItem = {
uid: item.uid,
show: item[$("#show-select").val()],
items: [omitKey(item, key, search)]
};
result.push(newItem);
} else {
result[existingItemIndex].items.push(omitKey(item, key, search));
}
}
}
return result;
},
/**
*数据例子
* [
* {"uid": 1, "name": "张三", "age": 20, "title": "标题"},
* {"uid": 2, "name": "李四", "age": 25},
* {"uid": 3, "name": "王四", "age": 30}
* ];
* @param list 数据
* @param typeName 要显示在项目的值
* @param func 点击获取选中事件
*/
init: function (list, typeName = "name", func) {
const pop_ListLayout = $("pop-ListLayout");
if (pop_ListLayout.length > 0) {
alert("请先关闭现有悬浮列表!");
return;
}
$("body").append(``);
for (let v of Util.getDistinctKeys(list)) {
$("#search-select").append(``);
$("#show-select").append(``);
}
HoverBlockList.initList(list, typeName);
$("#getSelectedCheckboxItem").click(() => {
// 获取所有选中的项
const checkedItems = $('#popList input[type="checkbox"]:checked');
if (checkedItems.length === 0) {
return;
}
const tempArrID = [];
// 遍历选中的元素并打印它们的值
checkedItems.each(function () {
tempArrID.push(parseInt($(this).val()));
});
if (tempArrID.length === 0) {
return;
}
func(tempArrID);
});
// 监听 input 的 value 变化
$('#search-input').on('input', function () {
const content = $(this).val();
if (content === "" || content.includes(" ")) {
return;
}
const search_selectV = $("#search-select").val();
HoverBlockList.initList(list, search_selectV, content);
});
$("#clone-popLayoutList").click(() => {//点击关闭,则删掉悬浮列表下面的所有jq添加的事件并删除列表元素
const popMain = $("#pop-ListLayout");
popMain.off();
popMain.remove();
$("#OpenTheFilteredList").show();
});
},
/**
*
* @param dataList 数据列表
* @param itemKey 匹配元素键中的key
* @param search 搜索的关键词
* @returns {boolean}
*/
initList: function (dataList, itemKey, search = "") {
const keyArr = HoverBlockList.searchAndInitList(dataList, itemKey, search);
if (keyArr.length === 0) {
return false;
}
const popList = $("#popList");
popList.children().remove();
keyArr.forEach((value) => {
popList.append($(``));
});
return true;
}
};
//添加元素
const addElement = {
homeVideoE: {
/**
* @param {string}title 视频标题
* @param {string}videoAddess 视频地址
* @param {string}videoImage 视频封面
* @param {string}userID 用户uid
* @param {string}userName 用户名
* @param {string}timeLong 视频时长
* @param {string}ctime 发布时间
* @param {string}view 播放量
* @param {string}danmaku 弹幕量
*/
getHtmlStr: function (title, videoAddess, videoImage, userID, userName, timeLong, ctime, view, danmaku) {
return ``;
}
}
}
function startMonitorTheNetwork() {//监听网络变化
const observer = new PerformanceObserver(perf_observer);
observer.observe({entryTypes: ['resource']});
}
const urleCrud = {//规则的增删改查
/**
* 单个元素进行添加
* @param {Array} arr
* @param {String,number} key
* @param {String} ruleStrName
*/
add: function (arr, key, ruleStrName) {
arr.push(key);
Util.setData(ruleStrName, arr);
Qmsg.success(`添加${ruleStrName}的值成功=${key}`);
Rule.ruleLength();
return true;
},
/**
* 批量添加,要求以数组形式
* @param {Array} arr
* @param {Array} key
* @param ruleStrName
*/
addAll: function (arr, key, ruleStrName) {
let tempLenSize = 0;
const set = new Set();
for (let v of key) {
if (arr.includes(v)) {
continue;
}
tempLenSize++;
arr.push(v);
set.add(v);
}
if (tempLenSize === 0) {
Print.ln("内容长度无变化,可能是已经有了的值")
return;
}
Util.setData(ruleStrName, arr);
Print.ln(`已添加个数${tempLenSize},新内容为【${JSON.stringify(Array.from(set))}】`)
Rule.ruleLength();
},
/**
*
* @param arr
* @param key
* @param ruleStrName
* @return {boolean}
*/
del: function (arr, key, ruleStrName) {
const index = arr.indexOf(key);
if (index === -1) {
Print.ln("未有该元素!")
return false;
}
arr.splice(index, 1);
Util.setData(ruleStrName, arr);
Print.ln("已经删除该元素=" + key);
Rule.ruleLength();
return true;
}
}
const butLayEvent = {
butaddName: function (ruleStr, contentV) {
if (contentV === '') {
Qmsg.error("请输入正确的内容");
return false;
}
if (!confirm(`您要添加的内容是? 【${contentV}】 ,类型=${ruleStr}`)) {
return false;
}
let arrayList = Util.getData(ruleStr);
if (arrayList === null || arrayList === undefined) {
urleCrud.add([], contentV, ruleStr);
return false;
}
if (arrayList.includes(contentV)) {
Qmsg.error("当前已有该值!")
return false;
}
return urleCrud.add(arrayList, contentV, ruleStr);
;
},
butaddAllName: function (ruleStr, contentV) {
if (contentV === '') {
Print.ln("请输入正确的内容")
return;
}
let tempList;
try {
tempList = JSON.parse(contentV);
} catch (error) {
Qmsg.error("内容不正确!内容需要数组或者json格式!错误信息=" + error);
return;
}
let arrayList = Util.getData(ruleStr);
if (arrayList === null || arrayList === undefined) {
urleCrud.addAll([], tempList, ruleStr);
return;
}
urleCrud.addAll(arrayList, tempList, ruleStr);
},
butDelName: function (ruleStr, contentV) {
let arrayList = Util.getData(ruleStr);
if (arrayList === null || arrayList === undefined) {
Print.ln("没有内容哟")
return false;
}
if (!arrayList.includes(contentV)) {
Print.ln("没有该内容哟=" + contentV)
return false;
}
return urleCrud.del(arrayList, contentV, ruleStr);
},
butDelAllName: function (ruleStr) {
const list = Util.getData(ruleStr);
if (list === null || list === undefined) {
Print.ln("没有内容哟")
return;
}
const b = confirm("您确定要全部删除吗?");
if (!b) {
return;
}
Util.delData(ruleStr);
Print.ln("已全部清除=" + ruleStr);
Rule.ruleLength();
},
//查询
butFindKey: function (ruleStr, contentV) {
if (contentV === '') {
Print.ln("请输入正确的内容")
return;
}
let arrayList = Util.getData(ruleStr);
if (arrayList === null || arrayList === undefined) {
Print.ln("找不到该内容!");
return;
}
if (arrayList.includes(contentV)) {
const info = `搜索的值【${contentV}】,已存在!`;
Print.ln(info);
Qmsg.success(info);
return;
}
const info = `找不到该内容!【${contentV}】`;
Print.ln(info);
Qmsg.error(info);
},
//修改
butSetKey: function (ruleStr, oldKey, newKey) {
if (oldKey === '' || oldKey.includes(" ") || newKey === "" || newKey.includes(" ")) {
return;
}
if (oldKey === newKey) {
Print.ln("请输入正确的内容,两者内容不能相同")
return;
}
let arrayList = Util.getData(ruleStr);
if (arrayList === null || arrayList === undefined) {
Print.ln("找不到该内容!");
return;
}
if (!arrayList.includes(oldKey)) {
Print.ln("找不到该内容!,无法替换!");
return;
}
const index = arrayList.indexOf(oldKey);
if (index === -1) {
Print.ln("未有该元素!")
return;
}
arrayList.splice(index, 1, newKey);
Util.setData(ruleStr, arrayList);
Qmsg.success("替换成功!旧元素=" + oldKey + " 新元素=" + newKey);
}
}
/**
* 针对言论内容根据name和uid进行屏蔽并打印消息
* @param element 网页元素
* @param name 用户名
* @param uid 用户uid
* @param content 言论内容
* @returns {boolean}
*/
function startPrintShieldNameOrUIDOrContent(element, name, uid, content) {
if (Remove.isWhiteUserUID(uid)) {
return false;
}
const key = Remove.contentKey(element, content);
if (key != null) {
Print.commentOn("#00BFFF", `已通过言论关键词了【${key}】`, name, uid, content);
return true;
}
const isUid = Remove.uid(element, uid);
if (isUid) {
Print.commentOn("#yellow", `已通过UID屏蔽`, name, uid, content);
return true;
}
const isName = Remove.name(element, name);
if (isName) {
Print.commentOn(null, `已通过指定用户名【${isName}】`, name, uid, content);
return true;
}
const isNameKey = Remove.nameKey(element, name);
if (isNameKey != null) {
Print.commentOn(null, `已通过指定用户名模糊规则【${isNameKey}】`, name, uid, content);
return true;
}
return false;
}
/**
* 屏蔽视频元素
* 针对用户名、用户uid,视频标题
* @param element 对应的视频元素
* @param {String}name 用户名
* @param {Number}uid 用户uid
* @param {String}title 视频标题
* @param{String}videoHref 视频地址
* @param {String}videoTime 视频时间
* @param{String}videoPlaybackVolume 播放量
* @returns {boolean} 是否执行完
*/
function shieldVideo_userName_uid_title(element, name, uid, title, videoHref, videoTime, videoPlaybackVolume) {
if (Remove.isWhiteUserUID(uid)) {
return false;
}
if (uid !== null) {
const isUid = Remove.uid(element, uid);
if (isUid) {
Print.video("yellow", "已通过UID屏蔽", name, uid, title, videoHref);
return true;
}
}
const isName = Remove.name(element, name);
if (isName) {
Print.video(null, "已通过用户名屏蔽", name, uid, title, videoHref);
return true;
}
const isNameKey = Remove.nameKey(element, name);
if (isNameKey != null) {
Print.video(null, `已通过用户名模糊屏蔽规则=【${isNameKey}】`, name, uid, title, videoHref)
return true;
}
const videoTitle = Remove.titleKey(element, title);
if (videoTitle != null) {
Print.video("#66CCCC", `已通过标题模糊屏蔽规则=【${videoTitle}】`, name, uid, title, videoHref);
return true;
}
const titleKeyCanonical = Remove.titleKeyCanonical(element, title);
if (titleKeyCanonical != null) {
Print.video("#66CCCC", `已通过标题正则表达式屏蔽规则=${titleKeyCanonical}`, name, uid, title, videoHref);
return true;
}
if (videoPlaybackVolume !== null) {
const change = Util.changeFormat(videoPlaybackVolume);
if (Remove.videoMinPlaybackVolume(element, change)) {
Print.video(null, `已过滤视频播放量小于=【${LocalData.video.getBroadcastMin()}】的视频`, name, uid, title, videoHref);
return true;
}
if (Remove.videoMaxPlaybackVolume(element, change)) {
Print.video(null, `已过滤视频播放量大于=【${LocalData.video.getBroadcastMax()}】的视频`, name, uid, title, videoHref);
return true;
}
}
if (videoTime === null) {
return false;
}
const timeTotalSeconds = Util.getTimeTotalSeconds(videoTime);
if (Remove.videoMinFilterS(element, timeTotalSeconds)) {
Print.video(null, `已通过视频时长过滤时长小于=【${LocalData.video.getFilterSMin()}】秒的视频`, name, uid, title, videoHref);
return true;
}
if (Remove.videoMaxFilterS(element, timeTotalSeconds)) {
Print.video(null, `已过滤时长大于=【${LocalData.video.getfilterSMax()}】秒的视频`, name, uid, title, videoHref);
return true;
}
return false;
}
//消息中心
const message = {//消息中心
/**
* 删除消息中心的回复我的规则
*/
delMessageReply: function () {
const list = document.getElementsByClassName("reply-item");
for (let v of list) {
const info = v.getElementsByClassName("name-field")[0];
const name = info.textContent;//用户名
const indess = info.getElementsByTagName("a")[0].getAttribute("href");
const uid = parseInt(indess.substring(indess.lastIndexOf("/") + 1));
const content = v.getElementsByClassName("text string")[0].textContent;//消息内容
if (startPrintShieldNameOrUIDOrContent(v, name, uid, content)) {
Qmsg.info("屏蔽了言论!!");
}
}
},
/**
* 删除消息中的艾特我的规则
*/
delMessageAT: function () {
for (let v of document.getElementsByClassName("at-item")) {
const userInfo = v.getElementsByClassName("name-field")[0].getElementsByTagName("a")[0];
const href = userInfo.getAttribute("href");
const userName = userInfo.textContent;
const uid = parseInt(href.substring(href.lastIndexOf("/") + 1));
const content = v.getElementsByClassName("content-list")[0].textContent;
if (startPrintShieldNameOrUIDOrContent(v, userName, uid, content)) {
Qmsg.info("屏蔽了言论!!");
}
}
}
}
//针对视频播放页的相关方法
const videoFun = {
//移除右侧悬浮按钮
rightSuspendButton: function () {
Util.circulateClassNames("storage-box", 0, 2, 2000, "已移除右侧的【返回旧版】【新版反馈】【客服】");//针对新版界面
},
delRightE: function () {
const video = Rule.videoData;
if (video.isRhgthlayout) {
Util.circulateClassNames("right-container is-in-large-ab", 0, 3, 1500, "已移除视频播放器右侧的布局");
return;
}
Util.circulateClassNames("video-page-special-card-small", 0, 2, 2000, "移除播放页右上角的其他推广");
Util.circulateClassNames("vcd", 0, 2, 2000, "已移除右上角的广告");
Util.circulateClassName("video-page-game-card-small", 2000, "移除播放页右上角的游戏推广");
Util.circulateIDs("right-bottom-banner", 2, 1500, "删除右下角的活动推广");
Util.circulateClassName("pop-live-small-mode part-undefined", 1000, "删除右下角的直播推广")
Util.circulateClassNames("ad-report video-card-ad-small", 0, 3, 2000, "已删除播放页右上角的广告内容");
if (video.isrigthVideoList) {
Util.circulateID("reco_list", 2000, "已移除播放页右侧的视频列表");
return;
}
if (!video.isRightVideo) {
setTimeout(() => {
document.getElementsByClassName("rec-footer")[0].addEventListener("click", () => {
Print.ln("用户点击了右侧的展开")
videoFun.rightVideo().then(() => {
});
})
}, 4000);
}
},
//对视频页的播放器下面的进行处理
delBottonE: function () {
this.commentArea();//处理评论区
Util.circulateIDs("bannerAd", 10, 2500, "已移除播放器底部的广告");
Util.circulateID("activity_vote", 2500, "已移除播放器底部的活动广告");
Util.circulateClassName("reply-notice", 2000, "已移除播放器底部的橙色横幅通知");
Util.circulateClassName("ad-floor-cover b-img", 2000, "已移除播放器底部的图片广告");
if (Rule.videoData.isTag) {
Util.circulateID("v_tag", 2000, "已移除播放器底部的tag栏");
}
if (Rule.videoData.isDesc) {
Util.circulateID("v_desc", 2000, "已移除播放器底部的简介");
}
}, commentArea: function () {
if (LocalData.getDelVideoCommentSections()) {
Util.circulateID("comment", 1500, "已移除评论区");
}
}, //针对视频播放页右侧的视频进行过滤处理。该界面无需用时长过滤,视频数目较少
rightVideo: async function () {//异步形式执行
const interval = setInterval(() => {
let list;
try {
list = document.querySelectorAll(".video-page-card-small");
} catch (e) {
return;
}
if (list.length === 0) {
return;
}
clearInterval(interval);
for (let v of list) {//获取右侧的页面的视频列表
//用户名
const name = v.querySelector(".name").textContent;
//视频标题
const videoTitle = v.querySelector(".title").textContent;
//用户空间地址
const upSpatialAddress = v.querySelector(".upname>a").href;
const id = upSpatialAddress.substring(upSpatialAddress.lastIndexOf("com/") + 4, upSpatialAddress.length - 1);
if (shieldVideo_userName_uid_title(v, name, parseInt(id), videoTitle, null, null, null)) {
Qmsg.info("屏蔽了视频!!");
continue;
}
$(v).mouseenter((e) => {
const domElement = e.delegateTarget;//dom对象
const name = domElement.querySelector(".name").textContent;
const title = domElement.querySelector(".title").textContent;
const upSpatialAddress = domElement.querySelector(".upname>a").href;
const id = upSpatialAddress.substring(upSpatialAddress.lastIndexOf("com/") + 4, upSpatialAddress.length - 1);
Util.showSDPanel(e, name, id, title);
});
}
}, 1000);
},
click_playerCtrlWhid: function () {//点击播放器的宽屏按钮
const interval = setInterval(() => {
try {
document.getElementsByClassName("bpx-player-ctrl-btn bpx-player-ctrl-wide")[0].click()
Print.ln("已自动点击播放器的宽屏")
clearInterval(interval);
} catch (e) {
}
}, 1000);
}
}
const greatDemand = {//热门
delVideo: function () {
let list = document.getElementsByClassName("video-card");
if (list.length === 0) {
list = document.getElementsByClassName("_card_1kuml_6");
for (let v of list) {
const title = v.getElementsByClassName("title")[1].textContent;
const name = v.getElementsByClassName("upName")[0].textContent;
const time = v.getElementsByClassName("time")[0].textContent;
if (shieldVideo_userName_uid_title(v, name, null, title, null, null, time)) {
Qmsg.info("屏蔽了视频!!");
}
}
return;
}
for (let v of list) {
//页面暂时没法获取uid,可能是我的技术问题,至少暂时先这样
const title = v.getElementsByClassName("video-name")[0].textContent;//标题
const name = v.getElementsByClassName("up-name__text")[0].textContent;//用户名
const play = v.getElementsByClassName("play-text")[0].textContent.trim();//播放量
//const like = v.getElementsByClassName("like-text")[0].textContent.trim();//弹幕量
if (shieldVideo_userName_uid_title(v, name, null, title, null, play)) {
Qmsg.info("屏蔽了视频!!");
}
}
}
}
const search = {//搜索
getDataV: function (v) {
let info = v.querySelector(".bili-video-card__info--right");
let userInfo = info.querySelector(".bili-video-card__info--owner");
//用户空间地址
let upSpatialAddress = userInfo.getAttribute("href");
const topInfo = v.querySelector(".bili-video-card__stats--left").querySelectorAll(".bili-video-card__stats--item");//1播放量2弹幕数
return {
//用户名
name: userInfo.querySelector(".bili-video-card__info--author").textContent,
//标题
title: info.querySelector(".bili-video-card__info--tit").getAttribute("title"),
upSpatialAddress: upSpatialAddress,
uid: Util.getSubUid(upSpatialAddress.substring(upSpatialAddress.lastIndexOf("/") + 1)),
//视频的时间
videoTime: v.querySelector(".bili-video-card__stats__duration").textContent,
//播放量
playbackVolume: topInfo[0],
//弹幕量
barrageQuantity: topInfo[1]
}
},
/**
* 保准页面加载了本脚本之后只会触发一次该判断
* 用于搜索页面的专栏按钮监听。且只会加载一次
* @type {boolean}
*/
searchColumnBool: false,
/**
* 删除搜索页面的视频元素
* @param videoList
*/
searchRules: function (videoList) {
if (videoList === undefined || videoList === null) {
return;
}
for (let v of videoList) {
try {
let info = v.querySelector(".bili-video-card__info--right");
let userInfo = info.querySelector(".bili-video-card__info--owner");
//用户名
let name = userInfo.querySelector(".bili-video-card__info--author").textContent;
//视频标题
let title = info.querySelector(".bili-video-card__info--tit").title;
//用户空间地址
let upSpatialAddress = userInfo.getAttribute("href");
if (!upSpatialAddress.includes("//space.bilibili.com/")) {
Qmsg.info("检测到不是正常视频内容,故隐藏该元素");
//如果获取的类型不符合规则则结束本轮
v.remove();
continue;
}
const videoTime = v.querySelector(".bili-video-card__stats__duration").textContent;//视频的时间
const topInfo = v.querySelector(".bili-video-card__stats--left").querySelectorAll(".bili-video-card__stats--item");//1播放量2弹幕数
let id = upSpatialAddress.substring(upSpatialAddress.lastIndexOf("/") + 1);
if (shieldVideo_userName_uid_title(v, name, id, title, null, videoTime, topInfo[0].textContent)) {
Qmsg.info("屏蔽了视频!!");
continue;
}
const jqE = $(v);
if (Util.isEventJq(jqE, "mouseover")) {
continue;
}
jqE.mouseenter((e) => {
const domElement = e.delegateTarget;//dom对象
const data = search.getDataV(domElement);
Util.showSDPanel(e, data.name, data.uid);
});
} catch (e) {
v.remove();
//console.log("错误信息=" + e + " 删除该元素" + v)
}
}
},
searchColumn: function () {//根据规则屏蔽搜索专栏项目
const interval = setInterval(() => {
const list = $(".media-list.row.mt_lg").children();
if (list.length === 0) {
return;
}
clearInterval(interval);
for (let v of list) {
const userInfo = v.querySelector(".flex_start.flex_inline.text3");
const title = v.querySelector(".text1").textContent;
const textContent = v.querySelector(".atc-desc.b_text.text_ellipsis_2l.text3.fs_5").textContent;//搜索专栏中的预览部分
const name = userInfo.text;
const upSpatialAddress = userInfo.href;
const uid = parseInt(upSpatialAddress.substring(upSpatialAddress.lastIndexOf("/") + 1));
if (Remove.isWhiteUserUID(uid)) {
continue;
}
if (Remove.uid(v, uid)) {
Print.ln("已通过uid【" + uid + "】,屏蔽用户【" + name + "】,专栏预览内容=" + textContent + " 用户空间地址=https://space.bilibili.com/" + uid);
continue;
}
if (Remove.name(v, name)) {
Print.ln("已通过黑名单用户【" + name + "】,屏蔽处理,专栏预览内容=" + textContent + " 用户空间地址=https://space.bilibili.com/" + uid);
continue;
}
const isNameKey = Remove.nameKey(v, name);
if (isNameKey != null) {
Print.ln("用户【" + name + "】的用户名包含屏蔽词【" + isNameKey + "】 故进行屏蔽处理 专栏预览内容=" + textContent + " 用户空间地址=https://space.bilibili.com/" + uid)
continue;
}
const isTitleKey = Remove.titleKey(v, title);
if (isTitleKey != null) {
Print.ln("通过标题关键词屏蔽用户【" + name + "】 专栏预览内容=" + textContent + " 用户空间地址=https://space.bilibili.com/" + uid);
continue;
}
const titleKeyCanonical = Remove.titleKeyCanonical(v, title);
if (titleKeyCanonical != null) {
Print.ln(`通过标题正则表达式=【${titleKeyCanonical}】屏蔽用户【${name}】专栏预览内容=${textContent} 用户空间地址=https://space.bilibili.com/${uid}`);
continue;
}
const key = Remove.columnContentKey(v, textContent);
if (key !== null) {
Print.ln("已通过专栏内容关键词【" + key + "】屏蔽用户【" + name + "】 专栏预览内容=" + textContent + " 用户空间地址=https://space.bilibili.com/" + uid);
continue;
}
$(v).mouseenter((e) => {
const domElement = e.delegateTarget;//dom对象
console.log(domElement);
const title = domElement.querySelector(".text1").textContent;
const info = domElement.querySelector(".flex_start.flex_inline.text3");
const name = info.querySelector(".lh_xs").text;
const userHref = info.href;
const uid = userHref.substring(userHref.lastIndexOf("/") + 1);
Util.showSDPanel(e, name, uid, title);
});
}
}, 1000);
}
}
const subjectOfATalk = {//话题
/**
* 针对b站话题
*/
deltopIC: function () {
for (let v of document.getElementsByClassName("list__topic-card")) {
const info = v.getElementsByClassName("bili-dyn-content__orig")[0];
const name = v.getElementsByClassName("bili-dyn-title")[0].textContent.trim();
const uid = parseInt(v.getElementsByClassName("bili-dyn-item__following")[0].getAttribute("data-mid"));
if (info.getElementsByClassName("bili-dyn-content__orig__desc").length === 1) {
const content = info.textContent;
if (startPrintShieldNameOrUIDOrContent(v, name, uid, content)) {
Qmsg.info("屏蔽了言论!!");
}
continue;
}//如果内容是视频样式
const videoInfo = info.getElementsByClassName("bili-dyn-card-video")[0];
const videoTime = videoInfo.getElementsByClassName("bili-dyn-card-video__duration")[0].textContent;
const title = videoInfo.getElementsByClassName("bili-dyn-card-video__title bili-ellipsis")[0].textContent;
if (shieldVideo_userName_uid_title(v, name, uid, title, null, videoTime, null)) {
Qmsg.info("屏蔽了视频!!");
}
}
}
}
function loadPartition() {//加载下拉框中的分区
const tempVar = Home.data.video_zoneList;
for (const v in tempVar) {
$("#video_zoneSelect").append(``);
}
}
function loadChannel() {//加载下拉框中的频道信息
const list = frequencyChannel.data.channel_idList;
for (const v in list) {
$("#video_zoneSelect").append(``);
}
}
(() => {
'use strict';
let href = Util.getWindowUrl();
console.log("当前网页url=" + href);
if (href.includes("github.com")) {
github(href);
return;
}
//加载布局
layout.loading.home();
$("body").prepend('');
layout.css.home();
$("#tabUl>li>button").click((e) => {
const domElement = e.delegateTarget;//dom对象
document.querySelectorAll("#tabUl>li>button").forEach((value, key, parent) => {
$(value).css("color", "");
})
domElement.style.color = "yellow";
Home.openTab(domElement.value);
});
$("#tabUl>li>button[value='ruleCenterLayout']").click(() => {
if (Home.isFirstRuleCenterLayoutClick) {
return;
}
Home.isFirstRuleCenterLayoutClick = true;
const loading = Qmsg.loading("请稍等...");
$.ajax({
type: "GET",
url: "https://vip.mikuchase.ltd/bilibili/shieldRule/",
data: {
model: "ruleCenter"
},
dataType: "json",
success: function (data) {
loading.close();
const message = data["message"];
if (data["code"] !== 1) {
Qmsg.error(message);
return;
}
Qmsg.success(message);
const dataList = data["list"];
const $ruleCenterLayoutUl = $("#ruleCenterLayout>ul");
for (let index in dataList) {
const userName = dataList[index]["userName"];
const time = dataList[index]["rule"]["time"];
const ruleRes = dataList[index]["rule"]["ruleRes"];
let centerIndexE = [];
for (let key in ruleRes) {
centerIndexE.push(`
${key}:${ruleRes[key].length}个
`);
}
const item = `
作者:${userName}
更新时间:${Util.timestampToTime(time)}
${centerIndexE.join("")}
`;
$ruleCenterLayoutUl.append(item);
}
Util.addStyle(`
#ruleCenterLayout>ul li {
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid rgb(0, 217, 0);
}
`);
$ruleCenterLayoutUl.on("click", "button", (e) => {
const target = e.target;
const li = $(target).closest("li").get(0);
const liValue = li.getAttribute("value");
const authorName = li.querySelector(".authorNameSpan").textContent;
const userRuleData = dataList[liValue];
const ruleRes = userRuleData["rule"]["ruleRes"];
switch (target.getAttribute("value")) {
case "inputLocalRule"://导入覆盖本地规则
if (!confirm(`您确定要导入该用户 ${authorName} 的规则并覆盖您当前本地规则?`)) {
return;
}
rulesAreImportedLocally(ruleRes);
break;
case "inputCloudRule"://导入覆盖云端规则
alert("暂不支持导入覆盖云端规则!");
break;
case "lookUserRule":
if (!confirm(`您是要查看用户 ${authorName} 的规则内容吗,需要注意的是,在某些浏览器中,由于安全原因,脚本不能使用 window.open() 创建新窗口。对于这些浏览器,如果您出现打不开的情况,用户必须将浏览器设置为允许弹出窗口才能打开新窗口`)) {
return;
}
Util.openWindowWriteContent(JSON.stringify(ruleRes, null, 2));
break;
default:
alert("出现错误的选项!");
break;
}
});
}, error: function (xhr, status, error) { //请求失败的回调函数
loading.close();
console.log(error, status);
Qmsg.error(error + " " + status);
}
});
});
Util.suspensionBall(document.getElementById("suspensionDiv"));
Rule.ruleLength();
Rule.showInfo();
$("#mybut").click(() => Home.hideDisplayHomeLaylout());
$(document).keyup(function (event) {//单按键监听-按下之后松开事件
const keycode = event.keyCode;
if (keycode === 192) {//按下`按键显示隐藏面板
Home.hideDisplayHomeLaylout();
}
if (keycode === 49) {//选中快捷悬浮屏蔽按钮跟随鼠标 键盘上的1
const q = $("#quickLevitationShield");
q.prop("checked", !q.is(':checked'));
}
if (keycode === 50) {//隐藏快捷悬浮屏蔽按钮 键盘上的2
const q = $("#fixedPanelValueCheckbox");
q.prop("checked", !q.is(':checked'));
}
if (keycode === 51) {//隐藏快捷悬浮屏蔽按钮 键盘上的3
$("#suspensionDiv").css("display", "none");
}
});
$('#singleDoubleModel').change(() => {//监听模式下拉列表
const modelStr = $('#singleDoubleModel').val();
const inputTextAreaModel = $('#inputTextAreaModel');
const butadd = $('#butadd');
const butdel = $('#butdel');
const butaddAll = $('#butaddAll');
const butdelAll = $('#butdelAll');
const butSet = $('#butSet');
const butFind = $('#butFind');
if (modelStr === "one") {//如果中的是单个
inputTextAreaModel.css("display", "none");
//暂时显示对应的按钮
butadd.css("display", "inline");
butdel.css("display", "inline");
butSet.css("display", "inline");
butFind.css("display", "inline");
butaddAll.css("display", "none");
butdelAll.css("display", "none");
return;
}//如果选择的是批量
inputTextAreaModel.css("display", "block");
butaddAll.css("display", "inline");
butdelAll.css("display", "inline");
//暂时隐藏别的按钮先
butadd.css("display", "none");
butdel.css("display", "none");
butSet.css("display", "none");
butFind.css("display", "none");
});
$("#rangePlaySpeed").bind("input propertychange", function (event) {//监听拖动条值变化-视频播放倍数拖动条
const vaule = $("#rangePlaySpeed").val();//获取值
Util.setVideoBackSpeed(vaule);
$("#playbackSpeedText").text(vaule + "x");//修改对应标签的文本显示
});
$('#playbackSpeedModel').change(() => {//监听模式下拉列表--下拉列表-视频播放倍数
Util.setVideoBackSpeed($('#playbackSpeedModel').val())
});
$("#preservePlaybackSpeedModel").click(() => {//保存固定值中的播放数据
const val = $('#playbackSpeedModel').val();
Util.setData("playbackSpeed", parseFloat(val));
Print.ln("已保存播放速度数据=" + val);
});
$("#preservePlaySpeed").click(() => {//保存拖动条中的值的播放数据
const val = $("#rangePlaySpeed").val();
Util.setData("rangePlaySpeed", parseFloat(val));
Print.ln("已保存播放速度数据=" + val);
});
$("#flipHorizontal").click(function () {//水平翻转视频
const videoData = Rule.videoData;
if (videoData.flipHorizontal) {
if (Util.setVideoRotationAngle("Y", 0)) {
videoData.flipHorizontal = false;
}
return;
}
if (Util.setVideoRotationAngle("Y", 180)) {
videoData.flipHorizontal = true;
}
});
$("#flipVertical").click(function () {//垂直翻转视频
const videoV = $("video");
if (videoV === null) {
return;
}
const videoData = Rule.videoData;
if (videoData.flipVertical) {
if (Util.setVideoRotationAngle("X", 0)) {
videoData.flipVertical = false;
}
return;
}
if (Util.setVideoRotationAngle("X", 180)) {
videoData.flipVertical = true;
}
});
$("#butShieldName").click(() => {//悬浮小窗体-添加屏蔽用户名
const name = $("#nameSuspensionDiv").text();
butLayEvent.butaddName("userNameArr", name);
});
$("#butShieldUid").click(() => {//悬浮小窗体-添加屏蔽uid
const uid = $("#uidSuspensionDiv").text();
const tempLoop = butLayEvent.butaddName("userUIDArr", parseInt(uid));
if (!tempLoop) {
return;
}
const title = document.title;
const url = Util.getWindowUrl();
if (title === "哔哩哔哩 (゜-゜)つロ 干杯~-bilibili") {
Home.startShieldMainVideo(".bili-video-card.is-rcmd");
return;
}
if (title.includes("-哔哩哔哩_Bilibili") && (url.includes("search.bilibili.com/all") || url.includes("search.bilibili.com/video"))) {//用于避免个别情况搜索界面屏蔽不生效问题
search.searchRules($(".video-list").children());
return;
}
if (href.includes("//live.bilibili.com/") && title.includes("哔哩哔哩直播,二次元弹幕直播平台")) {
Live.shield($("#chat-items").children());
return;
}
});
$("#findUserInfo").click(() => {
const uid = $("#uidSuspensionDiv").text();
if (uid === "") {
Qmsg.error("未检测到UID!")
return;
}
const loading = Qmsg.loading("正在获取中!");
HttpUtil.get(`https://api.bilibili.com/x/web-interface/card?mid=${uid}&photo=false`, (res) => {
const body = JSON.parse(res.responseText);
if (body["code"] !== 0) {
Qmsg.error("请求失败!");
loading.close();
return;
}
loading.close();
const cradInfo = body["data"]["card"];
const uid = cradInfo["mid"];//uid
const sex = cradInfo["sex"];//性别
const userName = cradInfo["name"];
const fans = cradInfo["fans"];//粉丝数
const sign = cradInfo["sign"];//个性签名信息
const face = cradInfo["face"];//头像
const current_level = cradInfo["level_info"]["current_level"];//当前用户b站等级
const friend = cradInfo["friend"];//关注量
const follower = body["data"]["follower"];//粉丝量
const like_num = body["data"]["like_num"];//点赞量
const userCardHtml = HtmlStr.getUserCard(uid, userName, current_level, sign, face, friend, follower, like_num);
if ($("#popDiv").length === 0) {
$("body").append(userCardHtml);
} else {
$("#popDiv").remove();
$("body").append(userCardHtml);
}
$("#popDiv").css("display", "inline");
});
});
$("#getVideoDanMueBut").click(() => {//打开当前视频弹幕列表
const windowUrl = Util.getWindowUrl();
if (!windowUrl.includes("www.bilibili.com/video")) {
alert("当前不是播放页!");
return;
}
const urlBVID = Util.getUrlBVID(windowUrl);
if (urlBVID === null) {
alert("获取不到BV号!");
return;
}
if (!confirm(`当前视频BV号是 ${urlBVID} 吗`)) {
return;
}
const loading = Qmsg.loading("正在获取数据中!");
HttpUtil.getVideoInfo(urlBVID, (res) => {
const body = JSON.parse(res.responseText);
const code = body["code"];
const message = body["message"];
if (code !== 0) {
Qmsg.error("获取失败!" + message);
loading.close();
return;
}
let data;
try {
data = body["data"][0];
} catch (e) {
Qmsg.error("获取数据失败!" + e);
loading.close();
return;
}
if (data === null || data === undefined) {
Qmsg.error("获取到的数据为空的!");
loading.close();
return;
}
loading.close();
const cid = data["cid"];
Qmsg.success("cid=" + cid);
Util.openWindow(`https://comment.bilibili.com/${cid}.xml`);
}, (err) => {
loading.close();
Qmsg.error("错误状态!");
Qmsg.error(err);
});
});
$("#getVideoCommentArea").click(() => {//获取视频的评论区列表可见的内容
const list = document.querySelectorAll(".reply-list>.reply-item");
if (list.length === 0) {
Qmsg.error("未获取评论区内容,可能是当前并未有人评论!");
return;
}
const arr = [];
for (let v of list) {
const rootName = v.querySelector(".user-name").textContent;
const rootUid = v.querySelector(".user-name").getAttribute("data-user-id");
const rootContent = v.querySelector(".root-reply .reply-content").textContent;
const subList = v.querySelectorAll(".sub-reply-list>.sub-reply-item");
const data = {
name: rootName,
uid: parseInt(rootUid),
content: rootContent,
};
if (subList.length === 0) {
arr.push(data);
continue;
}
const subArr = [];
for (let j of subList) {
const subName = j.querySelector(".sub-user-name").textContent;
const subUid = j.querySelector(".sub-user-name").getAttribute("data-user-id");
const subContent = j.querySelector(".reply-content").textContent;
const subData = {
name: subName,
uid: parseInt(subUid),
content: subContent
};
subArr.push(subData);
}
data["sub"] = subArr;
arr.push(data);
}
Util.fileDownload(JSON.stringify(arr), "评论区列表-" + Util.toTimeString());
Qmsg.success("已获取成功!");
});
$("#getLiveHighEnergyListBut").click(() => {//获取直播间的高能用户列表-需要用户先展开高能用户列表才可以识别到
const title = document.title;
const url = Util.getWindowUrl();
if (!(title.includes("- 哔哩哔哩直播,二次元弹幕直播平台") && url.includes("live.bilibili.com"))) {
Qmsg.error("错误的引用了该功能!");
return;
}
const list = document.querySelectorAll(".list-body>.list>*>.name");
if (list.length === 0) {
Qmsg.info("未获取到高能用户列表,当前长度微0,说明没有高能用户存在!");
return;
}
const array = [];
for (let v of list) {
const name = v.textContent;
array.push(name);
}
Util.fileDownload(JSON.stringify(array), Util.toTimeString() + "直播间高能用户列表.json");
});
$("#getLiveDisplayableBarrageListBut").click(() => {//获取可直播间可显示的弹幕列表
if (!(document.title.includes("- 哔哩哔哩直播,二次元弹幕直播平台") && Util.getWindowUrl().includes("live.bilibili.com"))) {
Qmsg.error("错误的引用了该功能!");
return;
}
const list = document.querySelectorAll("#chat-items>*");
if (list.length === 0) {
Qmsg.error("未检测到弹幕内容!");
return;
}
const arrData = [];
for (let v of list) {
const name = v.getAttribute("data-uname");
const uid = v.getAttribute("data-uid");
const timeDate = parseInt(v.getAttribute("data-ts"));//时间戳-秒
const content = v.getAttribute("data-danmaku");
/**
* 弹幕类型
* 0 正常弹幕消息
* 1 表情包弹幕消息
* @type {string}
*/
const type = v.getAttribute("data-type");
const data = {
name: name,
uid: uid,
content: content,
timeDate: timeDate,
toTime: Util.timestampToTime(timeDate)
};
if (type === "1") {
data["imge"] = v.getAttribute("data-image");
}
arrData.push(data);
}
Util.fileDownload(JSON.stringify(arrData), Util.toTimeString() + "_直播间弹幕内容.json");
Qmsg.success("获取成功并执行导出内容");
});
const openTheFilteredList = $("#OpenTheFilteredList");
openTheFilteredList.click(() => {
Qmsg.info("该功能暂未完善");
openTheFilteredList.hide();
const windowsTitle = document.title;
const windowUrl = Util.getWindowUrl();
HoverBlockList.init([
{"uid": 1, "name": "张三", "age": 20, "title": "标题"},
{"uid": 2, "name": "李四", "age": 25},
{"uid": 3, "name": "王四", "age": 30}
], "name", (data) => {
console.log(data);
});
console.log(href);
});
$("#axleRange").bind("input propertychange", function () {//监听拖动条值变化-视频播放器旋转角度拖动条
const value = $("#axleRange").val();//获取值
Util.setVideoCenterRotation(value);
$("#axleSpan").text(value + "%");//修改对应标签的文本显示
});
const tempdelBox = $("#delVideoCommentSectionsCheackBox");
tempdelBox.click(() => {
LocalData.setDelVideoCommentSections(tempdelBox.is(':checked'));
});
$("#backgroundPellucidityRange").bind("input propertychange", function () {//监听拖动条值变化-面板背景透明度拖动条
const value = $("#backgroundPellucidityRange").val();//获取值
$("#backgroundPelluciditySpan").text(value);//修改对应标签的文本显示
const back = Home.background;
$("#home_layout").css("background", Util.getRGBA(back.r, back.g, back.b, value));
});
$("#heightRange").bind("input propertychange", function (event) {//监听拖动条值变化-面板高度拖动条
const value = $("#heightRange").val();//获取值
$("#heightSpan").text(value + "%");//修改对应标签的文本显示
$("#home_layout").css("height", `${value}%`);
});
$("#widthRange").bind("input propertychange", function (event) {//监听拖动条值变化-面板宽度拖动条
const value = $("#widthRange").val();//获取值
$("#widthSpan").text(value + "%");//修改对应标签的文本显示
$("#home_layout").css("width", `${value}%`);
});
$("#DShielPanel").click(() => {//点击禁用快捷悬浮屏蔽面板自动显示
Util.setData("isDShielPanel", $("#DShielPanel").is(":checked"));
});
$("#autoPlayCheckbox").click(() => {//点击禁止打开b站视频时的自动播放
Util.setData("autoPlay", $("#autoPlayCheckbox").is(":checked"));
});
$("#butSelectVideo").click(function () {//确定时长播放量弹幕
const selectVideo = $("#selectVideo");
const typeV = selectVideo.val();
let inputVideoV = $("#inputVideo").val();
if (inputVideoV === "") {
return;
}
const name = selectVideo.find("option:selected").text();
Util.setData(typeV, parseInt(inputVideoV));
const info = `已设置${name}的具体值【${inputVideoV}】,为0则不生效`;
Print.ln(info);
Qmsg.success(info);
});
$("#butClearMessage").click(() => {
if ($("#butClearMessage+input:first").is(":checked")) {
if (!confirm("是要清空消息吗?")) {
return;
}
}
document.querySelector('#outputInfo').innerHTML = '';
});
$("#butadd").click(function () {//增
const typeVal = $("#model option:selected").val();
const content = prompt("请填写要添加的值");
if (content === null) {
return;
}
if (content === "") {
Qmsg.error("请输入正确的内容!");
return;
}
if (typeVal === "userUIDArr" || typeVal === "userWhiteUIDArr") {
butLayEvent.butaddName(typeVal, parseInt(content));
return;
}
butLayEvent.butaddName(typeVal, content);
})
$("#butaddAll").click(function () {
const typeVal = $("#model option:selected").val();
const content = $("#inputTextAreaModel").val();
if (content === null) {
return;
}
if (content === "") {
Qmsg.error("请输入正确的内容!");
return;
}
if (typeVal === "userUIDArr" || typeVal === "userWhiteUIDArr") {
alert("暂不支持uid和白名单uid");
return;
}
butLayEvent.butaddAllName(typeVal, content);
})
$("#butdel").click(function () {//删
const typeVal = $("#model option:selected").val();
const content = prompt("请输入你要删除的单个元素规则");
if (content === null) {
return;
}
if (content === "") {
Qmsg.error("请输入正确的内容!");
return;
}
if (typeVal === "userUIDArr" || typeVal === "userWhiteUIDArr") {
butLayEvent.butDelName(typeVal, parseInt(content));
return;
}
butLayEvent.butDelName(typeVal, content);
})
$("#butdelAll").click(function () {//指定规则全删
const typeVal = $("#model option:selected").val();
butLayEvent.butDelAllName(typeVal);
})
$("#butSet").click(() => {
const oldContent = prompt("请输入你要修改的单个元素规则");
const content = prompt("请输入修改之后的值");
if (content === null || oldContent === null) {
return;
}
if (content === "" || oldContent === "") {
Qmsg.error("请填写正常的内容");
return;
}
const typeVal = $("#model option:selected").val();
if (typeVal === "userUIDArr" || typeVal === "userWhiteUIDArr") {
butLayEvent.butSetKey(typeVal, parseInt(oldContent), parseInt(content));
return;
}
butLayEvent.butSetKey(typeVal, oldContent, content);
});
$("#butFind").click(function () {//查
const typeVal = $("#model option:selected").val();
const content = prompt("请输入你要查询的单个元素规则");
if (content === null) {
return;
}
if (content === "") {
Qmsg.error("请输入正确的内容!");
return;
}
if (typeVal === "userUIDArr" || typeVal === "userWhiteUIDArr") {
butLayEvent.butFindKey(typeVal, parseInt(content));
return;
}
butLayEvent.butFindKey(typeVal, content);
});
$("#printRuleBut").click(() => {
Print.ln(Util.getRuleFormatStr());
});
$("#sgSessdata>button:eq(0)").click(() => {
const content = prompt("请输入要保存的SESSDATA值");
if (content === null) {
return;
}
if (content === "") {
LocalData.setSESSDATA(null);
return;
}
if (content.includes(" ") || content.includes("=")) {
Qmsg.error("内容中包含空格或者=,请去除相关符号!");
return;
}
if (!confirm(`要保存的SESSDATA是\n${content}`)) {
return;
}
LocalData.setSESSDATA(content);
Qmsg.success("已设置SESSDATA的值!");
});
$("#bili_jctDiv>button:eq(0)").click(() => {
const content = prompt("设置bili_jct值为:");
if (content === null) {
return;
}
if (content === "" | content.includes(" ")) {
Qmsg.error("内容有误,请正确书写!");
return;
}
LocalData.setBili_jct(content);
Qmsg.success(`已设置bili_jct的值为\n${content}`);
});
$("#bili_jctDiv>button:eq(1)").click(() => {
const data = LocalData.getWebBili_jct();
if (data === null) {
Qmsg.error(`获取不到存储在网页中的bili_jct值:`);
return;
}
if (!confirm("确定要将存储在网页中的bili_jct值并设置存储在油猴脚本bili_jct值吗?")) {
return;
}
LocalData.setBili_jct(data);
Qmsg.success(`已读取存储在网页中的bili_jct值并设置存储在脚本bili_jct的值为\n${data}`);
});
$("#bili_jctDiv>button:eq(2)").click(() => {
const data = LocalData.getWebBili_jct();
if (data === null) {
Qmsg.error(`获取不到存储在网页中的bili_jct值:`);
return;
}
Qmsg.success("已获取到存储在网页中的bili_jct值,已输出到面板上");
Print.ln(data);
});
$("#bili_jctDiv>button:eq(3)").click(() => {
const biliJct = LocalData.getBili_jct();
if (biliJct === null) {
Qmsg.error(`用户未设置bili_jct值`);
return;
}
Qmsg.success("获取成功!,已将bili_jct值输出到面板上");
});
$("#sgSessdata>button:eq(1)").click(() => {
const data = LocalData.getSESSDATA();
if (data === null) {
const tip = '用户未添加SESSDATA或者已删除存储在脚本的SESSDATA';
Qmsg.error(tip);
alert(tip);
return;
}
Qmsg.success("已将值输出到脚本面板的输出信息上!");
Print.ln("用户存储在脚本中的SESSDATA,如上一条:");
Print.ln(data);
});
const openPrivacyModeCheckbox = $("#openPrivacyModeCheckbox");
openPrivacyModeCheckbox.click(() => {
const isbool = openPrivacyModeCheckbox.is(":checked");
LocalData.setPrivacyMode(isbool);
});
$("#outExport").click(() => {//点击导出规则事件
const selectedText = $('#outRuleSelect option:selected').text();
switch (selectedText) {
case "全部规则到文件":
let fileName = "规则-" + Util.toTimeString();
const s = prompt("保存为", fileName);
if (s === null) {
return;
}
if (!(s.includes(" ") || s === "" || s.length === 0)) {
fileName = s;
}
Util.fileDownload(Util.getRuleFormatStr(), fileName + ".json");
break;
case "全部规则到剪贴板":
Util.copyToClip(Util.getRuleFormatStr());
break;
case "全部UID规则到文件":
const list = LocalData.getArrUID();
Util.fileDownload(JSON.stringify(list), `UID规则-${list.length}个.json`);
break;
case "全部UID规则到云端":
alert("暂不支持");
break;
case "全部规则到云端账号":
const getInfo = LocalData.AccountCenter.getInfo();
if (getInfo === {} || Object.keys(getInfo).length === 0) {
alert("请先登录在进行操作.");
return;
}
if (!confirm("确定要将本地规则导出到对应账号的云端上吗")) {
return;
}
const loading = Qmsg.loading("请稍等...");
$.ajax({
type: "POST",
url: "https://vip.mikuchase.ltd/bilibili/shieldRule/",
data: {
model: "All",
userName: getInfo["userName"],
userPassword: getInfo["userPassword"],
postData: Util.getRuleFormatStr()
},
dataType: "json",
success: function (data) {
loading.close();
const message = data["message"];
if (data["code"] !== 1) {
Qmsg.error(message);
return;
}
Qmsg.success(message);
console.log(data["dataJson"])
}, error: function (xhr, status, error) { //请求失败的回调函数
loading.close();
console.log(error);
console.log(status);
}
});
break;
}
if (selectedText === "b站弹幕屏蔽规则") {
//已经登录b站账号的前提下,打开该api
//https://api.bilibili.com/x/dm/filter/user
//即可获取到该账号下的b站云端最新的屏蔽词内容
//type类型
//0 屏蔽文本
//1 屏蔽正则
//2 屏蔽用户
/**
* filter 规则内容
*/
/**
*opened 是否启用
*/
const item = window.localStorage.getItem("bpx_player_profile");
if (item === null || item === undefined) {
alert("找不到当前账号的屏蔽设定规则,请确定进行登录了并进行加载了弹幕的屏蔽设定");
return;
}
const arrList = JSON.parse(item)["blockList"];
if (arrList === undefined || arrList === null || arrList.length === 0) {
alert("当前账号的屏蔽设定规则没有屏蔽设定规则哟,请确定进行登录了并加载了弹幕的屏蔽设定");
return;
}
const list = [];
for (const arrListElement of arrList) {
const type = arrListElement["type"];
const filter = arrListElement["filter"];
const opened = arrListElement["opened"];
const id = arrListElement["id"];
if (type === 2) {
continue;
}
list.push(arrListElement);
}
Util.fileDownload(JSON.stringify(list), "b站账号弹幕屏蔽设定规则.json");
}
});
function rulesAreImportedLocally(ruleRes) {//规则导入本地
let list = ruleRes["用户名黑名单模式(精确匹配)"];
LocalData.setArrName(list);
list = ruleRes["用户名黑名单模式(模糊匹配)"];
LocalData.setArrNameKey(list);
list = ruleRes["用户uid黑名单模式(精确匹配)"];
LocalData.setArrUID(list)
list = ruleRes["用户uid白名单模式(精确匹配)"];
LocalData.setArrWhiteUID(list);
list = ruleRes["标题黑名单模式(模糊匹配)"];
LocalData.setArrTitle(list);
list = ruleRes["标题黑名单模式(正则匹配)"];
LocalData.setArrTitleKeyCanonical(list);
list = ruleRes["评论关键词黑名单模式(模糊匹配)"];
Util.setData("commentOnKeyArr", list);
list = ruleRes["评论关键词黑名单模式(正则匹配)"];
LocalData.setArrContentOnKeyCanonicalArr(list);
list = ruleRes["粉丝牌黑名单模式(精确匹配)"];
LocalData.setFanCardArr(list)
list = ruleRes["专栏关键词内容黑名单模式(模糊匹配)"];
LocalData.setContentColumnKeyArr(list)
list = ruleRes["动态关键词内容黑名单模式(模糊匹配)"];
LocalData.setDynamicArr(list);
Rule.ruleLength();
alert("已导入");
}
//导入按钮事件
$("#inputExport").click(function () {
const selectedText = $('#inputRuleSelect option:selected').text();
let content = $("#ruleEditorInput").val();
switch (selectedText) {
case "从云端账号导入覆盖本地规则":
const getInfo = LocalData.AccountCenter.getInfo();
if (getInfo === {} || Object.keys(getInfo).length === 0) {
alert("请先登录在进行操作.");
return;
}
if (!confirm("确定要云端账号对应的规则导入并覆盖到本地吗?")) {
return;
}
const loading = Qmsg.loading("请稍等...");
$.ajax({
type: "GET",
url: "https://vip.mikuchase.ltd/bilibili/shieldRule/",
data: {
userName: getInfo["userName"],
userPassword: getInfo["userPassword"]
},
dataType: "json",
success: function (data) {
loading.close();
const message = data["message"];
if (data["code"] !== 1) {
Qmsg.error(message);
return;
}
Qmsg.success(message);
const time = data["data"]["time"];
const ruleRes = data["data"]["ruleRes"];
console.log(time);
console.log(ruleRes);
rulesAreImportedLocally(ruleRes);
}, error: function (xhr, status, error) { //请求失败的回调函数
loading.close();
console.log(error);
console.log(status);
}
});
break;
case "全部规则":
if (content === "" || content === " ") {
alert("请填写正确的规则样式!");
return;
}
const b = confirm("需要注意的是,这一步操作会覆盖你先前的规则!您确定要导入吗?");
if (!b) {
return;
}
let jsonRule = [];
try {
jsonRule = JSON.parse(content);
} catch (error) {
alert("内容格式错误!" + error)
return;
}
rulesAreImportedLocally(jsonRule);
break;
case "确定合并导入UID规则":
let uidList;
try {
uidList = JSON.parse(content)
if (!(uidList instanceof Array)) {
throw new Error("错误信息,导入的类型不是数组!");
}
} catch (e) {
alert("类型错误,导入的内容不是jsoN")
return;
}
for (let i = 0; i < uidList.length; i++) {
try {
uidList[i] = parseInt(uidList[i]);
} catch (e) {
alert("数组中存在非数字内容")
return;
}
}
if (uidList.length === 0) {
alert("该数组长度为0!")
return;
}
const data = LocalData.getArrUID();
if (data === undefined || data === null || !(data instanceof Array) || data.length === 0) {
if (confirm("未检测到本地的UID规则,是否要覆盖或者直接添加?")) {
LocalData.setArrUID(uidList);
alert("添加成功!")
}
return;
}
let index = 0;
for (const v of uidList) {
if (data.includes(v)) {
continue;
}
index++;
data.push(v);
}
if (index === 0) {
alert("内容没有变化!,可能是原先的规则里已经有了");
return;
}
alert(`已新增${index}个UID规则`);
LocalData.setArrUID(data);
break;
case "本地b站弹幕屏蔽规则":
alert("暂时未写")
break;
}
});
$('#inputRuleSelect').change(() => {//监听模式下拉列表
const selectedText = $('#inputRuleSelect option:selected').text();
const editorInput = $("#ruleEditorInput");
if (selectedText === "从下面编辑框导入全部规则" || selectedText === "从下面编辑框合并导入UID规则") {
editorInput.show();
return;
}
editorInput.hide();
});
$("#fenestruleCheckbox").change(function () {
if ($("#fenestruleCheckbox").is(":checked")) {//如果是选中状态
try {
for (const v of $("video")) {
v.requestPictureInPicture();//进入画中画
}
} catch (e) {
alert("未找到视频播放器!")
}
} else {
try {
for (const v of $("video")) {
v.exitPictureInPicture();//退出画中画
}
} catch (e) {
alert("未找到视频播放器!")
}
}
});
const tempPushTypeSelect = $('#pushTypeSelect');
tempPushTypeSelect.change(() => {//监听模式下拉列表--下拉列表-指定推送类型-分区亦或者频道
const tempVar = tempPushTypeSelect.val();
const tempSortTypeSelect = $("#sort_typeSelect");
$("#video_zoneSelect>option:not(:first)").remove();//清空下拉选择器内的元素(除第一个)
if (tempVar === "分区") {
loadPartition();
tempSortTypeSelect.css("display", "none");
return;
}
tempSortTypeSelect.css("display", "inline");
tempSortTypeSelect.val(frequencyChannel.getSort_type());
loadChannel();
});
const tempVideoZoneSelect = $('#video_zoneSelect');
$("#okButton").click(() => {//确定首页指定推送视频
const pushType = $("#pushTypeSelect").val();
const selectVar = parseInt(tempVideoZoneSelect.val());
Home.setPushType(pushType);
if (pushType === "分区") {
Print.ln("选择了分区" + Home.data.video_zoneList[selectVar] + " uid=" + selectVar);
LocalData.setVideo_zone(selectVar);
} else {
const tempSortTypeSelect = $("#sort_typeSelect");
const tempVar = tempSortTypeSelect.val();
Print.ln("选择了" + tempSortTypeSelect.text() + "的频道" + frequencyChannel.data.channel_idList[selectVar] + " uid=" + selectVar);
frequencyChannel.setChannel_id(selectVar);
frequencyChannel.setSort_type(tempVar)
}
alert("已设置!")
});
const tempIdCheckbox = $("#isIdCheckbox");
$("#findButon").click(() => {
const tempContent = prompt("查询的类型关键词");
if (tempContent === null || tempContent === "" || tempContent.includes(" ")) {
Qmsg.error("请正确输入内容");
return;
}
function tempFunc(typeStr, tempContent) {
const list = typeStr === "分区" ? Home.data.video_zoneList : frequencyChannel.data.channel_idList;
if (tempIdCheckbox.is(":checked")) {//通过ID方式查找
if (tempContent in list) {
tempVideoZoneSelect.val(tempContent);
Print.ln(`通过ID方式找到该值!=${list[tempContent]}`);
return;
}
} else {
for (let v in list) {//通过遍历字典中的value,该值包含于tempContent时成立
if (!list[v].includes(tempContent)) {
continue;
}
tempVideoZoneSelect.val(v);
Print.ln(`通过value找到该值!=${tempContent}`);
return;
}
}
Qmsg.error("未找到该值!");
}
if (tempPushTypeSelect.val() === "分区") {
tempFunc("分区", tempContent);
} else {
tempFunc("频道", tempContent);
}
});
ruleList(href)//正常加载网页时执行
//每秒监听网页标题URL
setInterval(function () {//每秒监听网页中的url
const tempUrl = Util.getWindowUrl();
if (href === tempUrl) {//没有变化就结束本轮
return;
}//有变化就执行对应事件
console.log("页面url发生变化了,原=" + href + " 现=" + tempUrl);
href = tempUrl;//更新url
ruleList(href);//网页url发生变化时执行
bilibili(href);
}, 1000);
if (href.includes("bilibili.com")) {
bilibili(href);
bilibiliOne(href, document.title);
startMonitorTheNetwork();
}
})
();