您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
隐藏CC直播页面中的大部分广告, 并且当直播结束跳转其他直播间时, 自动关闭页面
// ==UserScript== // @name CC直播间净化 // @description 隐藏CC直播页面中的大部分广告, 并且当直播结束跳转其他直播间时, 自动关闭页面 // @name:en CCLiveClean // @description:en Hide almost CC live Element. // @author Yiero // @version 1.1.0 // @match https://cc.163.com/* // @match https://act/m/daily/anchor_end_countdown/* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @run-at document-start // @icon https://cc.163.com/favicon.ico // @namespace https://github.com/AliubYiero/TamperMonkeyScripts/ // @license GPL // ==/UserScript== var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class Info { constructor(projectName) { __publicField(this, "projectName"); __publicField(this, "header"); this.projectName = projectName; this.header = `[${projectName}]`; } log(...msg) { (() => {})(...this.contentInfo(...msg)); } info(...msg) { console.info(...this.contentInfo(...msg)); } warn(...msg) { console.warn(...this.contentInfo(...msg)); } error(...msg) { console.error(...this.contentInfo(...msg)); } contentInfo(...msg) { return [ this.header, `[${(new Date).toLocaleString("zh-ch")}]`, ...msg ]; } } class CSSRule { constructor() { __publicField(this, "cssRuleSet", new Set); __publicField(this, "styleDom", document.createElement("style")); } push(selector, rule) { let ruleString = ""; for (let ruleKey in rule) { const ruleValue = rule[ruleKey]; ruleString += `${ruleKey}:${ruleValue};`; } this.cssRuleSet.add(`${selector} {${ruleString}}`); } pushImportant(selector, rule) { let ruleString = ""; for (let ruleKey in rule) { let ruleValue = rule[ruleKey]; if (typeof ruleValue === "string") { ruleValue = ruleValue.replace("!important", ""); } ruleString += `${ruleKey}:${ruleValue} !important;`; } this.cssRuleSet.add(`${selector} {${ruleString}}`); } pushHide(selector) { this.pushImportant(selector, { display: "none" }); } pushHideList(selectorList) { selectorList.forEach((selector => { this.pushImportant(selector, { display: "none" }); })); } pushList(ruleList) { ruleList.forEach((({selector: selector, rule: rule}) => { this.push(selector, rule); })); } pushImportantList(ruleList) { ruleList.forEach((({selector: selector, rule: rule}) => { this.pushImportant(selector, rule); })); } submit() { this.removeAll(); new Info("AddStyle").log(Array.from(this.cssRuleSet).join(" ")); this.styleDom = GM_addStyle(Array.from(this.cssRuleSet).join(" ")); } removeAll() { if (this.styleDom) { this.styleDom.remove(); } } } const hideSelectorList = { main: [ ".ad-ct", "#webChat", "#js-side-nav", ".index-module_container_1pK9d", "::-webkit-scrollbar" ], headerNav: [ ".menu-location", "#my-follow, #my-record, #download, #menu-be-anchor", "#guard-head-avatar-red-dot-msg, .red-dot" ], danmuBar: [ "#room-tabs", "#gift-banner", ".gift-simp-banner", ".room-boardcast", ".activity-notify", ".gift_item", ".chat-msg-folder" ], liveTitle: [ "#achievement, .live-type, .live-guard, .live-fans-badge-diamond, .anchor-friends", "#plugins2374, #plugins9970, #plugins9670, #plugins9977, #plugins9412, #plugins9997, #plugins9089, #plugins6666, #plugins9217, #plugins2511, #plugins1609, #plugins9913, #plugins1016, #plugins14, #plugins5985, #plugins1353, #plugins1, #plugins9321 " ], live: [ "#recommend-module", "#live_left_bottom_box_wrap", ".video-watermark", "#new-player-banner, #player-banner, #new-player-banner, #mounts_player, #mounts_banner", ".gameH5Theater .user-tool-bar" ] }; const anchor_end_countdownHideSelectorList = { live: [ ".ui-wrap" ] }; const prefSelectorList = { main: { ".room-main-container": { "margin-top": "20px" } }, headerNav: { ".user-do": { "margin-right": "50%", transform: "translateX(50%)" } }, live: { ".page-right-container": { width: "100%" }, "#live_player": { height: "100%" } }, danmuBar: { ".chat-list-short": { height: "calc(100% - 110px)" }, "#chat-list-con": { height: "100%" } } }; function addCCNewStyle() { const cssRule = new CSSRule; cssRule.pushHideList(Object.values(hideSelectorList).flat()); const transformedPrefSelectorList = Object.entries(Object.values(prefSelectorList).flat().reduce(((result, current) => ({ ...result, ...current })))).map((([selector, rule]) => ({ selector: selector, rule: rule }))); cssRule.pushImportantList(transformedPrefSelectorList); cssRule.submit(); } function addCCIframeNewStyle() { const cssRule = new CSSRule; cssRule.pushHideList(Object.values(anchor_end_countdownHideSelectorList).flat()); cssRule.submit(); } function freshListenerPushState(callback, s = 1) { let _pushState = window.history.pushState; window.history.pushState = function() { setTimeout(callback, s * 1e3); return _pushState.apply(this, arguments); }; } const live = { id: "", historyId: "" }; Object.defineProperty(live, "id", { get() { const liveIdMatch = document.URL.match(/https:\/\/cc.163.com\/(\d+)/); if (liveIdMatch && liveIdMatch[1]) { const liveId = liveIdMatch[1]; sessionStorage.setItem("localLiveId", liveId); return liveId; } return ""; } }); Object.defineProperty(live, "historyId", { get() { return sessionStorage.getItem("localLiveId") || ""; } }); function equalLiveId() { freshListenerPushState((() => { if (live.historyId !== live.id) { window.close(); } })); } function getElement(parent = document.body, selector, timeoutPerSecond = 0, getElementDelayPerSecond = 0) { return new Promise((resolve => { let result = parent.querySelector(selector); if (result) { return resolve(result); } let timer; const mutationObserver = window.MutationObserver || window.WebkitMutationObserver || window.MozMutationObserver; if (mutationObserver) { const observer = new mutationObserver((mutations => { for (let mutation of mutations) { for (let addedNode of mutation.addedNodes) { if (addedNode instanceof Element) { result = addedNode.matches(selector) ? addedNode : addedNode.querySelector(selector); if (result) { observer.disconnect(); timer && clearTimeout(timer); setTimeout((() => resolve(result)), getElementDelayPerSecond * 1e3); } } } } })); observer.observe(parent, { childList: true, subtree: true }); if (timeoutPerSecond > 0) { timer = setTimeout((() => { observer.disconnect(); return resolve(null); }), timeoutPerSecond * 1e3); } } })); } document.querySelector.bind(document); const getEls = document.querySelectorAll.bind(document); async function selectOriginBanSetting() { await getElement(document.body, ".ban-effect-list", 0, 1); const banList = getEls(".ban-effect-list > li:not(.selected)"); banList.forEach((banItem => { banItem.click(); })); } function isMatchURL(...regExpList) { const matchResultList = []; regExpList.forEach((regExp => { if (typeof regExp === "string") { regExp = new RegExp(regExp); } matchResultList.push(!!document.URL.match(regExp)); })); return matchResultList.includes(true); } class EntryBranch { constructor() { __publicField(this, "branchList", []); } add(condition, callback) { this.branchList.push([ condition, callback ]); } run() { const entry = this.branchList.find((entry2 => entry2[0]())); if (entry) { entry[1](); } } } class GMConfigMenu { constructor(callback) { __publicField(this, "menuId", 0); __publicField(this, "callback"); this.callback = callback; } open(title) { if (this.menuId) { this.close(); } this.menuId = GM_registerMenuCommand(title, this.callback); } close() { GM_unregisterMenuCommand(this.menuId); this.menuId = 0; } } class GMStorage { constructor(key) { __publicField(this, "key"); this.key = key; } set(value) { dispatchEvent(new CustomEvent("GMStorageUpdate", { detail: { newValue: value, oldValue: this.get(), target: this.key } })); GM_setValue(this.key, value); } get(defaultValue = null) { return GM_getValue(this.key, defaultValue); } remove() { dispatchEvent(new CustomEvent("GMStorageUpdate", { detail: { newValue: null, oldValue: this.get(), target: this.key } })); GM_deleteValue(this.key); } } class WhiteList extends GMStorage { constructor() { super("liveIdWhiteList"); } get whiteList() { return this.get([ 361433, 239802416 ]); } add(liveId) { const whiteList2 = this.whiteList; whiteList2.push(liveId); this.set(whiteList2); } has(liveId) { return this.whiteList.includes(liveId); } delete(liveId) { this.set(this.whiteList.filter((whiteLiveId => whiteLiveId !== liveId))); } } const whiteList = new WhiteList; function disabledNotWhiteListUrl(liveId) { if (!whiteList.has(liveId)) { window.close(); return; } } function registerConfigBtn(liveId) { new GMConfigMenu((() => { const result = prompt(`输入需要添加白名单的直播间的数字Id (网页地址中的数字Id):\n当前白名单:\n[${whiteList.whiteList.join(", ")}]`); if (result) { whiteList.add(Number(result)); } })).open("添加直播间白名单"); new GMConfigMenu((() => { const result = prompt(`输入需要删除白名单的直播间数字Id(网页地址中的数字Id):\n当前白名单:\n[${whiteList.whiteList.join(", ")}]`, String(liveId || whiteList.whiteList[0] || "")); if (result) { whiteList.delete(Number(result)); } })).open("删除直播间白名单"); } async function mainPageEntry() { disabledNotWhiteListUrl(Number(live.id)); registerConfigBtn(Number(live.id)); addCCNewStyle(); await selectOriginBanSetting(); equalLiveId(); } function iframeEntry() { addCCIframeNewStyle(); } (async () => { const entryBranch = new EntryBranch; entryBranch.add((() => isMatchURL(/^https?:\/\/cc.163.com\/$/)), registerConfigBtn); entryBranch.add((() => isMatchURL(/^https?:\/\/cc.163.com\/(\d+)/)), mainPageEntry); entryBranch.add((() => isMatchURL("act/m/daily/anchor_end_countdown/index.html")), iframeEntry); entryBranch.run(); })();