pepeW Spammer 5

Wersja z ulepszonym interfejsem do dodawania i usuwania pojedynczych wiadomości z listy.

// ==UserScript==
// @name         pepeW Spammer 5
// @namespace    http://tampermonkey.net/
// @version      14.6
// @description  Wersja z ulepszonym interfejsem do dodawania i usuwania pojedynczych wiadomości z listy.
// @author       ewa
// @match        https://kick.com/*
// @grant        none
// ==/UserScript==
 
(function () {
    'use strict';
 
    const pepewImg = "https://i.pinimg.com/originals/02/06/8e/02068e2e1a90365496eebe40702f87d4.gif";
 
    const style = document.createElement("style");
    style.textContent = `
    @import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');
    @keyframes panel-flash-animation { 50% { box-shadow: 0 0 25px 5px #00ffa0; } }
    .panel-flash { animation: panel-flash-animation 0.4s ease-in-out; }
    #pepewPanel {
        position: fixed; top: 12px; right: 12px; width: 320px;
        background: url('${pepewImg}') no-repeat center center / cover;
        border-radius: 12px; box-shadow: 0 8px 24px rgba(0, 255, 165, 0.3);
        font-family: 'Inter', sans-serif; color: #d0d0d0; user-select: none;
        z-index: 99999999; transition: height 0.3s ease, width 0.3s ease, opacity 0.3s ease, box-shadow 0.3s ease;
        overflow: visible; display: flex; flex-direction: column; cursor: default; left: auto;
    }
    #pepewPanel::before {
        content: ""; position: absolute; inset: 0; border-radius: 12px;
        background-color: rgba(0, 0, 0, 0.6); pointer-events: none; z-index: 0; backdrop-filter: brightness(0.75);
    }
    #pepewPanel.minimized {
        width: 190px !important; height: 36px !important; background: #000; cursor: pointer;
        justify-content: center !important; align-items: center !important; padding: 0 16px 0 8px !important;
        color: #00ffa0 !important; font-weight: 600 !important; font-size: 16px !important;
        text-shadow: 0 0 12px #00ffa0cc !important; flex-direction: row !important; gap: 8px !important;
        white-space: nowrap; overflow: visible !important; backdrop-filter: brightness(0.25);
    }
    #pepewPanel.minimized::before { background: none !important; }
    #pepewPanel.minimized #pepewPanelHeader, #pepewPanel.minimized #pepewPanelContent {
        visibility: hidden !important; height: 0 !important; margin: 0 !important; padding: 0 !important;
        overflow: hidden !important; user-select: none !important;
    }
    #pepewPanel.minimized #miniLabel, #pepewPanel.minimized #miniImg {
        visibility: visible !important; margin: 0 !important; padding: 0 !important;
        user-select: text !important; display: flex !important; align-items: center !important;
    }
    #miniLabel { color: #00ffa0; font-weight: 600; text-shadow: 0 0 8px #00ffa0cc; user-select: text; white-space: nowrap; font-family: 'Inter', sans-serif; line-height: 1; }
    #miniImg { width: 25px; height: 25px; border-radius: 3px; image-rendering: pixelated; user-select: none; }
    #pepewPanelHeader {
        background: transparent; padding: 8px 12px; font-weight: 600; font-size: 16px; cursor: move;
        display: flex; justify-content: space-between; align-items: center; color: #00ffa0;
        text-shadow: 0 0 5px #00ffa0cc; position: relative; z-index: 10;
    }
    #pepewPanelContent { display: flex; flex-direction: column; gap: 10px; padding: 12px; position: relative; z-index: 1; }
    #pepewPanel input[type="text"], #pepewPanel input[type="number"], #pepewPanel textarea {
        width: 100%; padding: 6px 8px; border-radius: 6px; border: none; font-family: 'Inter', sans-serif;
        font-size: 14px; background: #111; color: #eee; box-sizing: border-box; box-shadow: inset 0 0 5px #00ffa0cc; resize: vertical;
    }
    #pepewPanel input[type="range"] { width: 100%; }
    #pepewPanel button {
        background: #00ffa0; border: none; border-radius: 6px; padding: 8px 16px; font-weight: 600;
        cursor: pointer; color: #000; box-shadow: 0 0 8px #00ffa0cc; transition: background 0.3s ease;
    }
    #pepewPanel button:hover { background: #00cc80; }
    #toggleMinimizeBtn { padding: 0; width: 24px; height: 24px; display: flex; justify-content: center; align-items: center; font-size: 20px; line-height: 1; }
    #counterDisplay { font-size: 14px; color: #00ffa0; text-align: center; font-weight: 600; text-shadow: 0 0 5px #00ffa0cc; }
    #countdownDisplay { font-size: 12px; color: #b0b0b0; text-align: center; min-height: 16px; font-weight: 500; margin-top: 4px; }
    .custom-dropdown { position: absolute; top: 50%; right: 50px; transform: translateY(-50%); width: 90px; }
    .dropdown-selected {
        background-color: #222; color: #ccc; border: 1px solid #444; border-radius: 6px; padding: 4px 8px;
        font-family: 'Inter', sans-serif; font-weight: 600; font-size: 12px; cursor: pointer; display: flex;
        justify-content: space-between; align-items: center;
    }
    .dropdown-selected::after { content: '▼'; font-size: 10px; transition: transform 0.2s ease; }
    .custom-dropdown.open .dropdown-selected::after { transform: rotate(180deg); }
    .dropdown-options {
        position: absolute; top: 110%; left: 0; right: 0; background-color: #222; border: 1px solid #444;
        border-radius: 6px; list-style: none; padding: 4px; margin: 0; z-index: 11; opacity: 0;
        visibility: hidden; pointer-events: none; transform: translateY(-10px);
        transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
    }
    .custom-dropdown.open .dropdown-options { opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(0); }
    .dropdown-options li { padding: 6px 8px; border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: 500; transition: background-color 0.2s ease; }
    .dropdown-options li:hover { background-color: #00ffa0; color: #000; }
    #msgCountContainer, #keywordContainer { display: flex; flex-direction: column; gap: 4px; }
 
    /* === NOWE STYLE DLA ZARZĄDZANIA WIADOMOŚCIAMI === */
    #addMessageContainer { display: flex; gap: 8px; }
    #newMessageInput { flex-grow: 1; }
    #addMessageBtn { padding: 0; width: 32px; flex-shrink: 0; font-size: 20px; }
    #messageList {
        display: flex; flex-direction: column; gap: 6px;
        max-height: 120px; overflow-y: auto; padding: 4px;
        background: rgba(0,0,0,0.2); border-radius: 6px;
    }
    .message-item {
        display: flex; justify-content: space-between; align-items: center;
        background: #222; padding: 4px 8px; border-radius: 4px;
        font-size: 13px;
    }
    .message-item-text { word-break: break-all; }
    .delete-msg-btn {
        background: none; border: none; color: #ff5555; cursor: pointer;
        font-size: 16px; line-height: 1; padding: 0 4px; font-weight: bold;
    }
    .delete-msg-btn:hover { color: #ff8888; }
    `;
    document.head.appendChild(style);
 
    const panel = document.createElement("div");
    panel.id = "pepewPanel";
    panel.innerHTML = `
        <div id="pepewPanelHeader">
            <div>pepeW Spammer</div>
            <div class="custom-dropdown" id="modeDropdownContainer">
                <div class="dropdown-selected" id="selectedMode">Czas</div>
                <ul class="dropdown-options" id="modeOptions">
                    <li data-value="time">Czas</li>
                    <li data-value="chat">Czat</li>
                    <li data-value="keyword">Słowo</li>
                </ul>
            </div>
            <button id="toggleMinimizeBtn">−</button>
        </div>
        <div id="pepewPanelContent">
            <label>Wiadomości:</label>
            <div id="messageList"></div>
            <div id="addMessageContainer">
                <input type="text" id="newMessageInput" placeholder="Wpisz nową wiadomość...">
                <button id="addMessageBtn">+</button>
            </div>
            <div id="timeSliders">
                <div><label>Min (s): <span id="minValDisplay">1.0</span></label><input type="range" id="minDelay" min="0" max="30" step="0.5" value="1" /></div>
                <div><label>Max (s): <span id="maxValDisplay">2.0</span></label><input type="range" id="maxDelay" min="0" max="30" step="0.5" value="2" /></div>
            </div>
            <div id="msgCountContainer" style="display:none;">
                <label for="msgCountInput">Co ile wiadomości na czacie:</label>
                <input type="number" id="msgCountInput" min="1" value="5" />
            </div>
            <div id="keywordContainer" style="display:none;">
                <label for="keywordInput">Wyzwalacze (każdy w nowej linii):</label>
                <textarea id="keywordInput" rows="3"></textarea>
            </div>
            <button id="startStopBtn">Start</button>
            <div id="counterDisplay">Wysłano wiadomości: 0</div>
            <div id="countdownDisplay">Oczekuje na start...</div>
        </div>
        <img id="miniImg" src="${pepewImg}" style="visibility:hidden; user-select:none;" />
        <div id="miniLabel" style="visibility:hidden; user-select:none;">pepeW Spammer</div>
    `;
    document.body.appendChild(panel);
 
    // === ZMIENNE ===
    const countdownDisplay = document.getElementById("countdownDisplay");
    const minSlider = document.getElementById("minDelay");
    const maxSlider = document.getElementById("maxDelay");
    const minDisplay = document.getElementById("minValDisplay");
    const maxDisplay = document.getElementById("maxValDisplay");
    const startStopBtn = document.getElementById("startStopBtn");
    const toggleMinimizeBtn = document.getElementById("toggleMinimizeBtn");
    const header = document.getElementById("pepewPanelHeader");
    const counterDisplay = document.getElementById("counterDisplay");
    const modeDropdownContainer = document.getElementById("modeDropdownContainer");
    const selectedModeDiv = document.getElementById("selectedMode");
    const modeOptions = document.getElementById("modeOptions");
    const msgCountInput = document.getElementById("msgCountInput");
    const msgCountContainer = document.getElementById("msgCountContainer");
    const timeSliders = document.getElementById("timeSliders");
    const keywordInput = document.getElementById("keywordInput");
    const keywordContainer = document.getElementById("keywordContainer");
 
    // NOWE ELEMENTY UI WIADOMOŚCI
    const messageListDiv = document.getElementById('messageList');
    const newMessageInput = document.getElementById('newMessageInput');
    const addMessageBtn = document.getElementById('addMessageBtn');
 
    let running = false;
    let timeoutId = null;
    let messageCount = 0;
    let observer = null;
    let mode = "time";
    let countdownInterval = null;
    let targetTime = 0;
    let isSending = false;
    let myUsername = null;
    const settingsKey = 'pepewSpammerSettings_v14.4'; // Zaktualizowany klucz dla nowej wersji
    let messagesArray = []; // Tablica przechowująca wiadomości
 
    // === ZARZĄDZANIE WIADOMOŚCIAMI ===
 
    function renderMessages() {
        messageListDiv.innerHTML = ''; // Wyczyść listę
        messagesArray.forEach((msg, index) => {
            const item = document.createElement('div');
            item.className = 'message-item';
            item.innerHTML = `
                <span class="message-item-text">${msg}</span>
                <button class="delete-msg-btn" data-index="${index}" title="Usuń wiadomość">×</button>
            `;
            messageListDiv.appendChild(item);
        });
    }
 
    function addMessage() {
        const newMessage = newMessageInput.value.trim();
        if (newMessage) {
            messagesArray.push(newMessage);
            newMessageInput.value = '';
            renderMessages();
            saveSettings();
        }
    }
 
    messageListDiv.addEventListener('click', (e) => {
        if (e.target.classList.contains('delete-msg-btn')) {
            const index = parseInt(e.target.dataset.index, 10);
            messagesArray.splice(index, 1);
            renderMessages();
            saveSettings();
        }
    });
 
    addMessageBtn.addEventListener('click', addMessage);
    newMessageInput.addEventListener('keydown', (e) => {
        if (e.key === 'Enter') {
            e.preventDefault();
            addMessage();
        }
    });
 
    // === GŁÓWNA LOGIKA ===
 
    function applyMode(newMode) { /* ... bez zmian ... */
        mode = newMode;
        timeSliders.style.display = 'none';
        msgCountContainer.style.display = 'none';
        keywordContainer.style.display = 'none';
        switch (newMode) {
            case 'time': timeSliders.style.display = 'block'; selectedModeDiv.textContent = "Czas"; break;
            case 'chat': msgCountContainer.style.display = 'flex'; selectedModeDiv.textContent = "Czat"; break;
            case 'keyword': keywordContainer.style.display = 'flex'; selectedModeDiv.textContent = "Słowo"; break;
        }
    }
 
    function saveSettings() {
        const settings = {
            messages: messagesArray, // Zapisujemy nową tablicę
            minDelay: minSlider.value, maxDelay: maxSlider.value,
            msgCount: msgCountInput.value, keyword: keywordInput.value, mode: mode,
            left: panel.style.left, top: panel.style.top,
        };
        localStorage.setItem(settingsKey, JSON.stringify(settings));
    }
 
    function loadSettings() {
        const saved = localStorage.getItem(settingsKey);
        if (saved) {
            try {
                const settings = JSON.parse(saved);
                messagesArray = Array.isArray(settings.messages) ? settings.messages : ['pepeW'];
                minSlider.value = settings.minDelay || '1';
                maxSlider.value = settings.maxDelay || '2';
                msgCountInput.value = settings.msgCount || '5';
                keywordInput.value = settings.keyword || '';
                const savedMode = settings.mode || 'time';
                applyMode(savedMode);
                if (settings.left && settings.top) {
                    panel.style.left = settings.left;
                    panel.style.top = settings.top;
                    panel.style.right = "auto";
                }
            } catch (e) { console.error("Błąd wczytywania ustawień:", e); messagesArray = ['pepeW']; }
        } else {
            messagesArray = ['pepeW']; // Domyślna wiadomość przy pierwszym uruchomieniu
        }
        renderMessages(); // Wyrenderuj wczytane wiadomości
        updateSlidersDisplay();
    }
 
    const triggerSendFlash = () => panel.classList.add('panel-flash');
    panel.addEventListener('animationend', () => panel.classList.remove('panel-flash'));
    const updateCounter = () => counterDisplay.textContent = `Wysłano wiadomości: ${messageCount}`;
    const updateSlidersDisplay = () => { /* ... bez zmian ... */
        minDisplay.textContent = parseFloat(minSlider.value).toFixed(1);
        maxDisplay.textContent = parseFloat(maxSlider.value).toFixed(1);
    };
    const getRandomDelay = () => (Math.random() * (parseFloat(maxSlider.value) - parseFloat(minSlider.value)) + parseFloat(minSlider.value)) * 1000;
 
    function getRandomMessage() {
        if (messagesArray.length === 0) return null;
        return messagesArray[Math.floor(Math.random() * messagesArray.length)];
    }
 
    const sendMessage = msg => { /* ... bez zmian ... */
        if (!msg) return false;
        const inputDiv = document.querySelector('div.editor-input[contenteditable="true"][data-testid="chat-input"]');
        if (!inputDiv) { console.error("PEPEW SPAMMER: Nie znaleziono pola wiadomości."); return false; }
        inputDiv.focus(); inputDiv.textContent = ""; document.execCommand('insertText', false, msg);
        inputDiv.dispatchEvent(new Event('input', { bubbles: true }));
        inputDiv.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: 'Enter', code: 'Enter', which: 13, keyCode: 13 }));
        triggerSendFlash(); return true;
    };
 
    function getMyUsername() { /* ... bez zmian ... */
        const usernameElement = document.querySelector('.user-menu-item-username');
        if (usernameElement) {
            myUsername = usernameElement.textContent.trim().toLowerCase();
            console.log(`PEPEW SPAMMER: Wykryto nazwę użytkownika: ${myUsername}`);
        } else {
            setTimeout(getMyUsername, 2000);
        }
    }
 
    function updateTimerCountdown() { /* ... bez zmian ... */
        if (!running) return;
        const remaining = targetTime - Date.now();
        if (remaining > 0) {
            countdownDisplay.textContent = `Następna za ${(remaining / 1000).toFixed(1)} s...`;
        } else {
            countdownDisplay.textContent = "Wysyłanie...";
        }
    }
 
    const spamLoopTime = () => { /* ... bez zmian ... */
        if (!running || mode !== "time") return;
        const msg = getRandomMessage();
        if (!msg) return stopSpamming();
        if (sendMessage(msg)) {
            messageCount++;
            updateCounter();
        }
        const delay = getRandomDelay();
        targetTime = Date.now() + delay;
        timeoutId = setTimeout(spamLoopTime, delay);
    };
 
    const setupChatObserver = () => { /* ... bez zmian ... */
        if (observer) observer.disconnect();
        const chatContainer = document.querySelector('#chatroom-messages > div');
        if (!chatContainer) { stopSpamming(); return; }
        console.log("PEPEW SPAMMER: Tryb czatu aktywny.");
        let newMessagesSinceLastSend = 0;
        const userSetCount = parseInt(msgCountInput.value, 10);
        countdownDisplay.textContent = `Oczekiwanie na ${userSetCount} wiadomości...`;
        observer = new MutationObserver(mutations => {
            if (!running || mode !== "chat" || isSending) return;
            for (const mutation of mutations) {
                if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                    newMessagesSinceLastSend += mutation.addedNodes.length;
                }
            }
            const remaining = Math.max(0, userSetCount - newMessagesSinceLastSend);
            countdownDisplay.textContent = `Oczekiwanie na ${remaining} wiadomości...`;
            if (newMessagesSinceLastSend >= userSetCount) {
                isSending = true;
                countdownDisplay.textContent = "Wysyłanie...";
                setTimeout(() => {
                    const msg = getRandomMessage();
                    if (msg && sendMessage(msg)) { messageCount++; updateCounter(); }
                    newMessagesSinceLastSend = 0;
                    countdownDisplay.textContent = `Oczekiwanie na ${userSetCount} wiadomości...`;
                    isSending = false;
                }, 200);
            }
        });
        observer.observe(chatContainer, { childList: true });
    };
 
    function setupKeywordObserver() { /* ... bez zmian ... */
        if (observer) observer.disconnect();
        const chatContainer = document.querySelector('#chatroom-messages > div');
        if (!chatContainer) { stopSpamming(); return; }
        console.log("PEPEW SPAMMER: Tryb wyzwalacza słownego aktywny.");
        function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
        const keywords = keywordInput.value.toLowerCase().split('\n').map(k => k.trim()).filter(k => k);
        if (keywords.length === 0) {
            countdownDisplay.textContent = 'Brak słów kluczowych!'; stopSpamming(); return;
        }
        const keywordRegexes = keywords.map(k => ({ keyword: k, regex: new RegExp(`\\b${escapeRegExp(k)}\\b`, 'i') }));
        countdownDisplay.textContent = `Czuwanie na słowa...`;
        observer = new MutationObserver(mutations => {
            if (!running || mode !== 'keyword' || isSending) return;
            for (const mutation of mutations) {
                if (mutation.type === 'childList') {
                    for (const node of mutation.addedNodes) {
                        if (node.nodeType === 1) {
                            const usernameEl = node.querySelector('.chat-entry-username');
                            if (myUsername && usernameEl && usernameEl.textContent.trim().toLowerCase() === myUsername) continue;
                            const messageText = node.textContent.toLowerCase();
                            const foundMatch = keywordRegexes.find(item => item.regex.test(messageText));
                            if (foundMatch) {
                                isSending = true;
                                countdownDisplay.textContent = `Wyzwalacz: "${foundMatch.keyword}"`;
                                setTimeout(() => {
                                    const spamMsg = getRandomMessage();
                                    if (spamMsg && sendMessage(spamMsg)) { messageCount++; updateCounter(); }
                                    setTimeout(() => {
                                        if (running && mode === 'keyword') { countdownDisplay.textContent = `Czuwanie na słowa...`; }
                                        isSending = false;
                                    }, 2000);
                                }, 150);
                                return;
                            }
                        }
                    }
                }
            }
        });
        observer.observe(chatContainer, { childList: true });
    }
 
    const startSpamming = () => { /* ... bez zmian ... */
        if (running) return;
        running = true; startStopBtn.textContent = "Stop"; messageCount = 0; updateCounter();
        switch (mode) {
            case 'time':
                if (countdownInterval) clearInterval(countdownInterval);
                countdownInterval = setInterval(updateTimerCountdown, 100); spamLoopTime(); break;
            case 'chat': setupChatObserver(); break;
            case 'keyword': setupKeywordObserver(); break;
        }
    };
    const stopSpamming = () => { /* ... bez zmian ... */
        running = false; startStopBtn.textContent = "Start";
        if (timeoutId) clearTimeout(timeoutId); timeoutId = null;
        if (countdownInterval) clearInterval(countdownInterval); countdownInterval = null;
        if (observer) { observer.disconnect(); observer = null; console.log("PEPEW SPAMMER: Obserwator rozłączony."); }
        countdownDisplay.textContent = "Oczekuje na start...";
    };
 
    // === EVENT LISTENERS (BEZ ZMIAN W WIĘKSZOŚCI) ===
    startStopBtn.onclick = () => running ? stopSpamming() : startSpamming();
    selectedModeDiv.addEventListener('click', () => modeDropdownContainer.classList.toggle('open'));
    modeOptions.addEventListener('click', (e) => {
        if (e.target.tagName === 'LI') {
            const newMode = e.target.dataset.value;
            if (newMode !== mode) {
                if (running) stopSpamming();
                applyMode(newMode);
                saveSettings();
            }
            modeDropdownContainer.classList.remove('open');
        }
    });
    window.addEventListener('click', (e) => { if (!modeDropdownContainer.contains(e.target)) { modeDropdownContainer.classList.remove('open'); } });
    minSlider.oninput = () => { if (parseFloat(minSlider.value) > parseFloat(maxSlider.value)) maxSlider.value = minSlider.value; updateSlidersDisplay(); saveSettings(); };
    maxSlider.oninput = () => { if (parseFloat(maxSlider.value) < parseFloat(minSlider.value)) minSlider.value = maxSlider.value; updateSlidersDisplay(); saveSettings(); };
    msgCountInput.addEventListener('input', saveSettings);
    keywordInput.addEventListener('input', saveSettings);
    toggleMinimizeBtn.onclick = e => {
        e.stopPropagation(); panel.classList.toggle("minimized");
        toggleMinimizeBtn.textContent = panel.classList.contains("minimized") ? "+" : "−";
    };
    panel.addEventListener("click", () => {
        if (panel.classList.contains("minimized")) {
            panel.classList.remove("minimized");
            toggleMinimizeBtn.textContent = "−";
        }
    });
    let isDragging = false, dragStartX, dragStartY, startLeft, startTop;
    header.onmousedown = e => {
        if (e.target.closest('.custom-dropdown') || e.target === toggleMinimizeBtn) return;
        isDragging = true; dragStartX = e.clientX; dragStartY = e.clientY;
        const rect = panel.getBoundingClientRect(); startLeft = rect.left; startTop = rect.top;
        document.body.style.userSelect = "none";
    };
    document.onmousemove = e => {
        if (!isDragging) return;
        const newX = Math.max(0, Math.min(window.innerWidth - panel.offsetWidth, startLeft + (e.clientX - dragStartX)));
        const newY = Math.max(0, Math.min(window.innerHeight - panel.offsetHeight, startTop + (e.clientY - dragStartY)));
        panel.style.left = `${newX}px`; panel.style.top = `${newY}px`;
        panel.style.right = "auto"; panel.style.bottom = "auto";
    };
    document.onmouseup = () => {
        if (isDragging) { isDragging = false; document.body.style.userSelect = "auto"; saveSettings(); }
    };
 
    // Inicjalizacja skryptu
    getMyUsername();
    loadSettings();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址