Greasy Fork

奶牛复制助手

奶牛复制助手,安装后页面会出现一个悬浮按钮,点击可以复制常用短语,然后粘贴到聊天栏中。这些短语可以自行修改。

目前为 2025-03-12 提交的版本。查看 最新版本

// ==UserScript==
// @name         奶牛复制助手
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  奶牛复制助手,安装后页面会出现一个悬浮按钮,点击可以复制常用短语,然后粘贴到聊天栏中。这些短语可以自行修改。
// @author       XiaoR
// @match        https://www.milkywayidle.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @license MIT
// ==/UserScript==
(function() {
    'use strict';

    // 初始化配置
    let config = {
        phrases: GM_getValue('phrases',
            ['分解糖(0-10)→苹果(10-20)→橙子(20-35)→竹子/紫茶叶(35-50)→桃子/月(50-65)→红茶叶(65-80)',
            '重组海洋精华(炼金1级)→丛林精华(10-23级)→哥布林精华(23-45级)→眼球精华(45-53级)→熊熊精华(53-65级)',
            '牛牛新人攻略https://test-ctmd6jnzo6t9.feishu.cn/docx/KG9ddER6Eo2uPoxJFkicsvbEnCe',
            '社交-推荐 可以看邀请链接',
            '牛牛官方群:482088950',
            '因为有经验buff',
            '公会没有任何加成',
            '法师35级前没有副手',
            '背部装备只有后期才有',
            '背叛火法,永久封禁']),
        position: GM_getValue('position', {x: 30, y: 30})
    };
    const defaultPhrases = [
'分解糖(0-10)→苹果(10-20)→橙子(20-35)→竹子/紫茶叶(35-50)→桃子/月(50-65)→红茶叶(65-80)',
            '重组海洋精华(炼金1级)→丛林精华(10-23级)→哥布林精华(23-45级)→眼球精华(45-53级)→熊熊精华(53-65级)',
            '牛牛新人攻略https://test-ctmd6jnzo6t9.feishu.cn/docx/KG9ddER6Eo2uPoxJFkicsvbEnCe',
            '社交-推荐 可以看邀请链接',
            '牛牛官方群:482088950',
            '因为有经验buff',
            '公会没有任何加成',
            '法师35级前没有副手',
            '背部装备只有后期才有',
            '背叛火法,永久封禁'
    ];
    // 创建UI样式
    const createStyles = () => {
        const style = document.createElement('style');
        style.textContent = `
            .mwc-container {
                position: fixed;
                z-index: 99999;
                transform: translate(-50%, -50%);
            }

            .mwc-main-btn {
                width: 48px;
                height: 48px;
                border-radius: 24px;
                background: linear-gradient(135deg, #6366f1, #8b5cf6);
                border: none;
                box-shadow: 0 4px 12px rgba(0,0,0,0.2);
                cursor: move;
                transition: all 0.3s;
                display: flex;
                align-items: center;
                justify-content: center;
                color: white;
                font-size: 24px;
            }

            .mwc-main-btn:hover {
                transform: scale(1.1);
                box-shadow: 0 6px 16px rgba(0,0,0,0.3);
            }

            .mwc-menu {
                position: absolute;
                left: 60px;
                top: 0;
                background: rgba(255,255,255,0.95);
                border-radius: 12px;
                padding: 8px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.1);
                backdrop-filter: blur(8px);
                min-width: 200px;
                display: none;
            }

            .mwc-menu-item {
                padding: 12px;
                border-radius: 8px;
                cursor: pointer;
                transition: all 0.2s;
                color: #374151;
                font-size: 14px;
                display: flex;
                align-items: center;
                gap: 8px;
            }

            .mwc-menu-item:hover {
                background: rgba(99,102,241,0.1);
                transform: translateX(4px);
            }

            .mwc-config {
                background: white;
                padding: 20px;
                border-radius: 16px;
                box-shadow: 0 8px 24px rgba(0,0,0,0.1);
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                z-index: 100000;
                display: none;
                width: 400px;
            }

            .mwc-config-item {
                display: flex;
                gap: 8px;
                align-items: center;
                margin-bottom: 12px;
            }

            .mwc-config-input {
                flex: 1;
                padding: 8px;
                border: 1px solid #e5e7eb;
                border-radius: 8px;
            }

            .mwc-add-btn {
                width: 100%;
                padding: 8px;
                background: #f3f4f6;
                border: 1px dashed #d1d5db;
                border-radius: 8px;
                cursor: pointer;
                color: #6b7280;
                margin-bottom: 16px;
            }

            .mwc-add-btn:hover {
                background: #e5e7eb;
            }

            .mwc-delete-btn {
                color: #ef4444;
                cursor: pointer;
                padding: 4px;
                border-radius: 4px;
            }

            .mwc-delete-btn:hover {
                background: #fee2e2;
            }

            .mwc-toast {
                position: fixed;
                bottom: 20px;
                left: 50%;
                transform: translateX(-50%);
                background: linear-gradient(135deg, #10b981, #059669);
                color: white;
                padding: 12px 24px;
                border-radius: 8px;
                display: none;
                animation: slideIn 0.3s;
            }

            @keyframes slideIn {
                from { bottom: -50px }
                to { bottom: 20px }
            }
        `;
        document.head.appendChild(style);
    };

    // 创建配置面板
    const createConfigPanel = (menu) => {
        const panel = document.createElement('div');
        panel.className = 'mwc-config';
        panel.addEventListener('click', e => e.stopPropagation());

        panel.innerHTML = `
        <h3 style="margin:0 0 16px;color:#1f2937">短语管理</h3>
        <div id="mwc-phrases-container"></div>
        <button class="mwc-add-btn">+ 添加新短语</button>
        <div style="display:flex;gap:8px;margin-top:16px;flex-wrap:wrap">
            <button style="flex:1;padding:8px;background:#4f46e5;color:white;border:none;border-radius:8px">保存</button>
            <button style="flex:1;padding:8px;background:#ef4444;color:white;border:none;border-radius:8px" class="mwc-reset-btn">恢复默认</button>
            <button style="padding:8px 16px;background:#f3f4f6;border:none;border-radius:8px">取消</button>
        </div>
    `;

        const phrasesContainer = panel.querySelector('#mwc-phrases-container');
        const addBtn = panel.querySelector('.mwc-add-btn');

        // 添加新短语
        addBtn.addEventListener('click', () => {
            const item = document.createElement('div');
            item.className = 'mwc-config-item';
            item.innerHTML = `
                <input class="mwc-config-input" placeholder="输入新短语">
                <div class="mwc-delete-btn">🗑️</div>
            `;
            phrasesContainer.appendChild(item);
        });

        phrasesContainer.addEventListener('click', (e) => {
            if (e.target.classList.contains('mwc-delete-btn')) {
                e.stopPropagation(); // 阻止事件冒泡
                e.target.closest('.mwc-config-item').remove();
            }
        });

        panel.querySelector('button:first-child').addEventListener('click', () => {
            const inputs = phrasesContainer.querySelectorAll('.mwc-config-input');
            config.phrases = Array.from(inputs).map(input => input.value.trim()).filter(Boolean);
            GM_setValue('phrases', config.phrases);
            updatePhrases(menu);
            panel.style.display = 'none';
        });
        // 取消
        panel.querySelector('button:last-child').addEventListener('click', () => {
            panel.style.display = 'none';
        });
        panel.querySelector('.mwc-reset-btn').addEventListener('click', () => {
            if (confirm('确定要恢复默认短语吗?当前所有修改将会丢失!')) {
                config.phrases = [...defaultPhrases];
                GM_setValue('phrases', config.phrases);

                const phrasesContainer = panel.querySelector('#mwc-phrases-container');
                phrasesContainer.innerHTML = '';
                config.phrases.forEach(text => {
                    const item = document.createElement('div');
                    item.className = 'mwc-config-item';
                    item.innerHTML = `
                        <input class="mwc-config-input" value="${text}">
                        <div class="mwc-delete-btn">🗑️</div>
                    `;
                    phrasesContainer.appendChild(item);
                });

                updatePhrases(menu);
                showToast('✅ 已恢复默认短语');
            }
        });

        return panel;
    };

    // 更新短语菜单
    const updatePhrases = (menu) => {
        // 先移除所有非配置按钮的菜单项
        const existingItems = menu.querySelectorAll('.mwc-menu-item:not(.mwc-config-btn)');
        existingItems.forEach(n => n.remove());

        // 添加新短语项
        config.phrases.forEach((text) => {
            const btn = document.createElement('div');
            btn.className = 'mwc-menu-item';
            btn.textContent = text;
            btn.addEventListener('click', () => {
                navigator.clipboard.writeText(text);
                showToast('✅ 复制成功');
            });
            menu.insertBefore(btn, menu.querySelector('.mwc-config-btn'));
        });
    };

    // 显示Toast提示
    const showToast = (message) => {
        const toast = document.createElement('div');
        toast.className = 'mwc-toast';
        toast.textContent = message;
        document.body.appendChild(toast);
        toast.style.display = 'block';
        setTimeout(() => toast.remove(), 2000);
    };

    // 初始化拖拽功能
    const initDrag = (container) => {
        let isDragging = false;
        let startX = 0;
        let startY = 0;

        container.addEventListener('mousedown', (e) => {
            isDragging = true;
            startX = e.clientX - container.offsetLeft;
            startY = e.clientY - container.offsetTop;
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            container.style.left = `${e.clientX - startX}px`;
            container.style.top = `${e.clientY - startY}px`;
        });

        document.addEventListener('mouseup', () => {
            if (!isDragging) return;
            isDragging = false;
            GM_setValue('position', {
                x: parseInt(container.style.left),
                y: parseInt(container.style.top)
            });
        });
    };

    // 主初始化函数
    const init = () => {
        createStyles();

        // 创建主界面
        const container = document.createElement('div');
        container.className = 'mwc-container';
        container.style.left = `${config.position.x}px`;
        container.style.top = `${config.position.y}px`;

        const mainBtn = document.createElement('button');
        mainBtn.className = 'mwc-main-btn';
        mainBtn.textContent = '+';
        container.appendChild(mainBtn);

        const menu = document.createElement('div');
        menu.className = 'mwc-menu';

        const configBtn = document.createElement('div');
        configBtn.className = 'mwc-menu-item mwc-config-btn'; // 添加特殊类名
        configBtn.textContent = '⚙️ 管理短语';
        menu.appendChild(configBtn);

        container.appendChild(menu);
        document.body.appendChild(container);

        // 创建配置面板
        const configPanel = createConfigPanel(menu);
        document.body.appendChild(configPanel);

        // 初始化功能
        initDrag(container);
        updatePhrases(menu);

        // 主按钮点击
        mainBtn.addEventListener('click', () => {
            menu.style.display = menu.style.display === 'block' ? 'none' : 'block';
        });

        // 打开配置面板
        configBtn.addEventListener('click', () => {
            const phrasesContainer = configPanel.querySelector('#mwc-phrases-container');
            phrasesContainer.innerHTML = '';
            config.phrases.forEach(text => {
                const item = document.createElement('div');
                item.className = 'mwc-config-item';
                item.innerHTML = `
                    <input class="mwc-config-input" value="${text}">
                    <div class="mwc-delete-btn">🗑️</div>
                `;
                phrasesContainer.appendChild(item);
            });
            configPanel.style.display = 'block';
        });

        // 点击外部关闭
        document.addEventListener('click', (e) => {
            if (!e.target.closest('.mwc-container') && !e.target.closest('.mwc-config')) {
                menu.style.display = 'none';
                configPanel.style.display = 'none';
            }
        });
    };

    window.addEventListener('load', init);
})();