// ==UserScript== // @name pseudo-Benben - tiger0132 // @namespace https://oj.akioi.ml:8200/ // @version 1.0.5 // @description qwq // @author tiger0132 // @match https://*.luogu.com.cn/ // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @downloadURL none // ==/UserScript== (function () { 'use strict'; var ignoreList = GM_getValue('LuoguIgnoreList_v2', {}); function getUid(name) { // 根据用户名反查 uid return new Promise((resolve, reject) => { $.get('/fe/api/user/search?keyword=' + name, function (resp) { resolve(resp.users[0].uid); }); }); } const $ = unsafeWindow.$, host = GM_getValue('benben_host', 'https://akioi.ml:8204'); const request = ({ url, data, method }) => new Promise((resolve, reject) => { // 历史遗留代码,以后改掉 $.ajax({ type: method, data: data, url: url, dataType: 'json', xhrFields: { withCredentials: false }, success: data => resolve(data), error: reject }); }); function verifyToken(cur_token) { console.log(cur_token); fetch("https://www.luogu.com.cn/paste/new", { "headers": { "content-type": "application/json;charset=UTF-8", "x-csrf-token": document.getElementsByName('csrf-token')[0].content, }, "body": `{"public":true,"data":"${cur_token}"}`, "method": "POST", }).then(resp => resp.json()).then(resp => { request({ url: host + '/api/verifyToken', data: { pasteId: resp.id }, method: 'POST' }).then(res => { if (res.status != 200) { console.error(res.data); return show_alert('提示', '[Benben\'] 出了一点问题 >_<', res.data); } console.log(`[Benben'] token: ${cur_token}, paste: ${resp.id}`); GM_setValue('benben_token', token = cur_token); fetch(`https://www.luogu.com.cn/paste/delete/${resp.id}`, { "credentials": "include", "headers": { "content-type": "application/json;charset=UTF-8", "x-csrf-token": document.getElementsByName('csrf-token')[0].content, }, "referrer": "https://www.luogu.com.cn/paste/nzqcvntn", "referrerPolicy": "no-referrer-when-downgrade", "body": `{\"data\":\"${cur_token}\",\"id\":\"${resp.id}\",\"public\":true}`, "method": "POST", "mode": "cors" }).then(res => res.json()).then(res => { if (res.id != resp.id) { console.error(`error when deleting paste: ${res.id} != ${resp.id}`); return show_alert('提示', '[Benben\'] 出了一点问题 >_<', `error when deleting paste: ${res.id} != ${resp.id}`); } show_alert('提示', '[Benben\'] 验证成功'); checkStatus(); }); }); }); } function genNewToken() { request({ url: host + '/api/getToken', data: { uid: _feInstance.currentUser.uid }, method: 'GET' }).then(token => { if (token.status != 200) { console.error(res.data); return alert('[Benben\'] 出了一点问题 >_<'); } verifyToken(token.data); }); } var token = GM_getValue('benben_token'); var sendMode = 0; // 1 是伪犇,0 是原 var origSend; function injectPostFeed() { // origSend = $._data($('#feed-submit')[0], 'events').click[0].handler; $('#feed-submit').unbind(); document.getElementById('feed-submit').onclick = function () { if (sendMode) { this.classList.add('am-disabled'); var content = document.getElementById('feed-content').value; request({ url: host + '/api/postFeed', data: { content: content, token: token, room_id: feedMode.substr(8) }, method: 'POST' }).then(resp => { if (resp.status !== 200) { show_alert('好像哪里有点问题', resp.data); } else { $("#feed-content").val(''); switchMode(feedMode); } this.classList.remove('am-disabled'); }); } else { $(this).addClass("am-disabled"); var content = $('#feed-content').val(), e = this; $.post("/api/feed/postBenben", { content: content }, function (resp) { if (resp.status !== 200) { show_alert("好像哪里有点问题", resp.data); } else { $(e).removeClass("am-disabled"); $("#feed-content").val(''); switchMode('watching'); } }); } }; } const selector_html = `伪犇犇`; // var origLoadFeed = unsafeWindow.loadFeed; function origLoadFeed() { $.get('/feed/' + feedMode + '?page=' + feedPage, function (resp) { console.log('[pLIE v2] loadFeed()'); var l = $(resp), res; for (var i = 0; i < l.length; i++) { // 在获取犇犇的时候就直接过滤 (function (node) { if (node.tagName == 'LI') { var uid = node.querySelector('div.lg-left > a').href.match(/\/user\/(\d+)/)[1]; if (ignQuery(uid)) { console.log(`[pLIE v2] ignored a feed from uid=${uid}`); // debug return; } var ignAddButton = $(`屏蔽`); var ignDelButton = $(`解除`); ignAddButton.click(() => { ignAdd(uid); }); ignDelButton.click(() => { ignDel(uid); }); $('div.am-comment-main > header > div', node).append(ignAddButton).append(' ').append(ignDelButton); $feed.append(node); } else $feed.append(node); })(l[i]); } $('#feed-more').children('a').text('点击查看更多...') $('[name=feed-delete]').click(function () { $.post('/api/feed/delete/' + $(this).attr('data-feed-id'), () => { switchMode('all'); // TODO: 把这个改了 }) }) $('[name=feed-reply]').click(function () { var content = $(this).parents('li.feed-li').find('.feed-comment').text(); $('#feed-content').val(' || @' + $(this).attr('data-username') + ' : ' + content); }) $('[name=feed-report]').click(function () { var reportType = $(this).attr('data-report-type'), reportID = $(this).attr('data-report-id'); $('#report').modal({ relatedTarget: this, onConfirm: (e) => { var reason = $('[name=reason]').val(); var detail = $('[name=content]').val(); $.post('/api/report/' + reportType, { relevantID: reportID, reason: reason + ' ' + detail }, function (data) { show_alert('提示', data.data); }); } }); }); }); feedPage++; } unsafeWindow.loadFeed = () => { if (unsafeWindow.feedMode.indexOf('pbenben') != -1) p_loadFeed(); else origLoadFeed(); } var origSwitchMode = unsafeWindow.switchMode; unsafeWindow.switchMode = mode => { if (mode.indexOf('pbenben') != -1) sendMode = 1; else sendMode = 0; origSwitchMode(mode); } function p_loadFeed() { request({ url: host + '/feed/' + unsafeWindow.feedMode.substr(8), data: { page: unsafeWindow.feedPage, uid: _feInstance.currentUser.uid, token: token }, method: 'GET' }).then(resp => { console.log('[pLIE v2] loadFeed()'); var l = $(resp.data), res; for (var i = 0; i < l.length; i++) { // 在获取犇犇的时候就直接过滤 (function (node) { if (node.tagName == 'LI') { var uid = node.querySelector('div.lg-left > a').href.match(/\/user\/(\d+)/)[1]; if (ignQuery(uid)) { console.log(`[pLIE v2] ignored a feed from uid=${uid}`); // debug return; } var ignAddButton = $(`屏蔽`); var ignDelButton = $(`解除`); ignAddButton.click(() => { ignAdd(uid); }); ignDelButton.click(() => { ignDel(uid); }); $('div.am-comment-main > header > div', node).append(ignAddButton).append(' ').append(ignDelButton); $feed.append(node); } else $feed.append(node); })(l[i]); } $('#feed-more').children('a').text('点击查看更多...'); $('[name=feed-delete]').click(function () { request({ url: host + '/api/feed/delete', data: { id: $(this).attr('data-feed-id'), token: token }, method: 'POST' }).then(resp => { if (resp.status != 200) show_alert(resp.data); else switchMode(feedMode); }); }); $('[name=feed-reply]').click(function () { var content = $(this).parents('li.feed-li').find('.feed-comment').text(); $('#feed-content').val(' || @' + $(this).attr('data-username') + ' : ' + content); }); feedPage++; }); } function addFeedModeSelector() { // deprecated try { var node = document.createElement('li'); node.className = 'feed-selector'; node.setAttribute('data-mode', 'pbenben-all'); node.id = 'pbenben-all'; node.innerHTML = selector_html; document.getElementById('home-center-nav').appendChild(node); $('#pbenben-all').click(() => switchMode('pbenben-all')); } catch (e) { console.log('addFeedModeSelector() failed'); } } function addColorSelector() { request({ url: host + '/api/allowedColors', data: {}, method: 'GET' }).then(resp => { var btn = $('#name-selector'); btn.append(``); var arr = JSON.parse(resp.data); for (var i of arr) { var d = JSON.parse(i); btn.append(``); } }); document.getElementById('change-color').onclick = () => { var val = document.getElementById('name-selector').value; if (val == 'qwq') return show_alert('提示', '请选择颜色'); var data = JSON.parse(val); request({ 'url': host + '/api/changeColor', data: { token: token, color: data.color, bold: data.bold }, method: 'POST' }).then(resp => show_alert('提示', resp.data)); }; } function checkStatus() { request({ url: host + '/api/tokenStatus', data: { token: token }, method: 'GET' }).then(resp => { var statusNode = document.getElementById('pbenben-status'); var btn = document.getElementById('benben-btn'); btn.textContent = ''; statusNode.textContent = ''; if (resp.status != 200) { statusNode.style.color = '#e74c3c'; statusNode.textContent = `错误:${resp.data}`; btn.textContent = '生成 token'; btn.style.visibility = 'visible'; btn.onclick = function () { this.classList.add('am-disabled'); genNewToken(); }; } else if (resp.data.verified/* && resp.data.uid == _feInstance.currentUser.uid*/) { btn.style.visibility = 'hidden'; statusNode.style.color = '#5eb95e'; statusNode.textContent = `正常:uid = ${resp.data.uid}`; } else { btn.style.visibility = 'visible'; statusNode.style.color = '#e67e22'; if (!resp.data.verified) { statusNode.textContent = 'token 未验证 '; btn.textContent = '验证 token'; btn.onclick = function () { this.classList.add('am-disabled'); verifyToken(token); }; } // if (resp.data.uid != _feInstance.currentUser.uid) { // statusNode.style.color = 'red'; // statusNode.textContent += 'uid 不匹配'; // btn.onclick = function () { // this.classList.add('am-disabled'); // genNewToken(); // }; // } } }); } function addTagChanger() { $('#change-tag').click(() => { var tag = $('#tag-content')[0].value; request({ url: host + '/api/changeTag', data: { token: token, tag: tag }, method: 'POST' }).then(data => show_alert('提示', data.data)); }); } function addVersionChecker() { $('#version-info')[0].textContent = `当前版本:${GM_info.script.version} `; request({ url: host + '/api/latestVersion', method: 'GET' }).then(data => $('#version-info')[0].textContent += `最新版本:${data.data}`); } function addFeedModeButton() { request({ url: host + '/api/allowedRooms', data: {}, method: 'GET' }).then(data => { var node = $('#feedmode-selector')[0]; if (data.status != 200) node.append('有理由怀疑伪犇犇又双叒叕爆炸了 >_<'); else { var rooms = JSON.parse(data.data); for (var i of rooms) { node.append($(` `)[0]); node.append('\u00a0'); } } }); } const entityMap = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`', '=': '=' }; function escapeHtml(string) { return String(string).replace(/[&<>"'`=\/]/g, s => entityMap[s]); } const status_html = `