/* eslint-disable no-multi-spaces */ // ==UserScript== // @name Kamigotchi辅助脚本-公开版 (helper) // @namespace http://tampermonkey.net/ // @version 1.2.9 // @downloadURL https://raw.githubusercontent.com/funcreator2030/kamigotchi-scripts/main/kamigotchi-helper.user.js // @updateURL https://raw.githubusercontent.com/funcreator2030/kamigotchi-scripts/main/kamigotchi-helper.meta.js // @homepageURL https://github.com/funcreator2030/kamigotchi-scripts // @x-release-date 2026/9/11 17:05:48 // @description Kamigotchi辅助脚本公开版:一键升级+技能管理+自动合成(DOM步长真值)+LT显示+地块适配分析+杀手候选扫描+启动窗口复活+精确清算线(每6小时全网最强杀手扫描+默认档案地板)+gas挂钩记账(1.2.4) // @match https://*.kamigotchi.io/* // @grant none // @run-at document-idle // ==/UserScript== // 🔻SYNC→内部版[1.1.20 看板白名单三批]:版本仪式(@name/@version/banner/启动log/命令清单banner 同步升 v1.1.20) // ╔══════════════════════════════════════════════════════════════════════════════╗ // ║ Kamigotchi 辅助脚本 · 公开版 v1.2.8 ║ // ╠══════════════════════════════════════════════════════════════════════════════╣ // ║ 本脚本是核心脚本的配套组件,与核心脚本同时安装在 Tampermonkey 中运行。 ║ // ║ 核心脚本负责部署/停采/喂食/复活等主流程;本辅助脚本提供以下能力: ║ // ║ ║ // ║ 1. LT 显示增强 —— 在每张 kami 卡片上叠加清算线(LT)徽标,危险的标红。 ║ // ║ 用 CSS 伪元素 + data 属性实现,React 重渲染也不会洗掉。 ║ // ║ 2. 自动升级 —— 游戏加载完成后自动为可升级的 kami 执行升级; ║ // ║ 按标准 build 顺序自动加技能点;检测到非标准技能时 ║ // ║ 用 Respec 药水自动重置再按标准加点。杀手 kami 自动跳过。 ║ // ║ 3. 自动合成 —— 按优先级列表(CRAFT_PRIORITY)周期性合成物品。 ║ // ║ 步长只认 DOM 实时读数(链上 API 的 stamina.sync 是 ║ // ║ 检查点旧值,不随时间回复,不可用作真值)。 ║ // ║ 遵循"先查后锁"纪律:确认有活干才占 TX 锁。 ║ // ║ 4. 启动窗口复活 —— 核心脚本启动需等约 2 分钟,本脚本加载快:刷新后一进游戏 ║ // ║ 就先批量复活死亡 kami(与核心共享防重发记录和 revive 锁)。 ║ // ║ 5. 地块适配分析 —— kamiAnalyze():按 body+hand 属性把 kami 分类到最适合的 ║ // ║ 地块类型,标出 majority/minority 分布,转移决策一目了然。 ║ // ║ 6. 杀手候选扫描 —— findKillerCandidates():在你自己账户的 kami 里,按 ║ // ║ 出生属性(vioBase/harmBase/powBase)筛出天生适合转型 ║ // ║ 做杀手的候选(选秀工具,非敌情侦察),零 API 成本, ║ // ║ 启动后自动跑一次。 ║ // ║ 7. 实时步长接口 —— getStaminaFromDOM():从页面读取实时步长, ║ // ║ 是本脚本和核心脚本合成决策的唯一步长真值来源。 ║ // ║ 8. 精确清算线 —— 每6小时自动全网扫描最强杀手(四桶档案存 localStorage ║ // ║ kami_top_predators 键,独立键值不覆盖其他数据),按游戏 ║ // ║ 合约官方公式重算全库清算线;代码内置默认档案兜底。 ║ // ║ ║ // ║ ▍与其他脚本的协作(通过 window.xxx 接口互相调用): ║ // ║ - 核心脚本 → 调用本脚本的 getStaminaFromDOM()(读步长)、 ║ // ║ __getMinorityKamis()(转移停采) ║ // ║ - 本脚本 → 调用核心脚本的 TX 锁接口(hasEmergencyLock 等), ║ // ║ 升级/重置前让路紧急停采 ║ // ║ - 精简数据库脚本 → 提供 window.kami_core_db(本脚本升级/扫描/分析的数据源) ║ // ║ - 杀手监控脚本 → 维护 window.MY_KILLER_KAMIS(本脚本升级/重置自动跳过名单) ║ // ║ ║ // ║ ▍自动任务时刻表: ║ // ║ - 自动升级:游戏加载完成后自动执行,之后每 30 分钟检查一次 ║ // ║ - 自动合成:脚本启动 5 分钟后首次检测,之后每 30 分钟一次 ║ // ║ - LT 显示刷新:每 5 分钟一次(手动刷新 window.__refreshLT()) ║ // ╚══════════════════════════════════════════════════════════════════════════════╝ // ============================================================ // 【术语速览(第一次使用前建议先读这里)】 // ------------------------------------------------------------ // TX — 链上交易(transaction)。脚本的每个"写"操作都要发 TX、消耗 gas。 // TX 双锁 — 核心/辅助脚本共享的两把发交易互斥锁:紧急锁(紧急停采专用, // 最高优先级,其他操作一律让路)+ 普通锁(升级/合成/复活等 // 常规操作互斥)。目的:防止多个脚本同时发 TX 造成 nonce 冲突。 // 清算线(LT) — kami 采集时 HP% 低于此线,就可能被其他玩家的杀手 kami 清算 // (击杀)。由 harmony、体质、防御技能加成算出,单位为 HP 百分比。 // 步长(stamina) — 账户级行动力资源(0~100,随时间回复),合成等操作消耗步长。 // build — 技能加点方案。"标准 build"指本脚本内置的采集向加点方案 // (作者的策略,可自定义,见 STANDARD_SKILLS 板块的新手提示)。 // 标准技能 — 属于标准 build 的技能 ID 集合(STANDARD_SKILLS);kami 点了 // 集合之外的技能即"非标准",会触发自动重置(Respec)。 // Respec — 技能洗点:消耗 1 瓶 Respec Potion(洗点药水)重置 kami 的 // 全部技能点,之后可重新分配。 // affinity — 亲和属性(地形属性)。kami 的 body/hand 部件与采集地块都带 // 属性(normal/eerie/scrap/insect),属性匹配的地块采集收益最优。 // majority/minority — 账户内 kami 按最适合的地块分四类后,数量最多的一类为 // majority(主流类),其余为 minority(少数派)——多账户分工 // 时 minority 是转移到其他账户的候选。 // db-first — 优先在本地精简数据库(window.kami_core_db,由精简数据库 // 脚本构建)的内存数据里筛选,只对少量候选发 API 查询的 // 省时策略,通常几秒完成。 // ============================================================ // ============================================================ // 【常用控制台命令速查】 // ------------------------------------------------------------ // upgradekamis() - 手动触发一轮升级+技能管理 // checkAllKamiSkills() - 检查全部 kami 的技能是否符合标准 build(只查不改) // getRespecPotionCount() - 查看背包 Respec 药水数量 // kamiAnalyze() - 地块适配分析(majority/minority 分布,四色分类输出) // findKillerCandidates() - 在自己账户的 kami 里找适合转型杀手的候选(db-first,几秒完成) // scanTopPredators() - 全网扫描最强杀手并更新威胁档案(自动:无档案/超6小时时启动自扫) // showTopPredators() - 查看当前生效的顶尖杀手档案(含来源与扫描时间) // refreshPreciseLT() - 手动按当前档案重算全库精确清算线 // showHealth() - 代码健康看板:期望表对照心跳,标红"该跑没跑"的模块(每30分钟自检) // autoCraft() - 手动触发一轮自动合成 // startAutoCraft() - 启动自动合成周期任务 // stopAutoCraft() - 停止自动合成周期任务 // window.__refreshLT() - 手动刷新卡片上的 LT 显示 // ============================================================ (function () { 'use strict'; // ============================================================ // 【板块:日志基础设施(log / __kamiLogBuffer)】 // ------------------------------------------------------------ // ▍功能: // 提供全脚本统一的 log() 函数:控制台输出自动带 [辅助脚本] 前缀 // 和配置时区的时间(默认浏览器本地);同时把一份剥离样式标记的明文推送到与核心 // 脚本共享的日志缓冲区 window.__kamiLogBuffer,供核心脚本的 // saveKamiLogs() 把核心/辅助两个脚本的日志合并导出保存。 // ▍触发时机: // 脚本内所有需要留痕的输出都走 log();以 "[调试]" 开头的高频调试 // 输出走 console.log(),由下方"调试总开关"板块统一放行/拦截。 // ▍依赖: // - window.__kamiLogBuffer:跨脚本共享的数组缓冲区,哪个脚本先 // 启动就由谁创建(本函数检测到不存在或非数组时会自行初始化); // - 不依赖 DOM、localStorage、链上 API。 // ▍核心流程: // 1) 取当前时间 +8 小时偏移,格式化为 "YYYY-MM-DD HH:mm:ss"; // 2) 控制台先打印前缀行、再打印内容本身(分两行打印,保留 // console 对对象的原生展开能力,不把对象强转成字符串); // 3) 把各参数序列化为明文(字符串剥离 %c 样式标记避免乱码; // 对象走 JSON.stringify,失败则退回 String()),拼成一行 // push 进缓冲区。 // ▍边界与保护: // - 缓冲区写入整体包在 try/catch 中:buffer 不可用只影响日志 // 存档,不影响控制台输出; // - JSON.stringify 失败(循环引用等)时回退 String(a) 容错。 // ▍可调参数: // - TZ_OFFSET_HOURS — 时区设置(v1.1.3 起):'auto' 自动跟随浏览器 // 本地时区;也可写死数字(小时,如 8 / -5 / 5.5)。 // ▍相关控制台命令: // - saveKamiLogs()(核心脚本提供)— 导出 __kamiLogBuffer 中的 // 全部日志。 // ▍补充说明(Console 中日志来源链接的显示差异): // 同步调用链里的 console.log(如在 Console 手动执行命令)来源 // 显示为短串 VM####:line;异步回调(Promise/setTimeout/RAF)里 // 的输出显示为长串 userscript.html?name…:line。这由 V8 按 // "调用栈是否处于 microtask/macrotask"决定,与函数定义位置无关, // 脚本层面无法改变;若希望全部显示为 VM 短串,可把 Tampermonkey // 设置中的 Inject Mode 改为 Instant。 // ============================================================ // 【时区设置】(v1.1.3 起)'auto'=自动跟随浏览器本地时区;也可写死数字(小时):8=UTC+8、-5=UTC-5、5.5=UTC+5:30 const TZ_OFFSET_HOURS = 'auto'; const __TZ_OFFSET_MS = (TZ_OFFSET_HOURS === 'auto') ? -new Date().getTimezoneOffset() * 60 * 1000 : Number(TZ_OFFSET_HOURS) * 60 * 60 * 1000; //=====定义日志格式,自动加配置时区的时间前缀===== function log(...args) { const now = new Date(); // UTC 毫秒数 +8 小时偏移,再借 toISOString 格式化成 "YYYY-MM-DD HH:mm:ss" const beijingTime = new Date(now.getTime() + __TZ_OFFSET_MS) .toISOString() .replace('T', ' ') .substring(0, 19); const prefix = `[辅助脚本][${beijingTime}]`; // 控制台输出:前缀与内容分两行打印,保留 console 对对象的展开能力 console.log(prefix); console.log(...args); // 推送到核心脚本的日志缓冲区,让 saveKamiLogs() 能保存 try { if (!Array.isArray(window.__kamiLogBuffer)) { window.__kamiLogBuffer = []; } const plainText = args.map(a => { if (typeof a === 'string') return a.replace(/%c/g, ''); try { return JSON.stringify(a); } catch { return String(a); } }).join(' '); window.__kamiLogBuffer.push(`${prefix} ${plainText}`); } catch (_) { /* buffer 不可用就忽略,不影响控制台输出 */ } } // ============================================================ // 【板块:控制台输出也进日志(clog / ctable)】 // ------------------------------------------------------------ // ▍log() 会同时写控制台和 __kamiLogBuffer(存档用),但脚本里还有一批直接 // console.log 的地方——启动命令清单、参数设置回执、调试行、表格…… 这些在 // 控制台看得见,保存出来的日志文件里却一行没有,事后没法复盘。 // ▍用户 0911 定案:「我要都走日志,方便事后检查日志」→ 自有 console.log 全部 // 改走 clog,console.table 改走 ctable。控制台输出一字不变(%c 彩色照常), // 额外把纯文本副本写进共享缓冲区。 // ▍%c 及其配套 CSS 参数剥掉;多行按行拆开逐行入库;全程 try 包住绝不影响主流程。 // 🔻SYNC→内部版[全量输出入日志] // ============================================================ function __plainArgs(args) { const parts = []; let cssLeft = 0; // 首参里有几个 %c,后面就有几个 CSS 字符串要跳过 for (let i = 0; i < args.length; i++) { const a = args[i]; if (i === 0 && typeof a === 'string') { cssLeft = (a.match(/%c/g) || []).length; parts.push(a.replace(/%c/g, '')); continue; } if (cssLeft > 0 && typeof a === 'string') { cssLeft--; continue; } if (typeof a === 'string') { parts.push(a); continue; } try { parts.push(JSON.stringify(a)); } catch (_) { parts.push(String(a)); } } return parts.join(' '); } function clog(...args) { console.log(...args); // 控制台原样输出,样式不受影响 try { if (!Array.isArray(window.__kamiLogBuffer)) window.__kamiLogBuffer = []; const __t = new Date(Date.now() + __TZ_OFFSET_MS).toISOString().replace('T', ' ').substring(0, 19); for (const __line of String(__plainArgs(args)).split('\n')) { window.__kamiLogBuffer.push(`[辅助脚本][${__t}] ${__line}`); } } catch (_) {} } function ctable(rows) { try { console.table(rows); } catch (_) { console.log(rows); } try { if (!Array.isArray(window.__kamiLogBuffer)) window.__kamiLogBuffer = []; const __t = new Date(Date.now() + __TZ_OFFSET_MS).toISOString().replace('T', ' ').substring(0, 19); const __list = Array.isArray(rows) ? rows : [rows]; window.__kamiLogBuffer.push(`[辅助脚本][${__t}] (表格 ${__list.length} 行)`); for (const __r of __list) { let __s; try { __s = JSON.stringify(__r); } catch (_) { __s = String(__r); } window.__kamiLogBuffer.push(`[辅助脚本][${__t}] ${__s}`); } } catch (_) {} } //=====提示脚本启动====== log('%c✅ Kamigotchi辅助脚本-公开版 v1.2.8 已成功启动,等待网页加载完成…', 'font-size:16px;font-weight:bold;color:#fff;background:#2e7d32;padding:3px 10px;border-radius:4px'); // 🔻SYNC→内部版[1.1.23 启动横幅醒目化] // 🔻SYNC→内部版[1.1.20 看板白名单三批] // ============ [版本检查] 启动时对比 GitHub 最新版本,提示用户是否已更新 ============ // 🔻SYNC→内部版[1.1.21 版本检查](内部版无 GitHub 分发,同步时可整块跳过) (function versionCheck() { const SELF_NAME = '辅助脚本'; const SELF_VERSION = '1.2.9'; // ⚠️ 版本仪式第6处:升版时必须同步改这里 const META_URL = 'https://raw.githubusercontent.com/funcreator2030/kamigotchi-scripts/main/kamigotchi-helper.meta.js'; let firstSeen = null; try { // 本机此版本首次运行时间 ≈ 篡改猴安装/更新时间(无法直接读TM,取首次见到该版本的时刻) const k = 'kami_ver_seen_' + SELF_NAME + '_' + SELF_VERSION; firstSeen = localStorage.getItem(k); if (!firstSeen) { firstSeen = new Date().toLocaleString('zh-CN'); localStorage.setItem(k, firstSeen); } } catch (e) { firstSeen = '未知'; } const cmpVer = (a, b) => { // 返回 -1/0/1 const pa = String(a).split('.').map(Number), pb = String(b).split('.').map(Number); for (let i = 0; i < Math.max(pa.length, pb.length); i++) { const d = (pa[i] || 0) - (pb[i] || 0); if (d) return d > 0 ? 1 : -1; } return 0; }; setTimeout(async () => { try { const resp = await fetch(META_URL + '?_=' + Date.now(), { cache: 'no-store' }); const txt = await resp.text(); const remoteVer = (txt.match(/@version\s+v?([\d.]+)/) || [])[1]; const relDate = (txt.match(/@x-release-date\s+(\S+[^\n\r]*)/) || [])[1] || '未知'; if (!remoteVer) { log(`ℹ️ [版本检查] 无法解析 GitHub 最新版本,跳过(网络/格式异常)`); return; } const c = cmpVer(SELF_VERSION, remoteVer); if (c === 0) { log(`✅ [版本检查] ${SELF_NAME} v${SELF_VERSION} 已是 GitHub 最新(该版发布于 ${relDate};本机安装/更新于 ${firstSeen})`); } else if (c < 0) { log(`%c⚠️ [版本检查] GitHub 最新为 v${remoteVer}(发布于 ${relDate}),本机 ${SELF_NAME} 还是 v${SELF_VERSION}(本机更新于 ${firstSeen})→ 请到篡改猴面板「实用工具→检查用户脚本更新」拉取最新`, 'color: orange; font-weight: bold;'); } else { log(`ℹ️ [版本检查] 本机 ${SELF_NAME} v${SELF_VERSION} 比 GitHub(v${remoteVer}) 更新(本地开发版)`); } } catch (e) { // 🔻SYNC→内部版[1.1.24 版本检查降噪](游戏 SPA 运行时注入 CSP meta 的 connect-src 白名单,raw 外联在游戏页永久失败) // fetch 失败绝大多数是游戏页 CSP 拒绝外联 GitHub(属正常,不影响篡改猴自动更新),旧版每次页面加载都打一行=刷屏。 // 改为 24h 内只提示一次:命中节流窗口则静默;否则打一条并刷新时间戳。 try { const noteKey = 'kami_vercheck_csp_note_' + SELF_NAME; const last = Number(localStorage.getItem(noteKey) || 0); if (Date.now() - last >= 86400000) { localStorage.setItem(noteKey, String(Date.now())); log(`ℹ️ [版本检查] 游戏页 CSP 限制外联 GitHub,无法在线比对版本(属正常,不影响篡改猴自动更新;手动检查:篡改猴图标→实用工具→检查用户脚本的更新)`); } } catch (e2) { log(`ℹ️ [版本检查] 游戏页 CSP 限制外联 GitHub,无法在线比对版本(属正常,不影响篡改猴自动更新;手动检查:篡改猴图标→实用工具→检查用户脚本的更新)`); } } }, 8000); // 延迟 8s,避开启动拥挤;raw 带 CORS *,页面上下文可直接 fetch })(); // ============================================================ // 【板块:LT 显示样式注入(injectLTStyle)】 // ------------------------------------------------------------ // ▍功能: // 向页面注入一段全局 CSS,为"LT 清算线显示"和"危险 Kami 标红" // 提供纯样式层的渲染通道。 // 为什么用 data 属性 + ::after 伪元素、而不是往卡片里插 DOM 节点: // 游戏前端是 React,重渲染会把脚本插入的子节点整批删掉;而 data-* // 只是元素上的 attribute,React 重渲染通常不会清除它。并且修改 // attribute 不触发 childList 型 MutationObserver,不会与本脚本 // 自己的 DOM 监听形成"写入→触发→再写入"的反馈循环。 // ▍触发时机:脚本载入时立即执行一次(IIFE)。 // ▍依赖:document.head(尚不存在时回退挂到 document.documentElement)。 // ▍核心流程: // 1) 检查 id 为 __aux_lt_style__ 的