Bilibili Comment UID Reader

Read UIDs from Bilibili comments

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Bilibili Comment UID Reader
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Read UIDs from Bilibili comments
// @author       You
// @match        *https://www.bilibili.com/video*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
const sidebarCss = `
#customSidebar {
    position: fixed;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    z-index: 1000;
    background-color: white;
    padding: 10px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    display: flex;
    flex-direction: column;
}
`;

const styleElement = document.createElement('style');
styleElement.type = 'text/css';
styleElement.appendChild(document.createTextNode(sidebarCss));
document.head.appendChild(styleElement);

const sidebar = document.createElement('div');
sidebar.id = 'customSidebar';
document.body.appendChild(sidebar);

const displayUsersBtn = document.createElement('button');
displayUsersBtn.innerText = '显示所有用户及其组别';
displayUsersBtn.onclick = displayAllUsersAndGroups;
sidebar.appendChild(displayUsersBtn);
sidebar.appendChild(document.createElement('br')); 

const clearGroupsBtn = document.createElement('button');
clearGroupsBtn.innerText = '清除所有组';
clearGroupsBtn.onclick = function() { clearSpecificGroup(null); };
sidebar.appendChild(clearGroupsBtn);
sidebar.appendChild(document.createElement('br'));

const clearAllBtn = document.createElement('button');
clearAllBtn.innerText = '完全清除';
clearAllBtn.onclick = clearAllData;
sidebar.appendChild(clearAllBtn);
    const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        mutation.addedNodes.forEach(function(node) {
            if (node.nodeType === 1 && node.classList.contains('user-info')) {
                addSpecialAttentionButton(node.querySelector('.user-name'));
            }
            else if (node.nodeType === 1) {
const userInfoElements = node.querySelectorAll('.user-info .user-name');
userInfoElements.forEach(userInfoElement => {
    const userId = userInfoElement.getAttribute('data-user-id');
    const userName = userInfoElement.textContent;
    addSpecialAttentionButton(userInfoElement, userId, userName);
});
            }
        });
    });
});

observer.observe(document.body, { childList: true, subtree: true });
    function addSpecialAttentionButton(userInfoElement, userId, userName) {
    const { currentGroupName } = getUserCurrentGroup(userId);

    let groupIndicator;
    if (currentGroupName) {
        groupIndicator = document.createElement('span');
        groupIndicator.textContent = `组别: ${currentGroupName}`;
        groupIndicator.style.border = '1px solid black';
        groupIndicator.style.padding = '2px';
        userInfoElement.parentNode.insertBefore(groupIndicator, userInfoElement.nextSibling);
    }
    const buttonText = currentGroupName ? '更改关注组' : '特别关注';
    const specialAttentionButton = document.createElement('button');
    specialAttentionButton.textContent = buttonText;
    userInfoElement.parentNode.appendChild(specialAttentionButton);

    specialAttentionButton.addEventListener('click', function() {
const groupSelect = document.getElementById('group-select-' + userId);
        if (groupSelect && groupSelect.style.display !== 'none') {
            const groupName = groupSelect.value;
            if (groupName) {
                addUserToGroup(userId, userName, groupName);
                groupSelect.style.display = 'none';
                document.getElementById('new-group-input-' + userId).style.display = 'none';
                document.getElementById('add-group-btn-' + userId).style.display = 'none';
            } else {
                alert('请选择一个组,或创建一个新组!');
            }
        } else {
            showGroupSelect(userInfoElement, userId, userName);
        }
        if (groupIndicator) {
            groupIndicator.textContent = `组别: ${groupSelect.value}`;
        }
    });
}
function getUserCurrentGroup(userId) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    for (const [groupName, users] of Object.entries(groups)) {
        const userInGroup = users.find(user => user.userId === userId);
        if (userInGroup) {
            return { currentGroupName: groupName };
        }
    }
    return { currentGroupName: null };
}

function updateGroupSelect(select) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    select.innerHTML = '<option value="">请选择一个组...</option>';
    select.innerHTML += '<option value="无组别">无组别</option>';

    Object.keys(groups).forEach(groupName => {
        const option = document.createElement('option');
        option.value = groupName;
        option.textContent = groupName;
        select.appendChild(option);
    });
}

function showGroupSelect(userNameDiv, userId, userName) {
    let existingSelect = document.getElementById('group-select-' + userId);
    if (existingSelect) {

        return;
    }

    let select = document.getElementById('group-select-' + userId) || document.createElement('select');
    select.id = 'group-select-' + userId;
    select.style.display = ''; 

    let newGroupInput = document.getElementById('new-group-input-' + userId) || document.createElement('input');
    newGroupInput.id = 'new-group-input-' + userId;
    newGroupInput.style.display = '';

    let addGroupBtn = document.getElementById('add-group-btn-' + userId);
if (!addGroupBtn) {
    addGroupBtn = document.createElement('button');
    addGroupBtn.id = 'add-group-btn-' + userId;
    addGroupBtn.textContent = '新增组类别'; 
    userNameDiv.parentNode.appendChild(addGroupBtn); 
}
addGroupBtn.style.display = ''; 
    updateGroupSelect(select);
    userNameDiv.parentNode.appendChild(select);
    userNameDiv.parentNode.appendChild(newGroupInput);
    userNameDiv.parentNode.appendChild(addGroupBtn);
    addGroupBtn.addEventListener('click', function() {
        const newGroupName = newGroupInput.value.trim();
        if (newGroupName) {
            addNewGroup(newGroupName);
            newGroupInput.value = '';
            updateGroupSelect(select);
        } else {
            alert('组名不能为空!');
        }
    });
}

function addNewGroup(groupName) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    if (groups[groupName]) {
        alert('该组已存在!');
        return;
    }
    groups[groupName] = [];
    localStorage.setItem('userGroups', JSON.stringify(groups));
    alert(`新组 "${groupName}" 已成功创建。`);
}
function displayAllUsersAndGroups() {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    let message = '所有用户及其组别:\n';

    for (const [groupName, users] of Object.entries(groups)) {
        users.forEach(({ userId, userName }) => { 
            message += `用户名: ${userName}, 用户ID: ${userId}, 组别: ${groupName}\n`;
        });
    }

    alert(message);
}

    function clearAllData() {
    const isConfirmed = confirm("确定要完全清除所有数据吗?这将包括所有用户的特别关注组信息。");

    if (isConfirmed) {
        localStorage.removeItem('userGroups');
        alert("所有数据已被成功清除。");
    }
}
function addUserToGroup(userId, userName, groupName) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    Object.keys(groups).forEach(group => {
        groups[group] = groups[group].filter(user => user.userId !== userId);
    });
    if (groupName !== "无组别") {
        if (!groups[groupName]) {
            groups[groupName] = [];
        }
        const isUserInGroup = groups[groupName].some(user => user.userId === userId);
        if (!isUserInGroup) {
            groups[groupName].push({ userId, userName });
        }
    }
    localStorage.setItem('userGroups', JSON.stringify(groups));
    alert(`用户 ${userName} (${userId}) 的组别已更新。`);
}

    function clearSpecificGroup(groupNameToClear) {
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    if (groupNameToClear && groups[groupNameToClear]) {
        if (!groups['臨時組']) groups['臨時組'] = [];
        groups['臨時組'] = groups['臨時組'].concat(groups[groupNameToClear]);
        delete groups[groupNameToClear];
    } else if (!groupNameToClear) {
        groups['臨時組'] = [];
        for (const groupName in groups) {
            if (groupName !== '臨時組') {
                groups['臨時組'] = groups['臨時組'].concat(groups[groupName]);
                delete groups[groupName];
            }
        }
    }

    localStorage.setItem('userGroups', JSON.stringify(groups));
    displayAllUsersAndGroups();
}
document.getElementById('add-group-btn').addEventListener('click', function() {
    const groupName = document.getElementById('new-group-name').value.trim();
    if (!groupName) {
        alert('關注組名稱不能為空!');
        return;
    }
    const groups = JSON.parse(localStorage.getItem('userGroups')) || {};
    if (groups[groupName]) {
        alert('該關注組已存在!');
        return;
    }
    groups[groupName] = [];
    localStorage.setItem('userGroups', JSON.stringify(groups));
    document.getElementById('new-group-name').value = '';
    updateGroupSelect();
});
    document.getElementById('assign-group-btn').addEventListener('click', function() {
        const uid = document.getElementById('user-uid').value;
        const groupName = document.getElementById('group-select').value;
    });
    updateGroupSelect();
})();