eval

simple eval script

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         eval
// @namespace    <gone>
// @version      3.0.4
// @description  simple eval script
// @author       soph b
// @include      /^https?:\/\/(?:www\.)?(?:multiplayerpiano\.(?:org|net|dev|com)|(?:soot)?mpp\.(?:8448\.space|smp-meow\.net|(?:hyye|autoplayer)\.xyz)|piano\.(?:mpp\.community|ourworldofpixels\.com)|staging-mpp\.sad\.ovh)(?:\/.*)?/
// @icon         data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsSAAALEgHS3X78AAAAAXNSR0IArs4c6QAAAUhJREFUeF7tmskOwyAMROH/P5qKAxVCpB4kK7LLyy0pYpnMgklrKaWVi68KADAACeABF3tgwQRJAVKAFCAFSAEDgdZsktTaAyXfJcUgAMAAJGCKGw/ABEkBUyYRGxCDXtVg1r2CxACFugCQdLMEA/AApxMhPAAPyFkwYYKKCb6pb2UsZV/S2ygVqsQAZVLKYMrElbGUfgAABiABPEDxJUyQGBRqASWaFLop8aWMpfTjGoPqgB7trgfAA8STPiQTPOkwW1sAUFIg21s9mW84Bswm2JOl388Jc3pvgRESAHXBA4wZlBWglACMSQ8gdgvtbVa2jGcne5LwDJgX9fSm/54Buzf75AU7VvySQTgGWJr1/h0A2AcI1aA37SL1hwSQABLg7/L2V81IruU8F0wQE8QE7zDBtWL8lty3SGA9Uxj3V5jg7rxgPPsAQdQYDUupC18AAAAASUVORK5CYII=
// ==/UserScript==

let header = {};
async function populateHeader() {
    header = {}; // set header to default

    /* fetch script */
    const updateURL = 'https://raw.githubusercontent.com/sophb-ccjt/eval/refs/heads/main/eval.user.js';
    const r = await fetch(updateURL);
    const script = await r.text();

    /* parse header */
    const headerLines = script
        .split("// ==/Userscript==")[0] // split script into header at index 0 and script content at index 1
        .split('\n') // split by lines
        .slice(1, -1); // remove the first item of the array, giving the header's lines without the separators

    const headerRegex = /\/\/ +@(.+) +(.+)/g; // group 1 is property name, group 2 is property value
    headerLines.forEach(line => {
        const lineMatch = headerRegex.exec(line);

        if (!lineMatch) return; // skip if there are no matches

        const groups = lineMatch
            .map(v => v) // normalize array by removing items with keys
            .slice(1) // remove first item of array, giving only groups
            .map(v => v.trim()); // trim whitespace (maybe merge with .map above?)
        
        header[groups[0]] = groups[1];
    });

    // freeze the header so it can't be messed with during runtime
    Object.freeze(header);
}
// populate the header
populateHeader();

let errors = [
    'failed',
    'error',
    'err',
    'nope',
    'nuh uh',
    'no',
    'uh oh',
    "yesn't",
    'oopsies',
    'oops',
    'oop',
    'fail',
    'false',
    ':(',
    ';(',
    'D:',
    'Uncaught SkillIssue',
    'Uncaught IntelligenceError',
    '❌',
    '❎',
    '🤷',
    'javascript is weird, right?',
    'S#!%',
    'F@$#',
    ';;;;;;;;;;;;;;;;;;;;;;;;;;;'
];
const zwsp = "​";
let outsymbols = [
    "⧔",
    ">",
    "<",
    zwsp + "~",
    "⤷",
    "⧐"
];
let outsymbol = outsymbols[0];
let types = false;
let validCmds = [
    '.',
    '>'
];

if (localStorage.eval_variables == null) {
    // defaults
    localStorage.eval_variables = JSON.stringify(
        {
            errors,
            outsymbol,
            outsymbols,
            types,
            validCmds
        }
    );
}
// set variables
const variables = JSON.parse(localStorage.eval_variables);
// load variables from storage
for (const [variable, value] of Object.entries(variables)) {
    window[variable] = value;
}

const log = [];
const charLimit = 512;
MPP.client.on("a", function(msg) {
    // helpers
    const args = msg.a.split(" ");
    const cmd = args[0];
    const error = errors[Math.floor(Math.random()*errors.length)];
    const client = MPP.client;
    const logMsg = (text) => {
        const prefix = `${Date.now()} [EVAL] `;
        const suffix = '';
        log.push(text);
        console.log(prefix + text + suffix);
    }

    // send function
    const send = (msg) => {
        if (typeof msg !== "string")
            msg = JSON.stringify(msg);

        if (msg.length > charLimit) {
            if (msg.length > charLimit * 2) {
                for (let i = 0; i < Math.floor(msg.length / charLimit) + 1; i++) {
                    MPP.client.sendArray([{
                        "m": "dm",
                        "message": msg.slice(
                            charLimit * i, charLimit * (i + 1)
                        ),
                        "_id": msg.p._id
                    }])
                }
            } else {
                for (let i = 0; i < Math.floor(msg.length / charLimit) + 1; i++) {
                    MPP.chat.send(
                        msg.slice(
                            charLimit * i, charLimit * (i + 1)
                        )
                    );
                }
            }
        } else
            MPP.chat.send(msg);
    }
    
    // the actual eval
    if (MPP.client.getOwnParticipant()._id === msg.p._id) {
        if (validCmds.includes(cmd)) {
            try {
                const result = eval(msg.a.substring(cmd.length).trim());
                const app = types ? `[${(typeof result).toUpperCase()}] ` : "";
                const output = (text) => {
                    MPP.chat.send(`${outsymbol} ${app}${text}`);
                }
                switch (typeof result) {
                    case 'string':
                        output(
                            (() => {
                                function btoaCensor(text, targetStr, replacer, depth = 10) {
                                    let finalStr = targetStr;
                                    for (let i = 1; i <= depth; i++) {
                                        finalStr = finalStr
                                        .replaceAll(
                                            eval(`${
                                                'btoa('.repeat(i)
                                            }"${
                                                text.replaceAll('"', '\\"')
                                            }"${
                                                ')'.repeat(i)
                                            }`)
                                        , replacer);
                                    }
                                    return finalStr;
                                }
                                return btoaCensor(localStorage.token, result, '[no]', 15);
                            })()
                        );
                        break;


                    case 'object':
                        const maxItems = 5;
                        if (result === null) {
                            // null
                            output('null')
                        } else if (Array.isArray(result)) {
                            // array
                            const arrayItemsStr = [...result]
                                .slice(0, maxItems)
                                .map(JSON.stringify) // lore accurate representation
                                .join(', ');
                            const arrayStr = `(${result.length} items) [ ${arrayItemsStr}${result.length > maxItems ? ', ...' : ''} ]`;
                            output(arrayStr);
                        } else {
                            // plain-object
                            output(JSON.stringify(result));

                            /* === NOTE === */
                            // make behavior consistent with array?
                            // don't know how to do that yet
                            // do when you get an epiphany or however you spell it
                        }
                        break;

                    case 'function':
                        output(`𝑓 ${result.name}(...${result.length})`)
                        break;

                    default:
                        output(JSON.stringify(result))
                        break;
                }
            } catch (err) {
                if (!err.message) {
                    send(`${outsymbol} *${error}* - ❌ [Raw \`throw\`] ${err}`);
                } else {
                    send(`${outsymbol} *${error}* - ❌ [${err.name}] ${err}`);
                }
                logMsg(`error: ${err}`);
            } finally {
                logMsg('eval executed');
                for (const [variable, value] of Object.entries(variables)) {
                    if (globalThis[variable] !== value) {
                        variables[variable] = window[variable];
                        localStorage.eval_variables = JSON.stringify(variables);
                    }
                }
            }
        }
        if (new RegExp(`(?:${validCmds.map(RegExp.escape).join('|')})about`).test(cmd)) {
            MPP.chat.send("eval - made by ccjt - running version " + header.version)
        }
    }
});