// ==UserScript==
// @name Real-Debrid Premium Link Converter
// @version 3.2
// @grant GM.xmlHttpRequest
// @namespace https://greasyfork.org/en/users/807108-jeremy-r
// @include https://*
// @description Convert standard links into premium links using Real-Debrid
// @icon https://icons.duckduckgo.com/ip2/real-debrid.com.ico
// @author JRem
// @license MIT
// ==/UserScript==
// https://real-debrid.com/apitoken
const authorization = '' // <- PUT YOUR BEARER AUTHENTICATION STRING INSIDE THE QUOTES - IMPORTANT!!!
// Can update domain list from https://api.real-debrid.com/rest/1.0/hosts/domains
// CORS prevent it from being dynamically grabbed
const targetURLs = ["1fichier.com","alterupload.com","cjoint.net","desfichiers.com","dfichiers.com","megadl.fr","mesfichiers.org","piecejointe.net","pjointe.com","tenvoi.com","dl4free.com","2shared.com","4shared.com","alfafile.net","anzfile.net","backin.net","bayfiles.com","bdupload.in","bdupload.asia","brupload.net","btafile.com","catshare.net","clicknupload.me","clicknupload.com","clicknupload.link","clicknupload.org","clicknupload.co","clicknupload.cc","clicknupload.click","clicknupload.xyz","clicknupload.online","clicknupload.download","clickndownload.org","clickndownload.space","clicknupload.space","clicknupload.click","clickndownload.link","clipwatching.com","highstream.tv","cosmobox.org","dailymotion.com","dailyuploads.net","daofile.com","datafilehost.com","ddownload.com","ddl.to","depositfiles.com","depositfiles.org","dfiles.eu","dfiles.ru","dl.free.fr","douploads.net","drop.download","dropapk.to","earn4files.com","easybytez.com","easybytez.eu","easybytez.me","ex-load.com","extmatrix.com","down.fast-down.com","fastclick.to","faststore.org","fikper.com","file.al","file4safe.com","fboom.me","filefactory.com","filefox.cc","filenext.com","filer.net","filerio.in","filerio.com","filesabc.com","filespace.com","filestore.me","file-up.org","fileupload.pw","filezip.cc","fireget.com","flashbit.cc","flashx.tv","flashx.ws","flashx.cc","flashx.bz","flashx.co","flashx.pw","florenfile.com","fshare.vn","gigapeta.com","goloady.com","docs.google.com","drive.google.com","gounlimited.to","heroupload.com","hexupload.net","hexload.com","hitfile.net","hitf.to","hitf.cc","htfl.net","hotlink.cc","hulkshare.com","icerbox.com","inclouddrive.com","isra.cloud","katfile.com","keep2share.cc","k2s.cc","keep2s.cc","k2share.cc","letsupload.cc","load.to","down.mdiaload.com","mediafire.com","mega.co.nz","mega.nz","mixdrop.co","mixdrop.club","mixdrop.sx","mixdrop.to","mdy48tn97.com","mixdrop.ag","mdfx9dc8n.net","mixdrop.cfd","mdzsmutpcvykb.net","mixdropjmk.pw","mixloads.com","mp4upload.com","nelion.me","ninjastream.to","nitroflare.com","nitro.download","nowvideo.club","nowvideo.pw","oboom.com","prefiles.com","sky.fm","radiotunes.com","di.fm","classicalradio.com","jazzradio.com","rapidgator.net","rg.to","rapidgator.asia","rapidrar.com","rapidu.net","rarefile.net","real-debrid.com","redbunker.net","redtube.com","rockfile.eu","rockfile.co","rutube.ru","scribd.com","sendit.cloud","sendspace.com","simfileshare.net","solidfiles.com","soundcloud.com","speed-down.org","4downfiles.org","streamon.to","streamtape.com","strcloud.link","strcloud.sx","adblockeronstreamtape.com","takefile.link","terabytez.org","tezfiles.com","thevideo.me","thevideo.io","tvad.me","thevideo.website","vev.io","turbobit.net","turbobit5.net","turbobita.net","turbobit.cc","turbo.to","turbobit.pw","turb.to","turb.cc","turbobif.com","tbit.to","tusfiles.com","tusfiles.net","ubiqfile.com","uloz.to","ulozto.net","ulozto.sk","ulozto.cz","pornfile.cz","zachowajto.pl","unibytes.com","uploadbox.io","uploadboy.com","uploadboy.me","uploadc.com","uploadc.ch","uploaded.net","uploaded.to","ul.to","uploadev.org","uploadgig.com","uploadrar.com","uppit.com","upstore.net","upstream.to","uptobox.com","uptobox.eu","uptobox.fr","uptostream.com","uptostream.eu","uptostream.fr","userscloud.com","usersdrive.com","vidcloud.ru","vidcloud.co","videobin.co","vidlox.tv","vidoza.net","vidoza.co","vidoza.org","vimeo.com","vivo.sx","vivo.st","vk.com","voe.sx","voe-unblock.com","voe-unblock.net","voeunblock.com","voeunblock1.com","voeunblock2.com","voeunbl0ck.com","voeunblck.com","voeunblk.com","voe-un-block.com","voeun-block.net","un-block-voe.net","v-o-e-unblock.com","audaciousdefaulthouse.com","launchreliantcleaverriver.com","reputationsheriffkennethsand.com","fittingcentermondaysunday.com","housecardsummerbutton.com","fraudclatterflyingcar.com","bigclatterhomesguideservice.com","uptodatefinishconferenceroom.com","20demidistance9elongations.com","wdupload.com","wipfiles.net","world-files.com","worldbytez.com","wupfile.com","salefiles.com","wushare.com","xubster.com","youporn.com","youtube.com","zippyshare.com"]
const processedURLs = new Set(); // Track processed URLs
// Check if the current URL contains any of the target URLs
function isTargetURL() {
const currentUrl = window.location.href;
return targetURLs.some(target => currentUrl.includes(target));
}
// Generate a regex pattern based on targetURLs
function generateUrlRegex() {
const domains = targetURLs.map(url => url.replace(/\./g, '\\.') + '[^\s"]*');
const pattern = `https:\\/\\/(?:${domains.join('|')})`;
return new RegExp(pattern, 'g');
}
function createFastDownloadButton(linkElement, fileURL) {
let button = document.createElement('button');
button.innerHTML = 'Send to RD';
button.style.marginLeft = '5px'; // Add space to the left of the button
button.style.padding = '2px 5px'; // Add space to the right of the button
button.style.backgroundColor = 'black'; // Set button background color to red
button.style.color = 'white'; // Optional: Set button text color to white for better contrast
button.style.borderRadius = '5px'; // Add rounded corners
button.onclick = () => {
GM.xmlHttpRequest({
method: 'POST',
url: 'https://app.real-debrid.com/rest/1.0/unrestrict/link',
headers: {
"authorization": `Bearer ${authorization}`
},
data: `link=${encodeURIComponent(fileURL)}&password=`,
onload: (response) => {
const jsonData = JSON.parse(response.responseText);
if (jsonData.download !== undefined) {
linkElement.href = jsonData.download;
linkElement.textContent = jsonData.filename;
} else {
linkElement.textContent += ' - failed';
}
button.remove();
}
});
};
linkElement.setAttribute('realdebrid', 'true');
linkElement.insertAdjacentElement('afterend', button);
}
function processTextNode(textNode) {
const textContent = textNode.textContent;
const urlRegex = generateUrlRegex();
let match;
while ((match = urlRegex.exec(textContent)) !== null) {
const url = match[0];
if (processedURLs.has(url)) {
continue; // Skip URLs that have already been processed
}
for (let targetURL of targetURLs) {
if (url.includes(targetURL)) {
const linkElement = document.createElement('a');
linkElement.href = url;
linkElement.textContent = url;
linkElement.style.display = 'block'; // Ensure each link appears on a new line
textNode.parentNode.insertBefore(linkElement, textNode);
createFastDownloadButton(linkElement, url);
processedURLs.add(url); // Mark URL as processed
}
}
}
}
function processPreElements() {
let preElements = document.getElementsByTagName('pre');
for (let i = 0; i < preElements.length; i++) {
let preElement = preElements[i];
let textNodes = Array.from(preElement.childNodes).filter(node => node.nodeType === Node.TEXT_NODE);
textNodes.forEach(node => processTextNode(node));
}
}
function observeLinks() {
if (!isTargetURL()) {
// Process anchor tags
let links = document.getElementsByTagName('a');
for (let i = 0; i < links.length; i++) {
let link = links[i];
if (link.getAttribute('realdebrid')) {
continue;
}
for (let targetURL of targetURLs) {
if (link.href.includes(targetURL) && !processedURLs.has(link.href)) {
createFastDownloadButton(link, link.href);
processedURLs.add(link.href); // Mark URL as processed
}
}
}
// Process text nodes in <pre> elements
processPreElements();
// Process text nodes in the rest of the document
const iterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
let node;
while ((node = iterator.nextNode())) {
if (node.parentNode.tagName !== 'PRE' && !node.parentNode.querySelector('a[realdebrid]')) { // Skip nodes with processed children
processTextNode(node);
}
}
}}
// Debounce function to limit how often observeLinks is called
function debounce(func, wait) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
// Observe the document body for changes
const observer = new MutationObserver(debounce(observeLinks, 500));
observer.observe(document.body, { childList: true, subtree: true });
// Also observe the links when the page first loads
window.onload = observeLinks;