Youtube直播独轮车-随机独轮车-自动融入

YouTube直播独轮车,随机独轮车,自动融入

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Advertisement:

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

Advertisement:

// ==UserScript==
// @name         Youtube直播独轮车-随机独轮车-自动融入
// @description  YouTube直播独轮车,随机独轮车,自动融入
// @namespace    http://tampermonkey.net/
// @version      2026-07-18-838
// @author       奶糖花的绿冻兄弟
// @match https://www.youtube.com/watch*
// @match https://www.youtube.com/live_chat*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        GM_setValue
// @grant        GM_addValueChangeListener
// @grant GM_setValue
// @grant GM_getValue
// @license      MIT
// ==/UserScript==


(function() {
    'use strict';


    if (location.pathname === "/watch") {


        const observer = new MutationObserver(() => {

            if (document.querySelector("ytd-live-chat-frame")) {

                observer.disconnect();

                const panel = createPanel();

                createToggle(panel);

            }

        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });

    }

    if (location.pathname === "/live_chat") {

        AutoIntegrate();

        const videoId = new URL(document.referrer).searchParams.get("v");

        console.log("YTID="+videoId);
        GM_addValueChangeListener("SM2RR"+videoId, (name, oldValue, newValue) => {
            sendMessageToRealChatRoom(newValue.msg);
        });
    }

    function createToggle(panel){

        const toggleBtn = document.createElement("button");

        toggleBtn.textContent = "独";
        toggleBtn.style.display = "flex";
        toggleBtn.style.justifyContent = "center"; // 水平居中
        toggleBtn.style.alignItems = "center";// 垂直居中
        toggleBtn.style.position = "fixed";
        toggleBtn.style.right = "0px";
        toggleBtn.style.bottom = "5px";
        toggleBtn.style.width = "20px";
        toggleBtn.style.height = "25px";
        toggleBtn.style.cursor = "pointer";
        toggleBtn.style.backgroundColor = "red";
        toggleBtn.style.zIndex = 999999;
        toggleBtn.style.display = "flex";

        toggleBtn.onclick = () => {

            if (panel.style.display === "none") {
                panel.style.display = "flex"
            }else{
                panel.style.removeProperty("left");
                panel.style.removeProperty("top");

                panel.style.right = "20px";
                panel.style.bottom = "35px";
            }

        };


        document.body.appendChild(toggleBtn);

    }

    function createPanel(){
        const Panel = document.createElement("div");
        Panel.style.position = "fixed";
        Panel.style.right = "20px";
        Panel.style.bottom = "35px";
        Panel.style.width = "350px";
        Panel.style.background = "#222";
        Panel.style.color = "white";
        Panel.style.padding = "0px";
        Panel.style.borderRadius = "0px";
        Panel.style.display = "none";
        Panel.style.flexDirection = "column";
        Panel.style.zIndex = 999999;

        const TopRow = document.createElement("div");
        TopRow.style.display = "flex";
        TopRow.style.width = "100%";

        const title = document.createElement("div");
        title.textContent = "YouTube DLC";
        title.style.cursor = "move";
        title.style.padding = "8px";
        title.style.background = "red";
        title.style.flex = "0.9";

        const btnHide = document.createElement("button");
        btnHide.textContent = "-";
        btnHide.style.flex = "0.1";

        btnHide.onclick = () => {

            Panel.style.display = "none";

        };

        TopRow.append(title, btnHide);

        Panel.prepend(TopRow);

        //panel move

        let dragging = false;
        let offsetX = 0;
        let offsetY = 0;

        const mask = document.createElement("div");
        mask.style.position = "fixed";
        mask.style.left = "0";
        mask.style.top = "0";
        mask.style.width = "100vw";
        mask.style.height = "100vh";
        mask.style.zIndex = "999998";
        mask.style.background = "transparent";

        title.addEventListener("pointerdown", (e) => {

            document.body.appendChild(mask);
            dragging = true;

            const rect = Panel.getBoundingClientRect();

            // 转换为 left/top 定位
            Panel.style.left = rect.left + "px";
            Panel.style.top = rect.top + "px";

            Panel.style.right = "auto";
            Panel.style.bottom = "auto";

            offsetX = e.clientX - rect.left;
            offsetY = e.clientY - rect.top;

            e.preventDefault();
        });


        document.addEventListener("pointermove", (e) => {

            if (!dragging) return;

            Panel.style.left = (e.clientX - offsetX) + "px";
            Panel.style.top = (e.clientY - offsetY) + "px";

        });


        document.addEventListener("pointerup", () => {

            dragging = false;

            mask.remove();
        });

        //






        const pageDlc= createDlcUI();

        const pageRandomDlc = createRandomDlcUI();

        const pageAutoInteragte = creatAutoIntegrateUI();

        const menu = createMenuUI(pageDlc,pageRandomDlc,pageAutoInteragte);

        Panel.appendChild(menu);

        Panel.appendChild(pageDlc);
        Panel.appendChild(pageRandomDlc);
        Panel.appendChild(pageAutoInteragte);



        document.body.appendChild(Panel);

        return Panel;
    }

    function createMenuUI(page1,page2,page3){
        const menu = document.createElement("div");
        menu.style.padding = "10px 10px 5px 10px";
        menu.style.display = "flex";
        menu.style.borderBottom = "1px solid #555";

        const btnDLC = document.createElement("button");
        btnDLC.textContent = "独轮车";

        const btnAuto = document.createElement("button");
        btnAuto.textContent = "随机独轮车";

        const btnAutoIntegrate = document.createElement("button");
        btnAutoIntegrate.textContent = "自动融入";

        [btnDLC, btnAuto, btnAutoIntegrate].forEach(btn => {

            btn.style.flex = "1";// 平分宽度
            btn.style.padding = "8px";
            btn.style.cursor = "pointer";

        });

        btnDLC.onclick = () => {
            showPage(page1,page2,page3);
        };

        btnAuto.onclick = () => {
            showPage(page2,page1,page3);
        };

        btnAutoIntegrate.onclick = () => {
            showPage(page3,page2,page1);
        };


        menu.append(btnDLC, btnAuto, btnAutoIntegrate);

        return menu;
    }

    function createDlcUI() {
        //panel
        const pageDLC = document.createElement("div");
        pageDLC.style.padding = "5px 10px 10px 10px";
        pageDLC.style.display = "flex";
        pageDLC.style.flexWrap = "wrap";

        const input = document.createElement("input");

        input.type = "text";
        input.placeholder = "输入弹幕";

        input.style.width = "100%";
        input.style.padding = "10px";
        input.style.boxSizing = "border-box";

        pageDLC.appendChild(input);

        const button = document.createElement("button");
        button.textContent = "发送";
        button.style.padding = "10px";
        button.style.cursor = "pointer";
        button.style.width = "100%";
        pageDLC.appendChild(button);
        //
        const inputStyle = document.createElement("style");

        inputStyle.textContent = `input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button {display: none;}`;
        document.head.appendChild(inputStyle);

        const CDinput = document.createElement("input");
        CDinput.type = "number";
        CDinput.style.padding = "10px";
        CDinput.placeholder = "冷却秒数";
        CDinput.min = 0.01;
        CDinput.max = 100000;
        CDinput.style.minWidth = "0";

        const DLCbutton = document.createElement("button");
        DLCbutton.textContent = "独轮车启动";
        DLCbutton.style.padding = "10px";
        DLCbutton.style.cursor = "pointer";

        const row = document.createElement("div");
        row.style.display = "flex";
        row.style.width = "100%";

        CDinput.style.width = "30%";
        DLCbutton.style.width = "70%";


        row.append(CDinput, DLCbutton);

        pageDLC.appendChild(row);
        //
        button.onclick = () => {
            const videoId = new URLSearchParams(location.search).get("v");
            GM_setValue("SM2RR"+videoId, { msg: input.value, time: Date.now() });
        };

        let timer = null;

        DLCbutton.onclick = () => {

            const value = CDinput.valueAsNumber;

            if (Number.isNaN(value)) {
                return;
            }

            if (timer) {
                // 已经在运行,不重复启动
                clearInterval(timer);
                timer = null;
                DLCbutton.textContent = "独轮车启动";
                DLCbutton.style.backgroundColor = "white";
                return;
            }


            DLCbutton.textContent = "独轮车启动中";
            DLCbutton.style.backgroundColor = "red";
            const videoId = new URLSearchParams(location.search).get("v");
            GM_setValue("SM2RR"+videoId, { msg: input.value, time: Date.now() });

            timer = setInterval(() => {

                console.log("T发送");
                GM_setValue("SM2RR"+videoId, { msg: input.value, time: Date.now() });

            }, CDinput.value*1000); // 每 * 秒发送一次

        };

        return pageDLC;
    }

    function createRandomDlcUI() {

        const groups = [ ["组一随机一", "组一随机二","组一随机三"], ["组二随机一", "组二随机二", "组二随机三"], ["组三随机一", "组三随机二", "组三随机三"] ];


        const page = document.createElement("div");
        page.style.display = "none";
        page.style.flexDirection = "column";
        page.style.gap = "10px";
        page.style.padding = "10px";

        function createRow() {

            const row = document.createElement("div");
            row.style.display = "flex";
            row.style.gap = "8px";
            row.style.alignItems = "center";

            const select = document.createElement("select");
            select.style.flex = "1";
            select.style.flex = "1";
            select.style.minWidth = "0";// 允许缩小,不会被内容撑开
            select.style.width = "0";// 配合 flex 使用
            select.style.textAlign = "left";// 文字靠左

            const addBtn = document.createElement("button");
            addBtn.textContent = "新增";

            const delBtn = document.createElement("button");
            delBtn.textContent = "删除当前";

            row.append(select, addBtn, delBtn);

            return {
                row,
                select,
                addBtn,
                delBtn
            };
        }

        function refreshGroupItems(selectC, group) {

            selectC.options.length = 0;

            group.forEach((item, index) => {

                let text;

                if (item === "") {
                    text = "(空)";
                } else if (item.length > 10) {
                    text = item.slice(0, 10) + "...";
                } else {
                    text = item;
                }

                selectC.add(new Option(text, index));
            });


        }

        function refreshGrops(selectG, selectC, groups) {

            selectG.options.length = 0;
            selectC.options.length = 0;

            // 填充组
            groups.forEach((group, index) => {
                selectG.add(new Option(`组 ${index + 1}`, index));
            });

        }

        function InitGrops(selectG, selectC, groups) {

            selectG.options.length = 0;
            selectC.options.length = 0;

            // 填充组
            groups.forEach((group, index) => {
                selectG.add(new Option(`组 ${index + 1}`, index));
            });

            // 默认显示第一组
            refreshGroupItems(selectC, groups[0]);

        }




        // 第一行
        const row1 = createRow();



        // 第二行
        const row2 = createRow();

        row1.select.onchange = () => {
            refreshGroupItems(row2.select, groups[row1.select.selectedIndex]);
        };

        InitGrops(row1.select, row2.select, groups);

        // 第三行
        const textarea = document.createElement("textarea");
        textarea.placeholder = "请输入内容...";
        textarea.style.width = "100%";
        textarea.style.height = "50px";
        textarea.style.resize = "vertical";
        textarea.style.boxSizing = "border-box";

        page.append(row1.row,row2.row,textarea);

        const CDinput = document.createElement("input");
        CDinput.type = "number";
        CDinput.style.padding = "10px";
        CDinput.placeholder = "冷却秒数";
        CDinput.min = 0.01;
        CDinput.max = 100000;
        CDinput.style.minWidth = "0";

        const DLCbutton = document.createElement("button");
        DLCbutton.textContent = "独轮车启动";
        DLCbutton.style.padding = "10px";
        DLCbutton.style.cursor = "pointer";

        const DLCrow = document.createElement("div");
        DLCrow.style.display = "flex";
        DLCrow.style.width = "100%";

        CDinput.style.width = "30%";
        DLCbutton.style.width = "70%";


        DLCrow.append(CDinput, DLCbutton);

        page.appendChild(DLCrow);



        row1.addBtn.onclick = () => {

            groups.push([""]);

            refreshGrops(row1.select, row2.select, groups);

            row1.select.selectedIndex = groups.length - 1;

            refreshGroupItems(row2.select, groups[row1.select.selectedIndex]);
            // 自动选中新建的组


        };

        row2.addBtn.onclick = () => {

            const groupIndex = row1.select.selectedIndex;
            if (groupIndex < 0) return;

            // 新增一个空字符串
            groups[groupIndex].push("");

            // 刷新第二个下拉框
            refreshGroupItems(row2.select, groups[groupIndex]);

            // 自动选中新建项
            row2.select.selectedIndex = groups[groupIndex].length - 1;

            // 清空编辑框
            textarea.value = "";

            // 聚焦到输入框
            textarea.focus();
        };

        row2.select.onchange = () => {

            const groupIndex = Number(row1.select.value);
            const msgIndex = Number(row2.select.value);

            textarea.value = groups[groupIndex][msgIndex];


        };

        textarea.oninput = () => {

            const groupIndex = Number(row1.select.value);
            const msgIndex = Number(row2.select.value);

            if (groups[groupIndex] && groups[groupIndex][msgIndex] !== undefined) {
                groups[groupIndex][msgIndex] = textarea.value;
            }

            row2.select.options[msgIndex].text = textarea.value.slice(0, 10);
        };

        row1.delBtn.onclick = () => {

            const groupIndex = row1.select.selectedIndex;

            if (groupIndex < 0) return;

            groups.splice(groupIndex, 1);

            refreshGrops(row1.select, row2.select, groups);

            if (groups.length > 0) {
                row1.select.selectedIndex = Math.min(groupIndex, groups.length - 1);
                refreshGroupItems(row2.select, groups[row1.select.selectedIndex]);
            } else {
                row2.select.innerHTML = "";
                textarea.value = "";
            }
        };

        row2.delBtn.onclick = () => {

            const groupIndex = row1.select.selectedIndex;
            const itemIndex = row2.select.selectedIndex;

            if (groupIndex < 0 || itemIndex < 0) return;

            // 从数组删除
            groups[groupIndex].splice(itemIndex, 1);

            // 刷新第二个下拉框
            refreshGroupItems(row2.select, groups[groupIndex]);

            // 清空 textarea(如果已经没有内容)
            if (groups[groupIndex].length === 0) {
                textarea.value = "";
            } else {
                // 重新选中一项
                row2.select.selectedIndex = Math.min(itemIndex, groups[groupIndex].length - 1);
                textarea.value = groups[groupIndex][row2.select.selectedIndex];
            }
        };


        let timer = null;
        DLCbutton.onclick = () => {

            const value = CDinput.valueAsNumber;

            if (Number.isNaN(value)) {
                return;
            }

            if (timer) {
                // 已经在运行,不重复启动
                clearInterval(timer);
                timer = null;
                DLCbutton.textContent = "独轮车启动";
                DLCbutton.style.backgroundColor = "white";
                return;
            }


            DLCbutton.textContent = "独轮车启动中";
            DLCbutton.style.backgroundColor = "red";
            const videoId = new URLSearchParams(location.search).get("v");
            GM_setValue("SM2RR"+videoId, { msg: groups[row1.select.selectedIndex][Math.floor(Math.random() * groups[row1.select.selectedIndex].length)], time: Date.now() });

            timer = setInterval(() => {

                console.log("DLC发送"+groups[row1.select.selectedIndex][Math.floor(Math.random() * groups[row1.select.selectedIndex].length)]);
                GM_setValue("SM2RR"+videoId, { msg: groups[row1.select.selectedIndex][Math.floor(Math.random() * groups[row1.select.selectedIndex].length)], time: Date.now() });

            }, CDinput.value*1000); // 每 * 秒发送一次

        };

        return page;
    }

    function creatAutoIntegrateUI(){
/*      const page = document.createElement("div");
        page.style.display = "none";
        page.style.flexDirection = "column";
        page.style.gap = "10px";
        page.style.padding = "10px";

        const headCountinput = document.createElement("input");
        headCountinput.type = "number";
        headCountinput.style.padding = "10px";
        headCountinput.placeholder = "人数";
        headCountinput.min = 0.01;
        headCountinput.max = 100000;
        headCountinput.style.minWidth = "0";

        const chatCountinput = document.createElement("input");
        chatCountinput.type = "number";
        chatCountinput.style.padding = "10px";
        chatCountinput.placeholder = "重复";
        chatCountinput.min = 0.01;
        chatCountinput.max = 100000;
        chatCountinput.style.minWidth = "0";

        const timeLimitInput = document.createElement("input");
        timeLimitInput.type = "number";
        timeLimitInput.style.padding = "10px";
        timeLimitInput.placeholder = "时限";
        timeLimitInput.min = 0.01;
        timeLimitInput.max = 100000;
        timeLimitInput.style.minWidth = "0";

        const CDinput = document.createElement("input");
        CDinput.type = "number";
        CDinput.style.padding = "10px";
        CDinput.placeholder = "冷却";
        CDinput.min = 0.01;
        CDinput.max = 100000;
        CDinput.style.minWidth = "0";

        const AuItbutton = document.createElement("button");
        AuItbutton.textContent = "自动融入启动";
        AuItbutton.style.padding = "10px";
        AuItbutton.style.cursor = "pointer";

        const AuItrow = document.createElement("div");
        AuItrow.style.display = "flex";
        AuItrow.style.width = "100%";

        headCountinput.style.width = "15%";
        chatCountinput.style.width = "15%";
        timeLimitInput.style.width = "15%";
        CDinput.style.width = "15%";

        AuItbutton.style.width = "40%";

        AuItrow.append(headCountinput,chatCountinput,timeLimitInput,CDinput, AuItbutton);

        page.appendChild(AuItrow);*/

        const page = document.createElement("div");
        page.style.display = "none";
        page.style.flexDirection = "column";
        page.style.gap = "10px";
        page.style.padding = "10px";

        const row1 = document.createElement("div");
        row1.style.display = "flex";
        row1.style.alignItems = "center";
        row1.style.width = "100%";
        row1.style.gap = "5px";

        const row2 = document.createElement("div");
        row2.style.display = "flex";
        row2.style.alignItems = "center";
        row2.style.width = "100%";
        row2.style.gap = "5px";

        function createInput(placeholder) {
            const input = document.createElement("input");
            input.type = "number";
            input.style.padding = "5px";
            input.placeholder = placeholder;
            input.min = 0.01;
            input.max = 100000;
            input.style.width = "70px";
            return input;
        }

        function text(content) {
            const span = document.createElement("span");
            span.textContent = content;
            return span;
        }

        const headCountinput = createInput("");
        headCountinput.style.width = "25px";
        const timeLimitInput = createInput("");
        timeLimitInput.style.width = "25px";
        const chatCountinput = createInput("");
        chatCountinput.style.width = "25px";
        const CDinput = createInput("");
        CDinput.style.width = "25px";


        row1.append(
            text("触发:"),
            headCountinput,
            text("人在"),
            timeLimitInput,
            text("秒内重复"),
            chatCountinput,
            text("次")
        );

        row2.append(
            text("自动融入冷却"),
            CDinput,
            text("秒")
        );

        const AuItbutton = document.createElement("button");
        AuItbutton.textContent = "自动融入启动";
        AuItbutton.style.padding = "10px";
        AuItbutton.style.cursor = "pointer";


        page.append(row1, row2,AuItbutton);

        let AuItstatus = false;
        AuItbutton.onclick = () => {

            const videoId = new URLSearchParams(location.search).get("v");

            if(!AuItstatus)
            {
                AuItbutton.style.background = "red";
                AuItstatus = true;
                GM_setValue("AutoIntegrateSwitch"+videoId, {
                    msg: "start",
                    HC: Number(headCountinput.value),
                    CC: Number(chatCountinput.value),
                    TL: Number(timeLimitInput.value),
                    CD: Number(CDinput.value),
                    time: Date.now()
                });

            }else{
                AuItbutton.style.background = "white";
                AuItstatus = false;
                GM_setValue("AutoIntegrateSwitch"+videoId, { msg: "stop", time: Date.now() });
            }



        }
        return page;
    }

    function sendMessageToRealChatRoom(msg) {

        const chatInput = document.querySelector(
            'yt-live-chat-text-input-field-renderer div[contenteditable]'
        );

        const sendButton = document.querySelector("#send-button button");

        if (!chatInput || !sendButton) {
            console.log("没找到聊天框");
            return;
        }

        chatInput.focus();

        chatInput.textContent = msg;

        chatInput.dispatchEvent(new InputEvent("input", {
            bubbles: true
        }));

        sendButton.click();
    }

    function showPage(pageShow,pageHide1,pageHide2) {

        pageShow.style.display = "flex";
        pageHide1.style.display = "none";
        pageHide2.style.display = "none";


}

    function changeShowHide(pageShow,pageHide){
        pageShow.style.display = "flex";
        pageHide.style.display = "none";
    }

    function UpdateChatComments(){
        const chat = document.querySelector("#items");

        const observer = new MutationObserver(mutations => {

            mutations.forEach(mutation => {

                mutation.addedNodes.forEach(node => {

                    if (node.tagName !== "YT-LIVE-CHAT-TEXT-MESSAGE-RENDERER") return;

                    const author = node.querySelector("#author-name")?.textContent.trim();

                    const text = node.querySelector("#message")?.textContent.trim();

                    console.log(author, ":", text);

                });

            });

        });

        observer.observe(chat, {
            childList: true
        });

    }

    function AutoIntegrate(){

        let chat = document.querySelector("#items");
        const videoId = new URL(document.referrer).searchParams.get("v");
        GM_addValueChangeListener("AutoIntegrateSwitch"+videoId, (name, oldValue, newValue) => {
            if(newValue.msg==="start"){
                chat = document.querySelector("#items");
                startAutoCopy(newValue.HC,newValue.CC,newValue.TL,newValue.CD)
            }
            if(newValue.msg==="stop"){
                stopAutoCopy();
            }
        });

        const messageMap = new Map();

        let observer = null;
        let clearTimer = null;

        function startAutoCopy(hc,cc,tl,cd) {

            if (
                hc == null || hc === "" || hc == 0 ||
                cc == null || cc === "" || cc == 0 ||
                tl == null || tl === "" || tl == 0 ||
                cd == null || cd === "" || cd == 0
            ) {
                console.log("不能有0和空");
                return;
            }

            if (observer) return;

            observer = new MutationObserver(mutations => {

                mutations.forEach(mutation => {

                    mutation.addedNodes.forEach(node => {

                        if (node.tagName !== "YT-LIVE-CHAT-TEXT-MESSAGE-RENDERER") return;

                        const author = node.querySelector("#author-name")?.textContent.trim();
                        const text = node.querySelector("#message")?.textContent.trim();

                        console.log(author, ":", text);

                        let isSent = autoCopy(hc, cc, author, text);

                        if (isSent) {

                            console.log("暂停监听 10 秒");

                            observer.disconnect();

                            setTimeout(() => {

                                messageMap.clear();

                                observeChat();

                                console.log("恢复监听");

                                clearInterval(clearTimer); // 先取消旧的

                                clearTimer = setInterval(() => {
                                    messageMap.clear();
                                    console.log("messageMap 已清空");
                                }, tl*1000);

                            }, cd*1000);
                        }

                    });

                });

            });

            observeChat();

            // 每30秒清空一次
            clearTimer = setInterval(() => {
                messageMap.clear();
                console.log("messageMap 已清空");
            }, tl*1000);

            console.log("AutoCopy Started");
        }

        function restartClearTimer() {

            clearInterval(clearTimer); // 先取消旧的

            clearTimer = setInterval(() => {
                messageMap.clear();
                console.log("messageMap 已清空");
            }, 1000);
        }

        function observeChat() {

            const chat = document.querySelector("#items");
            if (!chat) return;

            observer.observe(chat, {
                childList: true
            });
        }

        function stopAutoCopy() {

            if (!observer) return;

            observer.disconnect();
            observer = null;

            clearInterval(clearTimer);
            clearTimer = null;

            messageMap.clear();

            console.log("AutoCopy Stopped");
        }

        function autoCopy(headcount, chatcount, author, message) {

            if (!message || message.trim() === "") {
                return;
            }

            if (!messageMap.has(message)) {
                messageMap.set(message, {
                    users: new Set(),
                    count: 0
                });
            }

            const data = messageMap.get(message);

            data.count++;
            data.users.add(author);

            if (
                data.users.size >= headcount &&
                data.count >= chatcount
            ) {
                console.log("自动发送:", message);

                sendMessageToRealChatRoom(message);

                messageMap.delete(message);

                return true;
            }
        }

    }

})();