MCFunction Downloader

A simple quick and dirty hack to add an button for mcfunction downloads

// ==UserScript==
// @name         MCFunction Downloader
// @version      0.3.4
// @license      MIT
// @description  A simple quick and dirty hack to add an button for mcfunction downloads
// @author       Xemorph
// @match        https://minecraftshapes.com/
// @icon         https://www.google.com/s2/favicons?domain=minecraftshapes.com
// @grant        none
// @namespace https://gf.qytechs.cn/users/883400
// ==/UserScript==
(function() {
    'use strict';

    let uiHelper = {
        addRow: function(controls) {
            var tbody = document.querySelector("#ctrls > table > tbody");
            var row = document.createElement("tr");
            controls.forEach(x => {
                var td = document.createElement("td");
                if (x && x.nodeType) {
                    td.appendChild(x);
                } else {
                    td.innerHTML = x;
                }

                row.appendChild(td);
            });
            tbody.appendChild(row);
            return row;
        },
        createButton: function(text, callbackfn) {
            var button = document.createElement("button");
            button.innerHTML = text;
            button.onclick = callbackfn;
            return button;
        },
        createCheckbox: function() {
            var checkbox = document.createElement("input");
            checkbox.type = "checkbox";
            return checkbox;
        },
        createDropdown: function(items) {
            var select = document.createElement("select");
            items.forEach(x => {
                var option = document.createElement("option");
                option.value = x;
                option.innerHTML = x;
                select.appendChild(option);
            });
            return select;
        },
        createInputTextBox: function(placeholder = "") {
            var input = document.createElement("input");
            input.type = "text";
            input.placeholder = placeholder;
            return input;
        }
    }

    let commandGen = {
        svgToBlocksArray: function() {
            var raw_blocks = document.querySelectorAll("#svgElem > rect.filled");
            var blocks = [];

            raw_blocks.forEach(x => {
                var coords = x.children[0].textContent.match(/\d+/g).map(Number);
                blocks.push(coords);
            });
            return blocks;
        },
        blockToCommand: function(block, height) {

            var blocktype = document.querySelector("#ctrls > table > tbody > tr:nth-child(15) > td:nth-child(2) > input[type=text]").value;
            var command = `setblock ~${block[0]} ~${height} ~${block[1]} ${blocktype}`;
            return command;
        },
        blocksToCommand: function(blocks) {
            var cmd = "";
            var height = parseInt(document.querySelector("#ctrls > table > tbody > tr:nth-child(16) > td:nth-child(2) > input[type=number]").value);
            for (let index = 0; index < height; index++) {
                blocks.forEach(x => {
                    cmd += commandGen.blockToCommand(x, index) + "\n";
                });
            }

            return cmd;
        },
        buttonClick: function(origin) {
            let blocks = commandGen.svgToBlocksArray();

            var center = commandGen.getNewCenter(origin);
            blocks = commandGen.adjustBlockCoords(blocks, center);

            let command = commandGen.blocksToCommand(blocks);

            var blob = new Blob([command], {
                type: "text/plain"
            });            
            var shape = document.querySelector("#shape").options[document.querySelector("#shape").selectedIndex].text;

            window.saveAs(blob, `${shape.toLowerCase()}.mcfunction`);
        },
        getNewCenter: function(origin) {
            //"Top-Left", "Top-Middle", "Top-Right", "Middle-Left", "Center", "Middle-Right", "Bottom-Left", "Bottom-Middle", "Bottom-Right", "Custom"
            let size = commandGen.getSize();
            let centerX = Math.trunc((size[0] - 1) / 2)
            let centerY = Math.trunc((size[1] - 1) / 2);
            switch (origin) {
                case "Custom":
                    var markers = commandGen.getMarker();
                    if (markers.length == 0) {
                        alert("No marker set!");
                        throw Error("No marker set");
                    } else if (markers.length > 1) {
                        alert("More than one (1) marker set!");
                        throw Error("Too many markers Isaac");
                    } else {
                        return markers[0].children[0].textContent.match(/\d+/g).map(Number);
                    }

                    case "Top-Left":
                        return [0, 0];
                    case "Top-Middle":
                        return [centerX, 0]
                    case "Top-Right":
                        return [size[0] - 1, 0]
                    case "Middle-Left":
                        return [0, centerY];
                    case "Center":
                        return [centerX, centerY];
                    case "Middle-Right":
                        return [size[0] - 1, centerY];
                    case "Bottom-Left":
                        return [0, size[1] - 1];
                    case "Bottom-Middle":
                        return [centerX, size[1] - 1];
                    case "Bottom-Right":
                        return [size[0] - 1, size[1] - 1];
            }

        },
        adjustBlockCoords: function(blocks, newCenter) {
            return blocks.map(point => {
                return [point[0] - newCenter[0], point[1] - newCenter[1]];
            });
        },
        getSize: function(blocks) {
            var lines = Array.from(document.querySelectorAll("#svgElem > line"));
            var width = lines.filter(x => x.y1.baseVal.value == 0).length + 1;
            var height = lines.filter(x => x.x1.baseVal.value == 0).length + 1;
            return [width, height];
        },
        getMarker: function() {
            var markers = Array.from(document.querySelectorAll("#svgElem > rect.square.tog"));
            return markers;
        }
    }

    var dropdown = uiHelper.createDropdown(["Top-Left", "Top-Middle", "Top-Right", "Middle-Left", "Center", "Middle-Right", "Bottom-Left", "Bottom-Middle", "Bottom-Right", "Custom"]);

    uiHelper.addRow(["Generation Origin", dropdown]);

    var inputBox = uiHelper.createInputTextBox("block");
    inputBox.value = "minecraft:white_concrete";
    uiHelper.addRow(["Block", inputBox]);
    var heightBox = uiHelper.createInputTextBox("height");
    heightBox.type = "number";
    heightBox.min = "1";
    heightBox.value = "1";
    uiHelper.addRow(["Generation Height", heightBox]);

    var generateButton = uiHelper.createButton("mcfunction", () => {
        commandGen.buttonClick(dropdown.value);
    });
    uiHelper.addRow(["Generate", generateButton])

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址