TolyanHammerKombat

Игра поймай Толяна Хамстеркомбата в ленте Фанки

// ==UserScript==
// @name         TolyanHammerKombat
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Игра поймай Толяна Хамстеркомбата в ленте Фанки
// @author       Marina Khamsterkombat
// @match        https://vk.com/*
// @icon         https://em-content.zobj.net/source/apple/391/hamster_1f439.png
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Настройки
    const SETTINGS = {
        targetAuthor: 'Иван Русин',
        notification: {
            text: '🚫🐖🔨 Попалась, свинья! 🔨🐖🚫',
            styles: {
                background: '#303030',
                textColor: '#CD0086'
            }
        },
        hammer: {
            imageUrl: 'https://i.imgur.com/9hJJv6a.png',
            soundUrl: 'https://myinstants.com/media/sounds/fnaf-12-3-freddys-nose-sound.mp3',
            size: 50,
            animation: {
                durationMs: 200,
                rotations: {
                    initial: 0,
                    hit: -30,
                    reset: 0
                }
            }
        },
        delays: {
            beforeShowNotificationMs: 200,
            beforeHammerHitMs: 10,
            beforeHammerResetMs: 100
        }
    };

    // Переключатель состояния скрипта
    let scriptEnabled = true;

    // Создает уведомление об скрытии поста
    function createBlockedPostNotice() {
        const notice = document.createElement('div');
        const text = document.createElement('h2');

        notice.className = 'hammerkombat-notice';
        text.className = 'hammerkombat-notice-text';
        text.textContent = SETTINGS.notification.text;

        notice.appendChild(text);

        return notice;
    }

    // Показывает уведомление с анимацией
    function showNoticeWithAnimation(noticeElement) {
        const observer = new IntersectionObserver(([entry]) => {
            if (entry.isIntersecting) {
                observer.disconnect();
                setTimeout(() => {
                    noticeElement.style.opacity = '1';
                    noticeElement.style.transform = 'translateY(0)';
                }, SETTINGS.delays.beforeShowNotificationMs);
            }
        }, { threshold: 1.0 });

        observer.observe(noticeElement);
    }

    // Создает молоток в позиции клика
    function createHammerAtPosition(clickX, clickY) {
        const hammer = document.createElement('img');
        hammer.className = 'hammerkombat-cursor';
        hammer.src = SETTINGS.hammer.imageUrl;

        Object.assign(hammer.style, {
            left: `${clickX - 8}px`,
            top: `${clickY - 40}px`,
            width: `${SETTINGS.hammer.size}px`,
            height: `${SETTINGS.hammer.size}px`
        });

        document.body.appendChild(hammer);
        return hammer;
    }

    // Шаг анимации удара молотка
    function animateHammerStep(hammerElement, rotation) {
        hammerElement.style.transform = `rotate(${rotation}deg)`;
    }

    // Анимирует удар молотка
    function animateHammerHit(hammerElement) {
        const { rotations, durationMs } = SETTINGS.hammer.animation;

        setTimeout(() => {hammerElement.style.transform = `rotate(${rotations.hit}deg)`}, SETTINGS.delays.beforeHammerHitMs);
        setTimeout(() => {hammerElement.style.transform = `rotate(${rotations.reset}deg)`}, SETTINGS.delays.beforeHammerResetMs);
        setTimeout(() => hammerElement.remove(), durationMs);
    }

    // Воспроизводит звук удара
    function playHammerSound() {
        new Audio(SETTINGS.hammer.soundUrl).play();
    }

    // Настраивает обработчик клика на аватар
    function setupAvatarClickListener(avatarElement) {
        avatarElement.style.cursor = 'crosshair';
        avatarElement.removeAttribute('href');

        avatarElement.addEventListener('click', event => {
            const hammer = createHammerAtPosition(event.clientX, event.clientY);
            animateHammerHit(hammer);
            playHammerSound();
        });
    }

    // Основная функция проверки постов
    function checkPostsOnPage() {
        if (!scriptEnabled) return;

        document.querySelectorAll('.post').forEach(post => {
            const authorName = post.querySelector('.PostHeaderTitle__authorName')?.textContent.trim();

            if (authorName === SETTINGS.targetAuthor) {
                scriptEnabled = false;

                const postContent = post.querySelector('div._post_content');
                if (!postContent) return;

                // Скрываем оригинальный контент
                postContent.querySelector('.post_content').style.display = 'none';

                // Добавляем уведомление
                const notice = createBlockedPostNotice();
                postContent.append(notice);
                showNoticeWithAnimation(notice);

                // Настраиваем аватар
                const avatar = post.querySelector('.PostHeader__avatar a');
                if (avatar) setupAvatarClickListener(avatar);
            }
        });
    }

    // Инициализация
    function init() {
        // Добавляем базовые стили
        const style = document.createElement('style');
        style.textContent = `
            .hammerkombat-notice {
                position: relative;
                text-align: center;
                padding: 16px;
                background: ${SETTINGS.notification.styles.background};
                margin-top: 8px;
                opacity: 0;
                transform: translateY(-20px);
                transition: opacity 0.5s ease, transform 0.5s ease;
            }
            .hammerkombat-notice-text {
                color: ${SETTINGS.notification.styles.textColor};
                font-weight: bold;
                text-transform: uppercase;
            }
            .hammerkombat-cursor {
                position: fixed;
                pointer-events: none;
                transform-origin: bottom right;
                transition: transform 0.1s ease;
            }
        `;
        document.head.appendChild(style);

        // Запускаем проверку
        const observer = new MutationObserver(checkPostsOnPage);
        observer.observe(document.body, { childList: true, subtree: true });
        window.addEventListener('load', checkPostsOnPage);
    }

    init();
})();