FACEIT Auto Tool v6.0 (Multi-Language)

Авто-принятие, авто-коннект, кастомные звуки и мультиязычный интерфейс

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         FACEIT Auto Tool v6.0 (Multi-Language)
// @namespace    http://tampermonkey.net/
// @version      6.0
// @description  Авто-принятие, авто-коннект, кастомные звуки и мультиязычный интерфейс
// @author       Evre1pro
// @match        https://www.faceit.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_notification
// @grant        window.focus
// @run-at       document-idle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- КОНФИГУРАЦИЯ ---
    const CONFIG_KEY = 'faceit_tool_config_v6';
    const POS_KEY = 'faceit_tool_pos_v6';

    // Словарь переводов
    const TRANSLATIONS = {
        ru: {
            title: 'FACEIT AUTO TOOL',
            header: 'FACEIT AUTO TOOL',
            sec_automation: 'Автоматизация',
            lbl_accept: 'Авто-Принятие',
            lbl_connect: 'Авто-Коннект (1 клик)',
            desc_connect: '* Коннект срабатывает 1 раз при появлении кнопки.',
            sec_sounds: 'Звуки и Оповещения',
            lbl_sound_on: 'Включить звуки',
            lbl_notify: 'Оповещения (свернутый)',
            lbl_sound_match: 'Звук "Матч найден"',
            lbl_sound_connect: 'Звук "Коннект"',
            lbl_volume: 'Громкость',
            sec_settings: 'Настройки',
            lbl_language: 'Язык / Language',
            lbl_style: 'Вид кнопки',
            opt_floating: 'Плавающая',
            opt_native: 'Встроить в меню',
            btn_test: 'Тест',
            btn_upload: 'Загр.',
            footer: 'Меню можно перетаскивать | F8 для скрытия',
            notif_match: 'МАТЧ НАЙДЕН! Принимаю...',
            notif_ready: 'СЕРВЕР ГОТОВ! Подключаюсь...',
            notif_clicked: 'Кнопка подключения нажата.',
            alert_big_file: 'Файл > 1МБ. Используйте короткий звук.',
            alert_saved: 'Звук сохранен!',
            log_accept: '[FACEIT Tool] Матч принят',
            log_connect: '[FACEIT Tool] Коннект нажат'
        },
        en: {
            title: 'FACEIT AUTO TOOL',
            header: 'FACEIT AUTO TOOL',
            sec_automation: 'Automation',
            lbl_accept: 'Auto-Accept',
            lbl_connect: 'Auto-Connect (One-Tap)',
            desc_connect: '* Connect clicks once when button appears.',
            sec_sounds: 'Sounds & Notifications',
            lbl_sound_on: 'Enable Sounds',
            lbl_notify: 'Desktop Notifications',
            lbl_sound_match: 'Sound "Match Found"',
            lbl_sound_connect: 'Sound "Connect"',
            lbl_volume: 'Volume',
            sec_settings: 'Settings',
            lbl_language: 'Language',
            lbl_style: 'Button Style',
            opt_floating: 'Floating',
            opt_native: 'Native (Sidebar)',
            btn_test: 'Test',
            btn_upload: 'Upld',
            footer: 'Drag header to move | F8 to hide',
            notif_match: 'MATCH FOUND! Accepting...',
            notif_ready: 'SERVER READY! Connecting...',
            notif_clicked: 'Connect button clicked.',
            alert_big_file: 'File > 1MB. Use short audio.',
            alert_saved: 'Sound saved!',
            log_accept: '[FACEIT Tool] Match Accepted',
            log_connect: '[FACEIT Tool] Connect Clicked'
        },
        de: {
            title: 'FACEIT AUTO TOOL',
            header: 'FACEIT AUTO TOOL',
            sec_automation: 'Automatisierung',
            lbl_accept: 'Auto-Akzeptieren',
            lbl_connect: 'Auto-Verbinden',
            desc_connect: '* Klickt einmal, wenn Button erscheint.',
            sec_sounds: 'Töne & Benachrichtigungen',
            lbl_sound_on: 'Töne aktivieren',
            lbl_notify: 'Desktop-Benachricht.',
            lbl_sound_match: 'Ton "Match gefunden"',
            lbl_sound_connect: 'Ton "Verbinden"',
            lbl_volume: 'Lautstärke',
            sec_settings: 'Einstellungen',
            lbl_language: 'Sprache / Language',
            lbl_style: 'Button-Stil',
            opt_floating: 'Schwebend',
            opt_native: 'Im Menü',
            btn_test: 'Test',
            btn_upload: 'Laden',
            footer: 'Kopfzeile ziehen zum Bewegen | F8',
            notif_match: 'MATCH GEFUNDEN! Akzeptiere...',
            notif_ready: 'SERVER BEREIT! Verbinde...',
            notif_clicked: 'Verbinden geklickt.',
            alert_big_file: 'Datei > 1MB. Kurz halten.',
            alert_saved: 'Ton gespeichert!',
            log_accept: '[FACEIT Tool] Match akzeptiert',
            log_connect: '[FACEIT Tool] Verbindung geklickt'
        },
        zh: {
            title: 'FACEIT 自动工具',
            header: 'FACEIT 自动工具',
            sec_automation: '自动化',
            lbl_accept: '自动接受',
            lbl_connect: '自动连接 (单次)',
            desc_connect: '* 按钮出现时自动点击一次。',
            sec_sounds: '声音和通知',
            lbl_sound_on: '启用声音',
            lbl_notify: '桌面通知',
            lbl_sound_match: '声音 "找到比赛"',
            lbl_sound_connect: '声音 "连接"',
            lbl_volume: '音量',
            sec_settings: '设置',
            lbl_language: '语言 / Language',
            lbl_style: '按钮样式',
            opt_floating: '悬浮球',
            opt_native: '嵌入菜单',
            btn_test: '测试',
            btn_upload: '上传',
            footer: '拖动标题移动 | 按 F8 隐藏',
            notif_match: '找到比赛!正在接受...',
            notif_ready: '服务器就绪!正在连接...',
            notif_clicked: '已点击连接按钮。',
            alert_big_file: '文件 > 1MB。请使用短音频。',
            alert_saved: '声音已保存!',
            log_accept: '[FACEIT Tool] 已接受比赛',
            log_connect: '[FACEIT Tool] 已点击连接'
        }
    };

    const DEFAULT_CONFIG = {
        lang: 'ru', // Язык по умолчанию
        autoAccept: true,
        autoConnect: true,
        soundEnabled: true,
        volume: 0.5,
        buttonStyle: 'floating',
        acceptSoundData: null,
        connectSoundData: null,
        notifications: true
    };

    let config = { ...DEFAULT_CONFIG, ...GM_getValue(CONFIG_KEY, {}) };
    let menuPos = GM_getValue(POS_KEY, { top: '15%', left: '85%' });
    let isMenuOpen = false;
    let t = TRANSLATIONS[config.lang]; // Текущий словарь

    // Состояние
    let state = {
        hasAccepted: false,
        hasConnected: false,
        currentUrl: window.location.href
    };

    // Иконки
    const ICONS = {
        robot: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="24" height="24"><rect x="3" y="11" width="18" height="10" rx="2" /><circle cx="12" cy="5" r="2" /><path d="M12 7v4" /><line x1="8" y1="16" x2="8" y2="16" /><line x1="16" y1="16" x2="16" y2="16" /></svg>`,
        gear: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1Z"/></svg>`,
        play: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>`,
        upload: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>`
    };

    // Стили
    GM_addStyle(`
        .f-tool-btn-floating {
            position: fixed; top: 15%; right: 20px; z-index: 9999;
            background: #FF5500; color: white; border: none;
            border-radius: 50%; width: 50px; height: 50px;
            cursor: pointer; box-shadow: 0 4px 15px rgba(255, 85, 0, 0.4);
            display: flex; align-items: center; justify-content: center;
            transition: transform 0.2s;
        }
        .f-tool-btn-floating:hover { transform: scale(1.1); }

        .f-tool-btn-native {
            display: flex; align-items: center; justify-content: center;
            width: 40px; height: 40px; margin: 10px auto;
            border-radius: 50%; cursor: pointer;
            background: transparent; border: 1px solid #333;
            color: #888; transition: all 0.2s;
        }
        .f-tool-btn-native:hover, .f-tool-btn-native.active {
            color: #FF5500; border-color: #FF5500; background: rgba(255, 85, 0, 0.1);
        }

        .f-tool-modal {
            position: fixed; z-index: 10000;
            width: 360px; background: #1f1f1f;
            border-radius: 8px; box-shadow: 0 10px 50px rgba(0,0,0,0.9);
            border: 1px solid #333; color: #fff; font-family: "Play", sans-serif;
            display: none; opacity: 0; transition: opacity 0.2s;
            user-select: none;
        }
        .f-tool-modal.active { display: block; opacity: 1; }

        .f-tool-header {
            padding: 12px 15px; border-bottom: 1px solid #333;
            display: flex; justify-content: space-between; align-items: center;
            background: #161616; border-radius: 8px 8px 0 0;
            cursor: grab;
        }
        .f-tool-header:active { cursor: grabbing; }

        .f-tool-body { padding: 15px; }

        .f-tool-group {
            background: #262626; padding: 12px; border-radius: 6px;
            margin-bottom: 10px; border: 1px solid #333;
        }
        .f-tool-group h4 { margin: 0 0 10px 0; color: #FF5500; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }

        .f-tool-row {
            display: flex; justify-content: space-between; align-items: center;
            margin-bottom: 10px; font-size: 13px;
        }

        .f-switch { position: relative; display: inline-block; width: 36px; height: 18px; }
        .f-switch input { opacity: 0; width: 0; height: 0; }
        .f-slider {
            position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;
            background-color: #444; transition: .3s; border-radius: 18px;
        }
        .f-slider:before {
            position: absolute; content: ""; height: 14px; width: 14px;
            left: 2px; bottom: 2px; background-color: white;
            transition: .3s; border-radius: 50%;
        }
        input:checked + .f-slider { background-color: #FF5500; }
        input:checked + .f-slider:before { transform: translateX(18px); }

        .f-btn {
            background: #333; color: white; border: 1px solid #444;
            padding: 4px 8px; border-radius: 4px; cursor: pointer;
            font-size: 11px; display: flex; align-items: center; gap: 5px;
        }
        .f-btn:hover { background: #444; border-color: #555; }
        .f-select {
            background: #333; color: white; border: 1px solid #444;
            padding: 4px; border-radius: 4px; font-size: 12px; outline: none;
        }
        .f-volume-slider { width: 100%; accent-color: #FF5500; margin-top: 8px; height: 4px; }
        .f-close { cursor: pointer; font-size: 20px; color: #888; line-height: 1; }
        .f-close:hover { color: white; }
    `);

    // --- СИСТЕМА ---
    function setLanguage(langCode) {
        if (!TRANSLATIONS[langCode]) return;
        config.lang = langCode;
        t = TRANSLATIONS[langCode];
        GM_setValue(CONFIG_KEY, config);

        // Перерисовываем только контент модального окна
        updateModalContent();
    }

    function makeDraggable(el) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
        const header = el.querySelector('.f-tool-header');
        if (header) header.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            el.style.top = (el.offsetTop - pos2) + "px";
            el.style.left = (el.offsetLeft - pos1) + "px";
            el.style.transform = 'none';
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
            GM_setValue(POS_KEY, { top: el.style.top, left: el.style.left });
        }
    }

    function playSound(type) {
        if (!config.soundEnabled) return;

        if (document.hidden && config.notifications) {
            GM_notification({
                title: 'FACEIT Auto Tool',
                text: type === 'accept' ? t.notif_match : t.notif_ready,
                timeout: 4000,
                onclick: () => window.focus()
            });
        }

        const customData = type === 'accept' ? config.acceptSoundData : config.connectSoundData;
        if (customData) {
            const audio = new Audio(customData);
            audio.volume = config.volume;
            audio.play().catch(e => console.error(e));
            return;
        }

        const ctx = new (window.AudioContext || window.webkitAudioContext)();
        const osc = ctx.createOscillator();
        const gain = ctx.createGain();
        osc.connect(gain);
        gain.connect(ctx.destination);
        gain.gain.value = config.volume * 0.2;

        if (type === 'accept') {
            osc.type = 'square';
            osc.frequency.setValueAtTime(500, ctx.currentTime);
            osc.frequency.linearRampToValueAtTime(1000, ctx.currentTime + 0.1);
            osc.start();
            osc.stop(ctx.currentTime + 0.4);
        } else {
            osc.type = 'sine';
            osc.frequency.setValueAtTime(800, ctx.currentTime);
            osc.frequency.linearRampToValueAtTime(1200, ctx.currentTime + 0.2);
            osc.start();
            osc.stop(ctx.currentTime + 0.5);
        }
    }

    function findBtnByText(textArray, context = document) {
        const buttons = context.querySelectorAll('button');
        for (let btn of buttons) {
            if (btn.disabled || btn.offsetParent === null) continue;
            const btnText = btn.innerText.toUpperCase();
            if (textArray.some(t => btnText.includes(t))) return btn;
        }
        return null;
    }

    function automationLoop() {
        if (window.location.href !== state.currentUrl) {
            state.currentUrl = window.location.href;
            state.hasAccepted = false;
            state.hasConnected = false;
        }

        if (config.autoAccept && !state.hasAccepted) {
            const modal = document.querySelector('div[data-dialog-type="MODAL"]');
            if (modal) {
                const btn = findBtnByText(['ACCEPT', 'ПРИНЯТЬ', 'CHECK IN', 'ANNEHMEN', '接受'], modal);
                if (btn) {
                    playSound('accept');
                    state.hasAccepted = true;
                    setTimeout(() => btn.click(), 200);
                    console.log(t.log_accept);
                }
            }
        }

        if (config.autoConnect && !state.hasConnected) {
            if (window.location.href.includes('/room/')) {
                const btn = findBtnByText(['CONNECT', 'ПОДКЛЮЧИТЬСЯ', 'COPY IP', 'СКОПИРОВАТЬ', 'VERBINDEN', '连接']);
                if (btn) {
                    const txt = btn.innerText.toUpperCase();
                    if (!txt.includes('COPIED') && !txt.includes('ЗАПУСК') && !txt.includes('СКОПИРОВАНО')) {
                        btn.click();
                        state.hasConnected = true;
                        playSound('connect');
                        console.log(t.log_connect);
                        if (config.notifications) {
                             GM_notification({title: 'FACEIT Tool', text: t.notif_clicked, timeout: 2000});
                        }
                    }
                }
            }
        }
    }

    // --- UI РЕНДЕР ---
    function toggleMenu() {
        const modal = document.querySelector('.f-tool-modal');
        isMenuOpen = !isMenuOpen;
        if (isMenuOpen) modal.classList.add('active');
        else modal.classList.remove('active');
    }

    function renderButtons() {
        document.querySelectorAll('.f-tool-btn-floating, .f-tool-btn-native').forEach(e => e.remove());
        if (config.buttonStyle === 'native') {
            const sidebar = document.querySelector('div[class*="NavigationSidebar"] div[class*="Scrollable"]');
            if (sidebar) {
                const container = document.createElement('div');
                container.style.display = 'contents';
                const btn = document.createElement('button');
                btn.className = 'f-tool-btn-native';
                btn.innerHTML = ICONS.robot;
                btn.onclick = toggleMenu;
                sidebar.appendChild(container);
                container.appendChild(btn);
            } else {
                renderFloatingBtn();
            }
        } else {
            renderFloatingBtn();
        }
    }

    function renderFloatingBtn() {
        const btn = document.createElement('button');
        btn.className = 'f-tool-btn-floating';
        btn.innerHTML = ICONS.gear;
        btn.onclick = toggleMenu;
        document.body.appendChild(btn);
    }

    // Обновление внутреннего HTML модалки (для смены языка)
    function updateModalContent() {
        const modal = document.querySelector('.f-tool-modal');
        if (!modal) return;

        // Сохраняем старый заголовок для перетаскивания, меняем только innerHTML
        const html = `
            <div class="f-tool-header">
                <span style="font-weight:bold; color:#FF5500; display:flex; gap:8px; align-items:center">
                    ${ICONS.robot} ${t.header}
                </span>
                <span class="f-close" id="f-tool-close">×</span>
            </div>
            <div class="f-tool-body">
                <div class="f-tool-group">
                    <h4>${t.sec_automation}</h4>
                    <div class="f-tool-row">
                        <span>${t.lbl_accept}</span>
                        <label class="f-switch">
                            <input type="checkbox" id="chk-accept" ${config.autoAccept ? 'checked' : ''}>
                            <span class="f-slider"></span>
                        </label>
                    </div>
                    <div class="f-tool-row">
                        <span>${t.lbl_connect}</span>
                        <label class="f-switch">
                            <input type="checkbox" id="chk-connect" ${config.autoConnect ? 'checked' : ''}>
                            <span class="f-slider"></span>
                        </label>
                    </div>
                    <div style="font-size:10px; color:#888; margin-top:5px;">
                        ${t.desc_connect}
                    </div>
                </div>

                <div class="f-tool-group">
                    <h4>${t.sec_sounds}</h4>
                    <div class="f-tool-row">
                        <span>${t.lbl_sound_on}</span>
                        <label class="f-switch">
                            <input type="checkbox" id="chk-sound" ${config.soundEnabled ? 'checked' : ''}>
                            <span class="f-slider"></span>
                        </label>
                    </div>
                     <div class="f-tool-row">
                        <span>${t.lbl_notify}</span>
                        <label class="f-switch">
                            <input type="checkbox" id="chk-notify" ${config.notifications ? 'checked' : ''}>
                            <span class="f-slider"></span>
                        </label>
                    </div>

                    <div class="f-tool-row" style="margin-top:10px">
                        <span>${t.lbl_sound_match}</span>
                        <div style="display:flex; gap:5px">
                            <button class="f-btn" id="btn-test-accept" title="${t.btn_test}">${ICONS.play}</button>
                            <label class="f-btn" title="${t.btn_upload}">
                                ${ICONS.upload}
                                <input type="file" id="file-accept" accept="audio/*" style="display:none">
                            </label>
                        </div>
                    </div>
                     <div class="f-tool-row">
                        <span>${t.lbl_sound_connect}</span>
                        <div style="display:flex; gap:5px">
                            <button class="f-btn" id="btn-test-connect" title="${t.btn_test}">${ICONS.play}</button>
                            <label class="f-btn" title="${t.btn_upload}">
                                ${ICONS.upload}
                                <input type="file" id="file-connect" accept="audio/*" style="display:none">
                            </label>
                        </div>
                    </div>
                    <div class="f-tool-row" style="flex-direction:column; align-items:flex-start; gap:5px;">
                        <span>${t.lbl_volume}</span>
                        <input type="range" class="f-volume-slider" id="rng-volume" min="0" max="1" step="0.1" value="${config.volume}">
                    </div>
                </div>

                <div class="f-tool-group">
                    <h4>${t.sec_settings}</h4>
                    <div class="f-tool-row">
                        <span>${t.lbl_language}</span>
                        <select id="sel-lang" class="f-select">
                            <option value="ru" ${config.lang === 'ru' ? 'selected' : ''}>Русский</option>
                            <option value="en" ${config.lang === 'en' ? 'selected' : ''}>English</option>
                            <option value="de" ${config.lang === 'de' ? 'selected' : ''}>Deutsch</option>
                            <option value="zh" ${config.lang === 'zh' ? 'selected' : ''}>中文</option>
                        </select>
                    </div>
                    <div class="f-tool-row">
                        <span>${t.lbl_style}</span>
                        <select id="sel-style" class="f-select">
                            <option value="floating" ${config.buttonStyle === 'floating' ? 'selected' : ''}>${t.opt_floating}</option>
                            <option value="native" ${config.buttonStyle === 'native' ? 'selected' : ''}>${t.opt_native}</option>
                        </select>
                    </div>
                </div>
                <div style="text-align:center; font-size:10px; color:#555; margin-top:5px;">${t.footer}</div>
            </div>
        `;

        modal.innerHTML = html;
        bindEvents(); // Перепривязываем события после обновления HTML
        makeDraggable(modal); // Обновляем драг-хендлер
    }

    function bindEvents() {
        document.getElementById('f-tool-close').onclick = toggleMenu;

        ['autoAccept', 'autoConnect', 'soundEnabled', 'notifications'].forEach(key => {
            const id = 'chk-' + (key === 'soundEnabled' ? 'sound' : key === 'notifications' ? 'notify' : key === 'autoAccept' ? 'accept' : 'connect');
            document.getElementById(id).onchange = (e) => {
                config[key] = e.target.checked;
                GM_setValue(CONFIG_KEY, config);
            };
        });

        document.getElementById('rng-volume').oninput = (e) => {
            config.volume = parseFloat(e.target.value);
            GM_setValue(CONFIG_KEY, config);
        };

        document.getElementById('sel-style').onchange = (e) => {
            config.buttonStyle = e.target.value;
            GM_setValue(CONFIG_KEY, config);
            renderButtons();
        };

        // Смена языка
        document.getElementById('sel-lang').onchange = (e) => {
            setLanguage(e.target.value);
        };

        // Аудио
        const handleUpload = (id, key) => {
            document.getElementById(id).onchange = (e) => {
                const file = e.target.files[0];
                if (!file) return;
                if (file.size > 1024 * 1024) {
                    alert(t.alert_big_file);
                    return;
                }
                const reader = new FileReader();
                reader.onload = (evt) => {
                    config[key] = evt.target.result;
                    GM_setValue(CONFIG_KEY, config);
                    alert(t.alert_saved);
                };
                reader.readAsDataURL(file);
            };
        };
        handleUpload('file-accept', 'acceptSoundData');
        handleUpload('file-connect', 'connectSoundData');

        document.getElementById('btn-test-accept').onclick = () => playSound('accept');
        document.getElementById('btn-test-connect').onclick = () => playSound('connect');
    }

    function init() {
        const modal = document.createElement('div');
        modal.className = 'f-tool-modal';
        modal.style.top = menuPos.top;
        modal.style.left = menuPos.left;
        if(menuPos.top !== '50%') modal.style.transform = 'none';
        document.body.appendChild(modal);

        updateModalContent(); // Инициализация контента
        renderButtons();

        setInterval(() => {
            if (config.buttonStyle === 'native' && !document.querySelector('.f-tool-btn-native')) {
                renderButtons();
            }
        }, 2000);

        setInterval(automationLoop, 1000);

        document.addEventListener('keydown', (e) => {
            if (e.code === 'F8') toggleMenu();
        });
    }

    init();
    console.log("FACEIT Auto Tool v6.0 Loaded");

})();