// ==UserScript==
// @name MCBBS - Get New Post
// @name:zh MCBBS获取最新帖子
// @version 0.3.4.2
// @match https://www.mcbbs.net/*
// @author axototl (orignal by xmdhs)
// @license LGPLv3
// @description 获取版块最新帖子。
// @namespace io.github.msbbc
// @run-at document-body
// ==/UserScript==
var debug = false;
var patt = /^var\s+newthread.*?$/m; // 用于匹配JS代码开头
var numpatt = />([\d\-]+)<\/a>/; // 用于匹配帖子数
var titler = />([^<]+)<\/a>$/; // 用于匹配标题
function dbgopt(txt) {
if (debug) console.debug(txt);
}
function parse_result(txt) {
var matches = txt.match(patt);
var result = null;
if (matches && matches.length > 0) {
dbgopt(txt);
var table = null;
var removetbodyrow = function(_,__) {
result = newthread;
};
eval(matches[0]);
}
if (debug) dbgopt(txt);
if (!result) return null;
for (let item of result) {
item.thread.common.val = titler.exec(item.thread.common.val)[1];
}
return result;
}
(async () => {
await unsafeWindow.MExt;
let MExt = unsafeWindow.MExt;
let $ = MExt.jQuery;
Notification.requestPermission();
console.log( "Notify permission:" + Notification.permission);
const stime = 5000;
const getnewpost = {
"runcase": () => { return MExt.ValueStorage.get("getnewpost").length > 0 },
"core": () => {
debug = MExt.ValueStorage.get("debug");
var fidstemp = MExt.ValueStorage.get("getnewpost");
var fids = fidstemp.split(",");
if (!MExt.ValueStorage.get("exposter")) {
var id = Math.round(new Date().getTime() / 1000);
var tempid = localStorage.getItem("getnewpost");
if (tempid == null) {
localStorage.setItem("getnewpost", id);
tempid = id;
for (let index = 0; index < fids.length; index++) {
getposts(fids[index]);
}
} else {
var getifcan = setInterval(function () {
var atime = localStorage.getItem("getnewpost");
var btime = Math.round(new Date().getTime() / 1000);
if (btime - atime > 20) {
localStorage.setItem("getnewpost", btime)
for (let index = 0; index < fids.length; index++) {
getposts(fids[index]);
clearInterval(getifcan);
}
}
}, stime * 2)
}
} else {
// 实验中的代码
dbgopt("[Experimental] Loaded!");
let backtime = MExt.ValueStorage.get("backtime") * 1000;
let fids = MExt.ValueStorage.get("getnewpost").split(",");
function getpost_v2() {
dbgopt("[Experimental] New getpost function worked!");
for (let fid of fids)
fetch("https://www.mcbbs.net/forum.php?mod=ajax&action=forumchecknew&fid=" +
fid + "&time=" + (Math.round(new Date().getTime() / 1000) - Math.round(Math.random()*100)%50 - 25) +
"&uncheck=2&inajax=yes&inajax=1&ajaxtarget=forumnew").then(res => res.text().then(txt => {
var result = parse_result(txt);
if (result) {
var records = {};
let tmp = localStorage.getItem("newpostrecord-" + fid);
if (tmp) records = JSON.parse(tmp);
result = result.filter(item => {
let rn = numpatt.exec(item.thread.num.val) | 0;
if (!records.hasOwnProperty(item.tid) || records[item.tid] > rn) {
records[item.tid]=rn;
return true;
}
return false;
});
if (MExt.ValueStorage.get("onlyfresh")) {
result = result.filter(item => {
let rr = numpatt.exec(item.thread.num.val) | 0;
return rr && rr[1] <= 0;
});
}
tmp = JSON.stringify(records);
localStorage.setItem("newpostrecord-" + fid, tmp);
for (let item of result) push(item.tid, item.thread.common.val);
}
}));
setTimeout(getpost_v2, backtime);
}
getpost_v2();
}
function getposts(fid) {
setInterval(function () {
let time = Math.round(new Date().getTime() / 1000);
localStorage.setItem("getnewpost", time);
fetch("https://www.mcbbs.net/forum.php?mod=ajax&action=forumchecknew&fid=" +
fid + "&time=" + (time - Math.round(Math.random()*100)) +
"&uncheck=2&inajax=yes&inajax=1&ajaxtarget=forumnew").then(res => res.text().then(txt => {
dbgopt("Fetched!");
function pusher(ajson) {
if (localStorage.getItem("getnewpost-" + fid) == null || time - JSON.parse(localStorage.getItem("getnewpost-" + fid)).time > 7200000 || JSON.parse(localStorage.getItem("getnewpost-" + fid)).time == undefined) {
var tids = { tids: [], time: 0 }
for (let item of ajson) {
tids.tids.push(item.tid);
tids.time = time;
}
localStorage.setItem("getnewpost-" + fid, JSON.stringify(tids))
} else {
var temptids = localStorage.getItem("getnewpost-" + fid);
var tids = JSON.parse(temptids);
for (let item of ajson) {
if (tids.tids.indexOf(item.tid) == -1) {
push(item.tid, item.thread.common.val);
tids.tids.push(item.tid);
if (tids.tids.length > 100) {
tids.tids.splice(0, 30);
}
tids.time = time;
localStorage.setItem("getnewpost-" + fid, JSON.stringify(tids));
}
}
}
console.log("Fine!");
}
var result = parse_result(txt);
if (result) {
if (MExt.ValueStorage.get("onlyfresh")) {
result = result.filter(item => {
let rr = numpatt.exec(item.thread.num.val) | 0;
return rr && rr[1] <= 0;
});
} pusher(result);
}
}))
}, stime)
}
function push(tid, subject, title='发现新帖') {
var n = new Notification(title, {
body: subject,
data: {
url: "https://www.mcbbs.net/thread-" + tid + "-1-1.html"
}
});
n.onclick = function () {
window.open(n.data.url, '_blank');
n.close();
};
}
},
"config": [{
"id": "getnewpost",
"default": "52",
"type": "text",
"name": "推送版块最新帖子",
"desc": "填入版块 fid,使用半角逗号隔开"
},
{
"id": "onlyfresh",
"default": true,
"type": "check",
"name": "是否只推送新帖子",
"desc": "若勾选,则不会推送有人回复过的帖子"
},
{
"id": "exposter",
"default": false,
"type": "check",
"name": "(实验性)是否启用新的推送方式",
"desc": "可能会导致消息反复推送"
},
{
"id": "backtime",
"default": 20,
"type": "num",
"name": "(实验性)后台获取新帖的时间间隔(单位:秒)",
"desc": "(仅对新的推送方式有效)设置调用抓取新帖功能的时间间隔"
},
{
"id": "debug",
"defalt": false,
"type": "check",
"name": "(抓取新帖mod)开启调试模式",
"desc": "开启调试模式后,会在控制台额外输出部分信息"
}
]
};
MExt.exportModule(getnewpost);
})();