'use strict' /** * Страница настроек ВКонтакте */ class killer { constructor() { // /** // * Генерация списка пользователей // * // * @param {string} id Идентификатор // * @param {string} page Идентификатор страницы настроек // * // * @return {Function} Функция для выполнения в генераторе группы // */ // this.list = function (id, page = 'nadrez') { // /** // * Запись в группу (подразумевается выполнение в функции генерирующую группу) // * // * @param {string} group Группа // * // * @return {bool} Статус выполнения // */ // return function (group) { // if (typeof page === 'string' && typeof id === 'string' && typeof group === 'string') { // // Пройдена проверка входных параметров // // Инициализация блока // let block = document.getElementById('block_' + group); // // Инициализация верхнего колонтинула блока // let header = block.getElementsByClassName('page_block_header')[0]; // // Инициализация элемента со статусом // let status = header.getElementsByClassName('page_block_saved')[0]; // // Инициализация тела блока // let body = block.getElementsByClassName('settings_panel clear_fix settings_' + core.id + ' settings_section_' + core.id)[0]; // } // return false; // } // } /** * Обработка группы сообщений * * Иницилизионная функция запускающая процессы обработки сообщений * * @param {string} group Группа для обработки * * @return {bool} Статус выполнения */ this.tribunal = async function (group = this.last(), list = this.list()) { if (await this.search(this.account(group), this.list())) { // Найдена цель на удаление // Инициализация типа действия с группой сообщений заблокированного аккаунта const action = await settings.read('killer_action'); // Обработка найденной цели (сортировано по предполагаемой востребованности) if (action === 'clear') return this.clear(group); else if (action === 'delete') return this.delete(group); else if (action === 'hide') return this.hide(group); else { // Не скрывать группу сообщений // Размытие if (await settings.read('killer_action_blur_status') ?? true) return this.blur(group); // Пометка цветом if (await settings.read('killer_action_highlight_status') ?? false) return this.highlight(group); return true; } } } /** * Обработка всех видимых групп сообщений * * @return {number} Количество обработанных групп сообщений */ this.genocide = async function () { // Инициализация списка сообщений const wrap = this.wrap(); // Инициализация счётчика обработканных групп сообщений let handled = 0; for (let i = 0, l = wrap.children.length; i < l; ++i) { // Перебор групп сообщений // Обработка this.tribunal(wrap.children[i]); // Запись в счётчик ++handled; } return handled; } /** * Найти элемент-оболочку групп сообщений * * @return {Element} Оболочка групп сообщений */ this.wrap = function () { return document.getElementsByClassName('_im_peer_history im-page-chat-contain')[0]; } /** * Найти последнюю группу сообщений * * @return {Element} Группа сообщений, если найдена */ this.last = function () { // Инициализация списка сообщений const wrap = this.wrap(); // Инициализация последней группы сообщений const group = wrap.children[wrap.children.length - 1]; return group; } /** * Найти и прочитать пользователя последней группы сообщений * * @param {string} group Группа для обработки * * @return {number} Идентификатор страницы ВКонтакте (только цифры) */ this.account = function (group = this.last()) { // Инициализация идентификатора отправителя const id = +group.getAttribute('data-peer'); return id; } /** * Прочитать список аккаунтов на удаление из реестра * * @return {object} Список аккаунтов на удаление */ this.list = async function () { // Инициализация списка аккаунтов на удаление const targets = await settings.read('killer_targets'); return targets; } /** * Поиск аккаунта в списке на удаление * * @param {number} account Аккаунт для обработки * * @return {boolean} Статус наличия аккаунта в списке на удаление */ this.search = async function (account = this.account(), targets = await this.list()) { if (account === this.self()) { // Обрабатывается свой аккаунт // Инициализация статуса разрешения блокировки самого себя const self = await settings.read('killer_self'); return self ?? false; } console.log(targets); if (typeof targets === 'object') { // Пройдена проверка на тип if (Object.keys(targets).length >= await settings.read('killer_targets_limit') ?? 500) { // Достигло ограничения количество аккаунтов в реестре // Полная очистка реестра this.purge(); } else { // Не достигло ограничения rоличество аккаунтов в ресстре for (const { target, status } in targets) { // Перебор искомых целей для удаления alert(target); alert(status); if (target === account) { // Найдена цель return true; } } } } else { // Не пройдена проверка на тип и пустоту // Инициализация реестра this.purge(); } if (await this.blocked(account)) { // Пройдена проверка (заблокирован) // Инициализация буфера записи в хранилище let buffer = targets; // Запись аккаунта в буфер записи в хранилище buffer[account] = true; // Запись в реестр в хранилище settings.write('killer_targets', buffer); return true; } return false; } /** * Удаление группы сообщений (из HTML-документа) * * Для удаления на аккаунте со стороны ВКонтакте использовать this.delete() * * @param {string} group Группа для обработки * * @return {bool} Статус выполнения */ this.clear = async function (group = this.last()) { // Удаление group.remove(); return true; } /** * Скрытие группы сообщений (из HTML-документа) * * Для удаления из документа использовать this.clear() * * @param {string} group Группа для обработки * * @return {bool} Статус выполнения */ this.hide = async function (group = this.last()) { // Скрытие group.style.display = 'none'; return true; } /** * Пометка цветом группы сообщений (в HTML-документе) * * @param {string} group Группа для обработки * * @return {boolean} Статус выполнения */ this.highlight = async function (group = this.last()) { // Инициализация цвета для фона let color = await settings.read('killer_action_highlight_color'); // Проверка полученных значений if (typeof color !== 'string') color = '#aeafd0'; // Запись цвета group.style.background = color; return true; } /** * Размытие группы сообщений (в HTML-документе) * * @param {string} group Группа для обработки * * @return {boolean} Статус выполнения */ this.blur = async function (group = this.last()) { // Инициализация значения степени размытия let degree = await settings.read('killer_action_blur_degree'); // Проверка полученных значений if (typeof degree !== 'number') degree = 3; // Запись размытия group.style.filter = 'blur(' + degree + 'px)'; return true; } /** * Удаление группы сообщений на стороне ВКонтакте * * @param {string} group Группа для обработки * * @return {bool} Статус выполнения */ this.delete = async function (group = this.last()) { return false; } /** * Проверка аккаунта на наличие в списке заблокированных ВКонтакте * * @param {number} account Аккаунт для обработки * * @return {boolean} Статус аккаунта (true - заблокирован) */ this.blocked = async function (account = this.account()) { // Запрос на чтение страницы const response = await fetch('https://vk.com/id' + account); // Инициализация полученных данных const data = new TextDecoder('windows-1251').decode(new DataView(await response.arrayBuffer())); // Инициализация парсера const parser = new DOMParser(); // Инициализация HTML-страницы в понятном JS формате const page = parser.parseFromString(data, "text/html"); // Инициализация кнопки "Заблокировать пользователя" const button = page.body.querySelector('a[data-task-click="ProfileAction/toggle_blacklist"]'); // Проверка на инициализированность кнопки if (typeof button === 'null') return false; // Возвращает true если заблокирован пользователь (подразумевается наличие текста "Разблокировать {пользователь}") return button.innerText.trim()[0] === 'Р'; } /** * Прощение * * Удаляет аккаунт из реестра заблокированных * * @return {boolean} Статус выполнения * * @todo Доделать */ this.forgive = async function (account, targets = await this.list()) { if (typeof account !== 'undefined' && typeof account !== 'null') { // Пройдена проверка полученных значений аргументов // Инициализация буфера записи в хранилище let buffer = {}; for (const { target, status } in targets) { // Перебор заблокированных аккаунтов // Проверка на совпадение if (target === account) continue; // Запись в буфер записи в хранилище buffer.push(account); } // Запись в реестр в хранилище return settings.write('killer_targets', buffer); } return false; } /** * Очистка реестра аккаунтов * * Полностью удаляет все аккаунты из реестра * * @return {boolean} Статус выполнения */ this.purge = async function () { alert('попа'); return await settings.write('killer_targets', {}); } /** * Прочитать свой идентификатор аккаунта * * Ищет кнопку "Выход из аккаунта" и через неё узнает идентификатор * * @return {number} Идентификатор аккаунта, если найден */ this.self = function () { // Поиск идентификатора const id = +document.getElementById('top_logout_link').getAttribute('onclick').match(/[^_]*(?='\);\slogout\(\);)/)[0]; // Проверка найденного идентификатора if (typeof id === 'number') return id; return null; } } }