您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
save selection
// ==UserScript== // @name Wirelyre Select Saves (with next pc save) // @namespace http://tampermonkey.net/ // @version 0.1 // @description save selection // @author 13pake, TamTheBoss111 // @match https://wirelyre.github.io/tetra-tools/pc-solver.html* // @icon https://www.google.com/s2/favicons?sz=64&domain=github.io // @grant GM_addStyle // @license MIT // ==/UserScript== (function() { 'use strict'; GM_addStyle("#solutions > a { border-radius: 4px; }"); GM_addStyle("#solutions { row-gap: 20px; }"); GM_addStyle("#select-save { background-color: rgba(0,0,0,0.2); color: #fff; border: 1px solid rgba(0,0,0,0.3); margin-left: 5px; }"); GM_addStyle("#label-save { margin-top: 10px; }"); // Constants var pieces = ['T', 'I', 'L', 'J', 'S', 'Z', 'O']; var colors = [ 'rgb(180, 81, 172)', // purple 'rgb(65, 175, 222)', // cyan 'rgb(239, 149, 54)', // orange 'rgb(24, 131, 191)', // blue 'rgb(102, 198, 92)', // green 'rgb(239, 98, 77)', // red 'rgb(247, 211, 62)', // yellow ]; var remainingPieces = [4, 1, 5, 2, 6, 3, 7]; var piecesUsed = [3, 6, 2, 5, 1, 4, 0]; var pcNumSelectOptions = ["1st", "2nd", "3rd", "4th", "5th", "6th", "7th"] window.onload = function() { // Add save selection var label = document.createElement('label'); label.id = 'label-save'; label.innerHTML = 'Save'; document.querySelectorAll('#query > div:nth-child(6)')[0].appendChild(label); var select = document.createElement('select'); label.appendChild(select); select.id = 'select-save'; var selectOptions = ['All', ...pieces]; for (var i = 0; i < selectOptions.length; i++) { var option = document.createElement('option'); option.value = selectOptions[i]; option.text = selectOptions[i]; select.appendChild(option); } // Add pc num selection var pcNumLabel = document.createElement('label'); pcNumLabel.id = 'label-pc-num'; pcNumLabel.innerHTML = 'PC # '; document.querySelectorAll('#query > div:nth-child(6)')[0].appendChild(pcNumLabel); // Create the slider var pcNumSlider = document.createElement('input'); pcNumSlider.type = 'range'; pcNumSlider.id = 'slider-pc-num'; pcNumSlider.min = '1'; pcNumSlider.max = '7'; pcNumSlider.step = '1'; pcNumSlider.value = '1'; pcNumLabel.appendChild(pcNumSlider); // Display the selected value var pcNumDisplay = document.createElement('span'); pcNumDisplay.id = 'slider-value'; pcNumDisplay.innerHTML = '1'; // Default value pcNumLabel.appendChild(pcNumDisplay); // Update the displayed value when the slider changes pcNumSlider.addEventListener('input', function () { pcNumDisplay.innerHTML = pcNumSlider.value; var queue = document.getElementById('queue').value; // check if queue is just pieces var piecesOnlyMatch = queue.match(/^[TILJSZO]*$/); if (piecesOnlyMatch) { //console.log('good queue'); } else { return; } var queuePieces = pieces.map(function(piece) { return (queue.split(piece).length - 1); }); // We're just gonna assume the queue length is correct !!! //console.log('queue pieces', queuePieces); var solutionsContainer = document.getElementById('solutions'); // Loop over all 'a' tags inside the solutions container var aTags = solutionsContainer.getElementsByTagName('a'); for (let aNode of aTags) { // console.log('A child node has been added or removed.', mutation.addedNodes[0]); try { var dataField = aNode.firstChild.getAttribute('data-field'); var solutionPieces = pieces.map(function(piece) { return (dataField.split(piece).length - 1) / 4; }); //console.log('pieces used', solutionPieces); // get difference between arrays var differentIndex = -1; for (let i = 0; i < queuePieces.length; i++) { if (queuePieces[i] !== solutionPieces[i]) { differentIndex = i; } } // console.log('saved piece', pieces[differentIndex]); aNode.style.borderTop = "10px solid " + colors[differentIndex]; aNode.classList.add(pieces[differentIndex]); // Calculate what PC comes from this save let bag = new Set(["T", "I", "J", "L", "O", "S", "Z"]); // console.log("queuevalue", queue) let currentPCNum = pcNumSlider.value - 1; // -1 so that its an index starting from 0 // If there is a saved piece (4p setup with see7/3p setup with see8) if (differentIndex != -1) { // console.log(piecesUsed[currentPCNum], currentPCNum); for (let j = 1; j < piecesUsed[currentPCNum] + 2; j++) { // console.log("inloop") // console.log("piece to remove", queue[queue.length - j]) bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag // console.log("bag currently: ", Array.from(bag).join("")) } var save = Array.from(bag).join(""); //console.log("final save", save); // Add the saved piece // If there is a saved piece (4p setup with see7/3p setup with see8) save += pieces[differentIndex]; // console.log("final save", save); // Reorder the string const chars = save.split(""); const correctOrder = "TIJLOSZ"; // Sort the characters based on their position in the custom order chars.sort((a, b) => correctOrder.indexOf(a) - correctOrder.indexOf(b)); save = chars.join(""); } else if (differentIndex == -1) { // console.log(piecesUsed[currentPCNum], currentPCNum); for (let j = 1; j < piecesUsed[currentPCNum] + 1; j++) { // console.log("inloop") // console.log("piece to remove", queue[queue.length - j]) bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag // console.log("bag currently: ", Array.from(bag).join("")) } var save = Array.from(bag).join(""); } // hard coded stuff: //console.log(pcNumSelect.value) if (pcNumSlider.value == 2) { // for dealing with some 3+1setups on 2nd for 3rd pc saves save = pieces[differentIndex]; } if (pcNumSlider.value == 3) { // for renaming 4th pc const reference = "TIJLOSZ"; const missing = reference.split("").filter(letter => !save.includes(letter)); let dupe = ""; if (save.includes("TT")) { dupe = "T" } else if (save.includes("II")) { dupe = "I" } else if (save.includes("JJ")) { dupe = "J" } else if (save.includes("LL")) { dupe = "L" } else if (save.includes("OO")) { dupe = "O" } else if (save.includes("SS")) { dupe = "S" } else if (save.includes("ZZ")) { dupe = "Z" } // console.log(missing, dupe) if (missing.length > 0 && dupe == "") { save = `no ${missing.join("")}`; } else { // console.log("dupe") save = `${dupe}>${missing.join("")}`; // console.log("save", save) } } if (pcNumSlider.value == 5) { // for renaming 6th pc const reference = "TIJLOSZ"; const missing = reference.split("").filter(letter => !save.includes(letter)); let dupe = ""; if (save.includes("TT")) { dupe = "T" } else if (save.includes("II")) { dupe = "I" } else if (save.includes("JJ")) { dupe = "J" } else if (save.includes("LL")) { dupe = "L" } else if (save.includes("OO")) { dupe = "O" } else if (save.includes("SS")) { dupe = "S" } else if (save.includes("ZZ")) { dupe = "Z" } // console.log(missing, dupe) if (missing.length > 0 && dupe == "") { save = `no ${missing.join("")}`; } else { // console.log("dupe") save = `${dupe}>${missing.join("")}`; // console.log("save", save) } } if (pcNumSlider.value == 7) { // for renaming 1st/8th pc const reference = "TIJLOSZ"; const missing = reference.split("").filter(letter => !save.includes(letter)); let dupe = ""; if (save.includes("TT")) { dupe = "T" } else if (save.includes("II")) { dupe = "I" } else if (save.includes("JJ")) { dupe = "J" } else if (save.includes("LL")) { dupe = "L" } else if (save.includes("OO")) { dupe = "O" } else if (save.includes("SS")) { dupe = "S" } else if (save.includes("ZZ")) { dupe = "Z" } // console.log(missing, dupe) if (missing.length == 0) { save = "1st PC"; } else { // console.log("dupe") save = `${dupe}>${missing.join("")} 8th PC`; // console.log("save", save) } } // checks if the datafield is full and hence there is a pc if (!dataField.includes("_") && save != undefined) { if (currentPCNum != 6) { save += " " + pcNumSelectOptions[currentPCNum + 1] } // Check if there is an old text node there and delete it let existingTextNode = aNode.firstChild.firstChild.querySelector('text'); // console.log(existingTextNode); if (existingTextNode) { // If an existing text node is found, remove it aNode.firstChild.firstChild.removeChild(existingTextNode); } // Create the new text elem and add it const text = document.createElementNS("http://www.w3.org/2000/svg", "text"); text.setAttribute("x", "100"); // Set x to the center text.setAttribute("y", "15"); // Adjust y as needed text.setAttribute("fill", "black"); text.setAttribute("text-anchor", "middle"); // Center the text horizontally text.setAttribute("font-size", "15"); // Font size text.textContent = save; aNode.firstChild.firstChild.appendChild(text); } } catch (e) { // do nothing lol } } }); // On select change select.onchange = function(event) { selectSave(event.target.value); } function selectSave(value) { if (value !== 'All') { document.querySelectorAll('#solutions > a').forEach(function(a) { a.style.display = 'none'; // a.style.borderTopWidth = '0'; commented out by tam }); document.querySelectorAll('#solutions > a.' + value).forEach(function(a) { a.style.display = 'block'; }); } else if (value == 'All') { document.querySelectorAll('#solutions > a').forEach(function(a) { a.style.display = 'block'; a.style.borderTopWidth = '10px'; }); } } // Add listener for solutions and also the whole body for the slider var targetNode = document.getElementById('solutions'); var config = { // attributes: true, childList: true, subtree: true, characterData: true }; var observer = new MutationObserver(function(mutationsList) { var queue = document.getElementById('queue').value; // check if queue is just pieces var piecesOnlyMatch = queue.match(/^[TILJSZO]*$/); if (piecesOnlyMatch) { //console.log('good queue'); } else { return; } var queuePieces = pieces.map(function(piece) { return (queue.split(piece).length - 1); }); // We're just gonna assume the queue length is correct !!! //console.log('queue pieces', queuePieces); for (var mutation of mutationsList) { if (mutation.type == 'childList') { // console.log('A child node has been added or removed.', mutation.addedNodes[0]); try { var aNode = mutation.addedNodes[0]; var dataField = aNode.firstChild.getAttribute('data-field'); var solutionPieces = pieces.map(function(piece) { return (dataField.split(piece).length - 1) / 4; }); //console.log('pieces used', solutionPieces); // get difference between arrays var differentIndex = -1; for (let i = 0; i < queuePieces.length; i++) { if (queuePieces[i] !== solutionPieces[i]) { differentIndex = i; } } // console.log('saved piece', pieces[differentIndex]); aNode.style.borderTop = "10px solid " + colors[differentIndex]; aNode.classList.add(pieces[differentIndex]); // Calculate what PC comes from this save let bag = new Set(["T", "I", "J", "L", "O", "S", "Z"]); // console.log("queuevalue", queue) let currentPCNum = pcNumSlider.value - 1; // -1 so that its an index starting from 0 // If there is a saved piece (4p setup with see7/3p setup with see8) if (differentIndex != -1) { // console.log(piecesUsed[currentPCNum], currentPCNum); for (let j = 1; j < piecesUsed[currentPCNum] + 2; j++) { // console.log("inloop") // console.log("piece to remove", queue[queue.length - j]) bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag // console.log("bag currently: ", Array.from(bag).join("")) } var save = Array.from(bag).join(""); //console.log("final save", save); // Add the saved piece // If there is a saved piece (4p setup with see7/3p setup with see8) save += pieces[differentIndex]; // console.log("final save", save); // Reorder the string const chars = save.split(""); const correctOrder = "TIJLOSZ"; // Sort the characters based on their position in the custom order chars.sort((a, b) => correctOrder.indexOf(a) - correctOrder.indexOf(b)); save = chars.join(""); } else if (differentIndex == -1) { // console.log(piecesUsed[currentPCNum], currentPCNum); for (let j = 1; j < piecesUsed[currentPCNum] + 1; j++) { // console.log("inloop") // console.log("piece to remove", queue[queue.length - j]) bag.delete(queue[queue.length - j]) // bag ends up being the pieces left in the bag // console.log("bag currently: ", Array.from(bag).join("")) } var save = Array.from(bag).join(""); } // hard coded stuff: //console.log(pcNumSelect.value) if (pcNumSlider.value == 2) { // for dealing with some 3+1setups on 2nd for 3rd pc saves save = pieces[differentIndex]; } if (pcNumSlider.value == 3) { // for renaming 4th pc const reference = "TIJLOSZ"; const missing = reference.split("").filter(letter => !save.includes(letter)); let dupe = ""; if (save.includes("TT")) { dupe = "T" } else if (save.includes("II")) { dupe = "I" } else if (save.includes("JJ")) { dupe = "J" } else if (save.includes("LL")) { dupe = "L" } else if (save.includes("OO")) { dupe = "O" } else if (save.includes("SS")) { dupe = "S" } else if (save.includes("ZZ")) { dupe = "Z" } // console.log(missing, dupe) if (missing.length > 0 && dupe == "") { save = `no ${missing.join("")}`; } else { // console.log("dupe") save = `${dupe}>${missing.join("")}`; // console.log("save", save) } } if (pcNumSlider.value == 5) { // for renaming 6th pc const reference = "TIJLOSZ"; const missing = reference.split("").filter(letter => !save.includes(letter)); let dupe = ""; if (save.includes("TT")) { dupe = "T" } else if (save.includes("II")) { dupe = "I" } else if (save.includes("JJ")) { dupe = "J" } else if (save.includes("LL")) { dupe = "L" } else if (save.includes("OO")) { dupe = "O" } else if (save.includes("SS")) { dupe = "S" } else if (save.includes("ZZ")) { dupe = "Z" } // console.log(missing, dupe) if (missing.length > 0 && dupe == "") { save = `no ${missing.join("")}`; } else { // console.log("dupe") save = `${dupe}>${missing.join("")}`; // console.log("save", save) } } if (pcNumSlider.value == 7) { // for renaming 1st/8th pc const reference = "TIJLOSZ"; const missing = reference.split("").filter(letter => !save.includes(letter)); let dupe = ""; if (save.includes("TT")) { dupe = "T" } else if (save.includes("II")) { dupe = "I" } else if (save.includes("JJ")) { dupe = "J" } else if (save.includes("LL")) { dupe = "L" } else if (save.includes("OO")) { dupe = "O" } else if (save.includes("SS")) { dupe = "S" } else if (save.includes("ZZ")) { dupe = "Z" } // console.log(missing, dupe) if (missing.length == 0) { save = "1st PC"; } else { // console.log("dupe") save = `${dupe}>${missing.join("")} 8th PC`; // console.log("save", save) } } // checks if the datafield is full and hence there is a pc if (!dataField.includes("_") && save != undefined) { if (currentPCNum != 6) { save += " " + pcNumSelectOptions[currentPCNum + 1] } // Create the new text elem and add it const text = document.createElementNS("http://www.w3.org/2000/svg", "text"); text.setAttribute("x", "100"); // Set x to the center text.setAttribute("y", "15"); // Adjust y as needed text.setAttribute("fill", "black"); text.setAttribute("text-anchor", "middle"); // Center the text horizontally text.setAttribute("font-size", "15"); // Font size text.textContent = save; aNode.firstChild.firstChild.appendChild(text); } } catch (e) { // do nothing lol } } } }); observer.observe(targetNode, config); } })();