FACEIT Auto Tool v6.0 (Multi-Language)

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

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==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");

})();