Cooking Licker - Mod Menu

Terminal-style mod menu for Cookie Clicker with dot network background

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Cooking Licker - Mod Menu
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Terminal-style mod menu for Cookie Clicker with dot network background
// @author       Viros
// @match        https://orteil.dashnet.org/cookieclicker/
// @match        https://cookieclicker.eu/cookieclicker/
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Wait for Game object to be fully loaded
    let checkInterval = setInterval(() => {
        if (typeof Game !== 'undefined' && Game.ready) {
            clearInterval(checkInterval);
            initModMenu();
        }
    }, 100);

    function initModMenu() {
        // Create container for terminal and canvas
        const container = document.createElement('div');
        container.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 9999;
            width: 340px;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 4px 16px rgba(0,0,0,0.3);
            font-family: 'Courier New', 'Fira Code', monospace;
        `;

        // Canvas for dots and lines (background)
        const canvas = document.createElement('canvas');
        canvas.style.cssText = `
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 1;
        `;

        // Terminal panel (white background)
        const panel = document.createElement('div');
        panel.style.cssText = `
            position: relative;
            z-index: 2;
            background: #fff;
            color: #000;
            font-family: 'Courier New', 'Fira Code', monospace;
            font-size: 12px;
            padding: 12px;
            border-radius: 8px;
            border: 1px solid #aaa;
        `;

        panel.innerHTML = `
            <div style="margin-bottom: 8px; border-bottom: 1px solid #ccc; padding-bottom: 4px;">
                <span style="font-weight: bold; font-size: 14px;">$ cooking-licker</span>
                <span style="float: right;">v1.0</span>
            </div>
            <div style="font-size: 11px; margin-bottom: 12px; color: #555;">idk why u need cheats for this. But uh here xd</div>
            
            <!-- Quick Cookie Buttons -->
            <div style="margin-bottom: 8px;">
                <div style="font-size: 10px; color: #666; margin-bottom: 4px;">> COOKIES</div>
                <div style="display: flex; gap: 6px; flex-wrap: wrap;">
                    <button class="ck-cmd" data-cmd="cookies-1k" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">+1k</button>
                    <button class="ck-cmd" data-cmd="cookies-1m" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">+1M</button>
                    <button class="ck-cmd" data-cmd="cookies-1b" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">+1B</button>
                    <button class="ck-cmd" data-cmd="cookies-inf" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">∞</button>
                </div>
            </div>
            
            <!-- Sugar Lumps -->
            <div style="margin-bottom: 8px;">
                <div style="font-size: 10px; color: #666; margin-bottom: 4px;">> SUGAR LUMPS</div>
                <div style="display: flex; gap: 6px;">
                    <button class="ck-cmd" data-cmd="lumps-10" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">+10 lumps</button>
                    <button class="ck-cmd" data-cmd="lumps-100" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">+100 lumps</button>
                </div>
            </div>
            
            <!-- Achievements & Unlocks -->
            <div style="margin-bottom: 8px;">
                <div style="font-size: 10px; color: #666; margin-bottom: 4px;">> ACHIEVEMENTS</div>
                <div style="display: flex; gap: 6px; flex-wrap: wrap;">
                    <button class="ck-cmd" data-cmd="achieve-all" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">all achievements</button>
                    <button class="ck-cmd" data-cmd="upgrades-all" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">all upgrades</button>
                    <button class="ck-cmd" data-cmd="ruin-fun" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">ruin the fun</button>
                </div>
            </div>
            
            <!-- Save & Utility -->
            <div style="margin-bottom: 8px;">
                <div style="font-size: 10px; color: #666; margin-bottom: 4px;">> UTILITIES</div>
                <div style="display: flex; gap: 6px; flex-wrap: wrap;">
                    <button class="ck-cmd" data-cmd="save" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">save game</button>
                    <button class="ck-cmd" data-cmd="export" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">export save</button>
                    <button class="ck-cmd" data-cmd="ascend" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">ascend</button>
                </div>
            </div>
            
            <!-- Golden Cookie Spawner -->
            <div style="margin-bottom: 8px;">
                <div style="font-size: 10px; color: #666; margin-bottom: 4px;">> GOLDEN COOKIES</div>
                <div style="display: flex; gap: 6px; flex-wrap: wrap;">
                    <button class="ck-cmd" data-cmd="gc-frenzy" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">frenzy</button>
                    <button class="ck-cmd" data-cmd="gc-click" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">click frenzy</button>
                    <button class="ck-cmd" data-cmd="gc-sweet" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">sweet lump</button>
                </div>
            </div>
            
            <!-- Auto Clicker Toggle -->
            <div style="margin-bottom: 8px;">
                <div style="font-size: 10px; color: #666; margin-bottom: 4px;">> AUTO CLICKER</div>
                <div style="display: flex; gap: 6px;">
                    <button id="toggle-autoclicker" style="flex: 1; padding: 4px; background: #eee; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">[OFF] start auto</button>
                </div>
            </div>
            
            <!-- Custom Command Input -->
            <div style="margin-top: 8px; border-top: 1px solid #ccc; padding-top: 8px;">
                <input type="text" id="ck-custom-cmd" placeholder="Game.Earn(1000000)" style="width: 100%; padding: 6px; margin-bottom: 6px; border-radius: 4px; border: 1px solid #aaa; font-family: monospace; box-sizing: border-box;">
                <button id="ck-run-cmd" style="width: 100%; padding: 6px; background: #eee; color: #000; border: 1px solid #aaa; border-radius: 4px; font-family: monospace; cursor: pointer;">> execute</button>
            </div>
            
            <div id="ck-status" style="font-size: 10px; background: #f5f5f5; padding: 6px; border-radius: 4px; margin-top: 8px; word-wrap: break-word; border-left: 3px solid #888; font-family: monospace;">> ready. select a command.</div>
        `;

        container.appendChild(canvas);
        container.appendChild(panel);
        document.body.appendChild(container);

        // Draw network on canvas
        function drawNetwork() {
            const rect = container.getBoundingClientRect();
            canvas.width = rect.width;
            canvas.height = rect.height;
            const ctx = canvas.getContext('2d');
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            const dotCount = 45;
            const dots = [];
            const minDistance = 45;
            const maxDistance = 80;

            for (let i = 0; i < dotCount; i++) {
                dots.push({
                    x: Math.random() * canvas.width,
                    y: Math.random() * canvas.height
                });
            }

            ctx.beginPath();
            ctx.strokeStyle = '#ccc';
            ctx.lineWidth = 1;
            for (let i = 0; i < dots.length; i++) {
                for (let j = i + 1; j < dots.length; j++) {
                    const dx = dots[i].x - dots[j].x;
                    const dy = dots[i].y - dots[j].y;
                    const dist = Math.sqrt(dx * dx + dy * dy);
                    if (dist < maxDistance && dist > minDistance) {
                        ctx.beginPath();
                        ctx.moveTo(dots[i].x, dots[i].y);
                        ctx.lineTo(dots[j].x, dots[j].y);
                        ctx.stroke();
                    }
                }
            }

            ctx.fillStyle = '#aaa';
            for (let dot of dots) {
                ctx.beginPath();
                ctx.arc(dot.x, dot.y, 2, 0, Math.PI * 2);
                ctx.fill();
            }
        }

        const resizeObserver = new ResizeObserver(() => drawNetwork());
        resizeObserver.observe(container);
        drawNetwork();

        // Status update helper
        function setStatus(msg, isError = false) {
            const statusDiv = document.getElementById('ck-status');
            statusDiv.innerHTML = `> ${msg}`;
            statusDiv.style.borderLeftColor = isError ? '#d32f2f' : '#888';
            setTimeout(() => {
                if (document.getElementById('ck-status') === statusDiv) {
                    statusDiv.style.borderLeftColor = '#888';
                }
            }, 2000);
        }

        // Command executor
        function executeCommand(cmd, value = null) {
            try {
                switch(cmd) {
                    case 'cookies-1k':
                        Game.Earn(1000);
                        setStatus(`added 1,000 cookies. total: ${Beautify(Game.cookies)}`);
                        break;
                    case 'cookies-1m':
                        Game.Earn(1000000);
                        setStatus(`added 1,000,000 cookies. total: ${Beautify(Game.cookies)}`);
                        break;
                    case 'cookies-1b':
                        Game.Earn(1000000000);
                        setStatus(`added 1,000,000,000 cookies. total: ${Beautify(Game.cookies)}`);
                        break;
                    case 'cookies-inf':
                        Game.cookies = Infinity;
                        setStatus(`cookies set to ∞. you have infinite cookies.`);
                        break;
                    case 'lumps-10':
                        Game.lumps += 10;
                        setStatus(`added 10 sugar lumps. total: ${Game.lumps}`);
                        break;
                    case 'lumps-100':
                        Game.lumps += 100;
                        setStatus(`added 100 sugar lumps. total: ${Game.lumps}`);
                        break;
                    case 'achieve-all':
                        for (let i in Game.AchievementsById) {
                            if (!Game.AchievementsById[i].won) {
                                Game.AchievementsById[i].won = 1;
                            }
                        }
                        Game.CalculateLumps();
                        setStatus(`all achievements unlocked.`);
                        break;
                    case 'upgrades-all':
                        for (let i in Game.UpgradesById) {
                            if (Game.UpgradesById[i].unlock && !Game.UpgradesById[i].bought) {
                                Game.UpgradesById[i].unlock();
                            }
                        }
                        setStatus(`all upgrades unlocked.`);
                        break;
                    case 'ruin-fun':
                        Game.RuinTheFun();
                        setStatus(`RUIN THE FUN executed. everything unlocked.`);
                        break;
                    case 'save':
                        Game.Save();
                        setStatus(`game saved manually.`);
                        break;
                    case 'export':
                        const saveStr = Game.WriteSave(1);
                        prompt("Copy your save string:", saveStr);
                        setStatus(`save string copied to clipboard dialog.`);
                        break;
                    case 'ascend':
                        Game.Ascend();
                        setStatus(`ascending... goodbye cookies.`);
                        break;
                    case 'gc-frenzy':
                        Game.shimmerTypes['golden'].spawn();
                        setStatus(`golden cookie spawned (frenzy chance).`);
                        break;
                    case 'gc-click':
                        Game.shimmerTypes['golden'].spawn({force: 'click frenzy'});
                        setStatus(`click frenzy golden cookie spawned.`);
                        break;
                    case 'gc-sweet':
                        Game.shimmerTypes['golden'].spawn({force: 'sweet'});
                        setStatus(`sugar lump golden cookie spawned.`);
                        break;
                    default:
                        if (value !== null) {
                            eval(value);
                            setStatus(`executed: ${value.substring(0, 50)}${value.length > 50 ? '...' : ''}`);
                        }
                }
            } catch(e) {
                setStatus(`error: ${e.message}`, true);
            }
        }

        // Button handlers
        document.querySelectorAll('.ck-cmd').forEach(btn => {
            btn.addEventListener('click', () => {
                const cmd = btn.getAttribute('data-cmd');
                executeCommand(cmd);
            });
        });

        document.getElementById('ck-run-cmd').addEventListener('click', () => {
            const input = document.getElementById('ck-custom-cmd');
            if (input.value.trim()) {
                executeCommand('custom', input.value);
                input.value = '';
            } else {
                setStatus('enter a command (e.g., Game.Earn(50000))', true);
            }
        });

        document.getElementById('ck-custom-cmd').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                document.getElementById('ck-run-cmd').click();
            }
        });

        // Auto Clicker functionality
        let autoClickerInterval = null;
        const autoBtn = document.getElementById('toggle-autoclicker');
        
        function toggleAutoClicker() {
            if (autoClickerInterval) {
                clearInterval(autoClickerInterval);
                autoClickerInterval = null;
                autoBtn.innerHTML = '[OFF] start auto';
                autoBtn.style.background = '#eee';
                setStatus('auto clicker stopped.');
            } else {
                autoClickerInterval = setInterval(() => {
                    if (typeof Game !== 'undefined' && Game.ClickCookie) {
                        Game.ClickCookie();
                    }
                }, 50); // 20 clicks per second
                autoBtn.innerHTML = '[ON] stop auto';
                autoBtn.style.background = '#ffcccc';
                setStatus('auto clicker started (20 clicks/sec).');
            }
        }
        
        autoBtn.addEventListener('click', toggleAutoClicker);

        // Cleanup on page unload
        window.addEventListener('beforeunload', () => {
            if (autoClickerInterval) clearInterval(autoClickerInterval);
        });

        setStatus('mod menu loaded. cookies: ' + Beautify(Game.cookies));
        
        // Helper for number formatting (if Beautify not available)
        function Beautify(num) {
            if (typeof Game !== 'undefined' && Game.Beautify) return Game.Beautify(num);
            if (num === Infinity) return '∞';
            if (num >= 1e12) return (num / 1e12).toFixed(2) + 'T';
            if (num >= 1e9) return (num / 1e9).toFixed(2) + 'B';
            if (num >= 1e6) return (num / 1e6).toFixed(2) + 'M';
            if (num >= 1e3) return (num / 1e3).toFixed(2) + 'K';
            return Math.floor(num).toString();
        }
    }
})();