仙家军成分查询Helper

用于标记仙家军和动态转发仙以及使用仙话术的b站用户。可能存在误伤,请注意辨别。脚本改自【糊狸-B站成分查询Helper】

目前为 2023-09-10 提交的版本。查看 最新版本

// ==UserScript==
// @name         仙家军成分查询Helper
// @namespace    www.bilibili.com
// @version      1.4
// @description  用于标记仙家军和动态转发仙以及使用仙话术的b站用户。可能存在误伤,请注意辨别。脚本改自【糊狸-B站成分查询Helper】
// @author       Darknights
// @match        https://*.bilibili.com/*
// @exclude      https://message.bilibili.com/*
// @icon         https://static.hdslb.com/images/favicon.ico
// @connect      bilibili.com
// @connect      fastly.jsdelivr.net
// @connect      raw.githubusercontent.com
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @license      MIT
// @run-at       document-end
// ==/UserScript==

'use strict';

/* 配置区 */
const config = {
    urlSource: 1, // 0:githubusercontent, 1:jsdelivr
    times: 2500, // 标签处理间隔时间 单位:ms
    testLog: 0 // 是否开启调试日志。0:不开启,1:开启
}
// 显示标签配置在👇面

var xianList;
var xianFavList;
var xianWordList;

//以下为本地名单,可以自行添加
// 大部分为仙,少部分为其他成分但也跑到别游评论区贩过剑,极少数可能有误判
const localXianList = [];

// 转发者常见仙的,包含且不限于米吹/被仙死缠烂打的人等等
const localXianFavList = [];

// 仙可能会用的词汇
const localXianWordList = [];

// 辅助,因为有些正则匹配返回值为空
const aidList = ['响指', '瘴'];

const xianTag = ["目标:仙", "#11DD77"];

const xianSmellTag = ["转发仙:", "#1E971E"];

const xianFavTag = ["转发:", "#2C9EFF"];

const xianWordTag = ["仙语:", "#04AEAB"];

const apiTag = ["出错,请点此验证", "#FF3434"];

const blog = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?&host_mid=';


const recordMap = new Map();

const uidSet = new Set();



const log = function (message) {
    return config.testLog ? console.log(message) : null;
};

const spawnHtml = function (data) {
    return `<a style='color: ${data[1]} !important' target='_blank'>&lt;${data[0]}&gt;</b>`;
}

const spawnApiHtml = function (data) {
    return `<a style='color: ${data[1]} !important' href='https://space.bilibili.com/208259/dynamic' target='_blank'>&lt;${data[0]}&gt;</b>`;
}

const spawnHtmlWithStrRef = function (data, word, link) {
    return `<a style='color: ${data[1]} !important' href='https://t.bilibili.com/${link}' target='_blank'>&lt;${data[0]}${word}&gt;</b>`;
}

const getxianListUrl = function () {
    switch (config.urlSource) {
        case 0:
            return "https://raw.githubusercontent.com/Darknights1750/XianLists/main/xianLists.json";
        case 1:
        default:
            return "https://fastly.jsdelivr.net/gh/Darknights1750/XianLists@main/xianLists.json";
    }
};

// 检测是不是新版
const isNew = function () {
    if (document.getElementsByClassName('item goback').length != 0) {
        return true;
    }
    if (document.getElementsByClassName('app-v1').length != 0) {
        return true;
    }
    if (document.getElementsByClassName('opus-detail').length != 0) {
        return true;
    }
    return false;
};

const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));

function getXianListOnline() {
    return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
            method: "GET",
            url: getxianListUrl(),
            data: '',
            headers: {
                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
            },
            onload: res => {
                if (res.status === 200) {
                    resolve(JSON.parse(res.responseText));
                } else {
                    resolve(JSON.parse('{"xianList":[],"xianFavList":[],"xianWordList":[]}'));
                }
            }
        });
    });
}

async function fillLists() {
    let json = await getXianListOnline();
    xianList = [...localXianList, ...json.xianList];
    xianFavList = [...localXianFavList, ...json.xianFavList];
    let xianWordStrList = [...localXianWordList, ...json.xianWordList];
    xianWordList = xianWordStrList.map((item) => new RegExp(item));
    // log(xianWordList);
}

async function start() {
    await fillLists();
    runHelper();
}

function runHelper() {

    /* Functions */
    const getUid = function (htmlEntity) {
        if (isNew()) {
            return htmlEntity.children[0].dataset.userId;
        } else {
            return htmlEntity.children[0].href.replace(/[^\d]/g, "");
        }
    }

    const getName = function (htmlEntity) {
        if (isNew()) {
            return htmlEntity.innerText;
        } else {
            return htmlEntity.children[0].innerText;
        }
    }

    const getCommentList = function () {
        if (isNew()) {
            let lst = new Set();
            for (let c of document.getElementsByClassName('user-info')) {
                lst.add(c);
            }
            for (let c of document.getElementsByClassName('sub-user-info')) {
                lst.add(c);
            }
            return lst;
        } else {
            return document.getElementsByClassName('user');
        }
    }

    const smell = function (items) {
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            for (var key in item) {
                if (key == 'orig') {
                    var origId = String(item.orig.modules.module_author.mid);
                    if (xianList.indexOf(origId) > -1) {
                        var origName = String(item.orig.modules.module_author.name);
                        var link = String(item.id_str);
                        return [origId, origName, link];
                    }
                }
            }
        }
        return null;
    }

    const smellFav = function (items) {
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            for (var key in item) {
                if (key == 'orig') {
                    var origId = String(item.orig.modules.module_author.mid);
                    if (xianFavList.indexOf(origId) > -1) {
                        var origName = String(item.orig.modules.module_author.name);
                        var link = String(item.id_str);
                        return [origId, origName, link];
                    }
                }
            }
        }
        return null;
    }

    const hearAid = function (text) {
        for (var word of aidList) {
            var matchRes = text.match(word);
            if (matchRes != null) {
                return matchRes[0];
            }
        }
    }

    const hear = function (text) {
        for (var word of xianWordList) {
            var matchRes = text.match(word);
            if (matchRes != null) {
                var matchStr = matchRes[0];
                if (matchStr == '') {
                    matchStr = hearAid(text);
                }
                return matchStr;
            }
        }
        return null;
    }

    const hearWord = function (items) {
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            var ownMatch;
            var ownFullText;
            if (item.modules.module_dynamic.topic != null) {
                ownFullText += item.modules.module_dynamic.topic.name;
            }
            if (item.modules.module_dynamic.desc != null) {
                ownFullText += item.modules.module_dynamic.desc.text;
            }
            if (item.modules.module_dynamic.major != null && item.modules.module_dynamic.major.archive != null) {
                ownFullText += item.modules.module_dynamic.major.archive.title;
                ownFullText += item.modules.module_dynamic.major.archive.desc;
            }
            if (item.modules.module_dynamic.additional != null && item.modules.module_dynamic.additional.ugc != null) {
                ownFullText += item.modules.module_dynamic.additional.ugc.title;
            }
            if (ownFullText != null) {
                ownMatch = hear(ownFullText);
                if (ownMatch != null) {
                    return [ownMatch, String(item.id_str)];
                }
            }
            for (var key in item) {
                var origMatch;
                var origFullText;
                if (key == 'orig') {
                    if (item.orig.modules.module_dynamic.topic != null) {
                        origFullText += item.orig.modules.module_dynamic.topic.name;
                    }
                    if (item.orig.modules.module_dynamic.desc != null) {
                        origFullText += item.orig.modules.module_dynamic.desc.text;
                    }
                    if (item.orig.modules.module_dynamic.major != null && item.orig.modules.module_dynamic.major.archive != null) {
                        origFullText += item.orig.modules.module_dynamic.major.archive.title;
                        origFullText += item.orig.modules.module_dynamic.major.archive.desc;
                    }
                    if (origFullText != null) {
                        origMatch = hear(origFullText);
                        if (origMatch != null) {
                            return [origMatch, String(item.id_str)];
                        }
                    }
                }
            }
        }
        return null;
    }


    const checkRecord = async function (uid, name) {
        let oldTag;
        if (recordMap.has(uid)) {
            oldTag = recordMap.get(uid);
            uidSet.delete(uid);
            if (oldTag) {
                log('>>record:' + name + '@UID' + uid + '_find:' + oldTag.replaceAll(/<\/?a.*?>/g, "").replaceAll(/&gt;&lt;/g, "、").replaceAll(/&.t;/g, ""));
            }
        } else if (uidSet.has(uid)) {
            await sleep(500);
            oldTag = checkRecord(uid, name);
        } else {
            uidSet.add(uid);
        }
        return oldTag;
    }

    log('isNew:' + isNew());
    log("Loading...");

    setInterval(() => {
        const commentlist = getCommentList();
        if (commentlist.length != 0) {
            commentlist.forEach(async htmlEntity => {
                if (htmlEntity.innerHTML.indexOf(`<span id="huli">`) == -1) {
                    htmlEntity.innerHTML += `<span id="huli">`;
                    const uid = getUid(htmlEntity);
                    const name = getName(htmlEntity);
                    let oldTag = await checkRecord(uid, name);

                    if (oldTag != null) {
                        htmlEntity.innerHTML += oldTag;
                    } else {
                        GM_xmlhttpRequest({
                            method: "get",
                            url: blog + uid,
                            data: '',
                            headers: {
                                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
                            },
                            onload: res => {
                                if (res.status === 200) {
                                    var newTag = '';
                                    if (xianList.indexOf(uid) > -1) {
                                        log('>>target:' + name + '@UID' + uid);
                                        newTag += spawnHtml(xianTag);
                                    }
                                    const dynamicJson = JSON.parse(res.response).data;
                                    if (dynamicJson) {
                                        if (dynamicJson.items) {
                                            var origMsg = smell(dynamicJson.items);
                                            if (origMsg != null) {
                                                log('>>smell:' + name + '@UID' + uid + '_repost:' + origMsg[1] + '@UID' + origMsg[0]);
                                                newTag += spawnHtmlWithStrRef(xianSmellTag, origMsg[1], origMsg[2]);
                                            }
                                            var hearMatch = hearWord(dynamicJson.items);
                                            if (hearMatch != null) {
                                                log('>>hear:' + name + '@UID' + uid + '_say:' + hearMatch[0]);
                                                var fixedText = hearMatch[0];
                                                if (fixedText.length > 15) {
                                                    fixedText = fixedText.slice(0, 12) + '...';
                                                }
                                                newTag += spawnHtmlWithStrRef(xianWordTag, fixedText, hearMatch[1]);
                                            }
                                            var favOrigMsg = smellFav(dynamicJson.items);
                                            if (favOrigMsg != null) {
                                                log('>>tips:' + name + '@UID' + uid + '_repost:' + favOrigMsg[1] + '@UID' + favOrigMsg[0]);
                                                newTag += spawnHtmlWithStrRef(xianFavTag, favOrigMsg[1], favOrigMsg[2]);
                                            }
                                        }
                                        htmlEntity.innerHTML += newTag;
                                        recordMap.set(uid, newTag);
                                    } else {
                                        htmlEntity.innerHTML += spawnApiHtml(apiTag);
                                    }
                                } else {
                                    log('Fail...');
                                    log(res);
                                }
                            },
                        });
                    }
                    htmlEntity.innerHTML += `</span>`;
                }
            });
        }
    }, config.times);
}

start();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址