// ==UserScript==
// @name 清水河畔之谁是懂球帝
// @namespace http://tampermonkey.net/
// @version 0.1.3
// @description 睡睡睡(>﹏<)
// @author DARK-FLAME-MASTER FROM RIVERSIDE
// @match *://*.uestc.edu.cn/forum.php?mod=viewthread*
// @require https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js
// @icon https://www.google.com/s2/favicons?sz=64&domain=uestc.edu.cn
// @grant GM_setValue
// @grant GM_getValue
// @grant unsafeWindow
// @grant GM_registerMenuCommand
// @license WTFPL
// @downloadURL https://update.greasyfork.icu/scripts/455434/%E6%B8%85%E6%B0%B4%E6%B2%B3%E7%95%94%E4%B9%8B%E8%B0%81%E6%98%AF%E6%87%82%E7%90%83%E5%B8%9D.user.js
// @updateURL https://update.greasyfork.icu/scripts/455434/%E6%B8%85%E6%B0%B4%E6%B2%B3%E7%95%94%E4%B9%8B%E8%B0%81%E6%98%AF%E6%87%82%E7%90%83%E5%B8%9D.meta.js
// ==/UserScript==
(function () {
'use strict';
function notice(message) {
Notification.requestPermission().then((result) => { if (result === 'granted') { let n = new Notification(message); setTimeout(n.close.bind(n), 1800) } })
}
function generate(matches) {
let reg = /["',,.。/、\]|[【】\\n\s!!??——_<>%;‘’;)《()》(&+=`“”·*#@@]/
wrong = []
let names = data.map((u) => u.name)
data.forEach((d, i) => {
let predict = i != 0 ? d.content.length == matches ? d.content : d.content.split(reg).join('') : '楼主'
if (names.indexOf(d.name) != i)
d.predict = '重复'
else
d.predict = predict
let r = new RegExp(`[胜负平]{${matches}}`)
if ((predict.length != matches || !predict.match(r) && d.predict != '重复') && i != 0)
wrong.push(d.floor)
})
alert(`请完善${wrong.join('楼,')}的异常信息`)
}
function addWater(pid, water, reason, referer) {
return fetch("https://bbs.uestc.edu.cn/forum.php?mod=misc&action=rate&ratesubmit=yes&infloat=yes&inajax=1", {
"headers": {
'content-type': 'application/x-www-form-urlencoded'
},
"body": `tid=${tid}&pid=${pid}&formhash=${formhash}&referer=${encodeURI(referer)}&handlekey=rate&score2=${water}&reason=${reason}`,
"method": "POST",
});
}
function addWaterAll(water) {
let addPromises = win.map((index) => addWater(data[index - 1].pid, water, rewardMessage(data[index - 1].accuracy), `https://bbs.uestc.edu.cn/forum.php?mod=viewthread&tid=${tid}&page=${calcPage(data[index - 1].floor)}#${data[index - 1].pid}`))
Promise.all(addPromises).then((_)=>_.map((r,i)=>r.ok?'':win[i]+'楼,').reduce((p,c)=>p+c,'')).then((result)=>result==''?alert('完成加水'):alert(result+'需要手动加水'))
}
function check(result) {
if (wrong.length == 0) {
win = []
winMaLe = []
data.forEach((d) => {
d.accuracy = result.split('').reduce((count, p, i) => count + (p == d.predict[i] ? 1 : 0), 0) / matches
if (d.accuracy >= 0.5) win.push(d.floor)
if (d.accuracy == 1) winMaLe.push(d.floor)
})
notice('完成准确率计算')
checked = true
if (autoAdd){
document.body.innerHTML += `
🧧
`
$('#prewarda').addEventListener('click', () => addWaterAll(20))
}
} else {
notice(`还剩${wrong.join('楼,')}没有完成`)
}
}
function set(predicts, index, predict) {
predicts[index].predict = predict
store()
}
function search(predicts, index) {
return predicts[index].predict
}
async function getData(url, pages) {
let p = new Array(pages).fill(0)
let dataPromise = p.map((_, page) => fetch(url + (page + 1))
.then(data => data.text())
.then(data => {
let doc = new DOMParser().parseFromString(data, 'text/html');
let users = doc.querySelectorAll('div.authi > a.xw1')
let contents = doc.querySelectorAll('.t_f')
return [].slice.call(users, 0).map((user, index) => { return { space: user.href, floor: index + page * 20 + 1, name: user.text, content: contents[index].textContent.replaceAll('\n', ''), pid: contents[index].id.match(/(\d+)/)[1] } })
}))
return await Promise.all(dataPromise).then(data => data.reduce((p, c) => p.concat(c)).sort((a, b) => a.floor - b.floor))
}
async function initPredict() {
if (data == undefined) {
let link = unsafeWindow.location.href
tid = link.match(/tid=(\d*)/)[1]
let pages = parseInt($('#pgt > div > div > label > span').textContent.match(/(\d+)/)[1])
data = await getData(`https://bbs.uestc.edu.cn/forum.php?mod=viewthread&tid=${tid}&extra=&page=`, pages)
generate(matches)
$('#pgwrongf').textContent = wrong ? wrong[0] + '楼' : ''
store()
} else
alert('当前帖子为' + tid)
}
function save() {
let csvContent = '用户名,预测结果,楼层数,空间链接,帖子ID,预测准确率' + data.map(user => user.predict.length == 4 ? `${user.name},${user.predict},${user.floor},${user.space},${user.pid},${user.accuracy ? user.accuracy : 0}` : '').join('\n')
saveAs(new Blob([Uint8Array.from([0xEF, 0xBB, 0xBF]), csvContent], { type: "text/plain;charset=utf-8" }), new Date().toISOString() + '.csv').then((_) => notice('保存成功'))
}
function store() {
GM_setValue('data', data)
GM_setValue('wrong', wrong)
GM_setValue('rewardNow', rewardNow)
GM_setValue('matches', matches)
GM_setValue('win', win)
GM_setValue('winMaLe', winMaLe)
GM_setValue('tid', tid)
GM_setValue('checked', checked)
}
function load() {
data = GM_getValue('data', undefined)
wrong = GM_getValue('wrong', undefined)
rewardNow = GM_getValue('rewardNow', 0)
matches = GM_getValue('matches', undefined)
win = GM_getValue('win', undefined)
winMaLe = GM_getValue('winMaLe', undefined)
tid = GM_getValue('tid', undefined)
autoAdd = GM_getValue('autoAdd', false)
checked = GM_getValue('checked', false)
}
function clear() {
data = undefined
wrong = undefined
rewardNow = undefined
matches = undefined
win = undefined
winMaLe = undefined
tid = undefined
checked = false
store()
notice('已完成清空')
}
function registerEvents() {
/* if (autoAdd && reward)
addWater(data[win[rewardNow - 1]].pid, 1, 'test', unsafeWindow.location.href) */
$('#pgenerate').addEventListener('click', function () {
matches = parseInt(prompt('请输入比赛数:'))
if (matches) initPredict()
notice('已加载数据')
})
$('#pset').addEventListener('click', () => $('#psetm').style.visibility = ('visible' == $('#psetm').style.visibility ? 'hidden' : 'visible'))
$('#psearch').addEventListener('click', () => $('#psearchm').style.visibility = ('visible' == $('#psearchm').style.visibility ? 'hidden' : 'visible'))
$('#preward').addEventListener('click', () => $('#prewardm').style.visibility = ('visible' == $('#prewardm').style.visibility ? 'hidden' : 'visible'))
$('#psetb').addEventListener('click', function () {
let predict = $('#psetp').value
let index = parseInt($('#psetf').value) - 1
set(data, index, predict)
notice('设置成功')
})
$('#psearchb').addEventListener('click', function () {
let index = parseInt($('#psearchf').value) - 1
$('#psearchp').value = search(data, index)
})
$('#prewardb').addEventListener('click', function () {
let result = $('#prewardp').value
check(result)
rewardNow = 0
$('#pgrewardf').textContent = win ? win[rewardNow] + '楼' : ''
store()
})
$('#pgwrong').addEventListener('click', function () {
if (wrong.length >= 1) {
let wrongNow = wrong.shift()
store()
unsafeWindow.location = `https://bbs.uestc.edu.cn/forum.php?mod=viewthread&tid=${tid}&page=${calcPage(wrongNow)}#pid${data[wrongNow - 1].pid}`
}
$('#pgwrongf').textContent = wrong ? (wrong.length ? wrong[0] + '楼' : '完成') : ''
})
$('#pgreward').addEventListener('click', function () {
rewardNow++
store()
unsafeWindow.location = `https://bbs.uestc.edu.cn/forum.php?mod=viewthread&tid=${tid}&page=${calcPage(win[rewardNow - 1])}#pid${data[win[rewardNow - 1] - 1].pid}`
$('#pgrewardf').textContent = win ? win[rewardNow] + '楼' : ''
})
$('#pclear').addEventListener('click', clear)
$('#psave').addEventListener('click', save)
if (autoAdd && checked) $('#prewarda').addEventListener('click', () => addWaterAll(20))
}
function setting() {
autoAdd = !autoAdd
GM_setValue('autoAdd', autoAdd)
location.reload()
}
let data, wrong, rewardNow, matches, win, winMaLe, tid, autoAdd, checked, formhash
const rewardMessage = (accuracy) => accuracy == 1 ? '预测正确率100%' : '预测正确率≥50%'
const calcPage = (floor) => parseInt((floor - 1) / 20) + 1
function $(s) {
return document.querySelector(s)
}
load()
if (unsafeWindow.location.href.match(/tid=(\d*)/)[1] == tid || $('input[name=srhfid]').value == '157' && $("p > em > a").text == '版主' && $('.ts>a').text == '[比赛]') {
GM_registerMenuCommand((autoAdd ? '☑️' : '❌') + '全自动加水', setting, "h");
if (autoAdd && checked)
document.body.innerHTML += `🧧
`
document.body.innerHTML += `
`
formhash = $('input[name=formhash]').value
$('#pgrewardf').textContent = win ? win[rewardNow] + '楼' : ''
$('#pgwrongf').textContent = wrong ? (wrong.length ? wrong[0] + '楼' : '完成') : ''
registerEvents()
}
// Your code here...
})();