您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
提供种子认领管理功能,包括悬浮窗显示总体积、检查当月种子并一键放弃不达标种子等功能
// ==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'; } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址