TolyanHammerKombat

Игра поймай неудаленного Толяна Хамстеркомбата

目前为 2025-02-26 提交的版本。查看 最新版本

// ==UserScript==
// @name         TolyanHammerKombat
// @namespace    http://tampermonkey.net/
// @version      1.3
// @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 CONFIG = {
        targetName: 'Толян Хамстеркомбат', // Имя целевого автора
        message: '🎉🐹🔨 Попался, крысеныш! 🎉🐹🔨', // Текст уведомления
        colors: {
            background: '#5252CC', // Фон уведомления
            text: '#FFDDCC' // Цвет текста
        },
        assets: {
            hammerImage: 'https://i.imgur.com/9hJJv6a.png', // Изображение молотка
            hammerSound: 'https://myinstants.com/media/sounds/fnaf-12-3-freddys-nose-sound.mp3' // Звук удара
        },
        animation: {
            hammerSize: 50, // Размер молотка в пикселях
            hitAnimation: {
                duration: 200, // Длительность анимации
                rotations: {
                    initial: 0, // Начальный угол
                    hit: -30, // Угол при ударе
                    reset: 0 // Угол после удара
                }
            },
        }
    };

    // Переключатель работы скрипта
    let isActive = true;

    // Создание уведомления
    const createNotice = (postElement) => {
        const notice = document.createElement('div');
        Object.assign(notice.style, {
            position: 'relative',
            textAlign: 'center',
            padding: '16px',
            backgroundColor: CONFIG.colors.background,
            borderRadius: '8px',
            marginTop: '8px',
            opacity: '0',
            transform: 'translateY(-20px)',
            transition: 'opacity 0.5s ease, transform 0.5s ease'
        });

        // Создание и добавление элемента
        notice.innerHTML = `<h2 style="color: ${CONFIG.colors.text}; font-weight: 600;">
            ${CONFIG.message}
        </h2>`;
        postElement.prepend(notice);

        // Запуск анимации когда элемент виден на 100%
        const noticeObserver = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    observer.disconnect();
                    setTimeout(() => {
                        notice.style.opacity = '1';
                        notice.style.transform = 'translateY(0)';
                    }, 200);
                }
            });
        }, { threshold: 1.0 });

        noticeObserver.observe(notice);
    };

    // Создание и управление молотком
    const createHammer = (event) => {
        const hammer = document.createElement('img');
        Object.assign(hammer.style, {
            position: 'fixed',
            width: `${CONFIG.animation.hammerSize}px`,
            height: `${CONFIG.animation.hammerSize}px`,
            pointerEvents: 'none',
            transformOrigin: 'bottom right',
            transition: 'transform 0.1s ease',
            left: `${event.clientX - 8}px`,
            top: `${event.clientY - 40}px`
        });

        // Создание и добавление элемента
        hammer.src = CONFIG.assets.hammerImage;
        document.body.appendChild(hammer);

        // Анимация удара молотком
        function animateHammer(hammer, rotation) {
            hammer.style.transform = `rotate(${rotation}deg)`;
        }

        // Последовательность анимации
        setTimeout(() => animateHammer(hammer, CONFIG.animation.hitAnimation.rotations.hit), 10);
        setTimeout(() => animateHammer(hammer, CONFIG.animation.hitAnimation.rotations.reset), 100);
        setTimeout(() => hammer.remove(), CONFIG.animation.hitAnimation.duration);
    };

    // Воспроизведение звукового эффекта
    const playSound = () => new Audio(CONFIG.assets.hammerSound).play();

    // Обработчик клика по аватарке
    const setupHammerInteraction = (postElement) => {
        const avatar = postElement.querySelector('.PostHeader__avatar a');
        if (!avatar) return;

        Object.assign(avatar.style, {
            cursor: 'crosshair',
            userSelect: 'none'
        });

        avatar.removeAttribute('href');
        avatar.addEventListener('click', event => {
            createHammer(event);
            playSound();
        });
    };

    // Проверка удаления профиля по аватарке
    const isProfileDeleted = (postElement) => !postElement.querySelector('.PostHeader__avatar img')?.src.includes('ava=1');

    // Основная логика проверки постов
    const checkPosts = () => {
        if (!isActive) {
            observer.disconnect();
            return;
        }

        // Проверка всех постов на странице
        document.querySelectorAll('.post').forEach(post => {
            const authorElement = post.querySelector('.PostHeaderTitle__authorName');
            const authorName = authorElement?.textContent.trim();

            // Если имя автора совпадает с целью и профиль не удален
            if (authorName === CONFIG.targetName && !isProfileDeleted(post)) {
                isActive = false;
                createNotice(post);
                setupHammerInteraction(post);
            }
        });
    };

    // Инициализация наблюдателя
    const observer = new MutationObserver(checkPosts);
    window.addEventListener('load', checkPosts);
    observer.observe(document.body, { childList: true, subtree: true });
})();