SugarCube Game Cheat Panel

Edit variables in SugarCube games easily via a draggable, collapsible UI with dynamic suggestions and auto-populated values.

// ==UserScript==
// @name         SugarCube Game Cheat Panel
// @version      1.1
// @description  Edit variables in SugarCube games easily via a draggable, collapsible UI with dynamic suggestions and auto-populated values.
// @author       skydk
// @match        *://*/*
// @grant        none
// @license      Apache 2.0
// @namespace https://gf.qytechs.cn/users/1436204
// ==/UserScript==

/* global SugarCube */

(function() {
    'use strict';

    function checkSugarCube() {
        return typeof SugarCube !== 'undefined' &&
               SugarCube.version &&
               typeof SugarCube.version.build !== 'undefined' &&
               Number(SugarCube.version.build) > 500 &&
               typeof SugarCube.State !== 'undefined' &&
               typeof SugarCube.State.variables !== 'undefined';
    }

    function setVariable(varName, value) {
        if (checkSugarCube()) {
            SugarCube.State.variables[varName] = value;
        } else {
            alert("SugarCube not detected or incompatible version!");
        }
    }

    function updateSuggestions() {
        const dataList = document.getElementById('varSuggestions');
        if (!dataList) return;
        // Clear existing options
        dataList.innerHTML = '';
        if (checkSugarCube()) {
            Object.keys(SugarCube.State.variables).forEach(key => {
                const option = document.createElement('option');
                option.value = key;
                dataList.appendChild(option);
            });
        }
    }

    function createUI() {
        let panel = document.createElement('div');
        panel.id = 'sugarcube-cheat-panel';
        panel.innerHTML = `
            <div id="scp-header">
                <span>SugarCube Cheat Panel</span>
                <span id="scp-toggle">–</span>
            </div>
            <div id="scp-content">
                <div class="scp-field">
                    <label for="varName">Variable:</label>
                    <input type="text" id="varName" placeholder="Enter variable" list="varSuggestions">
                    <datalist id="varSuggestions"></datalist>
                </div>
                <div class="scp-field">
                    <label for="varValue">Value:</label>
                    <input type="text" id="varValue" placeholder="Enter value">
                </div>
                <button id="setVar">Set Variable</button>
            </div>
        `;
        document.body.appendChild(panel);

        makeDraggable(panel, document.getElementById('scp-header'));

        document.getElementById('scp-toggle').addEventListener('click', function(e) {
            e.stopPropagation();
            let content = document.getElementById('scp-content');
            if (content.style.display === 'none') {
                content.style.display = 'block';
                this.textContent = '–';
            } else {
                content.style.display = 'none';
                this.textContent = '+';
            }
        });

        const varNameInput = document.getElementById('varName');
        varNameInput.addEventListener('focus', updateSuggestions);

        varNameInput.addEventListener('change', function() {
            let varName = this.value;
            const varValueInput = document.getElementById('varValue');
            if (checkSugarCube() && SugarCube.State.variables.hasOwnProperty(varName)) {
                varValueInput.value = SugarCube.State.variables[varName];
            } else {
                varValueInput.value = '';
            }
        });

        document.getElementById("setVar").addEventListener("click", function() {
            let varName = document.getElementById("varName").value;
            let varValue = document.getElementById("varValue").value;
            setVariable(varName, isNaN(varValue) ? varValue : Number(varValue));
        });
    }

    function makeDraggable(el, handle) {
        handle.style.cursor = 'move';
        let posX = 0, posY = 0, mouseX = 0, mouseY = 0;
        handle.addEventListener('mousedown', dragMouseDown);

        function dragMouseDown(e) {
            e.preventDefault();
            mouseX = e.clientX;
            mouseY = e.clientY;
            document.addEventListener('mousemove', elementDrag);
            document.addEventListener('mouseup', closeDragElement);
        }

        function elementDrag(e) {
            e.preventDefault();
            posX = mouseX - e.clientX;
            posY = mouseY - e.clientY;
            mouseX = e.clientX;
            mouseY = e.clientY;
            el.style.top = (el.offsetTop - posY) + "px";
            el.style.left = (el.offsetLeft - posX) + "px";
        }

        function closeDragElement() {
            document.removeEventListener('mousemove', elementDrag);
            document.removeEventListener('mouseup', closeDragElement);
        }
    }

    function addCustomCSS() {
        const css = `
            #sugarcube-cheat-panel {
                position: fixed;
                top: 10px;
                right: 10px;
                background: #2e2e2e;
                color: #e0e0e0;
                border: 1px solid #444;
                border-radius: 8px;
                z-index: 10000;
                width: 310px;
                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
                font-family: Arial, sans-serif;
            }
            #scp-header {
                padding: 10px;
                background: #3a3a3a;
                border-top-left-radius: 8px;
                border-top-right-radius: 8px;
                font-weight: bold;
                display: flex;
                justify-content: space-between;
                align-items: center;
                user-select: none;
            }
            #scp-content {
                padding: 10px;
            }
            .scp-field {
                margin-bottom: 10px;
            }
            .scp-field label {
                display: block;
                margin-bottom: 4px;
                font-size: 0.9em;
            }
            .scp-field input {
                padding: 6px;
                border: 1px solid #555;
                border-radius: 4px;
                background: #444;
                color: #e0e0e0;
                box-sizing: border-box;
            }
            #setVar {
                width: 100%;
                padding: 8px;
                border: none;
                border-radius: 4px;
                background: #5a5a5a;
                color: #e0e0e0;
                cursor: pointer;
                font-size: 1em;
            }
            #setVar:hover {
                background: #6a6a6a;
            }
            #scp-toggle {
                cursor: pointer;
                padding: 5px 10px;
                display: inline-block;
                text-align: center;
                font-size: 1.2em;
                user-select: none;
            }
            #scp-toggle:hover {
                background: rgba(255, 255, 255, 0.1);
                border-radius: 4px;
            }
        `;
        let style = document.createElement('style');
        style.type = 'text/css';
        style.appendChild(document.createTextNode(css));
        document.head.appendChild(style);
    }

    setTimeout(function() {
        if (checkSugarCube()) {
            addCustomCSS();
            createUI();
        } else {
            console.log("SugarCube not detected or incompatible version. Cheat panel will not be loaded.");
        }
    }, 3000);

})();

QingJ © 2025

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