// ==UserScript==
// @name DBD-RawsBanHelper
// @namespace http://tampermonkey.net/
// @version 2.1
// @description 过滤动漫花园、末日动漫、Nyaa和蜜柑计划中的DBD-Raws内容,并修复行颜色问题
// @author Fuck DBD-Raws
// @license MIT
// @match *://share.dmhy.org/*
// @match *://share.acgnx.se/*
// @match *://nyaa.land/*
// @match *://nyaa.si/*
// @match *://mikanani.me/*
// @match *://mikanani.kas.pub/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 配置参数
const config = {
targetKeywords: ['DBD-Raws', 'DBD制作组', 'DBD製作組','DBD转发','DBD轉發','DBD-SUB','DBD字幕组','DBD字幕組','DBD代发','DBD代發','DBD代传','DBD代傳','DBD转载','DBD轉載','DBD自购','DBD自購','DBD&','&DBD','[DBD]'], // 要过滤的关键词列表
filterClass: 'dmhy-filtered', // 用于标记已过滤元素的类名
showNotification: true, // 是否显示过滤通知
notificationDuration: 3000 // 通知显示时间(毫秒)
};
// 添加CSS样式(不应用于蜜柑计划)
if (!isMikananiSite()) {
const style = document.createElement('style');
style.textContent = `
/* 行动画效果 */
.resource-row {
transition: background-color 0.3s ease;
}
.even {
background-color: #f5f5f5;
}
.odd {
background-color: #ffffff;
}
/* 为过滤区域添加视觉区分 */
.resource-list:empty::after {
content: "没有符合条件的内容或所有内容已被过滤";
display: block;
text-align: center;
padding: 20px;
color: #888;
font-style: italic;
}
/* 自定义通知样式 */
#dmhy-filter-notification {
position: fixed;
top: 20px;
right: 20px;
background: #ff4757;
color: white;
padding: 12px 18px;
border-radius: 4px;
z-index: 10000;
font-family: Arial, sans-serif;
font-size: 14px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
transition: opacity 0.5s ease;
cursor: pointer;
}
#dmhy-filter-notification:hover {
opacity: 1 !important;
}
`;
document.head.appendChild(style);
} else {
// 蜜柑计划专用的通知样式
const style = document.createElement('style');
style.textContent = `
#dmhy-filter-notification {
position: fixed;
top: 70px !important;
right: 20px;
background: #ff4757;
color: white;
padding: 12px 18px;
border-radius: 4px;
z-index: 9999;
font-family: Arial, sans-serif;
font-size: 14px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
transition: opacity 0.5s ease;
cursor: pointer;
}
#dmhy-filter-notification:hover {
opacity: 1 !important;
}
`;
document.head.appendChild(style);
}
// 全局变量用于存储通知的定时器
let notificationTimer = null;
// 检查文本是否包含任何目标关键词,并返回匹配到的关键词
function containsTargetText(text) {
const matchedKeywords = [];
config.targetKeywords.forEach(keyword => {
if (text.includes(keyword)) {
matchedKeywords.push(keyword);
}
});
return matchedKeywords.length > 0 ? matchedKeywords : false;
}
// 检查是否为蜜柑计划网站
function isMikananiSite() {
return window.location.hostname.includes('mikanani') ||
window.location.hostname.includes('mikanime');
}
// 等待页面加载完成
window.addEventListener('load', function() {
// 延迟执行以确保所有内容都已加载
setTimeout(() => {
filterContent();
// 监听蜜柑计划的动态内容
if (isMikananiSite()) {
observeMikananiDynamicContent();
}
}, 1000);
});
// 主过滤函数
function filterContent() {
let rowsRemoved = 0;
let matchedKeywords = new Set();
// 根据网站结构选择不同的处理方式
if (window.location.hostname.includes('dmhy.org')) {
// 动漫花园的处理方式 - 直接删除DOM元素
const rows = document.querySelectorAll('tr');
if (rows.length > 5) {
rows.forEach((row, index) => {
const keywords = containsTargetText(row.textContent);
if (keywords && !row.classList.contains(config.filterClass)) {
// 记录匹配的关键词
keywords.forEach(keyword => matchedKeywords.add(keyword));
// 直接删除元素
row.parentNode.removeChild(row);
rowsRemoved++;
}
});
// 重新着色表格行
recolorDmhyTableRows();
}
} else if (window.location.hostname.includes('acgnx.se')) {
const rowSelectors = ['tr', '.row', '.item'];
let rowsFound = false;
for (let selector of rowSelectors) {
const elements = document.querySelectorAll(selector);
if (elements.length > 5) {
rowsFound = true;
elements.forEach((element, index) => {
const keywords = containsTargetText(element.textContent);
if (keywords && !element.classList.contains(config.filterClass)) {
// 记录匹配的关键词
keywords.forEach(keyword => matchedKeywords.add(keyword));
// 标记为已过滤
element.classList.add(config.filterClass);
rowsRemoved++;
// 添加渐隐效果
setTimeout(() => {
element.style.display = 'none';
// 重新着色表格行
recolorAcgnxTableRows(selector);
}, 500);
}
});
break;
}
}
} else if (window.location.hostname.includes('nyaa')) {
// Nyaa.*的处理方式
const rows = document.querySelectorAll('tr');
if (rows.length > 0) {
rows.forEach((row, index) => {
const keywords = containsTargetText(row.textContent);
if (keywords && !row.classList.contains(config.filterClass)) {
// 记录匹配的关键词
keywords.forEach(keyword => matchedKeywords.add(keyword));
// 直接删除元素
row.parentNode.removeChild(row);
rowsRemoved++;
}
});
}
} else if (isMikananiSite()) {
// 蜜柑计划的处理方式
const result = filterMikananiContent();
rowsRemoved = result.removedCount;
result.matchedKeywords.forEach(keyword => matchedKeywords.add(keyword));
}
// 显示过滤通知
if (rowsRemoved > 0 && config.showNotification) {
const keywordsText = Array.from(matchedKeywords).join('、');
showNotification(`已过滤 ${rowsRemoved} 个DBD-Raws资源,匹配过滤词条:${keywordsText}`);
}
return { removedCount: rowsRemoved, matchedKeywords: Array.from(matchedKeywords) };
}
// 过滤蜜柑计划内容
function filterMikananiContent() {
let removedCount = 0;
let matchedKeywords = new Set();
// 1. 过滤主内容表格行
const allRows = document.querySelectorAll('tr[data-itemindex]');
const rowsToRemove = [];
// 第一步:识别需要删除的行
allRows.forEach(row => {
const keywords = containsTargetText(row.textContent);
if (keywords && !row.classList.contains(config.filterClass)) {
keywords.forEach(keyword => matchedKeywords.add(keyword));
rowsToRemove.push(row);
}
});
// 第二步:删除识别出的行
rowsToRemove.forEach(row => {
row.parentNode.removeChild(row);
removedCount++;
});
// 第三步:重新排序剩余的行的data-itemindex
if (removedCount > 0) {
reindexMikananiTable();
}
// 2. 过滤"相关字幕组"列表(搜索页面)
const subtitleGroups = document.querySelectorAll('.leftbar-nav');
subtitleGroups.forEach(container => {
const items = container.querySelectorAll('a, span, li, div');
items.forEach(item => {
const keywords = containsTargetText(item.textContent);
if (keywords && !item.classList.contains(config.filterClass)) {
keywords.forEach(keyword => matchedKeywords.add(keyword));
item.parentNode.removeChild(item);
removedCount++;
}
});
});
// 3. 过滤已加载的可展开内容
const expandableResult = filterMikananiExpandableContent();
removedCount += expandableResult.removedCount;
expandableResult.matchedKeywords.forEach(keyword => matchedKeywords.add(keyword));
return { removedCount, matchedKeywords: Array.from(matchedKeywords) };
}
// 精确过滤蜜柑计划可展开内容中的li元素
function filterMikananiExpandableContent() {
let removedCount = 0;
let matchedKeywords = new Set();
// 查找所有row an-res-row-frame元素
const expandableFrames = document.querySelectorAll('.row.an-res-row-frame');
expandableFrames.forEach(frame => {
// 查找所有包含目标关键词的元素
const elements = frame.querySelectorAll('div.sk-col.tag-res-name, li, a, span');
elements.forEach(element => {
const keywords = containsTargetText(element.textContent);
if (keywords) {
// 记录匹配的关键词
keywords.forEach(keyword => matchedKeywords.add(keyword));
// 向上查找li父级元素
const liElement = element.closest('li');
if (liElement && !liElement.classList.contains(config.filterClass)) {
liElement.remove();
removedCount++;
}
}
});
});
return { removedCount, matchedKeywords: Array.from(matchedKeywords) };
}
// 监听蜜柑计划动态加载的内容
function observeMikananiDynamicContent() {
// 监听点击事件,当用户点击an-box animated中的元素时触发过滤
document.addEventListener('click', function(e) {
// 检查点击的是否在an-box animated元素内
const clickedInAnBox = e.target.closest('.an-box.animated.fadeIn');
if (clickedInAnBox) {
// 延迟执行过滤,等待动态内容加载
setTimeout(() => {
const result = filterMikananiExpandableContent();
if (result.removedCount > 0 && config.showNotification) {
const keywordsText = result.matchedKeywords.join('、');
showNotification(`已过滤 ${result.removedCount} 个动态加载的DBD-Raws资源,匹配过滤词条:${keywordsText}`);
}
}, 300);
}
});
// 监听.row.an-res-row-frame元素内部的内容变化
const expandableFrames = document.querySelectorAll('.row.an-res-row-frame');
expandableFrames.forEach(frame => {
const observer = new MutationObserver(function(mutations) {
let shouldRefilter = false;
mutations.forEach(function(mutation) {
if (mutation.addedNodes && mutation.addedNodes.length > 0) {
for (let node of mutation.addedNodes) {
if (node.nodeType === 1) {
// 检查是否添加了包含目标内容的元素
if (node.querySelector && node.querySelector('div.sk-col.tag-res-name')) {
shouldRefilter = true;
break;
}
if (node.matches && node.matches('div.sk-col.tag-res-name')) {
shouldRefilter = true;
break;
}
}
}
}
});
if (shouldRefilter) {
setTimeout(() => {
const result = filterMikananiExpandableContent();
if (result.removedCount > 0 && config.showNotification) {
const keywordsText = result.matchedKeywords.join('、');
showNotification(`已过滤 ${result.removedCount} 个动态加载的DBD-Raws资源,匹配过滤词条:${keywordsText}`);
}
}, 100);
}
});
// 观察每个frame的内容变化
observer.observe(frame, {
childList: true,
subtree: true
});
});
// 同时监听全局的DOM变化作为备用
const globalObserver = new MutationObserver(function(mutations) {
let shouldRefilter = false;
mutations.forEach(function(mutation) {
if (mutation.addedNodes && mutation.addedNodes.length > 0) {
for (let node of mutation.addedNodes) {
if (node.nodeType === 1) {
// 检查是否添加了包含目标内容的元素
if (node.querySelector && node.querySelector('div.sk-col.tag-res-name')) {
shouldRefilter = true;
break;
}
if (node.matches && node.matches('div.sk-col.tag-res-name')) {
shouldRefilter = true;
break;
}
}
}
}
});
if (shouldRefilter) {
setTimeout(() => {
const result = filterMikananiExpandableContent();
if (result.removedCount > 0 && config.showNotification) {
const keywordsText = result.matchedKeywords.join('、');
showNotification(`已过滤 ${result.removedCount} 个动态加载的DBD-Raws资源,匹配过滤词条:${keywordsText}`);
}
}, 100);
}
});
// 观察整个文档的变化
globalObserver.observe(document.body, {
childList: true,
subtree: true
});
}
// 重新索引蜜柑计划表格的data-itemindex
function reindexMikananiTable() {
const allRows = document.querySelectorAll('tr[data-itemindex]');
// 按当前data-itemindex值排序
const sortedRows = Array.from(allRows).sort((a, b) => {
const indexA = parseInt(a.getAttribute('data-itemindex'));
const indexB = parseInt(b.getAttribute('data-itemindex'));
return indexA - indexB;
});
// 重新编号,从1开始
sortedRows.forEach((row, index) => {
row.setAttribute('data-itemindex', index + 1);
});
}
// 重新着色动漫花园表格行
function recolorDmhyTableRows() {
const rows = document.querySelectorAll('tbody tr:not(.' + config.filterClass + ')');
rows.forEach((row, index) => {
// 清空现有的颜色类
row.classList.remove('even', 'odd', 'even-row', 'odd-row');
// 添加新的颜色类
if (index % 2 === 0) {
row.classList.add('odd');
} else {
row.classList.add('even');
}
});
}
// 重新着色末日动漫表格行
function recolorAcgnxTableRows(selector) {
const rows = document.querySelectorAll(selector + ':not(.' + config.filterClass + ')');
rows.forEach((row, index) => {
// 移除现有的颜色类
row.classList.remove('alt1', 'alt2');
// 添加新的颜色类
if (index % 2 === 0) {
row.classList.add('alt1');
} else {
row.classList.add('alt2');
}
// 应用网站特定的样式
row.style.backgroundColor = index % 2 === 0 ? '#f8f9fa' : '#ffffff';
});
}
// 显示过滤通知
function showNotification(message) {
// 清除现有的定时器
if (notificationTimer) {
clearTimeout(notificationTimer);
notificationTimer = null;
}
// 移除现有的通知
const existingNotification = document.getElementById('dmhy-filter-notification');
if (existingNotification) {
existingNotification.remove();
}
// 创建新通知
const notification = document.createElement('div');
notification.id = 'dmhy-filter-notification';
notification.textContent = message;
// 添加鼠标事件监听器
notification.addEventListener('mouseenter', function() {
// 鼠标进入时清除定时器,暂停消失
if (notificationTimer) {
clearTimeout(notificationTimer);
notificationTimer = null;
}
});
notification.addEventListener('mouseleave', function() {
// 鼠标离开时重新启动消失定时器
startNotificationTimer(notification);
});
// 添加点击事件,点击也可以立即关闭
notification.addEventListener('click', function() {
hideNotification(notification);
});
document.body.appendChild(notification);
// 启动定时器
startNotificationTimer(notification);
}
// 启动通知定时器
function startNotificationTimer(notification) {
if (notificationTimer) {
clearTimeout(notificationTimer);
}
notificationTimer = setTimeout(() => {
hideNotification(notification);
}, config.notificationDuration);
}
// 隐藏通知
function hideNotification(notification) {
if (notification && notification.parentNode) {
notification.style.opacity = '0';
setTimeout(() => {
if (notification && notification.parentNode) {
notification.remove();
}
}, 500);
}
}
// 初始执行
setTimeout(filterContent, 1500);
})();