SPNATI FULL CHEAT

cheat for spnati.net + config editor for online version

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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();
})();