Skip to content

Instantly share code, notes, and snippets.

@KatieFrogs
Created February 9, 2023 01:14
Show Gist options
  • Save KatieFrogs/17f19d0722283a7691ed32ecd12735e6 to your computer and use it in GitHub Desktop.
Save KatieFrogs/17f19d0722283a7691ed32ecd12735e6 to your computer and use it in GitHub Desktop.
MCStacker Fixes userscript
// ==UserScript==
// @name MCStacker Fixes
// @namespace mcstacker-fixes
// @author Katie Frogs
// @description Adds a few small features to the MCStacker website and changes its look
// @match https://mcstacker.net/
// @grant none
// @version 2023.2.9
// ==/UserScript==
// ==UserScript==
// @name MCStacker Fixes
// @namespace mcstacker-fixes
// @author Katie Frogs
// @description Adds a few small features to the MCStacker website and changes its look
// @match https://mcstacker.net/
// @grant none
// @version 2023.2.9
// ==/UserScript==
addStylesheet()
var settingValue = false
var uuidInvalid = /[^\da-f]/ig
var uuidNumBlock = /.{8}/g
var uuidHexBlock = /^.{8}|.{12}$|.{4}/g
function uuidToNumber(input){
if(!input){
return ["", "", "", ""]
}
return input.replace(uuidInvalid, "").padStart(32, 0).match(uuidNumBlock).map(hex => {
var integer = parseInt(hex, 16)
if(integer & 0x80000000){
integer -= 0x100000000
}
return integer
})
}
function numberToUuid(input){
if(input[0] === "" && input[1] === "" && input[2] === "" && input[3] === ""){
return ""
}else{
return "{" + input.map(integer => {
integer = parseInt(integer, 10) || 0
if(integer < 0){
return (integer + 0x100000000).toString(16).padStart(8, 0)
}else{
return integer.toString(16).padStart(8, 0)
}
}).join("").toUpperCase().match(uuidHexBlock).join("-") + "}"
}
}
function elInsertBefore(newElement, targetElement){
return targetElement.parentNode.insertBefore(newElement, targetElement)
}
function insertAfter(newElement, targetElement){
var nextSibling = targetElement.nextSibling
if(nextSibling){
return elInsertBefore(newElement, nextSibling)
}else{
return targetElement.parentNode.appendChild(newElement)
}
}
var uuidIds = [
"UUID",
"Owner",
"LoveCause",
"Leash",
"AngryAt",
"Thrower",
"Target",
"ConversionPlayer",
"LikedPlayer"
].map(id => {
return "#commandForm input[id" + (id === "UUID" ? "*" : "^") + "=" + id + "]:not(.replaced)"
}).join(",")
new MutationObserver(mutations => {
var uuids = document.querySelectorAll(uuidIds)
for(var i = 0; i < uuids.length; i++){
let index = i
let a = uuids[i]
let b = uuids[i + 1]
let c = uuids[i + 2]
let d = uuids[i + 3]
if(a.nextSibling === b && b.nextSibling === c && c.nextSibling === d){
let uuidText = document.createElement("input")
uuidText.type = "text"
uuidText.value = numberToUuid([a.value, b.value, c.value, d.value])
uuidText.addEventListener("input", event => {
var uuidNum = uuidToNumber(uuidText.value)
settingValue = true
for(var j = 0; j < 4; j++){
uuids[index + j].value = uuidNum[j]
uuids[index + j].dispatchEvent(new KeyboardEvent("keyup"))
}
settingValue = false
})
insertAfter(uuidText, d)
var abcd = [a, b, c, d]
for(var j = i; j < i + 4; j++){
uuids[j].classList.add("replaced")
uuids[j].style.display = "none"
uuids[j]._value = uuids[j].value
let descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(uuids[j]), "value")
Object.defineProperty(uuids[j], "value", {
get: function(){
return descriptor.get.call(this)
},
set: function(val){
var output = descriptor.set.call(this, val)
if(!settingValue){
uuidText.value = numberToUuid([a.value, b.value, c.value, d.value])
}
return output
}
})
}
i += 3
}
}
}).observe(document.documentElement, {
childList: true,
subtree: true
})
function strFromFunc(func){
var output = func.toString()
return output.slice(output.indexOf("{") + 1, output.lastIndexOf("}"))
}
function insertBefore(input, insertedText, searchString){
var index = input.indexOf(searchString)
if(index === -1){
throw new Error("searchString not found: " + searchString)
}
return input.slice(0, index) + insertedText + input.slice(index)
}
function strReplace(input, searchString, insertedText){
var index = input.indexOf(searchString)
if(index === -1){
throw new Error("searchString not found: " + searchString)
}
return input.slice(0, index) + insertedText + input.slice(index + searchString.length)
};
/*
Support importing short tellraw strings
display:{Name:'"Boat"'}
*/
(0, eval)(`Section = class {
constructor(e) {
this.data = void 0 == e ? {
text: "",
font: "",
color: "unset",
bold: "unset",
italic: "unset",
underlined: "unset",
strikethrough: "unset",
obfuscated: "unset"
} : typeof e === "string" ? {
text: e,
font: "",
color: "unset",
bold: "unset",
italic: "unset",
underlined: "unset",
strikethrough: "unset",
obfuscated: "unset"
} : e
}
}`);
/*
Export short tellraw strings
*/
(0, eval)(`removeUnsetFromJSON = function(e) {
var t = replaceAll(',"color":"unset"', "", e);
t = replaceAll(',"hoverEvent":{"action":"show_text","contents":[{"text":""}]}', "", t = replaceAll(':"false"', ":false", t = replaceAll(':"true"', ":true", t = replaceAll(',"obfuscated":"unset"', "", t = replaceAll(',"strikethrough":"unset"', "", t = replaceAll(',"underlined":"unset"', "", t = replaceAll(',"italic":"unset"', "", t = replaceAll(',"bold":"unset"', "", t = replaceAll(',"font":""', "", t)))))))))
try{
var parsed = JSON.parse(t)
var keys = Object.keys(parsed)
if(keys.length === 1 && keys[0] === "text"){
return '"' + parsed.text + '"'
}
}catch(e){}
return t
}`)
/*
Support importing items with nbt without the give command
*/
var nbtParser = parseNBT.toString()
nbtParser = insertBefore(nbtParser, `
if(t.match(/^\\w+{.+}$/)){
t = "give @s " + t
}
`, "null==e&&new CMDParser(t).parseTheCommand(t)");
(0, eval)(nbtParser)
/*
Hide the target selector and change it to @s
*/
var targetSelectors = loadTargetSelectors.toString()
targetSelectors = strReplace(targetSelectors, `["@p","nearest player"],["@r","random player"],["@a","all players"],["@s","the entity executing the command"]`, `["@s","the entity executing the command"],["@p","nearest player"],["@r","random player"],["@a","all players"]`)
targetSelectors = targetSelectors.slice(0, -1) + `;showHide(i + "TSPane", "TSPaneSH")}`;
(0, eval)(targetSelectors)
/*
No trailing 1 in the give command
*/
var getItemNbt = getItemNBTForGive1p13.toString()
getItemNbt = strReplace(getItemNbt,
`try{0<$("#"+t+"Count").val().length?(a+=" "+$("#"+t+"Count").val(),e=",Count:"+$("#"+t+"Count").val()):a+=" 1"}catch(e){a+=" 1"}`,`try{$("#"+e+"Count").val().length>0&&$("#"+e+"Count").val()!=1?(t+=" "+$("#"+e+"Count").val(),n=",Count:"+$("#"+e+"Count").val()):t+=""}catch(e){t+=""}`);
(0, eval)(getItemNbt)
/*
Support importing empty CustomName
*/
var loadValue = strFromFunc(Entity.prototype.loadValue)
loadValue = insertBefore(loadValue, `a===""?"":`, `JSON.parse(JSON.parse('"'+a.replace(/"/g,'\\\\"').replace(/\\\\'/g,"'")+'"'))`);
Entity.prototype.loadValue = Function("e", "t", "a", "o", loadValue)
/*
Stylesheet
*/
function addStylesheet(){
var blob = new Blob([`
body{
font-family: segoe ui, sans-serif;
display: grid;
grid-template-columns: 250px 1fr 300px;
}
#logo img,
#socialbuts>a[target=_blank],
.ads,
#themes>br,
#intro>div[style="display: flex;"],
body>br,
#intro>a{
display: none !important;
}
#socialbuts,
#nav,
.combut,
#themeBut,
.pageSetup,
.pagePreviewFrame,
#logo,
.mainButtons,
#otherNav{
float: none;
}
.funcbuts{
position: static;
}
.funcbuts,
.combut,
.roundedDiv,
.redX,
.greenPlus,
#themeBut,
#community,
.navButton,
.pageButton,
.pageButtonSelected,
.mButton,
.showHide,
.ticks,
.anchorButton,
.mainButtons{
border-radius: 0;
}
.fLabel40,
.fLabel70,
.fLabel100,
.fLabel150,
.fLabel180,
.fLabel200{
padding-right: 5px;
}
input{
border-width: 1px;
border-style: solid;
}
#themes>a,
#themeBut{
background: #222;
}
.funcbuts,
.combut,
#themes>a,
#themeBut,
.mainButtons{
text-decoration: none;
display: inline-block;
padding: 5px 10px;
border: 2px solid #666;
color: #fff;
margin-right: 6px;
font-size: inherit;
font-weight: normal;
height: auto;
}
.passengerContainer,
.TradePane>.trade{
position: relative;
}
.ui-widget-content .redX,
.passengerContainer>.redX[href*=removePassenger],
#dialogbox a[href*=hideTip],
.trade>.redX:first-child{
position: absolute;
top: 2px;
right: 2px;
}
.ui-widget-content .redX,
.fRight .redX,
.fRight.redX,
.passengerContainer>.redX[href*=removePassenger],
.redX[href*=unsetItem],
#dialogbox a[href*=hideTip],
.redX[title*=Delete],
.TradePane>.trade>.redX:first-child{
display: inline-block;
width: 17px;
height: 17px;
margin: 0;
padding: 0;
text-align: center;
color: transparent;
background-image: url('data:image/svg+xml,<svg viewBox="-5 -5 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M0 0L1 0L10 9L10 10L9 10L0 1M10 0L10 1L1 10L0 10L0 9L9 0" fill="white"/></svg>');
background-repeat: no-repeat;
}
.TradePane>.trade>.redX:nth-child(5){
margin-right: 17px;
}
.ui-widget-content{
padding: 6px 3px 3px 3px;
cursor: default !important;
}
#settingsArea{
width: auto;
height: auto;
}
#themes{
grid-row: 2;
}
#topPart,
#socialbuts,
#nav,
#themes,
#socialandnav,
#otherNav{
width: auto;
}
#topPart a,
#themeBut,
span[id$=BookPanePages]>span,
#socialandnav{
display: block;
}
input[type=text][id*=clickEvent]{
width: calc(100% - 150px);
}
input[type=text][id*=clickEvent]+*{
margin-left: 130px;
}
span[id$=BookPanePages]{
display: grid;
grid-template-columns: 230px 1fr;
}
@font-face{
font-family: noslash;
src: url(data:application/octet-stream;base64,d09GMgABAAAAAAIoAA4AAAAABWAAAAHRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGhwGYACCQggEEQgKVHILCgABNgIkAxAEIAWCcQcqG3wEIB6FcZsTipciETpit5s2NR6+34927n1vVdp69SqatqHeSJYJFc+/BCSLhWwW8QaNmQ+Rjdlswfht/HHZV2hyQCB0lcQX6l1rtNZyl1ZrnsABeBxQi+K24DmnwIvSEmkJPagHRNkthW6xKGJUUt93IeD9pFcCPm1uz3D5vYkA+o3LIREI1Pgrd+XJ6/kIbtKl8VWIJHUUAAEABy82BvzjuDLbrupkAwQAZgkKCiYJ2JQVmJQzC1UVWGlb/Fa0rwgQnQQgEgkACAAAhR8zl9cg2laCCrqR6EYvoGJZBqi1r2OgHu/r6J1reppv+mv9LPAwrGz+dVV/4rez49PmX0l/It9SUR2uHjrjv+ngLAji21cXhjb/dfeV7yP2EgXEfDbQLUGQDZwGxDwBANS4pABiH0Cg6pYgEQK7LMCgewRAChC6jBGQuiwQUExaElBxk4AOw94EdOIlWVF7gBRhUJFpJlCsSqi4jg6zHts78Ry4Ym1voWtvgitX94vufgKHDY0dLXTt8MtYDXvWVg7hyM7YkIosT9UpaBAZCTbyMeBppGjsxkON1mtdNYdoktmcU4Djhnb2ptZWlOcFVoqnuGaS98Eya6+ABNoiQKmIRj8KAAAA);
}
@font-face{
font-family: hide-onds;
src: url(data:application/octet-stream;base64,d09GMgABAAAAAAJEAA4AAAAABYQAAAHvAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGhwGYACCUggEEQgKVHgLEAABNgIkAxYEIAWCdwcwG6QEEVWbCSG+OrCNxYl/2KKouAbUBzt/3HoS7gyOkKSTh6e1/507s/vFpH5MJaslGlm8vRLAE11CxSPezLLo6zbFDI/z/xOgJi2tuV2KF8qP+7dZmga7sGcIssGmljv/KGlL4LYAMA+kLYnbggKwBF5KE2gJRhJ74uVCYLFbKjqbFMUm+uVZCHh2yAx4eSo2ewFo0KFAQiBQxJe4piRdSI9wibaPN6ZEIikzgACAzQdW7HPePmfzyP/Z9qYKCACMCGRkDAiwXhYYUJiMGjUS9jnp7H+xzwm985YCgKgiAJGQAADBVfYaRYkqtMRoOof4rwSqQRMSalAHKDBRAoCiqC8bi531Zd1opbbyduTJ7ifC3TBp/r3qwuepd6vKl2RO9lCm0n5fFX+IODkQtP+4vanm+V9r6vO7wfuPUWIsVVAjgSBVsBeIMQEAKOKYUYgNACBQrUYCCSGw2ERAk1sCQBIg1OoWIKk2RYBswFkBCtwQoNTioQBVeCqLohZIEdpkJE1Gkc02BwWuoTTiZlcVHsMh6KNKZuiqBXuEaeNEXcBWqfm9bhP+IQvAygb3hZypSRQKoR1RumA26CDTYeXJ/jVmS0YRd0rysM1u6xCAndK0PIaORFzhLIT3TpS8dLQIIAH/H5oKKKlGFNarHE4XAA==);
}
#nav .combut{
font-family: noslash, segoe ui, sans-serif;
text-transform: capitalize;
}
#nav{
margin-top: 35px;
}
a.showHide:not(#addPool):not([id*=addEntrypool]){
display: inline-block;
width: 16px;
height: 16px;
padding: 0;
color: transparent;
background-repeat: no-repeat;
background-image: url('data:image/svg+xml,<svg viewBox="-3 -3 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M0 2.5L5 7.5L10 2.5" fill="white"/></svg>');
}
a.showHide:not(#addPool):not([id*=addEntrypool]).hiding{
background-image: url('data:image/svg+xml,<svg viewBox="-3 -3 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M2.5 0L7.5 5L2.5 10" fill="white"/></svg>');
}
.greenPlus{
display: inline-block;
min-width: 16px;
height: 16px;
padding: 0;
text-align: center;
}
#logo{
display: block;
}
#logo a{
text-decoration: none;
color: inherit;
font-size: 30px;
text-align: center;
}
#logo a::after{
content: "MCStacker";
}
.AEControl[id*=Effects]>table>tbody>tr:first-child>th:nth-child(2n){
font-size: 0;
}
.ticks{
display: inline-grid;
width: 40px;
overflow: hidden;
text-overflow: ellipsis;
font-family: hide-onds, segoe ui, sans-serif;
font-weight: normal;
}
.alertify{
animation: none !important;
transition: none !important;
}
input[placeholder=Filter]:focus{
width: 200px;
}
.entityWrapper{
display: flex;
flex-wrap: wrap;
}
.entityB{
flex-basis: 100%;
}
#commandOutput{
position: fixed !important;
top: 0 !important;
right: 0;
left: auto !important;
width: 300px;
height: 200px;
}
#commandForm>*{
display: block;
}
#nav,
#socialandnav,
#socialbuts,
#otherNav{
display: flex;
flex-direction: column;
}
#nav>a,
#socialbuts a,
#otherNav a{
order: 10;
}
#nav>a[href*=give],
#socialbuts,
#socialandnav a[href*=showImport]{
order: 1;
}
#nav>a[href*=summon],
#otherNav,
#socialandnav a[href*=showClipboard]{
order: 2;
}
#nav>a[href*=tellraw],
#nav{
order: 3;
}
#nav>a[href*=title]{
order: 4;
}
#nav>a[href*=playsound]{
order: 5;
}
#nav>a[href*=particle]{
order: 6;
}
#nav>a[href*=kill],
#nav>a[href*=fill],
#nav>a[href*=setblock],
#nav>a[href*=teleport],
#nav>a[href*="execute if entity"]{
display: none;
}
#otherNav{
margin: 0;
padding: 0;
}
.tellrawPreview span[style*="background-color:#ddd"]{
background-color: #ddd2 !important;
}
`], {
type:'text/css'
})
var link = document.createElement("link")
link.rel = "stylesheet"
link.href = URL.createObjectURL(blob)
document.head.appendChild(link)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment