Drawaria Shop & Trading

A shop for drawaria interactive, Ultra Optimized, Start OFF.

// ==UserScript==
// @name        Drawaria Shop & Trading
// @namespace   http://tampermonkey.net/
// @version     1.5
// @description A shop for drawaria interactive, Ultra Optimized, Start OFF.
// @author      YouTubeDrawaria
// @match       https://drawaria.online/*
// @match       https://*.drawaria.online/*
// @grant       none
// @license     MIT
// @icon        https://www.google.com/s2/favicons?sz=64&domain=drawaria.online
// @run-at      document-idle
// ==/UserScript==

(function() {
    'use strict';

    // --- LETTER & NUMBER PATHS --- (Mantenidos por el dibujo de texto)
    const letterPaths = {
        a: [[10, 40], [20, 0], [30, 40], [25, 20], [15, 20]], b: [[0, 0], [0, 40], [15, 40], [20, 35], [20, 25], [15, 20], [0, 20], [15, 20], [20, 15], [20, 5], [15, 0], [0, 0]],
        c: [[20, 0], [0, 0], [0, 40], [20, 40]], d: [[0, 0], [0, 40], [15, 40], [30, 20], [15, 0], [0, 0]], e: [[30, 0], [0, 0], [0, 20], [20, 20], [0, 20], [0, 40], [30, 40]],
        f: [[0, 0], [0, 40], [20, 40], null, [0, 20], [15, 20]], g: [[30, 10], [20, 0], [10, 0], [0, 10], [0, 30], [10, 40], [20, 40], [30, 30], [20, 20]],
        i: [[10, 0], [10, 40]], j: [[20, 0], [20, 40], [10, 40], [0, 30]], l: [[0, 0], [0, 40], [20, 40]], m: [[0, 40], [0, 0], [10, 20], [20, 0], [20, 40]],
        n: [[0, 40], [0, 0], [20, 40], [20, 0]], o: [[10, 0], [20, 0], [30, 10], [30, 30], [20, 40], [10, 40], [0, 30], [0, 10], [10, 0]],
        p: [[0, 40], [0, 0], [10, 0], [20, 10], [10, 20], [0, 20]], r: [[0, 40], [0, 0], [20, 0], [20, 20], [0, 20], [20, 40]],
        s: [[20, 0], [10, 0], [0, 10], [20, 20], [30, 30], [20, 40], [10, 40], [0, 30]], t: [[10, 0], [10, 40], null, [1, 0], [20, 0]],
        u: [[0, 0], [0, 30], [10, 40], [20, 40], [30, 30], [30, 0]], v: [[0, 0], [15, 40], [30, 0]], z: [[7.5, 35], [9, 36]],
        '$': [[10, 0], [20, 0], [30, 10], [20, 20], [10, 30], [0, 40], [10, 40], [20, 40], null, [15, 0], [15, 40]],
        ' ': [[0, 0]],
    };
    const numberPaths = {
        0: [[10, 0], [20, 0], [30, 10], [30, 30], [20, 40], [10, 40], [0, 30], [0, 10], [10, 0]],
        1: [[15, 0], [15, 40], null, [15, 0], [10, 10], null, [10, 40], [20, 40]],
        2: [[0, 10], [10, 0], [20, 0], [30, 10], [0, 40], [30, 40]],
        3: [[0, 10], [10, 0], [20, 0], [30, 10], [20, 20], [30, 30], [20, 40], [10, 40], [0, 30]],
        4: [[20, 0], [20, 40], null, [0, 20], [25, 20], null, [0, 20], [20, 0]],
        5: [[30, 0], [0, 0], [0, 20], [20, 20], [30, 30], [20, 40], [10, 40], [0, 30]],
        6: [[30, 10], [20, 0], [10, 0], [0, 10], [0, 30], [10, 40], [20, 40], [30, 30], [20, 20], [10, 20], [0, 20], [0, 10]],
        7: [[0, 0], [30, 0], [15, 40]],
        8: [[15, 0], [25, 10], [15, 20], [5, 10], [15, 0], null, [15, 20], [25, 30], [15, 40], [5, 30], [15, 20]],
        9: [[5, 35], [15, 40], [25, 30], [30, 10], [20, 0], [10, 0], [0, 10], [5, 20], [15, 20], [25, 20], [27.5, 20]],
    };

    // Funciones de dibujo (Mismas para optimización visual)
    function drawLetter(path, startX, startY, fontSize, color, thickness) {
        const scale = fontSize / 40;
        for (let i = 0; i < path.length - 1; i++) {
            if (path[i] === null || path[i + 1] === null) continue;
            const [x1, y1] = path[i], [x2, y2] = path[i + 1];
            drawLineServerLocal(startX + x1 * scale, startY + y1 * scale, startX + x2 * scale, startY + y2 * scale, color, thickness);
        }
    }
    function drawText(str, x, y, color, thickness = 2, fontSize = 18) {
        let cx = x;
        for (let i = 0; i < str.length; i++) {
            const char = str[i].toLowerCase();
            const path = letterPaths[char] || numberPaths[char];
            if (path) {
                drawLetter(path, cx, y, fontSize, color, thickness);
            }
            cx += fontSize * 0.6;
        }
    }

    // --- DRAWARIA ADAPTERS (Mantenidos) ---
    let drawariaSocket = null, drawariaCanvas = null, drawariaCtx = null;
    function waitUntilReady() {
        return new Promise(resolve => {
            const check = () => {
                drawariaCanvas = drawariaCanvas || document.getElementById('canvas');
                if (drawariaCanvas) { drawariaCtx = drawariaCtx || drawariaCanvas.getContext('2d'); }
                if (!drawariaSocket && window.WebSocket && window.WebSocket.prototype) {
                    const origSend = WebSocket.prototype.send;
                    WebSocket.prototype.send = function(...args) {
                        if (this.url && this.url.includes('drawaria')) {
                            drawariaSocket = this;
                            WebSocket.prototype.send = origSend;
                            resolve();
                        }
                        return origSend.apply(this, args);
                    };
                }
                if (drawariaCanvas && drawariaCtx && drawariaSocket) { resolve(); }
                else { setTimeout(check, 250); }
            };
            check();
        });
    }
    function drawLineServerLocal(x1, y1, x2, y2, color = '#222', thickness = 3) {
        if (!drawariaSocket || !drawariaCanvas) return;
        const nx1 = (x1 / drawariaCanvas.width).toFixed(4), ny1 = (y1 / drawariaCanvas.height).toFixed(4),
            nx2 = (x2 / drawariaCanvas.width).toFixed(4), ny2 = (y2 / drawariaCanvas.height).toFixed(4);
        const cmd = `42["drawcmd",0,[${nx1},${ny1},${nx2},${ny2},false,${-Math.abs(thickness)},"${color}",0,0,{}]]`;
        drawariaSocket.send(cmd);
        drawariaCtx.save();
        drawariaCtx.strokeStyle = color;
        drawariaCtx.lineWidth = thickness;
        drawariaCtx.lineCap = 'round';
        drawariaCtx.beginPath();
        drawariaCtx.moveTo(x1, y1); drawariaCtx.lineTo(x2, y2); drawariaCtx.stroke();
        drawariaCtx.restore();
    }
    function drawFilledRect(x, y, w, h, color = '#eee') {
        for (let i = 0; i < h; i += 4) drawLineServerLocal(x, y + i, x + w, y + i, color, 4);
    }
    function drawRectServerLocal(x, y, w, h, color = '#222', thickness = 3) {
        drawLineServerLocal(x, y, x + w, y, color, thickness);
        drawLineServerLocal(x + w, y, x + w, y + h, color, thickness);
        drawLineServerLocal(x + w, y + h, x, y + h, color, thickness);
        drawLineServerLocal(x, y + h, x, y, color, thickness);
    }
    function drawLine(x1, y1, x2, y2, color, thickness) {
        drawLineServerLocal(x1, y1, x2, y2, color, thickness);
    }

    // --- GAME STATE & DATA ---
    let SHOP_STATE = 'shop';
    // ESTE es el cambio clave para iniciar apagado.
    let isShopActive = false;
    const products = [
        { id: "apple", name: "a p p l e", icon: "a", price: 5, color: "#df3535" },
        { id: "ball", name: "b a l l", icon: "b", price: 7, color: "#2277f3" },
        { id: "coin", name: "c o i n", icon: "c", price: 3, color: "#ddbe37" },
        { id: "lamp", name: "l a m p", icon: "l", price: 11, color: "#eedd66" }
    ];
    let userCoins = 20;
    let userInventory = [];
    let lastButtons = [];

    // --- DRAW UI FUNCTIONS ---
    function renderShop() {
        if (!drawariaCanvas || !isShopActive) return;
        const screenW = drawariaCanvas.width, screenH = drawariaCanvas.height;
        const groundY = screenH - 120;
        const shopX = screenW / 2 + 100, shopY = groundY - 140;
        const stallX = screenW / 2 - 250, stallY = groundY - 60;
        lastButtons = [];

        // 1. Dibujar el suelo
        drawLine(0, groundY, screenW, groundY, '#222', 2);

        // 2. Dibujar la tienda (casa)
        drawFilledRect(shopX, shopY, 150, 140, '#EAE5DB');
        drawLine(shopX - 10, shopY + 10, shopX + 160, shopY + 10, '#222', 3);
        const awningStripeWidth = 10;
        for (let i = 0; i <= 150 / awningStripeWidth; i++) {
            drawLine(shopX - 10 + (i * awningStripeWidth), shopY + 10, shopX - 10 + (i * awningStripeWidth) + awningStripeWidth, shopY + 20, '#555', 3);
        }
        drawRectServerLocal(shopX + 90, shopY + 80, 40, 60, '#222', 3);
        drawRectServerLocal(shopX + 20, shopY + 50, 50, 50, '#222', 3);
        drawLine(shopX + 45, shopY + 50, shopX + 45, shopY + 100, '#222', 1);
        drawLine(shopX + 20, shopY + 75, shopX + 70, shopY + 75, '#222', 1);

        // 3. Dibujar el mostrador de productos (si estamos en modo 'shop')
        if (SHOP_STATE === 'shop') {
            drawFilledRect(stallX, stallY, 200, 40, '#8B4513');
            drawLine(stallX, stallY + 40, stallX, stallY + 120, '#222', 4);
            drawLine(stallX + 200, stallY + 40, stallX + 200, stallY + 120, '#222', 4);
            drawFilledRect(stallX + 5, stallY - 70, 190, 70, '#FF4500');
            drawRectServerLocal(stallX + 5, stallY - 70, 190, 70, '#FF4500', 1);
            drawText("p r o d u c t o s", stallX + 15, stallY - 50, '#FFF', 2, 18);

            const itemSpacing = (180 - (products.length * 30)) / (products.length + 1);
            for (let i = 0; i < products.length; i++) {
                const prod = products[i];
                const itemX = stallX + 10 + itemSpacing + (i * (30 + itemSpacing));
                const itemY = stallY + 5;
                drawFilledRect(itemX, itemY, 30, 30, prod.color);
                drawRectServerLocal(itemX, itemY, 30, 30, '#222', 2);
                drawText(prod.icon, itemX + 8, itemY + 8, '#333', 2, 18);
                drawText(`$${prod.price}`, itemX + 2, itemY + 40, '#000', 2, 12);
                const buyBtnX = itemX - 5, buyBtnY = stallY + 50, buyBtnW = 40, buyBtnH = 16;
                drawFilledRect(buyBtnX, buyBtnY, buyBtnW, buyBtnH, "#79c842");
                drawRectServerLocal(buyBtnX, buyBtnY, buyBtnW, buyBtnH, "#444", 2);
                drawText("b u y", buyBtnX + 2, buyBtnY + 2, "#fff", 1.5, 12);
                lastButtons.push({ x: buyBtnX, y: buyBtnY, w: buyBtnW, h: buyBtnH, prod, type: 'buy' });
            }
        }

        // 4. Dibujar el inventario (si estamos en modo 'inventory')
        if (SHOP_STATE === 'inventory') {
            const invX = stallX, invY = stallY - 180, invW = 200, invH = 180;
            drawFilledRect(invX, invY, invW, invH, '#F6F6FB');
            drawRectServerLocal(invX, invY, invW, invH, '#222', 3);
            drawText("i n v e n t o r y", invX + 20, invY + 10, '#262', 2, 18);

            if (userInventory.length === 0) {
                drawText("v a c i o", invX + 60, invY + 80, '#933', 2, 14);
            } else {
                for (let i = 0; i < userInventory.length; i++) {
                    const item = userInventory[i];
                    const itemX = invX + 10;
                    const itemY = invY + 40 + (i * 30);
                    drawFilledRect(itemX, itemY, 180, 25, '#fff');
                    drawRectServerLocal(itemX, itemY, 180, 25, '#bbb', 1);
                    drawFilledRect(itemX + 5, itemY + 3, 20, 20, item.color);
                    drawRectServerLocal(itemX + 5, itemY + 3, 20, 20, '#888', 1);
                    drawText(item.name, itemX + 30, itemY + 7, '#222', 1.5, 12);
                }
            }
        }

        // 5. Dibujar las monedas (Siempre visible para referencia)
        drawText("c o i n s :", stallX, groundY + 20, "#963", 2, 19);
        drawText("" + userCoins, stallX + 100, groundY + 20, "#282", 3, 20);
    }

    // --- UTILITY FUNCTIONS ---
    function getMouseCanvasCoords(e) {
        const rect = drawariaCanvas.getBoundingClientRect();
        return {
            x: (e.clientX - rect.left) * (drawariaCanvas.width / rect.width),
            y: (e.clientY - rect.top) * (drawariaCanvas.height / rect.height)
        };
    }

    // --- EVENT HANDLERS ---
    function onCanvasClick(e) {
        if (!isShopActive || SHOP_STATE !== 'shop') return;
        const { x: cx, y: cy } = getMouseCanvasCoords(e);

        for (const btn of lastButtons) {
            if (btn.type === 'buy' && cx >= btn.x && cx <= btn.x + btn.w && cy >= btn.y && cy <= btn.y + btn.h) {
                if (userCoins >= btn.prod.price) {
                    userCoins -= btn.prod.price;
                    userInventory.push({ ...btn.prod });
                    renderShop();
                    return;
                }
            }
        }
    }

    // --- CONTROL MENU ---
    function createControlMenu() {
        const menu = document.createElement('div');
        menu.id = 'drawaria-shop-menu';
        menu.style.cssText = `
            position: absolute;
            top: 20px;
            left: 20px;
            width: 200px;
            background: linear-gradient(135deg, #4b6cb7 0%, #182848 100%);
            border-radius: 12px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4);
            color: #fff;
            font-family: Arial, sans-serif;
            z-index: 10000;
            padding: 15px;
            cursor: move;
        `;
        // El texto inicial del botón refleja el estado inicial (OFF)
        menu.innerHTML = `
            <h4 style="margin: 0 0 10px; font-weight: bold; text-align: center;">Shop Control</h4>
            <div style="display: flex; flex-direction: column; gap: 10px;">
                <button id="toggle-shop" style="
                    padding: 8px;
                    border: none;
                    border-radius: 8px;
                    background-color: #e2a04a; /* Color de apagado */
                    color: white;
                    font-size: 14px;
                    font-weight: bold;
                    cursor: pointer;
                    transition: background-color 0.3s;
                ">Turn On</button>
                <div style="display: flex; gap: 8px;">
                    <button id="show-shop" style="flex: 1; padding: 8px; border: none; border-radius: 8px; background-color: #e2a04a; color: white; font-size: 14px; cursor: pointer;">Shop</button>
                    <button id="show-inventory" style="flex: 1; padding: 8px; border: none; border-radius: 8px; background-color: #64b5f6; color: white; font-size: 14px; cursor: pointer;">Inventory</button>
                </div>
                <button id="reset-shop" style="
                    padding: 8px;
                    border: none;
                    border-radius: 8px;
                    background-color: #8c73d9;
                    color: white;
                    font-size: 14px;
                    font-weight: bold;
                    cursor: pointer;
                    transition: background-color 0.3s;
                ">Reset Data</button>
            </div>
        `;
        document.body.appendChild(menu);

        let isDragging = false;
        let offset = { x: 0, y: 0 };
        const header = menu.querySelector('h4');
        header.addEventListener('mousedown', (e) => {
            isDragging = true;
            offset.x = e.clientX - menu.offsetLeft;
            offset.y = e.clientY - menu.offsetTop;
            menu.style.cursor = 'grabbing';
            e.preventDefault();
        });
        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                menu.style.left = `${e.clientX - offset.x}px`;
                menu.style.top = `${e.clientY - offset.y}px`;
            }
        });
        document.addEventListener('mouseup', () => {
            isDragging = false;
            menu.style.cursor = 'move';
        });

        const toggleButton = document.getElementById('toggle-shop');
        const shopButton = document.getElementById('show-shop');
        const invButton = document.getElementById('show-inventory');
        const resetButton = document.getElementById('reset-shop');

        toggleButton.addEventListener('click', () => {
            isShopActive = !isShopActive;
            if (isShopActive) {
                toggleButton.textContent = 'Turn Off';
                toggleButton.style.backgroundColor = '#4a90e2';
                renderShop(); // Fuerza un renderizado al encender
            } else {
                toggleButton.textContent = 'Turn On';
                toggleButton.style.backgroundColor = '#e2a04a';
                // Borra el área de la tienda al apagar
                drawLineServerLocal(0, 0, 0, 0, '#fff', 9999);
            }
        });

        shopButton.addEventListener('click', () => {
            SHOP_STATE = 'shop';
            if (isShopActive) renderShop();
        });

        invButton.addEventListener('click', () => {
            SHOP_STATE = 'inventory';
            if (isShopActive) renderShop();
        });

        resetButton.addEventListener('click', () => {
            userCoins = 20;
            userInventory = [];
            SHOP_STATE = 'shop';
            if (isShopActive) renderShop();
        });
    }

    // --- MAIN BOOTSTRAP ---
    waitUntilReady().then(() => {
        createControlMenu();
        const renderLoop = () => {
            // El bucle SOLO llama a renderShop si isShopActive es true.
            if (isShopActive) {
                renderShop();
            }
        };

        // Frecuencia del bucle reducida a 3000ms (3 segundos) para optimización.
        setInterval(renderLoop, 3000);
        document.getElementById('canvas').addEventListener('click', onCanvasClick);
    });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址