// ==UserScript==
// @name NGA优化摸鱼体验插件-标记整页
// @namespace https://github.com/DelCrona/WholePageMark
// @version 2.4
// @author DelCrona
// @description 一键标全楼,浏览自动标。
// @license MIT
// @require https://cdn.staticfile.net/jquery/3.4.0/jquery.min.js
// @require https://cdn.staticfile.net/spectrum/1.8.0/spectrum.js
// @require https://cdn.staticfile.net/localforage/1.10.0/localforage.min.js
// @require https://cdn.staticfile.net/echarts/5.4.2/echarts.min.js
// @match *://bbs.nga.cn/*
// @match *://ngabbs.com/*
// @match *://nga.178.com/*
// @match *://g.nga.cn/*
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_listValues
// @grant unsafeWindow
// @run-at document-start
// @inject-into content
// ==/UserScript==
(function (registerPlugin) {
'use strict';
const PageMark = ({
name: 'PageMark', // 插件唯一KEY
title: '标记整页', // 插件名称
desc: '一键对整页用户上标记,点击右边设置按钮使用', // 插件说明
settings: [{
key: 'tips',
title: '1.使用之前先备份本体配置文件和标记列表'
},{
key: 'tips2',
title: '2.不用的时候取消勾选或者关闭插件,否则看到哪标到哪。'
},{
key: 'tips3',
title: '3.出bug的话可以去github反馈'
},{
key: 'tips4',
title: '4.如果文本重复但是颜色不重复,不会自动标记'
},{
key: 'tips5',
title: '5.不同窗口同时一键标记会串标少标'
},{
key: 'markEnable',
title: '启用自动浏览标记',
desc: '勾选来启动自动标记(不用记得关)',
default: false
},{
key: 'markAllEnable',
title: '启用一键标记全贴',
desc: '勾选启动,请在单个窗口使用!',
default: true
},{
key: 'anonyEnable',
title: '启用标记匿名',
desc: '勾选标记匿名,不勾选就不标 P.S:匿名用户为共用UID,标记无法破匿名,可按需勾选',
default: false
},{
key: 'defColor',
title: '使用默认颜色(蓝色)[#1f72f1]',
desc: '这个选项出现的原因是:作者的默认色表没有他的默认颜色#1f72f1,我不懂这是为什么。',
default: true
},{
key: 'markColor',
title: '自定义颜色',
desc: '默认蓝色,下面的色表里没有这个颜色,需要默认颜色请勾选上方按钮',
default: '#1f72f1'
},{
key: 'markInput',
title: '输入你要挂的标记',
desc: '在此处填写,不宜过长,我不知道会不会有bug',
default: ''
}],
markColor: '#1f72f1',
markList: [],
executeCount: 0,
isMarking: false,
preProcFunc() {
// console.log('已运行: preProcFunc()')
},
initFunc() {
// 调用标准模块authorMark初始化颜色选择器
const $ = this.mainScript.libs.$;
this.mainScript.getModule('AuthorMark').initSpectrum(`[plugin-id="${this.pluginID}"][plugin-setting-key="markColor"]`);
// 提前标记颜色属性,在初始化模块判断使用哪个颜色
if(!this.pluginSettings['defColor']) this.markColor = this.pluginSettings['markColor'];
console.log(`标记颜色:${this.markColor}`);
/* console.log($.trim(' '))
console.log('已运行: 标记整页')
console.log('插件ID: ', this.pluginID)
console.log('插件配置: ', this.pluginSettings)
console.log('主脚本: ', this.mainScript)
console.log('主脚本引用库: ', this.mainScript.libs) */
},
postProcFunc() {
},
renderThreadsFunc($el) {
//筛掉不是主题帖的链接
if ($el.find('input[type="checkbox"]').length || !this.pluginSettings['markAllEnable']) return;
//写按钮和点击
$el.find('.c2').append(`<button class="hld__markForum hld__help" id=repair help=标记全贴 当前标记:${this.pluginSettings["markInput"]}>🏷️</button>`);
$el.find('.c2 > .hld__markForum').click(() =>{
if(this.pluginSettings['markInput'].trim() == '') {
this.mainScript.popMsg(`标记为空,无法标记`);
return;
} else if ($el.find('.c2 > .hld__markForum').attr('id') == 'repairing') {
this.mainScript.popMsg(`正在标记中,无法标记`, 'err');
return;
}
//找到对应链接和页数
$el.find('.c2 > .hld__markForum').attr('id', 'repairing');
if(this.pluginSettings['markInput'].trim() == '') return;
var forumlink = $el.find('.c2 > .topic').attr('href');
var tid = this.mainScript.getModule('AuthorMark').getQueryString('tid',forumlink);
var pageNumber = '1';
if ($el.find('.c2 > span > .pager').length){
pageNumber = $el.find('.c2 > span > .pager a').last().text();
}
const preMark = this.pluginSettings['markInput']; //准备标记
const markColor = this.markColor; //标记颜色
this.markList = this.mainScript.getModule('MarkAndBan').markList;
this.mergeUidlist(tid, pageNumber)
.then(list =>{
for (const item of list){
if (parseInt(item) > 0) this.markUser(item, preMark, markColor);
}
this.mainScript.setValue('hld__NGA_mark_list', JSON.stringify(this.markList))
this.mainScript.popMsg(`标记完成,标记了${this.executeCount}个`, 'ok');
console.log(`标记完成,标记了${this.executeCount}个`);
this.executeCount = 0;
$el.find('.c2 > .hld__markForum').attr('id', 'repair');
})
.catch(e =>{
console.log(e);
this.mainScript.popMsg('标记失败');
return;
})
})
},
renderFormsFunc($el) {
const currentUid = $el.find('[name=uid]').text() + '' ; // 获取uid,具体什么方式是复制的本体,能用就行。
// 判断是否勾选启动按钮和是否标记匿名
if (!this.pluginSettings['markEnable'] || (!this.pluginSettings['anonyEnable'] && parseInt(currentUid) < 0)){
console.log("未勾选启动标记或未开启标记匿名且本楼匿名,直接return");
return;
}
// const preMark = this.pluginSettings['markInput']; // 获取设置内自己填写的标记(准备标记)
const preMark = this.pluginSettings['markInput']; // 获取设置内自己填写的标记(准备标记)
let preColor = ""
if(this.pluginSettings['defColor']){
preColor = '#1f72f1';
}
else{
preColor = this.pluginSettings['markColor'];
}
try{
var markArray = this.mainScript.getModule('MarkAndBan').getUserMarks({uid: currentUid});
// 判断是否为空
if (!markArray){
// 空的直接标
// console.log("没被标记过,可以直接标");
// 定义标记对象
let markObj = {
marks: [{mark: preMark, text_color: '#ffffff', bg_color: preColor}],
name: '',
uid: currentUid
}
this.mainScript.getModule('MarkAndBan').setUserMarks(markObj); // 调用标记函数
console.log("无标记者标记成功");
}else{
// console.log(markArray.marks[0].mark);
// 使用find函数找重复,有的话if判断为true接return
if(markArray.marks.find((element) => {return preMark === element.mark;})){
console.log("有重复,无需标记");
return;
}
/*
老版本写法:
for (let i=0; i<markArray.marks.length; i++){
if (preMark === markArray.marks[i].mark){
console.log("有重复,无需标记");
return;
}
}
*/
// console.log("没重复,添加标记");
// 没有重复那么直接标记
// let markList = markArray.marks; // 接收标记数组
markArray.marks.push({mark: preMark, text_color: '#ffffff', bg_color: preColor}); // 在末尾插入标记 默认颜色是#1f72f1 作者为什么不在封装的取色列表里加入这个默认颜色,我不理解
// 写明标记对象并调用标记函数
// let markObj = {marks: markArray.marks, name: '', uid: currentUid};
this.mainScript.getModule('MarkAndBan').setUserMarks({marks: markArray.marks, name: '', uid: currentUid});
console.log("有标记者标记成功");
}
}catch(e){
console.log(e);
}
},
/**
* 标记功能
* @method markUser 标记功能
* @description 获取UID进行标记
* @param {String} _uid uid
*/
async markUser(_uid, preMark, markColor){
var markArray = this.getUserMarks({uid: _uid}); //标记对象的原标记
//const preMark = this.pluginSettings['markInput']; //准备标记
//const markColor = this.markColor; //标记颜色
try{
if (!markArray){
// 空的直接标,定义标记对象
let markObj = {
marks: [{mark: preMark, text_color: '#ffffff', bg_color: markColor}],
name: '',
uid: _uid
}
//this.mainScript.getModule('MarkAndBan').setUserMarks(markObj); // 调用标记函数
this.setUserMarks(markObj);
this.executeCount += 1;
console.log("无标记者标记成功");
}else{
// 使用find函数找重复,有的话if判断为true接return
if(markArray.marks.find((element) => {return preMark === element.mark;})){
console.log("有重复,无需标记");
return;
}
// 没有重复那么直接标记
let pushMark = {mark: preMark, text_color: '#ffffff', bg_color: markColor}
markArray.marks.push(pushMark); // 在末尾插入标记 默认颜色是#1f72f1 作者为什么不在封装的取色列表里加入这个默认颜色,我不理解
// 写明标记对象并调用标记函数
let markAll = {marks: markArray.marks, name: '', uid: _uid}
//this.mainScript.getModule('MarkAndBan').setUserMarks(markAll);
this.setUserMarks(markAll);
this.executeCount += 1;
console.log("有标记者标记成功");
}
}catch(e){
console.log(e);
this.mainScript.popMsg('标记失败')
}},
/**
* 保存标签
* @method setUserMarks
* @param {Object} userMarks 标签对象
*/
setUserMarks(userMarks) {
// 检查是否已有标签
const _this = this
const check = _this.markList.findIndex(v => (v.uid && userMarks.uid && v.uid == userMarks.uid) ||
(v.name && userMarks.name && v.name == userMarks.name))
if(check > -1) {
if (userMarks.marks.length == 0) {
_this.markList.splice(check, 1)
} else {
_this.markList[check] = userMarks
}
}else {
_this.markList.push(userMarks)
}
},
/**
* 获取用户标签对象
* @method getUserMarks
* @param {String} uid UID
* @param {String} user 用户名
* @return {Object|null} 标签对象
*/
getUserMarks(user) {
const _this = this
const check = _this.markList.findIndex(v => (v.uid && user.uid && v.uid == user.uid) || (v.name && user.name && v.name == user.name))
if(check > -1) {
let userMark = _this.markList[check]
if ((!userMark.uid && user.uid) || (!userMark.name && user.name)) {
userMark.uid = user.uid + '' || ''
userMark.name = user.name || ''
//script.setValue('hld__NGA_mark_list', JSON.stringify(this.markList))
}
return userMark
} else {
return null
}
},
/**
* 合并UID列表
* @method mergeUidlist 合并uid列表
* @description 合并uid列表
* @param {String} tid 帖子链接
* @param {Int} page 页码
*/
async mergeUidlist(tid, page){
//定义空set
var mergedSet = new Set();
//备用延迟函数
this.mainScript.popMsg('标记中', 'warn');
//循环获取每一页的uid并合并
for(let i=1; i<=page; i++){
let uidSet = await this.getUidlist(tid, i)
try{
mergedSet = new Set([...uidSet, ...mergedSet]);
}catch(e){
console.log(e)
this.mainScript.popMsg('获取第'+i+'页失败')
}
console.log(`第${i}页`);
}
console.log('获取UID完成,标记中')
this.mainScript.popMsg('获取uid完成,标记中', 'ok');
return(mergedSet);
},
/**
* 获取UID列表
* @method getUidlist
* @description 获取uid列表
* @param {String} tid 帖子链接
* @param {Int} page 页码
*/
getUidlist(tid, page) {
return new Promise((resolve, reject) =>{
let url = `https://${window.location.host}/read.php?tid=${tid}&page=${page}`
var uidSet = new Set();
$.ajax({url})
.then(postRes => {
var $dom = $(postRes) //获取的是未执行js代码的网页
var $uidList = $dom.find('td.c1 > span > a'); //找到有uid的链接
//遍历元素集合,获取uid的set
$uidList.each((index, href) => {
//console.log($(href).attr('href'));
let str = $(href).attr('href').toString();
let urlParams = new URLSearchParams(str);
let uid = urlParams.get('uid');
uidSet.add(uid);
})
resolve(uidSet)
})
.catch(e => {
reject(e)
})
})
},
renderAlwaysFunc() {
// console.log('循环运行: renderAlwaysFunc()')
},
asyncStyle() {
return `#ngascript_plugin_${this.pluginID} {color: red}`
},
style: `
#ngascript_plugin_test {color: red; }
.hld__markForum {text-decoration: none; background-color:#c7edcc; border:1px outset #000000; }
`
})
registerPlugin(PageMark)
})(function(plugin) {
plugin.meta = GM_info.script
unsafeWindow.ngaScriptPlugins = unsafeWindow.ngaScriptPlugins || []
unsafeWindow.ngaScriptPlugins.push(plugin)
});