53
【油猴脚本】女仆论坛自动签到
每天打开论坛自动帮你完成签到,再也不用手动点了 ✅
✨ 功能特性
- 🔄 全自动两步签到:自动点击侧边栏签到 → 自动点击日历弹窗确认
- 📅 当日去重:同一天内只执行一次,刷新页面不会重复签到
- 💬 页面 Toast 提示:签到成功/超时会在右上角弹出提示,不用打开控制台
- ⏰ 超时保护:30 秒内找不到按钮自动停止,不会无限循环
- 🛡️ 点击上限:最多点 3 次,防止异常情况死循环
- ⚙️ 可配置:顶部 CONFIG 区域可自定义超时时间、轮询间隔等参数
📦 安装方法
- 先安装 Tampermonkey 浏览器扩展
- 点击 Tampermonkey 图标 → 添加新脚本
- 清空默认内容,把下面的代码全部粘贴进去
Ctrl + S保存即可
📜 完整代码
javascript// ==UserScript== // @name 女仆论坛自动签到 // @namespace http://tampermonkey.net/ // @version 4.0 // @description 自动完成 bbs.bt.sb 侧边栏及日历弹窗的两步签到 // @author mochu // @match *://bbs.bt.sb/* // @icon https://bbs.bt.sb/favicon.ico // @grant none // @run-at document-idle // ==/UserScript== (function () { 'use strict'; // ═══════════════════════════════════════════ // 配 置 区 // ═══════════════════════════════════════════ const CONFIG = { maxClicks: 3, // 最多点击次数(侧边栏1次 + 弹窗1次 + 容错1次) maxWaitSec: 30, // 最长等待秒数,超时就放弃 pollMs: 1200, // 轮询间隔(毫秒) debug: false // 开启后在 console 输出详细日志 }; // ═══════════════════════════════════════════ // 工 具 函 数 // ═══════════════════════════════════════════ const TAG = '[女仆签到]'; const log = (...args) => console.log(TAG, ...args); const dbg = (...args) => CONFIG.debug && console.log(TAG, '[DBG]', ...args); /** 今天的日期字符串,用于 localStorage 去重 */ function todayKey() { const d = new Date(); return `checkin_${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`; } /** 页面内弹出一个小提示(右上角浮层,3 秒后自动消失) */ function showToast(msg, color = '#52c41a') { const el = document.createElement('div'); Object.assign(el.style, { position: 'fixed', top: '16px', right: '16px', zIndex: '99999', padding: '12px 22px', borderRadius: '10px', background: color, color: '#fff', fontSize: '14px', fontWeight: '600', boxShadow: '0 4px 16px rgba(0,0,0,.18)', opacity: '0', transform: 'translateY(-12px)', transition: 'all .35s ease', pointerEvents: 'none' }); el.textContent = msg; document.body.appendChild(el); requestAnimationFrame(() => { el.style.opacity = '1'; el.style.transform = 'translateY(0)'; }); setTimeout(() => { el.style.opacity = '0'; el.style.transform = 'translateY(-12px)'; setTimeout(() => el.remove(), 400); }, 3200); } /** * 在可见元素中查找纯文本完全匹配 target 的元素 * 优先返回层级最深(最内层)的匹配,避免误点父容器 */ function findVisibleByText(target) { const all = document.querySelectorAll('button, a, span, div, p, label'); const hits = []; for (const el of all) { // 只看自身直属文本,排除子元素干扰 const ownText = Array.from(el.childNodes) .filter(n => n.nodeType === Node.TEXT_NODE) .map(n => n.textContent.trim()) .join('') .replace(/\s+/g, ''); // 也兼容只有一个子元素且子元素包含目标文字的情况 const innerText = el.textContent.trim().replace(/\s+/g, ''); const matched = ownText === target || (innerText === target && el.children.length === 0); if (matched && el.offsetParent !== null) { hits.push(el); } } return hits; } /** 获取真正可点击的最近祖先(button > a > 自身) */ function clickable(el) { return el.closest('button') || el.closest('a') || el; } // ═══════════════════════════════════════════ // 主 逻 辑 // ═══════════════════════════════════════════ function run() { // —— 1. 今日已签到过就跳过(同一浏览器同一天内不重复执行) —— if (localStorage.getItem(todayKey())) { dbg('今日已在 localStorage 中标记签到完成,跳过。'); return; } let clicks = 0; let elapsed = 0; let timer = null; function stop(reason) { clearInterval(timer); dbg('停止轮询:', reason); } timer = setInterval(() => { elapsed += CONFIG.pollMs; // —— 2. 检测"已签到"状态 —— const doneHits = findVisibleByText('已签到'); if (doneHits.length > 0) { localStorage.setItem(todayKey(), '1'); log('✅ 签到成功!'); showToast('✅ 女仆论坛 · 今日签到完成'); stop('已签到'); return; } // —— 3. 超时保护 —— if (elapsed >= CONFIG.maxWaitSec * 1000) { log('⏰ 等待超时,可能未登录或签到按钮不存在。'); showToast('⏰ 签到超时,请检查登录状态', '#faad14'); stop('超时'); return; } // —— 4. 点击次数保护 —— if (clicks >= CONFIG.maxClicks) { log('⚠️ 已达最大点击次数,等待页面响应...'); // 不立即停止,继续等"已签到"状态出现 return; } // —— 5. 查找并点击"签到"按钮 —— const signBtns = findVisibleByText('签到'); if (signBtns.length > 0) { // 优先点击最后一个(弹窗内的按钮一般在 DOM 尾部) const target = clickable(signBtns[signBtns.length - 1]); clicks++; log(`🖱️ 第 ${clicks} 次点击 →`, target.tagName, target.className || ''); target.click(); } else { dbg(`等待签到按钮出现... (${Math.round(elapsed / 1000)}s)`); } }, CONFIG.pollMs); // —— 6. 兜底:页面卸载前清理定时器 —— window.addEventListener('beforeunload', () => stop('页面卸载')); } // —— 入口:等 DOM 完全就绪后再启动 —— if (document.readyState === 'complete') { setTimeout(run, 800); } else { window.addEventListener('load', () => setTimeout(run, 800)); } })();
💡 使用说明
- 安装后正常打开论坛就行,脚本会在页面加载完成后自动执行
- 签到成功后页面右上角会弹出绿色提示
✅ 女仆论坛 · 今日签到完成 - 同一天内刷新页面或在论坛内跳转不会重复签到
- 如果想看详细执行日志,把代码里的
debug: false改成debug: true,然后按F12打开控制台查看
⚠️ 注意事项
- 需要先登录论坛,脚本不会帮你自动登录
- 如果签到超时(30 秒),会弹出黄色提示,请检查是否已登录
有问题欢迎回帖交流 👋
这个用户还没有留下简介。
第 1 条附言·2小时前
可以直接使用油猴链接打开安装
https://gist.githubusercontent.com/mochu8/837602aa4c57579c96e28e8769c5133a/raw/女仆论坛自动签到.user.js