// ==UserScript==
// @Name CD后回复(固定30上限版)
// @namespace http://tampermonkey.net/
// @version 1.1.13
// @description 防止CD期间误发帖,每小时固定30次回帖上限。
// @author 福黎 + Single Tonight修正版
// @match *://www.gamemale.com/thread*
// @match *://www.gamemale.com/forum.php?mod=viewthread&tid=*
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict'
let replyMaxEnabled = true //是否启用上限判断
let checked = true //是否默认勾选“回帖后自动关闭页面”
GM_addStyle(`
#fastpostsubmit.dequeue{
background-color:#F49544;
border-color:#D17F3A;
}
#fastpostsubmit.dequeue:hover{
background-color:#AE6A30;
border-color:#8B5526;
}
#replyCount{
float:right;
margin-right:10px;
}
#clearReplyList{
display:block;
text-align:center;
float:right;
margin:0 20px;
}
`)
let replyList = JSON.parse(localStorage.getItem('replyList') || '[]')
let replyTime = JSON.parse(localStorage.getItem('replyTime') || '[]')
let tid = window.location.href.match(/thread-(\d+)|tid=(\d+)/)
tid = tid[2] || tid[1]
let type = true
let time = 0
// 固定每小时上限 30 次
const level = 0
const replyMax = replyMaxEnabled ? 30 : 10000000
const form = document.querySelector('#fastpostform')
const message = document.querySelector('#fastpostmessage')
const submit = document.querySelector('#fastpostsubmit')
const close = document.createElement('label')
const replyCountBox = document.createElement('div')
const clearReplyList = document.createElement('a')
clearReplyList.id = 'clearReplyList'
clearReplyList.href = 'javascript:;'
replyCountBox.id = 'replyCount'
form.onsubmit = ''
close.innerHTML = checked ? `<input id="close" type="checkbox" class="pc" checked>
回帖后自动关闭页面` : `<input id="close" type="checkbox" class="pc">
回帖后自动关闭页面`
clearReplyList.innerHTML = '清空队列'
document.querySelector('.ptm.pnpost').append(close, clearReplyList, replyCountBox)
updateReplyCount()
form.addEventListener('submit', e => e.preventDefault())
submit.addEventListener('click', () => { type ? enqueue() : dequeue() })
clearReplyList.addEventListener('click', delEnqueue)
function enqueue() {
if (!replyList.includes(tid) && replyTime.length + replyList.length < replyMax) {
if (new Blob([message.value]).size < 30) {
alert(`您的帖子长度不足30字节,当前长度:${new Blob([message.value]).size}`)
return
}
replyList.push(tid)
localStorage.setItem('replyList', JSON.stringify(replyList))
submit.classList.add('dequeue')
submit.innerHTML = '<strong>排队中...</strong>'
message.setAttribute('readonly', true)
type = false
if (replyList.length === 1) {
observeChanges()
send()
}
window.addEventListener('beforeunload', () => {
replyList = replyList.filter(item => item != tid)
localStorage.setItem('replyList', JSON.stringify(replyList))
})
updateReplyCount()
} else if (replyList.includes(tid)) {
alert('帖子已在队列中')
} else {
alert('您已达到1小时内30次回复上限!')
}
}
let formCheck1, formCheck2, isSubmitting = false
function send() {
form.onsubmit = sub()
const now = Math.floor(Date.now() / 1000)
replyTime = JSON.parse(localStorage.getItem('replyTime') || '[]')
time = time ? time : 60 - (now - replyTime[replyTime.length - 1])
formCheck1 = setTimeout(() => {
let t = 0
form.onsubmit = sub()
formCheck2 = setInterval(() => {
if (isSubmitting) return
if (t >= 24) {
dequeue()
alert('网络波动,请刷新页面重新排队')
clearTimeout(formCheck1)
clearTimeout(formCheck2)
}
form.onsubmit = sub()
t++
}, 5000)
}, time * 1000)
}
let isTriggered = false
function observeChanges() {
const targetNode = document.getElementById('append_parent')
const observer = new MutationObserver(() => {
if (document.getElementById("creditpromptdiv") && !isTriggered) {
isTriggered = true
const now = Math.floor(Date.now() / 1000)
replyTime.push(now)
localStorage.setItem('replyTime', JSON.stringify(replyTime))
clearInterval(formCheck1)
clearInterval(formCheck2)
observer.disconnect()
dequeue()
if (close.querySelector('input').checked) window.close()
}
})
observer.observe(targetNode, { childList: true })
}
function dequeue() {
submit.innerHTML = '<strong>发表回复</strong>'
submit.classList.remove('dequeue')
message.removeAttribute('readonly')
type = true
replyList = replyList.filter(item => item != tid)
localStorage.setItem('replyList', JSON.stringify(replyList))
clearTimeout(formCheck1)
clearTimeout(formCheck2)
}
window.addEventListener('storage', e => {
if (e.key === 'replyList' || e.key === 'replyTime') {
replyList = JSON.parse(localStorage.getItem('replyList') || '[]')
replyTime = JSON.parse(localStorage.getItem('replyTime') || '[]')
updateReplyCount()
if (e.key === 'replyList' && tid == replyList[0]) {
observeChanges()
send()
} else if (e.key === 'replyList' && replyList.length === 0) {
dequeue()
}
}
})
async function sub() {
if (isSubmitting) return
isSubmitting = true
const isValid = await fastpostvalidate(form)
isSubmitting = false
console.log('提交中...')
return isValid
}
function updateReplyCount() {
const now = Math.floor(Date.now() / 1000)
replyTime = replyTime.filter(t => now - t <= 3600)
replyCountBox.innerHTML = `<span>${replyTime.length}/30 | 排队数:${replyList.length}</span>`
localStorage.setItem('replyTime', JSON.stringify(replyTime))
}
function delEnqueue() {
if (confirm('确定清空队列吗?')) {
replyList = []
dequeue()
updateReplyCount()
localStorage.setItem('replyList', JSON.stringify(replyList))
}
}
})()
|