大佬论坛自动静默签到油猴插件

五霸哥 屌  (UID: 5079) [复制链接]
帖子链接已复制到剪贴板
帖子已经有人评论啦,不支持删除!

419 9

功能:访问自动静默签到、页面显示签到状态、预防多请求问题(当天对应UID只请求一次)

 

// ==UserScript==
// @name         大佬论坛-每日自动签到
// @version      1.0.0
// @description  每天自动静默签到,按UID记录,头部导航显示绿色"已签"
// @author       五霸哥
// @match        *://*.dalao.net/*
// @match        *://dalao.net/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    // 避免在 iframe 中执行
    if (window.self !== window.top) return;

    // ==================== 配置区域 ====================
    const SIGNIN_URL = 'signin.htm';
    const STORAGE_KEY = 'dahua_auto_signin_v2';
    const DEBUG = true;
    // ==================================================

    function log(...args) {
        if (DEBUG) console.log('[自动签到]', ...args);
    }

    function getTodayKey() {
        const d = new Date();
        return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
    }

    // ==================== UID 相关 ====================

    /**
     * 获取当前登录用户的 UID
     */
    function getCurrentUid() {
        // 1. 优先从全局变量获取(页面中通常有 var uid = 1234;)
        if (typeof window.uid !== 'undefined' && window.uid) {
            return String(window.uid);
        }

        // 2. 从导航栏个人链接提取
        const myLink = document.querySelector('a[href="my.htm"]');
        if (myLink) {
            const text = myLink.textContent || '';
            const m = text.match(/UID:\s*(\d+)/);
            if (m) return m[1];
        }

        // 3. 从 user-xxx.htm 链接提取当前用户自己的
        const userLinks = document.querySelectorAll('a[href*="user-"]');
        for (const a of userLinks) {
            const href = a.getAttribute('href') || '';
            const m = href.match(/user-(\d+)\.htm/);
            if (m) return m[1];
        }

        return null;
    }

    /**
     * 读取本地签到记录
     * 格式: { "1": "2026-05-05", "333": "2026-05-04" }
     */
    function getSigninRecord() {
        try {
            return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
        } catch {
            return {};
        }
    }

    function saveSigninRecord(record) {
        try {
            localStorage.setItem(STORAGE_KEY, JSON.stringify(record));
        } catch (e) {
            log('localStorage 写入失败', e);
        }
    }

    function isSignedToday(uid) {
        if (!uid) return false;
        const record = getSigninRecord();
        return record[uid] === getTodayKey();
    }

    function markSignedToday(uid) {
        if (!uid) return;
        const record = getSigninRecord();
        record[uid] = getTodayKey();
        saveSigninRecord(record);
        log(`UID ${uid} 已标记今天签到成功`);
    }

    function clearSigninRecord() {
        localStorage.removeItem(STORAGE_KEY);
        alert('签到记录已清除,刷新页面后将重新尝试签到。');
    }

    if (typeof GM_registerMenuCommand !== 'undefined') {
        GM_registerMenuCommand('🔄 清除签到记录', clearSigninRecord);
    }

    // ==================== 头部状态更新 ====================

    /**
     * 设置签到处理中状态:图标变为蓝色
     */
    function setSigninProcessing() {
        const selectors = ['#nav-signin', '#nav-signin-mobile'];
        selectors.forEach(sel => {
            const link = document.querySelector(sel);
            if (!link) return;
            const icon = link.querySelector('i.far.fa-calendar-check, i.fa-calendar-check');
            if (icon) {
                icon.style.color = '#007bff';
                icon.style.transition = 'color 0.3s ease';
            }
        });
    }

    /**
     * 更新头部导航为已签到状态:图标和文字均变为绿色
     */
    function updateHeaderSigned() {
        // --- 桌面端 ---
        const desktopLink = document.querySelector('#nav-signin');
        if (desktopLink) {
            const icon = desktopLink.querySelector('i.far.fa-calendar-check, i.fa-calendar-check');
            if (icon) {
                icon.style.color = '#28a745';
                icon.style.transition = 'color 0.3s ease';
            }
            const span = desktopLink.querySelector('span');
            if (span && span.textContent.trim() === '签到') {
                span.textContent = '已签';
                span.style.color = '#28a745';
                span.style.fontWeight = 'bold';
            }
            log('桌面端头部已改为绿色"已签"');
        }

        // --- 移动端 ---
        const mobileLink = document.querySelector('#nav-signin-mobile');
        if (mobileLink) {
            const icon = mobileLink.querySelector('i.far.fa-calendar-check, i.fa-calendar-check');
            if (icon) {
                icon.style.color = '#28a745';
                icon.style.transition = 'color 0.3s ease';
            }
            log('移动端头部图标已改为绿色');
        }
    }

    // ==================== 静默签到核心 ====================

    function checkSignedFromHtml(html) {
        const hasSignedText = /今日已签到/.test(html);
        const hasUnsignedText = /今日未签到/.test(html);
        return hasSignedText && !hasUnsignedText;
    }

    function extractVerifyKey(html) {
        const match = html.match(/var\s+g_verify_key\s*=\s*"([^"]+)"/);
        return match ? match[1] : null;
    }

    /**
     * 使用页面自带的 $.xpost 进行静默签到,确保请求格式与手动点击完全一致
     */
    function silentSignin(retryCount) {
        retryCount = retryCount || 0;
        return new Promise((resolve) => {
            // 等待 jQuery 及 $.xpost 可用(最多等 5 秒)
            let waitCount = 0;
            const maxWait = 50;

            function trySignin() {
                if (typeof $ === 'undefined' || typeof $.xpost !== 'function') {
                    if (++waitCount < maxWait) {
                        setTimeout(trySignin, 100);
                        return;
                    }
                    log('jQuery 或 $.xpost 未加载,无法静默签到');
                    resolve(false);
                    return;
                }

                log('开始静默签到...');

                // 1. 先 GET signin.htm 获取 verify_key 及当前状态
                $.get(SIGNIN_URL, function(html) {
                    if (checkSignedFromHtml(html)) {
                        log('服务器返回已签到');
                        resolve(true);
                        return;
                    }

                    const verifyKey = extractVerifyKey(html);
                    if (!verifyKey) {
                        log('未找到 verify_key');
                        resolve(false);
                        return;
                    }
                    log('verify_key:', verifyKey);

                    // 2. 延迟 2 秒后发送签到请求,避免触发频率限制
                    setTimeout(function() {
                        doXpost(verifyKey);
                    }, 2000);
                }).fail(function(xhr, status, err) {
                    log('获取 signin.htm 失败:', status, err);
                    resolve(false);
                });

                function doXpost(verifyKey) {
                    // 使用页面原生的 $.xpost 发送签到请求
                    $.xpost(SIGNIN_URL, { verify_key: verifyKey }, function(code, message) {
                        log('$.xpost 响应 code=', code, 'message=', message);

                        if (code === 0) {
                            log('静默签到成功');
                            resolve(true);
                            return;
                        }

                        const msg = (typeof message === 'object'
                            ? (message.message || JSON.stringify(message))
                            : message) || '';

                        if (/已签到|已经签到|今日已签/.test(String(msg))) {
                            log('服务器提示已签到');
                            resolve(true);
                            return;
                        }

                        // 触发频率限制,且未超过最大重试次数时,延迟 5 秒后重试
                        if (/操作太快|太快了|请稍后再试/.test(String(msg)) && retryCount < 2) {
                            log('触发频率限制,5秒后第' + (retryCount + 1) + '次重试...');
                            setTimeout(function() {
                                silentSignin(retryCount + 1).then(resolve);
                            }, 5000);
                            return;
                        }

                        log('静默签到失败:', msg);
                        resolve(false);
                    });
                }
            }

            trySignin();
        });
    }

    // ==================== 主入口 ====================

    async function main() {
        const uid = getCurrentUid();
        log('UID:', uid, '| 页面:', location.pathname, '| 今天:', getTodayKey());

        if (!uid) {
            log('未获取到 UID,跳过');
            return;
        }

        // 1. 本地已有记录 → 直接改头部,不再调接口
        if (isSignedToday(uid)) {
            log('本地记录该账号今天已签到,跳过接口调用');
            updateHeaderSigned();
            return;
        }

        // 2. 本地无记录 → 静默签到
        setSigninProcessing();
        const ok = await silentSignin();
        if (ok) {
            markSignedToday(uid);
            updateHeaderSigned();
        }
    }

    // ==================== 启动 ====================
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', main);
    } else {
        main();
    }

})();
紫名炫彩昵称2025-12-13到期
已有评论 ( 9 )
提示:您必须 登录 才能查看此内容。
域名市场
   域名载入中...
创建新帖
自助推广 (点击空位或 这里 添加)
确认删除
确定要删除这篇帖子吗?删除后将无法恢复。
删除成功
帖子已成功删除,页面将自动刷新。
删除失败
删除帖子时发生错误,请稍后再试。