Evowars.io Nixware

Zoom Hack, Speed Hack, Show Enemy Hitbox, Draw Lines To Enemy

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         Evowars.io Nixware
// @namespace    http://tampermonkey.net/
// @version      2026-04-08
// @description  Zoom Hack, Speed Hack, Show Enemy Hitbox, Draw Lines To Enemy
// @author       You
// @match        https://evowars.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=evowars.io
// @grant        none
// ==/UserScript==

(function() {
    const style = document.createElement('style');
    style.innerHTML = `
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');
        #cheat-menu-container {
            position: fixed;
            top: 50px;
            left: 50px;
            width: 780px;
            height: 500px;
            background-color: #121212;
            border-radius: 8px;
            font-family: 'Inter', sans-serif;
            color: #a0a0a0;
            z-index: 999999;
            box-shadow: 0 10px 30px rgba(0,0,0,0.5);
            border: 1px solid #1e1e1e;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            cursor: default;
        }
        #cheat-menu-header {
            height: 60px;
            padding: 0 25px;
            font-size: 16px;
            font-weight: 600;
            color: #ffffff;
            border-bottom: 1px solid #1e1e1e;
            cursor: grab;
            display: flex;
            align-items: center;
            gap: 15px;
            user-select: none;
            background-color: #121212;
        }
        #cheat-menu-header:active {
            cursor: grabbing;
        }
        #cheat-menu-header::before {
            content: '';
            display: inline-block;
            width: 14px;
            height: 14px;
            background-color: #ffffff;
            clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
        }
        .cheat-menu-body {
            display: flex;
            flex: 1;
            background-color: #0f0f0f;
        }
        .cheat-sidebar {
            width: 65px;
            background-color: #151515;
            border-right: 1px solid #1e1e1e;
        }
        .cheat-content {
            display: flex;
            flex: 1;
            padding: 30px;
            gap: 30px;
        }
        .cheat-col {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: 30px;
        }
        .cheat-section-title {
            font-size: 11px;
            font-weight: 600;
            letter-spacing: 1.5px;
            margin-bottom: 15px;
            text-transform: uppercase;
            color: #777;
            user-select: none;
        }
        .cheat-section {
            background-color: #181818;
            border-radius: 8px;
            padding: 20px;
            display: flex;
            flex-direction: column;
            gap: 20px;
            border: 1px solid #222;
        }
        .cheat-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 13px;
            color: #ccc;
            user-select: none;
        }
        .toggle-switch {
            position: relative;
            width: 36px;
            height: 20px;
        }
        .toggle-switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        .slider-round {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #333;
            transition: .3s;
            border-radius: 20px;
        }
        .slider-round:before {
            position: absolute;
            content: "";
            height: 14px;
            width: 14px;
            left: 3px;
            bottom: 3px;
            background-color: white;
            transition: .3s;
            border-radius: 50%;
        }
        input:checked + .slider-round {
            background-color: #3b82f6;
        }
        input:checked + .slider-round:before {
            transform: translateX(16px);
        }
        .slider-container {
            display: flex;
            align-items: center;
            gap: 15px;
            width: 65%;
        }
        input[type=range] {
            -webkit-appearance: none;
            width: 100%;
            height: 4px;
            background: #333;
            border-radius: 2px;
            outline: none;
            pointer-events: auto;
        }
        input[type=range]::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 14px;
            height: 14px;
            border-radius: 50%;
            background: #3b82f6;
            cursor: pointer;
        }
        .val-display {
            background-color: transparent;
            color: #888;
            font-size: 12px;
            min-width: 35px;
            text-align: right;
            font-variant-numeric: tabular-nums;
        }
    `;
    document.head.appendChild(style);

    const menuHtml = `
        <div id="cheat-menu-container">
            <div id="cheat-menu-header">Nixware</div>
            <div class="cheat-menu-body">
                <div class="cheat-sidebar"></div>
                <div class="cheat-content">
                    <div class="cheat-col">
                        <div>
                            <div class="cheat-section-title">VISUALS</div>
                            <div class="cheat-section">
                                <div class="cheat-row">
                                    <span>Draw Lines To Enemy</span>
                                    <label class="toggle-switch">
                                        <input type="checkbox" id="toggle-lines">
                                        <span class="slider-round"></span>
                                    </label>
                                </div>
                                <div class="cheat-row">
                                    <span>Show Enemy Hitboxes</span>
                                    <label class="toggle-switch">
                                        <input type="checkbox" id="toggle-hitboxes">
                                        <span class="slider-round"></span>
                                    </label>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="cheat-col">
                        <div>
                            <div class="cheat-section-title">MODIFIERS</div>
                            <div class="cheat-section">
                                <div class="cheat-row">
                                    <span>Speed</span>
                                    <div class="slider-container">
                                        <input type="range" id="slider-speed" min="0.10" max="25" step="0.1" value="1">
                                        <div class="val-display" id="val-speed">1.00</div>
                                    </div>
                                </div>
                                <div class="cheat-row">
                                    <span>Zoom</span>
                                    <div class="slider-container">
                                        <input type="range" id="slider-zoom" min="0.05" max="5" step="0.05" value="1">
                                        <div class="val-display" id="val-zoom">1.00</div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    `;

    const wrapper = document.createElement('div');
    wrapper.innerHTML = menuHtml;
    document.body.appendChild(wrapper);

    const menu = document.getElementById('cheat-menu-container');
    const header = document.getElementById('cheat-menu-header');
    let isDragging = false;
    let dragStartX, dragStartY;
    let menuStartLeft, menuStartTop;

    // Блокируем события только на элементах управления, но не на всём меню
    const controlElements = ['input', 'label', '.slider-round', '.toggle-switch'];
    const stopEvent = (e) => {
        const target = e.target;
        const isControl = target.matches && (
            target.matches('input') ||
            target.matches('label') ||
            target.closest('.toggle-switch') ||
            target.closest('.slider-container')
        );
        if (isControl) {
            e.stopPropagation();
        }
    };

    // Добавляем обработчики только для контроля, не блокируя drag
    document.addEventListener('click', stopEvent, true);
    document.addEventListener('mousedown', stopEvent, true);
    document.addEventListener('mouseup', stopEvent, true);

    header.addEventListener('mousedown', (e) => {
        // Запрещаем drag если кликнули на элементе управления внутри хедера
        if (e.target.closest('.toggle-switch') || e.target.closest('.slider-container') || e.target.tagName === 'INPUT') {
            return;
        }

        isDragging = true;
        dragStartX = e.clientX;
        dragStartY = e.clientY;

        const rect = menu.getBoundingClientRect();
        menuStartLeft = rect.left;
        menuStartTop = rect.top;

        menu.style.cursor = 'grabbing';
        header.style.cursor = 'grabbing';
        e.preventDefault();
    });

    document.addEventListener('mousemove', (e) => {
        if (!isDragging) return;

        const dx = e.clientX - dragStartX;
        const dy = e.clientY - dragStartY;

        let newLeft = menuStartLeft + dx;
        let newTop = menuStartTop + dy;

        // Ограничиваем по границам окна
        const maxX = window.innerWidth - menu.offsetWidth;
        const maxY = window.innerHeight - menu.offsetHeight;

        newLeft = Math.max(0, Math.min(newLeft, maxX));
        newTop = Math.max(0, Math.min(newTop, maxY));

        menu.style.left = `${newLeft}px`;
        menu.style.top = `${newTop}px`;
    });

    document.addEventListener('mouseup', () => {
        if (isDragging) {
            isDragging = false;
            menu.style.cursor = '';
            header.style.cursor = 'grab';
        }
    });

    // Обновляем позицию при ресайзе окна
    window.addEventListener('resize', () => {
        const rect = menu.getBoundingClientRect();
        const maxX = window.innerWidth - menu.offsetWidth;
        const maxY = window.innerHeight - menu.offsetHeight;

        let newLeft = rect.left;
        let newTop = rect.top;

        if (newLeft > maxX) newLeft = maxX;
        if (newLeft < 0) newLeft = 0;
        if (newTop > maxY) newTop = maxY;
        if (newTop < 0) newTop = 0;

        menu.style.left = `${newLeft}px`;
        menu.style.top = `${newTop}px`;
    });

    const updateSliderBg = (slider, min, max) => {
        const val = slider.value;
        const percentage = ((val - min) / (max - min)) * 100;
        slider.style.background = `linear-gradient(to right, #3b82f6 ${percentage}%, #333 ${percentage}%)`;
    };

    let rt, pType, gameCanvas;
    let showLines = false;
    let showHitboxes = false;

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    document.body.appendChild(canvas);
    canvas.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:999998;';

    window.addEventListener('resize', () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    });
    window.dispatchEvent(new Event('resize'));

    const setGameSpeed = (speed) => {
        if (rt && rt.timescale !== undefined) {
            rt.timescale = parseFloat(speed);
        }
    };

    const setZoom = (scale) => {
        if (rt && rt.running_layout && rt.running_layout.layers) {
            for (let i = 0; i < rt.running_layout.layers.length; i++) {
                const layer = rt.running_layout.layers[i];
                if (layer && layer.scale !== undefined) {
                    layer.scale = parseFloat(scale);
                    if (layer.setZIndicesStaleFrom) layer.setZIndicesStaleFrom(0);
                }
            }
            rt.redraw = true;
        }
    };

    document.getElementById('toggle-lines').addEventListener('change', (e) => {
        showLines = e.target.checked;
    });

    document.getElementById('toggle-hitboxes').addEventListener('change', (e) => {
        showHitboxes = e.target.checked;
    });

    const sliderSpeed = document.getElementById('slider-speed');
    const valSpeed = document.getElementById('val-speed');
    updateSliderBg(sliderSpeed, 0.50, 25);
    sliderSpeed.addEventListener('input', (e) => {
        const val = parseFloat(e.target.value).toFixed(2);
        valSpeed.textContent = val;
        updateSliderBg(e.target, 0.50, 25);
        setGameSpeed(val);
    });

    const sliderZoom = document.getElementById('slider-zoom');
    const valZoom = document.getElementById('val-zoom');
    updateSliderBg(sliderZoom, 0.05, 5);
    sliderZoom.addEventListener('input', (e) => {
        const val = parseFloat(e.target.value).toFixed(2);
        valZoom.textContent = val;
        updateSliderBg(e.target, 0.05, 5);
        setZoom(val);
    });

    const draw = () => {
        if (!rt || !rt.running_layout || !pType) return;

        let self = null;
        let min_d = Infinity;

        for (const p of pType.instances) {
            const d = Math.hypot(p.x - rt.running_layout.scrollX, p.y - rt.running_layout.scrollY);
            if (d < min_d) {
                min_d = d;
                self = p;
            }
        }

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        if (!self) return;

        const rect = gameCanvas.getBoundingClientRect();
        const viewX = rect.left + rect.width / 2;
        const viewY = rect.top + rect.height / 2;
        const scale = self.layer.getScale();

        for (const p of pType.instances) {
            if (p.uid === self.uid) continue;

            const pX = viewX + (p.x - self.x) * scale;
            const pY = viewY + (p.y - self.y) * scale;

            if (showHitboxes) {
                const radius = (p.width / 2) * scale * 1.7;
                ctx.beginPath();
                ctx.arc(pX, pY, radius, 0, 2 * Math.PI);
                ctx.fillStyle = "rgba(255, 255, 0, 0.3)";
                ctx.fill();
                ctx.strokeStyle = "#ffff00";
                ctx.lineWidth = 1;
                ctx.stroke();
            }

            if (showLines) {
                ctx.beginPath();
                ctx.moveTo(viewX, viewY);
                ctx.lineTo(pX, pY);
                ctx.strokeStyle = "#ffffff";
                ctx.lineWidth = 2;
                ctx.stroke();
            }
        }
    };

    const mainLoop = () => {
        try {
            if (rt && rt.running_layout && (showLines || showHitboxes)) {
                draw();
            } else {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
            }
        } catch {}
        requestAnimationFrame(mainLoop);
    };

    const init = setInterval(() => {
        if (window.cr_getC2Runtime && (rt = window.cr_getC2Runtime())) {
            clearInterval(init);
            gameCanvas = rt.canvas;

            for (const type of rt.types_by_index) {
                if (type && type.instvar_sids && type.instvar_sids.length === 72) {
                    pType = type;
                    break;
                }
            }

            mainLoop();
        }
    }, 500);
})();