您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
qwq
- // ==UserScript==
- // @name pseudo-Benben - tiger0132
- // @namespace https://oj.akioi.ml:8200/
- // @version 1.2.7
- // @description qwq
- // @author tiger0132
- // @match https://*.luogu.com.cn/
- // @grant unsafeWindow
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_deleteValue
- // @grant GM_addStyle
- // ==/UserScript==
- (function () {
- 'use strict';
- const $ = unsafeWindow.$, host = GM_getValue('benben_host', 'https://pbb.akioi.ml');
- const request = ({ url, data }) => new Promise((resolve, reject) => {
- try {
- data.img = 1;
- data._ = +new Date;
- var img = new Image();
- img.setAttribute('crossOrigin', 'anonymous');
- img.onload = function () {
- var canvas = document.createElement('canvas');
- canvas.width = this.width;
- canvas.height = this.height;
- var ctx = canvas.getContext('2d');
- ctx.drawImage(this, 0, 0);
- resolve(JSON.parse(new TextDecoder().decode(ctx.getImageData(0, 0, this.width, 1).data.filter((_, i) => i % 4 !== 3))));
- };
- img.onerror = reject;
- img.src = url + '?' + new URLSearchParams(data);
- } catch (e) {
- reject(e);
- }
- });
- function verifyToken(cur_token, secret) {
- console.log(`token: ${cur_token}`);
- console.log(`secret: ${secret}`);
- var slogan = _feInstance.currentUser.slogan;
- show_prompt('提示', '脚本可能会覆盖您的签名,请妥善备份。\n原签名:' + slogan, () => {
- fetch('https://www.luogu.com.cn/api/user/updateSlogan', {
- 'headers': {
- 'content-type': 'application/json;charset=UTF-8',
- 'x-csrf-token': document.getElementsByName('csrf-token')[0].content
- },
- 'body': `{"slogan":"${secret}"}`,
- 'method': 'POST',
- }).then(resp => resp.json()).then(resp => {
- request({
- url: host + '/api/auth/verifyToken',
- data: { token: cur_token }
- }).then(res => {
- if (res.status !== 200) {
- console.error(res.data);
- return show_alert('提示', '[Benben\'] 出了一点问题 >_<', res.data);
- }
- GM_setValue('benben_token', token = cur_token);
- fetch('https://www.luogu.com.cn/api/user/updateSlogan', {
- 'headers': {
- 'content-type': 'application/json;charset=UTF-8',
- 'x-csrf-token': document.getElementsByName('csrf-token')[0].content
- },
- 'body': `{"slogan":"${slogan}"}`,
- 'method': 'POST',
- }).then(res => res.json()).then(res => {
- show_alert('提示', '[Benben\'] 验证成功');
- checkStatus();
- });
- });
- });
- });
- }
- function genNewToken() {
- request({
- url: host + '/api/auth/getToken',
- data: { uid: _feInstance.currentUser.uid }
- }).then(res => {
- if (res.status !== 200) {
- console.error(res.data);
- return alert('[Benben\'] 出了一点问题 >_<');
- }
- verifyToken(res.data.token, res.data.secret);
- });
- }
- var token = GM_getValue('benben_token'), cur_uid;
- var sendMode = 0; // 1 是伪犇,0 是原
- function injectPostFeed() {
- $('#feed-submit').unbind();
- $('#feed-submit').click(function () {
- if (sendMode) {
- this.classList.add('am-disabled');
- var content = document.getElementById('feed-content').value;
- request({
- url: host + `/api/feed/${feedMode.substr(8)}/post`,
- data: { content: content, token: token }
- }).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 = `<a style="cursor: pointer">伪犇犇</a>`;
- 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 = $(`<span class="am-btn am-btn-danger am-btn-sm am-radius am-badge lg-bg-red ign-btn" data-uid="${uid}">屏蔽</span>`);
- var ignDelButton = $(`<span class="am-btn am-btn-success am-btn-sm am-radius am-badge lg-bg-green ign-btn" data-uid="${uid}">解除</span>`);
- 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(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);
- })
- $('[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 + '/api/feed/' + unsafeWindow.feedMode.substr(8),
- data: {
- page: unsafeWindow.feedPage,
- token: token
- }
- }).then(resp => {
- if (resp.status !== 200) return show_alert('提示', resp.data);
- const rootUsers = [ // 后端会检验的,如果没有权限,加进去也没用
- 28762
- ];
- var feedMd = [];
- var html = resp.data.reduce((last, i) => {
- var feed_del = '', badge_html = '';
- if (i.user.uid == cur_uid || rootUsers.includes(cur_uid))
- feed_del = `<a name="feed-delete" data-feed-id="${i.id}">删除</a>`;
- if (i.user.badge)
- badge_html = ` <span class="am-badge am-radius" style="background-color: ${i.user.color};">${escapeHtml(i.user.badge)}</span>`;
- return last + `
- <li class="am-comment am-comment-primary feed-li"}>
- <div class="lg-left"><a href="/user/${i.user.uid}" class="center">
- <img src="https://cdn.luogu.com.cn/upload/usericon/${i.user.uid}.png" class="am-comment-avatar">
- </a></div>
- <div class="am-comment-main">
- <header class="am-comment-hd">
- <div class="am-comment-meta">
- <span class="feed-username"><a class${i.user.bold ? '="lg-bold"' : ''} style="color: ${i.user.color} !important;" href="/user/${i.user.uid}" target="_blank">${i.user.name}</a>${badge_html}</span> ${fmtDate(new Date(i.time * 1000))}
- ${feed_del}
- <a name="feed-reply" href="javascript: scrollToId('feed-content')" data-username="${i.user.name}">回复</a>
- </header>
- <div class="am-comment-bd">
- <span class="feed-comment">${i.content_html}</span>
- <span class="feed-markdown">${encodeURIComponent(i.content_markdown)}</span>
- </div>
- </div>
- </li>`
- }, '');
- $feed.append(html);
- $('#feed-more').children('a').text('点击查看更多...');
- $('[name=feed-delete]').click(function () {
- request({
- url: host + '/api/feed/action/delete',
- data: {
- id: $(this).attr('data-feed-id'),
- token: token
- }
- }).then(resp => {
- if (resp.status != 200) show_alert(resp.data);
- else switchMode(feedMode);
- });
- });
- $('[name=feed-reply]').click(function () {
- var content_markdown = $(this).parents('li.feed-li').find('.feed-markdown').text();
- var content_html = $(this).parents('li.feed-li').find('.feed-comment').text();
- $('#feed-content').val(' || @' + $(this).attr('data-username') + ' : \n' + (decodeURIComponent(content_markdown) || content_html));
- });
- feedPage++;
- });
- }
- unsafeWindow.getFeedMode = () => {
- if (feedMode.startsWith('pbenben-'))
- return feedMode.substr(8);
- else
- return feedMode;
- };
- unsafeWindow.changeColor = (color, bold) =>
- request({
- url: host + '/api/user/changeColor',
- data: {
- token: token,
- color: color,
- bold: bold
- }
- }).then(data => {
- console.log(data.data);
- show_alert('提示', data.data)
- });
- unsafeWindow.changeTag = tag =>
- request({
- url: host + '/api/user/changeTag',
- data: { token: token, tag: tag }
- }).then(data => {
- console.log(data.data);
- show_alert('提示', data.data)
- });
- unsafeWindow.newRoom = name =>
- request({
- url: host + '/api/room/new',
- data: { token: token, name: name }
- }).then(data => {
- if (data.status === 200)
- show_alert('提示', '创建成功。分区 id:' + data.data.id);
- else
- show_alert('提示', data.data);
- });
- unsafeWindow.addUser = (uid, id) =>
- request({
- url: host + `/api/room/${id || getFeedMode()}/addUser`,
- data: { token: token, uid: uid }
- }).then(data => {
- console.log(data.data);
- show_alert('提示', data.data)
- });
- unsafeWindow.delUser = (uid, id) =>
- request({
- url: host + `/api/room/${id || getFeedMode()}/delUser`,
- data: { token: token, uid: uid }
- }).then(data => {
- console.log(data.data);
- show_alert('提示', data.data)
- });
- unsafeWindow.userList = id =>
- request({
- url: host + `/api/room/${id || getFeedMode()}/info`,
- data: { token: token }
- }).then(data => {
- console.log(data.data.users.map(x => x.name));
- console.log(data.data.users);
- });
- function checkStatus() {
- request({
- url: host + '/api/auth/tokenStatus',
- data: { token: token }
- }).then(resp => {
- console.logresp;
- 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 = ${cur_uid = resp.data.user.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);
- };
- }
- }
- });
- }
- function addTagChanger() {
- $('#change-tag').click(() => {
- var tag = $('#tag-content')[0].value;
- changeTag(tag);
- });
- }
- async function addVersionChecker() {
- try {
- $('#version-info')[0].textContent = `当前版本:${GM_info.script.version} `;
- var latestScriptVersion = await request({
- url: host + '/api/misc/latestScriptVersion',
- data: {}
- });
- $('#version-info')[0].textContent += `最新版本:${latestScriptVersion.data} `;
- var backendVersion = await request({
- url: host + '/api/misc/backendVersion',
- data: {}
- });
- $('#version-info')[0].textContent += `后端版本:${backendVersion.data}`;
- } catch (e) { console.error(e); }
- }
- async function addFeedModeButton() {
- request({
- url: host + '/api/room/list',
- data: { token: token, mode: 'public' }
- }).then(data => {
- var node = $('#feedmode-selector')[0];
- if (data.status != 200) node.append(data.data);
- else
- for (var i of data.data) {
- node.append($(`
- <button class="am-btn am-btn-primary am-btn-sm" onclick="switchMode('pbenben-${i.id}')">${escapeHtml(i.name)}</button>`)[0]);
- node.append('\u00a0');
- }
- });
- var ownedRooms = new Set();
- await request({
- url: host + '/api/room/list',
- data: { token: token, mode: 'my' }
- }).then(data => {
- if (data.status === 200)
- for (var i of data.data)
- ownedRooms.add(JSON.stringify({ name: i.name, id: i.id }));
- });
- request({
- url: host + '/api/room/list',
- data: { token: token, mode: 'joined' }
- }).then(data => {
- var node = $('#joined-selector')[0];
- if (data.status != 200) node.append(data.data);
- else
- for (var i of data.data) {
- node.append($(`
- <button class="am-btn ${ownedRooms.has(JSON.stringify({ name: i.name, id: i.id })) ? 'am-btn-success' : 'am-btn-secondary'} am-btn-sm" onclick="switchMode('pbenben-${i.id}')">${escapeHtml(i.name)}</button>`)[0]);
- node.append('\u00a0');
- }
- });
- }
- const entityMap = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": ''',
- '/': '/',
- '`': '`',
- '=': '='
- };
- function escapeHtml(string) {
- return String(string).replace(/[&<>"'`=\/]/g, s => entityMap[s]);
- }
- function fmtDate(dt) {
- return `${dt.getFullYear().toString().padStart(4, '0')}-${(dt.getMonth() + 1).toString().padStart(2, '0')}-${dt.getDate().toString().padStart(2, '0')} ${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}`;
- }
- const modal_html = `
- <div class="am-modal am-modal-prompt" tabindex="-1" id="pbenben-prompt">
- <div class="am-modal-dialog">
- <div class="am-modal-hd" id="pbenben-alert-title"></div>
- <div class="am-modal-bd" id="pbenben-alert-message"></div>
- <div class="am-modal-footer">
- <span class="am-modal-btn" data-am-modal-cancel>取消</span>
- <span class="am-modal-btn" data-am-modal-confirm>确定</span>
- </div>
- </div>
- </div>`;
- unsafeWindow.show_prompt = function show_prompt(title, message, callback) {
- $('#pbenben-alert-title').html(title);
- $('#pbenben-alert-message').html(message);
- $('#pbenben-prompt').modal({
- onConfirm: callback
- });
- }
- function addConfirmModal() {
- document.body.append($(modal_html)[0]);
- }
- const status_html = `
- <h2>伪犇犇</h2>
- <span id="version-info">版本信息:N/A</span> <a href="https://gf.qytechs.cn/zh-CN/scripts/402550-pseudo-benben-tiger0132">项目链接</a>
- <a href="/paste/b22sy2nu">FAQ</a>
- <a href="https://pbb.akioi.ml/">独立站</a><br>
- <span>状态:<span id="pbenben-status">N/A</span>
- <button class="am-btn am-btn-primary am-btn-sm" id="benben-btn" style="visibility: hidden !important"></button></span><br>
- <div class="am-input-group am-input-group-primary am-input-group-sm"><input type="text" class="am-form-field" placeholder="tag 内容" id="tag-content"></div>
- <button class="am-btn am-btn-danger am-btn-sm" id="change-tag">修改</button><br>
- <div id="feedmode-selector">
- <button class="am-btn am-btn-primary am-btn-sm" onclick="switchMode('watching')">我关注的</button>
- <!--<button class="am-btn am-btn-primary am-btn-sm" onclick="switchMode('all')">全网动态</button>-->
- <button class="am-btn am-btn-primary am-btn-sm" onclick="switchMode('my')">我发布的</button>
- </div>
- <div id="joined-selector">
- </div>
- <small>
- 提示:第一次使用请按「生成 token」<br>
- 注:如果选中的是「我关注的」、「全网动态」(和「我发布的」),那么发送的内容就在原犇犇,反之亦然<br>
- 以及,tag 长度最多 10 个字,特殊字符会被过滤</small>
- `;
- function init() {
- if (!_feInstance.currentUser) {
- console.error('[Benben\'] Not logined!');
- return;
- }
- var node = document.createElement('div');
- node.className = 'lg-article';
- node.id = 'benben-status';
- node.innerHTML = status_html;
- document.querySelector('div.lg-index-benben > div:nth-child(2)').insertAdjacentElement('afterend', node);
- GM_addStyle(`.feed-comment p {margin-bottom: 0;} .feed-markdown {display: none;}`);
- checkStatus();
- injectPostFeed();
- // addColorSelector(); disabled
- // addFeedModeSelector(); deprecated
- addTagChanger();
- addVersionChecker();
- addFeedModeButton();
- addConfirmModal();
- }
- init();
- unsafeWindow.getToken = () => GM_getValue('benben_token');
- unsafeWindow.setToken = data => {
- GM_setValue('benben_token', token = data);
- checkStatus();
- };
- unsafeWindow.rmToken = () => {
- GM_deleteValue('benben_token');
- token = undefined;
- checkStatus();
- };
- unsafeWindow.setHost = data => GM_setValue('benben_host', data);
- unsafeWindow.getHost = () => GM_getValue('benben_host');
- unsafeWindow.rmHost = () => GM_deleteValue('benben_host');
- // 屏蔽器相关
- var ignoreList = GM_getValue('LuoguIgnoreList_v2', {});
- function getUid(name) { // 根据用户名反查 uid
- return new Promise((resolve, reject) => {
- $.get('/api/user/search?keyword=' + name, function (resp) {
- resolve(resp.users[0].uid);
- });
- });
- }
- function ignAdd(uid) {
- ignoreList[uid] = true;
- console.log(`[pLIE v2] added ${uid}`);
- GM_setValue('LuoguIgnoreList_v2', ignoreList);
- }
- function ignSet(data) {
- ignoreList = data;
- console.log(`[pLIE v2] success`);
- GM_setValue('LuoguIgnoreList_v2', ignoreList);
- }
- function ignDel(uid) {
- delete ignoreList[uid];
- console.log(`[pLIE v2] deleted ${uid}`);
- GM_setValue('LuoguIgnoreList_v2', ignoreList);
- }
- function ignQuery(uid) {
- return ignoreList[uid] || false;
- }
- function ignTog(uid) {
- console.log(`[pLIE v2] toggled ${uid}`);
- ignQuery(uid) ? ignDel(uid) : ignAdd(uid);
- }
- function ignShow() {
- return ignoreList;
- }
- function ignClear() {
- ignoreList = {};
- GM_setValue('LuoguIgnoreList_v2', ignoreList);
- }
- function id2uid_pack(callback) {
- return function (uid) {
- getUid(uid).then((resp) => console.log(callback(resp)));
- };
- }
- unsafeWindow.ignAdd = id2uid_pack(ignAdd);
- unsafeWindow.ignDel = id2uid_pack(ignDel);
- unsafeWindow.ignSet = id2uid_pack(ignSet);
- unsafeWindow.ignQuery = id2uid_pack(ignQuery);
- unsafeWindow.ignTog = id2uid_pack(ignTog);
- unsafeWindow.ignShow = ignShow;
- unsafeWindow.ignClear = ignClear;
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址