Greasy Fork is available in English.

BiliBili房管禁言一键续期

b站房管禁言一键续期

// ==UserScript==
// @name         BiliBili房管禁言一键续期
// @icon         https://www.bilibili.com/favicon.ico
// @namespace    https://greasyfork.org/zh-CN/users/412790-smoke-n-mirrors
// @version      1.1.0
// @description  b站房管禁言一键续期
// @author       Permission
// @include      /https?:\/\/live\.bilibili\.com\/\d/
// @require      https://code.jquery.com/jquery-3.4.1.min.js
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// ==/UserScript==

/* globals jQuery, $ */

let list = [], mesg = "", ban_hour = 720;
unsafeWindow.toast = (msg, type = 'info', timeout = 3e3) => {
    let d = new Date().toLocaleTimeString();
    switch (type) {
        case 'success':
        case 'info':
            console.info(`[${d}]${msg}`);
            break;
        case 'caution':
            console.warn(`[${d}]${msg}`);
            break;
        case 'error':
            console.error(`[${d}]${msg}`);
            break;
        default:
            type = 'info';
            console.log(`[${d}]${msg}`);
    }
    const a = $(`<div class="link-toast ${type} fixed"><span class="toast-text">${msg}</span></div>`)[0];
    document.body.appendChild(a);
    a.style.top = (document.body.scrollTop + list.length * 40 + 10) + 'px';
    a.style.left = (document.body.offsetWidth + document.body.scrollLeft - a.offsetWidth - 5) + 'px';
    list.push(a);
    setTimeout(() => {
        a.className += ' out';
        setTimeout(() => {
            list.shift();
            list.forEach((v) => {
                v.style.top = (parseInt(v.style.top, 10) - 40) + 'px';
            });
            $(a).remove();
        }, 200);
    }, timeout);
};

let csrf_token, visit_id;

var BilibiliAPI = {
    setCommonArgs: (csrfToken = '', visitId = '') => {
        csrf_token = csrfToken;
        visit_id = visitId;
    },
    Getblocklist: () => {
        return BilibiliAPI.ajax({
            url: `liveact/ajaxGetBlockList?roomid=${unsafeWindow.BilibiliLive.ROOMID}&page=1`
        });
    },
    Getuname: (uid) => {
        return BilibiliAPI.ajax({
            url: `banned_service/v2/Silent/search_user?search=${uid}`
        });
    },
    Getmsg: () => {
        return BilibiliAPI.ajax({
            url: `x/msgfeed/like?build=0&mobi_app=web`
        }, false);
    },
    checkIfIsAdmin: () => {
        return BilibiliAPI.ajax({
            url: `xlive/web-room/v1/index/getInfoByUser?room_id=${unsafeWindow.BilibiliLive.ROOMID}`
        });
    },
    // ajax调用B站API
    runUntilSucceed: (callback, delay = 0, period = 50) => {
        setTimeout(() => {
            if (!callback()) BilibiliAPI.runUntilSucceed(callback, period, period);
        }, delay);
    },
    processing: 0,
    ajax: (settings, g = true) => {
        if (settings.xhrFields === undefined) settings.xhrFields = {};
        settings.xhrFields.withCredentials = true;
        jQuery.extend(settings, {
            url: g ? ((settings.url.substr(0, 2) === '//' ? '' : '//api.live.bilibili.com/') + settings.url) : ((settings.url.substr(0, 2) === '//' ? '' : '//api.bilibili.com/') + settings.url),
            method: settings.method || 'GET',
            crossDomain: true,
            dataType: settings.dataType || 'json',
            timeout: 10e3,
            onerror: function () {
                unsafeWindow.toast("ajax 请求发生错误!", "error");
            }
        });
        const p = jQuery.Deferred();
        BilibiliAPI.runUntilSucceed(() => {
            if (BilibiliAPI.processing > 8) return false;
            ++BilibiliAPI.processing;
            return jQuery.ajax(settings).then((arg1, arg2, arg3) => {
                --BilibiliAPI.processing;
                p.resolve(arg1, arg2, arg3);
                return true;
            }, (arg1, arg2, arg3) => {
                --BilibiliAPI.processing;
                p.reject(arg1, arg2, arg3);
                return true;
            });
        });
        return p;
    },
    ajaxWithCommonArgs: (settings) => {
        if (!settings.data) settings.data = {};
        settings.data.csrf = csrf_token;
        settings.data.csrf_token = csrf_token;
        settings.data.visit_id = visit_id;
        return BilibiliAPI.ajax(settings);
    }
};
const getCookie = (name) => {
    let arr;
    const reg = new RegExp(`(^| )${name}=([^;]*)(;|$)`);
    if ((arr = document.cookie.match(reg))) {
        return unescape(arr[2]);
    } else {
        return null;
    }
};
let API = BilibiliAPI;

API.setCommonArgs(getCookie('bili_jct'), '');

function sleep(miliseconds) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve();
        }, miliseconds);
    });
}

async function Step(selector, callback) {
    while ($(selector).length === 0) {
        await sleep(100);
    }
    await sleep();
    callback(selector);
}

function Wait(selector) {
    return new Promise(resolve => {
        Step(selector, function (selector) {
            resolve($(selector));
        });
    });
}

function blackforever(q = 1) {
    if (!confirm("确定续期黑名单?")) {
        return 0;
    }
    try {
        var user_list = q ? [] : ((JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`)) === null || JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`))[unsafeWindow.BilibiliLive.ROOMID] == undefined) ? "0" : JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`))[unsafeWindow.BilibiliLive.ROOMID].split(","));
    }
    catch (e) {
        //只有一个的情况单独考虑
        //eslint-disable-next-line
        var user_list = []
        user_list[0] = JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`))[unsafeWindow.BilibiliLive.ROOMID];
    }
    if (user_list === "0") {
        unsafeWindow.toast(`存储中的黑名单数据为空`, `error`);
        return -1;
    }
    if (user_list.length === 0) {
        unsafeWindow.toast(`正在获取禁言列表...`, `info`);
        API.Getblocklist().then((response) => {
            let data = response.data;
            for (let t in data) {
                user_list.push(data[t].uid);
            }
            return user_list.length ? workBegin(q, user_list) : unsafeWindow.toast(`没有黑名单数据!`, `error`);
        });
    }
    else {
        workBegin(q, user_list);
    }
}

async function workBegin(q, user_list) {
    var working = user_list.length;
    if (q) {
        unsafeWindow.toast(`成功获取禁言列表!`, `success`);
        var user_id = [];
        let g = {};
        try {
            g = JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`)) || {};
        }
        catch (e) {
        }
        if (g[unsafeWindow.BilibiliLive.ROOMID]) {
            try {
                var current_list = g[unsafeWindow.BilibiliLive.ROOMID].split(",");
            }
            catch (e) {
                //eslint-disable-next-line
                var current_list = []
                current_list[0] = JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`))[unsafeWindow.BilibiliLive.ROOMID];
            }
            let pointer = 1;
            for (let i in user_list) {
                for (let m in current_list) {
                    pointer = 1;
                    if (current_list[m] == user_list[i]) {
                        pointer = 0;
                        break;
                    }
                }
                if (pointer) {
                    g[unsafeWindow.BilibiliLive.ROOMID] += "," + user_list[i];
                }
            }
        }
        else {
            for (let i in user_list) {
                if (i == 0) {
                    g[unsafeWindow.BilibiliLive.ROOMID] = user_list[i];
                }
                else {
                    g[unsafeWindow.BilibiliLive.ROOMID] += "," + user_list[i];
                }
            }
        }
        unsafeWindow.toast(`导入黑名单到存储成功!`, `success`);
        localStorage.setItem(`black_list${unsafeWindow.location.pathname}`, JSON.stringify(g));

        API.Getblocklist().then((response) => {
            let data = response.data;
            let uname_map = {};
            for (let t in data) {
                user_id.push(data[t].id);
                uname_map[data[t].id] = data[t].uname;
            }
            for (let i in user_id) {
                unsafeWindow.toast(`正在解禁第${parseInt(i) + 1}个用户,用户名:${uname_map[user_id[i]]}`, `info`);
                //解禁
                API.ajaxWithCommonArgs({
                    method: 'POST',
                    url: 'banned_service/v1/Silent/del_room_block_user',
                    data: {
                        id: user_id[i],
                        roomid: unsafeWindow.BilibiliLive.ROOMID
                    }
                    //eslint-disable-next-line
                }).then((res) => {
                    if (res.code !== 0) {
                        unsafeWindow.toast(`出错! ${res.msg}`, `error`);
                        return;
                    }
                    unsafeWindow.toast(`正在禁言第${parseInt(i) + 1}个用户,用户名:${uname_map[user_id[i]]}`, `info`);
                    //禁言
                    API.ajaxWithCommonArgs({
                        method: 'POST',
                        url: 'banned_service/v2/Silent/add_block_user',
                        data: {
                            roomid: unsafeWindow.BilibiliLive.ROOMID,
                            msg: mesg,
                            block_uid: user_list[i],
                            hour: ban_hour
                        }
                    }).then((res) => {
                        working--;
                        if (res.data.block_end_time != undefined) {
                            unsafeWindow.toast(`解封时间:${res.data.block_end_time} 用户名:${res.data.uname}`, `success`)
                        }
                        else {
                            unsafeWindow.toast(`${res.msg}`, `info`);
                        }
                    })
                })
            }
        })
    }

    else {
        let uname;
        for (let i in user_list) {
            if (user_list[i] === "") {
                continue;
            }
            //eslint-disable-next-line
            API.Getuname(user_list[i]).then((response) => {
                uname = response.data.items;
                uname = uname[0].uname;
                unsafeWindow.toast(`正在禁言第${parseInt(i) + 1}个用户,用户名:${uname}`, `info`);
                API.ajaxWithCommonArgs({
                    method: 'POST',
                    url: 'banned_service/v2/Silent/add_block_user',
                    data: {
                        roomid: unsafeWindow.BilibiliLive.ROOMID,
                        msg: mesg,
                        block_uid: user_list[i],
                        hour: ban_hour
                    }
                    //eslint-disable-next-line
                }).then((res) => {
                    if (res.data.block_end_time != undefined) {
                        unsafeWindow.toast(`解封时间:${res.data.block_end_time} 用户名:${res.data.uname}`, `success`)
                    }
                    else {
                        unsafeWindow.toast(`${res.msg}`, `info`);
                    }
                    working--;
                })
            })
        }
    }
    while (working != 0) {
        await sleep(100);
    }
    unsafeWindow.toast("操作完成", "info");
}

const importCloudBlacklist = async () => {
    var user_list = [];
    unsafeWindow.toast(`正在获取禁言列表...`, `info`);
    API.Getblocklist().then((response) => {
        let data = response.data;
        for (let t in data) {
            user_list.push(data[t].uid);
        }
        let g = {};
        try {
            g = JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`)) || {};
        }
        catch (e) {
        }
        var change = false;
        if (g[unsafeWindow.BilibiliLive.ROOMID]) {
            try {
                var current_list = g[unsafeWindow.BilibiliLive.ROOMID].split(",");
            }
            catch (e) {
                //eslint-disable-next-line
                var current_list = [];
                current_list[0] = JSON.parse(localStorage.getItem(`black_list${unsafeWindow.location.pathname}`))[unsafeWindow.BilibiliLive.ROOMID];
            }
            let pointer = 1;
            for (let i in user_list) {
                for (let m in current_list) {
                    pointer = 1;
                    if (current_list[m] == user_list[i]) {
                        pointer = 0;
                        break;
                    }
                }
                if (pointer) {
                    change = true;
                    g[unsafeWindow.BilibiliLive.ROOMID] += "," + user_list[i];
                    unsafeWindow.toast(`uid:${user_list[i]}`, `success`);
                }
            }
        }
        else {
            change = true;
            for (let i in user_list) {
                unsafeWindow.toast(`uid:${user_list[i]}`, `success`);
                if (i == 0) {
                    g[unsafeWindow.BilibiliLive.ROOMID] = user_list[i];
                }
                else {
                    g[unsafeWindow.BilibiliLive.ROOMID] += "," + user_list[i];
                }
            }
        }
        localStorage.setItem(`black_list${unsafeWindow.location.pathname}`, JSON.stringify(g));
        return user_list.length ? (!change ? unsafeWindow.toast("黑名单数据距上次没有增加", "caution") : (unsafeWindow.toast("导入黑名单到存储成功!", "success"))) : unsafeWindow.toast("没有黑名单数据!", "error");
    });
};

async function main() {
    GM_registerMenuCommand("功能用法请看脚本首页", () => {
        window.open("https://greasyfork.org/scripts/401854");
    });
    GM_registerMenuCommand("按照云端数据禁言续期", () => {
        checkParms();
        blackforever();
    });
    GM_registerMenuCommand("按照本地数据禁言续期", () => {
        checkParms();
        blackforever(0);
    });
    GM_registerMenuCommand("清空本地黑名单", () => {
        if (confirm("确定要清除存储中的黑名单数据吗?")) {
            localStorage.removeItem(`black_list${unsafeWindow.location.pathname}`);
            unsafeWindow.toast(`成功移除黑名单数据`, `success`);
        }
    });
    GM_registerMenuCommand("导入云端黑名单", () => {
        importCloudBlacklist();
    });
    GM_registerMenuCommand("重置禁言参数(理由和时长)", () => {
        localStorage.removeItem("bannedReason_4s77dsa");
        localStorage.removeItem("bannedTime_4s77dsa");
        checkParms();
    });
}

const checkParms = () => {
    if (localStorage.getItem("bannedReason_4s77dsa") == null) {
        localStorage.setItem("bannedReason_4s77dsa", window.prompt("请定义禁言理由(不设置理由请直接回车)"));
    }
    mesg = localStorage.getItem("bannedReason_4s77dsa");
    if (localStorage.getItem("bannedTime_4s77dsa") == null) {
        let time = parseInt(window.prompt("请设置禁言时长 (1 ~ 720) 单位: 小时"));
        while (isNaN(time) || time > 720 || time < 1) {
            time = parseInt(window.prompt(`禁言时间设置错误! 详细要求见脚本首页. 请重新设置禁言时长 (1 ~ 720) 单位: 小时`));
        }
        localStorage.setItem("bannedTime_4s77dsa", time);
    }
    ban_hour = localStorage.getItem("bannedTime_4s77dsa");
}

API.checkIfIsAdmin().then((response) => {
    if (response.data.badge.is_room_admin) {
        main();
    }
})