您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
私密种子站点的助手
当前为
- // ==UserScript==
- // @name PT Helper
- // @name:zh-CN PT 助手
- // @version 0.1.0
- // @namespace https://github.com/amorphobia/pt-helper
- // @description A helper for private trackers
- // @description:zh-CN 私密种子站点的助手
- // @author amorphobia
- // @homepage https://github.com/amorphobia/pt-helper
- // @icon data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+IDxzdmcgaWQ9IkxheWVyXzEiIGRhdGEtbmFtZT0iTGF5ZXIgMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmQzOGQ7fS5jbHMtMntmaWxsOiM2ZDQxMzU7fTwvc3R5bGU+PC9kZWZzPjx0aXRsZT5zaGFyZS1maWxsZWQ8L3RpdGxlPjxjaXJjbGUgY2xhc3M9ImNscy0xIiBjeD0iNDA1LjMzIiBjeT0iMTA2LjY3IiByPSI4NS4zMyIvPjxjaXJjbGUgY2xhc3M9ImNscy0xIiBjeD0iNDA1LjMzIiBjeT0iNDA1LjMzIiByPSI4NS4zMyIvPjxjaXJjbGUgY2xhc3M9ImNscy0xIiBjeD0iMTA2LjY3IiBjeT0iMjU2IiByPSI4NS4zMyIvPjxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTQwNS4zMywyOTguNjdhMTA2LjU0LDEwNi41NCwwLDAsMC04My45LDQwLjg2TDIwOS42OSwyODMuNjZhMTA2Ljc4LDEwNi43OCwwLDAsMCwwLTU1LjMxbDExMS43NS01NS44N2ExMDYuMjcsMTA2LjI3LDAsMSwwLTE5LjEzLTM4LjE1TDE5MC41NiwxOTAuMmExMDYuNjcsMTA2LjY3LDAsMSwwLDAsMTMxLjZsMTExLjc1LDU1Ljg3YTEwNi42NywxMDYuNjcsMCwxLDAsMTAzLTc5Wm0wLTI1NmE2NCw2NCwwLDEsMS02NCw2NEE2NC4wNyw2NC4wNywwLDAsMSw0MDUuMzMsNDIuNjdaTTEwNi42NywzMjBhNjQsNjQsMCwxLDEsNjQtNjRBNjQuMDcsNjQuMDcsMCwwLDEsMTA2LjY3LDMyMFpNNDA1LjMzLDQ2OS4zM2E2NCw2NCwwLDEsMSw2NC02NEE2NC4wNyw2NC4wNywwLDAsMSw0MDUuMzMsNDY5LjMzWiIvPjwvc3ZnPg==
- // @supportURL https://github.com/amorphobia/pt-helper/issues
- // @license AGPL-3.0-or-later
- // @match *://hhanclub.top/*
- // @match *://nanyangpt.com/*
- // @match *://pt.sjtu.edu.cn/*
- // @match *://tjupt.org/*
- // @grant GM_addStyle
- // @grant GM_registerMenuCommand
- // @grant GM_unregisterMenuCommand
- // @grant GM_openInTab
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_notification
- // @grant GM_xmlhttpRequest
- // @noframes
- // ==/UserScript==
- /******/ (() => { // webpackBootstrap
- /******/ "use strict";
- /******/ var __webpack_modules__ = ([
- /* 0 */,
- /* 1 */
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
- Object.defineProperty(exports, "__esModule", ({ value: true }));
- exports.Hhanclub = void 0;
- const index_1 = __webpack_require__(2);
- class Hhanclub extends index_1.NexusPHP {
- constructor() {
- super("hhanclub.top");
- this.menu_items = [
- {
- "id": "bannerFold",
- "type": "switch",
- "display": "自动折叠横幅(隐藏时折叠设置无效)",
- "name": "自动折叠横幅",
- "value": true
- },
- {
- "id": "bannerHide",
- "type": "switch",
- "display": "隐藏横幅(隐藏时折叠设置无效)",
- "name": "隐藏横幅",
- "value": false
- }
- ].concat(this.menu_items);
- }
- onLoad() {
- super.onLoad();
- if (this.getHostValue("bannerHide")) {
- this.css += `
- td.clear.nowrap img {
- display: none;
- }`;
- }
- else if (this.getHostValue("bannerFold")) {
- const banner = document.querySelector("td.clear.nowrap");
- const original_height = banner === null || banner === void 0 ? void 0 : banner.clientHeight;
- this.css += `
- td.clear.nowrap img {
- height: 10px;
- overflow: hidden;
- transition: height 0.5s;
- }
- td.clear.nowrap img:hover {
- height: ${original_height}px;
- }`;
- }
- }
- }
- exports.Hhanclub = Hhanclub;
- /***/ }),
- /* 2 */
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
- Object.defineProperty(exports, "__esModule", ({ value: true }));
- exports.NexusPHP = void 0;
- const common_1 = __webpack_require__(3);
- class NexusPHP extends common_1.Common {
- constructor(host) {
- super(host);
- this.passkey = "";
- this.menu_items = [
- {
- "id": "thanks",
- "type": "switch",
- "display": "自动说谢谢",
- "name": "自动说谢谢",
- "value": true
- }
- ].concat(this.menu_items);
- }
- onLoad() {
- super.onLoad();
- this.getPasskey();
- if (this.getHostValue("thanks") && location.href.indexOf("/details.php") >= 0) {
- this.sayThanks();
- }
- }
- getPasskey() {
- const value = this.getHostValue("passkey");
- let passkey = "";
- if (value) {
- passkey = String(value);
- }
- if (passkey != "") {
- this.passkey = passkey;
- return;
- }
- const cp_url = "https://" + this.host + "/usercp.php";
- GM_xmlhttpRequest({
- method: "GET",
- url: cp_url,
- onload: (response) => {
- if (response.status != 200) {
- console.log("Failed to get passkey.");
- return;
- }
- const container = document.implementation.createHTMLDocument().documentElement;
- container.innerHTML = response.responseText;
- const tds = container.querySelectorAll("td.rowfollow");
- for (const td of tds) {
- const tc = td;
- const re = /[\w\d]{32}/;
- const result = re.exec(tc.innerText);
- if (result) {
- this.setHostValue("passkey", result[0]);
- this.passkey = result[0];
- return;
- }
- }
- },
- onabort: () => {
- console.log("Abort to get passkey");
- },
- onerror: () => {
- console.log("Error to get passkey");
- }
- });
- }
- sayThanks() {
- this.wait(2000).then(() => {
- const input = document.querySelector("#saythanks");
- if (input && !input.disabled) {
- input.click();
- }
- }).catch(() => { console.log("Failed to say thanks."); });
- }
- }
- exports.NexusPHP = NexusPHP;
- /***/ }),
- /* 3 */
- /***/ ((__unused_webpack_module, exports) => {
- Object.defineProperty(exports, "__esModule", ({ value: true }));
- exports.Common = void 0;
- const helper_home = "https://github.com/amorphobia/pt-helper";
- const num_emoji = ["0️⃣", "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟"];
- class Common {
- constructor(host) {
- this.host = "";
- this.menu_items = [{
- "id": "feedback",
- "type": "link",
- "display": "💬反馈与建议",
- "value": helper_home + "/issues"
- }];
- this.host = host;
- this.registered_items = [];
- this.css = "";
- }
- init() {
- for (const item of this.menu_items) {
- item.id = this.host + "_" + item.id;
- if ((item.type == "switch" || item.type == "selection") && GM_getValue(item.id) == null) {
- GM_setValue(item.id, item.value);
- }
- }
- this.registerMenu();
- }
- onLoad() { }
- addStyle() {
- if (typeof GM_addStyle !== "undefined") {
- GM_addStyle(this.css);
- }
- else {
- const style = document.createElement("style");
- style.appendChild(document.createTextNode(this.css));
- (document.querySelector("head") || document.documentElement).appendChild(style);
- }
- }
- registerMenu() {
- for (const item of this.registered_items) {
- GM_unregisterMenuCommand(item);
- }
- this.registered_items = [];
- for (const item of this.menu_items) {
- const value = GM_getValue(item.id);
- if (value && value != null) {
- item.value = value;
- }
- let reg_item;
- switch (item.type) {
- case "switch":
- reg_item = GM_registerMenuCommand(`${item.value ? "✅" : "❌"}${item.display}`, () => {
- this.toggleSwitch(item);
- });
- break;
- case "selection":
- reg_item = GM_registerMenuCommand(`${num_emoji[item.value]}${item.display[item.value]}`, () => {
- this.nextSelection(item);
- });
- break;
- case "link":
- reg_item = GM_registerMenuCommand(`${item.display}`, () => {
- GM_openInTab(item.value, { active: true, insert: true, setParent: true });
- });
- break;
- case "text":
- reg_item = GM_registerMenuCommand(`${item.display}`, () => { });
- break;
- default:
- console.log(`Unrecognized menu item: ${item.id}`);
- break;
- }
- if (reg_item !== undefined) {
- this.registered_items.push(reg_item);
- }
- }
- }
- toggleSwitch(item) {
- const status = item.value ? "关闭" : "开启";
- GM_setValue(item.id, !item.value);
- GM_notification({
- text: `已${status}「${item.name}」\n(点击刷新网页后生效)`,
- timeout: 3500,
- onclick: () => { location.reload(); }
- });
- this.registerMenu();
- }
- nextSelection(item) {
- const new_value = (item.value + 1) % item.display.length;
- GM_setValue(item.id, new_value);
- GM_notification({
- text: `切换为「${item.display[new_value]}」\n(点击刷新网页后生效)`,
- timeout: 3500,
- onclick: () => { location.reload(); }
- });
- this.registerMenu();
- }
- wait(ms) {
- return new Promise((resolve, reject) => {
- setTimeout(resolve, ms);
- });
- }
- getHostValue(id) {
- return GM_getValue(this.host + "_" + id);
- }
- setHostValue(id, value) {
- GM_setValue(this.host + "_" + id, value);
- }
- }
- exports.Common = Common;
- /***/ }),
- /* 4 */
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
- Object.defineProperty(exports, "__esModule", ({ value: true }));
- exports.NanyangPT = void 0;
- const NexusPHP_1 = __webpack_require__(2);
- class NanyangPT extends NexusPHP_1.NexusPHP {
- constructor() {
- super("nanyangpt.com");
- this.menu_items = [
- {
- "id": "bannerHide",
- "type": "switch",
- "display": "隐藏横幅",
- "name": "隐藏横幅",
- "value": false
- }
- ].concat(this.menu_items);
- }
- onLoad() {
- super.onLoad();
- if (this.getHostValue("bannerHide")) {
- const info = document.querySelector("#info_block");
- const info_height = (info === null || info === void 0 ? void 0 : info.clientHeight) ? info.clientHeight + 5 : 30;
- this.css += `
- table.head {
- display: none;
- }
- table.mainouter {
- margin-top: ${info_height}px;
- }`;
- }
- }
- }
- exports.NanyangPT = NanyangPT;
- /***/ }),
- /* 5 */
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
- Object.defineProperty(exports, "__esModule", ({ value: true }));
- exports.SJTU = void 0;
- const index_1 = __webpack_require__(2);
- class SJTU extends index_1.NexusPHP {
- constructor() {
- super("pt.sjtu.edu.cn");
- }
- }
- exports.SJTU = SJTU;
- /***/ }),
- /* 6 */
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
- Object.defineProperty(exports, "__esModule", ({ value: true }));
- exports.TJUPT = void 0;
- const index_1 = __webpack_require__(2);
- class TJUPT extends index_1.NexusPHP {
- constructor() {
- super("tjupt.org");
- this.menu_items = [
- {
- "id": "bannerFold",
- "type": "switch",
- "display": "自动折叠横幅(隐藏时折叠设置无效)",
- "name": "自动折叠横幅",
- "value": true
- },
- {
- "id": "bannerHide",
- "type": "switch",
- "display": "隐藏横幅(隐藏时折叠设置无效)",
- "name": "隐藏横幅",
- "value": false
- },
- {
- "id": "stickyHide",
- "type": "selection",
- "display": [
- "显示所有置顶",
- "隐藏一重置顶",
- "隐藏一、二重置顶",
- "隐藏所有置顶"
- ],
- "value": 0
- },
- {
- "id": "directLink",
- "type": "switch",
- "display": "种子直链按钮(左键点击按钮复制直链)",
- "name": "种子直链",
- "value": true
- },
- {
- "id": "colorBlind",
- "type": "switch",
- "display": "色盲模式",
- "name": "色盲模式",
- "value": false
- }
- ].concat(this.menu_items);
- }
- onLoad() {
- var _a;
- super.onLoad();
- if (this.getHostValue("bannerHide")) {
- this.css += `
- .logo_img img {
- display: none;
- }`;
- }
- else if (this.getHostValue("bannerFold")) {
- const logo_img = document.querySelector(".logo_img");
- const original_height = logo_img === null || logo_img === void 0 ? void 0 : logo_img.clientHeight;
- this.css += `
- .logo_img {
- height: 10px;
- overflow: hidden;
- transition: height 0.5s;
- }
- .logo_img:hover {
- height: ${original_height}px;
- }`;
- }
- switch (this.getHostValue("stickyHide")) {
- case 3:
- this.css += `
- .triple_sticky_bg {
- display: none;
- }`;
- case 2:
- this.css += `
- .double_sticky_bg {
- display: none;
- }`;
- case 1:
- this.css += `
- .sticky_bg {
- display: none;
- }`;
- default:
- break;
- }
- if (this.getHostValue("directLink") && this.passkey != "") {
- const id_re = /id=[\d]+/;
- const tds = document.querySelectorAll("table.torrentname > tbody > tr:nth-of-type(1) > td:nth-of-type(3)");
- for (const td of tds) {
- const dl = td.querySelector("a");
- const result = id_re.exec((_a = dl === null || dl === void 0 ? void 0 : dl.href) !== null && _a !== void 0 ? _a : "");
- if (!result) {
- continue;
- }
- const direct_link = `https://www.${this.host}/download.php?${result[0]}&passkey=${this.passkey}`;
- const img = document.createElement("img");
- img.setAttribute("src", "pic/trans.gif");
- img.setAttribute("class", "torrent_direct_link");
- img.setAttribute("alt", "DL");
- const a = document.createElement("a");
- a.setAttribute("title", "左键单击复制,链接中包含个人秘钥Passkey,切勿泄露!");
- a.setAttribute("onclick", "return false");
- a.setAttribute("id", "direct_link");
- a.setAttribute("href", direct_link);
- a.setAttribute("data-clipboard-text", direct_link);
- a.appendChild(img);
- td.prepend(a);
- }
- this.css += `
- img.torrent_direct_link {
- width: 16px;
- height: 16px;
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAH5QTFRFR3BMyKN4cz0Td3d3sLCw6enp////qHg4oaGhcz0TlpaWkV8opnU2lmQrjVklqHg4m2kvo3I03ruJiFMhn24y4r+N2raG5cSP9+jQg04e1rKD68uUnYpv6ceS0q5/fkkaoaGhzqp8h4eHr6+v+Pj4ekQXdkAV+/v78fHxy6Z6f0p3WgAAAAp0Uk5TAP///////5aWlrne7esAAACHSURBVBjTbc5HEsIwEERRA5qxLeecc77/BTEN0oq/m1ddKhnG36xxtPRhBq2UxyFlG5gAt5zXk+hc59IFRM3yQksTAdKOf3UpICxYCEFEXIQAL2NCnHkAJ/4s7jh2AH6uFrkPSOrvgrhOAFWvFn0FGCYWhDemAbBd6h/XBtgfuh1gP3X2fb4BlrkIUt3i2kgAAAAASUVORK5CYII=');
- padding-bottom: 1px;
- }`;
- location.assign("javascript:registerClipboardJS('#direct_link');void(0)");
- }
- if (this.getHostValue("colorBlind")) {
- if (location.href.indexOf("/classes.php") >= 0) {
- const spans = document.querySelectorAll("table.main > tbody > tr > td:nth-of-type(2) > ul > li > span[style=\"color: green\"]");
- for (const span of spans) {
- span.setAttribute("style", "color: blue");
- }
- }
- }
- }
- getPasskey() {
- const value = this.getHostValue("passkey");
- let passkey = "";
- if (value) {
- passkey = String(value);
- }
- if (passkey != "") {
- this.passkey = passkey;
- return;
- }
- const link = document.querySelector("[title=\"Latest Torrents\"]");
- const re = /passkey=([\d\w]+)/;
- const result = re.exec(link.href);
- this.passkey = result && result.length > 1 ? result[1] : "";
- if (this.passkey != "") {
- this.setHostValue("passkey", this.passkey);
- }
- }
- }
- exports.TJUPT = TJUPT;
- /***/ })
- /******/ ]);
- /************************************************************************/
- /******/ // The module cache
- /******/ var __webpack_module_cache__ = {};
- /******/
- /******/ // The require function
- /******/ function __webpack_require__(moduleId) {
- /******/ // Check if module is in cache
- /******/ var cachedModule = __webpack_module_cache__[moduleId];
- /******/ if (cachedModule !== undefined) {
- /******/ return cachedModule.exports;
- /******/ }
- /******/ // Create a new module (and put it into the cache)
- /******/ var module = __webpack_module_cache__[moduleId] = {
- /******/ // no module.id needed
- /******/ // no module.loaded needed
- /******/ exports: {}
- /******/ };
- /******/
- /******/ // Execute the module function
- /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
- /******/
- /******/ // Return the exports of the module
- /******/ return module.exports;
- /******/ }
- /******/
- /************************************************************************/
- var __webpack_exports__ = {};
- // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
- (() => {
- var exports = __webpack_exports__;
- Object.defineProperty(exports, "__esModule", ({ value: true }));
- const hhanclub_top_1 = __webpack_require__(1);
- const nanyangpt_com_1 = __webpack_require__(4);
- const pt_sjtu_edu_cn_1 = __webpack_require__(5);
- const index_1 = __webpack_require__(6);
- const host = window.location.host;
- const sites = new Map([
- ["hhanclub.top", new hhanclub_top_1.Hhanclub()],
- ["nanyangpt.com", new nanyangpt_com_1.NanyangPT()],
- ["pt.sjtu.edu.cn", new pt_sjtu_edu_cn_1.SJTU()],
- ["tjupt.org", new index_1.TJUPT()]
- ]);
- const site = sites.get(host);
- if (site) {
- site.init();
- site.onLoad();
- site.addStyle();
- }
- })();
- /******/ })()
- ;