PT种子认领管理助手

提供种子认领管理功能,包括悬浮窗显示总体积、检查当月种子并一键放弃不达标种子等功能

// ==UserScript==
// @name         PT种子认领管理助手
// @namespace    http://tampermonkey.net/
// @version      1.8.3
// @description  提供种子认领管理功能,包括悬浮窗显示总体积、检查当月种子并一键放弃不达标种子等功能
// @author       AI Assistant
// @match        */claim.php*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 全局变量存储状态
    let totalSize = 0;
    let abandonedCount = 0;
    let abandonedSize = 0;
    let nonCompletableTorrents = [];
    let zeroSeedTimeTorrents = [];
    let processingTorrent = false;
    let autoConfirmDialogs = false;
    let lastUrl = window.location.href; // 记录当前URL用于检测变化
    let panelInitialized = false; // 标记悬浮窗是否已初始化

    // 创建存储对象用于保存数据
    const storageKey = 'PT_SEED_MANAGER_DATA';
    const pendingKey = 'PT_PENDING_ABANDONS';
    const sessionStatsKey = 'PT_SESSION_STATS';
    const processingKey = 'PT_PROCESSING_ACTIVE';
    let savedData = loadData();

    // 页面加载完成后初始化
    window.addEventListener('load', init);

    // 定期检查悬浮窗是否存在,如果不存在则重新创建
    setInterval(checkPanelExists, 1000);

    // 监听URL变化
    setInterval(checkUrlChange, 500);

    // 检查URL变化,用于处理翻页
    function checkUrlChange() {
        if (lastUrl !== window.location.href) {
            console.log('URL已变化,重新初始化面板');
            lastUrl = window.location.href;
            // 清除面板初始化标记
            panelInitialized = false;
            // 延迟一下确保DOM已加载
            setTimeout(initOrUpdatePanel, 800);
        }
    }

    // 检查面板是否存在
    function checkPanelExists() {
        if (!document.getElementById('cyberPanel') && document.readyState === 'complete') {
            console.log('未找到面板,重新初始化');
            initOrUpdatePanel();
        }
    }

    // 初始化或更新面板
    function initOrUpdatePanel() {
        // 如果已有面板,移除它
        const existingPanel = document.getElementById('cyberPanel');
        if (existingPanel) {
            existingPanel.remove();
        }

        // 重新初始化
        init();
    }

    // 监听分页按钮点击
    function setupPaginationListeners() {
        const paginationLinks = document.querySelectorAll('.nexus-pagination a');
        if (paginationLinks.length > 0) {
            paginationLinks.forEach(link => {
                link.addEventListener('click', function() {
                    // 标记面板需要重新初始化
                    panelInitialized = false;
                });
            });
        }
    }

    function init() {
        if (panelInitialized) return;

        // 获取当前日期并计算本月剩余天数
        const today = new Date();
        const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
        const remainingDays = lastDayOfMonth.getDate() - today.getDate() + 1; // 包括今天

        // 创建悬浮窗
        createFloatingPanel(remainingDays);

        // 分析页面中的种子数据
        analyzeTorrents();

        // 监视页面变化,查找确认对话框
        setupDialogObserver();

        // 检查是否有未完成的放弃操作
        checkPendingAbandons();

        // 设置分页监听器
        setupPaginationListeners();

        panelInitialized = true;
    }

    function createFloatingPanel(remainingDays) {
        const panel = document.createElement('div');
        panel.id = 'cyberPanel';
        panel.style.cssText = `
            position: fixed;
            top: 100px;
            right: 20px;
            width: 300px;
            background-color: rgba(0, 0, 0, 0.8);
            border: 1px solid #00FF88;
            border-radius: 10px;
            padding: 15px;
            color: white;
            font-family: 'Courier New', monospace;
            z-index: 9999;
            box-shadow: 0 0 10px rgba(0, 255, 136, 0.5);
        `;

        // 获取会话统计信息
        const sessionStats = JSON.parse(localStorage.getItem(sessionStatsKey) || '{"count":0,"size":0,"total":0}');

        // 添加标题和内容
        panel.innerHTML = `
            <h2 style="color:#00FF88;margin:0 0 15px">种子认领管理</h2>
            <div id="totalSize">当前页总做种体积: 计算中...</div>
            <div id="abandonedStats">总计已放弃: ${savedData.abandonedCount || 0}个种子 (${formatSize(savedData.abandonedSize || 0)})</div>
            <div id="remainingDays">本月剩余天数: ${remainingDays}天</div>
            <button class="control-btn" id="mainSwitch" style="margin-top:10px;background:#22aa22;color:white;border:none;padding:5px 10px;border-radius:5px;cursor:pointer;">
                启动系统
            </button>
            <div style="margin-top:15px">
                <label style="display:block;margin:10px 0">
                    <input type="checkbox" id="abandonZeroSeed" ${savedData.abandonZeroSeed ? 'checked' : ''}>
                    删除0天做种种子
                </label>
                <label style="display:block;margin:10px 0">
                    <input type="checkbox" id="abandonNonCompletable" ${savedData.abandonNonCompletable ? 'checked' : ''}>
                    删除本月不达标种子
                </label>
                <label style="display:block;margin:10px 0">
                    <input type="checkbox" id="processNewTorrents" ${savedData.processNewTorrents ? 'checked' : ''}>
                    自动处理新发现的不达标种子
                </label>
                <label style="display:block;margin:10px 0">
                    <input type="checkbox" id="debugMode" ${savedData.debugMode ? 'checked' : ''}>
                    调试模式
                </label>
            </div>
            <div id="processingStats" style="margin-top:10px;display:${sessionStats.total > 0 ? 'block' : 'none'};">
                <div>处理进度: <span id="progressCount">${sessionStats.count}</span>/<span id="totalCount">${sessionStats.total}</span></div>
                <div>已放弃: <span id="currentAbandoned">${sessionStats.count}</span> 个种子</div>
                <div>已放弃体积: <span id="currentAbandonedSize">${formatSize(sessionStats.size)}</span></div>
                <button id="stopProcessing" style="margin-top:5px;background:#cc0000;color:white;border:none;padding:3px 8px;border-radius:3px;cursor:pointer;">
                    停止处理
                </button>
            </div>
        `;

        document.body.appendChild(panel);

        // 添加按钮点击事件
        document.getElementById('mainSwitch').addEventListener('click', toggleSystem);
        document.getElementById('abandonZeroSeed').addEventListener('change', saveSettings);
        document.getElementById('abandonNonCompletable').addEventListener('change', saveSettings);
        document.getElementById('processNewTorrents').addEventListener('change', saveSettings);

        // 停止处理按钮事件
        const stopButton = document.getElementById('stopProcessing');
        if (stopButton) {
            stopButton.addEventListener('click', function() {
                localStorage.removeItem(pendingKey);
                localStorage.removeItem(sessionStatsKey);
                localStorage.removeItem(processingKey);
                document.getElementById('processingStats').style.display = 'none';
                alert('已停止处理队列');
            });
        }

        // 调试模式按钮
        document.getElementById('debugMode').addEventListener('change', function() {
            saveSettings();
            if (this.checked) {
                console.log('调试模式已启用');
                console.log(`总种子数: ${document.querySelectorAll('#claim-table tr:not(:first-child)').length}`);
                console.log(`0天做种种子数: ${zeroSeedTimeTorrents.length}`);
                console.log(`不达标种子数: ${nonCompletableTorrents.length}`);
                console.log(`总做种体积: ${formatSize(totalSize)}`);
                console.log('待处理队列:', JSON.parse(localStorage.getItem(pendingKey) || '[]'));
            }
        });

        // 恢复之前的状态
        if (savedData.systemActive) {
            document.getElementById('mainSwitch').click();
        }
    }

    function toggleSystem() {
        const mainSwitch = document.getElementById('mainSwitch');

        if (mainSwitch.textContent.trim() === '启动系统') {
            // 启动系统
            mainSwitch.textContent = '系统运行中';
            mainSwitch.style.backgroundColor = '#aa2222';
            analyzeTorrents(); // 重新分析并标记

            // 添加"一键放弃"按钮
            let abandonButton = document.getElementById('abandonButton');
            if (!abandonButton) {
                abandonButton = document.createElement('button');
                abandonButton.id = 'abandonButton';
                abandonButton.className = 'control-btn';
                abandonButton.textContent = '一键放弃选定种子';
                abandonButton.style.cssText = 'margin-top:10px;background:#880000;color:white;border:none;padding:5px 10px;border-radius:5px;cursor:pointer;';
                abandonButton.addEventListener('click', abandonSelectedTorrents);
                mainSwitch.parentNode.insertBefore(abandonButton, mainSwitch.nextSibling);
            } else {
                abandonButton.style.display = 'block';
            }
        } else {
            // 关闭系统
            mainSwitch.textContent = '启动系统';
            mainSwitch.style.backgroundColor = '#22aa22';
            resetTorrentHighlights();

            // 隐藏放弃按钮
            const abandonButton = document.getElementById('abandonButton');
            if (abandonButton) {
                abandonButton.style.display = 'none';
            }
        }

        saveSettings();
    }

    function saveSettings() {
        savedData = {
            systemActive: document.getElementById('mainSwitch').textContent.trim() === '系统运行中',
            abandonZeroSeed: document.getElementById('abandonZeroSeed').checked,
            abandonNonCompletable: document.getElementById('abandonNonCompletable').checked,
            processNewTorrents: document.getElementById('processNewTorrents').checked,
            debugMode: document.getElementById('debugMode').checked,
            abandonedCount: abandonedCount,
            abandonedSize: abandonedSize
        };

        localStorage.setItem(storageKey, JSON.stringify(savedData));

        // 如果系统处于活动状态,更新高亮显示和按钮状态
        if (savedData.systemActive) {
            analyzeTorrents(); // 重新分析并标记

            // 确保放弃按钮存在
            const abandonButton = document.getElementById('abandonButton');
            if (!abandonButton) {
                const mainSwitch = document.getElementById('mainSwitch');
                const newButton = document.createElement('button');
                newButton.id = 'abandonButton';
                newButton.className = 'control-btn';
                newButton.textContent = '一键放弃选定种子';
                newButton.style.cssText = 'margin-top:10px;background:#880000;color:white;border:none;padding:5px 10px;border-radius:5px;cursor:pointer;';
                newButton.addEventListener('click', abandonSelectedTorrents);
                mainSwitch.parentNode.insertBefore(newButton, mainSwitch.nextSibling);
            } else {
                abandonButton.style.display = 'block';
            }
        }
    }

    function loadData() {
        try {
            const data = localStorage.getItem(storageKey);
            if (data) {
                const parsedData = JSON.parse(data);
                // 恢复保存的统计数据
                abandonedCount = parsedData.abandonedCount || 0;
                abandonedSize = parsedData.abandonedSize || 0;
                return parsedData;
            }
            return {};
        } catch (e) {
            console.error('加载存储数据时出错:', e);
            return {};
        }
    }

    // 修复: 重新计算剩余天数,并改进判定逻辑
    function analyzeTorrents() {
        // 重新计算剩余天数,避免使用旧值
        const today = new Date();
        const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
        const remainingDays = lastDayOfMonth.getDate() - today.getDate() + 1; // 包括今天

        const torrentRows = document.querySelectorAll('#claim-table tr:not(:first-child)');
        totalSize = 0;
        nonCompletableTorrents = [];
        zeroSeedTimeTorrents = [];

        const debugMode = document.getElementById('debugMode')?.checked;

        if (debugMode) {
            console.log(`当前日期: ${today.toLocaleDateString()}, 本月剩余天数: ${remainingDays}天`);
        }

        torrentRows.forEach((row, index) => {
            // 提取种子信息
            const removeButton = row.querySelector('button[data-action="removeClaim"]');
            if (!removeButton) return;  // 跳过没有放弃按钮的行

            const claimId = removeButton.getAttribute('data-claim_id');
            const torrentId = removeButton.getAttribute('data-torrent_id');
            const torrentName = row.querySelectorAll('td')[2].textContent.trim();
            const sizeText = row.querySelectorAll('td')[3].textContent.trim();
            const seedTimeText = row.querySelectorAll('td')[7].textContent.trim();
            const isCompletedCell = row.querySelectorAll('td')[9];
            const isCompleted = isCompletedCell.textContent.trim();

            // 计算总体积
            const sizeValue = parseSize(sizeText);
            totalSize += sizeValue;

            // 分析种子是否能完成做种要求
            const seedTimeDays = parseSeedTime(seedTimeText);

            // 修复: 直接使用页面显示的达标状态,不再自己计算
            // 如果页面显示"Yes"则认为达标,如果显示"No"则判断是否可能达标
            const canComplete = isCompleted === 'Yes' || (seedTimeDays > 0 && seedTimeDays + remainingDays >= 14);

            if (debugMode) {
                console.log(`种子 #${index + 1}: ${torrentName}`);
                console.log(`  做种时间: ${seedTimeText} (${seedTimeDays.toFixed(2)}天)`);
                console.log(`  页面显示是否达标: ${isCompleted}`);
                console.log(`  计算结果: 做种时间 ${seedTimeDays.toFixed(2)} + 剩余天数 ${remainingDays} = ${(seedTimeDays + remainingDays).toFixed(2)} 天`);
                console.log(`  判定结果: ${canComplete ? '达标(绿色)' : '不达标(红色)'}`);
            }

            // 直接修改"本月是否达标"列的颜色
            if (document.getElementById('mainSwitch').textContent.trim() === '系统运行中') {
                isCompletedCell.style.backgroundColor = canComplete ? 'rgba(0, 255, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)';
            } else {
                isCompletedCell.style.backgroundColor = '';
            }

            // 保存不能完成的种子信息
            if (!canComplete) {
                const torrentInfo = {
                    row: row,
                    claimId: claimId,
                    torrentId: torrentId,
                    torrentName: torrentName,
                    size: sizeValue,
                    sizeText: sizeText,
                    seedTimeDays: seedTimeDays
                };

                nonCompletableTorrents.push(torrentInfo);

                // 特别标记0天做种的种子
                if (seedTimeDays === 0) {
                    zeroSeedTimeTorrents.push(torrentInfo);
                }
            }
        });

        // 更新悬浮窗信息
        document.getElementById('totalSize').textContent = `总做种体积: ${formatSize(totalSize)}`;

        // 如果启用了调试模式,则显示更多信息
        if (debugMode) {
            console.log(`总种子数: ${torrentRows.length}`);
            console.log(`0天做种种子数: ${zeroSeedTimeTorrents.length}`);
            console.log(`不达标种子数: ${nonCompletableTorrents.length}`);
            console.log(`总做种体积: ${formatSize(totalSize)}`);
        }
    }

    function resetTorrentHighlights() {
        const torrentRows = document.querySelectorAll('#claim-table tr:not(:first-child)');
        torrentRows.forEach(row => {
            // 清除所有本月达标列的背景色
            const isCompletedCell = row.querySelectorAll('td')[9];
            if (isCompletedCell) {
                isCompletedCell.style.backgroundColor = '';
            }
        });
    }

    function abandonSelectedTorrents() {
        // 检查选项
        const abandonZeroSeed = document.getElementById('abandonZeroSeed').checked;
        const abandonNonCompletable = document.getElementById('abandonNonCompletable').checked;

        // 至少选择一个选项
        if (!abandonZeroSeed && !abandonNonCompletable) {
            alert('请至少选择一个放弃选项(删除0天做种种子或删除本月不达标种子)');
            return;
        }

        // 确定要放弃的种子列表
        let torrentsToAbandon = [];

        if (abandonZeroSeed) {
            torrentsToAbandon = torrentsToAbandon.concat(zeroSeedTimeTorrents);
        }

        if (abandonNonCompletable) {
            // 如果已经包含了0天种子,需要过滤掉重复的
            const nonZeroNonCompletable = nonCompletableTorrents.filter(torrent =>
                torrent.seedTimeDays > 0 || !abandonZeroSeed
            );
            torrentsToAbandon = torrentsToAbandon.concat(nonZeroNonCompletable);
        }

        // 去除重复项
        const uniqueTorrents = [];
        const seen = new Set();

        torrentsToAbandon.forEach(torrent => {
            if (!seen.has(torrent.claimId)) {
                seen.add(torrent.claimId);
                uniqueTorrents.push(torrent);
            }
        });

        torrentsToAbandon = uniqueTorrents;

        if (torrentsToAbandon.length === 0) {
            alert('没有需要放弃的种子');
            return;
        }

        // 检查是否已有处理队列
        if (localStorage.getItem(pendingKey)) {
            if (!confirm('已有正在处理的队列,是否重新开始?')) {
                return;
            }
        }

        if (!confirm(`确定要放弃 ${torrentsToAbandon.length} 个种子吗?`)) {
            return;
        }

        // 将种子信息保存到队列
        const pendingList = torrentsToAbandon.map(t => ({
            claimId: t.claimId,
            torrentId: t.torrentId,
            size: t.size,
            name: t.torrentName
        }));

        // 保存队列到localStorage
        localStorage.setItem(pendingKey, JSON.stringify(pendingList));
        localStorage.setItem(processingKey, 'true');

        // 初始化会话统计数据
        localStorage.setItem(sessionStatsKey, JSON.stringify({
            count: 0,
            size: 0,
            total: pendingList.length
        }));

        // 显示处理统计面板
        const processingStats = document.getElementById('processingStats');
        processingStats.style.display = 'block';
        document.getElementById('totalCount').textContent = pendingList.length;
        document.getElementById('progressCount').textContent = '0';
        document.getElementById('currentAbandoned').textContent = '0';
        document.getElementById('currentAbandonedSize').textContent = '0 B';

        // 开始处理第一个种子
        processNextTorrent();
    }

    // 检查是否有未完成的放弃操作
    function checkPendingAbandons() {
        const pendingList = JSON.parse(localStorage.getItem(pendingKey) || '[]');
        const isProcessing = localStorage.getItem(processingKey) === 'true';

        if (pendingList.length > 0 && isProcessing) {
            // 如果有待处理的种子,继续处理
            const stats = JSON.parse(localStorage.getItem(sessionStatsKey) || '{"count":0,"size":0,"total":0}');

            // 更新统计显示
            document.getElementById('processingStats').style.display = 'block';
            document.getElementById('totalCount').textContent = stats.total;
            document.getElementById('progressCount').textContent = stats.count;
            document.getElementById('currentAbandoned').textContent = stats.count;
            document.getElementById('currentAbandonedSize').textContent = formatSize(stats.size);

            // 延迟一会再处理,确保页面完全加载
            setTimeout(processNextTorrent, 1000);
        } else if (pendingList.length === 0 && isProcessing) {
            // 队列为空但仍处于处理状态,说明刚刚完成
            finishAbandonProcess();

            // 检查是否需要自动处理新种子
            checkForNewTorrents();
        } else {
            // 隐藏处理统计面板
            const processingStats = document.getElementById('processingStats');
            if (processingStats) {
                processingStats.style.display = 'none';
            }
        }
    }

    // 处理队列中的下一个种子
    function processNextTorrent() {
        // 获取待处理队列
        const pendingList = JSON.parse(localStorage.getItem(pendingKey) || '[]');

        if (pendingList.length === 0) {
            // 所有种子处理完成
            finishAbandonProcess();
            return;
        }

        // 取出第一个种子
        const torrent = pendingList[0];

        // 在页面上查找对应的放弃按钮
        const abandonButton = document.querySelector(`button[data-action="removeClaim"][data-claim_id="${torrent.claimId}"]`);

        if (!abandonButton) {
            // 如果找不到按钮,可能已经处理过,移到下一个
            pendingList.shift();
            localStorage.setItem(pendingKey, JSON.stringify(pendingList));
            processNextTorrent();
            return;
        }

        // 在调试模式下记录
        if (document.getElementById('debugMode')?.checked) {
            console.log(`准备放弃种子: ${torrent.name} (${formatSize(torrent.size)})`);
            console.log('放弃按钮:', abandonButton);
        }

        // 设置自动确认对话框
        autoConfirmDialogs = true;

        // 统计放弃信息
        abandonedCount++;
        abandonedSize += torrent.size;

        // 更新全局统计信息
        document.getElementById('abandonedStats').textContent =
            `已放弃: ${abandonedCount}个种子 (${formatSize(abandonedSize)})`;

        // 保存全局统计
        saveSettings();

        // 更新会话统计信息
        const sessionStats = JSON.parse(localStorage.getItem(sessionStatsKey) || '{"count":0,"size":0,"total":0}');
        sessionStats.count++;
        sessionStats.size += torrent.size;
        localStorage.setItem(sessionStatsKey, JSON.stringify(sessionStats));

        // 更新处理进度显示
        document.getElementById('progressCount').textContent = sessionStats.count;
        document.getElementById('currentAbandoned').textContent = sessionStats.count;
        document.getElementById('currentAbandonedSize').textContent = formatSize(sessionStats.size);

        // 移除该种子从待处理列表
        pendingList.shift();
        localStorage.setItem(pendingKey, JSON.stringify(pendingList));

        // 点击放弃按钮 (页面将在确认后刷新)
        abandonButton.click();
    }

    function finishAbandonProcess() {
        // 清除处理队列
        localStorage.removeItem(pendingKey);
        localStorage.removeItem(sessionStatsKey);
        localStorage.removeItem(processingKey);

        // 隐藏处理统计面板
        const processingStats = document.getElementById('processingStats');
        if (processingStats) {
            processingStats.style.display = 'none';
        }

        autoConfirmDialogs = false;

        // 重新分析页面
        analyzeTorrents();

        // 提示完成
        alert('所有种子放弃操作已完成!');

        // 检查是否需要自动处理新种子
        checkForNewTorrents();
    }

    // 检查并处理新发现的不达标种子
    function checkForNewTorrents() {
        // 检查是否启用了自动处理新种子选项
        const processNewTorrents = document.getElementById('processNewTorrents')?.checked;
        if (!processNewTorrents) return;

        // 检查系统是否处于活动状态
        const systemActive = document.getElementById('mainSwitch').textContent.trim() === '系统运行中';
        if (!systemActive) return;

        // 分析当前页面上的种子
        analyzeTorrents();

        // 获取选项设置
        const abandonZeroSeed = document.getElementById('abandonZeroSeed').checked;
        const abandonNonCompletable = document.getElementById('abandonNonCompletable').checked;

        // 准备新的放弃队列
        let newTorrentsToAbandon = [];

        if (abandonZeroSeed) {
            newTorrentsToAbandon = newTorrentsToAbandon.concat(zeroSeedTimeTorrents);
        }

        if (abandonNonCompletable) {
            const nonZeroNonCompletable = nonCompletableTorrents.filter(torrent =>
                torrent.seedTimeDays > 0 || !abandonZeroSeed
            );
            newTorrentsToAbandon = newTorrentsToAbandon.concat(nonZeroNonCompletable);
        }

        // 去除重复项
        const uniqueTorrents = [];
        const seen = new Set();

        newTorrentsToAbandon.forEach(torrent => {
            if (!seen.has(torrent.claimId)) {
                seen.add(torrent.claimId);
                uniqueTorrents.push(torrent);
            }
        });

        if (uniqueTorrents.length > 0) {
            // 如果找到新的不达标种子,询问是否自动处理
            if (confirm(`发现 ${uniqueTorrents.length} 个新的不达标种子,是否自动处理?`)) {
                // 将种子信息保存到队列
                const pendingList = uniqueTorrents.map(t => ({
                    claimId: t.claimId,
                    torrentId: t.torrentId,
                    size: t.size,
                    name: t.torrentName
                }));

                // 保存队列到localStorage
                localStorage.setItem(pendingKey, JSON.stringify(pendingList));
                localStorage.setItem(processingKey, 'true');

                // 初始化会话统计数据
                localStorage.setItem(sessionStatsKey, JSON.stringify({
                    count: 0,
                    size: 0,
                    total: pendingList.length
                }));

                // 显示处理统计面板
                const processingStats = document.getElementById('processingStats');
                processingStats.style.display = 'block';
                document.getElementById('totalCount').textContent = pendingList.length;
                document.getElementById('progressCount').textContent = '0';
                document.getElementById('currentAbandoned').textContent = '0';
                document.getElementById('currentAbandonedSize').textContent = '0 B';

                // 开始处理第一个种子
                setTimeout(processNextTorrent, 1000);
            }
        }
    }

    // 设置监听器来处理确认对话框
    function setupDialogObserver() {
        // 创建一个观察器来监听DOM变化
        const observer = new MutationObserver((mutations) => {
            if (!autoConfirmDialogs) return;

            for (const mutation of mutations) {
                if (mutation.addedNodes.length) {
                    for (const node of mutation.addedNodes) {
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            // 查找可能的确认对话框
                            const dialogButton = findConfirmButton(node);
                            if (dialogButton) {
                                // 在调试模式下记录
                                if (document.getElementById('debugMode')?.checked) {
                                    console.log('找到确认按钮,自动点击:', dialogButton);
                                }

                                // 点击确认按钮
                                setTimeout(() => {
                                    dialogButton.click();
                                }, 100);
                                return;
                            }
                        }
                    }
                }
            }
        });

        // 开始观察整个文档
        observer.observe(document.body, { childList: true, subtree: true });

        // 覆盖原生的confirm函数
        const originalConfirm = window.confirm;
        window.confirm = function(message) {
            if (autoConfirmDialogs && message.includes('确认要放弃认领')) {
                return true;
            }
            return originalConfirm.apply(this, arguments);
        };
    }

    // 查找确认按钮
    function findConfirmButton(container) {
        // 首先搜索container内的按钮
        const searchContainer = container || document;

        // 寻找包含特定文本的按钮,或者有特定ID/类的按钮
        const confirmKeys = ['确认', '确定', 'OK', '是', 'Yes'];

        // 查找按钮元素
        const buttons = Array.from(searchContainer.querySelectorAll('button, input[type="button"], .btn, .layui-layer-btn0'));

        // 找到符合条件的第一个按钮
        for (const key of confirmKeys) {
            const button = buttons.find(btn => {
                const text = btn.textContent || btn.value || '';
                return text.includes(key);
            });

            if (button) return button;
        }

        // 检查是否有layui的确认按钮
        const layuiBtn = searchContainer.querySelector('.layui-layer-btn0');
        if (layuiBtn) return layuiBtn;

        return null;
    }

    // 修复: 改进时间解析,考虑小时和分钟
    function parseSeedTime(timeText) {
        const timeRegex = /^(\d+)天(\d+):(\d+):(\d+)$/;
        const match = timeText.match(timeRegex);

        if (!match) {
            console.warn(`时间格式不匹配: "${timeText}"`);
            return 0;
        }

        const days = parseInt(match[1], 10);
        const hours = parseInt(match[2], 10);
        const minutes = parseInt(match[3], 10);

        // 考虑小时和分钟作为天的小数部分
        return days + (hours / 24) + (minutes / (24 * 60));
    }

    // 解析种子大小文本为字节数
    function parseSize(sizeText) {
        const sizeRegex = /^([\d.]+)\s+(KB|MB|GB|TB)$/;
        const match = sizeText.match(sizeRegex);

        if (!match) return 0;

        const value = parseFloat(match[1]);
        const unit = match[2];

        switch (unit) {
            case 'KB': return value * 1024;
            case 'MB': return value * 1024 * 1024;
            case 'GB': return value * 1024 * 1024 * 1024;
            case 'TB': return value * 1024 * 1024 * 1024 * 1024;
            default: return 0;
        }
    }

    // 格式化字节数为可读的大小文本
    function formatSize(bytes) {
        if (bytes < 1024) return bytes + ' B';
        if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
        if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
        if (bytes < 1024 * 1024 * 1024 * 1024) return (bytes / (1024 * 1024 * 1024)).toFixed(2) + ' GB';
        return (bytes / (1024 * 1024 * 1024 * 1024)).toFixed(2) + ' TB';
    }
})();