// ==UserScript== // @name NGA Likes Support // @namespace https://greasyfork.org/users/263018 // @version 1.2.2 // @author snyssss // @description 显示被点赞和粉丝数量,以及发帖数量、IP属地、曾用名 // @match *://bbs.nga.cn/* // @match *://ngabbs.com/* // @match *://nga.178.com/* // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @noframes // @downloadURL none // ==/UserScript== ((ui) => { if (!ui) return; // KEY const SHOW_OLDNAME_ENABLE_KEY = "SHOW_OLDNAME_ENABLE"; const SHOW_POSTNUM_ENABLE_KEY = "SHOW_POSTNUM_ENABLE"; const SHOW_IPLOC_ENABLE_KEY = "SHOW_IPLOC_ENABLE"; // 显示曾用名 const showOldnameEnable = GM_getValue(SHOW_OLDNAME_ENABLE_KEY) || false; // 显示发帖数 const showPostnumEnable = GM_getValue(SHOW_POSTNUM_ENABLE_KEY) || false; // 显示IP属地 const showIpLocEnable = GM_getValue(SHOW_IPLOC_ENABLE_KEY) || false; // 钩子 const hookFunction = (object, functionName, callback) => { ((originalFunction) => { object[functionName] = function () { const returnValue = originalFunction.apply(this, arguments); callback.apply(this, [returnValue, originalFunction, arguments]); return returnValue; }; })(object[functionName]); }; class UserInfo { execute(task) { task().finally(() => { if (this.waitingQueue.length) { const next = this.waitingQueue.shift(); this.execute(next); } else { this.isRunning = false; } }); } enqueue(task) { if (this.isRunning) { this.waitingQueue.push(task); } else { this.isRunning = true; this.execute(task); } } rearrange() { if (this.data) { const list = Object.values(this.children); for (let i = 0; i < list.length; i++) { if (list[i].source === undefined) { list[i].create(this.data); } Object.entries(this.container).forEach((item) => { list[i].clone(this.data, item); }); } } } reload() { this.enqueue(async () => { this.data = await new Promise((resolve) => { fetch(`/nuke.php?lite=js&__lib=ucp&__act=get&uid=${this.uid}`) .then((res) => res.blob()) .then((blob) => { const reader = new FileReader(); reader.onload = () => { const text = reader.result; const result = JSON.parse( text.replace("window.script_muti_get_var_store=", "") ); resolve(result.data[0]); }; reader.readAsText(blob, "GBK"); }) .catch(() => { resolve(); }); }); if (this.data.usernameChanged && showOldnameEnable) { this.data.oldname = await new Promise((resolve) => { fetch(`/nuke.php?lite=js&__lib=ucp&__act=oldname&uid=${this.uid}`) .then((res) => res.blob()) .then((blob) => { const reader = new FileReader(); reader.onload = () => { const text = reader.result; const result = JSON.parse( text.replace("window.script_muti_get_var_store=", "") ); resolve(result.data[0]); }; reader.readAsText(blob, "GBK"); }) .catch(() => { resolve(); }); }); } Object.values(this.children).forEach((item) => item.destroy()); this.rearrange(); }); } constructor(id) { this.uid = id; this.waitingQueue = []; this.isRunning = false; this.container = {}; this.children = {}; this.reload(); } } class UserInfoWidget { destroy() { if (this.source) { this.source = undefined; } if (this.target) { Object.values(this.target).forEach((item) => { if (item.parentNode) { item.parentNode.removeChild(item); } }); } } clone(data, [argid, container]) { if (this.source) { if (this.target[argid] === undefined) { this.target[argid] = this.source.cloneNode(true); if (this.callback) { this.callback(data, this.target[argid]); } } container.appendChild(this.target[argid]); } } constructor(func, callback) { this.create = (data) => { this.destroy(); this.source = func(data); this.target = {}; }; this.callback = callback; } } ui.sn = ui.sn || {}; ui.sn.userInfo = ui.sn.userInfo || {}; ((info) => { const execute = (argid) => { const args = ui.postArg.data[argid]; if (args.comment) return; const uid = +args.pAid; if (uid > 0) { if (info[uid] === undefined) { info[uid] = new UserInfo(uid); } if (document.contains(info[uid].container[argid]) === false) { info[uid].container[argid] = args.uInfoC.closest("tr").querySelector(".posterInfoLine") || args.uInfoC.querySelector("div"); } info[uid].enqueue(async () => { if (info[uid].children[8] === undefined) { info[uid].children[8] = new UserInfoWidget((data) => { const value = Object.values(data.more_info || {}).find( (item) => item.type === 8 )?.data || 0; const element = document.createElement("SPAN"); element.className = "small_colored_text_btn stxt block_txt_c2 vertmod"; element.style.cursor = "default"; element.innerHTML = ` ${value}`; return element; }); } if (info[uid].children[16] === undefined) { info[uid].children[16] = new UserInfoWidget((data) => { const value = data.follow_by_num || 0; const element = document.createElement("SPAN"); element.className = "small_colored_text_btn stxt block_txt_c2 vertmod"; element.style.cursor = "default"; element.innerHTML = ` ${value}`; return element; }); } info[uid].rearrange(); const container = info[uid].container[argid]; const isSmall = container.classList.contains("posterInfoLine"); if (showOldnameEnable) { if (ui._w.__GP.admincheck) { return; } if (isSmall) { const anchor = [...container.querySelectorAll("span.gray")].pop() .nextElementSibling; const uInfo = info[uid].data; if (anchor && uInfo && uInfo.oldname) { const element = document.createElement("SPAN"); element.className = "gray nobr"; element.innerHTML = ` 曾用名: ${Object.values(uInfo.oldname) .map( (item) => `${item.username}` ) .join(", ")}`; anchor.parentNode.insertBefore(element, anchor); } } else { const anchor = container.parentNode.querySelector( '.stat div[class="clear"]' ).parentNode; const uInfo = info[uid].data; if (anchor && uInfo && uInfo.oldname) { const element = document.createElement("DIV"); element.innerHTML = ` 曾用名: ${Object.values(uInfo.oldname) .map( (item) => `${item.username}` ) .join(", ")}`; anchor.parentNode.appendChild(element, anchor); } } } if (showPostnumEnable) { if (ui._w.__GP.admincheck) { return; } if (isSmall) { const anchor = [...container.querySelectorAll("span.gray")].pop(); const uInfo = ui.userInfo.users[uid]; if (anchor && uInfo) { const element = document.createElement("SPAN"); element.className = "gray nobr"; element.innerHTML = ` 发帖: ${uInfo.postnum}`; anchor.parentNode.insertBefore(element, anchor); } } else { const anchor = container.parentNode.querySelector( '.stat div[class="clear"]' ); const uInfo = ui.userInfo.users[uid]; if (anchor && uInfo) { const element = document.createElement("DIV"); element.style = "float:left;margin-right:3px;min-width:49%;*width:49%"; element.innerHTML = ` 发帖: ${uInfo.postnum} `; anchor.parentNode.insertBefore(element, anchor); } } } if (showIpLocEnable) { if (ui._w.__GP.admincheck) { return; } if (isSmall) { const anchor = [...container.querySelectorAll("span.gray")].pop(); const uInfo = info[uid].data; if (anchor && uInfo) { const element = document.createElement("SPAN"); element.className = "gray nobr"; element.innerHTML = ` 属地: ${uInfo.ipLoc}`; anchor.parentNode.insertBefore(element, anchor); } } else { const anchor = container.parentNode.querySelector( '.stat div[class="clear"]' ); const uInfo = info[uid].data; if (anchor && uInfo) { const element = document.createElement("DIV"); element.style = "float:left;margin-right:3px;min-width:49%;*width:49%"; element.innerHTML = ` 属地: ${uInfo.ipLoc} `; anchor.parentNode.insertBefore(element, anchor); } } } }); } }; if (ui.postArg) { Object.keys(ui.postArg.data).forEach((i) => execute(i)); } let initialized = false; hookFunction(ui, "eval", () => { if (initialized) return; if (ui.postDisp) { hookFunction( ui, "postDisp", (returnValue, originalFunction, arguments) => execute(arguments[0]) ); initialized = true; } }); })(ui.sn.userInfo); // 菜单项 (() => { // 显示曾用名 if (showOldnameEnable) { GM_registerMenuCommand("显示曾用名:启用", () => { GM_setValue(SHOW_OLDNAME_ENABLE_KEY, false); location.reload(); }); } else { GM_registerMenuCommand("显示曾用名:禁用", () => { GM_setValue(SHOW_OLDNAME_ENABLE_KEY, true); location.reload(); }); } // 显示发帖数 if (showPostnumEnable) { GM_registerMenuCommand("显示发帖数:启用", () => { GM_setValue(SHOW_POSTNUM_ENABLE_KEY, false); location.reload(); }); } else { GM_registerMenuCommand("显示发帖数:禁用", () => { GM_setValue(SHOW_POSTNUM_ENABLE_KEY, true); location.reload(); }); } // 显示IP属地 if (showIpLocEnable) { GM_registerMenuCommand("显示属地:启用", () => { GM_setValue(SHOW_IPLOC_ENABLE_KEY, false); location.reload(); }); } else { GM_registerMenuCommand("显示属地:禁用", () => { GM_setValue(SHOW_IPLOC_ENABLE_KEY, true); location.reload(); }); } })(); })(commonui);