Загрузка данных
// ==UserScript==
// @name Двач: Фильтрация сообщений внутри тредов
// @namespace http://tampermonkey.net
// @version 3.5
// @description Скрывает отдельные ответы внутри тредов по ключевым словам. Не трогает общие ленты досок.
// @author You
// @match *://*.2ch.org/*
// @match *://*.2ch.hk/*
// @match *://*.m2ch.hk/*
// @match *://*.2ch.life/*
// @match *://*.2ch.su/*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
function isInsideThread() {
const url = window.location.href;
return url.includes('/res/') || url.includes('.html');
}
const botShit = ['тарабс', 'какел', 'хохол',' хохлы', 'укро', 'тцк',
'микол', 'мыкол', 'мивин', 'перемог', 'ципсо'
];
function processReply(replyElement) {
if (replyElement.dataset.checkedByFilter) return;
replyElement.dataset.checkedByFilter = "true";
const messageArticle = replyElement.querySelector('article.post__message');
if (!messageArticle) return;
let replyText = messageArticle.textContent.toLowerCase();
const triggeredWord = botShit.find(word => replyText.includes(word.toLowerCase().trim()));
if (triggeredWord) {
const placeholder = document.createElement('div');
placeholder.className = 'lahta-placeholder';
placeholder.style.border = '1px dashed #777777'; // Рамка изменена на нейтральный темно-серый цвет
placeholder.style.padding = '10px 14px';
placeholder.style.margin = '4px 0 4px 20px';
placeholder.style.borderRadius = '4px';
placeholder.style.background = 'rgba(128, 128, 128, 0.08)'; // Фон изменен на полупрозрачный пастельно-серый
placeholder.style.display = 'inline-block';
placeholder.style.clear = 'both';
// Установлен насыщенный коралловый цвет текста (#ff6f61) для идеального контраста на сером фоне
placeholder.innerHTML = `<span style="color: #ff6f61; font-weight: bold; text-decoration: none !important;">УДАЛЕНА ЛАХТИНСКАЯ ВОШЬ: [ ${triggeredWord.trim()} ]</span>`;
replyElement.parentNode.insertBefore(placeholder, replyElement);
replyElement.style.setProperty('display', 'none', 'important');
}
}
function scan() {
if (!isInsideThread()) return;
document.querySelectorAll('div.post.post_type_reply').forEach(processReply);
}
scan();
new MutationObserver(scan).observe(document.body, { childList: true, subtree: true });
})();
--------------------------------------------------------------
// ==UserScript==
// @name Радужная кнопка Двача в конце блока
// @namespace http://tampermonkey.net
// @version 2.5
// @description Перенос радужной кнопки скрытия с жирным черным крестом в самый конец блока post__details без текста
// @match *://*.2ch.org/*
// @match *://*.2ch.hk/*
// @match *://*.m2ch.hk/*
// @match *://*.2ch.life/*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// 1. Внедряем CSS-стили для кнопки
const style = document.createElement('style');
style.textContent = `
/* Настройка внешнего контейнера SVG кнопки */
svg.post__btn.post__btn_type_hide.icon.desktop.js-processed-btn {
display: inline-block !important;
width: 50px !important;
height: 50px !important;
box-sizing: border-box !important;
margin-left: 10px !important;
border-radius: 8px !important;
/* Базовое состояние: приглушенный сине-лиловый пиксельный стиль */
filter: invert(40%) sepia(20%) saturate(1200%) hue-rotate(220deg) !important;
image-rendering: pixelated !important;
image-rendering: crisp-edges !important;
/* Плавный переход для анимации при наведении (0.2 секунды) */
transition: filter 0.2s ease-in-out, transform 0.2s ease-in-out !important;
}
/* ЭФФЕКТ ПРИ НАВЕДЕНИИ (HOVER) */
/* Исходное состояние кнопки — добавляем быстрое время отклика */
svg.post__btn.post__btn_type_hide.icon.desktop.js-processed-btn {
transition: filter 0.15s ease-in-out, transform 0.15s ease-in-out !important;
}
/* Состояние при наведении */
svg.post__btn.post__btn_type_hide.icon.desktop.js-processed-btn:hover {
/* Смещаем спектр (hue-rotate) в сторону теплого пастельно-розового оттенка
и немного увеличиваем яркость (brightness) */
filter: invert(40%) sepia(20%) saturate(1500%) hue-rotate(310deg) brightness(1.1) !important;
/* Кнопка слегка и аккуратно увеличивается при наведении */
transform: scale(1.01) !important;
}
/* Настройки пикселизации для внутренних элементов */
svg.post__btn.post__btn_type_hide.icon.desktop.js-processed-btn * {
image-rendering: pixelated !important;
image-rendering: crisp-edges !important;
}
`;
document.head.appendChild(style);
// 2. Функция поиска и перемещения кнопок
function modifyButtons() {
// Ищем SVG-кнопки скрытия, которые мы еще не обрабатывали
let svgs = document.querySelectorAll('svg.post__btn.post__btn_type_hide.icon.desktop:not(.js-processed-btn)');
svgs.forEach((svg) => {
let parentDiv = svg.closest('.post__details');
if (parentDiv) {
// Помечаем SVG классом-маркером (CSS применится автоматически)
svg.classList.add('js-processed-btn');
// Переносим саму оригинальную SVG кнопку в самый конец родительского div
// Браузер автоматически заберет её со старого места и вставит в конец
parentDiv.appendChild(svg);
}
});
}
modifyButtons();
// 3. Отслеживание динамической подгрузки постов в треде
const observer = new MutationObserver(() => {
if (document.querySelector('svg.post__btn.post__btn_type_hide.icon.desktop:not(.js-processed-btn)')) {
modifyButtons();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
})();
------------------------------------------------------
// ==UserScript==
// @name Двач: Анти-Лахта Мод (Умная фильтрация)
// @namespace http://tampermonkey.net
// @version 2.5
// @description Скрывает бототреды только в общих лентах досок и никогда не трогает контент внутри самих тредов.
// @author You
// @match *://*.2ch.org/*
// @match *://*.2ch.hk/*
// @match *://*.m2ch.hk/*
// @match *://*.2ch.life/*
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// Функция проверки: находимся ли мы внутри треда?
function isInsideThread() {
const url = window.location.href;
// Если в URL есть "/res/" или имя файла заканчивается на ".html" (переход внутрь треда)
// то скрипт не должен работать
return url.includes('/res/') || url.includes('.html');
}
// Массив ключевых слов
const botShit = [
'webm', 'тяноч', 'отношен', 'секс', 'танцуль', 'Воскресной молитвы',
'фурр', 'почему так', 'девушк', 'лесополос', 'ZASMOBOS', 'Это гуар.',
'фапочно', 'покажи', 'цуиь', 'аниме', 'mp4', 'banana', 'понитре',
'анимэ', 'дружботр', 'вацфу', 'вайф', 'тредю', 'зумер', 'тянка', 'тянко',
'тянок', 'септемба', 'котосуббота', '#пкм', 'пустите в', 'fap', 'РИСОВАЧ',
'рисовач тред', 'Храмом ГОЛОВЫ', 'храам голов', 'warcraft', 'war c',
'Главный новостной', 'ШЛИК', 'fap', 'Оцени член', 'оцени', 'писяндрик'
];
// Функция обработки ОП-поста
function processPost(postElement) {
// ЕСЛИ МЫ ВНУТРИ ТРЕДА — КАТЕГОРИЧЕСКИ НИЧЕГО НЕ СКРЫВАЕМ
if (isInsideThread()) return;
// Защита от повторной обработки одного и того же элемента
if (postElement.dataset.checkedByLahta) return;
postElement.dataset.checkedByLahta = "true";
// Извлекаем текст
let threadText = postElement.textContent.replace('(OP)', '').toLowerCase();
threadText = threadText.replace(/\>+(\d+)>/g, '').replace(/\>+(\d+)/g, '');
threadText = threadText.replace(/\s+/g, ' ').trim();
// Ищем совпадение
const triggeredWord = botShit.find(word => {
const cleanWord = word.trim().toLowerCase();
return cleanWord !== '' && threadText.includes(cleanWord);
});
if (triggeredWord) {
// Находим контейнер всего треда на доске
const threadContainer = postElement.closest('.thread') || postElement.closest('[id^="thread-"]') || postElement.closest('.post-wrapper');
if (threadContainer) {
// Создаем плашку-заглушку
const placeholder = document.createElement('div');
placeholder.className = 'lahta-placeholder';
placeholder.style.border = '1px dashed #555555';
placeholder.style.padding = '10px 14px';
placeholder.style.margin = '12px 0';
placeholder.style.borderRadius = '4px';
placeholder.style.background = 'rgba(221, 161, 172, 0.05)';
placeholder.style.display = 'block';
placeholder.style.clear = 'both';
placeholder.innerHTML = `<span style="color: #dda1ac; font-weight: bold; text-decoration: none !important;">УДАЛЕНА БОТОХУЕТА [ ${triggeredWord.trim()} ]</span>`;
// Вставляем плашку перед скрываемым тредом
threadContainer.parentNode.insertBefore(placeholder, threadContainer);
// Скрываем оригинальный тред на главной странице доски
threadContainer.style.setProperty('display', 'none', 'important');
}
}
}
// Запуск сканирования
function scan() {
if (isInsideThread()) return;
const opPosts = document.querySelectorAll('.post_type_oppost, .oppost, .post.post_type_oppost');
opPosts.forEach(post => processPost(post));
}
// Первый запуск при инициализации страницы
scan();
// Наблюдатель за динамической подгрузкой новых постов/тредов
const observer = new MutationObserver((mutations) => {
// Если пользователь перешел внутрь треда (пусть даже по AJAX без перезагрузки), прекращаем обработку
if (isInsideThread()) return;
let shouldScan = false;
for (let mutation of mutations) {
if (mutation.addedNodes.length > 0) {
shouldScan = true;
break;
}
}
if (shouldScan) {
scan();
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
})();