原神/明日方舟/王者荣耀玩家指示器(可扩展/全平台) - bilibili.com

2022/9/11 16:25:30

目前为 2022-09-12 提交的版本。查看 最新版本

// ==UserScript==
// @name        原神/明日方舟/王者荣耀玩家指示器(可扩展/全平台) - bilibili.com
// @namespace   Violentmonkey Scripts
// @match       https://*.bilibili.com/*
// @grant       none
// @version     1.10
// @author      fyb
// @description 2022/9/11 16:25:30
// @license MIT
// ==/UserScript==
(function () {
    const setting = {
        automatic: 0,//是否开启自动查询,开启后自动在用户名后显示成分,关闭后需要点击用户名后的按钮查询(0为关闭,1为开启)
        matchingDynamic: 1, //在动态里查询关键词(0为关闭,1为开启) 可与其他兼容
        matchingVideo: 0, //在视频标题简介里匹配关键词(0为关闭,1为开启)可与其他兼容
        matchingFollow: 0, //在关注列表里匹配关键词(0为关闭,1为开启)可与其他兼容
        matchingFollowPage: 2 //查询关注列表页数,一页50个,最多查询五页(1-5),需先开启matchingFollow
    }
    const match = [  //匹配规则,name为用户标签,color为显示标签的颜色,keyword为匹配关键词数组,follows为匹配关注列表数组
        {
            name: '[原神玩家]',
            color: "red",
            keyword: ['原神', '刻晴', '丘丘人', '雷电将军'],
            follows: ['原神']
        },
        {
            name: '[明日方舟玩家]',
            color: "orange",
            keyword: ['明日方舟'],
            follows: ['明日方舟']
        },
        {
            name: '[王者荣耀玩家]',
            color: "blue",
            keyword: ['王者荣耀'],
            follows: ['哔哩哔哩王者荣耀赛事']
        }
    ]
    let myCss = `
      .userComponentBtn{
      display:none;
      border:1px solid #fb7299;
      color:#fb7299;
      cursor:default;
      font-size:12px;
      line-height:16px;
      margin-left:5px;
      }
      .myCursor{
      cursor:pointer;
      }
      .toHover:hover .userComponentBtn{
      display:inline-block;
      }
`
    let css = document.createElement("style");
    css.innerHTML = myCss;
    document.body.appendChild(css);
    const bili_new = document.getElementsByClassName('comment-m-v1').length+document.getElementsByClassName('item goback').length != 0;
    console.log('原神/明日方舟/王者荣耀玩家指示器(可扩展/全平台)插件加载成功')
    const bili_dyn_url = 'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?&host_mid='
    const bili_video_url = 'https://api.bilibili.com/x/space/arc/search?mid='
    const bili_follow_url = 'https://api.bilibili.com/x/relation/followings?ps=50&pn='
    const isOk = new Set()
    const isAddBtn = new Set()
    const isPlayer = new Set()
    const bili_get_comment_list = () => {
        if (bili_new) {
            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 get_pid = (c) => {
        if (bili_new) {
            return c.dataset['userId']
        } else {
            return c.children[0]['href'].replace(/[^\d]/g, "")
        }
    }
    const addTag = (c, m) => {
        let toAppend = document.createElement("DIV");
        toAppend.style.color = m['color'];
        toAppend.style.display = 'inline-block'
        toAppend.innerHTML = m['name'];
        if (bili_new) {
            c.append(toAppend);
        } else {
            c.children[0].append(toAppend);
        }
    }
    const toMatchAll = (json, c) => {
        if (!isPlayer.has(c)) {
            match.forEach(m => {
                for (let i = 0; i < m['keyword'].length; i++) {
                    if (json.includes(m['keyword'][i])) {
                        addTag(c, m)
                        isPlayer.add(c)
                        break;
                    }
                }
            })
        }
    }
    const toMatchFollow = (json, c) => {
        if (!isPlayer.has(c)) {
            match.forEach(m => {
                for (let i = 0; i < json['data']['list'].length; i++) {
                    let a = m['follows'].filter((v) => json['data']['list'][i]['uname'] == v)
                    if (a.length != 0) {
                        addTag(c, m)
                        isPlayer.add(c)
                        break;
                    }
                }
            })
        }
    }
    const config = {
        attributes: true,
        childList: true,
        subtree: true
    };
    const queryUser = (c, sync) => {
        if (!isOk.has(c)) {
            isOk.add(c)
            let pid = get_pid(c);
            const xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    let json = JSON.stringify(JSON.parse(xhr.responseText))
                    toMatchAll(json, c)
                }
            }
            const xhrFollow = new XMLHttpRequest();
            xhrFollow.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    let json = JSON.parse(xhrFollow.responseText)
                    if (json['data'] == null) {
                        return;
                    }
                    toMatchFollow(json, c)
                }
            }
            if (setting.matchingDynamic == 1) {
                xhr.open('GET', bili_dyn_url + pid, sync)
                xhr.send()
            }
            if (setting.matchingVideo == 1) {
                xhr.open('GET', bili_video_url + pid, sync)
                xhr.send()
            }
            if (setting.matchingFollow == 1) {
                if (setting.matchingFollowPage >= 1 && setting.matchingFollowPage <= 5) {
                    for (let i = 1; i <= setting.matchingFollowPage; i++) {
                        xhrFollow.open('GET', bili_follow_url + i + '&vmid=' + pid, sync)
                        xhrFollow.send("CONTENT-TYPE", "application/json")
                    }
                }
            }
        }
        return;
    }
    const addQueryBtn = (c) => {
        if (!isAddBtn.has(c)) {
            isAddBtn.add(c);
            let toAppend = document.createElement("DIV");
            toAppend.innerHTML = '查成分'
            toAppend.className = 'userComponentBtn myCursor'
            toAppend.addEventListener("click", function () {
                let _this = this
                new Promise(function (resolve, reject) {
                    _this.innerHTML = '查询中'
                    resolve(queryUser(c, false));
                }).then(function () {
                    _this.innerHTML = '查询完毕'
                    _this.className = 'userComponentBtn'
                })
            })
            if (bili_new) {
                c.parentNode.parentNode.className += ' toHover';
                c.parentNode.append(toAppend);
            } else {
              c.className += ' toHover';
              c.insertBefore(toAppend,c.children[1]);
            }
        }
    }
    var bili_match = ['comment-list ', 'reply-box']
    const callback = function (mutationsList, observer) {
        for (let mutation of mutationsList) {
            if (mutation.type === 'childList') {
                for (let q = 0; q < bili_match.length; q++) {
                    if (mutation.target.className.toString() == bili_match[q]) {
                        console.log("评论增加");
                        let bgcl = bili_get_comment_list()
                        if (setting.automatic == 0) {
                            bgcl.forEach(c => {
                                addQueryBtn(c);
                            });
                        }
                        if (setting.automatic == 1) {
                            bgcl.forEach(c => {
                                queryUser(c, true)
                            });
                            break;
                        }
                    }
                }
            }
        }
    }
    const observer = new MutationObserver(callback);
    if (window.location.pathname.indexOf('video') != -1) {
        console.log("当前为视频页面")
        if (!bili_new) {
            observer.observe(document.body, config);
        } else {
            bili_match = ['reply-list', 'sub-reply-list'];
            observer.observe(document.body, config);
        }
    }
    if (window.location.hostname.indexOf('space') != -1 || window.location.hostname.indexOf('t.bilibili.com') != -1) {
        console.log("当前为动态页面")
        bili_match = ['comment-list has-limit', 'reply-box'];
        observer.observe(document.body, config);
    }
})();

QingJ © 2025

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