Greasy Fork

Library For Mxobot

Library for Mxobot

目前为 2023-08-11 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.cloud/scripts/461063/1234066/Library%20For%20Mxobot.js

// ==UserScript==
// @name         MXO LİBRARY
// @namespace    mxo
// @version      1.2
// @description  LİBRARY FOR MXOBOT
// @author       @ngixl
// @match        https://pixelplace.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=pixelplace.io
// @grant        unsafeWindow
// @require      https://greasyfork.org/scripts/462620-mxobot-example-bot/code/MxoBot%20Example%20Bot.js

/* globals unsafeWindow*/
/*jshint esversion: 11 */

Object.defineProperty(unsafeWindow,"console",{value:console,writable:false});class MxoBotLoggerFactory{static TEMPLATE="%c[MxoBotCore] %s: %s";static CSS_INFO="color:green";static CSS_WARNING="color:yellow;";static CSS_ERROR="color:red;font-weight: bold;";static TEMPLATE_INFO="INFO";static TEMPLATE_WARNING="WARNING";static TEMPLATE_ERROR="ERROR";static LEVEL_INFO=0;static LEVEL_WARNING=1;static LEVEL_ERROR=2;LEVEL=MxoBotLoggerFactory.LEVEL_INFO;constructor(){this.listeners=[];this.listeners.push(function(template,css,level,msg){console.log(template,css,level,msg)})}dispatch(template,css,level,msg){this.listeners.forEach(listener=>{listener(template,css,level,msg)})}info(msg){if(this.LEVEL<=MxoBotLoggerFactory.LEVEL_INFO){this.dispatch(MxoBotLoggerFactory.TEMPLATE,MxoBotLoggerFactory.CSS_INFO,MxoBotLoggerFactory.TEMPLATE_INFO,msg)}}warning(msg){if(this.LEVEL<=MxoBotLoggerFactory.LEVEL_WARNING){this.dispatch(MxoBotLoggerFactory.TEMPLATE,MxoBotLoggerFactory.CSS_WARNING,MxoBotLoggerFactory.TEMPLATE_WARNING,msg)}}error(msg){if(this.LEVEL<=MxoBotLoggerFactory.LEVEL_ERROR){this.dispatch(MxoBotLoggerFactory.TEMPLATE,MxoBotLoggerFactory.CSS_ERROR,MxoBotLoggerFactory.TEMPLATE_ERROR,msg);throw Error(msg)}}}class MxoBotImageConverter{static getClosestColor(r,g,b,palette){let closestColor={r:0,g:0,b:0};let closestDistance=Number.MAX_VALUE;for(let i=0;i<palette.colors.length;i++){let bigint=palette.colors[i];let p_r=bigint>>16&255;let p_g=bigint>>8&255;let p_b=bigint&255;let distance=(r-p_r)**2+(g-p_g)**2+(b-p_b)**2;if(distance<closestDistance){closestColor={r:p_r,g:p_g,b:p_b};closestDistance=distance}}return closestColor}static floydSteinberg(img_data,w,h,palette){if(unsafeWindow.YURIBOT_DO_NOT_DITHER===true){return img_data}let dithered=new Uint8ClampedArray(img_data.data);let error_matrix=new Float32Array(w*h*4);for(let y=0;y<h;y++){for(let x=0;x<w;x++){let i=(y*w+x)*4;let r=img_data.data[i]+error_matrix[i];let g=img_data.data[i+1]+error_matrix[i+1];let b=img_data.data[i+2]+error_matrix[i+2];let closest=MxoBotImageConverter.getClosestColor(r,g,b,palette);dithered[i]=closest.r;dithered[i+1]=closest.g;dithered[i+2]=closest.b;dithered[i+3]=img_data.data[i+3];let err_r=r-closest.r;let err_g=g-closest.g;let err_b=b-closest.b;if(x+1<w){error_matrix[i+4]+=err_r*7/16;error_matrix[i+5]+=err_g*7/16;error_matrix[i+6]+=err_b*7/16}if(y+1<h){if(x>0){error_matrix[i+4*w-4]+=err_r*3/16;error_matrix[i+4*w-3]+=err_g*3/16;error_matrix[i+4*w-2]+=err_b*3/16}error_matrix[i+4*w]+=err_r*5/16;error_matrix[i+4*w+1]+=err_g*5/16;error_matrix[i+4*w+2]+=err_b*5/16;if(x+1<w){error_matrix[i+4*w+4]+=err_r*1/16;error_matrix[i+4*w+5]+=err_g*1/16;error_matrix[i+4*w+6]+=err_b*1/16}}}}const dithered_img_data=new ImageData(dithered,w,h);return dithered_img_data}}const MxoBotLogger=new MxoBotLoggerFactory;class MxoBotPalette{static PALETTE_LOAD_STATIC=0;static PALETTE_LOAD_DYNAMIC=1;static hexStrToHex(hex_str){return parseInt(hex_str.slice(1),16)}static STATIC_COLORS=[16777215,12895428,8947848,5592405,2236962,0,13880,26112,1799168,4681808,2273612,179713,5366041,9756740,10025880,16514907,15063296,15121932,15045888,16740352,16726276,15007744,13510969,16728426,10420224,7012352,16741727,10512962,6503455,10048269,12275456,16762015,16768972,16754641,13594340,8201933,15468780,8519808,3342455,132963,5308671,234,281599,23457,6652879,3586815,33735,54237,4587464,11921646];static STATIC_INDEX=[0,1,2,3,4,5,39,6,49,40,7,8,9,10,41,11,12,13,14,42,21,20,43,44,19,18,23,15,17,16,22,24,25,26,27,45,28,29,46,31,30,32,33,47,34,35,36,37,38,48];initalizePalette(type){if(type==undefined){type=MxoBotPalette.PALETTE_LOAD_STATIC;MxoBotLogger.warning("MxoBotPalette invoked without specifying the loading type.")}MxoBotLogger.info("MxoBotPalette loading with type: "+(type==MxoBotPalette.PALETTE_LOAD_DYNAMIC?"DYNAMIC":"STATIC"));if(type==MxoBotPalette.PALETTE_LOAD_DYNAMIC){const palette=document.getElementById("palette-buttons");if(!palette){MxoBotLogger.error("Palette requested to be loaded dynamically but HTML is not loaded yet.")}this.colors=[];this.indexes=[];const palette_buttons=Array.from(palette.children);MxoBotLogger.info("Dynamic loading found these DOM elements:");console.log(palette_buttons);for(const palette_button of palette_buttons){const color={hex:palette_button.getAttribute("title"),index:palette_button.getAttribute("data-id")};this.colors.push(MxoBotPalette.hexStrToHex(color.hex));this.indexes.push(parseInt(color.index))}}else{this.colors=MxoBotPalette.STATIC_COLORS;this.indexes=MxoBotPalette.STATIC_INDEX}}getIndex(x){if(x instanceof Array){const[r,g,b]=x;const hex=r<<16|g<<8|b;return this.indexes[this.colors.indexOf(hex)]??-1}else if(typeof x=="number"){return this.indexes[this.colors.indexOf(x)]??-1}else{MxoBotLogger.error("Argument is neither type of Array nor a number")}}constructor(type){this.colors=undefined;this.indexes=undefined;this.initalizePalette(type)}}class MxoBotOriginalWebSocket extends WebSocket{}class MxoBotWS{constructor(mxoBotPalette,webSocket){if(webSocket){this.ws=webSocket;if(mxoBotPalette){this.mxoBotMapCache=new MxoBotMapCache(mxoBotPalette,this.ws);this.mxoBotMapCache.addPixelChangeListener(this)}}else{this.ws=undefined;var proxy=this;this.hook=class extends WebSocket{constructor(a,b){super(a,b);MxoBotLogger.info("MxoBotWS has hooked the game WebSocket connection.");proxy.ws=this;proxy.mxoBotMapCache.addPixelChangeListener(proxy)}};if(typeof unsafeWindow!==undefined){if(unsafeWindow.WebSocket!=MxoBotWS){unsafeWindow.WebSocket=this.hook}}this.mxoBotMapCache=new MxoBotMapCache(mxoBotPalette,this)}}}var map_cache;class MxoBotMapCache{init(mxoBotPalette,mxoBotWS){var canvas_id=parseInt(location.pathname.replace("/","").split("-")[0]);var url=`https://pixelplace.io/canvas/${canvas_id}.png?a=${Math.floor(Math.random()*1e9)+1e9}`;var canvas_image=new Image;var spare_canvas=document.createElement("canvas");this.before_poll=[];this.cache=map_cache;if(this.cache)return;spare_canvas.ctx=spare_canvas.getContext("2d");canvas_image.onload=()=>{MxoBotLogger.info("Map loaded");this.map_width=canvas_image.naturalWidth;this.map_height=canvas_image.naturalHeight;spare_canvas.width=this.map_width;spare_canvas.height=this.map_height;spare_canvas.ctx.drawImage(canvas_image,0,0,this.map_width,this.map_height);var data=spare_canvas.ctx.getImageData(0,0,this.map_width,this.map_height).data;this.cache=new Int8Array(this.map_width*this.map_height);for(let i=0;i<data.length;i+=4){var r=data[i];var g=data[i+1];var b=data[i+2];const i_color=mxoBotPalette.getIndex([r,g,b]);this.cache[i>>2]=i_color}for(let packet of this.before_poll){this.cache[packet[0]]=packet[1]}this.before_poll=undefined};canvas_image.src=url}constructor(mxoBotPalette,mxoBotWS){this.init(mxoBotPalette,mxoBotWS)}getPixel(x,y){var i=y*this.map_width+x;return this.cache[i]}addPixelChangeListener(mxoBotWS){mxoBotWS.ws.addEventListener("message",e=>{var data=e.data;if(!data.startsWith('42["p",')){return}var packets=JSON.parse(data.replace("42",""))[1];for(let packet of packets){var[x,y,color]=packet;var i=this.map_width*y+x;if(this.cache){this.cache[i]=color}else{this.before_poll.push([i,color])}}})}}class MxoBotImagePicker{static requestImageFromFileDialog(MxoBotPalette){return new Promise(resolve=>{const input=document.createElement("input");input.type="file";input.accept="image/*";input.click();input.addEventListener("change",function(){const reader=new FileReader;reader.onload=function(e){MxoBotLogger.info("Image loaded");resolve(new MxoBotImage(e.target.result,MxoBotPalette))};if(input.files&&input.files[0]){reader.readAsDataURL(input.files[0])}})})}static addClipboardListener(MxoBotPalette,callback){document.addEventListener("paste",function(paste_e){var items=(paste_e.clipboardData||paste_e.originalEvent.clipboardData).items;MxoBotLogger.info("Recieved data from clipboard: "+JSON.stringify(items));var blob=null;for(var i=0;i<items.length;i++){if(items[i].type.indexOf("image")===0){blob=items[i].getAsFile()}}if(blob!==null){var reader=new FileReader;reader.onload=function(e){MxoBotLogger.info("Readed image from clipboard!");callback(new MxoBotImage(e.target.result,MxoBotPalette))};reader.readAsDataURL(blob)}})}}function MxoBotWaitForElm(selector){return new Promise(resolve=>{if(document.querySelector(selector)){return resolve(document.querySelector(selector))}const observer=new MutationObserver(mutations=>{if(document.querySelector(selector)){resolve(document.querySelector(selector));observer.disconnect()}});observer.observe(document.body,{childList:true,subtree:true})})}function MxoBotCreateWorker(code){var blob=new Blob([code],{type:"text/javascript"});var url=URL.createObjectURL(blob);var worker=new Worker(url);return worker}class MxoBotImage{constructor(x,palette){this.MxoBotPalette=palette;this.image=undefined;this.image_canvas=document.createElement("canvas");this.image_context=this.image_canvas.getContext("2d");if(x instanceof Image){this.image=x}else if(typeof x=="string"){this.image=new Image;this.image.src=x}if(this.image==undefined){MxoBotLogger.error("Argument is neither type of Image nor a string")}this.image_context.mozImageSmoothingEnabled=false;this.image.onload=()=>{this.image_canvas.width=this.image.width;this.image_canvas.height=this.image.height;this.image_context.drawImage(this.image,0,0);this.image_data=this.image_context.getImageData(0,0,this.image_canvas.width,this.image_canvas.height);MxoBotLogger.info("Dithering loaded image!");this.image_data=MxoBotImageConverter.floydSteinberg(this.image_data,this.image.width,this.image.height,palette)}}convertToTasks(sx,sy,mxoBotWS){if(typeof sx!="number"||typeof sy!="number"){MxoBotLogger.error("Tried to convert an image to tasks yet the starting coordinates are not a number.")}if(!(mxoBotWS instanceof MxoBotWS)){MxoBotLogger.error("MxoBotImage.convertToTasks requires an MxoBotWS in new versions. Please update your code.")}var _tasks=[];for(let i=0;i<this.image_data.data.length;i+=4){var[r,g,b,a]=this.image_data.data.slice(i,i+4);if(a==0){continue}var x=i/4%this.image_data.width;var y=Math.floor(i/4/this.image_data.width);var colorIndex=this.MxoBotPalette.getIndex([r,g,b]);const c_color=mxoBotWS.mxoBotMapCache.getPixel(sx+x,sy+y);if(colorIndex==-1){console.log([r,g,b])}if(c_color==colorIndex||c_color==-1||colorIndex==-1){continue}_tasks.push([sx+x,sy+y,colorIndex])}return _tasks}}class MxoBotEngine{static convertToTask(x,y,colorIndex,packetType){if(packetType==undefined){packetType=1}return`42["p",${JSON.stringify([x,y,colorIndex,packetType])}]`}putPixel(x,y,colorIndex){this.tasks.push([x,y,colorIndex])}putPixelWithPriority(x,y,colorIndex){this.tasks.unshift([x,y,colorIndex])}constructor(MxoBotWS,timeout){if(!MxoBotWS||!timeout){return}this.tasks=[];this.MxoBotWS=MxoBotWS;this.intervalID=setInterval(()=>{const task=this.tasks.shift();if(!task){return}if(this.MxoBotWS.mxoBotMapCache.getPixel(task[0],task[1])==task[2]){return}this.MxoBotWS.ws.send(MxoBotEngine.convertToTask(...task))},timeout)}}class MxoBotEngineMultiBot extends MxoBotEngine{static getAccountDetailsFromCookie(cookie){const dict=cookie.split("; ").map(a=>a.split("=")).reduce(function(b,a){if(!["authKey","authToken","authId"].includes(a[0]))return b;b[a[0]]=a[1];return b},{});return[dict.authId,dict.authToken,dict.authKey]}addAccountFromCookies(authId,authToken,authKey){if(!authId||!authToken||!authKey){MxoBotLogger.warning("Auth informations are not defined. (Maybe not logged in?)");return}const boardId=parseInt(location.pathname.replace("/","").split("-")[0]);const socket=new MxoBotOriginalWebSocket("wss://pixelplace.io/socket.io/?EIO=3&transport=websocket");socket.headless=true;socket.onmessage=({data})=>{const[code,msg]=data.split(/(?<=^\d+)(?=[^\d])/);if(code=="40"){socket.send("42"+JSON.stringify(["init",{authKey:authKey,authToken:authToken,authId:authId,boardId:boardId}]))}const message=JSON.parse(msg||"[]");if(message.pingInterval)socket.ping=setInterval(()=>socket.send("2"),message.pingInterval);if(!message.length)return arguments;const[event,json]=message;if(event=="throw.error"){socket.close();MxoBotLogger.error(json)}};socket.onclose=()=>{MxoBotLogger.info("User Disconnected")};const mxoBotWS=new MxoBotWS(undefined,socket);this.sockets.push(mxoBotWS)}addAccountFromMxoBotWS(mxoBotWS){this.sockets.push(mxoBotWS)}constructor(timeout,mxoBotPalette){super();this.tasks=[];this.sockets=[];this.counter=0;function interval(){if(this.sockets.length==0){setTimeout(interval,100);return}const task=this.tasks.shift();if(!task){setTimeout(interval,timeout/this.sockets.length);return}console.log(this);this.counter=(this.counter+1)%this.sockets.length;this.sockets[this.counter]?.ws?.send(MxoBotEngine.convertToTask(...task));setTimeout(this.interval,timeout/this.sockets.length)}interval=interval.bind(this);interval();this.interval=interval}}class MxoBotProtect{constructor(core){MxoBotLogger.info("MxoBotProtect has been opened.");this.core=core;this.nimage=undefined;this.coordinates=undefined;this.working=false;this.core.mxoBotWS.ws.addEventListener("message",function(e){if(!this.working)return;if(!this.nimage)return;if(!this.coordinates)return;var data=e.data;if(!data.startsWith('42["p",')){return}var packets=JSON.parse(data.replace("42",""))[1];for(let packet of packets){var[x,y,color]=packet;var image_width=this.nimage.image.width;var image_height=this.nimage.image.height;var image_x=this.coordinates[0];var image_y=this.coordinates[1];var image_xmax=image_width+image_x;var image_ymax=image_height+image_y;if(!this.nimage){continue}if(x<image_x||x>=image_xmax||y<image_y||y>=image_ymax){continue}var img_data_index=4*(x-image_x+image_width*(y-image_y));var[r,g,b,a]=this.nimage.image_data.data.slice(img_data_index,img_data_index+4);if(a==0)continue;var image_color_i=this.core.palette.getIndex([r,g,b]);if(image_color_i==undefined){MxoBotLogger.error(JSON.stringify([[r,g,b],image_color_i,img_data_index]))}if(image_color_i!=color){this.core.engine.putPixelWithPriority(x,y,image_color_i)}}}.bind(this))}start(){this.working=true}stop(){this.working=false}load(nimage,coordinates){this.nimage=nimage;this.coordinates=coordinates}}class MxoBotCore{async testAccountValidation(){const req=await fetch("https://pixelplace.io/api/get-painting.php?id=7&connected=1");const json=await req.json();if(json.user.name=="Guest"){MxoBotLogger.warning("User is not logged in!")}else{MxoBotLogger.info("Logged in as "+json.user.name)}}constructor(options){this.testAccountValidation();this.palette=new MxoBotPalette(MxoBotPalette.PALETTE_LOAD_STATIC);this.mxoBotWS=new MxoBotWS(this.palette);if(options.multibot){this.engine=new MxoBotEngineMultiBot(options.timeout);localStorage.mxoBotAccounts=localStorage.mxoBotAccounts||"[]";const mxoBotAccounts=JSON.parse(localStorage.mxoBotAccounts);unsafeWindow.addThisAccount=function(){const session_account=MxoBotEngineMultiBot.getAccountDetailsFromCookie(document.cookie).join("_AND_");if(session_account[0]&&!mxoBotAccounts.includes(session_account)){mxoBotAccounts.push(session_account)}localStorage.mxoBotAccounts=JSON.stringify(mxoBotAccounts)};for(let account of mxoBotAccounts){const[authId,authToken,authKey]=account.split("_AND_");if(!authId||!authToken||!authKey){console.error(account);MxoBotLogger.error("Local account is corrupted")}this.engine.addAccountFromCookies(authId,authToken,authKey)}}else{this.engine=new MxoBotEngine(this.mxoBotWS,options.timeout)}this.picker=MxoBotImagePicker;this.logger=MxoBotLogger}}