
这个东西实在是太烦了,一直要点几十下,没办法了,上脚本
这样就可以不用管,安心的去刷剧了
// ==UserScript==
// @name Muse 审批助手(全自动·高亮门控版)
// @namespace https://muse.ai/
// @version 2.1-blue.3
// @description 五级自动审批:①「总是允许/始终允许{domain}」高亮门控 ②蓝色实底「允许」(蓝底+非淡色+审批上下文,存在①时礼让)③横幅蓝字「审核/批准」(蓝字+可点+审核上下文,点完进衔接窗等②接住)④「允许一次」回退(无可见①且无②候选时才点,与②同门控)。点击间隔≥1秒;单目标真实点击上限(允许2次/审核4次);绝不点「拒绝」族。
// @author Muse
// @match *://muse.ai/*
// @match *://*.muse.ai/*
// @all-frames true
// @grant none
// @run-at document-idle
// ==/UserScript==
(function () {
'use strict';
// ---------- 点击目标(黑名单前置,绝点不到别的) ----------
// P1:「总是允许」族(含英文变体与「始终允许{domain}」等 i18n 实录变体)——必须处于高亮态才点
var AUTO_TARGETS = ['总是允许此站点', '总是允许', 'always allow this site', 'always allow'];
var RE_ALWAYS = /^(总是|始终)允许.{1,40}$/; // 始终允许tuta.com / 始终允许Muse用于剪贴板 / 允许所有xxx方法…
// P2:主审批弹窗的蓝色实底「允许」(1.png / 2.png 实测形态)——词条全部来自产品 i18n 表
var BLUE_ALLOW_TEXTS = ['允许', '允许访问', '允许访问此站点', 'allow', 'allow access', 'approve', 'approve access'];
// P5:「允许一次」回退族(右侧「允许一次▾」主按钮实测形态)——v2.1-blue.3 起从黑名单解禁,
// 用户规则:没有「始终允许」的时候才点「允许一次」(可见 P1 在场硬挡,P2 候选在场礼让)
var ALLOW_ONCE_TEXTS = ['允许一次', 'allow once'];
// P4:横幅里的蓝字「审核/批准」入口(3.png 实测形态:行尾小型蓝色文字链,非 button 语义)
var REVIEW_TEXTS = ['审核', '批准'];
var FORBIDDEN = ['拒绝', 'reject', 'deny', '不允许', 'never allow', "don't allow", 'do not allow'];
// 高亮态的类名特征(应用自绘高亮时兜底识别)
var HIGHLIGHT_CLASS_RE = /(^|[-_\s])(is-)?(focus(ed)?|highlight(ed)?|selected|current|hover|active)([-_\s]|$)/i;
// ---------- 节流与重试参数(点击间隔硬性≥1秒) ----------
var MIN_CLICK_INTERVAL = 1000; // 任意两次真实点击的最小间隔
var HIGHLIGHT_WAIT = 150; // 触发 hover/focus 后等 UI 渲染高亮的时长
var RETRY_DELAY = 1000; // 未高亮/未生效后的重试间隔
var MAX_ATTEMPTS = 6; // 单个按钮最大尝试轮数
var MAX_CLICKS = 2; // P1/P2 单目标真实点击上限(el.click() 一次 + 指针序列一次)
var P2_DEFER = 1200; // P1 礼让:存在 P1 时 P2 每次推迟出手的时长
var P2_DEFER_MAX = 3; // 礼让重排上限(累计约 3.6 秒),超时降级点 P2
var P4_FOLLOWUP = 5000; // 点完「审核/批准」后等蓝色「允许」出现的衔接窗,期间不重重点
var P4_MAX_CLICKS = 4; // 审核入口重试上限(入口可能无响应,点完不弹窗才重试)
var BLUE_MARGIN = 20; // 蓝通道需领先红/绿通道的幅度
var DIM_OPACITY = 0.6; // 透明度低于此值视为淡色,不点
function norm(s) {
return (s || '').replace(/\s+/g, ' ').trim().toLowerCase();
}
// 0=非目标 1=P1 总是允许族 2=P2 蓝色允许族 3=P4 审核入口 5=P5 允许一次回退
function targetTier(el) {
if (!el || el.disabled || el.getAttribute('aria-disabled') === 'true') return 0;
var t = norm(el.textContent || el.value);
if (!t) return 0;
if (FORBIDDEN.indexOf(t) !== -1) return 0;
if (AUTO_TARGETS.indexOf(t) !== -1 || RE_ALWAYS.test(t)) return 1;
if (BLUE_ALLOW_TEXTS.indexOf(t) !== -1) return 2;
if (ALLOW_ONCE_TEXTS.indexOf(t) !== -1) return 5;
if (REVIEW_TEXTS.indexOf(t) !== -1) return isReviewEntry(el) ? 3 : 0;
return 0;
}
function isAutoTarget(el) { return targetTier(el) === 1; }
function isTarget(el) { return targetTier(el) !== 0; }
function isVisible(el) {
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
}
function stillPending(el) {
return el.isConnected && !el.disabled && isVisible(el) && isTarget(el);
}
// ---------- 高亮检测 ----------
// “高亮”= 截图里蓝底/焦点光环那种选中态。四类信号任一命中才算高亮:
// 1) :focus-visible 焦点环 2) 应用加的高亮类名
// 3) 背景色变成彩色(如蓝色高亮填充) 4) 相对基线的样式变化(描边/阴影/底色)
// 仅仅“获得焦点”不算高亮;无任何视觉信号时按要求不点击。
var STYLE_PROPS = ['background-color', 'outline', 'outline-color', 'box-shadow', 'border-color', 'color', 'opacity'];
function styleSignature(cs) {
var parts = [];
for (var i = 0; i < STYLE_PROPS.length; i++) {
try { parts.push(STYLE_PROPS[i] + ':' + cs.getPropertyValue(STYLE_PROPS[i])); } catch (e) {}
}
return parts.join('|');
}
function snapshot(el) {
try { return styleSignature(window.getComputedStyle(el)); } catch (e) { return ''; }
}
function parseRGB(str) {
var m = /rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)(?:[,\s/]+([\d.]+))?\s*\)/.exec(str || '');
if (!m) return null;
return { r: +m[1], g: +m[2], b: +m[3], a: m[4] === undefined ? 1 : parseFloat(m[4]) };
}
function looksAccent(cs) {
var c = parseRGB(cs.backgroundColor);
if (!c || c.a < 0.15) return false; // 透明背景不算
var max = Math.max(c.r, c.g, c.b), min = Math.min(c.r, c.g, c.b);
return (max - min) > 40; // 灰色系不算,彩色填充(蓝色高亮)才算
}
// ---------- P2 蓝色「允许」门控 ----------
// 只认静态蓝底实心填充(1.png / 2.png 实测形态):蓝通道领先红/绿通道。
// hover 才变蓝的形态(CSS :hover 合成事件触发不了)不算,绝不自己制造点击条件。
function looksBlue(cs) {
var c = parseRGB(cs.backgroundColor);
if (!c || c.a < 0.6) return false; // 透明/半透明不算实底
return (c.b - c.r) >= BLUE_MARGIN && (c.b - c.g) >= BLUE_MARGIN;
}
// 淡色(如 opacity<0.6 的置灰态)不算可点主按钮
function isDimmed(cs) {
var o = parseFloat(cs.opacity);
return isFinite(o) && o < DIM_OPACITY;
}
// 审批界面是否已打开:蓝色「允许」+ 同框审批上下文(不查淡色——置灰只是过渡态,
// 界面确实开着)。P4 门槛用这个判断,不能用“有没有 P2 候选”:
// 无审批语境的裸蓝允许(如「你想怎么继续?」+允许)是候选但界面并未打开,P4 仍要出手。
function p2SurfaceOpen(el) {
var cs = null;
try { cs = window.getComputedStyle(el); } catch (e) { return false; }
return !!cs && looksBlue(cs) && approvalContext(el);
}
// ---------- P4 蓝字「审核/批准」门控 ----------
// 3.png 实测形态:横幅行尾小型蓝色文字链(div/span,非 button 语义)。
// 三门控缺一不点:蓝字 + 可点(cursor:pointer 或 button/a 语义)+ 审核上下文。
function looksBlueText(cs) {
var c = parseRGB(cs.color);
if (!c || c.a < 0.6) return false;
return (c.b - c.r) >= BLUE_MARGIN && (c.b - c.g) >= BLUE_MARGIN;
}
function isClickableish(el) {
var tag = el.tagName;
if (tag === 'BUTTON' || tag === 'A' || el.getAttribute('role') === 'button') return true;
var cs = null;
try { cs = window.getComputedStyle(el); } catch (e) { return false; }
return !!(cs && cs.cursor === 'pointer');
}
function isReviewEntry(el) {
var cs = null;
try { cs = window.getComputedStyle(el); } catch (e) { return false; }
if (!cs || !looksBlueText(cs) || isDimmed(cs)) return false;
if (!isClickableish(el)) return false;
return reviewContext(el);
}
// ---------- 同框上下文门控 ----------
// P2:同框有拒绝族按钮,或容器文案含审批语义词。
// P4:祖先链含“需要…审核/批准/获批”类短语(从父级起查,避免入口自身文案自证)。
// 只沿祖先链向上 ≤6 层且跳过 body/html——别处横幅文案不得跨框泄漏,
// 且 <html> 的 textContent 含页面全部内联脚本源码(带着全套审批词),绝不能作为判据。
var RE_REJECT_WORDS = /拒绝|不允许|allow\s*once|reject|deny|never\s*allow|do\s*not\s*allow|don'?t\s*allow/;
var RE_CTX_WORDS = /访问|使用|结账|研究|授权|网络|敏感|权限|批准|审批|审核|access|permission|network|authori[sz]e|checkout|research/i;
var RE_REVIEW_CTX = /(需要|项).{0,12}(审核|批准|获批)/;
// 取容器可见文本:剔除 script/style 源码(否则内联脚本里的审批词会污染门控)
function frameText(container) {
if (!container.querySelector('script, style')) return container.textContent || '';
var clone = container.cloneNode(true);
var bad = clone.querySelectorAll('script, style');
for (var i = 0; i < bad.length; i++) {
if (bad[i].parentNode) bad[i].parentNode.removeChild(bad[i]);
}
return clone.textContent || '';
}
function hasApprovalContext(container) {
if (!container || container === document.body || !container.textContent) return false;
var txt = frameText(container);
if (RE_REJECT_WORDS.test(txt)) return true; // 同框有拒绝族按钮(1.png / 2.png 实测)
return RE_CTX_WORDS.test(txt);
}
function approvalContext(el) {
var node = el;
for (var d = 0; d < 6 && node && node.nodeType === 1 && node !== document.documentElement; d++) {
if (hasApprovalContext(node)) return true;
node = node.parentElement;
}
return false;
}
function reviewContext(el) {
var node = el.parentElement;
for (var d = 0; d < 6 && node && node.nodeType === 1 && node !== document.documentElement; d++) {
if (node !== document.body && RE_REVIEW_CTX.test(frameText(node))) return true;
node = node.parentElement;
}
return false;
}
function classText(el) {
var cn = el.className;
if (cn && typeof cn === 'object' && 'baseVal' in cn) cn = cn.baseVal; // SVGAnimatedString
return cn || '';
}
function highlightSignal(el, baseline) {
// 注意:仅“获得焦点”(:focus) 不算高亮;只有真实视觉信号才算
if (HIGHLIGHT_CLASS_RE.test(classText(el))) return 'class';
var cs = null;
try { cs = window.getComputedStyle(el); } catch (e) { return null; }
if (!cs) return null;
if (looksAccent(cs)) return 'accent-bg';
if (baseline && styleSignature(cs) !== baseline) return 'style-delta';
return null;
}
// ---------- 收集候选:主文档 + 开放 shadow DOM + 同源 iframe ----------
// P4 入口是文字链形态(div/span),按“叶子节点 + 文本精确命中”补采;
// 同一逻辑入口被多条路径收集时,只留最深节点(内层点击会冒泡到外层 handler)。
function collectButtons(root, out) {
if (!root || !root.querySelectorAll) return;
var sel = 'button, [role="button"], input[type="button"], input[type="submit"], [class*="btn"], [class*="button"]';
var nodes = root.querySelectorAll(sel);
for (var i = 0; i < nodes.length; i++) out.push(nodes[i]);
var all = root.querySelectorAll('*');
for (var j = 0; j < all.length; j++) {
var el = all[j];
if (el.shadowRoot) collectButtons(el.shadowRoot, out);
if (el.children.length === 0) {
var t = norm(el.textContent);
if (t === '审核' || t === '批准') out.push(el);
}
}
var frames = root.querySelectorAll('iframe, frame');
for (var k = 0; k < frames.length; k++) {
try {
if (frames[k].contentDocument) collectButtons(frames[k].contentDocument, out);
} catch (e) { /* 跨域 frame,跳过 */ }
}
}
function dedupeNested(list) {
var keep = [];
for (var i = 0; i < list.length; i++) {
if (keep.indexOf(list[i]) !== -1) continue; // 完全重复
var nested = false;
for (var j = 0; j < list.length; j++) {
if (list[j] !== list[i] && list[j].contains && list[j].contains(list[i])) { nested = true; break; }
}
if (!nested) keep.push(list[i]);
}
return keep;
}
function gatherTargets() {
var out = [];
collectButtons(document, out);
return dedupeNested(out.filter(isTarget));
}
// ---------- P5「允许一次」回退的优先级判定 ----------
// 用户规则:「允许一次」只在没有「始终允许」的时候才点。可见 P1 在场 → 硬挡;P2 候选在场 → 礼让。
// 只认可见候选:折叠菜单里的幻影「始终允许」(高度 0)不算“有”,否则回退链被无限挂住(phantom 教训)。
function hasVisibleTier(tier) {
var list = gatherTargets();
for (var i = 0; i < list.length; i++) {
if (targetTier(list[i]) === tier && isVisible(list[i])) return true;
}
return false;
}
function hasVisibleP1() { return hasVisibleTier(1); }
function hasVisibleP2() { return hasVisibleTier(2); }
// ---------- 事件触发(合成事件只用于触发应用的 hover/focus 高亮状态) ----------
function dispatchHover(el) {
var types = ['pointerover', 'mouseover', 'pointermove', 'mousemove'];
for (var i = 0; i < types.length; i++) {
try {
var Ctor = (types[i].indexOf('pointer') === 0 && window.PointerEvent) ? window.PointerEvent : window.MouseEvent;
el.dispatchEvent(new Ctor(types[i], { bubbles: true, cancelable: true, view: window }));
} catch (e) { /* 忽略 */ }
}
}
function fireMouseSequence(el) {
var seq = [
['pointerdown', 'p'], ['mousedown', 'm'],
['pointerup', 'p'], ['mouseup', 'm'],
['click', 'm']
];
for (var i = 0; i < seq.length; i++) {
try {
var Ctor = (seq[i][1] === 'p' && window.PointerEvent) ? window.PointerEvent : window.MouseEvent;
el.dispatchEvent(new Ctor(seq[i][0], { bubbles: true, cancelable: true, view: window }));
} catch (e) { /* 忽略 */ }
}
}
// ---------- 状态与点击 ----------
var nodeState = new WeakMap();
var lastClickAt = 0;
var totalClicks = 0;
function stateOf(el) {
var st = nodeState.get(el);
if (!st) {
st = { attempts: 0, busy: false, clickTimer: null, baseline: '', clicks: 0, awaitingVerify: false, gaveUp: false, p2Chain: false, p5Chain: false, lastClickAt: 0 };
nodeState.set(el, st);
}
return st;
}
function tierLabel(tier) {
if (tier === 1) return '总是允许此站点';
if (tier === 2) return '允许';
if (tier === 5) return '允许一次';
return '审核/批准';
}
function doClick(el, st) {
if (!stillPending(el)) return;
if (st.awaitingVerify) return; // 已发出点击、待校验:禁止第二次
var tier = targetTier(el);
var cap = (tier === 3) ? P4_MAX_CLICKS : MAX_CLICKS;
if (st.clicks >= cap) { // 达到真实点击上限:按已处理收手
st.gaveUp = true;
console.log('[Muse 全自动] 「' + tierLabel(tier) + '」点击已达上限 ' + cap + ' 次仍未生效,按已处理收手');
return;
}
var wait = MIN_CLICK_INTERVAL - (Date.now() - lastClickAt);
if (wait > 0) {
// 点击间隔硬性≥1秒:节流窗口未到就延后
if (!st.clickTimer) {
st.clickTimer = setTimeout(function () { st.clickTimer = null; doClick(el, st); }, wait);
}
return;
}
// 点击瞬间再次确认条件(节流延后期间可能已变):P1 高亮可能消失;P2 蓝底/上下文可能失效;P4 蓝字/上下文可能失效
if (tier === 2 || tier === 5) {
var cs0 = null;
try { cs0 = window.getComputedStyle(el); } catch (e) {}
if (!cs0 || !looksBlue(cs0) || isDimmed(cs0) || !approvalContext(el) || (tier === 5 && hasVisibleP1())) {
console.log('[Muse 全自动] 点击前条件已不满足(蓝底/淡色/审批上下文/始终允许在场),取消本次点击');
setTimeout(function () { attemptClick(el); }, RETRY_DELAY);
return;
}
} else if (tier === 3) {
if (!isReviewEntry(el)) {
console.log('[Muse 全自动] 点击前条件已不满足(蓝字/可点/审核上下文),取消本次点击');
setTimeout(function () { attemptClick(el); }, RETRY_DELAY);
return;
}
} else if (!highlightSignal(el, st.baseline)) {
console.log('[Muse 全自动] 点击前高亮已消失,取消本次点击');
setTimeout(function () { attemptClick(el); }, RETRY_DELAY);
return;
}
st.awaitingVerify = true;
lastClickAt = Date.now();
st.lastClickAt = lastClickAt;
totalClicks += 1;
st.clicks += 1;
try {
if (st.clicks === 1) {
el.click();
} else {
fireMouseSequence(el); // 原生 click() 未生效时补发完整鼠标事件序列
}
console.log('[Muse 全自动] 条件确认后点击「' + tierLabel(tier) + '」(本按钮第 ' + st.clicks + ' 次,累计 ' + totalClicks + ')');
} catch (e) {
console.warn('[Muse 全自动] 点击异常:', e);
}
st.baseline = snapshot(el); // 以点击后状态为新基线,便于下轮判断
// 点完若目标还在(没生效),整轮重新走“门控->点击”;已达点击上限则收手
setTimeout(function () {
st.awaitingVerify = false;
if (stillPending(el) && !st.gaveUp && st.clicks < cap) attemptClick(el);
}, RETRY_DELAY + 200);
}
function attemptClick(el) {
var st = stateOf(el);
if (st.busy || st.gaveUp) return;
if (!stillPending(el)) return;
var tier = targetTier(el);
if (!tier) return;
if (tier === 5 && hasVisibleP1()) {
// 用户规则:可见「始终允许」候选在场,「允许一次」永不点。不计 attempts——
// P1 消失(如菜单里选完)后由扫描重新评估。
if (!st.p5BlockLog) {
st.p5BlockLog = true;
console.log('[Muse 全自动] 检测到可见「始终允许」候选,按规则不点「允许一次」');
}
return;
}
if (st.attempts >= MAX_ATTEMPTS) return;
if (tier === 3) {
// 衔接窗:刚点过「审核/批准」,等蓝色「允许」出现,期间不重重点(否则反复开关对话框)
if (st.clicks > 0 && Date.now() - st.lastClickAt < P4_FOLLOWUP) {
setTimeout(function () { attemptClick(el); }, P4_FOLLOWUP - (Date.now() - st.lastClickAt));
return;
}
if (st.clicks >= P4_MAX_CLICKS) {
st.gaveUp = true;
console.log('[Muse 全自动] 「审核/批准」点击已达上限 ' + P4_MAX_CLICKS + ' 次仍未出现审批弹窗,按已处理收手');
return;
}
}
st.busy = true;
st.attempts += 1;
if (!st.baseline) st.baseline = snapshot(el);
if (tier === 2) {
// P2 蓝色「允许」:只认静态蓝底 + 非淡色 + 审批上下文,不制造高亮
setTimeout(function () {
st.busy = false;
if (!stillPending(el)) return;
var cs = null;
try { cs = window.getComputedStyle(el); } catch (e) {}
if (!cs || !looksBlue(cs) || isDimmed(cs) || !approvalContext(el)) {
console.log('[Muse 全自动] 「允许」未满足点击条件(静态蓝底/非淡色/审批上下文),本次不触发点击(第 ' + st.attempts + ' 轮观察)');
if (st.attempts < MAX_ATTEMPTS) {
setTimeout(function () { attemptClick(el); }, RETRY_DELAY);
}
return;
}
doClick(el, st);
}, HIGHLIGHT_WAIT);
return;
}
if (tier === 5) {
// P5「允许一次」回退:与 P2 同门控(静态蓝底 + 非淡色 + 审批上下文),外加“无始终允许”硬条件
setTimeout(function () {
st.busy = false;
if (!stillPending(el)) return;
if (hasVisibleP1()) return; // 「始终允许」出现(如下拉展开)→让位,不计轮次
var cs = null;
try { cs = window.getComputedStyle(el); } catch (e) {}
if (!cs || !looksBlue(cs) || isDimmed(cs) || !approvalContext(el)) {
console.log('[Muse 全自动] 「允许一次」未满足点击条件(静态蓝底/非淡色/审批上下文),本次不触发点击(第 ' + st.attempts + ' 轮观察)');
if (st.attempts < MAX_ATTEMPTS) {
setTimeout(function () { attemptClick(el); }, RETRY_DELAY);
}
return;
}
doClick(el, st);
}, HIGHLIGHT_WAIT);
return;
}
if (tier === 3) {
// P4 蓝字「审核/批准」:只认蓝字 + 可点 + 审核上下文
setTimeout(function () {
st.busy = false;
if (!stillPending(el)) return;
if (!isReviewEntry(el)) {
console.log('[Muse 全自动] 「审核/批准」未满足点击条件(蓝字/可点/审核上下文),本次不触发点击(第 ' + st.attempts + ' 轮观察)');
if (st.attempts < MAX_ATTEMPTS) {
setTimeout(function () { attemptClick(el); }, RETRY_DELAY);
}
return;
}
doClick(el, st);
}, HIGHLIGHT_WAIT);
return;
}
// P1「总是允许此站点」族:先制造高亮:聚焦 + 合成 hover(触发应用自身的高亮状态)
try { el.focus({ preventScroll: true }); } catch (e) { try { el.focus(); } catch (e2) {} }
dispatchHover(el);
setTimeout(function () {
st.busy = false;
if (!stillPending(el)) return;
var sig = highlightSignal(el, st.baseline);
if (!sig) {
// 严格门控:未高亮绝不触发点击
console.log('[Muse 全自动] 「' + tierLabel(tier) + '」未处于高亮态,本次不触发点击(第 ' + st.attempts + ' 轮观察)');
if (st.attempts < MAX_ATTEMPTS) {
setTimeout(function () { attemptClick(el); }, RETRY_DELAY);
}
return;
}
doClick(el, st);
}, HIGHLIGHT_WAIT);
}
// ---------- P1 礼让 ----------
// 同一轮扫描里存在 P1 候选时,P2 推迟出手,让「总是允许」的高亮点击链先完成第一拍(永久授权优先)。
// 礼让期间 P1 判废/消失/达上限,或重排超过 P2_DEFER_MAX,才降级点 P2。
function deferP2(el, round) {
if (!stillPending(el)) return;
if (round < P2_DEFER_MAX && gatherTargets().some(isAutoTarget)) {
setTimeout(function () { deferP2(el, round + 1); }, P2_DEFER);
return;
}
attemptClick(el);
}
// P5 礼让:P2 候选在场时推迟出手(普通「允许」优先),超时后 P2 仍点不动才降级点「允许一次」。
// 注意 P1 在场不是礼让而是硬挡(见 attemptClick/scan):用户规则“有始终允许就不点允许一次”。
function deferAllowOnce(el, round) {
if (!stillPending(el)) return;
if (round < P2_DEFER_MAX && hasVisibleP2()) {
setTimeout(function () { deferAllowOnce(el, round + 1); }, P2_DEFER);
return;
}
attemptClick(el);
}
// ---------- 主扫描:出现即处理,后台持续 ----------
function scan() {
var targets = gatherTargets();
var p1 = [], p2 = [], p3 = [], p5 = [];
for (var i = 0; i < targets.length; i++) {
var t = targetTier(targets[i]);
if (t === 1) p1.push(targets[i]);
else if (t === 2) p2.push(targets[i]);
else if (t === 3) p3.push(targets[i]);
else if (t === 5) p5.push(targets[i]);
}
for (var a = 0; a < p1.length; a++) attemptClick(p1[a]);
for (var b = 0; b < p2.length; b++) {
if (p1.length) {
var st = stateOf(p2[b]);
if (st.p2Chain) continue; // 礼让链已存在,不重复排
st.p2Chain = true;
deferP2(p2[b], 0);
} else {
attemptClick(p2[b]);
}
}
// P5「允许一次」回退:可见 P1 在场 → 硬挡(用户规则:有「始终允许」不点「允许一次」);
// P2 候选在场 → 礼让后降级;两者皆无才直接点。每轮扫描重新评估,P1 消失即放行。
var p1Visible = hasVisibleP1();
for (var d = 0; d < p5.length; d++) {
if (p1Visible) continue;
if (hasVisibleP2()) {
var st5 = stateOf(p5[d]);
if (st5.p5Chain) continue; // 礼让链已存在,不重复排
st5.p5Chain = true;
deferAllowOnce(p5[d], 0);
} else {
attemptClick(p5[d]);
}
}
// P4 只在“审批界面还没打开”时出手:无 P1 候选,且没有处于审批上下文中的蓝色「允许」/「允许一次」。
// 注意不能用 p2.length 判断——过不了上下文门控的裸蓝允许是候选但界面并未打开,P4 仍要出手。
var surfaceOpen = false;
for (var e = 0; e < p2.length; e++) {
if (p2SurfaceOpen(p2[e])) { surfaceOpen = true; break; }
}
if (!surfaceOpen) {
for (var f = 0; f < p5.length; f++) {
if (p2SurfaceOpen(p5[f])) { surfaceOpen = true; break; }
}
}
if (!p1.length && !surfaceOpen) {
for (var c = 0; c < p3.length; c++) attemptClick(p3[c]);
}
}
var timer = null;
function scanSoon() {
if (timer) return;
timer = setTimeout(function () { timer = null; scan(); }, 200);
}
try {
new MutationObserver(scanSoon).observe(document.documentElement, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['disabled', 'class', 'style']
});
} catch (e) { /* 忽略 */ }
setInterval(scan, 1500); // 主线程兜底扫描
// 后台标签页定时器会被 Chrome 降频(隐藏>5分钟后链式 timer 约1次/分钟),
// 用 Worker 心跳补上;CSP 禁止 blob worker 时静默降级为主线程 setInterval。
try {
var blob = new Blob(['setInterval(function(){postMessage(1);},1000);'], { type: 'application/javascript' });
var worker = new Worker(URL.createObjectURL(blob));
worker.onmessage = scanSoon;
} catch (e) { /* 忽略 */ }
scan();
console.log('[Muse 全自动·高亮门控] 已启动:①总是允许/始终允许族(高亮才点)②蓝色实底「允许」(蓝底+审批上下文,存在①时礼让)③横幅蓝字「审核/批准」(点完等②接住)④「允许一次」回退(无可见①且无②候选才点);间隔≥1秒,单目标点击上限 允许2/审核4;绝不点「拒绝」族。');
})();