Greasy Fork

Greasy Fork is available in English.

BGM小组信息加密工具

null

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         BGM小组信息加密工具
// @namespace    http://tampermonkey.net/
// @version      1.7
// @author       Sedoruee
// @match        https://bgm.tv/group/topic/*
// @match        https://bangumi.tv/group/topic/*
// @match        https://chii.in/group/topic/*
// @description null
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @require      https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Target elements and replacement text
    const elementsToHide = [
        { selector: '.ico_reply.ico', replacement: '解密后不支持回复楼层' },
        { selector: 'div.action:nth-of-type(4)', replacement: '' }
    ];


    function hideElementsAndReplace() {
        elementsToHide.forEach(item => {
            const elements = document.querySelectorAll(item.selector);
            elements.forEach(element => {
                const replacement = document.createElement('span');
                replacement.textContent = item.replacement;
                replacement.style.color = 'red'; // Optional: Style the replacement text
                element.parentNode.replaceChild(replacement, element);
            });
        });
    }


    // Run the function when the page loads and also when the DOM changes
    const observer = new MutationObserver(hideElementsAndReplace);
    observer.observe(document.body, { childList: true, subtree: true });

    //Initial execution for elements already present on load
    hideElementsAndReplace();

})();

(function() {
    'use strict';

    const defaultKeys = {
        "bangumi": "默认密钥",
        "sedoruee": "Sedoruee"
    };

    let keys = GM_getValue('keys', defaultKeys);
    let currentKey = GM_getValue('currentKey', "bangumi");
    let decryptionEnabled = GM_getValue('decryptionEnabled', true); // Track decryption state

    // 加密/解密函数 (使用 AES)
    function encrypt(text, key) { return CryptoJS.AES.encrypt(text, key).toString(); }
    function decrypt(ciphertext, key) {
        try { return CryptoJS.AES.decrypt(ciphertext, key).toString(CryptoJS.enc.Utf8); }
        catch (e) { return null; }
    }

    // 自动解密
    function autoDecryptPage() {
        const encryptedRegex = /\[加密\](.*?)\[topic409567\]/g;
        document.body.innerHTML = document.body.innerHTML.replace(encryptedRegex, (match, p1) => {
            if (decryptionEnabled) { // Only decrypt if enabled
                for (const key in keys) {
                    const decryptedText = decrypt(p1, key);
                    if (decryptedText) return decryptedText;
                }
            }
            return match; // 解密失败保留原文
        });
    }

    function createButtons() {
        const submitBtn = document.querySelector('#submitBtnO');
        if (!submitBtn) return;

        // 密钥选择下拉框
        const keySelect = document.createElement('select');
        for (const key in keys) {
            const option = document.createElement('option');
            option.value = key;
            option.text = keys[key];
            if (key === currentKey) option.selected = true;
            keySelect.appendChild(option);
        }
        keySelect.addEventListener('change', () => {
            currentKey = keySelect.value;
            GM_setValue('currentKey', currentKey);
        });

        // 加密按钮
        const encryptBtn = document.createElement('button');
        encryptBtn.innerText = '加密';
        encryptBtn.style.marginLeft = '10px';
        encryptBtn.addEventListener('click', (event) => {
            event.preventDefault();
            const contentTextarea = document.querySelector('#content');
            if (contentTextarea) {
                const encryptedText = '[加密]' + encrypt(contentTextarea.value, currentKey) + '[topic409567]';
                contentTextarea.value = encryptedText;
            }
        });

        // 添加密钥按钮
        const addKeyBtn = document.createElement('button');
        addKeyBtn.innerText = '添加密钥';
        addKeyBtn.style.marginLeft = '10px';
        addKeyBtn.addEventListener('click', () => {
            let newKeyInput = prompt("请输入新的密钥和备注,以|分隔 (例如: mykey|我的密钥):");
            if (newKeyInput) {
                let [newKey, newKeyDesc] = newKeyInput.split("|");
                if (!newKey) return alert("密钥不能为空!");
                newKey = newKey.trim();
                newKeyDesc = (newKeyDesc || newKey).trim();
                keys[newKey] = newKeyDesc;
                GM_setValue('keys', keys);
            }
        });

        // 删除密钥按钮
        const deleteKeyBtn = document.createElement('button');
        deleteKeyBtn.innerText = '删除密钥';
        deleteKeyBtn.style.marginLeft = '10px';
        deleteKeyBtn.addEventListener('click', () => {
            let keyToDelete = prompt("请输入要删除的密钥:", currentKey);
             if (keyToDelete && keys[keyToDelete]) {
                if (confirm(`确定要删除密钥 ${keys[keyToDelete]} (${keyToDelete}) 吗?`)) {
                   delete keys[keyToDelete];
                   GM_setValue('keys', keys);
                   if (keyToDelete === currentKey) { // 如果删除的是当前密钥,则重置为默认密钥
                       currentKey = "bangumi";
                       GM_setValue('currentKey', currentKey);
                   }
                   location.reload(); // 刷新页面
                }
             } else {
                alert("密钥不存在!");
             }
        });


        // 解密切换按钮
        const toggleDecryptBtn = document.createElement('button');
        toggleDecryptBtn.innerText = decryptionEnabled ? '隐藏解密' : '显示解密';
        toggleDecryptBtn.style.marginLeft = '10px';
        toggleDecryptBtn.addEventListener('click', () => {
            decryptionEnabled = !decryptionEnabled;
            GM_setValue('decryptionEnabled', decryptionEnabled);
            toggleDecryptBtn.innerText = decryptionEnabled ? '隐藏解密' : '显示解密';
            autoDecryptPage(); // Redo decryption based on new state
            document.body.classList.toggle('show-replies', decryptionEnabled); // Toggle CSS class
        });

        // 插入按钮
        submitBtn.parentNode.insertBefore(keySelect, submitBtn.nextSibling);
        submitBtn.parentNode.insertBefore(encryptBtn, keySelect.nextSibling);
        submitBtn.parentNode.insertBefore(addKeyBtn, encryptBtn.nextSibling);
        submitBtn.parentNode.insertBefore(deleteKeyBtn, addKeyBtn.nextSibling);
        submitBtn.parentNode.insertBefore(toggleDecryptBtn, deleteKeyBtn.nextSibling);
    }

    // 页面加载时执行
    window.addEventListener('load', () => {
        autoDecryptPage();
        createButtons();

        // Add CSS to hide replies
        const style = document.createElement('style');
        style.textContent = `
            body:not(.show-replies) .ico_reply.ico {
                display: none !important;
            }
        `;
        document.head.appendChild(style);

        //Initial state of reply visibility
        document.body.classList.toggle('show-replies', decryptionEnabled);
    });

})();