Greasy Fork is available in English.
Bypass FileCrypt
// ==UserScript==// @name Bypass FileCrypt (New)// @namespace Bhunter// @version 1.0.3// @description Bypass FileCrypt// @author Bhunter// @license MIT// @match http://filecrypt.cc/*// @match http://www.filecrypt.cc/*// @match http://filecrypt.co/*// @match http://www.filecrypt.co/*// @match https://filecrypt.cc/*// @match https://www.filecrypt.cc/*// @match https://filecrypt.co/*// @match https://www.filecrypt.co/*// @run-at document-end// @connect dcrypt.it// @connect self// @grant GM.xmlHttpRequest// ==/UserScript==(function() {'use strict';// Determine if dark theme is usedconst isDarkTheme = document.head.querySelector('meta[name="theme-color"]') !== null ||document.body.classList.contains('dark') ||window.getComputedStyle(document.body).backgroundColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)/)?.[1] < 100;// Add stylesheet to documentaddStylesheet(isDarkTheme);// Remove adsremoveAds();// Apply main functionality based on URLif (document.location.href.includes("/Link/")) {processSingleLink();} else if (document.location.href.includes("/Container/")) {waitForCaptchaSolved();}})();// Add stylesheet to documentfunction addStylesheet(isDarkTheme) {const style = document.createElement('style');// Define the colors based on themeconst colors = isDarkTheme ? {background: '#1e1e2e',text: '#cdd6f4',accent: '#cba6f7',border: '#313244',itemBg: '#181825',itemHover: '#11111b',actionBg: '#45475a',actionText: '#cdd6f4'} : {background: '#ffffff',text: '#333333',accent: '#4f46e5',border: '#e5e7eb',itemBg: '#f9fafb',itemHover: '#f3f4f6',actionBg: '#e0e7ff',actionText: '#4f46e5'};// Stylesheet contentstyle.textContent = `/* Main container */.fc-container {background-color: ${colors.background};color: ${colors.text};border: 1px solid ${colors.border};border-radius: 12px;box-shadow: 0 10px 15px -3px ${isDarkTheme ? 'rgba(0, 0, 0, 0.4)' : 'rgba(0, 0, 0, 0.1)'};max-width: 560px;margin: 40px auto 30px;overflow: hidden;font-size: 14px;line-height: 1.5;position: relative;z-index: 10;}/* Header */.fc-header {padding: 14px 18px;border-bottom: 1px solid ${colors.border};display: flex;justify-content: space-between;align-items: center;}.fc-title {margin: 0;font-weight: 600;font-size: 16px;}.fc-counter {padding: 4px 10px;border-radius: 20px;font-size: 12px;background-color: ${colors.actionBg};color: ${colors.actionText};}/* Content area */.fc-content {max-height: 250px;overflow-y: auto;padding: 4px 0;scrollbar-width: thin;scrollbar-color: ${colors.border} transparent;}.fc-content::-webkit-scrollbar {width: 6px;}.fc-content::-webkit-scrollbar-track {background: transparent;}.fc-content::-webkit-scrollbar-thumb {background-color: ${colors.border};border-radius: 3px;}/* Loading */.fc-loading {padding: 16px;text-align: center;}.fc-loading p {margin-top: 12px;font-size: 14px;}.fc-spinner {animation: fc-rotate 2s linear infinite;}.fc-spinner-path {stroke-dasharray: 1, 200;stroke-dashoffset: 0;animation: fc-dash 1.5s ease-in-out infinite;stroke: ${colors.accent};}@keyframes fc-rotate {100% {transform: rotate(360deg);}}@keyframes fc-dash {0% {stroke-dasharray: 1, 200;stroke-dashoffset: 0;}50% {stroke-dasharray: 89, 200;stroke-dashoffset: -35px;}100% {stroke-dasharray: 89, 200;stroke-dashoffset: -124px;}}/* Domain headers */.fc-domain-header {padding: 6px 16px;font-size: 13px;font-weight: 500;color: ${colors.accent};display: flex;align-items: center;gap: 6px;}.fc-domain-header:not(:first-child) {margin-top: 10px;}.fc-domain-count {background-color: ${colors.actionBg};border-radius: 10px;padding: 1px 6px;font-size: 11px;}/* Link items */.fc-link-item {padding: 8px 16px;margin: 4px 0;display: flex;align-items: center;gap: 10px;border-radius: 4px;transition: background-color 0.2s;cursor: pointer;}.fc-link-item:hover {background-color: ${colors.itemHover};}.fc-link-text {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;flex: 1;font-size: 14px;color: white !important;opacity: 0.9;}/* Copy button */.fc-copy-btn {width: 28px;height: 28px;min-width: 28px;background-color: transparent;color: ${colors.accent};border: none;border-radius: 50%;display: flex;align-items: center;justify-content: center;cursor: pointer;padding: 0;transition: background-color 0.2s;margin: 0;}.fc-copy-btn:hover {background-color: ${colors.actionBg};}/* Footer */.fc-footer {padding: 12px 16px;border-top: 1px solid ${colors.border};display: flex;justify-content: space-between;align-items: center;}.fc-info-text {opacity: 0.7;font-size: 12px;}.fc-copy-all {padding: 8px 12px;background-color: ${colors.accent};color: white;border: none;border-radius: 6px;cursor: pointer;font-size: 14px;transition: all 0.2s ease;}.fc-copy-all:disabled {opacity: 0.5;cursor: not-allowed;}.fc-copy-all:hover:not(:disabled) {filter: brightness(1.1);}`;document.head.appendChild(style);}// Remove adsfunction removeAds() {const usenetAds = document.querySelectorAll('a[href*="/pink/"]');for (const ad of usenetAds) {if (ad.parentNode) {ad.parentNode.remove();}}}// Check if captcha is solved by looking for download buttonsfunction waitForCaptchaSolved() {// Function to check if captcha is solved based on visible elementsfunction isCaptchaSolved() {// Look for download buttons or elements that appear after captchareturn document.querySelectorAll('.dlcdownload').length > 0;}// If captcha is already solved, proceed immediatelyif (isCaptchaSolved()) {processContainerPage();return;}// Otherwise, wait for captcha to be solvedconst captchaObserver = new MutationObserver((mutations, observer) => {if (isCaptchaSolved()) {observer.disconnect();processContainerPage();}});captchaObserver.observe(document.body, {childList: true,subtree: true});}// Process single link pageasync function processSingleLink() {if (document.body.getElementsByTagName("SCRIPT").length === 0) {window.stop();let htmlContent = document.body.innerHTML;if (!htmlContent || document.body.children.length === 0) {try {const response = await fetch(document.location.href);htmlContent = await response.text();} catch (error) {console.error("Failed to fetch page content:", error);return;}}const httpIndex = htmlContent.lastIndexOf("http");if (httpIndex !== -1) {const endIndex = htmlContent.indexOf('id=', httpIndex) + 43;let finalUrl = htmlContent.substring(httpIndex, endIndex).replace(/&/g, '&');window.location.href = finalUrl;}}}// Process container pagefunction processContainerPage() {// Find the best container to insert our link boxconst containerSection = findBestContainer();// Create container elementsconst { container, content, counter, copyAllBtn } = createLinkBox();// Insert the box at the appropriate locationcontainerSection.insertBefore(container, containerSection.firstChild);// Try to get DLC fileconst dlcButtons = document.getElementsByClassName("dlcdownload");if (dlcButtons.length > 0) {const dlcId = dlcButtons[0].getAttribute("onclick")?.split("'")[1];if (dlcId) {fetchDlcAndDecrypt(dlcId, { content, counter, copyAllBtn });return;}}// Fall back to manual link extractionextractLinks({ content, counter, copyAllBtn });}// Find the best container for inserting our boxfunction findBestContainer() {// Try various selectors in order of preferenceconst selectors = ['.content .window','.download','.content','main','article','.container','#container'];for (const selector of selectors) {const element = document.querySelector(selector);if (element) {return element;}}// Fallback to body if no suitable container foundreturn document.body;}// Create DOM structure for the link boxfunction createLinkBox() {// Create containerconst container = document.createElement("div");container.className = "fc-container";// Create headerconst header = document.createElement("div");header.className = "fc-header";const title = document.createElement("h3");title.className = "fc-title";title.innerHTML = "🔓 Decrypted Links";const counter = document.createElement("span");counter.className = "fc-counter";counter.id = "fc-counter";counter.textContent = "Loading...";header.appendChild(title);header.appendChild(counter);container.appendChild(header);// Create content areaconst content = document.createElement("div");content.className = "fc-content";content.id = "fc-content";// Add loading animationconst loadingDiv = document.createElement("div");loadingDiv.className = "fc-loading";loadingDiv.id = "fc-loading";loadingDiv.innerHTML = `<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><circle class="fc-spinner fc-spinner-path" cx="12" cy="12" r="10" fill="none" stroke-width="2" /></svg><p>Decrypting links...</p>`;content.appendChild(loadingDiv);container.appendChild(content);// Create footerconst footer = document.createElement("div");footer.className = "fc-footer";// Add info textconst infoText = document.createElement("small");infoText.className = "fc-info-text";infoText.textContent = "Click link to open, or use copy button";// Add copy all buttonconst copyAllBtn = document.createElement("button");copyAllBtn.className = " fc-copy-all";copyAllBtn.id = "fc-copy-all";copyAllBtn.textContent = "Copy All";copyAllBtn.disabled = true;footer.appendChild(infoText);footer.appendChild(copyAllBtn);container.appendChild(footer);return { container, content, counter, copyAllBtn };}// Fetch DLC file and decrypt itasync function fetchDlcAndDecrypt(dlcId, elements) {try {// Update the loading messageconst loadingDiv = document.getElementById("fc-loading");const loadingText = loadingDiv.querySelector("p");loadingText.textContent = "Fetching DLC file...";// Fetch the DLC fileconst response = await fetch(`https://${document.location.hostname}/DLC/${dlcId}.dlc`);if (!response.ok) throw new Error('Failed to fetch DLC file');const dlcContent = await response.text();loadingText.textContent = "Decrypting links via dcrypt.it...";// Use GM.xmlHttpRequest for dcrypt.it (since it may require CORS handling)GM.xmlHttpRequest({method: "POST",url: "http://dcrypt.it/decrypt/paste",headers: {"Content-Type": "application/x-www-form-urlencoded"},data: "content=" + encodeURIComponent(dlcContent),onload: function(response) {try {const r###lt = JSON.parse(response.response);if (r###lt.success && r###lt.success.links && r###lt.success.links.length > 0) {displayLinks(r###lt.success.links, elements);} else {throw new Error("No links were found in the dcrypt.it response");}} catch (error) {console.error("Error parsing dcrypt.it response:", error);extractLinks(elements);}},onerror: function() {console.error("Error connecting to dcrypt.it");extractLinks(elements);}});} catch (error) {console.error("Error fetching DLC:", error);extractLinks(elements);}}// Extract links directly from pagefunction extractLinks(elements) {const loadingDiv = document.getElementById("fc-loading");const loadingText = loadingDiv.querySelector("p");loadingText.textContent = "Extracting links directly...";const encLinks = document.querySelectorAll("[onclick^=openLink]");if (encLinks.length === 0) {showError("No links found on this page.");return;}// Update counter to show progresselements.counter.textContent = `0/${encLinks.length}`;let completedLinks = 0;const validLinks = [];// Process each link with a small delay between requests to avoid overloadingconst processLink = (index) => {if (index >= encLinks.length) {if (validLinks.length > 0) {displayLinks(validLinks, elements);} else {showError("Failed to extract any valid links.");}return;}const link = encLinks[index];const onclick = link.getAttribute("onclick");const encParam = onclick.split("'")[1];const encValue = link.getAttribute(encParam);const linkUrl = `http://${document.location.hostname}/Link/${encValue}.html`;fetchFinalLink(linkUrl).then(finalLink => {completedLinks++;elements.counter.textContent = `${completedLinks}/${encLinks.length}`;if (finalLink) {validLinks.push(finalLink);}// Process next link with a small delaysetTimeout(() => processLink(index + 1), 100);}).catch(() => {completedLinks++;elements.counter.textContent = `${completedLinks}/${encLinks.length}`;setTimeout(() => processLink(index + 1), 100);});};// Start processing linksprocessLink(0);}// Show error messagefunction showError(message) {const loadingDiv = document.getElementById("fc-loading");loadingDiv.innerHTML = `<div style="color:var(--fc-accent,#4f46e5);font-size:24px;margin-bottom:10px">❌</div><p style="margin:0">${message}</p>`;const counter = document.getElementById("fc-counter");if (counter) counter.textContent = "Error";}// Fetch a single link's destinationasync function fetchFinalLink(url) {try {const response = await fetch(url);if (!response.ok) return null;const html = await response.text();const parser = new DOMParser();const doc = parser.parseFromString(html, "text/html");// Try to find the redirect URL in scriptsconst scripts = doc.querySelectorAll("script");for (const script of scripts) {if (script.textContent.includes("top.location.href=")) {const matches = script.textContent.match(/top\.location\.href\s*=\s*['"]([^'"]+)['"]/);if (matches && matches[1]) {return await resolveRedirect(matches[1]);}}}return null;} catch (error) {console.error("Error fetching link:", error);return null;}}// Resolve final URL from redirectasync function resolveRedirect(url) {try {// Using fetch with HEAD method to get the final URLconst controller = new AbortController();const signal = controller.signal;// Set a timeout to abort the requestconst timeoutId = setTimeout(() => controller.abort(), 5000);const response = await fetch(url, {method: 'HEAD',signal,redirect: 'follow'});clearTimeout(timeoutId);return response.url;} catch (error) {// If HEAD fails, try GET with GM.xmlHttpRequestreturn new Promise((resolve) => {GM.xmlHttpRequest({method: "GET",url: url,onreadystatechange: function(response) {if (response.readyState === 2) { // HEADERS_RECEIVEDresolve(response.finalUrl);this.abort();}},onerror: function() {resolve(url); // Return original URL if everything fails}});});}}// Display links with modern UIfunction displayLinks(links, elements) {// Update counterelements.counter.textContent = `${links.length} Links`;// Clear loading indicatorelements.content.innerHTML = '';// Enable copy all buttonelements.copyAllBtn.disabled = false;elements.copyAllBtn.addEventListener('click', () => {navigator.clipboard.writeText(links.join('\n')).then(() => {const originalText = elements.copyAllBtn.textContent;elements.copyAllBtn.textContent = "✓ Copied";setTimeout(() => {elements.copyAllBtn.textContent = originalText;}, 2000);});});// Group links by domain for better organizationconst linksByDomain = {};links.forEach(link => {try {const url = new URL(link);const domain = url.hostname;if (!linksByDomain[domain]) {linksByDomain[domain] = [];}linksByDomain[domain].push(link);} catch (e) {// If parsing fails, put in "Other" categoryif (!linksByDomain["Other"]) {linksByDomain["Other"] = [];}linksByDomain["Other"].push(link);}});// Sort domains alphabeticallyconst domains = Object.keys(linksByDomain).sort();// Create link items by domaindomains.forEach((domain, domainIndex) => {// Add domain header if multiple domains existif (domains.length > 1) {const domainHeader = document.createElement("div");domainHeader.className = "fc-domain-header";domainHeader.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4"></circle></svg><span>${domain}</span><span class="fc-domain-count">${linksByDomain[domain].length}</span>`;elements.content.appendChild(domainHeader);}// Add links for this domainlinksByDomain[domain].forEach(link => {const linkItem = createLinkItem(link);elements.content.appendChild(linkItem);});});}// Create a link item elementfunction createLinkItem(link) {const linkItem = document.createElement("div");linkItem.className = "fc-link-item";// Link text containerconst linkText = document.createElement("a");linkText.className = "fc-link-text";linkText.href = link;linkText.textContent = link;linkText.title = link;linkText.rel = "noopener";linkText.target = "_blank";// Copy buttonconst copyBtn = document.createElement("button");copyBtn.className = "fc-copy-btn";copyBtn.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`;copyBtn.addEventListener('click', (e) => {e.stopPropagation();navigator.clipboard.writeText(link).then(() => {// Visual feedback when copiedcopyBtn.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"></path></svg>`;setTimeout(() => {copyBtn.innerHTML = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>`;}, 1500);});});linkItem.appendChild(linkText);linkItem.appendChild(copyBtn);return linkItem;}