// ==UserScript==
// @name Bilibili Black Deque
// @version 0.0.6
// @namespace http://tampermonkey.net/
// @description Make blacklist of bilibili a deque
// @author Zxilly
// @source https://github.com/Zxilly/bili-black-deque
// @license https://opensource.org/licenses/MIT
// @match *://www.bilibili.com/*
// @require https://cdn.jsdelivr.net/npm/[email protected]
// ==/UserScript==
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ 242:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getBlackListCnt = getBlackListCnt;
const axios_1 = __importDefault(__webpack_require__(719));
function getBlackListCnt() {
return __awaiter(this, void 0, void 0, function* () {
const result = (yield axios_1.default.get('https://api.bilibili.com/x/relation/blacks', {
withCredentials: true
})).data;
return result.data.total;
});
}
/***/ }),
/***/ 449:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
const pop_1 = __webpack_require__(74);
const count_1 = __webpack_require__(242);
function manualRemove() {
return __awaiter(this, void 0, void 0, function* () {
let total = yield (0, count_1.getBlackListCnt)();
const uin = window.prompt(`现在黑名单有 ${total} 人,想移除:`);
if (uin === null) {
alert("必须输入一个整数");
return;
}
const deleteNum = Number.parseInt(uin);
if (Number.isNaN(deleteNum)) {
alert(`${uin} 不能被解释为合法整数`);
return;
}
if (deleteNum <= 0) {
alert("数字必须大于 0");
}
if (total < deleteNum) {
alert(`当前黑名单中的人数 ${total} 少于 ${deleteNum}`);
return;
}
yield (0, pop_1.popBlack)(deleteNum, total);
const current = yield (0, count_1.getBlackListCnt)();
alert(`处理完成,当前黑名单有 ${current} 人`);
});
}
function configureAndSet() {
return __awaiter(this, void 0, void 0, function* () {
let total = yield (0, count_1.getBlackListCnt)();
const uin = window.prompt(`当前黑名单有 ${total} 人,想保持在:`);
if (uin === null) {
alert("必须输入一个整数");
return;
}
const target = Number.parseInt(uin);
if (Number.isNaN(target)) {
alert(`${uin} 不能被解释为合法整数`);
return;
}
if (target <= 0) {
alert("数字必须大于 0");
}
if (target > total) {
console.warn(`当前黑名单中的人数 ${total} 少于 ${target}`);
}
localStorage.setItem(KEEP_TARGET, target.toString());
localStorage.removeItem(LAST_TASK_DATE);
yield task();
});
}
function task() {
return __awaiter(this, void 0, void 0, function* () {
const keepTarget = localStorage.getItem(KEEP_TARGET);
if (keepTarget === null) {
return;
}
const target = Number.parseInt(keepTarget);
if (Number.isNaN(target)) {
console.error(`target ${keepTarget} is not a number`);
return;
}
const lastTaskDate = localStorage.getItem(LAST_TASK_DATE);
const today = new Date().toDateString();
if (lastTaskDate === today) {
return;
}
let total = yield (0, count_1.getBlackListCnt)();
if (total > target) {
yield (0, pop_1.popBlack)(total - target, total);
}
localStorage.setItem(LAST_TASK_DATE, today);
});
}
document.addEventListener("keydown", (ev) => __awaiter(void 0, void 0, void 0, function* () {
if (ev.altKey && ev.key === "b") {
yield manualRemove();
}
if (ev.altKey && ev.key === "c") {
yield configureAndSet();
}
}));
const KEEP_TARGET = "keep-target";
const LAST_TASK_DATE = "last-task-date";
(() => __awaiter(void 0, void 0, void 0, function* () {
console.info("alt + b to run");
console.info("alt + c to set target");
yield task();
}))();
/***/ }),
/***/ 74:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.popBlack = popBlack;
const axios_1 = __importDefault(__webpack_require__(719));
const csrf_token = document.cookie.split('; ').find(row => row.startsWith('bili_jct')).split('=')[1];
function popBlack(num, total) {
return __awaiter(this, void 0, void 0, function* () {
const last_page = Math.ceil(total / 50);
const toRemove = [];
for (let current_page = last_page; current_page > 0; current_page--) {
const resp = (yield axios_1.default.get('https://api.bilibili.com/x/relation/blacks', {
params: {
ps: 20,
pn: current_page
},
withCredentials: true
})).data;
const list = resp.data.list;
list.reverse();
for (const user of list) {
const id = user['mid'];
toRemove.push(id);
if (toRemove.length >= num) {
break;
}
}
if (toRemove.length >= num) {
break;
}
}
console.log(JSON.stringify(toRemove));
console.log("收集完成,准备解除");
console.groupCollapsed("解除请求细节");
for (let id of toRemove) {
const params = new URLSearchParams();
params.append("fid", id);
params.append("csrf", csrf_token);
params.append("act", "6");
params.append("re_src", "116");
let retries = 3;
while (retries > 0) {
const resp = (yield axios_1.default.post("https://api.bilibili.com/x/relation/modify", params, {
withCredentials: true
})).data;
console.debug(JSON.stringify(resp));
if (resp.code === 0) {
break;
}
retries--;
console.log("限流中,等待2秒");
yield new Promise(r => setTimeout(r, 2000));
}
}
console.groupEnd();
});
}
/***/ }),
/***/ 719:
/***/ ((module) => {
module.exports = axios;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__(449);
/******/
/******/ })()
;