Bypass FileCrypt (New)

Bypass FileCrypt

  1. // ==UserScript==
  2. // @name Bypass FileCrypt (New)
  3. // @namespace Bhunter
  4. // @version 1.0.3
  5. // @description Bypass FileCrypt
  6. // @author Bhunter
  7. // @license MIT
  8. // @match http://filecrypt.cc/*
  9. // @match http://www.filecrypt.cc/*
  10. // @match http://filecrypt.co/*
  11. // @match http://www.filecrypt.co/*
  12. // @match https://filecrypt.cc/*
  13. // @match https://www.filecrypt.cc/*
  14. // @match https://filecrypt.co/*
  15. // @match https://www.filecrypt.co/*
  16. // @run-at document-end
  17. // @connect dcrypt.it
  18. // @connect self
  19. // @grant GM.xmlHttpRequest
  20. // ==/UserScript==
  21.  
  22. (function() {
  23. 'use strict';
  24. // Determine if dark theme is used
  25. const isDarkTheme = document.head.querySelector('meta[name="theme-color"]') !== null ||
  26. document.body.classList.contains('dark') ||
  27. window.getComputedStyle(document.body).backgroundColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)/)?.[1] < 100;
  28. // Add stylesheet to document
  29. addStylesheet(isDarkTheme);
  30. // Remove ads
  31. removeAds();
  32. // Apply main functionality based on URL
  33. if (document.location.href.includes("/Link/")) {
  34. processSingleLink();
  35. } else if (document.location.href.includes("/Container/")) {
  36. waitForCaptchaSolved();
  37. }
  38. })();
  39.  
  40. // Add stylesheet to document
  41. function addStylesheet(isDarkTheme) {
  42. const style = document.createElement('style');
  43. // Define the colors based on theme
  44. const colors = isDarkTheme ? {
  45. background: '#1e1e2e',
  46. text: '#cdd6f4',
  47. accent: '#cba6f7',
  48. border: '#313244',
  49. itemBg: '#181825',
  50. itemHover: '#11111b',
  51. actionBg: '#45475a',
  52. actionText: '#cdd6f4'
  53. } : {
  54. background: '#ffffff',
  55. text: '#333333',
  56. accent: '#4f46e5',
  57. border: '#e5e7eb',
  58. itemBg: '#f9fafb',
  59. itemHover: '#f3f4f6',
  60. actionBg: '#e0e7ff',
  61. actionText: '#4f46e5'
  62. };
  63. // Stylesheet content
  64. style.textContent = `
  65. /* Main container */
  66. .fc-container {
  67. background-color: ${colors.background};
  68. color: ${colors.text};
  69. border: 1px solid ${colors.border};
  70. border-radius: 12px;
  71. box-shadow: 0 10px 15px -3px ${isDarkTheme ? 'rgba(0, 0, 0, 0.4)' : 'rgba(0, 0, 0, 0.1)'};
  72. max-width: 560px;
  73. margin: 40px auto 30px;
  74. overflow: hidden;
  75. font-size: 14px;
  76. line-height: 1.5;
  77. position: relative;
  78. z-index: 10;
  79. }
  80. /* Header */
  81. .fc-header {
  82. padding: 14px 18px;
  83. border-bottom: 1px solid ${colors.border};
  84. display: flex;
  85. justify-content: space-between;
  86. align-items: center;
  87. }
  88. .fc-title {
  89. margin: 0;
  90. font-weight: 600;
  91. font-size: 16px;
  92. }
  93. .fc-counter {
  94. padding: 4px 10px;
  95. border-radius: 20px;
  96. font-size: 12px;
  97. background-color: ${colors.actionBg};
  98. color: ${colors.actionText};
  99. }
  100. /* Content area */
  101. .fc-content {
  102. max-height: 250px;
  103. overflow-y: auto;
  104. padding: 4px 0;
  105. scrollbar-width: thin;
  106. scrollbar-color: ${colors.border} transparent;
  107. }
  108. .fc-content::-webkit-scrollbar {
  109. width: 6px;
  110. }
  111. .fc-content::-webkit-scrollbar-track {
  112. background: transparent;
  113. }
  114. .fc-content::-webkit-scrollbar-thumb {
  115. background-color: ${colors.border};
  116. border-radius: 3px;
  117. }
  118. /* Loading */
  119. .fc-loading {
  120. padding: 16px;
  121. text-align: center;
  122. }
  123. .fc-loading p {
  124. margin-top: 12px;
  125. font-size: 14px;
  126. }
  127. .fc-spinner {
  128. animation: fc-rotate 2s linear infinite;
  129. }
  130. .fc-spinner-path {
  131. stroke-dasharray: 1, 200;
  132. stroke-dashoffset: 0;
  133. animation: fc-dash 1.5s ease-in-out infinite;
  134. stroke: ${colors.accent};
  135. }
  136. @keyframes fc-rotate {
  137. 100% {
  138. transform: rotate(360deg);
  139. }
  140. }
  141. @keyframes fc-dash {
  142. 0% {
  143. stroke-dasharray: 1, 200;
  144. stroke-dashoffset: 0;
  145. }
  146. 50% {
  147. stroke-dasharray: 89, 200;
  148. stroke-dashoffset: -35px;
  149. }
  150. 100% {
  151. stroke-dasharray: 89, 200;
  152. stroke-dashoffset: -124px;
  153. }
  154. }
  155. /* Domain headers */
  156. .fc-domain-header {
  157. padding: 6px 16px;
  158. font-size: 13px;
  159. font-weight: 500;
  160. color: ${colors.accent};
  161. display: flex;
  162. align-items: center;
  163. gap: 6px;
  164. }
  165. .fc-domain-header:not(:first-child) {
  166. margin-top: 10px;
  167. }
  168. .fc-domain-count {
  169. background-color: ${colors.actionBg};
  170. border-radius: 10px;
  171. padding: 1px 6px;
  172. font-size: 11px;
  173. }
  174. /* Link items */
  175. .fc-link-item {
  176. padding: 8px 16px;
  177. margin: 4px 0;
  178. display: flex;
  179. align-items: center;
  180. gap: 10px;
  181. border-radius: 4px;
  182. transition: background-color 0.2s;
  183. cursor: pointer;
  184. }
  185. .fc-link-item:hover {
  186. background-color: ${colors.itemHover};
  187. }
  188. .fc-link-text {
  189. white-space: nowrap;
  190. overflow: hidden;
  191. text-overflow: ellipsis;
  192. flex: 1;
  193. font-size: 14px;
  194. color: white !important;
  195. opacity: 0.9;
  196. }
  197. /* Copy button */
  198. .fc-copy-btn {
  199. width: 28px;
  200. height: 28px;
  201. min-width: 28px;
  202. background-color: transparent;
  203. color: ${colors.accent};
  204. border: none;
  205. border-radius: 50%;
  206. display: flex;
  207. align-items: center;
  208. justify-content: center;
  209. cursor: pointer;
  210. padding: 0;
  211. transition: background-color 0.2s;
  212. margin: 0;
  213. }
  214. .fc-copy-btn:hover {
  215. background-color: ${colors.actionBg};
  216. }
  217. /* Footer */
  218. .fc-footer {
  219. padding: 12px 16px;
  220. border-top: 1px solid ${colors.border};
  221. display: flex;
  222. justify-content: space-between;
  223. align-items: center;
  224. }
  225. .fc-info-text {
  226. opacity: 0.7;
  227. font-size: 12px;
  228. }
  229. .fc-copy-all {
  230. padding: 8px 12px;
  231. background-color: ${colors.accent};
  232. color: white;
  233. border: none;
  234. border-radius: 6px;
  235. cursor: pointer;
  236. font-size: 14px;
  237. transition: all 0.2s ease;
  238. }
  239. .fc-copy-all:disabled {
  240. opacity: 0.5;
  241. cursor: not-allowed;
  242. }
  243. .fc-copy-all:hover:not(:disabled) {
  244. filter: brightness(1.1);
  245. }
  246. `;
  247. document.head.appendChild(style);
  248. }
  249.  
  250. // Remove ads
  251. function removeAds() {
  252. const usenetAds = document.querySelectorAll('a[href*="/pink/"]');
  253. for (const ad of usenetAds) {
  254. if (ad.parentNode) {
  255. ad.parentNode.remove();
  256. }
  257. }
  258. }
  259.  
  260. // Check if captcha is solved by looking for download buttons
  261. function waitForCaptchaSolved() {
  262.  
  263. // Function to check if captcha is solved based on visible elements
  264. function isCaptchaSolved() {
  265. // Look for download buttons or elements that appear after captcha
  266. return document.querySelectorAll('.dlcdownload').length > 0;
  267. }
  268.  
  269. // If captcha is already solved, proceed immediately
  270. if (isCaptchaSolved()) {
  271. processContainerPage();
  272. return;
  273. }
  274.  
  275. // Otherwise, wait for captcha to be solved
  276. const captchaObserver = new MutationObserver((mutations, observer) => {
  277. if (isCaptchaSolved()) {
  278. observer.disconnect();
  279. processContainerPage();
  280. }
  281. });
  282.  
  283. captchaObserver.observe(document.body, {
  284. childList: true,
  285. subtree: true
  286. });
  287. }
  288.  
  289. // Process single link page
  290. async function processSingleLink() {
  291. if (document.body.getElementsByTagName("SCRIPT").length === 0) {
  292. window.stop();
  293. let htmlContent = document.body.innerHTML;
  294. if (!htmlContent || document.body.children.length === 0) {
  295. try {
  296. const response = await fetch(document.location.href);
  297. htmlContent = await response.text();
  298. } catch (error) {
  299. console.error("Failed to fetch page content:", error);
  300. return;
  301. }
  302. }
  303. const httpIndex = htmlContent.lastIndexOf("http");
  304. if (httpIndex !== -1) {
  305. const endIndex = htmlContent.indexOf('id=', httpIndex) + 43;
  306. let finalUrl = htmlContent.substring(httpIndex, endIndex).replace(/&amp;/g, '&');
  307. window.location.href = finalUrl;
  308. }
  309. }
  310. }
  311.  
  312. // Process container page
  313. function processContainerPage() {
  314. // Find the best container to insert our link box
  315. const containerSection = findBestContainer();
  316. // Create container elements
  317. const { container, content, counter, copyAllBtn } = createLinkBox();
  318. // Insert the box at the appropriate location
  319. containerSection.insertBefore(container, containerSection.firstChild);
  320. // Try to get DLC file
  321. const dlcButtons = document.getElementsByClassName("dlcdownload");
  322. if (dlcButtons.length > 0) {
  323. const dlcId = dlcButtons[0].getAttribute("onclick")?.split("'")[1];
  324. if (dlcId) {
  325. fetchDlcAndDecrypt(dlcId, { content, counter, copyAllBtn });
  326. return;
  327. }
  328. }
  329. // Fall back to manual link extraction
  330. extractLinks({ content, counter, copyAllBtn });
  331. }
  332.  
  333. // Find the best container for inserting our box
  334. function findBestContainer() {
  335. // Try various selectors in order of preference
  336. const selectors = [
  337. '.content .window',
  338. '.download',
  339. '.content',
  340. 'main',
  341. 'article',
  342. '.container',
  343. '#container'
  344. ];
  345. for (const selector of selectors) {
  346. const element = document.querySelector(selector);
  347. if (element) {
  348. return element;
  349. }
  350. }
  351. // Fallback to body if no suitable container found
  352. return document.body;
  353. }
  354.  
  355. // Create DOM structure for the link box
  356. function createLinkBox() {
  357. // Create container
  358. const container = document.createElement("div");
  359. container.className = "fc-container";
  360. // Create header
  361. const header = document.createElement("div");
  362. header.className = "fc-header";
  363. const title = document.createElement("h3");
  364. title.className = "fc-title";
  365. title.innerHTML = "🔓 Decrypted Links";
  366. const counter = document.createElement("span");
  367. counter.className = "fc-counter";
  368. counter.id = "fc-counter";
  369. counter.textContent = "Loading...";
  370. header.appendChild(title);
  371. header.appendChild(counter);
  372. container.appendChild(header);
  373. // Create content area
  374. const content = document.createElement("div");
  375. content.className = "fc-content";
  376. content.id = "fc-content";
  377. // Add loading animation
  378. const loadingDiv = document.createElement("div");
  379. loadingDiv.className = "fc-loading";
  380. loadingDiv.id = "fc-loading";
  381. loadingDiv.innerHTML = `
  382. <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  383. <circle class="fc-spinner fc-spinner-path" cx="12" cy="12" r="10" fill="none" stroke-width="2" />
  384. </svg>
  385. <p>Decrypting links...</p>
  386. `;
  387. content.appendChild(loadingDiv);
  388. container.appendChild(content);
  389. // Create footer
  390. const footer = document.createElement("div");
  391. footer.className = "fc-footer";
  392. // Add info text
  393. const infoText = document.createElement("small");
  394. infoText.className = "fc-info-text";
  395. infoText.textContent = "Click link to open, or use copy button";
  396. // Add copy all button
  397. const copyAllBtn = document.createElement("button");
  398. copyAllBtn.className = " fc-copy-all";
  399. copyAllBtn.id = "fc-copy-all";
  400. copyAllBtn.textContent = "Copy All";
  401. copyAllBtn.disabled = true;
  402. footer.appendChild(infoText);
  403. footer.appendChild(copyAllBtn);
  404. container.appendChild(footer);
  405. return { container, content, counter, copyAllBtn };
  406. }
  407.  
  408. // Fetch DLC file and decrypt it
  409. async function fetchDlcAndDecrypt(dlcId, elements) {
  410. try {
  411. // Update the loading message
  412. const loadingDiv = document.getElementById("fc-loading");
  413. const loadingText = loadingDiv.querySelector("p");
  414. loadingText.textContent = "Fetching DLC file...";
  415. // Fetch the DLC file
  416. const response = await fetch(`https://${document.location.hostname}/DLC/${dlcId}.dlc`);
  417. if (!response.ok) throw new Error('Failed to fetch DLC file');
  418. const dlcContent = await response.text();
  419. loadingText.textContent = "Decrypting links via dcrypt.it...";
  420. // Use GM.xmlHttpRequest for dcrypt.it (since it may require CORS handling)
  421. GM.xmlHttpRequest({
  422. method: "POST",
  423. url: "http://dcrypt.it/decrypt/paste",
  424. headers: {
  425. "Content-Type": "application/x-www-form-urlencoded"
  426. },
  427. data: "content=" + encodeURIComponent(dlcContent),
  428. onload: function(response) {
  429. try {
  430. const result = JSON.parse(response.response);
  431. if (result.success && result.success.links && result.success.links.length > 0) {
  432. displayLinks(result.success.links, elements);
  433. } else {
  434. throw new Error("No links were found in the dcrypt.it response");
  435. }
  436. } catch (error) {
  437. console.error("Error parsing dcrypt.it response:", error);
  438. extractLinks(elements);
  439. }
  440. },
  441. onerror: function() {
  442. console.error("Error connecting to dcrypt.it");
  443. extractLinks(elements);
  444. }
  445. });
  446. } catch (error) {
  447. console.error("Error fetching DLC:", error);
  448. extractLinks(elements);
  449. }
  450. }
  451.  
  452. // Extract links directly from page
  453. function extractLinks(elements) {
  454. const loadingDiv = document.getElementById("fc-loading");
  455. const loadingText = loadingDiv.querySelector("p");
  456. loadingText.textContent = "Extracting links directly...";
  457. const encLinks = document.querySelectorAll("[onclick^=openLink]");
  458. if (encLinks.length === 0) {
  459. showError("No links found on this page.");
  460. return;
  461. }
  462. // Update counter to show progress
  463. elements.counter.textContent = `0/${encLinks.length}`;
  464. let completedLinks = 0;
  465. const validLinks = [];
  466. // Process each link with a small delay between requests to avoid overloading
  467. const processLink = (index) => {
  468. if (index >= encLinks.length) {
  469. if (validLinks.length > 0) {
  470. displayLinks(validLinks, elements);
  471. } else {
  472. showError("Failed to extract any valid links.");
  473. }
  474. return;
  475. }
  476. const link = encLinks[index];
  477. const onclick = link.getAttribute("onclick");
  478. const encParam = onclick.split("'")[1];
  479. const encValue = link.getAttribute(encParam);
  480. const linkUrl = `http://${document.location.hostname}/Link/${encValue}.html`;
  481. fetchFinalLink(linkUrl)
  482. .then(finalLink => {
  483. completedLinks++;
  484. elements.counter.textContent = `${completedLinks}/${encLinks.length}`;
  485. if (finalLink) {
  486. validLinks.push(finalLink);
  487. }
  488. // Process next link with a small delay
  489. setTimeout(() => processLink(index + 1), 100);
  490. })
  491. .catch(() => {
  492. completedLinks++;
  493. elements.counter.textContent = `${completedLinks}/${encLinks.length}`;
  494. setTimeout(() => processLink(index + 1), 100);
  495. });
  496. };
  497. // Start processing links
  498. processLink(0);
  499. }
  500.  
  501. // Show error message
  502. function showError(message) {
  503. const loadingDiv = document.getElementById("fc-loading");
  504. loadingDiv.innerHTML = `
  505. <div style="color:var(--fc-accent,#4f46e5);font-size:24px;margin-bottom:10px">❌</div>
  506. <p style="margin:0">${message}</p>
  507. `;
  508. const counter = document.getElementById("fc-counter");
  509. if (counter) counter.textContent = "Error";
  510. }
  511.  
  512. // Fetch a single link's destination
  513. async function fetchFinalLink(url) {
  514. try {
  515. const response = await fetch(url);
  516. if (!response.ok) return null;
  517. const html = await response.text();
  518. const parser = new DOMParser();
  519. const doc = parser.parseFromString(html, "text/html");
  520. // Try to find the redirect URL in scripts
  521. const scripts = doc.querySelectorAll("script");
  522. for (const script of scripts) {
  523. if (script.textContent.includes("top.location.href=")) {
  524. const matches = script.textContent.match(/top\.location\.href\s*=\s*['"]([^'"]+)['"]/);
  525. if (matches && matches[1]) {
  526. return await resolveRedirect(matches[1]);
  527. }
  528. }
  529. }
  530. return null;
  531. } catch (error) {
  532. console.error("Error fetching link:", error);
  533. return null;
  534. }
  535. }
  536.  
  537. // Resolve final URL from redirect
  538. async function resolveRedirect(url) {
  539. try {
  540. // Using fetch with HEAD method to get the final URL
  541. const controller = new AbortController();
  542. const signal = controller.signal;
  543. // Set a timeout to abort the request
  544. const timeoutId = setTimeout(() => controller.abort(), 5000);
  545. const response = await fetch(url, {
  546. method: 'HEAD',
  547. signal,
  548. redirect: 'follow'
  549. });
  550. clearTimeout(timeoutId);
  551. return response.url;
  552. } catch (error) {
  553. // If HEAD fails, try GET with GM.xmlHttpRequest
  554. return new Promise((resolve) => {
  555. GM.xmlHttpRequest({
  556. method: "GET",
  557. url: url,
  558. onreadystatechange: function(response) {
  559. if (response.readyState === 2) { // HEADERS_RECEIVED
  560. resolve(response.finalUrl);
  561. this.abort();
  562. }
  563. },
  564. onerror: function() {
  565. resolve(url); // Return original URL if everything fails
  566. }
  567. });
  568. });
  569. }
  570. }
  571.  
  572. // Display links with modern UI
  573. function displayLinks(links, elements) {
  574. // Update counter
  575. elements.counter.textContent = `${links.length} Links`;
  576. // Clear loading indicator
  577. elements.content.innerHTML = '';
  578. // Enable copy all button
  579. elements.copyAllBtn.disabled = false;
  580. elements.copyAllBtn.addEventListener('click', () => {
  581. navigator.clipboard.writeText(links.join('\n'))
  582. .then(() => {
  583. const originalText = elements.copyAllBtn.textContent;
  584. elements.copyAllBtn.textContent = "✓ Copied";
  585. setTimeout(() => {
  586. elements.copyAllBtn.textContent = originalText;
  587. }, 2000);
  588. });
  589. });
  590. // Group links by domain for better organization
  591. const linksByDomain = {};
  592. links.forEach(link => {
  593. try {
  594. const url = new URL(link);
  595. const domain = url.hostname;
  596. if (!linksByDomain[domain]) {
  597. linksByDomain[domain] = [];
  598. }
  599. linksByDomain[domain].push(link);
  600. } catch (e) {
  601. // If parsing fails, put in "Other" category
  602. if (!linksByDomain["Other"]) {
  603. linksByDomain["Other"] = [];
  604. }
  605. linksByDomain["Other"].push(link);
  606. }
  607. });
  608. // Sort domains alphabetically
  609. const domains = Object.keys(linksByDomain).sort();
  610. // Create link items by domain
  611. domains.forEach((domain, domainIndex) => {
  612. // Add domain header if multiple domains exist
  613. if (domains.length > 1) {
  614. const domainHeader = document.createElement("div");
  615. domainHeader.className = "fc-domain-header";
  616. domainHeader.innerHTML = `
  617. <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">
  618. <circle cx="12" cy="12" r="10"></circle>
  619. <circle cx="12" cy="12" r="4"></circle>
  620. </svg>
  621. <span>${domain}</span>
  622. <span class="fc-domain-count">${linksByDomain[domain].length}</span>
  623. `;
  624. elements.content.appendChild(domainHeader);
  625. }
  626. // Add links for this domain
  627. linksByDomain[domain].forEach(link => {
  628. const linkItem = createLinkItem(link);
  629. elements.content.appendChild(linkItem);
  630. });
  631. });
  632. }
  633.  
  634. // Create a link item element
  635. function createLinkItem(link) {
  636. const linkItem = document.createElement("div");
  637. linkItem.className = "fc-link-item";
  638. // Link text container
  639. const linkText = document.createElement("a");
  640. linkText.className = "fc-link-text";
  641. linkText.href = link;
  642. linkText.textContent = link;
  643. linkText.title = link;
  644. linkText.rel = "noopener";
  645. linkText.target = "_blank";
  646. // Copy button
  647. const copyBtn = document.createElement("button");
  648. copyBtn.className = "fc-copy-btn";
  649. copyBtn.innerHTML = `
  650. <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  651. <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
  652. <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
  653. </svg>
  654. `;
  655. copyBtn.addEventListener('click', (e) => {
  656. e.stopPropagation();
  657. navigator.clipboard.writeText(link)
  658. .then(() => {
  659. // Visual feedback when copied
  660. copyBtn.innerHTML = `
  661. <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  662. <path d="M20 6L9 17l-5-5"></path>
  663. </svg>
  664. `;
  665. setTimeout(() => {
  666. copyBtn.innerHTML = `
  667. <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  668. <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
  669. <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
  670. </svg>
  671. `;
  672. }, 1500);
  673. });
  674. });
  675. linkItem.appendChild(linkText);
  676. linkItem.appendChild(copyBtn);
  677. return linkItem;
  678. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址