只要被骂三次“巨魔”就会变成乱码
// ==UserScript==
// @name 关于完全听不懂S1巨魔在说什么的事
// @namespace http://bbs.saraba1st.com
// @version 0.01
// @description 只要被骂三次“巨魔”就会变成乱码
// @author RobinEatCorn
// @match https://*.saraba1st.com/2b/thread-*
// @match https://*.saraba1st.com/2b/forum.php?*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// ==/UserScript==
var scanRex=/巨魔|傻逼|滚|去死|你妈死了|(N|n)(M|m)(S|s|\$)(L|l)/;
const MAX_NAME_INDEX_LENGTH=30;
var parser=new DOMParser();
var idx={};
var threadData;
var userId;
function saveThreadData(){
var threadId=threadData.currentThread;
if(isUndefined(threadId)||isNaN(threadId)){ throw Error("invalid thread ID");}
var nameIndex=GM_getValue("stage1st-thread",[]);
if(!nameIndex.includes(threadId)){
if(nameIndex.length>=MAX_NAME_INDEX_LENGTH){
var tmpid=nameIndex.shift();
GM_deleteValue(`stage1st-thread-${tmpid}`);
GM_deleteValue(`stage1st-thread-${tmpid}-idx`);
}
nameIndex.push(threadId);
GM_setValue("stage1st-thread",nameIndex)
}
GM_setValue(`stage1st-thread-${threadId}`,threadData);
saveIdx();
}
function saveIdx(){
var idxAb={};
Object.keys(idx).forEach((key)=>{
var abstract={};
abstract.pid=idx[key].pid;
abstract.xw1=idx[key].xw1;
abstract.floor=idx[key].floor;
if(idx[key].quotePid){ abstract.quotePid=idx[key].quotePid; }
abstract.textInside=idx[key].textInside;
idxAb[key]=abstract;
});
GM_setValue(`stage1st-thread-${threadData.currentThread}-idx`,idxAb);
}
function arrayAdd(value){ this.push(value);this.sort(); }
function preProcess(dom){
var plhins=dom.getElementsByClassName("plhin");
for(let i=0;i<plhins.length;i++){
plhins[i].pid=Number(plhins[i].id.substr(3));
plhins[i].xw1=Number(plhins[i].getElementsByClassName("xw1")[0].href.split("space-uid-")[1].split(".")[0]);
let tmpele=plhins[i].querySelector("a[id^=postnum]>em");
if(tmpele){
plhins[i].floor=Number(tmpele.innerText);
} else {
plhins[i].floor=1;
}
var quote=plhins[i].querySelector("div.quote>blockquote>font>a");
if(quote){
plhins[i].quoteURL=new URL(quote.href);
plhins[i].quotePid=Number(plhins[i].quoteURL.searchParams.get("pid"));
}
var textInside="";
let tmpt_f=plhins[i].querySelector(".t_f");
if(tmpt_f){
var childNodes=tmpt_f.childNodes;
for(let i=0;i<childNodes.length;i++){
if(childNodes[i].nodeType==Node.TEXT_NODE){ textInside+=childNodes[i].textContent; }
}
plhins[i].textInside=textInside;
} else {
plhins[i].textInside="";
}
idx[`pid${plhins[i].pid}`]=plhins[i];
idx[`floor${plhins[i].floor}`]=plhins[i];
threadData.maxFloor=Math.max(threadData.maxFloor,plhins[i].floor);
if(isUndefined(threadData.userTrollIndex[plhins[i].xw1])){ threadData.userTrollIndex[plhins[i].xw1]=0; }
}
let tmpEle=dom.querySelector(`span[title^="共"]`);
if(tmpEle){
let tmps=tmpEle.innerText;
threadData.maxPage=Number(tmps.substring(3,tmps.length-2));
} else {
threadData.maxPage=1;
}
return {idx,threadData};
}
function shiftString(s,shift=1){
var ans="";
for(let i=0;i<s.length;i++){
ans+=String.fromCharCode(s.charCodeAt(i)+shift);
}
return ans;
}
function trollize(dom,shift=1){
shift=Number(shift);
if(isUndefined(dom.nodeType)){ return;}
if(Number(dom.trollShift)==Number(shift)){ return; }
if(isUndefined(dom.trollShift)||isNaN(dom.trollShift)){ dom.trollShift=0; }
var nodeIterator=document.createNodeIterator(dom,NodeFilter.SHOW_TEXT);
var currentNode;
while(currentNode=nodeIterator.nextNode()){
currentNode.textContent=shiftString(currentNode.textContent,shift-dom.trollShift);
}
dom.trollShift=shift;
}
function appendEnterPoint(dom,shift){
var enterPoint=document.createElement("div");
enterPoint.classList.add("enterPoint");
enterPoint.innerText="进入该巨魔视角";
enterPoint.shiftView=shift;
enterPoint.entered=false;
enterPoint.onclick=function(){
if(this.entered){
trollize(document,0);
this.entered=false;
this.innerText="进入该巨魔视角";
} else {
let rep=confirm("确定要进入该巨魔视角?");
if(rep==false){ return; }
trollize(document,shift)
this.entered=true;
this.innerText="离开该巨魔视角";
}
}
dom.appendChild(enterPoint);
}
function recognizeTrolls(){
var {maxFloor}=threadData;
for(let i=1;i<=maxFloor;i++){
if(threadData.seenFloors.includes(i)) { continue; }
let currentFloor=idx[`floor${i}`];
if(isUndefined(currentFloor)){ continue; }
if(!isUndefined(currentFloor.quotePid) && idx[`pid${currentFloor.quotePid}`]){
if(currentFloor.textInside.match(scanRex)){
threadData.userTrollIndex[idx[`pid${currentFloor.quotePid}`].xw1]+=4;
threadData.userTrollIndex[currentFloor.xw1]+=2;
}
} else {
if(currentFloor.textInside.match(scanRex)){
threadData.userTrollIndex[currentFloor.xw1]+=1;
if(currentFloor.textInside.match("楼主|lz|Lz|lZ|LZ") && !isUndefined(idx.floor1)){
threadData.userTrollIndex[idx.floor1.xw1]+=4;
threadData.userTrollIndex[currentFloor.xw1]+=1;
}
}
}
threadData.seenFloors.add(i);
}
for(let i=1;i<=maxFloor;i++){
let currentFloor=idx[`floor${i}`];
if(isUndefined(currentFloor)||isUndefined(currentFloor.nodeType)){ continue; }
if(threadData.userTrollIndex[currentFloor.xw1]>=12){
let trollShift=Math.trunc(threadData.userTrollIndex[currentFloor.xw1]/12);
trollize(currentFloor,trollShift);
var enterPoint=currentFloor.querySelector(".enterPoint");
if(enterPoint){
enterPoint.shift=trollShift;
} else {
var currentt_f=currentFloor.querySelector(".t_f");
if(currentt_f){ appendEnterPoint(currentFloor.querySelector(".t_f"),-trollShift); }
}
}
if(!isUndefined(currentFloor.quotePid) && idx[`pid${currentFloor.quotePid}`]){
if(threadData.userTrollIndex[idx[`pid${currentFloor.quotePid}`].xw1]>=12){
trollize(currentFloor.querySelector("div.quote"));
}
}
}
if(threadData.userTrollIndex[userId]>=12){ trollize(document,-Math.trunc(threadData.userTrollIndex[userId]/12))}
//console.log(threadData);
saveThreadData();
}
function grabPages(){
//console.log(idx);
//console.log(threadData);
var pageToGrab=1;
var flag=false;
while(threadData.seenPages.includes(pageToGrab)&&pageToGrab<=threadData.maxPage){pageToGrab++;}
if(pageToGrab==threadData.maxPage+1&&threadData.currentPage==threadData.maxPage){recognizeTrolls();console.log(threadData);return;}
if(pageToGrab==threadData.maxPage+1) { pageToGrab--; flag=1; }
console.log(`grab page ${pageToGrab}(关于完全听不懂S1巨魔在说什么的事)`);
var xhr=new XMLHttpRequest();
if(flag){
xhr.onreadystatechange=function(){
if(this.readyState==4&&this.status==200){
var dom=parser.parseFromString(this.response,"text/html");
preProcess(dom);
recognizeTrolls();
//console.log(dom);
threadData.seenPages.add(pageToGrab);
saveThreadData();
recognizeTrolls();
console.log(threadData);
}
}
} else {
xhr.onreadystatechange=function(){
if(this.readyState==4&&this.status==200){
var dom=parser.parseFromString(this.response,"text/html");
preProcess(dom);
recognizeTrolls();
//console.log(dom);
threadData.seenPages.add(pageToGrab);
saveThreadData();
setTimeout(grabPages,1000);
}
}
}
xhr.open("GET",`https://bbs.saraba1st.com/2b/thread-${threadData.currentThread}-${pageToGrab}-1.html`);
xhr.send();
}
function addCSS(){
var styleEle=document.createElement("style");
document.head.appendChild(styleEle);
var styleSheet=styleEle.sheet;
styleSheet.insertRule(`
.enterPoint {
text-decoration : none;
background-color : #eeeeee;
color : #000000;
user-select : none;
padding-left : 1%;
padding-right : 1%;
font-weight : bold;
text-align : center;
}`);
styleSheet.insertRule(`
.enterPoint:hover {
background-color : #888888;
}`);
styleSheet.insertRule(`
.enterPoint:active {
background-color : #000000;
color : #FFFFFF;
}`);
}
function processWindow(){
//if(location.href.indexOf("2b/thread")==-1){ return -1; }
let nameIndex=GM_getValue("stage1st-thread",[]);
console.log(`关魔说事:本地存储了 ${nameIndex.length} 篇帖子(最多 ${MAX_NAME_INDEX_LENGTH} 篇)`);
let tmpele=document.querySelector("#um .avt.y a");
if(tmpele){
userId=Number(tmpele.href.split("space-uid-")[1].split(".html")[0]);
if(isNaN(userId)||isUndefined(userId)){ userId=0; }
} else { userId=0;}
let href=new URL(location.href);
var pageId;
var threadId;
if(href.searchParams.get("mod")=="viewthread"){
threadId=href.searchParams.get("tid");
pageId=Number(href.searchParams.get("page")) || 1;
} else {
threadId=location.href.split("-");
pageId=Number(threadId[2]);
threadId=Number(threadId[1]);
}
if(isUndefined(pageId)||isUndefined(threadId)||isNaN(pageId)||isNaN(threadId)){ return -1;}
console.log(`thread=${threadId},page=${pageId},(关于完全听不懂S1巨魔在说什么的事)`);
threadData=GM_getValue(`stage1st-thread-${threadId}`,undefined);
if(!threadData){
threadData={
startFloor:1,
maxFloor:0,
maxPage:0,
currentPage:pageId,
currentThread:threadId,
userTrollIndex:{0:0},
seenPages:[],
seenFloors:[]
};
} else {
threadData.currentPage=pageId;
threadData.currentThread=threadId;
}
threadData.userTrollIndex[userId]=0;
idx=GM_getValue(`stage1st-thread-${threadId}-idx`,{});
threadData.seenPages.add=arrayAdd;
threadData.seenFloors.add=arrayAdd;
threadData.seenPages.add(pageId);
preProcess(document);
addCSS();
saveThreadData();
//console.log(idx);
//console.log(threadData);
setTimeout(grabPages,1000);
}
(function() {
'use strict';
window.onload=processWindow;
})();