FileCR 助手

一键获取FileCR的软件下载链接(包括快速下载),无需拓展即可访问premium内容。

目前为 2023-11-17 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name FileCR Assistant Bypass & Helper
  3. // @name:zh-CN FileCR 助手
  4. // @name:zh-TW FileCR 助手
  5. // @namespace xiakele
  6. // @version 2.1
  7. // @description A script for FileCR that is capable of obtaining software download links (including 'fast download' URLs) and providing access to premium contents.
  8. // @description:zh-CN 一键获取FileCR的软件下载链接(包括快速下载),无需拓展即可访问premium内容。
  9. // @description:zh-TW 一鍵取得FileCR的軟體下載連結(包括快速下載),無需拓展即可存取premium內容。
  10. // @author xiakele
  11. // @license MIT
  12. // @match *://filecr.com/*
  13. // @icon https://filecr.com/favicon.png
  14. // @grant window.onurlchange
  15. // ==/UserScript==
  16.  
  17. (function () {
  18. const versionInfo = {
  19. id: 'ddgilliopjknmglnpkegbjpoilgachlm',
  20. version: '9.9.9',
  21. };
  22.  
  23. if (!document.cookie.includes('extensionIsInstalled')) {
  24. document.cookie = 'extensionIsInstalled=true;';
  25. }
  26.  
  27. window.addEventListener(
  28. 'message',
  29. (event) => {
  30. const data = {
  31. direction: 'from-content-script',
  32. responseFor: event.data.id,
  33. type: 'response',
  34. };
  35. if (event.data.action === 'app.info') {
  36. data.data = versionInfo;
  37. window.postMessage(data);
  38. } else if (event.data.action === 'downloads.extractLink') {
  39. data.data = event.data.data.url;
  40. window.postMessage(data);
  41. }
  42. },
  43. );
  44.  
  45. async function getLinks(meta) {
  46. if (['Torrent', 'Internal'].includes(meta.type)) {
  47. const result = {};
  48. result.provider = meta.type;
  49. result.url = await fetch(`/api/actions/downloadlink/?id=${meta.id}`)
  50. .then((data) => data.json())
  51. .then((json) => json.url);
  52. return result;
  53. }
  54. const result = await fetch(`https://filecr.com/api/actions/worker/?link_id=${meta.id}`)
  55. .then((data) => data.json())
  56. .then((json) => ({ provider: json.download_provider, url: json.url }));
  57. return result;
  58. }
  59.  
  60. async function displayLinks(json) {
  61. if (document.querySelector('#link-field')) {
  62. return;
  63. }
  64. const trigger = document.querySelector('#trigger');
  65. const div = document.createElement('div');
  66. div.id = 'link-field';
  67. document.querySelector('.download-info').appendChild(div);
  68. trigger.innerText = 'Loading...';
  69. const linksMeta = json.props.pageProps.post.downloads[0].links;
  70. const downloadLinks = await Promise.all(linksMeta.map((meta) => getLinks(meta)));
  71. downloadLinks.forEach((link, i) => {
  72. const a = document.createElement('a');
  73. a.href = link.url;
  74. a.classList.add('link-light');
  75. a.innerText = `Link ${i + 1} (${link.provider})\n`;
  76. div.appendChild(a);
  77. });
  78. trigger.innerText = 'COMPLETE!';
  79. }
  80.  
  81. let reloaded = false;
  82. function addTrigger() {
  83. if (document.querySelector('.e-404') && !reloaded) {
  84. reloaded = true;
  85. window.location.reload();
  86. }
  87. if (!document.querySelector('.download-info') || document.querySelector('#trigger')) {
  88. return;
  89. }
  90. const rawJSON = JSON.parse(document.querySelector('#__NEXT_DATA__').textContent);
  91. const a = document.createElement('a');
  92. a.id = 'trigger';
  93. a.innerText = 'GET DOWNLOAD LINKS';
  94. a.classList.add('link-light');
  95. if (!window.location.pathname.includes(rawJSON.query.postSlug)) {
  96. a.addEventListener('click', () => window.location.reload());
  97. a.innerText += '\n(Data mismatch. Reload is required.)';
  98. } else {
  99. a.addEventListener('click', () => displayLinks(rawJSON));
  100. }
  101. document.querySelector('.download-info').appendChild(a);
  102. }
  103.  
  104. addTrigger();
  105. if (window.onurlchange === null) {
  106. window.addEventListener('urlchange', () => addTrigger());
  107. } else {
  108. const observer = new MutationObserver(() => addTrigger());
  109. observer.observe(document.head, { childList: true });
  110. }
  111. }());