auto-open-sheet

目前為 2025-01-07 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         auto-open-sheet
// @namespace    http://tampermonkey.net/
// @description:zh-CN  自动打开当前页的种子!,配合auto-say-hello-plus插件有意想不到的效果!如果未匹配成功请联系我:[email protected]
// @description:en  自动打开当前页的种子!,配合auto-say-hello-plus插件有意想不到的效果!如果未匹配成功请联系我:[email protected]
// @license MIT
// @author       wiiii
// @version      1.0
// @email        [email protected]
// @copyright (c) 2025-01-01
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @match        *://pt.m-team.cc/*torrents.php*
// @match        *://kp.m-team.cc/*torrents.php*
// @match        *://xp.m-team.io/*torrents.php*
// @match        *://pt.btschool.club/torrents.php*
// @match        *://www.haidan.video/torrents.php*
// @match        *://www.hddolby.com/torrents.php*
// @match        *://www.hdarea.co/torrents.php*
// @match        *://hdatmos.club/torrents.php*
// @match        *://hdhome.org/torrents.php*
// @match        *://hdsky.me/torrents.php*
// @match        *://hdtime.org/torrents.php*
// @match        *://hhanclub.top/torrents.php*
// @match        *://lemonhd.org/details*
// @match        *://pt.soulvoice.club/torrents.php*
// @match        *://avgv.cc/torrents.php*
// @match        *://ptsbao.club/torrents.php*
// @match        *://www.beitai.pt/torrents.php*
// @match        *://et8.org/torrents.php*
// @match        *://pt.eastgame.org/torrents.php*
// @match        *://pthome.net/torrents.php*
// @match        *://pterclub.com/torrents.php*
// @match        *://ourbits.club/torrents.php*
// @match        *://hdzone.me/torrents.php*
// @match        *://pt.msg.vg/torrents.php*
// @match        *://hdfans.org/torrents.php*
// @match        *://rousi.zip/torrents.php*
// @match        *://carpt.net/torrents.php*
// @match        *://www.tjupt.org/torrents.php*
// @match        *://yingk.com/torrents.php*
// @match        *://www.dragonhd.xyz/torrents.php*
// @match        *://chdbits.co/torrents.php*
// @grant        none
// ==/UserScript==


(function () {
    'use strict';

    // 配置参数
    const maxLinksToOpen = 10; // 最多同时打开的链接数
    const minIntervalTime = 3000; // 每次打开的最小间隔(毫秒)
    const maxIntervalTime = 10000; // 每次打开的最大间隔(毫秒)
    const storageKey = 'openedLinks'; // localStorage 键名,用于记录已打开的链接
    const userPromptKey = 'userPrompt'; // localStorage 键名,用于记录用户选择和时间
    const regex = /^details\.php\?id=(\d+)&hit=1$/; // 链接匹配规则

    // 辅助函数:获取当前时间的时间戳
    function getCurrentTimestamp() {
        return new Date().getTime(); // 获取时间戳(毫秒)
    }

    // 辅助函数:获取用户提示记录
    function getUserPromptRecord() {
        return JSON.parse(localStorage.getItem(userPromptKey));
    }

    // 辅助函数:保存用户提示记录
    function saveUserPromptRecord(confirmed) {
        const record = {
            confirmed, // 用户选择:true 表示确认开启,false 表示取消
            timestamp: getCurrentTimestamp() // 当前时间
        };
        localStorage.setItem(userPromptKey, JSON.stringify(record));
    }

    // 辅助函数:获取已打开链接记录
    function getOpenedLinks() {
        return JSON.parse(localStorage.getItem(storageKey)) || [];
    }

    // 辅助函数:保存已打开链接记录
    function saveOpenedLinks(openedLinks) {
        localStorage.setItem(storageKey, JSON.stringify(openedLinks));
    }

    // 辅助函数:在右上角显示提示信息
    function showNotification(message) {
        // 创建提示框容器
        const notification = document.createElement('div');
        notification.textContent = message;
        notification.style.position = 'fixed';
        notification.style.top = '20px';
        notification.style.right = '20px';
        notification.style.zIndex = '9999';
        notification.style.backgroundColor = '#007bff';
        notification.style.color = '#fff';
        notification.style.padding = '10px 20px';
        notification.style.borderRadius = '5px';
        notification.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)';
        notification.style.fontFamily = 'Arial, sans-serif';
        notification.style.fontSize = '14px';

        // 添加到页面中
        document.body.appendChild(notification);

        // 设置定时器,3秒后自动移除提示
        setTimeout(() => {
            notification.remove();
        }, 3000);
    }

    // 主逻辑:后台打开符合条件的链接
    function startOpeningLinks() {
        const openedLinks = getOpenedLinks(); // 获取已打开的链接记录
        const links = document.querySelectorAll('a'); // 获取页面中所有的 <a> 标签

        // 筛选出符合条件的链接
        const matchedLinks = [];
        links.forEach(link => {
            const href = link.getAttribute('href');
            if (href && regex.test(href)) {
                const match = href.match(regex);
                const id = match[1]; // 提取链接中的 ID
                const domainWithId = `${location.hostname}:${id}`; // 组合为 "域名:ID"

                if (!openedLinks.includes(domainWithId)) {
                    matchedLinks.push({ link, domainWithId }); // 存储符合条件的链接和 ID
                }
            }
        });

        if (matchedLinks.length === 0) {
            // 当前页面所有链接都已访问过,右上角提示用户打开下一页
            showNotification('当前页面的所有链接都已打开,请打开下一页!');
            console.log('%c 当前页面的所有链接都已打开,请打开下一页!', 'color: orange;');
            return;
        }

        console.log(`%c 找到 ${matchedLinks.length} 个符合条件的未访问链接,最多打开 ${maxLinksToOpen} 个。`, 'color: blue;');
        console.table(matchedLinks);

        // 限制最多打开的链接数量
        const linksToOpen = matchedLinks.slice(0, maxLinksToOpen);

        let index = 0;

        // 递归方式逐一打开链接
        function openNextLink() {
            if (index >= linksToOpen.length) {
                console.log('%c 所有链接已按设置打开,任务完成。', 'color: green;');
                return; // 所有链接已打开,退出递归
            }

            const { link, domainWithId } = linksToOpen[index];

            try {
                // 使用 window.open 打开链接,并确保当前页面视角不切换
                window.open(link.href, '_blank', 'noopener,noreferrer');
                console.log(`%c 成功后台打开链接 (${index + 1}/${linksToOpen.length}): ${link.href}`, 'color: green;');

                // 记录已打开链接
                openedLinks.push(domainWithId);
                saveOpenedLinks(openedLinks);
            } catch (error) {
                console.log(`%c 打开链接失败 (${index + 1}/${linksToOpen.length}): ${link.href}`, 'color: red;', error);
            }

            index++; // 处理下一个链接

            // 随机设置下一个打开的时间间隔
            const randomInterval = Math.floor(Math.random() * (maxIntervalTime - minIntervalTime + 1)) + minIntervalTime;
            console.log(`%c 下一个链接将在 ${randomInterval / 1000} 秒后尝试打开。`, 'color: orange;');

            setTimeout(openNextLink, randomInterval); // 递归调用
        }

        // 开始递归调用
        openNextLink();
    }

    // 页面加载时执行主逻辑
    window.onload = function () {
        const record = getUserPromptRecord();

        // 如果用户已开启功能,直接执行打开链接逻辑
        if (record && record.confirmed) {
            console.log('%c 功能已开启,直接执行打开链接逻辑。', 'color: green;');
            startOpeningLinks();
        } else {
            console.log('%c 功能未开启,跳过打开链接逻辑。', 'color: orange;');
        }
    };
})();