You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tampermonkey脚本刷新后持久化迭代计数实现指定运行逻辑求助

实现方案

你之前的代码存在四个核心问题:

  • 同步for循环会瞬间触发两次main()调用,和函数内部基于setTimeout的异步DOM重命名逻辑冲突,导致功能异常
  • 未处理main()内部自动跳转至正确子页面的场景,跳转动作的无效执行被计入运行次数
  • 计数达到阈值后未做重置,页面刷新后会一直卡在计数满的状态,无法循环执行
  • 缺少同页面运行锁,导致脚本重复触发,出现你提到的每秒重复运行问题

直接替换原脚本全部内容为以下版本即可实现需求:

// ==UserScript==
// @name         Shinko BT Renamer
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  try to take over the world!
// @author       You
// @match        https://*/game.php*mode=incomings*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=devilicious.dev
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

var FORMAT = "#unit# from #coords# -> BT: #backtime#";
let refreshTime = 5; // 页面刷新等待时间,单位分钟

// 全局运行锁,防止同页面重复初始化
if (window.__btRenamerInited) return;
window.__btRenamerInited = true;

function main()
{
    if(window.location.href.indexOf("subtype=attacks")==-1)
    {
        window.location.href = window.location.pathname+ "?screen=overview_villages&mode=incomings&mode=incomings&subtype=attacks";
        return;
    }

    if (typeof FORMAT === 'undefined')
        FORMAT = "#unit# from #coords# - #player# Backtime: #backtime#";
    FORMAT = FORMAT.replace(/#/g, "%");
    if(FORMAT.match(/%backtime%/g)!=null)
        FORMAT = ("`" + FORMAT + "`").replace(/%backtime%/, "%return%:${('00' + ((arrivalSeconds+parseInt('%duration%'.split(':')[2]))%60).toString()).slice(-2)}");

    console.log(FORMAT);
    $('input[name=label_format]').val(FORMAT);

    let tagRows =$("#incomings_table > tbody > tr").not(':first').not(':last');
    tagRows = $.grep(tagRows, (obj)=> $(".quickedit-label", obj)[0].innerText.match(/`.*`/g)!=null);

    if(tagRows.length >0)
        $.map(tagRows, (obj, key)=>setTimeout(()=>{
            evalTag(obj);
        }, 250* key));
    else
        tagCommands();

    return tagRows.length;
}


function renameCommand(command, name)
{
    $('.rename-icon', command).click();
    $('.quickedit-edit input[type="text"]', command).val(name);
    $('.quickedit-edit input[type="button"]', command).click();
}

function evalTag(row)
{
    let command = $("td:nth-child(1)", row)[0];
    let arrivalTime = $("td:nth-child(6)", row)[0].innerText;
    let arrivalSeconds = parseInt(arrivalTime.split(":")[2]);
    let evalCommandTag;
    try
    {
        evalCommandTag = eval(command.innerText);
    }
    catch(err)
    {
        evalCommandTag = command.innerText;
    }
    renameCommand(command, evalCommandTag);
}

function tagCommands()
{
    if($("#incomings_form").length > 0)
    {
        selectAll($("#incomings_form")[0], true);
        $("[name='label']")[0].click();
    }
}

// 执行流程控制
const COUNT_STORAGE_KEY = 'bt_renamer_run_count';
function runWorkflow() {
    let currentCount = GM_getValue(COUNT_STORAGE_KEY, 0);
    if (currentCount < 2) {
        const preRunUrl = window.location.href;
        // 执行主逻辑,返回待处理的行数量,用于计算异步操作等待时间
        const rowCount = main();
        // 未触发页面跳转才是有效执行
        if (preRunUrl.includes("subtype=attacks")) {
            currentCount++;
            GM_setValue(COUNT_STORAGE_KEY, currentCount);
            // 等待所有异步重命名操作完成后,再触发下一轮执行
            const waitMs = (rowCount || 0) * 250 + 500;
            setTimeout(runWorkflow, waitMs);
        }
    } else {
        // 两次执行完成,等待指定时间后刷新
        setTimeout(() => {
            // 刷新前重置计数,下一轮页面加载从0开始
            GM_setValue(COUNT_STORAGE_KEY, 0);
            window.location.reload();
        }, refreshTime * 60 * 1000);
    }
}

// 页面加载完成后启动流程
window.addEventListener('load', runWorkflow);
关键逻辑说明
  • 运行锁通过全局变量标记初始化状态,解决脚本每秒重复执行的问题
  • 基于Tampermonkey的GM存储API持久化执行计数,页面刷新后状态不会丢失
  • 自动识别main()触发的页面跳转动作,这类未执行核心逻辑的跳转不会计入运行次数
  • 主逻辑执行后会等待所有异步DOM重命名操作全部完成,再启动下一次执行,避免操作冲突
  • 触发页面前置零存储的计数,保证刷新后的新一轮流程可以正常从0开始计数

内容的提问来源于stack exchange,提问作者jose alevs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:39:59