// ==UserScript==
// @name Bypassa FileCrypt (https)
// @namespace IA
// @version 1.1.5
// @description Bypass FileCrypt with improved link extraction and filename display
// @author IA(with improvements)
// @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';
console.log('FileCrypt Bypass script started');
// Add basic stylesheet
addStylesheet();
// Remove ads
removeAds();
// Apply main functionality based on URL
if (document.location.href.includes("/Link/")) {
console.log('Single link page detected');
getSingleLink();
} else if (document.location.href.includes("/Container/")) {
console.log('Container page detected');
waitForCaptchaSolved();
}
})();
// Add basic stylesheet
function addStylesheet() {
const style = document.createElement('style');
style.textContent = `
.fc-container {
background-color: #1e1e2e;
color: #cdd6f4;
border: 1px solid #313244;
border-radius: 10px;
padding: 1em;
margin: 1em auto;
max-width: 800px;
position: relative;
z-index: 10000;
font-size: 14px;
}
.fc-error {
color: #f38ba8;
}
.fc-success {
color: #a6e3a1;
}
.fc-loading {
text-align: center;
padding: 1em;
}
.fc-link-item {
margin-bottom: 1em;
padding: 1em;
border: 1px solid #313244;
border-radius: 6px;
background: rgba(30, 30, 46, 0.5);
}
.fc-filename {
color: #a6adc8;
font-size: 1em;
font-weight: bold;
margin-bottom: 0.5em;
}
.fc-link {
word-break: break-all;
font-size: 0.9em;
font-family: monospace;
color: #cba6f7;
cursor: pointer;
}
.fc-link:hover {
text-decoration: underline;
}
.fc-hosting {
font-size: 0.8em;
color: #a6adc8;
margin-left: 0.5em;
}
.fc-buttons {
margin: 1em 0;
text-align: center;
}
.fc-button {
background: #cba6f7;
color: #1e1e2e;
border: none;
padding: 0.5em 1em;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
margin: 0 0.5em;
}
.fc-button:hover {
background: #b692f6;
}
.fc-button:disabled {
background: #6c7086;
cursor: not-allowed;
}
`;
document.head.appendChild(style);
}
// Remove ads
function removeAds() {
const usenetAds = document.querySelectorAll('a[href*="/pink/"]');
for (const ad of usenetAds) {
if (ad.parentNode) ad.parentNode.remove();
}
}
// Check if captcha is solved
function waitForCaptchaSolved() {
console.log('Waiting for captcha to be solved...');
function isCaptchaSolved() {
return document.querySelectorAll('.dlcdownload, .download, [href*="/DLC/"]').length > 0;
}
if (isCaptchaSolved()) {
console.log('Captcha already solved');
processContainerPage();
return;
}
const captchaObserver = new MutationObserver((mutations, observer) => {
if (isCaptchaSolved()) {
console.log('Captcha solved!');
observer.disconnect();
processContainerPage();
}
});
captchaObserver.observe(document.body, {
childList: true,
subtree: true
});
// Fallback: process after 10 seconds anyway
setTimeout(() => {
captchaObserver.disconnect();
console.log('Fallback: processing page after timeout');
processContainerPage();
}, 10000);
}
// Process container page
function processContainerPage() {
console.log('Processing container page...');
const containerSection = findBestContainer();
const container = createLinkBox();
containerSection.insertBefore(container, containerSection.firstChild);
// Try DLC first
const dlcButtons = document.querySelectorAll('.dlcdownload, [href*="/DLC/"]');
if (dlcButtons.length > 0) {
console.log('DLC button found, trying DLC method');
const dlcId = dlcButtons[0].getAttribute('onclick')?.split("'")[1] ||
dlcButtons[0].getAttribute('href')?.match(/\/DLC\/(.+)\.dlc/)?.[1];
if (dlcId) {
console.log('DLC ID:', dlcId);
fetchDlcAndDecrypt(dlcId, container);
return;
}
}
console.log('Using direct link extraction method');
xhrLinkExtract(container);
}
// Find the best container
function findBestContainer() {
const selectors = [
'.content .window',
'.download',
'.content',
'main',
'article',
'.container',
'#container'
];
for (const selector of selectors) {
const element = document.querySelector(selector);
if (element) {
console.log('Found container:', selector);
return element;
}
}
console.log('Using body as container');
return document.body;
}
// Create link box
function createLinkBox() {
const container = document.createElement('div');
container.className = 'fc-container';
container.id = 'fc-container';
const loading = document.createElement('div');
loading.className = 'fc-loading';
loading.textContent = 'Decrypting links...';
container.appendChild(loading);
return container;
}
// Fetch and decrypt DLC
function fetchDlcAndDecrypt(dlcId, container) {
console.log('Fetching DLC file...');
container.querySelector('.fc-loading').textContent = 'Fetching DLC file...';
GM.xmlHttpRequest({
method: 'GET',
url: `https://${document.location.hostname}/DLC/${dlcId}.dlc`,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
},
onload: function(response) {
console.log('DLC file fetched, decrypting...');
container.querySelector('.fc-loading').textContent = 'Decrypting via dcrypt.it...';
// Prima prova con HTTPS
tryHttpsFirst(response.responseText, container);
},
onerror: function() {
console.error('Error fetching DLC file');
xhrLinkExtract(container);
}
});
}
// Try HTTPS first, then fallback to HTTP
function tryHttpsFirst(dlcContent, container) {
console.log('Trying HTTPS first...');
GM.xmlHttpRequest({
method: 'POST',
url: 'https://dcrypt.it/decrypt/paste',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
},
data: 'content=' + encodeURIComponent(dlcContent),
timeout: 10000,
onload: function(res) {
try {
const result = JSON.parse(res.responseText);
if (result.success && result.success.links && result.success.links.length > 0) {
console.log('DLC decrypted successfully via HTTPS, links found:', result.success.links.length);
displayLinksWithFilenames(result.success.links, container);
} else {
console.error('No links from dcrypt.it via HTTPS, trying HTTP...');
tryHttpFallback(dlcContent, container);
}
} catch (e) {
console.error('Error parsing dcrypt.it HTTPS response, trying HTTP...', e);
tryHttpFallback(dlcContent, container);
}
},
onerror: function() {
console.error('Error connecting to dcrypt.it via HTTPS, trying HTTP...');
tryHttpFallback(dlcContent, container);
}
});
}
// Fallback to HTTP
function tryHttpFallback(dlcContent, container) {
console.log('Trying HTTP fallback...');
container.querySelector('.fc-loading').textContent = 'Decrypting via dcrypt.it (HTTP fallback)...';
GM.xmlHttpRequest({
method: 'POST',
url: 'http://dcrypt.it/decrypt/paste',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
},
data: 'content=' + encodeURIComponent(dlcContent),
timeout: 10000,
onload: function(res) {
try {
const result = JSON.parse(res.responseText);
if (result.success && result.success.links && result.success.links.length > 0) {
console.log('DLC decrypted successfully via HTTP, links found:', result.success.links.length);
displayLinksWithFilenames(result.success.links, container);
} else {
console.error('No links from dcrypt.it via HTTP:', result);
xhrLinkExtract(container);
}
} catch (e) {
console.error('Error parsing dcrypt.it HTTP response:', e);
xhrLinkExtract(container);
}
},
onerror: function() {
console.error('Error connecting to dcrypt.it via HTTP');
xhrLinkExtract(container);
}
});
}
// Process single link page
function getSingleLink() {
console.log('Processing single link page');
if (document.body.getElementsByTagName('SCRIPT').length === 0) {
window.stop();
let htmlContent = document.body.innerHTML;
if (document.body.children.length === 0) {
GM.xmlHttpRequest({
method: 'GET',
url: document.location.href,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
},
onload: function(response) {
extractAndResolveLink(response.responseText);
},
onerror: function() {
console.error('Failed to fetch page content');
}
});
} else {
extractAndResolveLink(htmlContent);
}
}
}
function extractAndResolveLink(htmlContent) {
const urlMatch = htmlContent.match(/https?:\/\/[^\s'"]+/);
if (urlMatch) {
let intermediateLink = urlMatch[0].replace(/&/g, '&');
resolveFinalLink(intermediateLink);
} else {
console.error('No valid URL found in HTML');
}
}
function resolveFinalLink(intermediateLink) {
GM.xmlHttpRequest({
method: 'GET',
url: intermediateLink,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
},
timeout: 5000,
onload: function(response) {
let finalUrl = response.finalUrl || intermediateLink;
console.log('Resolved final URL:', finalUrl);
top.location.href = finalUrl;
},
onerror: function() {
console.error('Error resolving link:', intermediateLink);
top.location.href = intermediateLink;
}
});
}
// Extract filename from table row - IMPROVED VERSION
function extractFilename(linkElement) {
console.log('Extracting filename for:', linkElement);
// Look for the table row containing this link
const row = linkElement.closest('tr');
if (row) {
// Method 1: Look for filename in the row structure
const filename = findFilenameInRow(row);
if (filename) {
return filename;
}
// Method 2: Look for any cell with a filename-like pattern
const cells = row.querySelectorAll('td');
for (let cell of cells) {
let text = cell.textContent.trim();
if (text && (text.includes('.rar') || text.includes('.zip') || text.includes('.7z') || text.includes('part') || text.match(/\.(mp4|avi|mkv|pdf|exe|msi)$/i))) {
// Clean the filename
text = cleanFilename(text);
if (text && text.length > 3) {
console.log('Found filename by pattern and cleaned:', text);
return text;
}
}
}
}
console.log('No filename found');
return null;
}
// Improved filename extraction from table row
function findFilenameInRow(row) {
// Try different cell positions that commonly contain filenames
const cellSelectors = [
'td:first-child', // Usually the filename
'td:nth-child(1)', // First cell
'td:nth-child(2)', // Second cell (sometimes filename is here)
'.filename', // Specific class
'[class*="name"]' // Any class containing "name"
];
for (const selector of cellSelectors) {
const cell = row.querySelector(selector);
if (cell) {
let text = cell.textContent.trim();
if (text && text.length > 3 && !text.includes('/Link/') && !text.includes('http') && !text.match(/^(Download|DLC|Link|Click|Continue|Premium|Free)$/i)) {
// Clean the filename
text = cleanFilename(text);
if (text && text.length > 3) {
console.log('Found filename in cell:', text);
return text;
}
}
}
}
return null;
}
// Clean filename by removing hosting names and other artifacts
function cleanFilename(filename) {
if (!filename) return filename;
// List of hosting names and patterns to remove
const hostingPatterns = [
'filestore.me',
'worldbytez.net',
'terabytez.org',
'clicknupload',
'uploadhaven',
'rapidgator',
'nitroflare',
'turbobit',
'katfile',
'dropapk'
];
let cleaned = filename;
// Remove hosting names from the end of filename
for (const hosting of hostingPatterns) {
// Remove if at the end (with or without extension)
const pattern1 = new RegExp(hosting + '\\.?\\w*$', 'i');
cleaned = cleaned.replace(pattern1, '');
// Remove if in the middle with common separators
const pattern2 = new RegExp('[\\s\\-\\._]?' + hosting + '[\\s\\-\\._]?', 'gi');
cleaned = cleaned.replace(pattern2, '');
}
// Remove common artifacts and clean up
cleaned = cleaned
.replace(/^\d+\.\s*/, '') // Remove numbering like "1. "
.replace(/\s*\([^)]*\)$/, '') // Remove trailing parentheses
.replace(/\s*\[[^\]]*\]$/, '') // Remove trailing brackets
.replace(/[\\s\\-\\._]+$/, '') // Remove trailing separators
.replace(/^[\\s\\-\\._]+/, '') // Remove leading separators
.trim();
// If we removed too much, return original
if (cleaned.length < 3) {
return filename;
}
return cleaned;
}
// Extract hosting name - IMPROVED VERSION
function extractHosting(linkElement) {
const text = linkElement.textContent.trim();
const hostingPatterns = [
/(filestore\.me|worldbytez\.net|terabytez\.org|clicknupload|uploadhaven|rapidgator|nitroflare|turbobit)/i
];
for (const pattern of hostingPatterns) {
const match = text.match(pattern);
if (match) {
return match[1];
}
}
// Also check parent elements for hosting names
const parent = linkElement.closest('tr, td, div');
if (parent) {
const parentText = parent.textContent.trim();
for (const pattern of hostingPatterns) {
const match = parentText.match(pattern);
if (match) {
return match[1];
}
}
}
return null;
}
// Resolve intermediate link to final destination
function resolveToFinalUrl(intermediateUrl, callback) {
console.log('Resolving intermediate URL:', intermediateUrl);
GM.xmlHttpRequest({
method: 'GET',
url: intermediateUrl,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
},
timeout: 15000,
onload: function(response) {
let finalUrl = response.finalUrl || intermediateUrl;
// If it's still a FileCrypt link, try to extract the real redirect
if (finalUrl.includes('filecrypt.cc') || finalUrl.includes('filecrypt.co')) {
console.log('Still FileCrypt link, extracting redirect...');
// Look for script redirect
const scriptMatch = response.responseText.match(/top\.location\.href\s*=\s*'([^']+)'/);
if (scriptMatch) {
finalUrl = scriptMatch[1];
console.log('Found script redirect:', finalUrl);
}
// Look for meta refresh
if (!scriptMatch) {
const metaMatch = response.responseText.match(/<meta[^>]*http-equiv=["']refresh["'][^>]*content=["'][^"']*url=([^"']+)["']/i);
if (metaMatch) {
finalUrl = metaMatch[1];
console.log('Found meta redirect:', finalUrl);
}
}
// If we found another intermediate link, resolve it recursively
if (finalUrl.includes('filecrypt.cc') || finalUrl.includes('filecrypt.co')) {
console.log('Found another intermediate, resolving recursively...');
resolveToFinalUrl(finalUrl, callback);
return;
}
}
// Clean the final URL
finalUrl = finalUrl.replace(/login\?redirect=/, '');
console.log('Final resolved URL:', finalUrl);
callback(finalUrl);
},
onerror: function(error) {
console.error('Error resolving URL:', error);
callback(intermediateUrl); // Return original if resolution fails
}
});
}
// Extract links directly - FIXED VERSION
function xhrLinkExtract(container) {
console.log('Starting direct link extraction');
const loading = container.querySelector('.fc-loading');
loading.textContent = 'Searching for links...';
// Find all potential links
const encLinks = document.querySelectorAll('[onclick^="openLink"], a[href*="/Link/"]');
console.log('Found links:', encLinks.length);
if (encLinks.length === 0) {
console.log('No links found, showing error');
showError('No download links found on this page.', container);
return;
}
const finalLinksDiv = document.createElement('div');
finalLinksDiv.style.padding = '1em';
finalLinksDiv.innerHTML = '<strong class="fc-success">Decrypted links:</strong><br><br>';
container.replaceChild(finalLinksDiv, loading);
let processed = 0;
let success = 0;
let allLinks = []; // Store all successful links for copy function
function processNextLink() {
if (processed >= encLinks.length) {
console.log(`Processing complete: ${success}/${encLinks.length} successful`);
// Show summary and add copy button
if (success > 0) {
const summary = document.createElement('div');
summary.className = 'fc-success';
summary.textContent = `✓ Successfully decrypted ${success} links`;
finalLinksDiv.appendChild(summary);
// Add copy all button
addCopyAllButton(finalLinksDiv, allLinks);
}
return;
}
const link = encLinks[processed];
const filename = extractFilename(link);
const hosting = extractHosting(link);
console.log(`Processing link ${processed + 1}/${encLinks.length}`, link);
let linkUrl;
if (link.getAttribute('href')?.includes('/Link/')) {
linkUrl = link.getAttribute('href');
} else if (link.getAttribute('onclick')?.startsWith('openLink')) {
const onclick = link.getAttribute('onclick');
const key = onclick.split("'")[1];
const linkId = link.getAttribute(key);
if (linkId) {
linkUrl = `https://${document.location.hostname}/Link/${linkId}.html`;
}
}
if (!linkUrl) {
console.log('No valid URL found for link');
createLinkItem(null, filename, hosting, `Link ${processed + 1} - Invalid URL`, finalLinksDiv);
processed++;
setTimeout(processNextLink, 100);
return;
}
console.log('Fetching intermediate link:', linkUrl);
// First get the intermediate page
GM.xmlHttpRequest({
method: 'GET',
url: linkUrl,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'
},
timeout: 10000,
onload: function(response) {
let intermediateUrl = null;
// Extract redirect from the intermediate page
const scriptMatch = response.responseText.match(/top\.location\.href\s*=\s*'([^']+)'/);
if (scriptMatch) {
intermediateUrl = scriptMatch[1];
}
if (!intermediateUrl) {
const metaMatch = response.responseText.match(/<meta[^>]*http-equiv=["']refresh["'][^>]*content=["'][^"']*url=([^"']+)["']/i);
if (metaMatch) {
intermediateUrl = metaMatch[1];
}
}
if (intermediateUrl) {
console.log('Found intermediate redirect:', intermediateUrl);
// Now resolve this intermediate URL to the final destination
resolveToFinalUrl(intermediateUrl, function(finalUrl) {
console.log('Got final URL:', finalUrl);
// Store successful link for copy function
allLinks.push({
url: finalUrl,
filename: filename,
hosting: hosting
});
createLinkItem(finalUrl, filename, hosting, finalUrl, finalLinksDiv);
success++;
processed++;
setTimeout(processNextLink, 500);
});
} else {
console.log('No redirect found in intermediate page');
createLinkItem(null, filename, hosting, `Link ${processed + 1} - No redirect found`, finalLinksDiv);
processed++;
setTimeout(processNextLink, 500);
}
},
onerror: function(error) {
console.log('Fetch error:', error);
createLinkItem(null, filename, hosting, `Link ${processed + 1} - Network error`, finalLinksDiv);
processed++;
setTimeout(processNextLink, 500);
}
});
}
processNextLink();
}
// Add copy all button
function addCopyAllButton(container, links) {
const buttonsDiv = document.createElement('div');
buttonsDiv.className = 'fc-buttons';
const copyAllButton = document.createElement('button');
copyAllButton.className = 'fc-button';
copyAllButton.textContent = '📋 Copy All Links';
copyAllButton.title = 'Copy all decrypted links to clipboard';
copyAllButton.addEventListener('click', function() {
if (links.length === 0) {
alert('No links to copy!');
return;
}
// Create text with all links
const allLinksText = links.map(link => link.url).join('\n');
navigator.clipboard.writeText(allLinksText).then(() => {
const originalText = copyAllButton.textContent;
copyAllButton.textContent = '✓ All Links Copied!';
copyAllButton.disabled = true;
setTimeout(() => {
copyAllButton.textContent = originalText;
copyAllButton.disabled = false;
}, 2000);
}).catch(err => {
console.error('Failed to copy links:', err);
alert('Failed to copy links to clipboard');
});
});
buttonsDiv.appendChild(copyAllButton);
container.appendChild(buttonsDiv);
}
// Create a link item
function createLinkItem(finalUrl, filename, hosting, linkText, container) {
const linkItem = document.createElement('div');
linkItem.className = 'fc-link-item';
// Filename
const filenameElement = document.createElement('div');
filenameElement.className = 'fc-filename';
if (filename) {
filenameElement.textContent = `📄 ${filename}`;
if (hosting) {
const hostingElement = document.createElement('span');
hostingElement.className = 'fc-hosting';
hostingElement.textContent = `[${hosting}]`;
filenameElement.appendChild(hostingElement);
}
} else {
filenameElement.textContent = `📄 File`;
if (hosting) {
filenameElement.textContent += ` [${hosting}]`;
}
}
linkItem.appendChild(filenameElement);
// Link text
const linkTextElement = document.createElement('div');
linkTextElement.className = 'fc-link';
if (finalUrl) {
linkTextElement.textContent = finalUrl;
linkTextElement.style.cursor = 'pointer';
linkTextElement.title = 'Click to copy URL';
linkTextElement.addEventListener('click', function() {
navigator.clipboard.writeText(finalUrl).then(() => {
const originalText = linkTextElement.textContent;
linkTextElement.textContent = '✓ Copied to clipboard!';
linkTextElement.className = 'fc-link fc-success';
setTimeout(() => {
linkTextElement.textContent = originalText;
linkTextElement.className = 'fc-link';
}, 2000);
});
});
} else {
linkTextElement.textContent = linkText;
linkTextElement.className += ' fc-error';
}
linkItem.appendChild(linkTextElement);
container.appendChild(linkItem);
}
// Display links with filenames from DLC
function displayLinksWithFilenames(links, container) {
console.log('Displaying DLC links:', links.length);
const finalLinksDiv = document.createElement('div');
finalLinksDiv.style.padding = '1em';
finalLinksDiv.innerHTML = '<strong class="fc-success">Decrypted links:</strong><br><br>';
const allLinks = [];
links.forEach((link, index) => {
let cleanedLink = link.replace(/login\?redirect=/, '');
// Extract filename from URL
let filename = null;
try {
const url = new URL(cleanedLink);
const pathname = url.pathname;
const pathParts = pathname.split('/').filter(part => part);
if (pathParts.length > 0) {
filename = pathParts[pathParts.length - 1];
filename = decodeURIComponent(filename);
if (filename.includes('?')) {
filename = filename.split('?')[0];
}
}
} catch (e) {
console.log('Could not parse URL for filename:', cleanedLink);
}
allLinks.push({
url: cleanedLink,
filename: filename,
hosting: null
});
createLinkItem(cleanedLink, filename, null, cleanedLink, finalLinksDiv);
});
// Add copy all button for DLC links too
if (links.length > 0) {
addCopyAllButton(finalLinksDiv, allLinks);
}
container.replaceChild(finalLinksDiv, container.querySelector('.fc-loading'));
}
// Show error message
function showError(message, container) {
console.log('Showing error:', message);
const errorDiv = document.createElement('div');
errorDiv.className = 'fc-error';
errorDiv.textContent = message;
container.replaceChild(errorDiv, container.querySelector('.fc-loading'));
}