From c0e7af54717e9df9e75bdee5194fb59b728c663e Mon Sep 17 00:00:00 2001 From: chinosk Date: Sat, 2 May 2026 14:28:41 +0800 Subject: [PATCH] 111 --- metamogu.js | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 metamogu.js diff --git a/metamogu.js b/metamogu.js new file mode 100644 index 0000000..b6e9d58 --- /dev/null +++ b/metamogu.js @@ -0,0 +1,124 @@ +// ==UserScript== +// @name Metamogu 补货自动检测 (Fetch 终极版) +// @namespace http://tampermonkey.net/ +// @version 3.0 +// @description 使用原生 Fetch 突破拦截,响应非 500 时直接替换页面或重定向,避免重复访问消耗兑换码。 +// @author Gemini +// @match https://metamogu.sa-vrc-media.com/redeem-code/redirect* +// @grant GM_notification +// @run-at document-idle +// ==/UserScript== + +(function() { + 'use strict'; + + let checkCount = 0; + let countdownTimer = null; + + // 1. 创建右下角浮窗 UI + const ui = document.createElement('div'); + ui.style.cssText = ` + position: fixed; + bottom: 20px; + right: 20px; + padding: 15px 20px; + background-color: rgba(0, 0, 0, 0.75); + color: #00FF00; + font-family: 'Microsoft YaHei', sans-serif; + font-size: 14px; + border-radius: 8px; + z-index: 2147483647; + box-shadow: 0 4px 10px rgba(0,0,0,0.3); + pointer-events: none; + backdrop-filter: blur(4px); + line-height: 1.6; + transition: all 0.3s ease; + `; + if (document.body) { + document.body.appendChild(ui); + } else { + document.documentElement.appendChild(ui); + } + + // 更新浮窗内容 + function updateUI(text, color = "#00FF00") { + ui.style.color = color; + ui.innerHTML = text; + } + + // 2. 核心检测逻辑 (原生 async/await fetch) + async function doCheck() { + checkCount++; + updateUI(`🔄 第 ${checkCount} 次检测中...`, "#FFD700"); + + try { + // 使用原生 fetch,完美伪装成正常的页面加载请求 + const response = await fetch(window.location.href, { + method: "GET", + cache: "no-store", // 强制不缓存,确保获取最新状态 + headers: { + // 模拟常见的浏览器请求头,避免被 WAF 拦截 + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" + } + }); + + const status = response.status; + // 如果发生了 301/302 重定向,fetch 默认会跟随,response.redirected 会变为 true + const finalUrl = response.url; + const isRedirected = response.redirected; + + if (status === 500) { + // 缺货状态:随机 5~30 秒倒计时 + const delaySec = Math.floor(Math.random() * (30 - 5 + 1)) + 5; + let currentSec = delaySec; + + updateUI(`❌ 状态: 缺货中 (500)
⏱️ 倒计时: ${currentSec} 秒后检测
📊 累计检测: ${checkCount} 次`, "#FF4500"); + document.title = `[等待 ${currentSec}s] 监控中...`; + + countdownTimer = setInterval(() => { + currentSec--; + if (currentSec <= 0) { + clearInterval(countdownTimer); + doCheck(); + } else { + updateUI(`❌ 状态: 缺货中 (500)
⏱️ 倒计时: ${currentSec} 秒后检测
📊 累计检测: ${checkCount} 次`, "#FF4500"); + document.title = `[等待 ${currentSec}s] 监控中...`; + } + }, 1000); + + } else { + // 已补货!状态不再是 500 + updateUI(`✅ 状态: ${status}
🎉 已补货,正在处理...
📊 累计检测: ${checkCount} 次`, "#00FF00"); + document.title = `[已补货!] 状态 ${status}`; + + GM_notification({ + title: "🌟 Metamogu 补货啦!", + text: `检测到状态变化,已为您渲染最新页面!`, + timeout: 10000, + highlight: true, + onclick: () => window.focus() + }); + + // 处理 302 重定向或 200 成功 + if (isRedirected || finalUrl !== window.location.href) { + console.log("检测到重定向,正在跳转至:", finalUrl); + window.location.replace(finalUrl); // 使用 replace 避免产生多余的历史记录 + } else { + console.log("状态 200,正在替换页面 DOM..."); + const htmlText = await response.text(); + document.open(); + document.write(htmlText); + document.close(); + } + } + } catch (error) { + // 请求出错处理 (例如断网或跨域异常) + console.error("Fetch 请求出错:", error); + updateUI(`⚠️ 网络请求异常
⏱️ 10秒后重试...
📊 累计检测: ${checkCount} 次`, "#FF6347"); + setTimeout(doCheck, 10000); + } + } + + // 启动检测 + doCheck(); +})(); \ No newline at end of file