您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Upload images to the shoutbox by pasting or selecting a file (via Litterbox.catbox.moe - temporary hosting)
// ==UserScript== // @name Shoutbox Image Uploader // @version 7.0 // @description Upload images to the shoutbox by pasting or selecting a file (via Litterbox.catbox.moe - temporary hosting) // @author Sumbul⚡ // @match https://*.torrentbd.com/* // @match https://*.torrentbd.net/* // @match https://*.torrentbd.org/* // @match https://*.torrentbd.me/* // @icon https://s14.gifyu.com/images/bT3Pc.png // @grant GM_xmlhttpRequest // @run-at document-end // @namespace https://greasyfork.org/users/1511401 // ==/UserScript== (function() { 'use strict'; const UPLOAD_API_URL = 'https://litterbox.catbox.moe/resources/internals/api.php'; const EXPIRY = '24h'; // change to "1h", "12h", "72h" if needed const SHOUTBOX_INPUT_SELECTOR = '#shout_text'; const SHOUTBOX_TRAY_SELECTOR = '#shout-ibb-container'; function initializeUploader() { const shoutInput = document.querySelector(SHOUTBOX_INPUT_SELECTOR); const shoutTray = document.querySelector(SHOUTBOX_TRAY_SELECTOR); if (!shoutInput || !shoutTray || document.getElementById('tbd-uploader-button')) { return false; } const uploadImage = (imageFile, fileName) => { const originalText = shoutInput.value; shoutInput.value = '[Uploading to Litterbox...]'; shoutInput.disabled = true; const formData = new FormData(); formData.append('reqtype', 'fileupload'); formData.append('time', EXPIRY); formData.append('fileToUpload', imageFile, fileName); GM_xmlhttpRequest({ method: 'POST', url: UPLOAD_API_URL, data: formData, onload: (response) => { try { if (response.status !== 200) throw new Error(`HTTP Status ${response.status}`); const imageUrl = response.responseText.trim(); if (!imageUrl.startsWith('http')) throw new Error(`API returned an error: ${imageUrl}`); shoutInput.value = originalText + imageUrl + ' '; } catch (e) { shoutInput.value = `[Upload failed! ${e.message}]`; setTimeout(() => { shoutInput.value = originalText; }, 3000); } finally { shoutInput.disabled = false; shoutInput.focus(); } }, onerror: () => { shoutInput.value = `[Upload failed! Network error.]`; setTimeout(() => { shoutInput.value = originalText; }, 3000); shoutInput.disabled = false; shoutInput.focus(); } }); }; const handlePaste = (event) => { const items = (event.clipboardData || event.originalEvent.clipboardData).items; const imageFile = [...items].find(item => item.type.startsWith('image/'))?.getAsFile(); if (imageFile) { event.preventDefault(); uploadImage(imageFile, 'pasted_image.png'); } }; shoutInput.addEventListener('paste', handlePaste); const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.accept = 'image/*'; fileInput.style.display = 'none'; document.body.appendChild(fileInput); fileInput.addEventListener('change', (event) => { const file = event.target.files[0]; if (file) { uploadImage(file, file.name); } event.target.value = null; }); const uploaderButton = document.createElement('span'); uploaderButton.id = 'tbd-uploader-button'; uploaderButton.className = 'inline-submit-btn'; uploaderButton.title = 'Upload Image from File'; uploaderButton.innerHTML = '<i class="material-icons">add_photo_alternate</i>'; uploaderButton.style.cursor = 'pointer'; uploaderButton.addEventListener('click', () => fileInput.click()); const urlButton = shoutTray.querySelector('#urlBtn'); shoutTray.insertBefore(uploaderButton, urlButton || null); return true; } let attempts = 0; const interval = setInterval(() => { if (initializeUploader() || ++attempts > 60) { clearInterval(interval); } }, 250); })();