Scratch Admin Permissions

Sets admin perms for Scratch!! Client side only though D:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Scratch Admin Permissions
// @namespace    http://tampermonkey.net/
// @version      5.2
// @description  Sets admin perms for Scratch!! Client side only though D:
// @author       Phil 🥹👍
// @license      MIT
// @match        https://scratch.mit.edu/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    function tryGrant() {
        const appEl = document.querySelector('#app');
        if (!appEl) return false;

        const keys = Object.keys(appEl);
        const reactKey = keys.find(key => key.startsWith('__reactContainer$') || key.startsWith('__reactFiber$'));
        if (!reactKey) return false;

        try {
            const internalInstance = appEl[reactKey];
            function findStore(obj, depth = 0) {
                if (!obj || depth > 15) return null;
                if (obj.store && typeof obj.store.getState === 'function') return obj.store;
                if (obj.props && obj.props.store && typeof obj.props.store.getState === 'function') return obj.props.store;

                const keys = Object.keys(obj);
                for (let key of keys) {
                    if (['child', 'memoizedState', 'memoizedProps', 'element', 'props', 'children'].includes(key)) {
                        if (obj[key] && typeof obj[key] === 'object') {
                            const found = findStore(obj[key], depth + 1);
                            if (found) return found;
                        }
                    }
                }
                return null;
            }

            const store = findStore(internalInstance);
            if (store) {
                // Set the admin permission
                store.getState().permissions.admin = true;

                // CRITICAL: Force the comment container to stay visible
                // Scratch hides it when it thinks you are an admin.
                setInterval(() => {
                    const commentBox = document.querySelector('.comment-container');
                    if (commentBox) {
                        commentBox.style.display = 'block';
                    }
                }, 1000);

                console.log("%c[Admin Grant] SUCCESS: Admin perms active. Comments force-patched.", "color: green; font-weight: bold;");
                return true;
            }
        } catch (e) {}
        return false;
    }

    let attempts = 0;
    const interval = setInterval(() => {
        attempts++;
        if (tryGrant() || attempts > 10) clearInterval(interval);
    }, 500);
})();