// ==UserScript==
// @name NGA Watcher
// @namespace https://gf.qytechs.cn/users/263018
// @version 1.0.0
// @author snyssss
// @description wkq yyds
// @match *bbs.nga.cn/*
// @match *ngabbs.com/*
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addValueChangeListener
// @grant GM_registerMenuCommand
// @noframes
// ==/UserScript==
((ui) => {
"use strict";
if (ui === undefined) return;
// KEY
const KEY_filterUser = "KEY_filterUser";
const KEY_filterKeyword = "KEY_filterKeyword";
const KEY_filterInterval = "KEY_filterInterval";
const KEY_lastTime = "KEY_lastTime";
const KEY_data = "KEY_data";
// 用户
const filterUser = GM_getValue(KEY_filterUser) || "";
// 关键词
const filterKeyword = GM_getValue(KEY_filterKeyword) || "";
// 监视间隔
const filterInterval = parseInt(GM_getValue(KEY_filterInterval), 10) || 600;
// 上次更新时间
const lastTime = parseInt(GM_getValue(KEY_lastTime), 10) || 0;
// 获取当前时间
const currentTime = parseInt(new Date() / 1000, 10);
// 是否匹配
const isMatch = function (text) {
if (filterKeyword) {
return text.search(filterKeyword) >= 0;
}
return true;
};
// 请求数据
const fetchData = async (uid) => {
if (!uid) {
return;
}
// 请求发帖记录
const ts = await new Promise((resolve) => {
fetch(`/thread.php?authorid=${uid}&lite=js`)
.then((res) => res.blob())
.then((blob) => {
const reader = new FileReader();
reader.onload = () => {
const text = reader.result;
const data = JSON.parse(
text.replace("window.script_muti_get_var_store=", "")
);
resolve(
Object.values(data.data.__T || {})
.filter(
(item) => item.postdate > lastTime && isMatch(item.subject)
)
.map((item) => ({
0: 5,
1: item.authorid,
2: item.author,
5: item.subject,
6: item.tid,
9: item.postdate,
10: 1,
}))
);
};
reader.readAsText(blob, "GBK");
})
.catch(() => {
resolve([]);
});
});
// 请求回帖记录
const rs = await new Promise((resolve) => {
fetch(`/thread.php?authorid=${uid}&searchpost=1&lite=js`)
.then((res) => res.blob())
.then((blob) => {
const reader = new FileReader();
reader.onload = () => {
const text = reader.result;
const data = JSON.parse(
text.replace("window.script_muti_get_var_store=", "")
);
resolve(
Object.values(data.data.__T || {})
.filter(
(item) =>
item.__P.postdate > lastTime && isMatch(item.__P.content)
)
.map((item) => ({
0: 6,
5: item.subject,
6: item.__P.tid,
7: item.__P.pid,
9: item.__P.postdate,
10: 1,
}))
);
};
reader.readAsText(blob, "GBK");
})
.catch(() => {
resolve([]);
});
});
// 获取用户信息
if (ts.length) {
for (let i in rs) {
rs[i] = {
...rs[i],
1: ts[0][1],
2: ts[0][2],
};
}
} else {
const username = await new Promise((resolve) => {
fetch(`nuke.php?__lib=ucp&__act=get&uid=${uid}&lite=js`)
.then((res) => res.blob())
.then((blob) => {
const reader = new FileReader();
reader.onload = () => {
const text = reader.result;
const data = JSON.parse(
text.replace("window.script_muti_get_var_store=", "")
);
resolve(data.data[0].username);
};
reader.readAsText(blob, "GBK");
})
.catch(() => {
resolve();
});
});
if (username === undefined) {
return [];
}
for (let i in rs) {
rs[i] = {
...rs[i],
1: uid,
2: username,
};
}
}
return [...ts, ...rs];
};
// 执行检测
const execute = async () => {
if (filterInterval + lastTime > currentTime) {
return;
}
const data = (
await Promise.all(
filterUser.split("|").map(async (uid) => await fetchData(uid))
)
)
.flat()
.sort((a, b) => a[9] - b[9]);
GM_setValue(KEY_lastTime, currentTime);
GM_setValue(KEY_data, data);
};
// 监听结果
GM_addValueChangeListener(KEY_data, function (_, prev, next) {
if (next && next.length) {
ui.loadNotiScript(function () {
// 修复 NGA 脚本错误
TPL[KEY["_BIT_SYS"]][KEY["_TYPE_KEYWORD_WATCH_REPLY"]] = function (x) {
return x[KEY["_ABOUT_ID_4"]]
? "{_U} 在{_T1} {_R2} 中的 {_R5} 触发了关键词监视<br/>"
: "{_U} 在主题 {_T} 中的 {_R5} 触发了关键词监视<br/>";
};
// 推送消息
for (let i in next) {
ui.notification._add(1, next[i], 1);
}
// 打开窗口
ui.notification.openBox();
});
}
});
GM_registerMenuCommand("设置监视用户ID", () => {
const result = window.prompt(`多个用户ID用"|"隔开`, filterUser);
if (result === null || result === filterUser) {
return;
}
GM_setValue(KEY_filterUser, result);
GM_setValue(KEY_lastTime, 0);
GM_setValue(KEY_data, []);
location.reload();
});
GM_registerMenuCommand("设置监视规则", () => {
const result = window.prompt(`正则表达式`, filterKeyword);
if (result === null || result === filterKeyword) {
return;
}
GM_setValue(KEY_filterKeyword, result);
GM_setValue(KEY_lastTime, 0);
GM_setValue(KEY_data, []);
location.reload();
});
GM_registerMenuCommand("设置监视间隔", () => {
const result = window.prompt(`单位:秒`, filterInterval);
if (result === null || result === filterInterval) {
return;
}
GM_setValue(KEY_filterInterval, parseInt(result, 10) || 600);
location.reload();
});
GM_registerMenuCommand("重置监视时间", () => {
GM_setValue(KEY_lastTime, 0);
GM_setValue(KEY_data, []);
location.reload();
});
execute();
})(commonui);