Paste or make your own sheet, then paste it!
// ==UserScript==
// @name VP sheet player
// @namespace http://tampermonkey.net/
// @version 1.0.1
// @description Paste or make your own sheet, then paste it!
// @author x/y
// @match *://multiplayerpiano.net/*
// @match *://mpp.8448.space/*
// @grant none
// @run-at document-end
// @license MIT
// ==/UserScript==
//######==== Creation - Sheets button ---------
let Button = document.createElement("div")
Button.id = "sheets-btn"
Button.className = "ugly-button sheets-btn"
Button.textContent = "Sheets"
Button.style.position = "absolute"
Button.style.top = "32px"
Button.style.left = "1140px"
document.querySelector("#bottom .relative").appendChild(Button)
//######==== Constants ------------------------
const KEYMAP = {
"1": { ptr: 15 }, "!": { ptr: 16 }, "2": { ptr: 17 }, "@": { ptr: 18 },
"3": { ptr: 19 }, "4": { ptr: 20 }, "$": { ptr: 21 }, "5": { ptr: 22 },
"%": { ptr: 23 }, "6": { ptr: 24 }, "^": { ptr: 25 }, "7": { ptr: 26 },
"8": { ptr: 27 }, "*": { ptr: 28 }, "9": { ptr: 29 }, "(": { ptr: 30 },
"0": { ptr: 31 }, "q": { ptr: 32 }, "Q": { ptr: 33 }, "w": { ptr: 34 },
"W": { ptr: 35 }, "e": { ptr: 36 }, "E": { ptr: 37 }, "r": { ptr: 38 },
"t": { ptr: 39 }, "T": { ptr: 40 }, "y": { ptr: 41 }, "Y": { ptr: 42 },
"u": { ptr: 43 }, "i": { ptr: 44 }, "I": { ptr: 45 }, "o": { ptr: 46 },
"O": { ptr: 47 }, "p": { ptr: 48 }, "P": { ptr: 49 }, "a": { ptr: 50 },
"s": { ptr: 51 }, "S": { ptr: 52 }, "d": { ptr: 53 }, "D": { ptr: 54 },
"f": { ptr: 55 }, "g": { ptr: 56 }, "G": { ptr: 57 }, "h": { ptr: 58 },
"H": { ptr: 59 }, "j": { ptr: 60 }, "J": { ptr: 61 }, "k": { ptr: 62 },
"l": { ptr: 63 }, "L": { ptr: 64 }, "z": { ptr: 65 }, "Z": { ptr: 66 },
"x": { ptr: 67 }, "c": { ptr: 68 }, "C": { ptr: 69 }, "v": { ptr: 70 },
"V": { ptr: 71 }, "b": { ptr: 72 }, "B": { ptr: 73 }, "n": { ptr: 74 },
"m": { ptr: 75 }, '"': { ptr: 18 }
}
const OFFSET = Object.entries(MPP.piano.keys).findIndex((e) => {return e[0] === "c1"}) - 15
//######==== General use functions ------------
window.parseSheet = (sh) => {
sh = sh.replaceAll("|", "").replaceAll("{", "").replaceAll("}", "").replaceAll("`", "").replaceAll("✱", "*")
let output = []
let current = ""
let inside = false
for (let i = 0; i < sh.length; i++) {
let c = sh[i]
if (c === "[") {
for (let ch of current.trim()) output.push(ch)
current = ""
inside = true
continue
}
if (c === "]") {
output.push(current)
current = ""
inside = false
continue
}
if (!inside) {
if (c === " ") {
for (let ch of current.trim()) output.push(ch)
current = ""
} else {
current += c
}
} else {
current += c
}
}
for (let ch of current.trim()) output.push(ch)
return output
}
window.thisAndThat = (d) => {
let that = window.loadedSheet
let put = ""
for (let i = window.currentIndex; i < window.currentIndex + 40; i++) {
if (i > window.loadedSheet.length - 1) {
put += ""
} else {
if (i - window.currentIndex === 0) {put += "("}
if (window.loadedSheet[i].length > 1) {
put += "[" + window.loadedSheet[i] + "]"
} else {
put += window.loadedSheet[i]
}
if (i - window.currentIndex === 0) {put += ")"}
put += " "
}
}
window.sheetinput.value = put
}
function pressGroup(groupString) {
for (let ch of groupString) {
let key = KEYMAP[ch]
if (!key) continue
let index = key.ptr + OFFSET
let note = Object.values(MPP.piano.keys).map(k => k.note)[index + window.Trans]
if (note) MPP.press(note, 0.8)
}
}
//######==== Sheets menu HTML -----------------
let buttonStyle = `background-image: linear-gradient(#111, #333); color: white;`
let makeSheetsMenu = document.createElement("div")
makeSheetsMenu.innerHTML = `<div id="sheets" style="box-shadow: 0px 5px 12px rgba(0,0,0,0.7); font-size: 12px; z-index: 10000; display: block; width: 300px; height: 150px; position: fixed; top: 77.5%; left: 50%; transform: translate(-50%, 150%); outline: 2.5px solid #567; background-image: linear-gradient(to bottom, #789 5%, #9ab 25%, #89a 42.5%, #789 80%, #678 92.5%, #789 100%); opacity: 0; pointer-events: none; transition: opacity 0.5s ease, transform 0.5s linear;">
<span style="display: block; text-align: center;">
<big><b>(SHEET LOADER)</b></big><br>
Paste your sheet here, or <u>type your own!</u>
<textarea spellcheck="false" rows="1" style="overflow: hidden; scrollbar-width: none; white-space: nowrap; overflow-x: auto; overflow-y: hidden; width: 280px; resize: none;"></textarea>
Dash [-] | Equals [=] | LeftBracket ([) | RightBracket (]) | SemiColon [;] | Comma [,] | Period [.] | Comma [,] <br>
<button style="${buttonStyle}" onclick="window.Playing = !window.Playing; if (window.Playing) {window.currentIndex = 0; window.loadedSheet = parseSheet(window.sheetinput.value); window.curSheet = window.sheetinput.value; window.thisAndThat();} else {window.sheetinput.value = window.curSheet}; this.innerHTML = window.Playing ? '🔴 Stop Playing Sheet' : '🟢 Play Sheet'">🟢 Play Sheet</button><br>
<button style="${buttonStyle.replace("111", "200").replace("333", "400")}" onclick="window.Trans += -12; if (window.Trans < -48) {window.Trans = -48}; document.getElementById('ptransposition').textContent = window.Trans;">--</button>
<button style="${buttonStyle.replace("111", "311").replace("333", "622")}" onclick="window.Trans += -1; if (window.Trans < -48) {window.Trans = -48}; document.getElementById('ptransposition').textContent = window.Trans;">-</button>
<b>Transpose: <i id="ptransposition">0</i></b>
<button style="${buttonStyle.replace("111", "131").replace("333", "062")}" onclick="window.Trans += 1; if (window.Trans > 48) {window.Trans = 48}; document.getElementById('ptransposition').textContent = window.Trans;">+</button>
<button style="${buttonStyle.replace("111", "020").replace("333", "040")}" onclick="window.Trans += 12; if (window.Trans > 48) {window.Trans = 48}; document.getElementById('ptransposition').textContent = window.Trans;">++</button>
</span></div>`
document.body.appendChild(makeSheetsMenu)
//######==== Sheet button logic ---------------
let sheetButton = document.getElementById("sheets-btn")
let sheetMenuShown = false
let sheetMenu = document.getElementById("sheets")
sheetButton.onclick = () => {
sheetMenuShown = !sheetMenuShown
if (sheetMenuShown) {
sheetMenu.style.opacity = "1"
sheetMenu.style.pointerEvents = "auto"
sheetMenu.style.transform = "translate(-50%, -50%)"
} else {
sheetMenu.style.opacity = "0"
sheetMenu.style.pointerEvents = "none"
sheetMenu.style.transform = "translate(-50%, 150%)"
}
}
//######==== Submit sheet logic ---------------
window.sheetinput = document.querySelector("#sheets textarea")
window.sheetinput.addEventListener("keydown", e => {
if (e.key === "Enter") e.preventDefault()
})
window.sheetinput.addEventListener("input", () => {
window.sheetinput.value = window.sheetinput.value.replace(/\n/g, "")
})
//######==== Autoplaying ----------------------
window.curSheet = ""
window.Trans = 0
window.Playing = false
window.currentIndex = 0
window.loadedSheet = []
window.addEventListener("keydown", e => {
if ((e.key === "-" || e.key === "=" || e.key === "[" || e.key === "]" || e.key === ";" || e.key === "." || e.key === ",") && (window.Playing && window.loadedSheet.length && e.target === document.body)) {
pressGroup(window.loadedSheet[window.currentIndex] || "")
window.currentIndex = (window.currentIndex + 1) % window.loadedSheet.length
window.thisAndThat()
}
})
setInterval(() => {
if (window.Playing) {
window.sheetinput.scrollLeft = 0
window.sheetinput.disabled = true
} else {
window.sheetinput.disabled = false
}
}, 33)