返回首頁 

NGA成分指示

标注出NGA网页版帖子中用户的成分。


Install this script?
// ==UserScript==// @name         NGA成分指示// @namespace    No namespace.// @version      0.11451// @license      WTFPL// @description  标注出NGA网页版帖子中用户的成分。// @author       You// @match       *://bbs.nga.cn/*// @match       *://ngabbs.com/*// @match       *://nga.178.com/*// ==/UserScript==(function () {'use strict';let forums = {};let cfs = {};let cftime = {};let cfzsPanel;// 查询结果的保质期,默认为3天,单位为秒const VALIDITY_PERIOD = 3 * 86400;const PANEL_DIV_HTML = `<div id="cfzs_setting_panel" style="display:none; position:fixed; background:#fff6df; box-shadow:0 0 15px #444; border:1px solid #591804; top: 55px; left: 100px; padding-left: 10px; padding-right: 10px; padding-bottom: 10px;"><h3 style="text-align:center;">NGA成分指示</h3><hr>填写要关注版块的FID:<input id="cfzs_add_input" style="width:72px;"><button id="cfzs_add_forum" style="width:60px;">添加</button><div>或是直接添加当前版块:<button id="cfzs_add_current_forum">添加</button></div><hr><p>目前关注的版块:</p><div id="tag_modifier" style="padding: 5px; border: 1px solid #591804;"></div><div id="cfzs_feedback_info" style="float:left;"></div><button style="float:right;" id="cfzs_close_button">关闭</button><button style="float:right;" id="cfzs_clear_cache_button">清除缓存</button></div>`;class SettingPanel {constructor(form) {this.form = form;this.tagModifier = this.form.querySelector("#tag_modifier");this.feedback = this.form.querySelector("#cfzs_feedback_info");// 添加版块按钮document.getElementById("cfzs_add_forum").addEventListener("click", () => { this.addForum(document.getElementById('cfzs_add_input').value); });// 添加当前版块按钮document.getElementById("cfzs_add_current_forum").addEventListener("click", () => { this.addForum(__CURRENT_FID) });// 清除缓存按钮document.getElementById("cfzs_close_button").addEventListener("click", () => { this.close() });// 关闭按钮document.getElementById("cfzs_clear_cache_button").addEventListener("click", () => { this.clearData() });// 添加设置按钮document.getElementsByClassName("right")[0].getElementsByClassName("td")[0].insertAdjacentHTML("afterend", `<div class=" td"><a id="cfzs_setting_button" class="mmdefault  gray" href="javascript:void(0)" title="成分指示" style="white-space: nowrap;">成分指示</a></div>`);document.getElementById("cfzs_setting_button").addEventListener("click", () => { this.open() });this.drawPanel();}drawPanel() {// 绘制面板this.tagModifier.innerHTML = "";let placeholder;let thistag;for (let fid in forums) {placeholder = document.createElement("div");placeholder.insertAdjacentHTML("afterbegin",  `<div class="cfzs_forum_tag" style="display:flex;justify-content:space-between;"><div>FID:${fid}</div><div><input class="cfzs_forum_name" id="cfzs_remark_${fid}" style="width:60px;" value="${forums[fid]}"><button id="cfzs_modify_remark_${fid}">备注</button><button id="cfzs_delete_forum_${fid}">删除</button></div></div>`);thistag = placeholder.firstElementChild;this.tagModifier.appendChild(thistag);// 修改备注按钮thistag.querySelector(`#cfzs_modify_remark_${fid}`).addEventListener("click", () => { this.changeRemark(fid, document.getElementById(`cfzs_remark_${fid}`).value); });// 删除按钮thistag.querySelector(`#cfzs_delete_forum_${fid}`).addEventListener("click", () => { this.deleteForum(fid); });}}open() {// 在打开面板时再更新面板上的信息this.form.style.display = 'block';}addForum(fid) {if (fid in forums) {this.feedback.innerHTML = `这个版块已经添加过了…`;return ######;}let postData;fetch(`https://${window.location.host}/thread.php?fid=${fid}&__output=8`).then(res => res.arrayBuffer()).catch(error => { postData = { 'error': [error] } }).then(buffer => new TextDecoder("gbk").decode(buffer)).then((res) => {try {postData = JSON.parse(res);} catch {this.feedback.innerHTML = `发生了奇怪的错误,也许此版块(FID:${fid})不存在…`;return ######;}if (!postData || 'error' in postData) {this.feedback.innerHTML = `发生了奇怪的错误,也许此版块(FID:${fid})不存在…`;return ######;}let fname = postData.data.__F.name;forums[fid] = fname;window.localStorage.setItem("cfzs_forums", JSON.stringify(forums));// 添加了一个版块后将cftime清空,以对每个用户发起新的查询cftime = {};window.localStorage.setItem('cfzs_cftime', "{}");this.feedback.innerHTML = `添加了版块${fid}…`;//alert(`${fname}(FID:${fid})添加成功!`);this.drawPanel();});}addCurrentForm() {this.addForum(__CURRENT_FID);//forums[__CURRENT_FID] = document.querySelector(`[href='/thread.php?fid=${__CURRENT_FID}'`).innerHTML;}deleteForum(fid) {delete forums[fid];window.localStorage.setItem("cfzs_forums", JSON.stringify(forums));this.feedback.innerHTML = `删除了版块${fid}…`;this.drawPanel();}clearData() {if (window.confirm("这会清空已保存的用户成分,可能会造成成分判断不准确。确定要这样做吗?")) {forums = {};cfs = {};cftime = {};window.localStorage.setItem('cfzs_forums', "{}");window.localStorage.setItem('cfzs_cfs', "{}");window.localStorage.setItem('cfzs_cftime', "{}");alert("清空完毕,刷新以生效…");}}changeRemark(fid, remark) {forums[fid] = remark;window.localStorage.setItem("cfzs_forums", JSON.stringify(forums));this.feedback.innerHTML = `将版块${fid}备注为${remark}…`;//this.drawPanel();}close() {this.form.style.display = 'none';}}// 初始化脚本function cfzs_init() {// 生成设置面板// 从localStorage中读取保存的配置信息if (!('cfzs_forums' in window.localStorage)) {// 首次使用时添加配置信息window.localStorage.setItem('cfzs_forums', "{}");window.localStorage.setItem('cfzs_cfs', "{}");window.localStorage.setItem('cfzs_cftime', "{}");}forums = JSON.parse(window.localStorage.getItem('cfzs_forums'));cfs = JSON.parse(window.localStorage.getItem('cfzs_cfs'));cftime = JSON.parse(window.localStorage.getItem('cfzs_cftime'));document.body.insertAdjacentHTML('beforeend', PANEL_DIV_HTML);cfzsPanel = new SettingPanel(document.getElementById('cfzs_setting_panel'));if (Object.keys(forums).length < 1) {alert('您没有关注任何版面。请添加一些以开始使用。');cfzsPanel.open();}}// 添加成分function addChengFen(uid, fid) {// 仅当fid在关注版面中且用户成分尚未包括该fid时才将fid加入用户成分cftime[uid] = __NOW;window.localStorage.setItem("cfzs_cftime", JSON.stringify(cftime));if (fid in forums) {cfs[uid].push(fid);cfs[uid] = Array.from(new Set(cfs[uid]));window.localStorage.setItem("cfzs_cfs", JSON.stringify(cfs));}}// 将查询结果推送到用户面板上function pushChengFen(form, uid) {let text = '成分: ';let thiscf = [];//console.log(cfs[uid]);for (let i of cfs[uid]) {if (i in forums) thiscf.push(i);}if (thiscf.length > 0) {text += thiscf.map((e) => { return `<span class='silver'>${forums[e]}</span>&nbsp;(<a style='text-decoration: underline;' href='https:\/\/${window.location.host}\/thread.php?authorid=${uid}&fid=${e}'>贴</a>·<a style='text-decoration: underline;' href='https:\/\/${window.location.host}\/thread.php?searchpost=1&authorid=${uid}&fid=${e}'>回</a>)` }).join(' / ');} else {text += "<span class='silver'>群众</span>";}form.getElementsByClassName("ngatag_container")[0].innerHTML = text;return ######;}// 主循环function cfzs_mainLoop() {// 获取每层楼的结构let floors = Array.from(document.getElementsByClassName("forumbox postbox"));if (floors.length > 0) {floors.forEach(f => {// 筛除分页符if (!f.querySelector(".postrow")) return ######;// 判断本楼是否存在已有的查询结果if (f.getElementsByClassName("ngatag_container").length > 0) {// 若是则直接跳过循环console.log(`Div existed, jumped...`);return ######;} else {// 若否,则在用户面板的最下方插入divf.getElementsByClassName("clear")[0].insertAdjacentHTML('beforebegin', '<div class="ngatag_container" style="float: left; margin-right: 3px;min-width:49%;*width:49%;"></div>');}// 获取本层用户的UIDlet uid = f.querySelector("a[name='uid']").innerHTML;if (uid in cftime) {// 如果已经保存有该UID的查询结果,则判断查询结果的保存时间// __NOW 是NGA网页内部的时间戳,希望二哥不要乱动它if ((__NOW - cftime[uid]) <  VALIDITY_PERIOD) {// 若查询结果仍处于保质期内,则直接向div推送查询结果,跳过循环console.log(`Found available uid, creating div...`);pushChengFen(f, uid);return ######;} else {// 若查询结果已经过期,则开始一轮新的查询console.log(`Found out-of-date uid, searching...`);}} else {// 如果遇到新的UIDconsole.log(`Found new uid, searching...`);cfs[uid] = [];}// 查询用户发表的主题let postData1;fetch(`https://${window.location.host}/thread.php?authorid=${uid}&__output=8`).then(res => res.arrayBuffer()).catch(error => { postData1 = { 'error': [error] } }).then(buffer => new TextDecoder("gbk").decode(buffer)).then((res) => {postData1 = JSON.parse(res);// 如果用户活跃的版面是关注的版面,则将该版面其加入用户的成分中for (let i in postData1.data.__T) {addChengFen(uid, postData1.data.__T[i].fid.toString());}pushChengFen(f, uid);});// 查询用户发表的回复。逻辑应当与前者是一样的let postData2;fetch(`https://${window.location.host}/thread.php?searchpost=1&authorid=${uid}&__output=8`).then(res => res.arrayBuffer()).catch(error => { postData2 = { 'error': [error] } }).then(buffer => new TextDecoder("gbk").decode(buffer)).then((res) => {postData2 = JSON.parse(res);for (let i in postData2.data.__T) {addChengFen(uid, postData2.data.__T[i].fid.toString());}pushChengFen(f, uid);});})}}cfzs_init();//mainLoop();setInterval(cfzs_mainLoop, 3000);})();