mirror of
https://github.com/SwingTheVine/Wplace-BlueMarble.git
synced 2026-01-11 22:40:18 +00:00
Added styling in consoles
This commit is contained in:
parent
aa68b22478
commit
8230b08e94
16 changed files with 241 additions and 103 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -3,6 +3,10 @@
|
|||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User specified files
|
||||
## Generated files
|
||||
mapCSS.json
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import esbuild from 'esbuild';
|
||||
import fs from 'fs';
|
||||
import { execSync } from 'child_process';
|
||||
import { consoleStyle } from './utils.js';
|
||||
import mangleSelectors from './cssMangler.js';
|
||||
|
||||
import { createRequire } from 'module';
|
||||
|
|
@ -19,14 +20,16 @@ const require = createRequire(import.meta.url);
|
|||
// CommonJS imports (require)
|
||||
const terser = require('terser');
|
||||
|
||||
const isGitHub = !!process.env?.GITHUB_ACTIONS; // Is this running in a GitHub Action Workflow?
|
||||
const isGitHub = !!process.env?.GITHUB_ACTIONS; // Is this running in a GitHub Action Workflow?'
|
||||
|
||||
console.log(`${consoleStyle.BLUE}Starting build...${consoleStyle.RESET}`);
|
||||
|
||||
// Tries to bump the version
|
||||
try {
|
||||
const update = execSync('node build/update-version.js', { stdio: 'inherit' });
|
||||
console.log('Version updated in meta file successfully');
|
||||
console.log(`Version updated in meta file ${consoleStyle.GREEN}successfully${consoleStyle.RESET}`);
|
||||
} catch (error) {
|
||||
console.error('Failed to update version number:', error);
|
||||
console.error(`${consoleStyle.RED + consoleStyle.BOLD}Failed to update version number${consoleStyle.RESET}:`, error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +93,11 @@ let resultTerser = await terser.minify(resultEsbuildJS.text, {
|
|||
fs.writeFileSync('dist/BlueMarble.user.js', resultTerser.code, 'utf8');
|
||||
|
||||
// Mangles the CSS selectors
|
||||
mangleSelectors('bm-', 'bm-', 'dist/BlueMarble.user.js', 'dist/BlueMarble.user.css');
|
||||
// If we are NOT in production (GitHub Workflow), then generate the CSS mapping
|
||||
const mapCSS = mangleSelectors('bm-', 'bm-', 'dist/BlueMarble.user.js', 'dist/BlueMarble.user.css', !isGitHub);
|
||||
if (mapCSS) {
|
||||
fs.writeFileSync('dist/mapCSS.json', JSON.stringify(mapCSS, null, 2));
|
||||
}
|
||||
|
||||
// Adds the banner
|
||||
fs.writeFileSync(
|
||||
|
|
@ -98,3 +105,5 @@ fs.writeFileSync(
|
|||
metaContent + fs.readFileSync('dist/BlueMarble.user.js', 'utf8'),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
console.log(`${consoleStyle.GREEN + consoleStyle.BOLD + consoleStyle.UNDERLINE}Building complete!${consoleStyle.RESET}`);
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
|
||||
import fs from 'fs';
|
||||
import { execSync } from 'child_process';
|
||||
import { consoleStyle } from './utils.js';
|
||||
|
||||
console.log(`${consoleStyle.BLUE}Starting patch...${consoleStyle.RESET}`);
|
||||
|
||||
try {
|
||||
const update = execSync('npm version patch --no-git-tag-version', { stdio: 'inherit' });
|
||||
console.log('Version patch updated successfully');
|
||||
console.log(`Version patch updated ${consoleStyle.GREEN}successfully${consoleStyle.RESET}`);
|
||||
} catch (error) {
|
||||
console.error('Failed to update version number:', error);
|
||||
console.error(`${consoleStyle.RED + consoleStyle.BOLD}Failed to update version number${consoleStyle.RESET}:`, error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import { consoleStyle } from './utils.js';
|
||||
|
||||
console.log(`${consoleStyle.BLUE}Starting update-version...${consoleStyle.RESET}`);
|
||||
|
||||
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
const version = pkg.version;
|
||||
|
|
@ -12,4 +15,4 @@ let meta = fs.readFileSync('src/BlueMarble.meta.js', 'utf-8');
|
|||
meta = meta.replace(/@version\s+[\d.]+/, `@version ${version}`);
|
||||
|
||||
fs.writeFileSync('src/BlueMarble.meta.js', meta);
|
||||
console.log(`Updated userscript version to ${version}`);
|
||||
console.log(`${consoleStyle.GREEN}Updated${consoleStyle.RESET} userscript version to ${consoleStyle.MAGENTA}${version}${consoleStyle.RESET}`);
|
||||
32
build/utils.js
Normal file
32
build/utils.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/** Styling for the console log.
|
||||
* This only affects the console in the dev's IDE and GitHub Workflow.
|
||||
* @since 0.58.24
|
||||
*/
|
||||
export const consoleStyle = {
|
||||
|
||||
/** Resets all styling */
|
||||
RESET: '\x1b[0m',
|
||||
/** Makes the text **bold** */
|
||||
BOLD: '\x1b[1m',
|
||||
/** Makes the text underlined */
|
||||
UNDERLINE: '\x1b[4m',
|
||||
/** Inverses the color of the text and the background */
|
||||
INVERSE: '\x1b[7m',
|
||||
|
||||
/** Turns the text white */
|
||||
WHITE: '\x1b[37m',
|
||||
/** Turns the text black */
|
||||
BLACK: '\x1b[30m',
|
||||
/** Turns the text red */
|
||||
RED: '\x1b[31m',
|
||||
/** Turns the text green */
|
||||
GREEN: '\x1b[32m',
|
||||
/** Turns the text yellow */
|
||||
YELLOW: '\x1b[33m',
|
||||
/** Turns the text blue */
|
||||
BLUE: '\x1b[34m',
|
||||
/** Turns the text magenta */
|
||||
MAGENTA: '\x1b[35m',
|
||||
/** Turns the text cyan */
|
||||
CYAN: '\x1b[36m'
|
||||
}
|
||||
2
dist/BlueMarble.user.css
vendored
2
dist/BlueMarble.user.css
vendored
|
|
@ -1 +1 @@
|
|||
#bm-p{position:fixed;background-color:#153063e6;color:#fff;padding:10px;border-radius:8px;z-index:9000}div#bm-p{font-family:Roboto Mono,Courier New,Monaco,DejaVu Sans Mono,monospace,Arial;letter-spacing:.05em}#bm-k{margin-bottom:.5em;background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="5" height="5"><circle cx="3" cy="3" r="1.5" fill="CornflowerBlue" /></svg>') repeat;cursor:grab;width:100%;height:1em}#bm-k.dragging{cursor:grabbing}#bm-b{margin-bottom:.5em}#bm-p img{display:inline-block;height:2.5em;margin-right:1ch;vertical-align:middle}#bm-p h1{display:inline-block;font-size:x-large;font-weight:700;vertical-align:middle}#bm-3 input[type=checkbox]{vertical-align:middle;margin-right:.5ch}#bm-3 label{margin-right:.5ch}.bm-q{border:white 1px solid;height:1.5em;width:1.5em;margin-top:2px;text-align:center;line-height:1em;padding:0!important}#bm-h{vertical-align:middle}#bm-h svg{width:50%;margin:0 auto;fill:#111}div#bm-7{display:flex;gap:.5ch}#bm-8 svg,#bm-button-template svg{height:1em;margin:2px auto 0;text-align:center;line-height:1em;vertical-align:bottom}#bm-c input[type=number]{appearance:auto;-moz-appearance:textfield;width:5.5ch;margin-left:1ch;background-color:#0003;padding:0 .5ch;font-size:small}#bm-c input[type=number]::-webkit-outer-spin-button,#bm-c input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}#bm-0{display:flex;flex-direction:row;flex-wrap:wrap;align-content:center;justify-content:center;align-items:center;gap:1ch}div:has(>#bm-2)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#bm-e{font-size:small;background-color:#0003;padding:0 .5ch;height:3.75em;width:100%}#bm-1{display:flex;justify-content:space-between}#bm-p small{font-size:x-small;color:#d3d3d3}#bm-4,#bm-3,#bm-c,#bm-0,div:has(>#bm-2),#bm-e{margin-top:.5em}#bm-p button{background-color:#144eb9;border-radius:1em;padding:0 .75ch}#bm-p button:hover,#bm-p button:focus-visible{background-color:#1061e5}#bm-p button:active,#bm-p button:disabled{background-color:#2e97ff}#bm-p button:disabled{text-decoration:line-through}
|
||||
#bm-p{position:fixed;background-color:#153063e6;color:#fff;padding:10px;border-radius:8px;z-index:9000}div#bm-p{font-family:Roboto Mono,Courier New,Monaco,DejaVu Sans Mono,monospace,Arial;letter-spacing:.05em}#bm-k{margin-bottom:.5em;background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="5" height="5"><circle cx="3" cy="3" r="1.5" fill="CornflowerBlue" /></svg>') repeat;cursor:grab;width:100%;height:1em}#bm-k.dragging{cursor:grabbing}#bm-b{margin-bottom:.5em}#bm-p img{display:inline-block;height:2.5em;margin-right:1ch;vertical-align:middle}#bm-p h1{display:inline-block;font-size:x-large;font-weight:700;vertical-align:middle}#bm-3 input[type=checkbox]{vertical-align:middle;margin-right:.5ch}#bm-3 label{margin-right:.5ch}.bm-s{border:white 1px solid;height:1.5em;width:1.5em;margin-top:2px;text-align:center;line-height:1em;padding:0!important}#bm-h{vertical-align:middle}#bm-h svg{width:50%;margin:0 auto;fill:#111}div>#bm-7{display:flex;gap:.5ch}#bm-8 svg,#bm-button-template svg{height:1em;margin:2px auto 0;text-align:center;line-height:1em;vertical-align:bottom}#bm-c input[type=number]{appearance:auto;-moz-appearance:textfield;width:5.5ch;margin-left:1ch;background-color:#0003;padding:0 .5ch;font-size:small}#bm-c input[type=number]::-webkit-outer-spin-button,#bm-c input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}#bm-0{display:flex;flex-direction:row;flex-wrap:wrap;align-content:center;justify-content:center;align-items:center;gap:1ch}div:has(>#bm-2)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#bm-e{font-size:small;background-color:#0003;padding:0 .5ch;height:3.75em;width:100%}#bm-1{display:flex;justify-content:space-between}#bm-p small{font-size:x-small;color:#d3d3d3}#bm-4,#bm-3,#bm-c,#bm-0,div:has(>#bm-2),#bm-e{margin-top:.5em}#bm-p button{background-color:#144eb9;border-radius:1em;padding:0 .75ch}#bm-p button:hover,#bm-p button:focus-visible{background-color:#1061e5}#bm-p button:active,#bm-p button:disabled{background-color:#2e97ff}#bm-p button:disabled{text-decoration:line-through}
|
||||
|
|
|
|||
4
dist/BlueMarble.user.js
vendored
4
dist/BlueMarble.user.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -35,7 +35,7 @@
|
|||
<a href="https://github.com/SwingTheVine/Wplace-BlueMarble/blob/main/LICENSE.txt" target="_blank"><img alt="Software License: MPL-2.0" src="https://img.shields.io/badge/Software_License-MPL--2.0-brightgreen?style=flat"></a>
|
||||
<a href="https://discord.gg/tpeBPy46hf" target="_blank"><img alt="Contact Me" src="https://img.shields.io/badge/Contact_Me-gray?style=flat&logo=Discord&logoColor=white&logoSize=auto&labelColor=cornflowerblue"></a>
|
||||
<a href="" target="_blank"><img alt="WakaTime" src="https://img.shields.io/badge/Coding_Time-35hrs_30mins-blue?style=flat&logo=wakatime&logoColor=black&logoSize=auto&labelColor=white"></a>
|
||||
<a href="" target="_blank"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-229-black?style=flat"></a>
|
||||
<a href="" target="_blank"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-252-black?style=flat"></a>
|
||||
<a href="" target="_blank"><img alt="Total Lines of Code" src="https://tokei.rs/b1/github/SwingTheVine/Wplace-BlueMarble?category=code"></a>
|
||||
<a href="" target="_blank"><img alt="Total Comments" src="https://tokei.rs/b1/github/SwingTheVine/Wplace-BlueMarble?category=comments"></a>
|
||||
<a href="" target="_blank"><img alt="Compression" src="https://img.shields.io/badge/Compression-70.56%25-blue"></a>
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.58.2",
|
||||
"version": "0.58.25",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.58.2",
|
||||
"version": "0.58.25",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"terser": "^5.43.1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.58.2",
|
||||
"version": "0.58.25",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node build/build.js",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name Blue Marble
|
||||
// @namespace https://github.com/SwingTheVine/
|
||||
// @version 0.58.2
|
||||
// @version 0.58.25
|
||||
// @description A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @author SwingTheVine
|
||||
// @license MPL-2.0
|
||||
|
|
|
|||
|
|
@ -609,6 +609,18 @@ export default class Overlay {
|
|||
});
|
||||
}
|
||||
|
||||
/** Handles status display.
|
||||
* This will output plain text into the output Status box.
|
||||
* Additionally, this will output an info message to the console.
|
||||
* @param {string} text - The status text to display.
|
||||
* @since 0.58.4
|
||||
*/
|
||||
handleDisplayStatus(text) {
|
||||
const consoleInfo = console.info; // Creates a copy of the console.info function
|
||||
consoleInfo(`${this.name}: ${text}`); // Outputs something like "ScriptName: text" as an info message to the console
|
||||
this.updateInnerHTML(this.outputStatusId, 'Status: ' + text, true); // Update output Status box
|
||||
}
|
||||
|
||||
/** Handles error display.
|
||||
* This will output plain text into the output Status box.
|
||||
* Additionally, this will output an error to the console.
|
||||
|
|
@ -616,8 +628,8 @@ export default class Overlay {
|
|||
* @since 0.41.6
|
||||
*/
|
||||
handleDisplayError(text) {
|
||||
const consoleError = console.error; // Idk anymore...
|
||||
consoleError(`${this.name}: ${text}`); // Outputs something like "ScriptName: text" as an error to the console
|
||||
this.updateInnerHTML(this.outputStatusId, 'Error: ' + text, true);
|
||||
const consoleError = console.error; // Creates a copy of the console.error function
|
||||
consoleError(`${this.name}: ${text}`); // Outputs something like "ScriptName: text" as an error message to the console
|
||||
this.updateInnerHTML(this.outputStatusId, 'Error: ' + text, true); // Update output Status box
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ export default class ApiManager {
|
|||
// E.g. "wplace.live/api/pixel/0/0?payload" -> "pixel"
|
||||
const endpointText = data['endpoint'].split('?')[0].split('/').filter(s => s && isNaN(Number(s))).pop();
|
||||
|
||||
console.log(`Recieved message about "${endpointText}"`);
|
||||
console.log(`%cBlue Marble%c: Recieved message about "${endpointText}"`, 'color: cornflowerblue;', '');
|
||||
|
||||
// Each case is something that Blue Marble can use from the fetch.
|
||||
// For instance, if the fetch was for "me", we can update the overlay stats
|
||||
|
|
|
|||
188
src/main.js
188
src/main.js
|
|
@ -1,28 +1,40 @@
|
|||
/** The main file. Everything in the userscript is executed from here.
|
||||
* @since 0.0.0
|
||||
*/
|
||||
|
||||
import Overlay from './Overlay.js';
|
||||
import Observers from './observers.js';
|
||||
import ApiManager from './apiManager.js';
|
||||
import TemplateManager from './templateManager.js';
|
||||
import { consoleLog } from './utils.js';
|
||||
|
||||
const name = GM_info.script.name.toString();
|
||||
const version = GM_info.script.version.toString();
|
||||
const name = GM_info.script.name.toString(); // Name of userscript
|
||||
const version = GM_info.script.version.toString(); // Version of userscript
|
||||
const consoleStyle = 'color: cornflowerblue;'; // The styling for the console logs
|
||||
|
||||
/** Injects code into the client
|
||||
* This code will execute outside of TamperMonkey's sandbox
|
||||
* @param {*} fn - The code to execute
|
||||
* @param {*} callback - The code to execute
|
||||
* @since 0.11.15
|
||||
*/
|
||||
function inject(fn) {
|
||||
function inject(callback) {
|
||||
const script = document.createElement('script');
|
||||
script.textContent = `(${fn})();`;
|
||||
script.setAttribute('bm-name', name); // Passes in the name value
|
||||
script.setAttribute('bm-cStyle', consoleStyle); // Passes in the console style value
|
||||
script.textContent = `(${callback})();`;
|
||||
document.documentElement.appendChild(script);
|
||||
script.remove();
|
||||
}
|
||||
|
||||
/** What code to execute instantly in the client.
|
||||
* This code will execute outside of TamperMonkey's sandbox
|
||||
/** What code to execute instantly in the client (webpage).
|
||||
* This code will execute outside of TamperMonkey's sandbox.
|
||||
* @since 0.11.15
|
||||
*/
|
||||
inject(() => {
|
||||
|
||||
const script = document.currentScript; // Gets the current script HTML Script Element
|
||||
const name = script?.getAttribute('bm-name') || 'Blue Marble'; // Gets the name value that was passed in. Defaults to "Blue Marble" if nothing was found
|
||||
const consoleStyle = script?.getAttribute('bm-cStyle') || ''; // Gets the console style value that was passed in. Defaults to no styling if nothing was found
|
||||
|
||||
// Spys on "spontaneous" fetch requests made by the client
|
||||
const originalFetch = window.fetch; // Saves a copy of the original fetch
|
||||
|
|
@ -39,9 +51,9 @@ inject(() => {
|
|||
|
||||
// Retrieves the endpoint name. Unknown endpoint = "ignore"
|
||||
let endpointName = ((args[0] instanceof Request) ? args[0]?.url : args[0]) || 'ignore';
|
||||
//endpointName = endpointName.split('/').filter(Boolean).pop() || 'ignore';
|
||||
|
||||
console.log(`Sending JSON message about endpoint "${endpointName}"`);
|
||||
// Since this code does not run in the userscript, we can't use consoleLog().
|
||||
console.log(`%c${name}%c: Sending JSON message about endpoint "${endpointName}"`, consoleStyle, '');
|
||||
|
||||
// Sends a message about the endpoint it spied on
|
||||
cloned.json()
|
||||
|
|
@ -53,7 +65,7 @@ inject(() => {
|
|||
}, '*');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('BM - Failed to parse JSON:', err);
|
||||
console.error(`%c${name}%c: Failed to parse JSON: `, consoleStyle, '', err);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +88,7 @@ stylesheetLink.onload = function () {
|
|||
};
|
||||
document.head.appendChild(stylesheetLink);
|
||||
|
||||
// CONSTRUCTORS
|
||||
const observers = new Observers(); // Constructs a new Observers object
|
||||
const overlay = new Overlay(name, version); // Constructs a new Overlay object
|
||||
const templateManager = new TemplateManager(); // Constructs a new TemplateManager object
|
||||
|
|
@ -83,81 +96,90 @@ const apiManager = new ApiManager(); // Constructs a new ApiManager object
|
|||
|
||||
overlay.setApiManager(apiManager); // Sets the API manager
|
||||
|
||||
// Deploys the overlay to the page
|
||||
// Parent/child relationships in the DOM structure below are indicated by indentation
|
||||
overlay.addDiv({'id': 'bm-overlay', 'style': 'top: 10px; right: 75px;'})
|
||||
.addDiv({'id': 'bm-contain-header'})
|
||||
.addDiv({'id': 'bm-bar-drag'}).buildElement()
|
||||
.addImg({'alt': 'Blue Marble Icon', 'src': 'https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png'}).buildElement()
|
||||
.addHeader(1, {'textContent': name}).buildElement()
|
||||
.buildElement()
|
||||
|
||||
.addHr().buildElement()
|
||||
|
||||
.addDiv({'id': 'bm-contain-userinfo'})
|
||||
.addP({'id': 'bm-user-name', 'textContent': 'Username:'}).buildElement()
|
||||
.addP({'id': 'bm-user-droplets', 'textContent': 'Droplets:'}).buildElement()
|
||||
.addP({'id': 'bm-user-nextlevel', 'textContent': 'Next level in...'}).buildElement()
|
||||
.buildElement()
|
||||
|
||||
.addHr().buildElement()
|
||||
|
||||
.addDiv({'id': 'bm-contain-automation'})
|
||||
.addCheckbox({'id': 'bm-input-stealth', 'textContent': 'Stealth', 'checked': true}).buildElement()
|
||||
.addButtonHelp({'title': 'Waits for the website to make requests, instead of sending requests.'}).buildElement()
|
||||
.addBr().buildElement()
|
||||
.addCheckbox({'id': 'bm-input-possessed', 'textContent': 'Possessed', 'checked': true}).buildElement()
|
||||
.addButtonHelp({'title': 'Controls the website as if it were possessed.'}).buildElement()
|
||||
.addBr().buildElement()
|
||||
.addDiv({'id': 'bm-contain-coords'})
|
||||
.addButton({'id': 'bm-button-coords', 'className': 'bm-help', 'style': 'margin-top: 0;', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 6"><circle cx="2" cy="2" r="2"></circle><path d="M2 6 L3.7 3 L0.3 3 Z"></path><circle cx="2" cy="2" r="0.7" fill="white"></circle></svg></svg>'},
|
||||
(instance, button) => {
|
||||
button.onclick = () => {
|
||||
const coords = instance.apiManager?.coordsTilePixel; // Retrieves the coords from the API manager
|
||||
if (!coords?.[0]) {
|
||||
instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?');
|
||||
return;
|
||||
}
|
||||
instance.updateInnerHTML('bm-input-tx', coords?.[0] || '');
|
||||
instance.updateInnerHTML('bm-input-ty', coords?.[1] || '');
|
||||
instance.updateInnerHTML('bm-input-px', coords?.[2] || '');
|
||||
instance.updateInnerHTML('bm-input-py', coords?.[3] || '');
|
||||
}
|
||||
}
|
||||
).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-tx', 'placeholder': 'Tl X', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-ty', 'placeholder': 'Tl Y', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-px', 'placeholder': 'Px X', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-py', 'placeholder': 'Px Y', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.buildElement()
|
||||
.addInputFile({'id': 'bm-input-file-template', 'textContent': 'Upload Template', 'accept': 'image/png, image/jpeg, image/webp, image/bmp, image/gif'}).buildElement()
|
||||
.addDiv({'id': 'bm-contain-buttons-template'})
|
||||
.addButton({'id': 'bm-button-enable', 'textContent': 'Enable'}, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
const input = document.querySelector('#bm-input-file-template');
|
||||
|
||||
// Kills itself if there is no file
|
||||
if (!input?.files[0]) {instance.handleDisplayError(`No file selected!`); return;}
|
||||
|
||||
templateManager.setTemplateImage(input.files[0]);
|
||||
}
|
||||
}).buildElement()
|
||||
.addButton({'id': 'bm-button-disable', 'textContent': 'Disable'}).buildElement()
|
||||
.buildElement()
|
||||
.addTextarea({'id': overlay.outputStatusId, 'placeholder': `Status: Sleeping...\nVersion: ${version}`, 'readOnly': true}).buildElement()
|
||||
.addDiv({'id': 'bm-contain-buttons-action'})
|
||||
.addDiv()
|
||||
.addButton({'id': 'bm-button-teleport', 'className': 'bm-help', 'textContent': '✈'}).buildElement()
|
||||
.addButton({'id': 'bm-button-favorite', 'className': 'bm-help', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><polygon points="10,2 12,7.5 18,7.5 13.5,11.5 15.5,18 10,14 4.5,18 6.5,11.5 2,7.5 8,7.5" fill="white"></polygon></svg>'}).buildElement()
|
||||
.addButton({'id': 'bm-button-templates', 'className': 'bm-help', 'innerHTML': '🖌'}).buildElement()
|
||||
.buildElement()
|
||||
.addSmall({'textContent': 'Made by SwingTheVine', 'style': 'margin-top: auto;'}).buildElement()
|
||||
.buildElement()
|
||||
.buildElement()
|
||||
.buildOverlay(document.body);
|
||||
buildOverlayMain(); // Builds the main overlay
|
||||
|
||||
overlay.handleDrag('#bm-overlay', '#bm-bar-drag'); // Creates dragging capability on the drag bar for dragging the overlay
|
||||
|
||||
apiManager.spontaneousResponseListener(overlay); // Reads spontaneous fetch responces
|
||||
|
||||
console.log(`${name} (${version}) userscript has loaded!`);
|
||||
consoleLog(`%c${name}%c (${version}) userscript has loaded!`, 'color: cornflowerblue;', '');
|
||||
|
||||
/** Deploys the overlay to the page.
|
||||
* Parent/child relationships in the DOM structure below are indicated by indentation.
|
||||
* @since 0.58.3
|
||||
*/
|
||||
function buildOverlayMain() {
|
||||
overlay.addDiv({'id': 'bm-overlay', 'style': 'top: 10px; right: 75px;'})
|
||||
.addDiv({'id': 'bm-contain-header'})
|
||||
.addDiv({'id': 'bm-bar-drag'}).buildElement()
|
||||
.addImg({'alt': 'Blue Marble Icon', 'src': 'https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png'}).buildElement()
|
||||
.addHeader(1, {'textContent': name}).buildElement()
|
||||
.buildElement()
|
||||
|
||||
.addHr().buildElement()
|
||||
|
||||
.addDiv({'id': 'bm-contain-userinfo'})
|
||||
.addP({'id': 'bm-user-name', 'textContent': 'Username:'}).buildElement()
|
||||
.addP({'id': 'bm-user-droplets', 'textContent': 'Droplets:'}).buildElement()
|
||||
.addP({'id': 'bm-user-nextlevel', 'textContent': 'Next level in...'}).buildElement()
|
||||
.buildElement()
|
||||
|
||||
.addHr().buildElement()
|
||||
|
||||
.addDiv({'id': 'bm-contain-automation'})
|
||||
.addCheckbox({'id': 'bm-input-stealth', 'textContent': 'Stealth', 'checked': true}).buildElement()
|
||||
.addButtonHelp({'title': 'Waits for the website to make requests, instead of sending requests.'}).buildElement()
|
||||
.addBr().buildElement()
|
||||
.addCheckbox({'id': 'bm-input-possessed', 'textContent': 'Possessed', 'checked': true}).buildElement()
|
||||
.addButtonHelp({'title': 'Controls the website as if it were possessed.'}).buildElement()
|
||||
.addBr().buildElement()
|
||||
.addDiv({'id': 'bm-contain-coords'})
|
||||
.addButton({'id': 'bm-button-coords', 'className': 'bm-help', 'style': 'margin-top: 0;', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 6"><circle cx="2" cy="2" r="2"></circle><path d="M2 6 L3.7 3 L0.3 3 Z"></path><circle cx="2" cy="2" r="0.7" fill="white"></circle></svg></svg>'},
|
||||
(instance, button) => {
|
||||
button.onclick = () => {
|
||||
const coords = instance.apiManager?.coordsTilePixel; // Retrieves the coords from the API manager
|
||||
if (!coords?.[0]) {
|
||||
instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?');
|
||||
return;
|
||||
}
|
||||
instance.updateInnerHTML('bm-input-tx', coords?.[0] || '');
|
||||
instance.updateInnerHTML('bm-input-ty', coords?.[1] || '');
|
||||
instance.updateInnerHTML('bm-input-px', coords?.[2] || '');
|
||||
instance.updateInnerHTML('bm-input-py', coords?.[3] || '');
|
||||
}
|
||||
}
|
||||
).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-tx', 'placeholder': 'Tl X', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-ty', 'placeholder': 'Tl Y', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-px', 'placeholder': 'Px X', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-py', 'placeholder': 'Px Y', 'min': 0, 'max': 2047, 'step': 1}).buildElement()
|
||||
.buildElement()
|
||||
.addInputFile({'id': 'bm-input-file-template', 'textContent': 'Upload Template', 'accept': 'image/png, image/jpeg, image/webp, image/bmp, image/gif'}).buildElement()
|
||||
.addDiv({'id': 'bm-contain-buttons-template'})
|
||||
.addButton({'id': 'bm-button-enable', 'textContent': 'Enable'}, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
const input = document.querySelector('#bm-input-file-template');
|
||||
|
||||
// Kills itself if there is no file
|
||||
if (!input?.files[0]) {instance.handleDisplayError(`No file selected!`); return;}
|
||||
|
||||
templateManager.setTemplateImage(input.files[0]);
|
||||
|
||||
templateManager.tempDraw();
|
||||
instance.handleDisplayStatus(`Drew to canvas!`);
|
||||
}
|
||||
}).buildElement()
|
||||
.addButton({'id': 'bm-button-disable', 'textContent': 'Disable'}).buildElement()
|
||||
.buildElement()
|
||||
.addTextarea({'id': overlay.outputStatusId, 'placeholder': `Status: Sleeping...\nVersion: ${version}`, 'readOnly': true}).buildElement()
|
||||
.addDiv({'id': 'bm-contain-buttons-action'})
|
||||
.addDiv()
|
||||
.addButton({'id': 'bm-button-teleport', 'className': 'bm-help', 'textContent': '✈'}).buildElement()
|
||||
.addButton({'id': 'bm-button-favorite', 'className': 'bm-help', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><polygon points="10,2 12,7.5 18,7.5 13.5,11.5 15.5,18 10,14 4.5,18 6.5,11.5 2,7.5 8,7.5" fill="white"></polygon></svg>'}).buildElement()
|
||||
.addButton({'id': 'bm-button-templates', 'className': 'bm-help', 'innerHTML': '🖌'}).buildElement()
|
||||
.buildElement()
|
||||
.addSmall({'textContent': 'Made by SwingTheVine', 'style': 'margin-top: auto;'}).buildElement()
|
||||
.buildElement()
|
||||
.buildElement()
|
||||
.buildOverlay(document.body);
|
||||
}
|
||||
|
|
@ -7,10 +7,28 @@ export default class TemplateManager {
|
|||
* @since 0.55.8
|
||||
*/
|
||||
constructor() {
|
||||
this.canvas = null; // The canvas
|
||||
this.canvasID = 'div#map canvas'; // The selector for the main canvas
|
||||
this.template = null; // The template image.
|
||||
this.state = ''; // The state of the template ('blob', 'proccessing', 'template', etc.)
|
||||
}
|
||||
|
||||
/** Retrieves the pixel art canvas.
|
||||
* If the canvas has been updated/replaced, it retrieves the new one.
|
||||
* @param {string} selector - The CSS selector to use to find the canvas.
|
||||
* @returns {HTMLCanvasElement|null} The canvas as an HTML Canvas Element, or null if the canvas does not exist
|
||||
* @since 0.58.3
|
||||
*/
|
||||
getCanvas(selector) {
|
||||
|
||||
// If the stored canvas is "fresh," return the stored canvas
|
||||
if (document.body.contains(this.canvas)) {return this.canvas;}
|
||||
// Else, the stored canvas is "stale," get the canvas again
|
||||
|
||||
this.canvas = document.querySelector(selector); // Get the new canvas
|
||||
return this.canvas; // Return the new canvas or null
|
||||
}
|
||||
|
||||
/** Sets the template to the image passed in.
|
||||
* @param {File} file - The file of the template image.
|
||||
* @since 0.55.8
|
||||
|
|
@ -24,4 +42,12 @@ export default class TemplateManager {
|
|||
window.open(url, '_blank'); // Opens a new tab with blob
|
||||
setTimeout(() => URL.revokeObjectURL(url), 10000); // Destroys the blob 10 seconds later
|
||||
}
|
||||
|
||||
tempDraw() {
|
||||
const ctx = this.getCanvas(this.canvasID)?.getContext('2d');
|
||||
if (ctx) {
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.fillRect(21511, 1305644, 500, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/utils.js
29
src/utils.js
|
|
@ -43,4 +43,31 @@ export function serverTPtoDisplayTP(tile, pixel) {
|
|||
*/
|
||||
export function negativeSafeModulo(a, b) {
|
||||
return (a % b + b) % b;
|
||||
}
|
||||
}
|
||||
|
||||
/** Bypasses terser's stripping of console function calls.
|
||||
* This is so the non-obfuscated code will contain debugging console calls, but the distributed version won't.
|
||||
* However, the distributed version needs to call the console somehow, so this wrapper function is how.
|
||||
* This is the same as `console.log()`.
|
||||
* @param {...any} args - Arguments to be passed into the `log()` function of the Console
|
||||
* @since 0.58.9
|
||||
*/
|
||||
export function consoleLog(...args) {((consoleLog) => consoleLog(...args))(console.log);}
|
||||
|
||||
/** Bypasses terser's stripping of console function calls.
|
||||
* This is so the non-obfuscated code will contain debugging console calls, but the distributed version won't.
|
||||
* However, the distributed version needs to call the console somehow, so this wrapper function is how.
|
||||
* This is the same as `console.error()`.
|
||||
* @param {...any} args - Arguments to be passed into the `error()` function of the Console
|
||||
* @since 0.58.13
|
||||
*/
|
||||
export function consoleError(...args) {((consoleError) => consoleError(...args))(console.error);}
|
||||
|
||||
/** Bypasses terser's stripping of console function calls.
|
||||
* This is so the non-obfuscated code will contain debugging console calls, but the distributed version won't.
|
||||
* However, the distributed version needs to call the console somehow, so this wrapper function is how.
|
||||
* This is the same as `console.warn()`.
|
||||
* @param {...any} args - Arguments to be passed into the `warn()` function of the Console
|
||||
* @since 0.58.13
|
||||
*/
|
||||
export function consoleWarn(...args) {((consoleWarn) => consoleWarn(...args))(console.warn);}
|
||||
Loading…
Reference in a new issue