// ==UserScript== // @name B站直播间自动点赞 (定时+按钮版) // @namespace http://tampermonkey.net/ // @version 3.3.0 // @description 在B站直播间“点赞”按钮前增加控制按钮,支持批量点赞+间隔暂停模式,可配置间隔条数、时间等参数 // @author Xubai0224 // @match https://live.bilibili.com/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // 配置项 - 可根据需要修改 const MIN_INTERVAL_SEC = 0.5; // 单次点赞最小间隔时间(秒) const MAX_INTERVAL_SEC = 0.8; // 单次点赞最大间隔时间(秒) const AUTO_DURATION_MIN = 40; // 自动点赞总持续时间(分钟) const DAILY_MAX_LIKES = 1000; // 单日最大点赞次数(单个直播间) const MIN_INTERVAL_COUNT = 18; // 最小间隔条数(每批点赞次数下限) const MAX_INTERVAL_COUNT = 22; // 最大间隔条数(每批点赞次数上限) const MIN_BATCH_PAUSE_SEC = 5; // 批次间最小暂停时间(秒) const MAX_BATCH_PAUSE_SEC = 8; // 批次间最大暂停时间(秒,不能大于“自动点赞总持续时间”) // 状态变量 let autoLikeInterval = null; // 单次点赞定时器ID let autoStopTimeout = null; // 总时长自动停止定时器ID let batchPauseTimeout = null; // 批次间暂停定时器ID let controlButton = null; // 控制按钮元素 let currentRoomId = null; // 当前直播间ID let likeStats = {}; // 点赞统计数据 {房间ID: {date: 日期, count: 次数}} let currentBatchCount = 0; // 当前批次已点赞次数 let currentBatchTotal = 0; // 当前批次需点赞总次数 /** * 初始化点赞统计数据 */ function initLikeStats() { const urlMatch = window.location.href.match(/live\.bilibili\.com\/(\d+)/); if (urlMatch && urlMatch[1]) { currentRoomId = urlMatch[1]; } else { console.log('无法获取直播间ID'); return; } const savedStats = localStorage.getItem('bilibiliAutoLikeStats'); if (savedStats) { try { likeStats = JSON.parse(savedStats); } catch (e) { console.error('解析点赞统计数据失败', e); likeStats = {}; } } const today = new Date().toISOString().split('T')[0]; if (!likeStats[currentRoomId] || likeStats[currentRoomId].date !== today) { likeStats[currentRoomId] = { date: today, count: 0 }; } saveLikeStats(); } /** * 保存点赞统计数据到localStorage */ function saveLikeStats() { try { localStorage.setItem('bilibiliAutoLikeStats', JSON.stringify(likeStats)); } catch (e) { console.error('保存点赞统计数据失败', e); } } /** * 增加点赞计数 * @returns {boolean} 是否超过每日限制 */ function incrementLikeCount() { if (!currentRoomId) return true; likeStats[currentRoomId].count++; saveLikeStats(); return likeStats[currentRoomId].count >= DAILY_MAX_LIKES; } /** * 检查是否已达到每日点赞限制 * @returns {boolean} 是否超过限制 */ function isOverDailyLimit() { if (!currentRoomId) return false; return likeStats[currentRoomId].count >= DAILY_MAX_LIKES; } /** * 生成随机数(范围内) * @param {number} min 最小值 * @param {number} max 最大值 * @returns {number} 随机数 */ function getRandomValue(min, max) { return Math.random() * (max - min) + min; } /** * 生成单次点赞间隔时间(毫秒) * @returns {number} 随机间隔时间 */ function getClickInterval() { return getRandomValue(MIN_INTERVAL_SEC, MAX_INTERVAL_SEC) * 1000; } /** * 生成批次点赞数量 * @returns {number} 随机批次数量(取整数) */ function getBatchCount() { return Math.floor(getRandomValue(MIN_INTERVAL_COUNT, MAX_INTERVAL_COUNT + 1)); } /** * 生成批次间暂停时间(毫秒) * @returns {number} 随机暂停时间 */ function getBatchPauseTime() { return getRandomValue(MIN_BATCH_PAUSE_SEC, MAX_BATCH_PAUSE_SEC) * 1000; } /** * 开始新的点赞批次 */ function startNewBatch() { // 生成当前批次的点赞数量 currentBatchTotal = getBatchCount(); currentBatchCount = 0; console.log(`开始新批次点赞,共${currentBatchTotal}次`); // 启动本批次的点赞流程 startLikeInterval(); } /** * 启动单次点赞定时器 */ function startLikeInterval() { // 清除可能存在的单次定时器 if (autoLikeInterval) { clearTimeout(autoLikeInterval); } // 执行一次点赞 const isOverLimit = triggerLikeClick(); if (isOverLimit) { return; // 已达上限,终止流程 } // 累计当前批次计数 currentBatchCount++; // 检查当前批次是否完成 if (currentBatchCount >= currentBatchTotal) { console.log(`本批次${currentBatchTotal}次点赞完成`); startBatchPause(); // 进入批次间暂停 return; } // 未完成则继续本批次的下一次点赞 const nextInterval = getClickInterval(); autoLikeInterval = setTimeout(startLikeInterval, nextInterval); } /** * 开始批次间暂停 */ function startBatchPause() { // 清除可能存在的暂停定时器 if (batchPauseTimeout) { clearTimeout(batchPauseTimeout); } // 生成暂停时间 const pauseTime = getBatchPauseTime(); console.log(`进入批次间暂停,时长${(pauseTime / 1000).toFixed(1)}秒`); // 暂停结束后开始新批次 batchPauseTimeout = setTimeout(() => { batchPauseTimeout = null; startNewBatch(); }, pauseTime); } /** * 切换自动点赞状态 */ function toggleAutoLike() { // 检查是否超过每日限制 if (!autoLikeInterval && !batchPauseTimeout && isOverDailyLimit()) { alert(`本直播间点赞次数已达到单日最大点赞次数(${DAILY_MAX_LIKES}次)`); return; } if (autoLikeInterval || batchPauseTimeout) { // 停止所有定时器 clearTimeout(autoLikeInterval); clearTimeout(autoStopTimeout); clearTimeout(batchPauseTimeout); autoLikeInterval = null; autoStopTimeout = null; batchPauseTimeout = null; currentBatchCount = 0; currentBatchTotal = 0; console.log('自动点赞已停止'); updateButtonState(false); } else { // 启动自动点赞 const durationText = AUTO_DURATION_MIN % 1 === 0 ? `${AUTO_DURATION_MIN}分钟` : `${AUTO_DURATION_MIN}分钟`; console.log(`自动点赞已启动,总持续${durationText}`); console.log(`批次配置:每批${MIN_INTERVAL_COUNT}-${MAX_INTERVAL_COUNT}次,间隔${MIN_BATCH_PAUSE_SEC}-${MAX_BATCH_PAUSE_SEC}秒`); // 立即开始第一个批次 startNewBatch(); // 设置总时长自动停止定时器 const durationMs = AUTO_DURATION_MIN * 60 * 1000; autoStopTimeout = setTimeout(() => { if (autoLikeInterval || batchPauseTimeout) { clearTimeout(autoLikeInterval); clearTimeout(batchPauseTimeout); autoLikeInterval = null; batchPauseTimeout = null; currentBatchCount = 0; currentBatchTotal = 0; console.log(`自动点赞已达到${durationText},已停止`); updateButtonState(false); } }, durationMs); updateButtonState(true); } } /** * 触发点赞按钮点击 * @returns {boolean} 是否达到点赞限制 */ function triggerLikeClick() { const likeButton = document.querySelector('.like-btn'); if (!likeButton) { console.log('未找到点赞按钮,已停止自动点赞'); if (autoLikeInterval || batchPauseTimeout) { toggleAutoLike(); } return false; } // 检查是否超过每日限制 if (isOverDailyLimit()) { alert(`本直播间点赞次数已达到单日最大点赞次数(${DAILY_MAX_LIKES}次)`); if (autoLikeInterval || batchPauseTimeout) { toggleAutoLike(); } return true; } likeButton.click(); // 增加计数并检查是否超过限制 const isOverLimit = incrementLikeCount(); if (isOverLimit) { alert(`本直播间点赞次数已达到单日最大点赞次数(${DAILY_MAX_LIKES}次)`); return true; } return false; } /** * 更新控制按钮状态 * @param {boolean} isRunning - 是否正在运行自动点赞 */ function updateButtonState(isRunning) { if (!controlButton) return; const displayDuration = AUTO_DURATION_MIN % 1 === 0 ? Math.floor(AUTO_DURATION_MIN) : AUTO_DURATION_MIN; if (isRunning) { controlButton.textContent = '停止点赞'; controlButton.style.backgroundColor = '#e74c3c'; controlButton.style.borderColor = '#c0392b'; } else { controlButton.textContent = `自动赞${displayDuration}min`; controlButton.style.backgroundColor = '#3498db'; controlButton.style.borderColor = '#2980b9'; } } /** * 创建并插入控制按钮 */ function createControlButton() { if (document.getElementById('auto-like-control-btn') || !document.querySelector('.like-btn')) { return; } const likeButton = document.querySelector('.like-btn'); controlButton = document.createElement('button'); controlButton.id = 'auto-like-control-btn'; Object.assign(controlButton.style, { marginRight: '8px', padding: '0 10px', border: '1px solid', borderRadius: '4px', cursor: 'pointer', fontSize: '12px', height: `${likeButton.offsetHeight}px`, color: 'white', transition: 'background-color 0.3s' }); updateButtonState(false); controlButton.addEventListener('click', toggleAutoLike); likeButton.parentNode.insertBefore(controlButton, likeButton); console.log('自动点赞控制按钮已加载'); } /** * 初始化键盘事件监听 */ function initKeyboardListener() { document.addEventListener('keydown', (event) => { if (event.code === 'NumpadSubtract') { toggleAutoLike(); } }); } /** * 初始化程序 */ function init() { initLikeStats(); initKeyboardListener(); const checkInterval = setInterval(() => { if (document.querySelector('.like-btn')) { createControlButton(); clearInterval(checkInterval); } }, 1000); } // 启动初始化 init(); })();