【已失效】编程猫 CoCo 作品分享审核绕过

绕过 CoCo 作品分享的审核机制,让他人可以看到你分享的作品,请低调使用

נכון ליום 17-08-2024. ראה הגרסה האחרונה.

// ==UserScript==
// @name         【已失效】编程猫 CoCo 作品分享审核绕过
// @namespace    https://s-lightning.github.io/
// @version      0.1.9
// @description  绕过 CoCo 作品分享的审核机制,让他人可以看到你分享的作品,请低调使用
// @author       SLIGHTNING
// @match        http://coco.codemao.cn/editor/*
// @match        https://coco.codemao.cn/editor/*
// @icon         https://coco.codemao.cn/favicon.ico
// @grant        none
// @license      AGPL-3.0
// ==/UserScript==

(function() {
    'use strict';

    ;(function() {
        if (location.pathname != "/editor/") {
            return
        }
        let originalFetch = fetch
        fetch = async function(input, init) {
            let response = await originalFetch(input, init)
            if (input == "https://static.codemao.cn/coco/whitelist.json") {
                try {
                    let workID = location.search.match(/(?<=(\?|&)workId=)[0-9]+(?=$|&)/)
                    if (workID == null) {
                        throw new Error("获取作品 ID 失败,可能因为作品未保存到云端,请将作品保存到云端后再尝试。")
                    }
                    workID = Number(workID[0])
                    if (workID == 0 || isNaN(workID)) {
                        throw new Error("获取作品 ID 失败,可能因为作品未保存到云端,请将作品保存到云端后再尝试。")
                    }
                    let whiteList = await response.json()
                    whiteList.push(workID)
                    return new Response(JSON.stringify(whiteList), {
                        ...response
                    })
                } catch (error) {
                    error.message = `绕过审核失败:${error.message}`
                    console.error(error)
                    return response
                }
            }
            return response
        }
    })()

    function bypassAudit() {
        if (window.SLIGHTNING_BYPASS_AUDIT_STOP) {
            return
        }
        window.SLIGHTNING_BYPASS_AUDIT_STOP = true

        let originalAlert = alert
        alert = function(message) {
            if (message == "作品审核中,请稍后再试。") {
                console.log(message)
            } else {
                originalAlert.apply(this, arguments)
            }
        }

        function start() {
            const stringWorkID = location.pathname.split("/").pop()
            if (stringWorkID == null) {
                alert("绕过审核失败:获取作品 ID 失败")
                return
            }
            const workID = parseInt(stringWorkID)
            const storageKey = `SLIGHTNING_BYPASS_AUDIT_@${workID}_ALLOW_RUN`
            if (!JSON.parse(localStorage.getItem(storageKey) || "false")) {
                if (confirm("该作品包含未经审核的自定义控件,确定要运行该作品吗?若确定要运行该作品,请点击“取消”,否则请点击“确定”。")) {
                    return
                }
                if (!confirm("确定要运行该作品吗?")) {
                    return
                }
                localStorage.setItem(storageKey, JSON.stringify(true))
            }

            let iframe = document.createElement("iframe")
            iframe.src = location.href
            Object.assign(iframe.style, {
                border: "none",
                position: "fixed",
                left: "0px",
                top: "0px",
                width: "100%",
                height: "100%",
                zIndex: 10000
            })
            document.body.append(iframe)
            let {contentWindow} = iframe
            contentWindow.SLIGHTNING_BYPASS_AUDIT_STOP = true

            let originalFetch = contentWindow.fetch
            contentWindow.fetch = async function(input, init) {
                let response = await originalFetch(input, init)
                if (/https?:\/\/static.codemao.cn\/coco\/whitelist.json/.test(input.toString())) {
                    let whiteList = await response.json()
                    whiteList.push(workID)
                    return new Response(JSON.stringify(whiteList), {
                        ...response
                    })
                }
                return response
            }
        }

        function setStartButton(element) {
            let startCoverElement = document.createElement("div")
            Object.assign(startCoverElement.style, {
                width: "100%",
                height: "100%",
                position: "absolute",
                top: "0px",
                zIndex: 10,
                backgroundColor: "#00000080",
                display: "flex",
                alignItems: "center",
                justifyContent: "center"
            })

            let startButton = document.createElement("img")
            startButton.src = "https://cdn-community.codemao.cn/community_frontend/asset/play_btn_76b2a.png"
            Object.assign(startButton.style, {
                width: "96px",
                height: "96px",
                cursor: "pointer"
            })
            startCoverElement.append(startButton)

            element.append(startCoverElement)

            startButton.addEventListener("click", start)
        }

        let styleElement = document.createElement("style")
        styleElement.innerHTML = "#rootPlayer:after { content: none !important; }"
        document.body.append(styleElement)

        let wrapElement = document.getElementById("webPlayer")
        if (wrapElement == null) {
            setStartButton(document.getElementById("root"))
        } else {
            wrapElement = wrapElement.children[0]
            let originalAppendChild = wrapElement.appendChild
            wrapElement.appendChild = function() {
                originalAppendChild.apply(this, arguments)
                setTimeout(function() {
                    setStartButton(document.getElementById("rootPlayer"))
                }, 0)
                wrapElement.appendChild = originalAppendChild
            }
        }
    }

    function modifyReleaseFile(file) {
        if (file.unsafeExtensionWidgetList.length == 0) {
            return
        }
        addExtension(file)
        moveUnsafeToSafe(file.unsafeExtensionWidgetList, file.extensionWidgetList)
    }

    function moveUnsafeToSafe(unsafeList, safeList) {
        let safeMap = {}
        safeList.forEach(safe => {
            safeMap[safe.type] = safe
        })
        let unsafe
        while (unsafe = unsafeList.shift()) {
            let safe,
                cdnUrl = `data:text/plain;charset=UTF-8,${encodeURIComponent(unsafe.code)}//`,
                {type} = unsafe
            if (safe = safeMap[type]) {
                safe.cdnUrl = cdnUrl
            } else {
                let safe = {
                    id: Math.floor(Math.random() * 10000) + 10000,
                    type: type,
                    cdnUrl: cdnUrl
                }
                safeList.push(safe)
            }
        }
    }

    function addExtension(file) {
        file.extensionWidgetList.push({
            id: 0,
            type: "EXTENSION_SLIGHTNING_BYPASS_AUDIT",
            cdnUrl:
                "data:text/plain;charset=UTF-8," +
                encodeURIComponent(`
                    new Function(\`(\${${
                        bypassAudit.toString()
                    }}) ()\`) ()
                    const types = {
                        type: "SLIGHTNING_BYPASS_AUDIT",
                        title: "审核绕过",
                        icon: "",
                        isInvisibleWidget: true,
                        isGlobalWidget: true,
                        properties: [],
                        methods: [],
                        events: []
                    }
                    class Widget extends InvisibleWidget {
                        constructor(props) {
                            super(props)
                        }
                    }
                    exports.types = types
                    exports.widget = Widget
                //`)
        })
    }

    ;(function () {
        let originalSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function(data) {
            if (data instanceof FormData) {
                let fileName = data.get("fname"),
                    originalFile = data.get("file")
                if (fileName == "test.json") {
                    let xhr = this,
                        xhrArguments = arguments
                    let reader = new FileReader()
                    reader.readAsText(originalFile)
                    reader.onload = async function() {
                        try {
                            let fileContent = JSON.parse(this.result.replaceAll("UNSAFE_EXTENSION_", "EXTENSION_"))
                            modifyReleaseFile(fileContent)
                            let blob = new Blob([JSON.stringify(fileContent)], { type: "text/plain" })
                            let file = new File([blob], originalFile.name, { type: originalFile.type })
                            data.set("file", file)
                        } catch (error) {
                            console.error(error)
                            alert(`绕过审核失败:${error.message}`)
                        }
                        originalSend.apply(xhr, xhrArguments)
                    }
                } else {
                    originalSend.apply(this, arguments)
                }
            } else {
                originalSend.apply(this, arguments)
            }
        }
    })()
})()
长期地址
遇到问题?请前往 GitHub 提 Issues。