U2显示文件校验和

为文件列表添加校验和信息

  1. // ==UserScript==
  2. // @name U2显示文件校验和
  3. // @namespace U2显示文件校验和
  4. // @version 0.0.4
  5. // @description 为文件列表添加校验和信息
  6. // @author kysdm
  7. // @match *://u2.dmhy.org/details.php?id=*
  8. // @grant none
  9. // @license MIT
  10. // @icon https://u2.dmhy.org/favicon.ico
  11. // @require https://unpkg.com/xhook@1.6.2/dist/xhook.min.js
  12. // @require https://cdnjs.cloudflare.com/ajax/libs/localforage/1.10.0/localforage.min.js
  13. // ==/UserScript==
  14.  
  15. (async () => {
  16. 'use strict';
  17.  
  18. xhook.before(async (request, callback) => {
  19. if (request.url.match(/viewfilelist\.php\?id=\d+/)) { await checkTorrentChecksum(); }
  20. callback();
  21. })
  22.  
  23. xhook.after(function (request, response) {
  24. if (request.url.match(/viewfilelist\.php\?id=\d+/)) {
  25. if (torrent_checksum === 'null') return;
  26. const resp = response.text;
  27. const doc = $('<div></div>').html(resp);
  28. const f_ids = doc.find('[id^=f_id_]');
  29. const f_obj = new Object();
  30. const f_tmp = [];
  31. let f_id = '';
  32.  
  33. f_ids.each(function () {
  34. const f_name = $(this).find('td').first().text();
  35. const f_name_trim = f_name.trimStart();
  36. const leadingSpaceCount = countLeadingSpaces(f_name);
  37. const _depth = leadingSpaceCount / 4;
  38. const f_depth = f_tmp.length - 1;
  39.  
  40. if (_depth === f_depth + 1) {
  41. // root
  42. } else if (_depth === f_depth) {
  43. if (f_tmp.length !== 0) f_obj[f_tmp.join('/')] = f_id;
  44. f_tmp.pop();
  45. } else {
  46. f_obj[f_tmp.join('/')] = f_id;
  47. f_tmp.splice(-(f_depth - _depth + 1));
  48. }
  49.  
  50. f_tmp.push(f_name_trim);
  51. f_id = $(this).attr("id");
  52. });
  53.  
  54. f_obj[f_tmp.join('/')] = f_id;
  55.  
  56. if (torrent_checksum.length !== 0) {
  57. doc.append(`<style>.checksum {
  58. font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
  59. text-align: center;
  60. color: rgb(128, 128, 128);
  61. border-left: none;
  62. border-right: none;
  63. }</style>`);
  64. doc.find("td.rowfollow.dir_size").attr("colspan", "2");
  65. doc.find("tr:first").find("td.colhead:last").attr("colspan", "2");
  66.  
  67. torrent_checksum[0].torrent_files_info.files.forEach(function (item) {
  68. const path = item.path.split("/").slice(1).join("/");
  69. const hash = item.hash;
  70. const f_id = f_obj[path];
  71. const td2 = doc.find(`#${f_id}`).find('td:last');
  72. td2.css({ "border-left": "none" });
  73. td2.before(`<td class="rowfollow checksum">&nbsp;${hash}&nbsp;</td>`)
  74. });
  75. }
  76. response.text = doc.html();
  77. }
  78. })
  79.  
  80. var checkTorrentChecksumPromise, uid, tid, torrent_checksum;
  81.  
  82. function checkTorrentChecksum() {
  83. return new Promise((resolve, reject) => {
  84. if (typeof torrent_checksum !== 'undefined') { resolve(); } else { checkTorrentChecksumPromise = resolve; }
  85. });
  86. }
  87.  
  88. function assignTorrentChecksum() {
  89. if (checkTorrentChecksumPromise) checkTorrentChecksumPromise();
  90. }
  91.  
  92. let em = /.*id=(?<tid>\d{3,5})/i.exec(location.search); if (em) tid = em.groups.tid; else tid = null; // 当前种子ID
  93. uid = $('#info_block').find('a:first').attr('href').match(/\.php\?id=(\d{3,5})/i) || ['', '']; if (uid[1] !== '') uid = uid[1]; // 当前用户ID
  94. const lang = new lang_init($('#locale_selection').val()); // 获取当前网页语言
  95. const db = localforage.createInstance({ name: "history" });
  96. const token = await db.getItem('token');
  97. if (token === null || token.length !== 96) { window.alert('未找到有效 API Token,将无法使用此脚本。') };
  98.  
  99. torrent_checksum = await getApi(uid, token, tid);
  100. assignTorrentChecksum();
  101.  
  102. if (torrent_checksum === 'null') {
  103. $("#closeall").after(`<span id="checksum">[校验和获取失败]</a></span>`);
  104. return;
  105. }
  106.  
  107. if (torrent_checksum.length !== 0) {
  108. $("#closeall").after(`<span id="checksum"><a href="javascript:void(0)">[复制校验和]</a></span>`);
  109.  
  110. const __checksum = [];
  111. torrent_checksum[0].torrent_files_info.files.forEach(function (item) { __checksum.push(`${item.hash} *${item.path}`); });
  112.  
  113. $("#checksum").click(function () {
  114. navigator.clipboard.writeText(__checksum.join('\n')).then(() => {
  115. window.alert('成功')
  116. }).catch(() => {
  117. window.alert('失败 - 可能是你的浏览器太古老了')
  118. });
  119. });
  120. } else {
  121. $("#closeall").after(`<span id="checksum">[无校验和信息]</a></span>`);
  122. }
  123.  
  124. if ($('#showfl').length === 0) {
  125. // 单文件种子
  126. const checksum = torrent_checksum.length !== 0 ? torrent_checksum[0].torrent_files_info.files[0].hash : '---';
  127. $(`td[class='rowhead nowrap']:contains('${lang['torrent_info']}')`).next('td').find('tr:first')
  128. .after(`<tr><td style="border: none;" colspan="4"><b>文件校验和:</b>&nbsp;${checksum}</td></tr>`);
  129. return;
  130. }
  131.  
  132. })();
  133.  
  134. async function getApi(uid, token, tid) {
  135. return new Promise(async (resolve) => {
  136. $.ajax({
  137. type: 'post',
  138. url: 'https://u2.kysdm.com/api/v1/torrent_checksum/',
  139. contentType: "application/json",
  140. dataType: 'json',
  141. data: JSON.stringify({ "uid": uid, "token": token, "torrent_id": tid }),
  142. success: async function (d) {
  143. if (d.msg === 'success') {
  144. return resolve(d.data.torrent);
  145. } else {
  146. window.alert('checksum 获取失败')
  147. return resolve('null');
  148. };
  149. },
  150. error: async function (d) {
  151. window.alert('checksum 获取失败')
  152. return resolve('null');
  153. },
  154. })
  155. })
  156. };
  157.  
  158. function countLeadingSpaces(s) {
  159. return s.length - s.trimStart().length;
  160. }
  161.  
  162. function lang_init(lang) {
  163. const lang_json = {
  164. "zh_CN": {
  165. "torrent_info": "种子信息",
  166. },
  167. "zh_TW": {
  168. "torrent_info": "種子訊息",
  169. },
  170. "zh_HK": {
  171. "torrent_info": "種子訊息",
  172. },
  173. "en_US": {
  174. "torrent_info": "Torrent Info",
  175. },
  176. "ru_RU": {
  177. "torrent_info": "Информация о торренте",
  178. }
  179. };
  180. return lang_json[lang];
  181. };

QingJ © 2025

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