NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==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(); }