SPNATI FULL CHEAT

cheat for spnati.net + config editor for online version

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         SPNATI FULL CHEAT
// @name:ru      SPNATI ПОЛНЫЙ ЧИТ
// @namespace    http://tampermonkey.net/
// @version      2026-04-18
// @description  cheat for spnati.net + config editor for online version
// @description:ru  чит для spnati.net + редактор confg-настроек для онлайн-версии
// @author       TOOM_TYM
// @match        https://*.spnati.net/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=spnati.net
// @grant        none
// @license      MIT

// ==/UserScript==




(function() {
    'use strict';
    // -- CONFIG EDITOR
    const fakeConfig = `
            <config>
                <debug>true</debug>
                <epilogues>true</epilogues>
                <epilogues-unlocked>true</epilogues-unlocked>
                <collectibles>true</collectibles>
                <collectibles-unlocked>true</collectibles-unlocked>

                <default-fill>default</default-fill>
                <custom-cards>true</custom-cards>
                <default-card-deck>default</default-card-deck>

                <alternate-costumes>true</alternate-costumes>
                <alternate-costume-sets>valentines</alternate-costume-sets>
                <alternate-costume-sets>april_fools</alternate-costume-sets>
                <alternate-costume-sets>easter</alternate-costume-sets>
                <alternate-costume-sets>summer</alternate-costume-sets>
                <alternate-costume-sets>halloween</alternate-costume-sets>
                <alternate-costume-sets>xmas</alternate-costume-sets>
                <alternate-costume-sets>all</alternate-costume-sets>


                <!-- <default-costume-set>summer</default-costume-set> че это -->

                <default-background>inventory</default-background>
                <resort>false</resort>
                <testing-max-age>31</testing-max-age>


                <include-status>testing</include-status>
                <include-status>offline</include-status>
                <include-status>incomplete</include-status>

                <commit>9a368f9e7d04ae3a1b866a84aa0171c76ad7f3e3</commit>
                <version-tag>v13.56.0-6-g9a368f9e7d</version-tag>
            </config>

        `;
    // -- CONFIG EDITOR






    // code of cheat
    const CONFIG = {
        title: "BY TOOM_TYM",
        elements: [
            { type: 'button', text: 'Globals,info', callback: () => Globals() },
            { type: 'button', text: 'ace-high straight', callback: () => ace() },
            {
                type: 'toggle',
                text: 'Chose Loser',
                id: 'loser_picker',
                default: false,
                callback: (active) => {
                    if (active) {
                        enableLoserPicker();
                    } else {
                        disableLoserPicker();
                    }
                }
            },
            {
                type: 'toggle',
                text: 'Card Peeking',
                id: 'always_reveal',
                default: false,
                callback: (active) => {
                    if (active) {
                        window.revealTimer = setInterval(() => {
                            const suitNames = ['spade', 'heart', 'diamo', 'clubs'];

                            for (let p = 1; p <= 4; p++) {
                                try {
                                    const player = players[p];
                                    if (!player || !player.hand || !player.hand.cards) continue;

                                    const container = document.getElementById(`opponent-card-area-${p}`);
                                    if (container) {
                                        container.classList.add('shown');
                                        container.style.width = "auto";
                                        container.style.whiteSpace = "nowrap";
                                    }

                                    player.hand.cards.forEach((card, i) => {
                                        const img = document.getElementById(`player-${p}-card-${i + 1}`);
                                        if (img && card) {
                                            const suitName = suitNames[card.suit];
                                            const rank = card.rank;
                                            const newSrc = `img/cards/default/${suitName}${rank}.svg`;
                                            if (img.getAttribute('src') !== newSrc) {
                                                img.src = newSrc;
                                            }
                                            img.alt = `${suitName}${rank}`
                                            img.style.margin = "0 1px";
                                            img.style.position = "static";
                                            img.style.width = "auto";
                                            img.style.display = "inline-block";
                                        }
                                    });
                                } catch (e) {
                                }
                            }
                        }, 500);
                    } else {
                        if (window.revealTimer) {
                            clearInterval(window.revealTimer);
                            window.revealTimer = null;
                        }
                    }
                }
            },

        ]
    };

    const style = document.createElement('style');
    style.innerHTML = `
        #gui-fab { position: fixed; top: 20px; right: 20px; width: 45px; height: 45px; background: #ff4b2b; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px; cursor: pointer; z-index: 1000000; box-shadow: 0 4px 10px rgba(0,0,0,0.3); user-select: none; transition: 0.3s; }
        #gui-m {
            position: fixed;
            top: 75px; /* Сразу под кнопкой */
            right: -300px; /* Спрятано за краем */
            width: 220px;
            background: rgba(26, 26, 26, 0.95);
            border-radius: 10px;
            padding: 15px;
            display: flex;
            flex-direction: column;
            z-index: 1000002;
            color: #fff;
            font-family: sans-serif;
            box-shadow: -5px 5px 20px rgba(0,0,0,0.4);
            transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            border: 1px solid #333;
        }
        #gui-m.active { right: 20px; }
        .g-title { text-align: center; font-size: 14px; font-weight: bold; margin-bottom: 10px; border-bottom: 1px solid #444; padding-bottom: 8px; color: #ff4b2b; }
        .g-btn { background: #333; border: none; color: #fff; padding: 10px; margin: 4px 0; border-radius: 5px; cursor: pointer; transition: 0.2s; width: 100%; font-size: 13px; }
        .g-btn:hover { background: #444; }
        .g-btn:active { background: #555; }
        .g-row { display: flex; justify-content: space-between; align-items: center; background: #222; padding: 8px; margin: 4px 0; border-radius: 5px; font-size: 13px; }
        .g-tog { position: relative; width: 34px; height: 18px; -webkit-appearance: none; background: #444; border-radius: 10px; outline: none; transition: 0.3s; cursor: pointer; }
        .g-tog:checked { background: #4caf50; }
        .g-tog:before { content: ''; position: absolute; width: 14px; height: 14px; border-radius: 50%; top: 2px; left: 2px; background: #fff; transition: 0.3s; }
        .g-tog:checked:before { left: 18px; }
        .g-close { background: #444; color: #bbb; margin-top: 8px; font-size: 11px; padding: 5px; }
    `;
    document.head.appendChild(style);

    const fab = document.createElement('div');
    fab.id = 'gui-fab';
    fab.innerHTML = '😈';

    const menu = document.createElement('div');
    menu.id = 'gui-m';

    let html = `<div class="g-title">${CONFIG.title}</div>`;
    CONFIG.elements.forEach((el, i) => {
        if (el.type === 'button') html += `<button class="g-btn" id="g-el-${i}">${el.text}</button>`;
        else if (el.type === 'toggle') html += `<div class="g-row"><span>${el.text}</span><input type="checkbox" class="g-tog" id="g-el-${i}" ${el.default ? 'checked' : ''}></div>`;
    });
    html += `<button class="g-btn g-close" id="g-close">HIDE</button>`;
    menu.innerHTML = html;

    document.body.appendChild(fab);
    document.body.appendChild(menu);

    function toggle() {
        menu.classList.toggle('active');
    }

    fab.onclick = toggle;
    document.getElementById('g-close').onclick = toggle;

    CONFIG.elements.forEach((el, i) => {
        const dom = document.getElementById(`g-el-${i}`);
        if (el.type === 'button') dom.onclick = () => el.callback();
        else dom.onchange = (e) => el.callback(e.target.checked);
    });

    function updateVisuals() {
        try {
            const cardElements = document.querySelectorAll('#player-game-card-area input.large-card-image');
            const suitNames = ['spade', 'heart', 'diamo', 'clubs'];
            cardElements.forEach((img, index) => {
                const card = players[0].hand.cards[index];
                if (card) {
                    img.src = `img/cards/default/${suitNames[card.suit]}${card.rank}.svg`;
                }
            });
        } catch(e) {}
    }


    function Globals(){
        alert(`
        -- unlocked everything
        -- removed wearing limit
        `)
    }
    function ace(){
        players[0].hand.cards = [14, 13, 12, 11, 10].map(function(n) {
            let randomSuit = Math.floor(Math.random() * 4);
            return new Card(randomSuit, n);
        });

        try {
            const cardElements = document.querySelectorAll('#player-game-card-area input.large-card-image');
            const hand = players[0].hand.cards;
            const suitNames = ['spade', 'heart', 'diamo', 'clubs'];

            if (cardElements.length === 0) {
                throw new Error("err");
            }

            cardElements.forEach((img, index) => {
                const card = hand[index];
                if (card) {
                    let suitName = suitNames[card.suit];
                    let rank = card.rank;
                    img.src = `img/cards/default/${suitName}${rank}.svg`;
                    if (typeof card.toString === 'function') {
                        img.alt = card.toString();
                    }
                }
            });
        } catch (guiError) {
            console.warn("visual error");
        }
    }
    function enableLoserPicker() {
        const labels = document.querySelectorAll('.bordered.name-label');

        labels.forEach((label, index) => {
            label.style.cursor = 'crosshair';
            label.onmouseenter = () => {
                label.style.outline = '3px solid red';
                label.style.backgroundColor = 'rgba(255, 0, 0, 0.2)';
            };

            label.onmouseleave = () => {
                label.style.outline = 'none';
                label.style.backgroundColor = '';
            };


            label.onclick = () => {
                let playerIndex = index - 4;
                if (playerIndex >= 0 && players[playerIndex]) {
                    const target = players[playerIndex];
                    players[playerIndex].hand.strength = -3
                    players[playerIndex].hand.cards = [7, 5, 4, 3, 2].map(function(n) {
                        let randomSuit = Math.floor(Math.random() * 4);
                        return new Card(randomSuit, n);
                    });
                }
            };
        });


    }

    function disableLoserPicker() {
        const labels = document.querySelectorAll('.bordered.name-label');
        labels.forEach(label => {
            label.style.outline = 'none';
            label.style.backgroundColor = '';
            label.style.cursor = 'default';
            label.onclick = null;
            label.onmouseenter = null;
            label.onmouseleave = null;
        });
    }
    const originalFetch = window.fetch;
    window.fetch = async function(...args) {
        const url = args[0];
        if (typeof url === 'string' && url.includes("config.xml")) {

            return new Response(fakeConfig, {
                status: 200,
                statusText: 'OK',
                headers: { 'Content-Type': 'text/xml' }
            });
        }
        return originalFetch.apply(this, args);
    };


    if (typeof window.validateTitleScreen === 'function') {
        window.validateTitleScreen = function() {
            // THIS IS MODIFED "validateTitleScreen" FUNCTION
            /* determine the player's name */
            var playerName = '';

            if ($nameField.val() != "") {
                playerName = $nameField.val();
            } else if (humanPlayer.gender == "male") {
                playerName = "Mister";
            } else if (humanPlayer.gender == "female") {
                playerName = 'Miss';
            }

            humanPlayer.first = playerName;
            humanPlayer.label = playerName;

            $gameLabels[HUMAN_PLAYER].text(humanPlayer.label);

            /* count clothing */
            var clothingItems = save.selectedClothing();
            console.log(clothingItems.length);


            /* dress the player */
            wearClothing();
            setPlayerTags();

            save.savePlayer();
            console.log(players[0]);

            setLocalDayOrNight();
            updateAllBehaviours(null, null, SELECTED);
            updateSelectionVisuals();

            Sentry.setTag("screen", "select-main");
            screenTransition($titleScreen, $selectScreen);

            updateAnnouncementDropdown();
            showAnnouncements();

            if (curResortEvent && !curResortEvent.resort.checkCharacterThreshold()) {
                curResortEvent.resort.setFlag(false);
            }

        };
    }
    const pinButtonToTop = () => {
        const modal = document.querySelector('.bordered.modal-dialog-surface');
        const footer = document.querySelector('.modal-footer');
        const selectBtn = document.getElementById('stripping-modal-button');
        if (modal && footer && selectBtn) {
            Object.assign(footer.style, {
                position: 'absolute',
                top: '40px',
                left: '0',
                right: '0',
                zIndex: '9999',
                display: 'flex',
                justifyContent: 'center',
                background: 'transparent',
                border: 'none',
                padding: '0',
                pointerEvents: 'none'
            });
            Object.assign(selectBtn.style, {
                pointerEvents: 'auto',
                boxShadow: '0 0 15px rgba(0,0,0,0.8)', // this just for make strip button avalible when you wearing more than 8 clothes
                width: '80%',
                maxWidth: '300px'
            });
            const body = document.querySelector('.modal-body');
            if (body) {
                body.style.paddingTop = '60px';
            }
        }
    };
    const observer = new MutationObserver(() => pinButtonToTop());
    observer.observe(document.body, { childList: true, subtree: true });
    pinButtonToTop();
})();