SPNATI FULL CHEAT

cheat for spnati.net + config editor for online version

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==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();
})();