G00DB0Y / Multifunctional box(Adult Private Tracker)

// ==UserScript==
// @name         Multifunctional box(Adult Private Tracker)
// @namespace    http://tampermonkey.net/
// @version      3.7
// @description  Adds a comment box with fixed phrases, navigation buttons, and a copy button. Remembers its position and includes a centered Add Comment button. Includes license verification and fallback navigation to browser history if no previous torrent is found. Adds a fixed title between navigation buttons.
// @author       NiGHTCUM
// @license      MIT
// @match        https://www.happyfappy.org/torrents.php?id=*
// @match        https://pornbay.org/torrents.php?id=*
// @match        https://femdomcult.org/torrents.php?id=*
// @match        https://kufirc.com/torrents.php?id=*
// @match        https://www.homeporntorrents.club/torrents.php?id=*
// @match        https://www.empornium.is/torrents.php?id=*
// @match        https://www.empornium.sx/torrents.php?id=*
// @match        https://lusthive.org/torrents.php?id=*
// @match        https://www.happyfappy.org/upload.php
// @match        https://pornbay.org/upload.php
// @match        https://femdomcult.org/upload.php
// @match        https://kufirc.com/upload.php
// @match        https://www.homeporntorrents.club/upload.php
// @match        https://www.empornium.is/upload.php
// @match        https://www.empornium.sx/upload.php
// @match        https://lusthive.org/upload.php
// @grant        none
// ==/UserScript==

'use strict';

// Global notification function
const showNotification = message => {
    let notification = document.getElementById('notification');
    if (!notification) {
        notification = Object.assign(document.createElement('div'), {
            id: 'notification',
            innerText: message,
            style: 'position: fixed; top: 20px; right: 20px; background-color: #4CAF50; color: #fff; padding: 10px 15px; border-radius: 5px; font-size: 14px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); z-index: 10000; display: none;'
        });
        document.body.appendChild(notification);
    }
    notification.innerText = message;
    notification.style.display = 'block';
    setTimeout(() => notification.style.display = 'none', 1000);
};

// Check page type
const isTorrentPage = window.location.href.includes('torrents.php?id=');
const isUploadPage = window.location.href.includes('/upload.php');

// Function to wait for the target element to appear
const waitForElement = (selector, timeout = 3000) => {
    return new Promise((resolve, reject) => {
        const interval = 100;
        let elapsed = 0;
        const check = () => {
            const element = document.querySelector(selector);
            if (element) {
                resolve(element);
            } else if (elapsed >= timeout) {
                reject(`Element with selector "${selector}" not found`);
            } else {
                elapsed += interval;
                setTimeout(check, interval);
            }
        };
        check();
    });
};

// Show comment box and copy button on torrent page
if (isTorrentPage) {
    const STORED_HASH = 'e077e74c96c4de1fc7b8be2f0d3cb396ecc9c13e030d8b93ec0df84483a0de79';
    const isLicensed = localStorage.getItem('isLicensed');
    const phrases = ['Great Upload', 'Hot & Sexy', 'Jav is real deal', 'Thank You'];

    const styles = `
    #comment-box { position: fixed; top: 20px; right: 20px; width: 200px; height: 150px; min-width: 150px; min-height: 150px; background-color: #333; border: 1px solid #555; border-radius: 8px; padding: 10px; box-shadow: 0 6px 12px rgba(0,0,0,0.1); z-index: 9999; transition: box-shadow 0.3s; font-family: Arial, sans-serif; overflow: hidden; color: #e0e0e0; }
    #comment-box:hover { box-shadow: 0 8px 16px rgba(0,0,0,0.15); }
    #navigation-buttons { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 10px; }
    .nav-button, #add-comment-btn { background-color: #4CAF50; color: #fff; border: none; border-radius: 5px; padding: 5px; cursor: pointer; font-size: 12px; transition: background-color 0.3s; }
    .nav-button:hover, #add-comment-btn:hover { background-color: #45a049; }
    .nav-button:active { transform: scale(1.3); background-color: #388E3C; box-shadow: 0 4px 8px rgba(0,0,0,0.2); }
    #custom-comment-input { width: 100%; padding: 7px; margin: 5px 0; border: 1px solid #555; border-radius: 5px; font-size: 12px; background-color: #444; color: #e0e0e0; transition: border-color 0.3s; }
    #custom-comment-input:focus { border-color: #fff; }
    .comment { cursor: pointer; padding: 8px; margin: 5px 0; background-color: #444; border: 1px solid #555; border-radius: 5px; text-align: center; font-size: 12px; transition: background-color 0.3s; }
    .comment:hover { background-color: #555; }
    #resize-handle { position: absolute; bottom: 0; right: 0; width: 15px; height: 15px; background-color: #555; cursor: se-resize; border-top: 1px solid #666; border-left: 1px solid #666; border-bottom-right-radius: 4px; }
    #notification { position: fixed; top: 20px; right: 20px; background-color: #4CAF50; color: #fff; padding: 10px 15px; border-radius: 5px; font-size: 14px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); z-index: 10000; display: none; }
    #add-comment-btn { width: 100%; margin-top: 5px; }
    #fixed-title { color: #fff; font-weight: bold; margin: 0; flex-grow: 1; text-align: center; background: linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet); background-size: 300% 100%; -webkit-background-clip: text; color: transparent; animation: smoothRainbow 10s ease-in-out infinite; }
    .copy-button { margin-right: 10px; padding: 5px 10px; background-color: #4CAF50; color: #fff; border: none; border-radius: 5px; cursor: pointer; font-size: 12px; transition: background-color 0.3s; float: left; }
    .copy-button:hover { background-color: #45a049; }
    .copy-button:active { background-color: #388E3C; }
    @keyframes smoothRainbow { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; }
    `;

    document.head.appendChild(Object.assign(document.createElement('style'), { type: 'text/css', innerText: styles }));

    // Comment box elements
    const commentBox = Object.assign(document.createElement('div'), { id: 'comment-box' });
    const navContainer = Object.assign(document.createElement('div'), { id: 'navigation-buttons' });
    const customInput = Object.assign(document.createElement('input'), { id: 'custom-comment-input', placeholder: 'Enter your custom comment' });
    const addCommentButton = Object.assign(document.createElement('button'), { id: 'add-comment-btn', innerText: 'Add Comment' });
    const commentsContainer = Object.assign(document.createElement('div'), { style: 'overflow-y: auto; max-height: calc(100% - 100px);' });
    const resizeHandle = Object.assign(document.createElement('div'), { id: 'resize-handle' });
    const notification = Object.assign(document.createElement('div'), { id: 'notification', innerText: 'Comment added' });
    const fixedTitle = Object.assign(document.createElement('span'), { id: 'fixed-title', innerText: 'NiGHTCUM' });

    document.body.append(commentBox, notification);
    commentBox.append(navContainer, customInput, addCommentButton, commentsContainer, resizeHandle);
    navContainer.append(
        Object.assign(document.createElement('button'), { className: 'nav-button', innerText: '<', onclick: () => { const link = document.querySelector('a[title="goto previous torrent"], a[alt="prev"][title="goto previous torrent"]'); link ? (window.location.href = link.href) : window.history.back(); } }),
        Object.assign(document.createElement('span'), { id: 'fixed-title', innerText: 'NiGHTCUM' }),
        Object.assign(document.createElement('button'), { className: 'nav-button', innerText: '>', onclick: () => { const link = document.querySelector('a[title="goto next torrent"], a[alt="next"][title="goto next torrent"]'); link ? (window.location.href = link.href) : alert('No next torrent found'); } })
    );

    if (!isLicensed) {
        const verifyLicense = async () => {
            const enteredHash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(prompt('Please enter the secret code to use this script:'))).then(b => Array.from(new Uint8Array(b)).map(x => x.toString(16).padStart(2, '0')).join(''));
            return enteredHash === STORED_HASH ? (localStorage.setItem('isLicensed', 'true'), true) : (alert('Incorrect code. You cannot use this script.'), false);
        };
        if (!await verifyLicense()) return;
    }

    addCommentButton.onclick = () => customInput.value.trim() && addCommentToPostField(customInput.value.trim());

    const addCommentToPostField = comment => {
        const commentField = document.querySelector('textarea#quickpost[name="body"]');
        commentField ? (commentField.value += (commentField.value ? '\n' : '') + comment, commentField.focus(), showNotification('Comment added')) : setTimeout(() => addCommentToPostField(comment), 500);
    };

    const savePosition = () => {
        localStorage.setItem('boxTop', commentBox.offsetTop);
        localStorage.setItem('boxLeft', commentBox.offsetLeft);
    };

    const makeDraggable = element => {
        let [posX, posY, mouseX, mouseY] = [0, 0, 0, 0];
        element.addEventListener('mousedown', e => {
            if (e.target !== element) return;
            [mouseX, mouseY] = [e.clientX, e.clientY];
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', () => { document.removeEventListener('mousemove', onMouseMove); savePosition(); });
        });
        const onMouseMove = e => {
            [posX, posY] = [mouseX - e.clientX, mouseY - e.clientY];
            [mouseX, mouseY] = [e.clientX, e.clientY];
            Object.assign(element.style, { top: (element.offsetTop - posY) + 'px', left: (element.offsetLeft - posX) + 'px' });
        };
    };

    const makeResizable = (element, handle) => {
        handle.addEventListener('mousedown', e => {
            document.addEventListener('mousemove', resize);
            document.addEventListener('mouseup', () => document.removeEventListener('mousemove', resize));
        });
        const resize = e => {
            Object.assign(element.style, { width: (e.clientX - element.offsetLeft) + 'px', height: (e.clientY - element.offsetTop) + 'px' });
            localStorage.setItem('boxWidth', element.offsetWidth);
            localStorage.setItem('boxHeight', element.offsetHeight);
        };
    };

    makeDraggable(commentBox);
    makeResizable(commentBox, resizeHandle);

// Modify the existing code for adding comments to the comment box
phrases.forEach(comment => {
    const commentElement = Object.assign(document.createElement('div'), { className: 'comment', innerText: comment });

    // Check if the comment is "Thank You"
    if (comment === 'Thank You') {
        commentElement.onclick = () => addCommentToPostField('[img]https://images2.imgbox.com/b0/04/XBNJByov_o.png[/img]');
    } else {
        // Default behavior for other comments
        commentElement.onclick = () => addCommentToPostField(comment);
    }

    commentsContainer.appendChild(commentElement);
});

    ['boxWidth', 'boxHeight'].forEach(prop => {
        const saved = localStorage.getItem(prop);
        if (saved) commentBox.style[prop.replace('box', '').toLowerCase()] = saved + 'px';
    });

    ['boxTop', 'boxLeft'].forEach(prop => {
        const saved = localStorage.getItem(prop);
        if (saved) commentBox.style[prop.replace('box', '').toLowerCase()] = saved + 'px';
    });

    const savedCustomComment = localStorage.getItem('customComment');
    if (savedCustomComment) customInput.value = savedCustomComment;

    customInput.addEventListener('input', () => localStorage.setItem('customComment', customInput.value));

// Function to add a copy button to the torrent page
function addCopyButtonToTorrentPage() {
    const reportElement = document.querySelector('[title="Report"]'); // The element to the right of which we want to place the button
    const titleElement = document.querySelector('h1'); // Assuming the title is in an <h1> tag, change selector if needed
    const specialElement = document.querySelector('[title="Add this torrent to the speed records torrent watchlist"]'); // Special element for HappyFappy
    const isHappyFappy = window.location.href.includes('happyfappy'); // Check if current page is HappyFappy

    if (reportElement && titleElement) {
        // Get the computed style of the report element
        const reportElementHeight = window.getComputedStyle(reportElement).height;

        // Create the copy button
        const copyButton = Object.assign(document.createElement('button'), {
            innerText: 'Copy Title',
            style: `
                height: auto; /* Allow height to adjust based on content */
                min-height: ${reportElementHeight}; /* Set a minimum height to match the report element */
                background-color: #4CAF50; /* Green background */
                color: #fff; /* White text */
                border: none; /* Remove border */
                border-radius: 5px; /* Rounded corners */
                cursor: pointer; /* Pointer cursor on hover */
                transition: transform 0.1s ease-in-out; /* Animation on click */
                margin-left: 10px; /* Add some space from the report element */
                display: inline-flex; /* Align items in the center */
                align-items: center; /* Vertically center text */
                justify-content: center; /* Horizontally center text */
                box-sizing: border-box; /* Include padding and border in the element's width and height */
                padding: 5 15px; /* Horizontal padding to ensure background covers the text */
                font-size: 14px; /* Set font size */
                text-align: center; /* Center the text */
                line-height: 1.3; /* Ensure the background covers the text */
                white-space: nowrap; /* Prevent the button text from wrapping */
            `
        });

        // Event listeners for the button
        copyButton.addEventListener('click', () => {
            // Get the document title
            const fullTitle = document.title;
            // Split the title and remove any suffix/prefix after "::"
            const mainTitle = fullTitle.split('::')[0].trim(); // Change the delimiter if needed
            if (mainTitle) {
                navigator.clipboard.writeText(mainTitle).then(() => {
                    showNotification('Title copied');
                }).catch(err => {
                    console.error('Could not copy Title: ', err);
                });
            }
        });

        copyButton.addEventListener('mousedown', () => copyButton.style.transform = 'translateY(2px)');
        copyButton.addEventListener('mouseup', () => copyButton.style.transform = 'translateY(0)');
        copyButton.addEventListener('mouseleave', () => copyButton.style.transform = 'translateY(0)');

        // Insert the button next to the appropriate element based on the site condition
        if (isHappyFappy && specialElement) {
            specialElement.parentNode.insertBefore(copyButton, specialElement.nextSibling);
        } else {
            reportElement.parentNode.insertBefore(copyButton, reportElement.nextSibling);
        }

        console.log('Copy button added successfully to torrent page.');
    } else {
        console.error('Report element or title element not found.');
    }
}

addCopyButtonToTorrentPage();



}

// Add "Copy" and "Fix" buttons on upload page
if (isUploadPage) {
    function addCopyButton() {
        const announceInput = document.querySelector("input[type='text'][value*='announce']");
        if (announceInput) {
            console.log('Announce input box found:', announceInput);

            const copyButton = Object.assign(document.createElement('button'), {
                innerText: 'Copy',
                style: 'margin-left: 10px; padding: 5px; background-color: #4CAF50; color: #fff; border: none; border-radius: 5px; cursor: pointer; transition: transform 0.1s ease-in-out;'
            });

            copyButton.addEventListener('click', () => {
                const announceUrl = announceInput.value.trim();
                if (announceUrl) {
                    navigator.clipboard.writeText(announceUrl).then(() => {
                        showNotification('Announce URL copied');
                    }).catch(err => {
                        console.error('Could not copy text: ', err);
                    });
                }
            });

            copyButton.addEventListener('mousedown', () => copyButton.style.transform = 'translateY(2px)');
            copyButton.addEventListener('mouseup', () => copyButton.style.transform = 'translateY(0)');
            copyButton.addEventListener('mouseleave', () => copyButton.style.transform = 'translateY(0)');

            announceInput.parentNode.insertBefore(copyButton, announceInput.nextSibling);
            console.log('Copy button added successfully.');
        } else {
            console.error('Announce input box not found.');
        }
    }

// Ensure the script runs on the correct page
(function() {
    if (!/kufric\.com\/upload\.php/.test(window.location.href)) {
        console.log('Script not running on the Kufric upload page.');
        return;
    }

    console.log('Script is running on the Kufric upload page.');

    addFixButton();
})();

function addFixButton() {
    console.log('Attempting to add the Fix button.');

    // Check for the specific text node on the Kufric page
    const textNodes = Array.from(document.querySelectorAll('*')).flatMap(el =>
        Array.from(el.childNodes).filter(node => node.nodeType === 3 && node.nodeValue.includes('Enter the full URL of the image.'))
    );

    if (textNodes.length) {
        console.log('Target text node found on Kufric page, adding Fix button next to the text node.');
        insertFixButton(textNodes[0]);
    } else {
        console.warn('Text node not found. Trying to add the Fix button near the image URL input field.');
        const imageInput = document.getElementById('image');
        if (imageInput) {
            insertFixButton(imageInput.parentNode);
        } else {
            console.error('Image URL input field not found.');
        }
    }
}

function insertFixButton(targetElement) {
    const fixButton = Object.assign(document.createElement('button'), {
        innerText: 'Fix',
        id: 'customFixButton', // Add a unique ID to the button
        style: `
            height: auto; min-height: 30px; background-color: #f44336; color: #fff;
            border: none; border-radius: 5px; cursor: pointer; transition: transform 0.1s ease-in-out;
            margin-left: 10px; display: inline-flex; align-items: center; justify-content: center;
            box-sizing: border-box; padding: 0 10px; font-size: 14px; text-align: center; line-height: 1;`
    });

    fixButton.addEventListener('click', (e) => {
        e.stopPropagation();
        e.preventDefault();
        handleFixButtonClick();
    });

    ['mousedown', 'mouseup', 'mouseleave'].forEach(event =>
        fixButton.addEventListener(event, () => fixButton.style.transform = event === 'mousedown' ? 'translateY(2px)' : 'translateY(0)')
    );

    targetElement.appendChild(fixButton); // Append the button to the target element
    console.log('Fix button added successfully.');

    // Monitor changes to the button text and revert if changed
    const observer = new MutationObserver(() => {
        if (fixButton.innerText !== 'Fix') {
            console.warn(`Button text changed to "${fixButton.innerText}", reverting to "Fix".`);
            fixButton.innerText = 'Fix';
        }
    });

    observer.observe(fixButton, { childList: true });
}

function handleFixButtonClick() {
    const imageURLInput = document.getElementById('image');
    if (imageURLInput) {
        let imageURL = imageURLInput.value.trim();
        console.log('Image URL input value:', imageURL);

        if (!imageURL) {
            showNotification('No Image URL Found', 'red');
        } else if (isValidImageURL(imageURL)) {
            imageURL = removeBBCode(imageURL);
            imageURLInput.value = imageURL;
            showNotification('Image URL Fixed', '#4CAF50');
            console.log('Direct image URL:', imageURL);
        } else {
            showNotification('Invalid Image URL. Must contain jpg, jpeg, png, gif, tiff, bmp', 'red');
        }
    } else {
        console.error('Image input field not found.');
        showNotification('Image URL input field not found', 'red');
    }
}

function isValidImageURL(url) {
    return /(jpg|jpeg|png|gif|tiff|bmp)/i.test(url);
}

function removeBBCode(url) {
    const match = url.match(/\[IMG\](.*?)\[\/IMG\]/i);
    return match ? match[1] : url;
}

function showNotification(message, backgroundColor = '#4CAF50') {
    let notification = document.getElementById('notification');
    if (!notification) {
        notification = Object.assign(document.createElement('div'), {
            id: 'notification',
            style: `
                position: fixed; top: 20px; right: 20px; color: #fff; padding: 10px 15px;
                border-radius: 5px; font-size: 14px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); z-index: 10000; display: none;`
        });
        document.body.appendChild(notification);
    }
    notification.innerText = message;
    notification.style.backgroundColor = backgroundColor;
    notification.style.display = 'block';
    setTimeout(() => notification.style.display = 'none', 2000);
}

addFixButton();
    addCopyButton();
}