// ==UserScript==
// @name MCBBS水帖辅助工具
// @namespace https://www.mcbbs.net/?3074655
// @version 0.18
// @description 帮助坛友高效水帖
// @author 开心的阿诺
// @match https://www.mcbbs.net/*
// @icon https://www.mcbbs.net/favicon.ico
// @grant unsafeWindow
// @grant GM_registerMenuCommand
// @run-at document-body
// @license MIT
// ==/UserScript==
(function() {
'use strict';
if (typeof jQuery == "undefined") return -1;
let $ = unsafeWindow.jQuery;
let url = window.location.href, searchParams = new URLSearchParams((new URL(url)).search);
//获取tid
let tid = "";
if (url.indexOf("thread-") != -1){
let start = url.indexOf("thread-") + 7;
tid = url.substring(start, url.indexOf("-", start));
}
else if (searchParams.get("mod") == "viewthread" && searchParams.has("tid")){
tid = searchParams.get("tid");
}
//修复备注历史遗留问题
let string = localStorage.getItem("note");
if (string != null){
if (string[0] != "\`"){
string = "\`" + string;
localStorage.setItem("note", string);
}
let obj = {}, pos = 1;
while(pos < string.length){
let t = string.indexOf("\`\`", pos);
let key = string.substring(pos, t);
pos = t + 2;
t = string.indexOf("\`", pos);
let name = string.substring(pos, t);
obj[key] = name;
pos = t + 1;
}
localStorage.removeItem("note");
localStorage.setItem("newNote", JSON.stringify(obj));
}
try{
if (JSON.parse(localStorage.getItem("newNote")).constructor != Object) throw -1;
}
catch(err){
localStorage.setItem("newNote", "{}");
}
//是否聚焦输入框
function inputing(){
return document.activeElement.type == "text" || document.activeElement.type == "textarea";
}
//备注图片
const src = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAADuSURBVDhPjZKxD8FAFMa/UsEijUSTkoiZxSBl7ND/uKMOHekkEmaTJrVgqdA43vWuuaL4lvfevffLd/dyGv6U67pMpPB9/z9OhUhUV0T+UVPDZDTkeR4cx9mLY65SkKBFrSEqIFltLRX+COaQ1RYnANUq/AbmkGlguT5hHsVoTKaiC+i6btFyCqAKhZszNDAeVaVpGlHM16pCUgTZoxYQHzG7XdAcD6MgCLrU444SCg/ZBaRLGUSqqk49JAh3V97omfVSiJRZiDdRtDv3r05SGfgcomEJ/4Jy0XVZp8+WGPBI9etPeVVhqyL97QTgAV0+hUuijeVaAAAAAElFTkSuQmCC`;
//刷新script
$(document).ready(function(){
//设置界面弹出后刷新<script>(用innerHTML插入的<script>不会维护到DOM里面)
if ($('#append_parent')[0]){
//刷新script
function refresh(script){
let newScript = document.createElement("script");
newScript.innerHTML = script.innerHTML;
let src = script.getAttribute("src");
if (src) newScript.setAttribute("src", src);
newScript.setAttribute("initialized", "true");//打标记
script.parentNode.replaceChild(newScript, script);
}
//监听#append_parent子节点的变化
let appendObserver = new MutationObserver(() => {
//console.log($("#append_parent")[0]);
$('#append_parent #fwin_dialog #auxiliaryToolSetting script').each((i, v) => {
if(v.initialized != "true") refresh(v);
});
});
appendObserver.observe($('#append_parent')[0], { childList: true });
}
});
//触发条件
let conditions = {
forum: url.indexOf("forum-") != -1 || (searchParams.get("mod") == "forumdisplay" && searchParams.has("fid")),//版块
thread: tid != "",//帖子
forum_chat: url.indexOf("forum-chat-") != -1 || (searchParams.get("mod") == "forumdisplay" && searchParams.get("fid") == 52),//矿工茶馆版块
friend: url.indexOf("do=friend") != -1,//好友列表
space: ((searchParams.has("uid") && searchParams.get("mod") == "space") || url.indexOf("/?") != -1) && searchParams.get("do") != "thread"//个人空间
}
//功能模块
let modules = [
{
name: "菜单栏矿工茶馆按钮",
run_at: "document-body",
condition: true,
code: () => {
function teahouse(){
$('.z.light')[0].innerHTML += `<a href="forum-chat-1.html" style="font-weight: bold;">矿工茶馆</a>`;
}
try { teahouse(); }
catch(err) { $(document).ready(teahouse); }
}
},
{
name: "Q键回复",
run_at: "document-body",
condition: conditions.thread,
code: () => {
document.addEventListener("keydown", () => {
if(window.event.keyCode == 81 && !event.ctrlKey && !event.shiftKey && !$('#fwin_reply #postsubmit')[0] && !inputing()){
unsafeWindow.showWindow("reply", "forum.php?mod=post&action=reply&tid=" + tid);//弹出回复窗口
}
});
}
},
{
name: "外链直接跳转",
run_at: "document-ready",
condition: true,
code: () => {
$('a[href^="https://www.mcbbs.net/plugin.php?id=link_redirect"]').each((i, v) => {
v.href = decodeURIComponent(v.href.substr(v.href.indexOf("&target=") + 8));//链接解码
});
}
},
{
name: "自动确认发帖提示窗口",
run_at: "document-ready",
condition: true,
code: () => {
if ($("#append_parent")[0]){
let appendObserver = new MutationObserver(() => {
//console.log($("#append_parent"));
try {
let dom = $("#append_parent #fwin_dialog td.m_c");
if (dom.find("div.c.altw > div.alert_right > p")[0].innerHTML.indexOf("[ 点击这里转入主题列表 ]") != -1) {
dom.find("p.o.pns > button#fwin_dialog_submit")[0].click();
}
}
catch(err) {}
});
appendObserver.observe($("#append_parent")[0], { childList: true });
}
}
},
{
name: "坟贴标记",
run_at: "document-ready",
condition: conditions.forum_chat,
code: () => {
let now = new Date().getTime();
$('#threadlist td.by>cite+em>a').each((i, v) => {
//截取日期
let str = v.children[0] ? v.children[0].title : v.innerHTML;
//判断时间是否在10天内
let t = v.parentNode.parentNode.parentNode.children[1].children[2].children[0];
if (Date.parse(str) + 864000000 < now && t){
t.style = "color:red;";
t.title = "最后回复日期超过十天时,主题将被定义为坟帖,论坛禁止挖坟行为";
}
});
}
},
{
name: "滑动到帖子的位置(板块内)",
run_at: "document-ready",
condition: conditions.forum,
code: () => {
if (window.pageYOffset == 0) $('#thread_types')[0].scrollIntoView({behavior: "smooth"});
}
},
{
name: "预览Q键回复",
run_at: "document-ready",
condition: conditions.forum,
code: () => {
document.addEventListener("keydown", () => {
if(window.event.keyCode == 81 && !event.ctrlKey && !inputing()){
let screenHeight = document.documentElement.clientHeight / 2;//屏幕一半的位置
$('.fastpreview').each((i, v) => {
let info = v.getBoundingClientRect(), top = info.top, bottom = info.bottom;
if (top <= screenHeight && screenHeight <= bottom){
v.children[2].children[0].children[0].children[0].children[0].children[1].children[0].children[0].onclick()//显示回复窗口
return false;
}
});
}
});
}
},
{
name: "更好的快速回复按钮",
run_at: "document-ready",
condition: conditions.thread,
code: () => {
function fastPost(){
if ($('#vfastpostform')[0]){
$('#vfastpostform')[0].innerHTML = `<a id="custom_post_reply" onclick="showWindow('reply', 'forum.php?mod=post&action=reply&tid=` + tid + `')" href="javascript:;" title="回复"><img src="template/mcbbs/image/pn_reply.png" align="right" alt="回复"></a>`;
}
}
fastPost();
let postObserver = new MutationObserver(() => {
postObserver.disconnect();
fastPost();
postObserver.observe($('#postlist')[0], { childList: true, subtree: true });
});
postObserver.observe($('#postlist')[0], { childList: true, subtree: true });//监听#postlist里的变化,再次修改
}
},
{
name: "滑动到帖子的位置(帖子内)",
run_at: "document-ready",
condition: conditions.thread,
code: () => {
if (window.pageYOffset == 0) $('#pgt')[0].scrollIntoView({behavior: "smooth"});
}
},
{
name: "回复帖的快速回复",
run_at: "document-ready",
condition: conditions.thread,
code: () => {
document.addEventListener("keydown", () => {
if(window.event.keyCode == 81 && (event.ctrlKey || event.shiftKey) && !inputing()){
let reply = $('.fastre');//获取回复链接
let screenHeight = document.documentElement.clientHeight / 2;//屏幕一半的位置
$('table.plhin').each((i, v) => {
let info = v.getBoundingClientRect(), top = info.top, bottom = info.bottom;
if (top <= screenHeight && screenHeight <= bottom){
window.scrollTo({ top: v.offsetTop - $('#toptb')[0].clientHeight, behavior: "smooth" });
unsafeWindow.showWindow('reply', reply[i].href);//显示回复窗口
return false;
}
});
}
});
}
},
{
name: "帖子内显示备注",
run_at: "document-ready",
condition: conditions.thread,
code: () => {
let obj = JSON.parse(localStorage.getItem("newNote"));
$('.xw1[href^="home.php?mod=space&uid="]').each((i, v) => {
let uid = v.href.substring(v.href.indexOf("&uid=") + 5);
if (obj[uid]) v.innerHTML = obj[uid] + `<img src="` + src + `" class="vm" alt="备注" title="` + v.innerHTML + `">`;//替换用户名
});
}
},
{
name: "快速打开/关闭隐藏内容",
run_at: "document-ready",
condition: conditions.thread,
code: () => {
document.addEventListener("keydown", () => {
if(window.event.keyCode == 73 && !event.ctrlKey && !inputing()){
$('.spoilerbody').each((i, v) => { v.style.display = "block"; });
}
else if(window.event.keyCode == 79 && !event.ctrlKey && !inputing()){
$('.spoilerbody').each((i, v) => { v.style.display = "none"; });
}
});
}
},
{
name: "好友列表内显示备注",
run_at: "document-ready",
condition: conditions.friend,
code: () => {
let obj = JSON.parse(localStorage.getItem("newNote"));
$('.xg1.xw0.y').each((i, v) => {
let name = v.parentNode.children[1], uid = name.href.substring(name.href.indexOf("&uid=") + 5);
if (obj[uid]) name.innerHTML = obj[uid] + `<img src="` + src + `" class="vm" alt="备注" title="` + name.innerHTML + `">`;//替换用户名
});
}
},
{
name: "个人空间设置备注",
run_at: "document-ready",
condition: conditions.space,
code: () => {
//设置备注
let uid = $('a.xg1[href^="http"]')[0].href;
uid = uid.substring(uid.indexOf('?') + 1);
$('.pbm.mbm.bbda.cl .mbn')[0].outerHTML += `<img src="` + src + `" title="备注"> <input id="noteInput" class="pt" title="输入备注" maxlength="15" style="width:25%"> <button id="noteButton" class="pn pnc vm"><strong>保存</strong></button>`;
let obj = JSON.parse(localStorage.getItem("newNote"));
if (obj[uid]) $('#noteInput.pt')[0].value = obj[uid];
$('#noteButton.pn.pnc.vm')[0].addEventListener('click', () => {//点击保存按钮
let pt = $('#noteInput.pt')[0].value;
obj = JSON.parse(localStorage.getItem("newNote"));
if (pt.replace(/[\u0391-\uFFE5]/g, "aa").length <= 15){//备注不得超过15个字符
if (pt == "" && obj[uid] != null) delete obj[uid];//为空就删除备注
else obj[uid] = pt;
localStorage.setItem("newNote", JSON.stringify(obj));
unsafeWindow.showDialog('备注设置成功~', '', '', () => {}, 0, () => {}, '', '', '', '1');
}
else{
unsafeWindow.showDialog('备注名非法!', 'alert', '错误');
}
});
}
},
{
name: "晋级用户组显示",
run_at: "document-ready",
condition: conditions.space,
code: () => {
let userPoint = parseInt($("#psts")[0].children[1].children[1].childNodes[1].data);
let point = [-999999999, 0, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000];
let userGroup = ["Lv.? Herobrine", "Lv.0 流浪者", "Lv.1 伐木工", "Lv.2 采石匠", "Lv.3 挖沙工", "Lv.4 矿工", "Lv.5 农夫", "Lv.6 手艺人", "Lv.7 猎手", "Lv.8 考古家", "Lv.9 牧场主", "Lv.10 附魔师", "Lv.11 领主", "Lv.12 屠龙者"];
let l = 0, r = point.length - 1;
while (l < r){//我知道这里没什么必要,但还是想秀一波(被打
let mid = (l + r + 1) >> 1;
if (point[mid] <= userPoint) l = mid;
else r = mid - 1;
}
$('#psts .pf_l')[0].innerHTML += `<li><em>晋级用户组</em>` + userGroup[l] + `</li>`;
}
}
];
let success = true;
modules.forEach((v) => {
if (!v.condition) return;
function execute(){
try{
v.code();
}
catch{
success = false;
console.log("MCBBS水帖辅助工具 - 模块“" + v.name + "”加载失败");
}
}
switch(v.run_at){
case "document-body":
execute();
break;
case "document-ready":
$(document).ready(execute);
break;
}
});
$(document).ready(function(){
if (success) console.log('MCBBS水帖辅助工具 - 正常加载');
});
})();