// ==UserScript== // @name 网站保活助手 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 在指定网站上自动保活,定时滚动和刷新页面,用户操作会重置计时 // @author damu // @match *://*/* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @grant GM_notification // @run-at document-idle // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/550622/%E7%BD%91%E7%AB%99%E4%BF%9D%E6%B4%BB%E5%8A%A9%E6%89%8B.user.js // @updateURL https://update.greasyfork.icu/scripts/550622/%E7%BD%91%E7%AB%99%E4%BF%9D%E6%B4%BB%E5%8A%A9%E6%89%8B.meta.js // ==/UserScript== (function() { 'use strict'; const DEFAULT_SCROLL = 5, DEFAULT_REFRESH = 20, DEFAULT_ACTIVITY = 1; let scrollTimer, refreshTimer, lastActivityTime = Date.now(); let globalEnabled = GM_getValue('globalEnabled', true); let sites = GM_getValue('keepAliveSites', []); // 修复旧数据格式:如果sites是字符串数组,转换为对象数组 if (sites.length > 0 && typeof sites[0] === 'string') { sites = sites.map(url => ({ url: url, enabled: true, scroll: DEFAULT_SCROLL, refresh: DEFAULT_REFRESH, activity: DEFAULT_ACTIVITY })); GM_setValue('keepAliveSites', sites); } GM_registerMenuCommand("网站保活管理", openManagerUI); GM_registerMenuCommand("添加当前网站", addCurrentSite); function addCurrentSite() { const currentUrl = window.location.origin + window.location.pathname; const sitePattern = currentUrl + (window.location.pathname.endsWith('/') ? '*' : '/*'); if (!sites.some(s => s.url === sitePattern)) { sites.push({url: sitePattern, enabled: true, scroll: DEFAULT_SCROLL, refresh: DEFAULT_REFRESH, activity: DEFAULT_ACTIVITY}); GM_setValue('keepAliveSites', sites); GM_notification({ text: `已添加 ${sitePattern}`, timeout: 2000 }); if (globalEnabled) initKeepAlive(); } else { GM_notification({ text: '网站已存在', timeout: 2000 }); } } function openManagerUI() { if (!document.getElementById('keepAliveManager')) createManagerUI(); document.getElementById('keepAliveOverlay').style.display = 'block'; document.getElementById('keepAliveManager').style.display = 'block'; } function closeManagerUI() { document.getElementById('keepAliveOverlay').style.display = 'none'; document.getElementById('keepAliveManager').style.display = 'none'; } function addSiteFromUI() { const url = document.getElementById('siteUrl').value.trim(); if (url && !sites.some(s => s.url === url)) { sites.push({url: url, enabled: true, scroll: DEFAULT_SCROLL, refresh: DEFAULT_REFRESH, activity: DEFAULT_ACTIVITY}); renderSiteList(); document.getElementById('siteUrl').value = ''; } } function saveConfig() { globalEnabled = document.getElementById('globalToggle').checked; GM_setValue('keepAliveSites', sites); GM_setValue('globalEnabled', globalEnabled); GM_notification({ text: '已保存', timeout: 1500 }); closeManagerUI(); clearTimers(); if (globalEnabled && checkSite()) initKeepAlive(); } function createManagerUI() { const overlay = document.createElement('div'); overlay.id = 'keepAliveOverlay'; overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:9999;display:none'; overlay.onclick = closeManagerUI; const manager = document.createElement('div'); manager.id = 'keepAliveManager'; manager.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:400px;background:white;border-radius:8px;z-index:10000;display:none'; manager.innerHTML = `

网站保活管理

`; document.body.appendChild(overlay); document.body.appendChild(manager); document.getElementById('closeBtn').onclick = closeManagerUI; document.getElementById('addBtn').onclick = addSiteFromUI; document.getElementById('saveBtn').onclick = saveConfig; document.getElementById('cancelBtn').onclick = closeManagerUI; renderSiteList(); } function renderSiteList() { const siteListDiv = document.getElementById('siteList'); if (!siteListDiv) return; siteListDiv.innerHTML = sites.length ? '' : '
暂无网站
'; sites.forEach((site, index) => { const siteItem = document.createElement('div'); siteItem.style.cssText = 'padding:10px;border-bottom:1px solid #eee;display:flex;align-items:center;justify-content:space-between'; siteItem.innerHTML = `
`; const checkbox = siteItem.querySelector('input[type="checkbox"]'); checkbox.onchange = function() { sites[index].enabled = this.checked; }; const deleteBtn = siteItem.querySelector('button'); deleteBtn.onclick = function() { sites.splice(index, 1); renderSiteList(); }; siteListDiv.appendChild(siteItem); }); } function clearTimers() { clearTimeout(scrollTimer); clearTimeout(refreshTimer); } function checkSite() { const currentUrl = window.location.href; return sites.some(site => site.enabled && new RegExp('^' + site.url.replace(/\*/g, '.*') + '$').test(currentUrl)); } function getCurrentSiteSettings() { const currentUrl = window.location.href; return sites.find(site => site.enabled && new RegExp('^' + site.url.replace(/\*/g, '.*') + '$').test(currentUrl)); } function simulateScroll() { window.scrollBy(0, 200); setTimeout(() => window.scrollBy(0, -100), 1000); } function refreshPage() { const settings = getCurrentSiteSettings(); if (settings && Date.now() - lastActivityTime > settings.activity * 60000) { window.location.reload(); } else { resetTimers(); } } function resetTimers() { const settings = getCurrentSiteSettings(); if (!settings) return; lastActivityTime = Date.now(); clearTimers(); scrollTimer = setTimeout(simulateScroll, settings.scroll * 60000); refreshTimer = setTimeout(refreshPage, settings.refresh * 60000); } function initKeepAlive() { ['mousemove', 'keypress', 'click', 'scroll'].forEach(event => { document.addEventListener(event, () => { lastActivityTime = Date.now(); }, {passive: true}); }); resetTimers(); } // 初始化 if (globalEnabled && checkSite()) { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initKeepAlive); } else { initKeepAlive(); } } })();