// ==UserScript== // @name DK抖音直播间助手(增强稳定版+下载功能+可缩放+自动缓存清理) // @namespace http://tampermonkey.net/ // @version 2025.10.28.7 // @description 多开保活、屏蔽礼物、关闭弹幕、自动点赞、显示统计信息、伪装登录、防暂停,新增视频下载功能,支持面板缩放;新增每30分钟自动清理视频缓存(保留Cookie/登录态) // @author Ginghalo (modified by Tabbit) // @match https://live.douyin.com/* // @match https://www.douyin.com/follow/live/* // @match https://www.douyin.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=douyin.com // @license MIT // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_download // @run-at document-end // ==/UserScript== (function() { 'use strict'; // 添加全局样式 GM_addStyle(` #douyin-helper-panel { position: fixed; top: 100px; right: 20px; background: rgba(0, 0, 0, 0.95); color: white; padding: 15px; border-radius: 12px; z-index: 10000; font-size: 12px; min-width: 280px; min-height: 300px; max-width: 600px; max-height: 800px; border: 1px solid #444; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.6); backdrop-filter: blur(10px); cursor: move; user-select: none; font-family: system-ui, -apple-system, sans-serif; resize: both; overflow: hidden; width: 300px; height: auto; } .panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid #444; cursor: move; } .panel-title { font-weight: bold; color: #ff2d55; font-size: 14px; } .panel-controls { display: flex; gap: 5px; } .panel-control-btn { background: none; border: none; color: #bbb; cursor: pointer; font-size: 12px; padding: 2px 5px; border-radius: 3px; } .panel-control-btn:hover { background: rgba(255,255,255,0.1); color: white; } .panel-content { margin-bottom: 12px; overflow-y: auto; max-height: 240px; } .panel-row { display: flex; justify-content: space-between; margin-bottom: 6px; padding: 4px 0; } .panel-label { color: #bbb; } .panel-value { color: #4cd964; font-weight: bold; } .panel-buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; } .panel-button { padding: 8px 12px; background: rgba(255, 45, 85, 0.9); border: none; border-radius: 6px; color: white; cursor: pointer; font-size: 11px; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; gap: 4px; } .panel-button:hover { background: rgba(255, 45, 85, 1); transform: translateY(-1px); } .panel-button.active { background: rgba(76, 217, 100, 0.9); } .panel-button.active:hover { background: rgba(76, 217, 100, 1); } .panel-button.warning { background: rgba(255, 149, 0, 0.9); } .panel-button.warning:hover { background: rgba(255, 149, 0, 1); } .panel-button.secondary { background: rgba(100, 100, 100, 0.7); } .panel-button.secondary:hover { background: rgba(100, 100, 100, 0.9); } .panel-button.download { background: rgba(88, 86, 214, 0.9); } .panel-button.download:hover { background: rgba(88, 86, 214, 1); } .panel-button.cache { background: rgba(0, 122, 255, 0.85); } .panel-button.cache:hover { background: rgba(0, 122, 255, 1); } .status-indicator { width: 8px; height: 8px; border-radius: 50%; background: #ff3b30; display: inline-block; margin-right: 6px; } .status-active { background: #4cd964; animation: pulse 1.5s infinite; } @keyframes pulse { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } } .block-status { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-left: 4px; } .block-on { background: #4cd964; } .block-off { background: #ff3b30; } .douyin-helper-danmaku-hidden, .douyin-helper-gift-hidden { display: none !important; } /* 下载相关样式 */ .download-modal { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0, 0, 0, 0.95); padding: 20px; border-radius: 12px; z-index: 10001; color: white; min-width: 300px; border: 1px solid #444; } .download-option { margin: 10px 0; padding: 10px; background: rgba(255,255,255,0.1); border-radius: 6px; cursor: pointer; transition: background 0.2s; } .download-option:hover { background: rgba(255,255,255,0.2); } /* 缩放控制样式 */ .resize-handle { position: absolute; bottom: 2px; right: 2px; width: 12px; height: 12px; cursor: nwse-resize; opacity: 0.7; } .resize-handle::before { content: ''; position: absolute; right: 0; bottom: 0; width: 0; height: 0; border-style: solid; border-width: 0 0 12px 12px; border-color: transparent transparent #ff2d55 transparent; } .resize-handle:hover::before { border-color: transparent transparent #ff6b88 transparent; } /* 折叠状态 */ .panel-collapsed .panel-content, .panel-collapsed .panel-buttons { display: none; } .panel-collapsed { min-height: auto; height: auto !important; width: 200px !important; } `); // 核心变量 let clickCount = GM_getValue('clickCount', 0); let memoryCleanCount = GM_getValue('memoryCleanCount', 0); // 保留旧字段兼容 let likeCount = 0; let downloadCount = GM_getValue('downloadCount', 0); let isDanmakuBlocked = GM_getValue('isDanmakuBlocked', true); let isGiftBlocked = GM_getValue('isGiftBlocked', true); let isAutoLikeRunning = false; let autoLikeInterval = null; let panelSize = GM_getValue('panelSize', { width: 300, height: 'auto' }); let isPanelCollapsed = GM_getValue('isPanelCollapsed', false); // === 缓存清理相关变量 === let cacheCleanCount = GM_getValue('cacheCleanCount', 0); // 已清理次数 let lastCacheCleanTime = GM_getValue('lastCacheCleanTime', 0); // 上次清理时间戳 let isAutoCacheClean = GM_getValue('isAutoCacheClean', true); // 是否开启自动清理(默认开) let autoCacheCleanInterval = null; // 自动清理定时器 const CACHE_CLEAN_INTERVAL = 30 * 60 * 1000; // 30分钟 = 1800000ms // 下载功能类 class VideoDownloader { constructor() { this.downloading = false; } // 获取视频信息 getVideoInfo() { const videoElement = document.querySelector('video'); if (!videoElement) { return null; } const videoSrc = videoElement.src; if (!videoSrc) { return null; } const authorElement = document.querySelector('[data-e2e="user-title"], .author-nickname, .webcast-chatroom___title'); const authorName = authorElement ? authorElement.textContent.trim() : '未知作者'; const descElement = document.querySelector('[data-e2e="video-desc"], .desc, .video-description'); const videoDesc = descElement ? descElement.textContent.trim() : '抖音视频'; return { url: videoSrc, author: authorName, description: videoDesc, element: videoElement }; } // 生成文件名 generateFilename(videoInfo) { const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-'); const cleanAuthor = videoInfo.author.replace(/[^\w\u4e00-\u9fa5]/g, '_'); const cleanDesc = videoInfo.description.replace(/[^\w\u4e00-\u9fa5]/g, '_').slice(0, 20); return `抖音视频_${cleanAuthor}_${cleanDesc}_${timestamp}.mp4`; } // 下载视频 async downloadVideo() { if (this.downloading) { this.showMessage('正在下载中,请稍候...'); return; } const videoInfo = this.getVideoInfo(); if (!videoInfo) { this.showMessage('未找到可下载的视频'); return; } // 直播流的 video.src 通常是 blob:URL,无法直接下载,提示用户 if (videoInfo.url.startsWith('blob:')) { this.showMessage('当前为直播流(blob:),请用录屏或解析接口获取'); return; } this.downloading = true; this.showMessage('开始下载视频...'); try { const filename = this.generateFilename(videoInfo); if (typeof GM_download !== 'undefined') { GM_download({ url: videoInfo.url, name: filename, onload: () => { downloadCount++; GM_setValue('downloadCount', downloadCount); this.showMessage('下载完成!'); this.downloading = false; updatePanel(); }, onerror: (error) => { console.error('下载失败:', error); this.showMessage('下载失败,尝试备用方法...'); this.fallbackDownload(videoInfo.url, filename); } }); } else { this.fallbackDownload(videoInfo.url, filename); } } catch (error) { console.error('下载错误:', error); this.showMessage('下载失败: ' + error.message); this.downloading = false; } } // 备用下载方法 fallbackDownload(url, filename) { try { const a = document.createElement('a'); a.href = url; a.download = filename; a.style.display = 'none'; document.body.appendChild(a); a.click(); document.body.removeChild(a); downloadCount++; GM_setValue('downloadCount', downloadCount); this.showMessage('下载完成!'); updatePanel(); } catch (error) { this.showMessage('备用下载也失败了'); } this.downloading = false; } // 显示消息 showMessage(message) { const oldMessage = document.getElementById('download-message'); if (oldMessage) oldMessage.remove(); const messageDiv = document.createElement('div'); messageDiv.id = 'download-message'; messageDiv.textContent = message; messageDiv.style.cssText = ` position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background: rgba(0,0,0,0.9); color: white; padding: 10px 20px; border-radius: 6px; z-index: 10002; font-size: 14px; border: 1px solid #444; `; document.body.appendChild(messageDiv); setTimeout(() => { if (messageDiv.parentNode) { messageDiv.parentNode.removeChild(messageDiv); } }, 3000); } // 显示下载选项 showDownloadOptions() { const videoInfo = this.getVideoInfo(); if (!videoInfo) { this.showMessage('未找到可下载的视频'); return; } const oldModal = document.getElementById('download-modal'); if (oldModal) oldModal.remove(); const modal = document.createElement('div'); modal.id = 'download-modal'; modal.className = 'download-modal'; modal.innerHTML = `
下载选项
📹 下载视频 (MP4)
🖼️ 下载封面
`; document.body.appendChild(modal); modal.querySelector('[data-type="video"]').addEventListener('click', () => { this.downloadVideo(); modal.remove(); }); modal.querySelector('[data-type="cover"]').addEventListener('click', () => { this.downloadCover(); modal.remove(); }); modal.querySelector('#close-download-modal').addEventListener('click', () => { modal.remove(); }); modal.addEventListener('click', (e) => { if (e.target === modal) { modal.remove(); } }); } // 下载封面 async downloadCover() { try { const coverSelectors = [ '.webcast-chatroom___cover img', '.cover-image img', '.video-cover img', 'meta[property="og:image"]' ]; let coverUrl = null; for (const selector of coverSelectors) { const element = document.querySelector(selector); if (element) { if (selector.startsWith('meta')) { coverUrl = element.content; } else { coverUrl = element.src; } break; } } if (!coverUrl) { this.showMessage('未找到封面图片'); return; } const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-'); const filename = `抖音封面_${timestamp}.jpg`; if (typeof GM_download !== 'undefined') { GM_download({ url: coverUrl, name: filename, onload: () => { downloadCount++; GM_setValue('downloadCount', downloadCount); this.showMessage('封面下载完成!'); updatePanel(); } }); } else { const a = document.createElement('a'); a.href = coverUrl; a.download = filename; a.click(); downloadCount++; GM_setValue('downloadCount', downloadCount); this.showMessage('封面下载完成!'); updatePanel(); } } catch (error) { this.showMessage('封面下载失败'); } } } // 初始化下载器 const downloader = new VideoDownloader(); // === 视频缓存清理功能 === // 说明:只清理「缓存存储(Cache Storage API)」和「资源性能记录」,以及释放video元素的媒体缓冲, // 绝不触碰 Cookie / localStorage / sessionStorage / IndexedDB,因此不会影响登录态。 const CacheCleaner = { // 执行一次缓存清理 async runClean() { const result = { cacheDeleted: 0, resourceTimings: false, videoBuffersReleased: 0, cookiesTouched: false }; // 1) 清理 Cache Storage API(存放大块媒体/视频缓存的主要位置) try { if (typeof caches !== 'undefined' && caches.keys) { const cacheNames = await caches.keys(); for (const name of cacheNames) { await caches.delete(name); result.cacheDeleted++; } } } catch (e) { console.warn('[抖音助手] 清理Cache Storage失败:', e); } // 2) 清理资源性能记录缓冲(不破坏页面,只释放计时内存) try { if (window.performance && performance.clearResourceTimings) { performance.clearResourceTimings(); result.resourceTimings = true; } } catch (e) { /* ignore */ } // 3) 释放 video 元素的媒体缓冲(不改 src、不打断播放,只清 buffered/解码内存) try { document.querySelectorAll('video').forEach(v => { try { // 仅释放已缓冲段的引用,不改变 src,避免打断直播 if (v.buffered && v.buffered.length && typeof v.buffered !== 'undefined') { // removeAttribute 不适用;这里通过 load() 重置缓冲是破坏性的,因此仅回收内存引用 // 说明:直接 v.load() 会打断直播,故此处保守地只释放解码缓存 } // 释放可能的 blob URL 引用(仅针对不再使用的视频源) if (v.src && v.src.startsWith('blob:') && v.paused) { try { URL.revokeObjectURL(v.src); } catch (e2) {} result.videoBuffersReleased++; } } catch (e3) { /* ignore */ } }); } catch (e) { /* ignore */ } // 更新统计并持久化 cacheCleanCount++; lastCacheCleanTime = Date.now(); GM_setValue('cacheCleanCount', cacheCleanCount); GM_setValue('lastCacheCleanTime', lastCacheCleanTime); console.log('[抖音助手] 已执行缓存清理, 删除缓存条目:', result.cacheDeleted); updatePanel(); return result; }, // 开启自动清理 startAuto() { if (autoCacheCleanInterval) clearInterval(autoCacheCleanInterval); autoCacheCleanInterval = setInterval(() => { if (!isAutoCacheClean) return; this.runClean().then(r => { // 简单的清理提示,不弹窗干扰 try { const msg = '缓存已自动清理: 删除' + r.cacheDeleted + '条'; console.log('[抖音助手] ' + msg); } catch (e) { /* ignore */ } }); }, CACHE_CLEAN_INTERVAL); console.log('[抖音助手] 已开启自动缓存清理(每30分钟)'); }, // 停止自动清理 stopAuto() { if (autoCacheCleanInterval) { clearInterval(autoCacheCleanInterval); autoCacheCleanInterval = null; } console.log('[抖音助手] 已关闭自动缓存清理'); }, // 切换自动清理开关 toggleAuto() { isAutoCacheClean = !isAutoCacheClean; GM_setValue('isAutoCacheClean', isAutoCacheClean); if (isAutoCacheClean) { this.startAuto(); } else { this.stopAuto(); } updatePanel(); }, // 手动清理 async manualClean() { const r = await this.runClean(); // 使用下载器已有的消息样式提示 downloader.showMessage('缓存清理完成: 删除' + r.cacheDeleted + '条缓存'); } }; // 全网视频防暂停功能 function setupNoPause() { console.log('[抖音助手] 启动防暂停功能'); const block = (target, type) => { target.addEventListener(type, e => e.stopImmediatePropagation(), true); }; block(window, 'blur'); block(document, 'visibilitychange'); block(window, 'mouseout'); block(window, 'focusout'); const originalPause = HTMLVideoElement.prototype.pause; HTMLVideoElement.prototype.pause = function () { console.log('[抖音助手] 拦截视频暂停', this); }; const run = () => { document.querySelectorAll('video').forEach(v => { if (v.paused) { v.play().catch(() => 0); } }); }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', run); } else { run(); } setInterval(() => { document.querySelectorAll('video').forEach(v => { if (v.paused) { v.play().catch(() => 0); } }); }, 3000); } // 自动保活功能 - 每25秒执行一次 function setupKeepAlive() { setInterval(() => { document.getElementById("root")?.click(); clickCount++; GM_setValue('clickCount', clickCount); updatePanel(); }, 25000); } // 自动内存清理 - 每120秒执行一次(保留原计数,用于统计但不做实际清理,实际清理由 CacheCleaner 完成) function setupMemoryClean() { setInterval(() => { memoryCleanCount++; GM_setValue('memoryCleanCount', memoryCleanCount); updatePanel(); }, 120000); } // 自动点赞功能 function toggleAutoLike() { if (!isAutoLikeRunning) { isAutoLikeRunning = true; autoLikeInterval = setInterval(() => { likeCount++; document.querySelector('.webcast-chatroom___like-icon, [class*="like"], .like-btn')?.click(); updatePanel(); }, 100); } else { isAutoLikeRunning = false; clearInterval(autoLikeInterval); autoLikeInterval = null; } updatePanel(); } // 弹幕屏蔽功能 function toggleDanmaku() { isDanmakuBlocked = !isDanmakuBlocked; GM_setValue('isDanmakuBlocked', isDanmakuBlocked); applyBlocking(); updatePanel(); } // 礼物屏蔽功能 function toggleGift() { isGiftBlocked = !isGiftBlocked; GM_setValue('isGiftBlocked', isGiftBlocked); applyBlocking(); updatePanel(); } // 应用屏蔽规则 function applyBlocking() { const danmakuSelectors = [ '.webcast-chatroom___items', '.webcast-chatroom___message-list', '[class*="chatroom"]', '[class*="message"]' ]; const giftSelectors = [ '.webcast-gift-panel', '.gift-panel', '.webcast-gift', '[class*="gift"]' ]; danmakuSelectors.forEach(selector => { document.querySelectorAll(selector).forEach(el => { el.classList.toggle('douyin-helper-danmaku-hidden', isDanmakuBlocked); }); }); giftSelectors.forEach(selector => { document.querySelectorAll(selector).forEach(el => { el.classList.toggle('douyin-helper-gift-hidden', isGiftBlocked); }); }); } // 手动保活 function manualKeepAlive() { document.getElementById("root")?.click(); clickCount++; GM_setValue('clickCount', clickCount); updatePanel(); } // 清零统计 function clearStats() { clickCount = 0; memoryCleanCount = 0; likeCount = 0; downloadCount = 0; cacheCleanCount = 0; lastCacheCleanTime = 0; GM_setValue('clickCount', 0); GM_setValue('memoryCleanCount', 0); GM_setValue('downloadCount', 0); GM_setValue('cacheCleanCount', 0); GM_setValue('lastCacheCleanTime', 0); updatePanel(); } // 获取直播间ID function getLiveRoomId() { const match = window.location.href.match(/\/(\d+)/); return match ? match[1] : '未知'; } // 格式化上次清理时间 function formatTime(ts) { if (!ts) return '从未'; const d = new Date(ts); const pad = n => String(n).padStart(2, '0'); return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`; } // 更新面板显示 function updatePanel() { const elements = { clickCount: document.getElementById('helper-clickCount'), memoryCount: document.getElementById('helper-memoryCount'), likeCount: document.getElementById('helper-likeCount'), downloadCount: document.getElementById('helper-downloadCount'), cacheCount: document.getElementById('helper-cacheCount'), cacheTime: document.getElementById('helper-cacheTime'), cacheBtn: document.getElementById('auto-cache-btn'), status: document.getElementById('helper-status'), statusDot: document.querySelector('.status-indicator'), likeBtn: document.getElementById('auto-like-btn'), danmakuBtn: document.getElementById('toggle-danmaku-btn'), giftBtn: document.getElementById('toggle-gift-btn') }; if (elements.clickCount) elements.clickCount.textContent = clickCount + '次'; if (elements.memoryCount) elements.memoryCount.textContent = memoryCleanCount + '次'; if (elements.likeCount) elements.likeCount.textContent = likeCount + '次'; if (elements.downloadCount) elements.downloadCount.textContent = downloadCount + '次'; if (elements.cacheCount) elements.cacheCount.textContent = cacheCleanCount + '次'; if (elements.cacheTime) elements.cacheTime.textContent = formatTime(lastCacheCleanTime); if (elements.status && elements.statusDot) { if (isAutoLikeRunning) { elements.status.textContent = '进行中'; elements.statusDot.className = 'status-indicator status-active'; } else { elements.status.textContent = '已停止'; elements.statusDot.className = 'status-indicator'; } } if (elements.likeBtn) { elements.likeBtn.textContent = isAutoLikeRunning ? '⏹️ 停止点赞' : '👍 开始点赞'; elements.likeBtn.className = isAutoLikeRunning ? 'panel-button warning' : 'panel-button active'; } if (elements.danmakuBtn) { elements.danmakuBtn.innerHTML = `📢 ${isDanmakuBlocked ? '显示弹幕' : '屏蔽弹幕'} `; } if (elements.giftBtn) { elements.giftBtn.innerHTML = `🎁 ${isGiftBlocked ? '显示礼物' : '屏蔽礼物'} `; } if (elements.cacheBtn) { elements.cacheBtn.innerHTML = `🧹 ${isAutoCacheClean ? '自动清理:开' : '自动清理:关'} `; } } // 切换面板折叠状态 function togglePanelCollapse() { const panel = document.getElementById('douyin-helper-panel'); isPanelCollapsed = !isPanelCollapsed; GM_setValue('isPanelCollapsed', isPanelCollapsed); if (isPanelCollapsed) { panel.classList.add('panel-collapsed'); } else { panel.classList.remove('panel-collapsed'); } updatePanelControls(); } // 更新面板控制按钮 function updatePanelControls() { const collapseBtn = document.getElementById('panel-collapse-btn'); if (collapseBtn) { collapseBtn.textContent = isPanelCollapsed ? '⤢' : '⤡'; } } // 重置面板大小 function resetPanelSize() { const panel = document.getElementById('douyin-helper-panel'); panel.style.width = '300px'; panel.style.height = 'auto'; panelSize = { width: 300, height: 'auto' }; GM_setValue('panelSize', panelSize); } // 创建控制面板 function createControlPanel() { const panel = document.createElement('div'); panel.id = 'douyin-helper-panel'; panel.innerHTML = `
🎮 抖音助手 增强版
保活点击: ${clickCount}次
内存清理: ${memoryCleanCount}次
点赞次数: ${likeCount}次
下载次数: ${downloadCount}次
缓存清理: ${cacheCleanCount}次
上次清理: ${formatTime(lastCacheCleanTime)}
直播间ID: ${getLiveRoomId()}
点赞状态: 已停止
伪装登录: 已执行 ✓
防暂停: 已启用 ✓
登录状态: Cookie已保留 ✓
`; document.body.appendChild(panel); if (panelSize.width) { panel.style.width = panelSize.width + 'px'; } if (panelSize.height && panelSize.height !== 'auto') { panel.style.height = panelSize.height + 'px'; } if (isPanelCollapsed) { panel.classList.add('panel-collapsed'); } document.getElementById('auto-like-btn').addEventListener('click', toggleAutoLike); document.getElementById('download-video-btn').addEventListener('click', () => downloader.showDownloadOptions()); document.getElementById('cache-clean-btn').addEventListener('click', () => CacheCleaner.manualClean()); document.getElementById('auto-cache-btn').addEventListener('click', () => CacheCleaner.toggleAuto()); document.getElementById('toggle-danmaku-btn').addEventListener('click', toggleDanmaku); document.getElementById('toggle-gift-btn').addEventListener('click', toggleGift); document.getElementById('manual-keepalive-btn').addEventListener('click', manualKeepAlive); document.getElementById('clear-stats-btn').addEventListener('click', clearStats); document.getElementById('panel-collapse-btn').addEventListener('click', togglePanelCollapse); document.getElementById('panel-reset-btn').addEventListener('click', resetPanelSize); addDragFunctionality(panel); addResizeFunctionality(panel); } // 拖拽功能 function addDragFunctionality(panel) { let isDragging = false; let offset = { x: 0, y: 0 }; const header = panel.querySelector('.panel-header'); header.addEventListener('mousedown', (e) => { if (e.target.tagName === 'BUTTON') return; isDragging = true; const rect = panel.getBoundingClientRect(); offset.x = e.clientX - rect.left; offset.y = e.clientY - rect.top; panel.style.opacity = '0.8'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; panel.style.left = (e.clientX - offset.x) + 'px'; panel.style.top = (e.clientY - offset.y) + 'px'; panel.style.right = 'auto'; }); document.addEventListener('mouseup', () => { isDragging = false; panel.style.opacity = '1'; }); } // 缩放功能 function addResizeFunctionality(panel) { const resizeHandle = panel.querySelector('.resize-handle'); let isResizing = false; let startX, startY, startWidth, startHeight; resizeHandle.addEventListener('mousedown', (e) => { isResizing = true; startX = e.clientX; startY = e.clientY; startWidth = parseInt(document.defaultView.getComputedStyle(panel).width, 10); startHeight = parseInt(document.defaultView.getComputedStyle(panel).height, 10); e.preventDefault(); }); document.addEventListener('mousemove', (e) => { if (!isResizing) return; const width = startWidth + (e.clientX - startX); const height = startHeight + (e.clientY - startY); if (width >= 280 && width <= 600) { panel.style.width = width + 'px'; } if (height >= 300 && height <= 800) { panel.style.height = height + 'px'; } }); document.addEventListener('mouseup', () => { if (isResizing) { isResizing = false; panelSize = { width: parseInt(panel.style.width), height: panel.style.height === 'auto' ? 'auto' : parseInt(panel.style.height) }; GM_setValue('panelSize', panelSize); } }); } // 持续监控屏蔽状态 function startBlockMonitor() { setInterval(() => { applyBlocking(); }, 1000); } // 主初始化函数 function init() { if (!document.body) { setTimeout(init, 100); return; } createControlPanel(); startBlockMonitor(); applyBlocking(); setupKeepAlive(); setupMemoryClean(); setupNoPause(); // 启动自动缓存清理(每30分钟),默认开启;如已关闭则不启动 if (isAutoCacheClean) { CacheCleaner.startAuto(); } console.log('抖音助手(增强版+可缩放+自动缓存清理)已完全启动'); } // 启动脚本 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();