// ==UserScript== // @name 自動點擊生成 (Grok Imagine) v1.4 // @namespace http://tampermonkey.net/ // @version 1.4 // @description 自動生成影片,閾值警示、音量調整、0%重試、額度用完提醒,支援背景執行(修正額度警告重複觸發問題)。 // @match https://grok.com/* // @grant none // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; const targetClassString = 'text-xs font-semibold w-[4ch] mb-[1px]'; const selector = `div[class="${targetClassString}"]`; let lastValue = null; let wasPresent = false; let autoMode = true; let threshold = 30; let playBeepOnLow = true; let playBeepOnLimit = true; let beepVolume = 0.005; let limitAlertShown = false; // ✅ 額度提醒觸發狀態 let zeroCount = 0; const zeroThreshold = 20; const checkInterval = 500; const zeroMaxCount = zeroThreshold * 1000 / checkInterval; function getTimeString() { const now = new Date(); const pad = n => n.toString().padStart(2, '0'); return `[${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}]`; } function parseNumber(text) { if (!text) return null; const match = text.match(/-?\d+(\.\d+)?/); return match ? parseFloat(match[0]) : null; } function beepTriple(frequency = 880, duration = 0.1, volume = beepVolume) { const ctx = new (window.AudioContext || window.webkitAudioContext)(); const playBeep = () => { const oscillator = ctx.createOscillator(); const gain = ctx.createGain(); oscillator.connect(gain); gain.connect(ctx.destination); oscillator.type = 'square'; oscillator.frequency.value = frequency; gain.gain.value = volume; oscillator.start(); oscillator.stop(ctx.currentTime + duration); }; playBeep(); setTimeout(playBeep, duration * 1000 + 100); setTimeout(playBeep, 2 * (duration * 1000 + 100)); } function createControlPanel() { const panel = document.createElement('div'); panel.style.position = 'fixed'; panel.style.top = '80px'; panel.style.right = '10px'; panel.style.zIndex = '99999'; panel.style.background = 'rgba(30,30,30,0.9)'; panel.style.color = '#fff'; panel.style.padding = '10px 15px'; panel.style.borderRadius = '10px'; panel.style.fontSize = '14px'; panel.style.fontFamily = 'monospace'; panel.style.boxShadow = '0 4px 12px rgba(0,0,0,0.6)'; panel.style.backdropFilter = 'blur(5px)'; panel.style.width = '320px'; panel.style.maxHeight = '480px'; panel.style.display = 'flex'; panel.style.flexDirection = 'column'; panel.style.pointerEvents = 'auto'; const controlsHTML = `
Grok 檢查控制
`; const consoleBox = document.createElement('div'); consoleBox.id = 'grok-console'; consoleBox.style.flex = '1'; consoleBox.style.background = 'rgba(0,0,0,0.3)'; consoleBox.style.padding = '6px'; consoleBox.style.borderRadius = '6px'; consoleBox.style.overflowY = 'auto'; consoleBox.style.fontSize = '12px'; consoleBox.style.lineHeight = '1.4'; consoleBox.style.whiteSpace = 'pre-wrap'; const clearBtn = document.createElement('button'); clearBtn.textContent = '🧹 清空紀錄'; clearBtn.style.marginTop = '6px'; clearBtn.style.background = 'rgba(255,255,255,0.1)'; clearBtn.style.border = 'none'; clearBtn.style.color = '#ccc'; clearBtn.style.padding = '4px 8px'; clearBtn.style.borderRadius = '4px'; clearBtn.style.cursor = 'pointer'; clearBtn.style.fontSize = '12px'; clearBtn.addEventListener('mouseenter', () => clearBtn.style.color = '#fff'); clearBtn.addEventListener('mouseleave', () => clearBtn.style.color = '#ccc'); clearBtn.addEventListener('click', () => (consoleBox.innerHTML = '')); panel.innerHTML = controlsHTML; panel.appendChild(consoleBox); panel.appendChild(clearBtn); document.body.appendChild(panel); const autoModeToggle = panel.querySelector('#autoModeToggle'); const thresholdInput = panel.querySelector('#thresholdInput'); const beepToggle = panel.querySelector('#beepToggle'); const limitToggle = panel.querySelector('#limitToggle'); const volumeSlider = panel.querySelector('#volumeSlider'); const volumeDisplay = panel.querySelector('#volumeDisplay'); autoModeToggle.addEventListener('change', () => { autoMode = autoModeToggle.checked; console.log(`${getTimeString()} 自動模式: ${autoMode ? '啟用' : '停用'}`); }); thresholdInput.addEventListener('change', () => { threshold = parseFloat(thresholdInput.value); console.log(`${getTimeString()} 閥值更新為 ${threshold}`); }); beepToggle.addEventListener('change', () => { playBeepOnLow = beepToggle.checked; console.log(`${getTimeString()} 低於閾值播放音效: ${playBeepOnLow ? '啟用' : '停用'}`); }); limitToggle.addEventListener('change', () => { playBeepOnLimit = limitToggle.checked; console.log(`${getTimeString()} 額度用完提醒音效: ${playBeepOnLimit ? '啟用' : '停用'}`); }); volumeSlider.addEventListener('input', () => { beepVolume = parseFloat(volumeSlider.value); volumeDisplay.textContent = beepVolume.toFixed(3); }); return consoleBox; } function hookConsole(consoleBox) { const originalLog = console.log; console.log = (...args) => { originalLog.apply(console, args); const msg = args.join(' '); const entry = document.createElement('div'); if (msg.includes('成功')) entry.style.color = '#6eff9f'; else if (msg.includes('失敗')) entry.style.color = '#ff7b7b'; else if (msg.includes('閥值') || msg.includes('模式') || msg.includes('額度') || msg.includes('分頁')) entry.style.color = '#ffd966'; else entry.style.color = '#ccc'; entry.textContent = msg; consoleBox.appendChild(entry); consoleBox.scrollTop = consoleBox.scrollHeight; }; } function check() { if (!autoMode) return; // ✅ 額度用完只提示一次,直到狀態改變 const upgradeElem = document.querySelector('span.text-secondary.font-medium'); if (upgradeElem && upgradeElem.textContent.includes('Upgrade to unlock more')) { if (!limitAlertShown) { limitAlertShown = true; console.log(`${getTimeString()} 額度已用完!`); if (playBeepOnLimit) beepTriple(440, 0.15); } } else { limitAlertShown = false; } const elem = document.querySelector(selector); if (elem) { wasPresent = true; const val = parseNumber(elem.textContent.trim()); if (!isNaN(val)) lastValue = val; if (val === 0) { zeroCount++; if (zeroCount >= zeroMaxCount) { const button = document.querySelector('button[aria-label="製作影片"]'); if (button) { button.click(); console.log(`${getTimeString()} 進度長時間為0,已再次點擊生成按鈕`); } else { console.log(`${getTimeString()} 找不到生成按鈕,無法重點擊`); } zeroCount = 0; } } else zeroCount = 0; } else if (wasPresent) { wasPresent = false; const progress = lastValue !== null ? `${lastValue}%` : "未知"; const container = document.querySelector('div.relative.mx-auto.rounded-2xl.overflow-hidden'); let success = false; if (container) { const grid = container.querySelector('div.grid'); if (grid && grid.querySelector('video#sd-video')) { console.log(`${getTimeString()} 生成成功 (進度:${progress})`); success = true; } } if (!success) { if (lastValue !== null && lastValue >= threshold) { console.log(`${getTimeString()} 生成失敗 (進度:${progress})`); const button = document.querySelector('button[aria-label="製作影片"]'); if (button) { const section = document.querySelector('section[aria-label="Notifications alt+T"]'); let attempts = 0; const maxAttempts = 10; const intervalId = setInterval(() => { const exists = section && section.querySelector('span')?.textContent.trim() === "Content Moderated. Try a different idea."; attempts++; if (exists) { button.click(); console.log(`${getTimeString()} 已點擊製作影片按鈕`); clearInterval(intervalId); } else if (attempts >= maxAttempts) { console.log(`${getTimeString()} 失敗訊息超時仍未出現`); clearInterval(intervalId); button.click(); } }, 500); } else { console.log(`${getTimeString()} 找不到製作影片按鈕`); } } else { console.log(`${getTimeString()} 生成失敗且低於閾值 (進度:${progress})`); if (playBeepOnLow) beepTriple(); } } lastValue = null; } } const consoleBox = createControlPanel(); hookConsole(consoleBox); // ✅ Web Worker 背景檢查 function startBackgroundChecker() { const workerCode = ` let interval = ${checkInterval}; setInterval(() => postMessage('tick'), interval); `; const blob = new Blob([workerCode], { type: 'application/javascript' }); const worker = new Worker(URL.createObjectURL(blob)); worker.onmessage = () => check(); } startBackgroundChecker(); document.addEventListener('visibilitychange', () => { if (!document.hidden) check(); }); })();