// ==UserScript==
// @name Pixeldrain DL Bypass
// @namespace https://greasyfork.org/users/821661
// @version 1.0
// @description Adds direct-download buttons and links for Pixeldrain files using an alternate proxy — inspired by 'Pixeldrain Download Bypass' by hhoneeyy and MegaLime0
// @author hdyzen
// @match https://pixeldrain.com/*
// @match https://pixeldrain.net/*
// @icon https://www.google.com/s2/favicons?domain=pixeldrain.com/&sz=64
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @license GPL-3.0-only
// ==/UserScript==
const BYPASS_URL = "pd.1drv.eu.org";
function createElementWithListener(html, type, listener) {
const div = document.createElement("div");
div.style.setProperty("display", "contents", "important");
div.innerHTML = html;
div.addEventListener(type, listener);
return div;
}
function showModal(title, content) {
const MODAL_HTML = `
<div class="background svelte-1f8gt9n" style="z-index: 10001;" role="dialog">
<div class="window svelte-1f8gt9n" role="dialog" aria-modal="true">
<div class="header svelte-1f8gt9n">
<span class="title svelte-1f8gt9n" style="padding-inline: calc(2rem + 32px) 2rem;">${title}</span>
<button class="button svelte-1ef47mx round close-button">
<i class="icon">close</i>
</button>
</div>
<div class="body svelte-1f8gt9n" style="padding: 1rem;">
<div class="container svelte-1j8hfe6">
<div class="indent" style="display: flex; flex-direction: column;justify-content: center;align-items: center;">
${content}
</div>
</div>
</div>
</div>
</div>
`;
const modalElement = createElementWithListener(MODAL_HTML, "click", (event) => {
if (event.target.matches(".background") || event.target.closest(".close-button")) {
modalElement.remove();
}
});
document.body.insertAdjacentElement("afterbegin", modalElement);
}
function downloadFile(fileName, fileID, el) {
return new Promise((resolve, reject) => {
const url = `https://${BYPASS_URL}/${fileID}`;
GM_xmlhttpRequest({
url,
responseType: "blob",
onload(event) {
resolve(event);
if (event.status !== 200) {
showModal("Download error", "The server probably blocked this download.");
return;
}
const a = document.createElement("a");
a.target = "_blank";
a.href = URL.createObjectURL(event.response);
a.download = fileName;
a.click();
el.style.setProperty("--loaded", "0");
},
onerror(event) {
reject(event);
},
onprogress(event) {
el.style.setProperty("--loaded", `${(event.loaded * el.clientWidth) / event.total}px`);
},
});
});
}
async function massiveDownload(files, el) {
for (const file of files) {
try {
// console.log("Downloading:", file.name);
await downloadFile(file.name, file.id, el);
// console.log("Finished:", file.name);
} catch (error) {
console.error(`Failed to download ${file.name}:`, error);
showModal("Download error", `Failed to download ${file.name}.`);
}
}
}
function copyBypassURL(fileID) {
const url = `https://${BYPASS_URL}/${fileID}`;
navigator.clipboard
.writeText(url)
.then(() => showModal("URL copied", "The bypass URL has been copied to your clipboard."))
.catch(() => showModal("Copy failed", "Could not copy the URL. Please copy it manually."));
}
function handleSingleFile(separator, fileData) {
const { name, id } = fileData;
const downloadButtonHTML = `
<button class="toolbar_button svelte-jngqwx download-bypass" style="box-shadow: inset var(--highlight_background) var(--loaded, 0) 0;" title="Bypass download">
<i class="icon">download</i>
<span class="svelte-jngqwx">Download bypass</span>
</button>
`;
const copyButtonHTML = `
<button class="toolbar_button svelte-jngqwx" title="Copy bypass url">
<i class="icon">content_copy</i>
<span class="svelte-jngqwx">Copy bypass URL</span>
</button>
`;
const downloadButton = createElementWithListener(downloadButtonHTML, "click", () => downloadFile(name, id, downloadButton.firstElementChild));
const copyButton = createElementWithListener(copyButtonHTML, "click", () => copyBypassURL(id));
separator.insertAdjacentElement("afterend", downloadButton);
downloadButton.insertAdjacentElement("afterend", copyButton);
}
function handleFileList(separator, listData) {
const availableFiles = listData.files.filter((file) => file.availability === "");
const fileUrls = availableFiles.map((file) => `<a href="https://${BYPASS_URL}/${file.id}">${file.name}</a>`).join("<br>");
const dlSelectedButtonHTML = `
<button class="toolbar_button svelte-jngqwx" style="box-shadow: inset var(--highlight_background) var(--loaded, 0) 0;" title="Bypass download selected file">
<i class="icon">download</i>
<span class="svelte-jngqwx">Download selected file</span>
</button>
`;
const dlAllButtonHTML = `
<button class="toolbar_button svelte-jngqwx" style="box-shadow: inset var(--highlight_background) var(--loaded, 0) 0;" title="Bypass download all files">
<i class="icon">download</i>
<span class="svelte-jngqwx">Download all files</span>
</button>
`;
const showUrlsButtonHTML = `
<button class="toolbar_button svelte-jngqwx" title="Show bypass URLs">
<i class="icon">link</i>
<span class="svelte-jngqwx">Show bypass URLs</span>
</button>
`;
const dlAllButton = createElementWithListener(dlAllButtonHTML, "click", () => massiveDownload(availableFiles, dlAllButton.firstElementChild));
const showUrlsButton = createElementWithListener(showUrlsButtonHTML, "click", () => showModal("Bypass URLs", fileUrls));
const dlSelectedButton = createElementWithListener(dlSelectedButtonHTML, "click", () => {
const selectedFile = listData.files.find((file) => file.selected);
if (selectedFile.availability !== "") {
showModal(selectedFile.availability, selectedFile.availability_message);
return;
}
downloadFile(selectedFile.name, selectedFile.id, dlSelectedButton.firstElementChild);
});
separator.insertAdjacentElement("afterend", dlSelectedButton);
dlSelectedButton.insertAdjacentElement("afterend", dlAllButton);
dlAllButton.insertAdjacentElement("afterend", showUrlsButton);
}
function init() {
const VIEWER_DATA = unsafeWindow.viewer_data;
if (!VIEWER_DATA) {
console.warn("Viewer data not found. Script may not function correctly.");
return;
}
const separator = document.querySelector(".toolbar > .separator.svelte-jngqwx");
if (!separator) {
console.warn("Toolbar separator not found. Cannot add buttons.");
return;
}
GM_addStyle(`.file_preview_row:has(.gallery) [title="Bypass download selected file"] { display: none !important; }`);
switch (VIEWER_DATA.type) {
case "file":
handleSingleFile(separator, VIEWER_DATA.api_response);
break;
case "list":
handleFileList(separator, VIEWER_DATA.api_response);
break;
default:
console.warn(`File type "${VIEWER_DATA.type}" not supported.`);
}
}
init();