Greasy Fork

Greasy Fork is available in English.

仙家军成分查询Helper

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

当前为 2023-07-27 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

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


(function () {
    'use strict';

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

    // 大部分为仙,少部分为其他成分但也跑到别游评论区贩过剑,极少数可能有误判
    const xianList = ['2626308','91294717','691660481','594265974','1399233488','201128149','492233743','1384853937','193242084','59212436','1547943832','355829734','439010078','3493110134868545','289739171','455857213','559989730','252864981','595397699','1825148722','300313419','2142529765','333755368','372672537','366752296','628918703','359762403','449254922','27748754','1397451482','435429250','293497224','87355702','1080954745','1005732624','353381701','3493146415598203','36832623','298253160','3493109944027757','1459252016','626718713','3493128606583732','1413259326','3493108211780104','288608355','398268451','527079387','1705910990','2072727585','19227977','8118856710','1986311121','273627979','322540587','3493264994863124','1436392582','3493122713586530','503354352','3493267740035490','3461576510147287','643362376','55417546','3493282594163167','20617055','3461564359248624','388317005','2029973237','543283877','599439268','937235','259851861','511355405','37660844','524480956','375074321','87296302','44952669','172725229','1369696284','389007','589755766','4947574','394067676','499866803','35612911','10453721','3493295195949740','1134025725','1350039692','442716028','1044725703','36579529','1677221329','5765492','1691881192','86520669','525706751','353839591','1113890768','3461574566086858','111339218','1531330351','662110818','3461574433966081','1770158437','646116461','2112612559','3494349983714230','3493080227383503','626139499','408443934','503777492','490811664','3493120108923438','1861056960','161537754','3493260081236751','3493123518892834','3493281459604332','1055982250','97156738','549164139','572103170','19767091','17426743','26144732','3493104510306572','20668227','310739216','38134752','2086415808','24370011','227711','341345864','131686171','1215911548','518890959','361110695','343483727','22356679','1500447686','382322597','1652444369','1379468139','700334419','1920077601','629636812','342625887','1999783629','1521899960','1250227139','1035834480','515953856','1269661366','1580057','342504730','492886360','322003546','402337847','509967955','545157646','46700199','393185198','330060938','1773068006','3493292132010608','2049417456','421415625','1901385718','1299712856','184834562','323316289','592098805','3493130307373585','3493283921660585','497749570','38669319','1886920878','3493128552057316','158409499','592716471','41500446','259073912','12763949','244195965','539194895','3493258432874938','185340617','3494352779217234','522203755','327726586','1727271882','36487502','338875111','3493257564654426','1920025624','2139759349','524487767','544543545','1924967026','179842197','1420029844','442412268','102046074','495136626','407011914','36451416','1790581737','1297044734','511375871','454444045','44118648','108124076','1025261779','238768745','454549461','188592371','495962652','396474607','89156315','11485934','1515887582','95185631','431370017','1590385783','107454145','36608252','406945605','3493261545048989','18207363','39146080','128154158','1980544130','676066921','3493272863377880','490806240','3494353609689164','3493116193540136','227608286','516810524','406295394','513207733','397766990','385510829','474230029','1081849613','275361832','439632100','386219932','18736476','104186483','277899630','471878098','111381478','50736064','8666108','1362431770','26115845','32722773','13403990','84463540','350354084','405415031','1991965567','298351534','413328287','522577702','81621195','1095759525','503706427','292414916','669537029','2060377372','482356860','1590744061','1376192084','396361992','471334531','345588161','338768507','35153977','367372614','411665360','677159875','1849036165','344981454','32851127','701978114','209529040','454823096','1618928982','3461575383976728','3349819','14366695','3493131985095171','92331223','3493298123573685','298117775','18751756','1444457374','1574664405','3493261085772646','436507166','1420968986','688466259','3493282797586906','187557328','1867867671','36932461','191992559','144401850','475217623','1111554919','624827700','25158006','686687499','1156704720','297838241','66599005','43854759','1603367507','14090853','519007354','3493083834485551','23015716','3493298899520216','615801484','1853984270','1410981905','447667064','1768232056','180315490','17483142','237674610','290486440','145867269','501151562','1394280381','262396227','2059564611','158464755','27337034','329070265','616230238','2623651','673469590','348788153','1334481839','94245663','364102169','443561230','9001961','14226237','367118584','1715063749','26402698','85611225','175842498','293040191','92377304','661406541','291722117','456461013','511285113','40385074','157701945','313553430','3461573989369955','699620788','400288459','1684941132','126798519','243709167','343182646','267633883','7882572','44111012','642283332','2041358736','452923927','450766160','435962591','1260137194','392716813','2080471657','6094118','471121310','41140492','32342920','3494361308334195','289950036','66521033','1982084352','694375176','437547128','452995986','698512554','521791224','553607033','1279206852','1078139271','627276122','507602655','351536044','574438986','1498581388','1953930621','351580155','2021919256','122393280','170726627','1987518644','3493114608093916','534814839','241338402','324930510','247906722','3493258577578528','526758551','1224611104','1629086717','470295121','1015769484','442674135','102780343','1864259475','1433898519','1545949280','344317205','521772035','50188349','433369591','589722708','554455561','55435191','1380528208','475906798','544882','668713461','1505750441','515330','1734911','2016568835','157542864','518335325','24828163','514659409','294978697','349917619','32702015','103821769','271813086','602144428','435906846','299872036','137526919','194166500','691281033','407073386','1241635077','190855152','263175839','526504511','510313973','28602017','10896289','1087076583','692144492','336167197','1095385996','399371277','1223531535','2618049','1582683418','202193533','398264373','701712713','80858222','449547891','30568443','1889880416','475608878','20560179','255826495','254145929','1099986072','698515024','88853595','402903760','374934613','1685666556','61203105','688529392','392510301','3493076987284155','3494366586865673','408458332','3493297729309011','1825148722','379345446','3493135845952424','3494357707524620','498210343','3493277441460803','693926725','220281114','3461568727616374','432297452','1492050671','254595253','3494366528145719','509968352','22838437','349394738','398105453','16467858','3493142600878179','64503605','32279378','2010571111','1812362081','619944324','3493136946956989','131708205','349765241','26124997','482556024','388693260','491268656','1483421493','168018648','2106733812','1169988691','379029828','1369589264','4043797','589950799','95342921','351822906','1941043685','15476586','353230533','473451416','161106598','1879025877','171327152','3493297746086665','2101187526','1910752327','14910694','3493268704725181','27537451','3461568146705343','1379177398','272080366','411568407','40635142','1638081136','1917159403','3494371223669667','439011736','1182243305','1839449242','517358498','1564406324','1651183436','3494366528145719','1436095759','352206267','1498739542','3493087477238164','649666880','1589745057','339783856','646745965','1783539871','129039354','1381567229','549754464','113102036','668467168','23969569','8982','690042974','5913670','436934472','28393728','1176168756','3493142082882094','3493262037879556','1216415487','690187287','3494349667043797','570169874','2054508615','1299593753','3494367025171334','3493280140495629','443222017','3178205','38087587','150562754','486260217','394714817','','','',''];

    // 转发者常见仙的,包含且不限于米吹/被仙死缠烂打的人等等
    const xianFavList=['179948458','39112946','487361449','3493133841074718','349983685','17603188','503949833','3493086401399030','32187114','37948216','262975601','406097135','1903716905','22283556','3196602','1443474511','3493080149789014','1608427646','3493284112501484','3791966','13632597','485671402'];

    // 主祭,但都合流了好像也没必要区分
    const jiList = ['676066921', '3493272863377880', '490806240', '3494353609689164'];

    // 仙可能会用的词汇
    const xianWordList = ['1234', '3412', '枘凿六合', '镀金旅团','牛肉泡面', /(手磨|手工|手调|手游|买量|横幅|联动)(咖啡|仙人)/, /(?=.*笑哭)(?=.*响指)/, '仙家', '仙驱', '仙庭', '仙不灭', '散去吧', '(不是|是不)好惹的','怎么你了', /[周粥舟皱塞赛][处÷➗除畜批皮pP翁]/, '利刃', '[原|o|O]婴', /[宦幻]官/, '孝战', '镍币人', /@(欢愉|智识|丰饶|巡猎|毁灭|虚无|均衡|存护|同谐|贪饕|追忆|薪炎|贝洛伯格|朋克洛德|不朽星神|绝灭大君|尘冥将军|假面愚者|千人律者|巡海游侠|米社|全自动|仙舟|仙家|仙驱|先驱|天华SRSH|诸天|QM|原牌芭|纯白神教|Yishiki|星穹列车|米可nya)/, /(百分百|100%)参团/, /(鹰|婴|ying?|舟|粥|周|皱|猴)(游社|ga|GA|站|乎)/,/尸[场厂游批Pp]/, /霜星(焚化|高尔夫|骨灰|碎|尸|石|十)/, /(纸|卡|小人|立绘).*?[对碰撞].*?[碰撞]/, /[4四]字游戏/, '美洲大蠊', /(大蠊|蟑螂|高蛋白|蛋白质)(饼干|巧克力)/, '半壁江山', '硬核不媚', /龙门(开盒|独立)/, '烂穿地心', '百万塞尔达', /([(\(][)\)]?){4}?/, /屠夫[钩勾√]子/, '裹尸袋', /(?=.*(海拉|火把|任天堂))(?=.*瘴)/,'吸瘴', '51522','十猴九粥','冥日','花粥',/[反返][原米崩]雅士/,/(铁道|崩铁|星铁).*[五5]天/];

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

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

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

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

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

    const apiTag = ["api限制", "#FF3434"];

    const recordMap = new Map();

    const uidSet = new Set();


    /* Functions */
    const getUid = function (htmlEntity) {
        if (isNew()) {
            return htmlEntity.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-name')) {
                lst.add(c);
            }
            for (let c of document.getElementsByClassName('sub-user-name')) {
                lst.add(c);
            }
            return lst;
        } else {
            return document.getElementsByClassName('user');
        }
    }

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

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

    const spawnHtmlWithStr = function (data, word) {
        return `<b style='color: ${data[1]}' >&lt;${data[0]}${word}&gt;</b>`
    }

    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);
                        return [origId, origName];
                    }
                }
            }
        }
        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);
                        return [origId, origName];
                    }
                }
            }
        }
        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);
                }
                if (matchStr.length > 15) {
                    matchStr = '*文本过长*';
                }
                return matchStr;
            }
        }
        return null;
    }

    const hearWord = function (items) {
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            if (item.modules.module_dynamic.desc != null) {
                var ownText = item.modules.module_dynamic.desc.text;
                var ownMatch = hear(ownText);
                if (ownMatch != null) {
                    return ownMatch;
                }
            }
            for (var key in item) {
                if (key == 'orig' && item.orig.modules.module_dynamic.desc != null) {
                    var origText = item.orig.modules.module_dynamic.desc.text;
                    var origMatch = hear(origText);
                    if (origMatch != null) {
                        return origMatch;
                    }
                }
            }
        }
        return null;
    }

    const blog = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?&host_mid=';
    // 检测是不是新版
    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));

    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(/<\/?b.*?>/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 += spawnHtmlWithStr(xianSmellTag, origMsg[1]);
                                            }
                                            var hearMatch = hearWord(dynamicJson.items);
                                            if (hearMatch != null) {
                                                log('>>hear:' + name + '@UID' + uid + '_say:' + hearMatch);
                                                newTag += spawnHtmlWithStr(xianWordTag, hearMatch);
                                            }
                                            var favOrigMsg = smellFav(dynamicJson.items);
                                            if (favOrigMsg != null) {
                                                log('>>tips:' + name + '@UID' + uid + '_repost:' + favOrigMsg[1] + '@UID' + favOrigMsg[0]);
                                                newTag += spawnHtmlWithStr(xianFavTag, favOrigMsg[1]);
                                            }
                                        }
                                        htmlEntity.innerHTML += newTag;
                                        recordMap.set(uid, newTag);
                                    } else {
                                        htmlEntity.innerHTML += spawnHtml(apiTag);
                                    }
                                } else {
                                    log('Fail...');
                                    log(res);
                                }
                            },
                        });
                    }
                    htmlEntity.innerHTML += `</span>`;
                }
            });
        }
    }, config.times);
})();