Greasy Fork

Greasy Fork is available in English.

pseudo-Benben - tiger0132

qwq

目前为 2020-05-13 提交的版本。查看 最新版本

// ==UserScript==
// @name         pseudo-Benben - tiger0132
// @namespace    https://oj.akioi.ml:8200/
// @version      1.0.4
// @description  qwq
// @author       tiger0132
// @match        https://*.luogu.com.cn/
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// ==/UserScript==

(function () {
	'use strict';

	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 = `<a style="cursor: pointer">伪犇犇</a>`;

	// var origLoadFeed = unsafeWindow.loadFeed;
	function origLoadFeed() {
		$.get("/feed/" + feedMode + "?page=" + feedPage, function (resp) {
			$feed.append(resp);
			$("#feed-more").children("a").text("点击查看更多...")
			$("[name=feed-delete]").click(function () {
				$.post("/api/feed/delete/" + $(this).attr('data-feed-id'), function () {
					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: function (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 => {
			$feed.append(resp.data);
			$('#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(`<option value="qwq">请选择颜色</option>`);
			var arr = JSON.parse(resp.data);
			for (var i of arr) {
				var d = JSON.parse(i);
				btn.append(`<option style="color: ${d.color};${d.bold ? ' font-weight: bold;' : ''}" value="${escapeHtml(i)}">${d.color}</option>`);
			}
		});

		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 未验证&nbsp;';
					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($(`
<button class="am-btn am-btn-primary am-btn-sm" onclick="switchMode('pbenben-${i.id}')">${i.name}</button>`)[0]);
					node.append('\u00a0');
				}
			}
		});
	}

	const entityMap = {
		'&': '&amp;',
		'<': '&lt;',
		'>': '&gt;',
		'"': '&quot;',
		"'": '&#39;',
		'/': '&#x2F;',
		'`': '&#x60;',
		'=': '&#x3D;'
	};
	function escapeHtml(string) {
		return String(string).replace(/[&<>"'`=\/]/g, s => entityMap[s]);
	}

	const status_html = `
<h2>伪犇犇</h2>
<span id="version-info">版本信息:N/A</span>&nbsp;<a href="http://greasyfork.icu/zh-CN/scripts/402550-pseudo-benben-tiger0132">项目链接</a>&nbsp;
<a href="https://www.luogu.com.cn/paste/flnvmy64">FAQ</a><br>
<span>状态:<span id="pbenben-status">N/A</span>&nbsp;
<button class="am-btn am-btn-primary am-btn-sm" id="benben-btn" style="visibility: hidden !important"></button></span><br>
颜色选取:<select id="name-selector"></select>&nbsp;<button class="am-btn am-btn-primary am-btn-sm" id="change-color">修改颜色</button><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>
<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);
		// document.getElementById('switch-btn').onclick = function () {
		// 	sendMode ^= 1;
		// 	this.textContent = sendMode ? '切换到原犇犇' : '切换到伪犇犇';
		// };

		checkStatus();
		injectPostFeed();
		addColorSelector();
		// addFeedModeSelector(); deprecated
		addTagChanger();
		addVersionChecker();
		addFeedModeButton();
	}
	init();

	// unsafeWindow.verifyToken = verifyToken;
	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);

	// console.log(`benben_token: ${GM_getValue('benben_token')}`);
	// if (!GM_getValue('benben_token')) {
	// 	verifyToken();
	// }
})();