您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Load saves for whatbeatsrock.com with pause functionality, adjustable wait time, file-based save selection, improved UI with padding, and edge-only dragging with scrollable middle
- // ==UserScript==
- // @name WhatBeatsRock Save Loader
- // @namespace http://violentmonkey.net/
- // @version 3.0
- // @description Load saves for whatbeatsrock.com with pause functionality, adjustable wait time, file-based save selection, improved UI with padding, and edge-only dragging with scrollable middle
- // @author JoTheStupid
- // @match https://www.whatbeatsrock.com/*
- // @grant none
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- let paused = false;
- let saveEntries = [];
- let index = 0;
- let isDragging = false;
- let dragStartX, dragStartY, startX, startY;
- // UI Styles
- const buttonStyle = `
- padding: 8px 16px;
- margin-top: 10px;
- background-color: #4CAF50;
- border: 2px solid #333;
- color: white;
- cursor: pointer;
- font-size: 14px;
- border-radius: 5px;
- text-align: center;
- `;
- const pauseButtonStyle = `
- padding: 8px 16px;
- margin-top: 10px;
- background-color: #f44336;
- border: 2px solid #333;
- color: white;
- cursor: pointer;
- font-size: 14px;
- border-radius: 5px;
- text-align: center;
- `;
- const containerStyle = `
- padding: 10px;
- background-color: white;
- border: 2px solid black;
- border-radius: 10px;
- position: fixed;
- top: 10px;
- right: 10px;
- width: 320px;
- height: 500px;
- z-index: 1000;
- resize: both;
- overflow: auto;
- min-width: 200px;
- min-height: 200px;
- `;
- const edgeThreshold = 10; // The distance from the edge in pixels to allow dragging
- // Create a container for input elements
- let container = document.createElement('div');
- container.style.cssText = containerStyle;
- document.body.appendChild(container);
- // Handle dragging the container (only from edges)
- container.addEventListener('mousedown', function (e) {
- const rect = container.getBoundingClientRect();
- const isEdge = e.clientX - rect.left < edgeThreshold ||
- rect.right - e.clientX < edgeThreshold ||
- e.clientY - rect.top < edgeThreshold ||
- rect.bottom - e.clientY < edgeThreshold;
- if (isEdge) {
- isDragging = true;
- dragStartX = e.clientX;
- dragStartY = e.clientY;
- startX = container.offsetLeft;
- startY = container.offsetTop;
- e.preventDefault();
- }
- });
- document.addEventListener('mousemove', function (e) {
- if (isDragging) {
- let offsetX = e.clientX - dragStartX;
- let offsetY = e.clientY - dragStartY;
- container.style.left = startX + offsetX + 'px';
- container.style.top = startY + offsetY + 'px';
- }
- });
- document.addEventListener('mouseup', function () {
- isDragging = false;
- });
- // Create a file input for save file upload
- let fileInput = document.createElement('input');
- fileInput.type = 'file';
- fileInput.accept = '.txt';
- fileInput.style.width = '100%';
- fileInput.style.marginBottom = '10px';
- container.appendChild(fileInput);
- // Create a textbox for input
- let inputBox = document.createElement('textarea');
- inputBox.style.width = '100%';
- inputBox.style.height = '100px';
- inputBox.style.padding = '5px';
- inputBox.style.border = '1px solid #ccc';
- inputBox.style.borderRadius = '5px';
- inputBox.style.marginBottom = '10px';
- container.appendChild(inputBox);
- // Create a button to apply the save
- let enterSaveButton = document.createElement('button');
- enterSaveButton.innerHTML = 'Enter Save';
- enterSaveButton.style.cssText += buttonStyle;
- container.appendChild(enterSaveButton);
- // Create a pause/resume button
- let pauseButton = document.createElement('button');
- pauseButton.innerHTML = 'Pause';
- pauseButton.style.cssText += pauseButtonStyle;
- container.appendChild(pauseButton);
- pauseButton.addEventListener('click', () => {
- paused = !paused;
- pauseButton.innerHTML = paused ? 'Resume' : 'Pause';
- pauseButton.style.backgroundColor = paused ? '#f44336' : '#4CAF50';
- if (!paused) {
- processNextEntry();
- }
- });
- // Create a label for the slider
- let sliderLabel = document.createElement('label');
- sliderLabel.innerHTML = 'Wait Time (ms):';
- container.appendChild(sliderLabel);
- // Create a slider for wait time
- let waitTimeSlider = document.createElement('input');
- waitTimeSlider.type = 'range';
- waitTimeSlider.min = '100';
- waitTimeSlider.max = '3000';
- waitTimeSlider.value = '1000';
- waitTimeSlider.style.width = '100%';
- waitTimeSlider.style.marginBottom = '10px';
- container.appendChild(waitTimeSlider);
- // Display the current wait time
- let waitTimeDisplay = document.createElement('div');
- waitTimeDisplay.innerHTML = `Current wait time: ${waitTimeSlider.value} ms`;
- waitTimeDisplay.style.marginBottom = '10px';
- container.appendChild(waitTimeDisplay);
- // Create a div to show color-coded save options
- let saveListContainer = document.createElement('div');
- saveListContainer.style.width = '100%';
- saveListContainer.style.height = '150px'; // Set height and make it scrollable
- saveListContainer.style.overflowY = 'auto'; // Enable vertical scrolling for the save list
- saveListContainer.style.border = '1px solid #ccc';
- saveListContainer.style.borderRadius = '5px';
- container.appendChild(saveListContainer);
- // Color cycle for the saves
- const colors = ['red', 'orange', 'yellow', 'blue', 'purple'];
- // Handle file reading and populate the saveList with color-coded saves
- fileInput.addEventListener('change', (event) => {
- const file = event.target.files[0];
- if (file) {
- const reader = new FileReader();
- reader.onload = function(e) {
- const contents = e.target.result;
- const saves = contents.split('\n').map(save => save.trim()).filter(save => save !== '');
- // Clear previous saves
- saveListContainer.innerHTML = '';
- // Populate the save list with color-coded clickable divs
- saves.forEach((save, idx) => {
- let saveItem = document.createElement('div');
- saveItem.textContent = save;
- saveItem.style.cursor = 'pointer';
- saveItem.style.padding = '5px';
- saveItem.style.border = '1px solid black';
- saveItem.style.marginBottom = '5px';
- saveItem.style.backgroundColor = colors[idx % colors.length]; // Alternate colors
- // Click to insert the save into the input box
- saveItem.addEventListener('click', () => {
- inputBox.value = save;
- });
- saveListContainer.appendChild(saveItem);
- });
- console.log('Saves loaded:', saves);
- };
- reader.readAsText(file);
- }
- });
- // Update the wait time display as the slider is moved
- waitTimeSlider.addEventListener('input', () => {
- waitTimeDisplay.innerHTML = `Current wait time: ${waitTimeSlider.value} ms`;
- });
- // Function to find the Next button
- function findNextButton() {
- return document.querySelector('button.py-4.px-8.border.border-1-black.text-lg');
- }
- // Function to simulate typing and clicking
- function simulateInput(input, callback) {
- if (paused) return;
- console.log(`Simulating input: ${input}`);
- let inputField = document.querySelector('.pl-4.py-4.text-lg.border.border-1-black');
- let submitButton = document.querySelector('.p-4.border.border-1-black.text-lg.bg-green-200, .p-4.border.border-1-black.text-lg.text-gray-400');
- if (inputField && submitButton) {
- inputField.focus();
- Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set.call(inputField, input);
- let inputEvent = new Event('input', { bubbles: true });
- let changeEvent = new Event('change', { bubbles: true });
- inputField.dispatchEvent(inputEvent);
- inputField.dispatchEvent(changeEvent);
- setTimeout(() => {
- submitButton.click();
- setTimeout(() => {
- let nextButton = findNextButton();
- if (nextButton) {
- nextButton.click(); // Click the next button
- setTimeout(callback, parseInt(waitTimeSlider.value));
- } else {
- console.log('Next button not found, retrying...');
- setTimeout(() => simulateInput(input, callback), parseInt(waitTimeSlider.value)); // Retry if the next button is not found
- }
- }, parseInt(waitTimeSlider.value));
- }, parseInt(waitTimeSlider.value));
- } else {
- console.log('Input field or submit button not found, retrying...');
- setTimeout(() => simulateInput(input, callback), parseInt(waitTimeSlider.value));
- }
- }
- // Function to enter the save from the input box and start processing it
- function enterSave() {
- let saveText = inputBox.value.trim();
- if (!saveText) {
- alert('Please enter a save');
- console.log('No save text entered.');
- return;
- }
- saveEntries = saveText.split('🤜').map(entry => entry.trim()).reverse();
- index = 0;
- processNextEntry();
- }
- function processNextEntry() {
- if (paused) return;
- if (index < saveEntries.length) {
- let currentInput = checkTextBoxForCurrentInput();
- let currentIndex = saveEntries.findIndex(entry => entry.toLowerCase() === currentInput.toLowerCase());
- if (currentIndex !== -1 && currentIndex + 1 < saveEntries.length) {
- console.log(`Current input is "${currentInput}". Inputting next entry: ${saveEntries[currentIndex + 1]}`);
- simulateInput(saveEntries[currentIndex + 1], () => {
- index = currentIndex + 2;
- processNextEntry();
- });
- } else {
- console.log(`Current input "${currentInput}" does not match any expected input. Retrying...`);
- setTimeout(processNextEntry, parseInt(waitTimeSlider.value));
- }
- } else {
- console.log('All entries processed.');
- }
- }
- function checkTextBoxForCurrentInput() {
- let currentInputElement = document.querySelector('.text-2xl.text-center');
- if (currentInputElement) {
- let currentInput = currentInputElement.textContent.trim();
- if (currentInput.endsWith('?')) {
- currentInput = currentInput.slice(0, -1);
- }
- return currentInput;
- }
- return null;
- }
- // Add the Enter Save button click event
- enterSaveButton.addEventListener('click', () => {
- console.log('Enter Save button clicked.');
- enterSave();
- });
- })();