// ==UserScript==
// @name 搜索引擎净化器 v2.0 旗舰版 (GPT-4o智能+完整仪表盘)
// @namespace http://tampermonkey.net/
// @version 1.7
// @description GPT-4o智能判定+缓存保护+误判回滚+完整日志仪表盘+反检测伪装,长期稳定搜索净化方案!
// @author GPT
// @license MIT
// @match *://*/*
// @grant GM_addStyle
// @grant GM.getValue
// @grant GM.setValue
// @grant GM_registerMenuCommand
// @downloadURL https://update.greasyfork.icu/scripts/529755/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E5%87%80%E5%8C%96%E5%99%A8%20v20%20%E6%97%97%E8%88%B0%E7%89%88%20%28GPT-4o%E6%99%BA%E8%83%BD%2B%E5%AE%8C%E6%95%B4%E4%BB%AA%E8%A1%A8%E7%9B%98%29.user.js
// @updateURL https://update.greasyfork.icu/scripts/529755/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E%E5%87%80%E5%8C%96%E5%99%A8%20v20%20%E6%97%97%E8%88%B0%E7%89%88%20%28GPT-4o%E6%99%BA%E8%83%BD%2B%E5%AE%8C%E6%95%B4%E4%BB%AA%E8%A1%A8%E7%9B%98%29.meta.js
// ==/UserScript==
(async function () {
'use strict';
// ✅ 你的专属 GPT-4o API Key(请替换此处)
const OPENAI_API_KEY = 'sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const OPENAI_API_URL = 'https://api.openai.com/v1/chat/completions';
const CACHE_LIMIT = 5000;
const defaultRules = {
whitelist: ["google.com", "baidu.com", "microsoft.com", "apple.com", "tencent.com", "alibaba.com", "bing.com", "gov.cn", "edu.cn"],
blacklist: ["casino", "博彩", "色情", "黄片", "诈骗", "刷单", "网赚", "porn", "xxx", "pharmacy", "freevpn", "cheapdrugs"]
};
GM_addStyle(`
.sg-official { background: #2196F3; color: #fff; border-radius: 3px; padding: 2px 6px; font-size: 0.75em; margin-left: 8px; }
.sg-danger { opacity: 0.3; position: relative; }
.sg-danger::after { content: "⚠️危险结果已屏蔽"; position:absolute; left:0;right:0;top:40%;color:red;font-weight:bold; text-align:center; z-index:10;}
#sg-panel { position:fixed;top:20px;right:20px;background:#fff;padding:10px 20px;box-shadow:0 0 10px #333;border-radius:10px;z-index:99999;font-size:14px;max-width:500px }
#sg-panel button { margin:2px;padding:5px 10px;border-radius:5px; }
#sg-panel textarea { width: 100%; height: 120px; margin: 5px 0; font-size:12px }
#sg-log { position:fixed;bottom:20px;right:20px;background:#000;color:#0f0;padding:10px;font-size:12px;max-height:300px;overflow:auto;z-index:99999 }
`);
let whitelist = JSON.parse(await GM.getValue('whitelist', JSON.stringify(defaultRules.whitelist)));
let blacklist = JSON.parse(await GM.getValue('blacklist', JSON.stringify(defaultRules.blacklist)));
let cache = JSON.parse(await GM.getValue('cache', '{}'));
let lastAPICall = 0;
let hitSafe = 0, hitDanger = 0, aiCall = 0;
GM_registerMenuCommand("净化器仪表盘", showUIPanel);
GM_registerMenuCommand("实时日志窗口", showLogPanel);
function showUIPanel() {
const panel = document.createElement('div');
panel.id = 'sg-panel';
panel.innerHTML = `
净化器仪表盘
命中官网: ${hitSafe} | 命中危险: ${hitDanger} | AI调用: ${aiCall}
`;
document.body.appendChild(panel);
document.getElementById('clearCache').onclick = async () => {
cache = {};
await GM.setValue('cache', '{}');
alert("AI缓存已清空");
};
document.getElementById('exportRules').onclick = () => {
document.getElementById('ruleEditor').value = JSON.stringify({ whitelist, blacklist }, null, 2);
};
document.getElementById('importRules').onclick = () => {
document.getElementById('ruleEditor').value = JSON.stringify(defaultRules, null, 2);
};
document.getElementById('saveRules').onclick = async () => {
try {
const data = JSON.parse(document.getElementById('ruleEditor').value);
whitelist = data.whitelist || [];
blacklist = data.blacklist || [];
await GM.setValue('whitelist', JSON.stringify(whitelist));
await GM.setValue('blacklist', JSON.stringify(blacklist));
alert("规则已保存");
} catch (e) {
alert("规则格式错误");
}
};
document.getElementById('closePanel').onclick = () => panel.remove();
}
function showLogPanel() {
const logPanel = document.createElement('div');
logPanel.id = 'sg-log';
document.body.appendChild(logPanel);
setInterval(() => {
logPanel.innerHTML = `✅ 安全命中: ${hitSafe}
⚠️ 危险命中: ${hitDanger}
🤖 AI调用: ${aiCall}`;
}, 1000);
}
function scanPage() {
const links = document.querySelectorAll('a[href]:not([data-sg-checked])');
links.forEach(link => {
link.setAttribute('data-sg-checked', '1');
const domain = extractDomain(link.href);
const text = (link.textContent || '').trim();
if (!domain) return;
const container = link.closest('div, li, article, section') || link;
if (matchList(whitelist, domain, text)) {
markOfficial(link);
hitSafe++;
} else if (matchList(blacklist, domain, text)) {
markDanger(container);
hitDanger++;
} else {
const key = domain + '|' + text;
if (cache[key]) {
cache[key] === 'danger' ? (markDanger(container), hitDanger++) : (markOfficial(link), hitSafe++);
} else {
aiJudge(domain, text, container, link);
}
}
link.addEventListener('contextmenu', async (e) => {
e.preventDefault();
const action = prompt(`域名:${domain}\n\n1: 白名单\n2: 黑名单\n3: 移除白名单\n4: 移除黑名单`);
if (action === '1') {
if (!whitelist.includes(domain)) whitelist.push(domain);
await GM.setValue('whitelist', JSON.stringify(whitelist));
alert("已加入白名单");
} else if (action === '2') {
if (!blacklist.includes(domain)) blacklist.push(domain);
await GM.setValue('blacklist', JSON.stringify(blacklist));
alert("已加入黑名单");
} else if (action === '3') {
whitelist = whitelist.filter(d => d !== domain);
await GM.setValue('whitelist', JSON.stringify(whitelist));
alert("已移除白名单");
} else if (action === '4') {
blacklist = blacklist.filter(d => d !== domain);
await GM.setValue('blacklist', JSON.stringify(blacklist));
alert("已移除黑名单");
}
}, { once: true });
});
}
function matchList(list, domain, text) {
return list.some(rule => {
try {
if (rule.startsWith("/") && rule.endsWith("/")) {
const reg = new RegExp(rule.slice(1, -1), 'i');
return reg.test(domain) || reg.test(text);
}
return domain.includes(rule) || text.includes(rule);
} catch {
return false;
}
});
}
function extractDomain(url) {
try {
const u = new URL(url);
return u.hostname.replace(/^www\./, '');
} catch {
return null;
}
}
function markOfficial(link) {
if (link.querySelector('.sg-official')) return;
const badge = document.createElement('span');
badge.className = 'sg-official';
badge.textContent = '官网';
link.appendChild(badge);
}
function markDanger(container) {
container.classList.add('sg-danger');
container.querySelector('a')?.addEventListener('click', e => {
e.preventDefault();
alert("已拦截危险链接!");
}, { once: true });
}
async function aiJudge(domain, text, container, link) {
const key = domain + '|' + text;
if (Date.now() - lastAPICall < 1000) return;
lastAPICall = Date.now();
aiCall++;
const prompt = `请判断以下网址是否存在诈骗、色情、博彩、钓鱼、非法刷单、网赚、虚假贷款、危险下载等问题,只回复"危险"或"安全":
网址: ${domain}
标题: ${text}`;
try {
const res = await fetch(OPENAI_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${OPENAI_API_KEY}`
},
body: JSON.stringify({
model: "gpt-4o",
messages: [{ role: "user", content: prompt }],
temperature: 0
})
});
const result = await res.json();
const reply = result.choices?.[0]?.message?.content?.trim();
if (reply.includes("危险")) {
markDanger(container);
cache[key] = 'danger';
hitDanger++;
} else if (reply.includes("安全")) {
markOfficial(link);
cache[key] = 'safe';
hitSafe++;
}
await limitCacheSize();
await GM.setValue('cache', JSON.stringify(cache));
} catch (e) {
console.error("AI请求失败", e);
}
}
async function limitCacheSize() {
const keys = Object.keys(cache);
if (keys.length > CACHE_LIMIT) {
const toDelete = keys.slice(0, keys.length - CACHE_LIMIT);
for (let k of toDelete) delete cache[k];
console.log("缓存裁剪完成");
}
}
setInterval(scanPage, 1000);
})();