MasterBot Client

Bot client with many functions. Good UI and code.

  1. // ==UserScript==
  2. // @name MasterBot Client
  3. // @version 1.2.0
  4. // @license MIT
  5. // @description Bot client with many functions. Good UI and code.
  6. // @author scar17off & bjc
  7. // @released_on 2022.04.06 (6st april 2022)
  8. // =-=-=-=coders & other authors=-=-=-=
  9. // Bot name was suggested by Not Bot (449948380035153920)
  10. // sobakaya helped with UI designing (909443291198664735)
  11. // Desmecito looked for bugs in the code and had early access (924366077155237918)
  12. // Animations was made by Not Bot (449948380035153920)
  13. // @match *://augustberchelmann.com/owop/*
  14. // @match *://ourworldofpixels.com/*
  15. // @match *://ywop.netlify.app/*
  16. // @match *://yourworldofpixels.glitch.me/*
  17. // @match *://ourworldofscripts.glitch.me/*
  18. // @match *://ywoa.glitch.me/*
  19. // @match *://owoppa.glitch.me/*
  20. // @match *://owoppa.netlify.app/*
  21. // @icon https://www.google.com/s2/favicons?domain=ourworldofpixels.com
  22. // @grant none
  23. // @namespace none
  24. // ==/UserScript==
  25.  
  26. (function(){
  27. "use strict";
  28.  
  29. /*OWOP.once(6666667, (() => {*/setTimeout(() => {
  30. // fix
  31. window.history.pushState("object or string", "Title", "/?#main");
  32. if(!OWOP.cursors.paste) OWOP.cursors.paste = OWOP.cursors.stamp;
  33. // jq
  34. () => {
  35. let xhttpt = new XMLHttpRequest();
  36. xhttpt.open("GET", "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js");
  37. xhttpt.responseType = "text";
  38. xhttpt.addEventListener("load", function() {
  39. eval(xhttpt.response);
  40. });
  41. xhttpt.send();
  42. };
  43. // script
  44. let Master = {};
  45.  
  46. function configSys() {
  47. if(document.getElementById("tabbar") && localStorage.MasterClient){
  48. Master = JSON.parse(localStorage.MasterClient);
  49. } else if(!localStorage.MasterClient){
  50. localStorage.MasterClient = JSON.stringify({
  51. BotCount: 1,
  52. ProxyPasswords: "",
  53. BotNickname: "MASTER-BOT",
  54. ReconnectTime: 250,
  55. AutoReconnect: false,
  56. BigChat: false,
  57. UsePlayer: false,
  58. Animation: "Circle",
  59. Animations: {
  60. circle: 0,
  61. disk: 1,
  62. atom: 2,
  63. random: 3,
  64. wave: 4,
  65. line: 5,
  66. hyperbola: 6,
  67. ez: 7,
  68. botline: 8,
  69. x: 9,
  70. spiral: 10,
  71. cool: 11,
  72. disktwo: 12,
  73. topbottom: 13,
  74. laggy: 14,
  75. smallcircle: 15,
  76. eight: 16,
  77. cool2: 17,
  78. tworings: 18,
  79. threed: 19,
  80. flower: 20,
  81. square: 21,
  82. infinity: 22,
  83. infinity2: 23,
  84. default2: 24,
  85. trialge: 25,
  86. disk3: 26,
  87. saturn: 27,
  88. storm: 28,
  89. disk4: 29
  90. },
  91. SmartAutoReconnect: false,
  92. WolfMove: false,
  93. OldMBPaste: false,
  94. NoVignette: false,
  95. ChatColor: "#969696",
  96. EraserPattern: "Default",
  97. AutoNickname: false,
  98. AutoPassword: false,
  99. BotsUpdateRate: 1000,
  100. ConfigUpdateRate: 750,
  101. Follow: false,
  102. PaintFollow: false,
  103. AutoLogin: false,
  104. NoBots: false,
  105. Chat: false,
  106. ChatName: "Anonymous",
  107. AssetPasterPattern: "Default",
  108. AreaPattern: "Default",
  109. Patterns: {
  110. Eraser: ["Default", "TopBottom", "Perfect", "Circle"],
  111. AssetPaster: ["Default", "LeftUp", "Grid", "Square", "Random"],
  112. Area: ["Default", "TopBottom", "Random"]
  113. }
  114. });
  115. Master = JSON.parse(localStorage.MasterClient);
  116. };
  117. if(!document.getElementById("tabbar")) {
  118. clearInterval(configSys);
  119. };
  120. };
  121. function abool(arg1) {
  122. let toret;
  123. if(arg1 == "on") toret = true;
  124. if(arg1 == "off") toret = false;
  125. if(arg1 == "true") toret = true;
  126. if(arg1 == "false") toret = false;
  127. if(arg1 == true) toret = true;
  128. if(arg1 == false) toret = false;
  129. return toret;
  130. };
  131. let chatInput = document.getElementById("chat-input");
  132. chatInput.title = "Press shift to send message to MasterBot users.";
  133. let socket;
  134. let antisleep;
  135. function reconn(){
  136. function sendmsg(toSend){
  137. let contenT = [ window.MasterBot.socket.id, window.MasterBot.socket.name, toSend, window.MasterBot.socket.color ];
  138. socket.send(JSON.stringify({
  139. type: "chat",
  140. content: contenT
  141. }));
  142. return contenT; // dev
  143. };
  144. chatInput.addEventListener("keydown", function(event) {
  145. var key = event.key + event.location;
  146. if(key == "Shift2"){
  147. let options = sendmsg(chatInput.value);
  148. if(socket.readyState === 1 && !chatInput.value.startsWith("/")) {
  149. OWOP.chat.local(`<span title="User ID: ${options[0]} | Player ID: unavailable | Chatting from: unavailable" style="color: ${options[3]}">${options[1]}: ${options[2]}</span>`);
  150. };
  151. chatInput.value = "";
  152. chatInput.style.height = "16px";
  153. event.stopPropagation();
  154. };
  155. });
  156. window.MasterBot = {};
  157. window.MasterBot.socket = new WebSocket("ws://masterbot-chat.glitch.me/", null, {
  158. origin: location.href,
  159. plid: OWOP.player.id
  160. });
  161. socket = window.MasterBot.socket;
  162. socket.addEventListener("open", () => {
  163. socket.name = Master.ChatName;
  164. socket.send(JSON.stringify({
  165. type: "connect",
  166. content: socket.name+" connected."
  167. }));
  168. if(Master.ChatColor.length == 6 || Master.ChatColor.startsWith("#")){
  169. socket.color = Master.ChatColor;
  170. window.MasterBot.socket.color = Master.ChatColor;
  171. };
  172. antisleep = setInterval(() => {
  173. socket.send(JSON.stringify({
  174. type: "antisleep",
  175. content: "this thing needed to make the glitch project work 24/7"
  176. }));
  177. }, 8000);
  178. });
  179. socket.addEventListener("message", ({ data }) => {
  180. let packet = JSON.parse(data);
  181.  
  182. switch(packet.type) {
  183. case "chat":
  184. if(packet.content[0] !== socket.id){
  185. let author = packet.content[1];
  186. let author_id = packet.content[0];
  187. let message = packet.content[2];
  188. let color = packet.content[3];
  189. if(author == "[D] MasterBot Gateway#0317") return;
  190. OWOP.chat.local(`<span style="color: ${color}" title="User ID: ${author_id} | Player ID: unavailable | Chatting from: unavailable">${author}: ${message}</span>`);
  191. };
  192. break;
  193. case "connected":
  194. console.log("Connected! Your id is: "+packet.content[0]);
  195. socket.id = packet.content[0];
  196. if(packet.content[1].startsWith("Anonymous_")) {
  197. if(Master.ChatName == "" || Master.ChatName == " "){
  198. socket.name = packet.content[1];
  199. };
  200. };
  201. break;
  202. case "color_change":
  203. if(Master.ChatColor == "#969696"){
  204. socket.color = packet.content;
  205. window.MasterBot.socket.color = packet.content;
  206. Master.ChatColor = packet.content;
  207. localStorage.MasterClient = JSON.stringify(Master);
  208. } else {
  209. socket.color = Master.ChatColor;
  210. window.MasterBot.socket.color = Master.ChatColor;
  211. localStorage.MasterClient = JSON.stringify(Master);
  212. };
  213. break;
  214. case "users":
  215. let players = [];
  216. for(let i in packet.content){
  217. players.push(packet.content[i].name);
  218. if(players.length >= packet.content.length){
  219. OWOP.chat.local(players.join(", "));
  220. };
  221. };
  222. break;
  223. case "cmd_handling":
  224. OWOP.chat.local(packet.content);
  225. break;
  226. case "name_change":
  227. socket.name = packet.name;
  228. Master.ChatName = packet.name;
  229. localStorage.MasterClient = JSON.stringify(Master);
  230. break;
  231. case "server":
  232. OWOP.chat.local(`<span style="${packet.style}">[Server] </span><span style="${packet.style2 || ""}">${packet.content}</span>`);
  233. break;
  234. };
  235. });
  236. socket.addEventListener("close", () => {
  237. clearInterval(antisleep);
  238. if(Master.Chat && socket.readyState !== 1) reconn();
  239. });
  240. };
  241. var cfgint = setInterval(configSys, Master.ConfigUpdateRate);
  242. let BOTS = [];
  243. let botlist = [];
  244. if(!OWOP.tools) OWOP.tools = OWOP.tool;
  245. var chars = [
  246. [0b1111111, 0b1000001, 0b1010111, 0b1010100, 0b1010111, 0b1000001, 0b1111111] /*A*/ ,
  247. [0b1111111, 0b1000001, 0b1010101, 0b1010101, 0b1010101, 0b1001001, 0b1111111] /*B*/ ,
  248. [0b1111111, 0b1000001, 0b1011101, 0b1010101, 0b1010101, 0b1010101, 0b1110111] /*C*/ ,
  249. [0b1111111, 0b1000001, 0b1011101, 0b1010101, 0b1011101, 0b1100011, 0b0111110] /*D*/ ,
  250. [0b1111111, 0b1000001, 0b1010101, 0b1010101, 0b1010101, 0b1011101, 0b1110111] /*E*/ ,
  251. [0b1111111, 0b1000001, 0b1010111, 0b1010100, 0b1010100, 0b1011100, 0b1110000] /*F*/ ,
  252. [0b1111111, 0b1000001, 0b1011101, 0b1010101, 0b1010101, 0b1010001, 0b1111111] /*G*/ ,
  253. [0b1111111, 0b1000001, 0b1110111, 0b0010100, 0b1110111, 0b1000001, 0b1111111] /*H*/ ,
  254. [0b1111111, 0b1000001, 0b1111111] /*I*/ ,
  255. [0b1111111, 0b1010001, 0b1011101, 0b1010101, 0b1011101, 0b1000001, 0b1111111] /*J*/ ,
  256. [0b1111111, 0b1000001, 0b1110111, 0b0110110, 0b1101011, 0b1011101, 0b1110111] /*K*/ ,
  257. [0b1111111, 0b1000001, 0b1111101, 0b0000101, 0b0000101, 0b0000101, 0b0000111] /*L*/ ,
  258. [0b1111111, 0b1000001, 0b1011111, 0b1000001, 0b1011111, 0b1000001, 0b1111111] /*M*/ ,
  259. [0b1111111, 0b1000001, 0b1011111, 0b1000001, 0b1111101, 0b1000001, 0b1111111] /*N*/ ,
  260. [0b1111111, 0b1000001, 0b1011101, 0b1010101, 0b1011101, 0b1000001, 0b1111111] /*O*/ ,
  261. [0b1111111, 0b1000001, 0b1010111, 0b1010100, 0b1010100, 0b1000100, 0b1111100] /*P*/ ,
  262. [0b1111111, 0b1000001, 0b1011101, 0b1010101, 0b1011101, 0b1000011, 0b1111111] /*Q*/ ,
  263. [0b1111111, 0b1000001, 0b1010111, 0b1010100, 0b1010111, 0b1001001, 0b1111111] /*R*/ ,
  264. [0b1111111, 0b1000101, 0b1010101, 0b1010101, 0b1010101, 0b1010001, 0b1111111] /*S*/ ,
  265. [0b1110000, 0b1010000, 0b1011111, 0b1000001, 0b1011111, 0b1010000, 0b1110000] /*T*/ ,
  266. [0b1111111, 0b1000001, 0b1111101, 0b0000101, 0b1111101, 0b1000001, 0b1111111] /*U*/ ,
  267. [0b1111100, 0b1000110, 0b1111011, 0b0001101, 0b1111011, 0b1000110, 0b1111100] /*V*/ ,
  268. [0b1111110, 0b1000011, 0b1111101, 0b0100011, 0b1111101, 0b1000011, 0b1111110] /*W*/ ,
  269. [0b1110111, 0b1011101, 0b1101011, 0b0110110, 0b1101011, 0b1011101, 0b1110111] /*X*/ ,
  270. [0b1111000, 0b1001100, 0b1110111, 0b0011001, 0b1110111, 0b1001100, 0b1111000] /*Y*/ ,
  271. [0b1111111, 0b1010001, 0b1010101, 0b1010101, 0b1010101, 0b1000101, 0b1111111] /*Z*/ ,
  272. ];
  273. var NUMS = [
  274. [0b11111, 0b10001, 0b11111] /*0*/ ,
  275. [0b01000, 0b11111] /*1*/ ,
  276. [0b10111, 0b10101, 0b11101] /*2*/ ,
  277. [0b10101, 0b10101, 0b11111] /*3*/ ,
  278. [0b11100, 0b00100, 0b11111] /*4*/ ,
  279. [0b11101, 0b10101, 0b10111] /*5*/ ,
  280. [0b11111, 0b10101, 0b10111] /*6*/ ,
  281. [0b10000, 0b10000, 0b11111] /*7*/ ,
  282. [0b11111, 0b10101, 0b11111] /*8*/ ,
  283. [0b11101, 0b10101, 0b11111] /*9*/
  284. ];
  285. var symbols = {
  286. "33": [0b11101] /*!*/ ,
  287. "34": [0b11000, 0b00000, 0b11000] /*"*/ ,
  288. "35": [0b01010, 0b11111, 0b01010, 0b11111, 0b01010] /*#*/ ,
  289. "39": [0b11000] /*'*/ ,
  290. "40": [0b01110, 0b10001] /*(*/ ,
  291. "41": [0b10001, 0b01110] /*)*/ ,
  292. "43": [0b00100, 0b01110, 0b00100] /*+*/ ,
  293. "45": [0b00100, 0b00100, 0b00100] /*-*/ ,
  294. "46": [0b00001] /*.*/ ,
  295. "47": [0b00001, 0b00110, 0b11000] /*/*/ ,
  296. "58": [0b01010] /*:*/ ,
  297. "61": [0b01010, 0b01010, 0b01010] /*=*/ ,
  298. "63": [0b10101, 0b01000] /*?*/ ,
  299. "91": [0b11111, 0b10001] /*[*/ ,
  300. "93": [0b10001, 0b11111] /*]*/
  301. };
  302. function infinityX(t) {
  303. let x = (Math.cos(t*2)-1)/2;
  304. if(Math.abs(t*2) % (4*Math.PI) > 2*Math.PI) return -x;
  305. else return x;
  306. };
  307. function infinityY(t) {
  308. return Math.sin(t*2) / 2;
  309. };
  310. function squareX(angle) {
  311. let x = Math.sin(angle), y = Math.cos(angle);
  312. return x / Math.max(Math.abs(x), Math.abs(y));
  313. };
  314. function squareY(angle) {
  315. let x = Math.sin(angle), y = Math.cos(angle);
  316. return y / Math.max(Math.abs(x), Math.abs(y));
  317. };
  318. function pixColor(img, X, Y, RGB) {
  319. var abab = img.getImageData(X, Y, 1, 1).data
  320. return [abab[0], abab[1], abab[2]]
  321. };
  322. function getRandomInt2(max) {
  323. return Math.floor(Math.random() * max);
  324. };
  325. function dist(x, y) {
  326. return Math.sqrt(x * x + y * y);
  327. };
  328. function append(src, onload) {
  329. var s = document.createElement('script');
  330. s.src = src;
  331. s.onload = onload;
  332. document.body.appendChild(s);
  333. };
  334. const proxyJoin = server => {
  335. let ws = "wss://ws-proxy" + server + ".glitch.me";
  336. let BotCount = parseFloat(document.getElementById("master-main-content-botcount").value);
  337. for (let i = 0; i < BotCount; i++) {
  338. let bot = new OJS.Client({
  339. ws: ws + `?ws=${OWOP.options.serverAddress[0].url}`,
  340. origin: location.href.split("?#")[0],
  341. index: BOTS.length + 1,
  342. proxy: server,
  343. reconnect: Master.AutoReconnect || false,
  344. world: location.href.split("#")[1],
  345. reconnectTime: Master.ReconnectTime || 250,
  346. nolog: true
  347. });
  348. bot.net.ws.onmessage = msg => {
  349. if (msg.data.toString().startsWith('You are banned.')) {
  350. document.getElementById(`master-proxy-proxystatus-${server}`).innerText = "🔨";
  351. document.getElementById(`master-proxy-proxystatus-${server}`).title = msg.data.toString();
  352. //document.getElementById(`proxy-${server}`).style.cssText = "display:none";
  353. };
  354. };
  355. bot.on("join", () => {
  356. BOTS.push(bot);
  357. if(!Master.NoBots){
  358. let device;
  359. if(bot.clientOptions.proxy) {device = "📡";} else {device = '🖥️';};
  360. let color = rgbtohex(bot.player.color[0], bot.player.color[1], bot.player.color[2]);
  361. let bottable = document.createElement("tr");
  362. bottable.innerHTML = `<td id="master-bots-content-list-bot-${bot.player.id}-index">${bot.clientOptions.index}</td><td id="master-bots-content-list-bot-${bot.player.id}-id">`+bot.player.id+`</td><td id="master-bots-content-list-bot-${bot.player.id}-x">`+bot.player.x+`</td><td id="master-bots-content-list-bot-${bot.player.id}-y">`+bot.player.y+`</td><td id="master-bots-content-list-bot-${bot.player.id}-pq">`+bot.net.bucket.allowance+`</td><td id="master-bots-content-list-bot-${bot.player.id}-color" style="font-size: 20px;color: ${color}" title="${color} | R: ${bot.player.color[0]} G: ${bot.player.color[1]} B: ${bot.player.color[2]}">■</td><td id="master-bots-content-list-bot-${bot.player.id}-device" title="${bot.clientOptions.proxy || ""}">`+device+'</td>'+`<button id="master-bots-content-list-bot-${bot.player.id}-leave">Leave</button>`+'';
  363. bottable.id = `master-bots-content-list-bot-${bot.player.id}`;
  364. for(let i = 0; i < BOTS.length; i++){
  365. if(BOTS[i].player.id === bot.player.id) {
  366. document.getElementById("master-bots-content-list").appendChild(bottable);
  367. document.getElementById(`master-bots-content-list-bot-${bot.player.id}-leave`).addEventListener("click", () => {
  368. bot.net.ws.close();
  369. document.getElementById(`master-bots-content-list-bot-${bot.player.id}`).style.display = "none";;
  370. for(let i = 0; i < BOTS.length; i++){
  371. if(BOTS[i].player.id === bot.player.id) {
  372. BOTS.splice(i, 1);
  373. };
  374. };
  375. });
  376. };
  377. };
  378. };
  379. if(bot.clientOptions.proxy) document.getElementById(`master-proxy-content-proxyconns-${bot.options.proxy}`).innerText = parseInt(document.getElementById(`master-proxy-content-proxyconns-${bot.options.proxy}`).innerText) + 1;
  380. if(Master.AutoLogin == true){
  381. if(localStorage.adminlogin) {
  382. let cmd = "adminlogin";
  383. if(location.host = "ourworldofpixels.com") cmd = "pass";
  384. bot.chat.send(`/${cmd} ${localStorage.adminlogin}`);
  385. };
  386. };
  387. if(Master.AutoPassword == true) {
  388. if(AutoPassword && JSON.parse(localStorage.worldPasswords)[location.href.split("?#")[0]]) bot.chat.send(`/pass ${JSON.parse(localStorage.worldPasswords)[location.href.split("?#")[0]]}`);
  389. };
  390. if(Master.AutoNickname == true) {
  391. bot.chat.send(`/nickname ${Master.BotNickname}`);
  392. };
  393. });
  394.  
  395. bot.on("close", () => {
  396. for(let i = 0; i < BOTS.length; i++){
  397. if(BOTS[i].player.id === bot.player.id) {
  398. clearInterval(BOTS[i].interval);
  399. BOTS.splice(i, 1);
  400. };
  401. };
  402. if(Master.AutoReconnect == false && Master.SmartAutoReconnect == true) {
  403. bot.world.join(location.href.split("?#")[1]);
  404. };
  405. });
  406. };
  407. };
  408. let last = 0;
  409. const getFree = () => {
  410. let b = BOTS.filter(i => i.net.ws.readyState === 1);
  411. if(b.length === 0) return -1;
  412. if(last >= b.length) last = 0;
  413. return last++;
  414. };
  415. let botslen = 7;
  416. async function writeChar(matrix, x, y) {
  417. for (var xx = 0; xx < matrix.length; xx++)
  418. for (var yy = 0; yy < 8; yy += slen)
  419. for (var bb = 0; bb < slen; bb++)
  420. if((matrix[xx] >> (7 - yy - bb)) & 1 && yy + bb < 8) {
  421. const abc = getFree();
  422. BOTS[abc].world.setPixel(x + xx, y + yy + bb, OWOP.player.selectedColor, false);
  423. };
  424. };
  425. const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
  426. async function writeText(str, x, y) {
  427. if(isNaN(x) || isNaN(y)) return OWOP.chat.local('Invalid Coordinates')
  428. str = str.toUpperCase();
  429. var len = str.length,
  430. ccode, matrix;
  431. for (var i = 0; i < len; i++) {
  432. ccode = str.charCodeAt(i);
  433. if(ccode >= 0x41 && ccode <= 0x5a)
  434. matrix = chars[ccode - 65];
  435. else if(ccode == 0x20) {
  436. x += 2;
  437. continue;
  438. } else if(ccode >= 0x30 && ccode <= 0x39)
  439. matrix = NUMS[ccode - 0x30];
  440. else if(symbols[ccode])
  441. matrix = symbols[ccode];
  442. else {
  443. continue;
  444. }
  445. writeChar(matrix, x, y);
  446. x += matrix.length + 1;
  447. }
  448. };
  449. function loadScript(url) {
  450. let xhttpt = new XMLHttpRequest();
  451. xhttpt.open("GET", url);
  452. xhttpt.responseType = "text";
  453. xhttpt.addEventListener("load", function() {
  454. eval(xhttpt.response);
  455. });
  456. xhttpt.send();
  457. };
  458. const error = m => console.error("%c " + m, "color: #ff0000");
  459. /*
  460. Events:
  461. name - description [arguments].
  462. open - Opened WebSocket connection.
  463. close - Closed WebSocket connection.
  464. join - Joined to world [world name].
  465. id - Got id [id].
  466. rawMessage - Any message from WebSocket server. (It can be object or string) [data].
  467. update - Player in world updates [player object].
  468. pixel - New pixel in world [x, y, [r, g, b]].
  469. disconnect - Someone in world disconnected [player object].
  470. teleport - got 'teleport' opcode. Very rare. [x, y].
  471. rank - Got new rank. [rank].
  472. captcha - Captcha state. [gcaptcha id].
  473. chunkProtect - Chunk (un)protected. [x, y, newState].
  474. pquota - New PQuota. [rate, per].
  475. destroy - Socket was destroyed and won't reconnect anymore.
  476. chunk - New chunk. [x, y, chunk, protected].
  477. message - New message in chat. [msg].
  478. */
  479. class ChunkSystem {
  480. constructor() {
  481. this.chunks = [];
  482. this.chunkProtected = [];
  483. };
  484. setChunk(x, y, data) {
  485. if(!data || typeof x !== "number" || typeof y !== "number") return error("ChunkSystem.setChunk: failed to set chunk (no data or invalid coords).");
  486. if(data.constructor.name !== "Array") data = Array.from(data);
  487. if(!this.chunks[x]) this.chunks[x] = [];
  488. return this.chunks[x][y] = data;
  489. };
  490. getChunk(x, y, raw) {
  491. if(!raw) {
  492. x = Math.floor(x / Client.options.chunkSize);
  493. y = Math.floor(y / Client.options.chunkSize);
  494. };
  495. if(!this.chunks[x]) return;
  496. return this.chunks[x][y];
  497. };
  498. removeChunk(x, y) {
  499. if(!this.chunks[x]) return;
  500. if(!this.chunks[x][y]) return;
  501. return this.chunks[x].splice(y, 1);
  502. };
  503. setPixel(x, y, rgb) {
  504. if(!rgb || typeof rgb !== "object" || typeof x !== "number" || typeof y !== "number") return error("ChunkSystem.setPixel: failed to set pixel (no/wrong rgb or invalid coords).");
  505. const chunkX = Math.floor(x / Client.options.chunkSize);
  506. const chunkY = Math.floor(y / Client.options.chunkSize);
  507. if(!this.chunks[chunkX]) return;
  508. const chunk = this.chunks[chunkX][chunkY];
  509. if(!chunk) return false;
  510. const getIbyXY = (x, y, w) => (y * w + x) * 3;
  511. const i = getIbyXY(x & Client.options.chunkSize - 1, y & Client.options.chunkSize - 1, Client.options.chunkSize);
  512. chunk[i] = rgb[0];
  513. chunk[i + 1] = rgb[1];
  514. chunk[i + 2] = rgb[2];
  515. return true;
  516. };
  517. getPixel(x, y) {
  518. if(typeof x !== "number" || typeof y !== "number") return error("ChunkSystem.getPixel: failed to get pixel (invalid coords).");
  519. const chunkX = Math.floor(x / Client.options.chunkSize);
  520. const chunkY = Math.floor(y / Client.options.chunkSize);
  521. if(!this.chunks[chunkX]) return;
  522. const chunk = this.chunks[chunkX][chunkY];
  523. const getIbyXY = (x, y, w) => (y * w + x) * 3;
  524. const i = getIbyXY(x & Client.options.chunkSize - 1, y & Client.options.chunkSize - 1, Client.options.chunkSize);
  525. return [chunk[i], chunk[i + 1], chunk[i + 2]];
  526. };
  527. protectChunk(x, y) {
  528. if(typeof x !== "number" || typeof y !== "number") return error("ChunkSystem.protectChunk: failed to protect chunk (invalid coords).");
  529. if(!this.chunkProtected[x]) this.chunkProtected[x] = [];
  530. return this.chunkProtected[x][y] = true;
  531. }
  532. unProtectChunk(x, y) {
  533. if(typeof x !== "number" || typeof y !== "number") return error("ChunkSystem.unprotectChunk: failed to unprotect chunk (invalid coords).");
  534. if(!this.chunkProtected[x]) return false;
  535. this.chunkProtected[x][y] = false;
  536. return true;
  537. }
  538. isProtected(x, y) {
  539. if(typeof x !== "number" || typeof y !== "number") return error("ChunkSystem.isProtected: failed to check (invalid coords).");
  540. if(!this.chunkProtected[x]) return false;
  541. return Boolean(this.chunkProtected[x][y]);
  542. }
  543. };
  544. const Chunks = new ChunkSystem();
  545. class Client {
  546. /**
  547. * @param {Object} options Options for connection
  548. * @param {string} [options.ws=wss://ourworldofpixels.com] Websocket server address. ✔️
  549. * @param {?number} options.id ID for logging. If not set, OWOP ID will be used. ✔️
  550. * @param {string} [options.world=main] World name. ✔️
  551. * @param {?boolean} options.noLog No logging. ✔️
  552. * @param {?boolean} options.reconnect Reconnect if disconnected. ✔️
  553. * @param {?string} options.adminlogin Admin login. ✔️
  554. * @param {?string} options.modlogin Mod login. ✔️
  555. * @param {?string} options.pass Pass for world. ✔️
  556. * @param {?string} options.captchapass Captcha pass. ✔️
  557. * @param {?string} options.teleport Teleport on 'teleport' opcode. ✔️
  558. * @param {number} [options.reconnectTime=5000] Reconnect time (ms) after disconnect. ✔️
  559. * @param {?boolean} options.unsafe Use methods that are supposed to be only for admin or moderator. ✔️
  560. * @param {?boolean} options.simpleChunks Use original OWOP chunks instead of OJS. ✔️
  561. */
  562. constructor(options = {}) {
  563. if(!options.ws) options.ws = OWOP.options.serverAddress[0].url;
  564. if(!options.world) options.world = "main";
  565. if(!options.reconnectTime) options.reconnectTime = 2500;
  566. const OJS = this;
  567. this.clientOptions = options;
  568. this.RANK = {
  569. ADMIN: 3,
  570. MODERATOR: 2,
  571. USER: 1,
  572. NONE: 0
  573. };
  574. this.options = {
  575. chunkSize: 16,
  576. maxChatBuffer: 256,
  577. maxMessageLength: {
  578. 0: 128,
  579. 1: 128,
  580. 2: 512,
  581. 3: 16384
  582. },
  583. maxWorldNameLength: 24,
  584. worldBorder: 0xFFFFFF,
  585. opcode: {
  586. setId: 0,
  587. worldUpdate: 1,
  588. chunkLoad: 2,
  589. teleport: 3,
  590. setRank: 4,
  591. captcha: 5,
  592. setPQuota: 6,
  593. chunkProtected: 7
  594. },
  595. captchaState: {
  596. CA_WAITING: 0,
  597. CA_VERIFYING: 1,
  598. CA_VERIFIED: 2,
  599. CA_OK: 3,
  600. CA_INVALID: 4
  601. },
  602. captchaStateNames: {
  603. 0: "WAITING",
  604. 1: "VERIFYING",
  605. 2: "VERIFIED",
  606. 3: "OK",
  607. 4: "INVALID"
  608. }
  609. };
  610. if(window.document === undefined) {
  611. this.options.misc = {
  612. chatVerification: String.fromCharCode(10),
  613. tokenVerification: "CaptchA",
  614. worldVerification: 25565
  615. };
  616. } else this.options.misc = {
  617. chatVerification: OWOP.options.serverAddress[0].proto.misc.chatVerification,
  618. tokenVerification: OWOP.options.serverAddress[0].proto.misc.tokenVerification,
  619. worldVerification: OWOP.options.serverAddress[0].proto.misc.worldVerification
  620. };
  621. OJS.chat = {
  622. send(msg) {
  623. if(typeof OJS.player.rank !== "number") return false;
  624. msg = OJS.chat.sendModifier(msg);
  625. OJS.net.ws.send(msg.substr(0, OJS.options.maxMessageLength[OJS.player.rank]) + OJS.options.misc.chatVerification);
  626. return true;
  627. },
  628. local(msg) {
  629. OJS.util.log(msg)
  630. },
  631. sendModifier(msg) {
  632. return msg
  633. },
  634. recvModifier(msg) {
  635. return msg
  636. },
  637. messages: []
  638. };
  639. OJS.world = {
  640. join(world = "main") {
  641. if(OJS.net.ws.readyState !== 1 || !OJS.net.isWebsocketConnected) return false;
  642. let ints = [];
  643. world = world.toLowerCase();
  644. for (let i = 0; i < world.length && i < 24; i++) {
  645. let charCode = world.charCodeAt(i);
  646. if((charCode < 123 && charCode > 96) || (charCode < 58 && charCode > 47) || charCode === 95 || charCode === 46)
  647. ints.push(charCode);
  648. }
  649. let array = new ArrayBuffer(ints.length + 2);
  650. let dv = new DataView(array);
  651. for (let i = ints.length; i--;) dv.setUint8(i, ints[i]);
  652. dv.setUint16(ints.length, OJS.options.misc.worldVerification, true);
  653. OJS.net.ws.send(array);
  654. OJS.util.log(`Joining world: ${world}`);
  655. OJS.world.name = world;
  656. return true;
  657. },
  658. leave() {
  659. OJS.net.isWorldConnected = false;
  660. OJS.net.isWebsocketConnected = false;
  661. OJS.net.ws.close();
  662. },
  663. destroy() {
  664. OJS.net.isWorldConnected = false;
  665. OJS.net.isWebsocketConnected = false;
  666. OJS.net.destroyed = true;
  667. OJS.net.ws.close();
  668. OJS.emit("destroy");
  669. },
  670. move(x = 0, y = 0) {
  671. if(OJS.net.ws.readyState !== 1 || !OJS.net.isWebsocketConnected) return false;
  672. OJS.player.x = x;
  673. OJS.player.y = y;
  674. let x2 = x*16;
  675. let y2 = y*16;
  676. const dv = new DataView(new ArrayBuffer(12));
  677. OJS.player.worldX = x2;
  678. OJS.player.worldY = y2;
  679. dv.setInt32(0, x2, true);
  680. dv.setInt32(4, y2, true);
  681. dv.setUint8(8, OWOP.player.selectedColor[0]);
  682. dv.setUint8(9, OWOP.player.selectedColor[1]);
  683. dv.setUint8(10, OWOP.player.selectedColor[2]);
  684. dv.setUint8(11, OJS.player.tool);
  685. OJS.net.ws.send(dv.buffer);
  686. if(Master.PaintFollow) OJS.world.setPixel(x, y, OWOP.player.selectedColor);
  687. if(!Master.NoBots){
  688. if(document.getElementById(`master-bots-content-list-bot-${OJS.player.id}`) && document.getElementById(`master-bots-content-list-bot-${OJS.player.id}-x`) !== Math.round(OJS.player.x).toString() || document.getElementById(`master-bots-content-list-bot-${OJS.player.id}-y`) !== Math.round(OJS.player.y).toString() && OJS.net.ws.readyState === 1) {
  689. setTimeout(() => {
  690. document.getElementById(`master-bots-content-list-bot-${OJS.player.id}-x`).innerText = Math.round(OJS.player.x).toString();
  691. document.getElementById(`master-bots-content-list-bot-${OJS.player.id}-y`).innerText = Math.round(OJS.player.y).toString();
  692. }, parseInt(Master.BotsUpdateRate));
  693. };
  694. };
  695. return true;
  696. },
  697. setPixel(x = OJS.player.x, y = OJS.player.y, color = OJS.player.color, move = true) {
  698. if(OJS.net.ws.readyState !== 1 || !OJS.net.isWebsocketConnected || OJS.player.rank === OJS.RANK.NONE) return false;
  699. if(!OJS.net.bucket.canSpend(1)) return false;
  700. const lX = OJS.player.x,
  701. lY = OJS.player.y;
  702. if(move) OJS.world.move(x, y);
  703. const dv = new DataView(new ArrayBuffer(11));
  704. dv.setInt32(0, x, true);
  705. dv.setInt32(4, y, true);
  706. dv.setUint8(8, color[0]);
  707. dv.setUint8(9, color[1]);
  708. dv.setUint8(10, color[2]);
  709. OJS.player.color = color;
  710. OJS.net.ws.send(dv.buffer);
  711. if(Master.WolfMove == true) OJS.world.move(lX, lY);
  712. return true;
  713. },
  714. setTool(id = 0) {
  715. if(OJS.net.ws.readyState !== 1 || !OJS.net.isWebsocketConnected) return false;
  716. OJS.player.tool = id;
  717. const dv = new DataView(new ArrayBuffer(12));
  718. dv.setInt32(0, OJS.player.worldX, true);
  719. dv.setInt32(4, OJS.player.worldY, true);
  720. dv.setUint8(8, OJS.player.color[0]);
  721. dv.setUint8(9, OJS.player.color[1]);
  722. dv.setUint8(10, OJS.player.color[2]);
  723. dv.setUint8(11, id);
  724. OJS.net.ws.send(dv.buffer);
  725. return true;
  726. },
  727. setColor(color = [0, 0, 0]) {
  728. if(OJS.net.ws.readyState !== 1 || !OJS.net.isWebsocketConnected) return false;
  729. OJS.player.color = color;
  730. const dv = new DataView(new ArrayBuffer(12));
  731. dv.setInt32(0, OJS.player.worldX, true);
  732. dv.setInt32(4, OJS.player.worldY, true);
  733. dv.setUint8(8, OJS.player.color[0]);
  734. dv.setUint8(9, OJS.player.color[1]);
  735. dv.setUint8(10, OJS.player.color[2]);
  736. dv.setUint8(11, OJS.player.tool);
  737. OJS.net.ws.send(dv.buffer);
  738. return true;
  739. },
  740. protectChunk(x = OJS.player.x, y = OJS.player.y, newState = 1) {
  741. if(OJS.net.ws.readyState !== 1 || !OJS.net.isWebsocketConnected) return false;
  742. if(OJS.player.rank < OJS.RANK.ADMIN && !options.unsafe) return false;
  743. const dv = new DataView(new ArrayBuffer(10));
  744. dv.setInt32(0, x, true);
  745. dv.setInt32(4, y, true);
  746. dv.setUint8(8, newState);
  747. OJS.net.ws.send(dv.buffer);
  748. return true;
  749. },
  750. clearChunk(x = OJS.player.x, y = OJS.player.y, rgb = OJS.player.color) {
  751. if(OJS.player.rank === OJS.RANK.ADMIN || options.unsafe) {
  752. const dv = new DataView(new ArrayBuffer(13));
  753. dv.setInt32(0, x, true);
  754. dv.setInt32(4, y, true);
  755. dv.setUint8(8, rgb[0]);
  756. dv.setUint8(9, rgb[1]);
  757. dv.setUint8(10, rgb[2]);
  758. OJS.net.ws.send(dv.buffer);
  759. return true;
  760. }
  761. return false;
  762. },
  763. requestChunk(x, y, inaccurate) {
  764. if(options.simpleChunks) return true;
  765. if(OJS.net.ws.readyState !== 1 || !OJS.net.isWebsocketConnected) return false;
  766. if(typeof x !== "number" && typeof y !== "number") {
  767. x = OJS.player.x;
  768. y = OJS.player.y;
  769. inaccurate = true;
  770. };
  771. if(inaccurate) {
  772. x = Math.floor(x / OJS.options.chunkSize);
  773. y = Math.floor(y / OJS.options.chunkSize);
  774. };
  775. let wb = OJS.options.worldBorder;
  776. if(x > wb || y > wb || x < ~wb || y < ~wb) return;
  777. let dv = new DataView(new ArrayBuffer(8));
  778. dv.setInt32(0, x, true);
  779. dv.setInt32(4, y, true);
  780. OJS.net.ws.send(dv.buffer);
  781. return true;
  782. },
  783. getPixel(x = OJS.player.x, y = OJS.player.y) {
  784. if(options.simpleChunks) return OWOP.world.getPixel(x, y);
  785. // It'll return undefined on unknown chunk but it'll request it, so you'll need to getPixel(x, y) again. I suggest you requesting chunks manually and getting them from ChunkSystem.
  786. if(!Chunks.getChunk(x, y)) OJS.world.requestChunk(x, y, true);
  787. return Chunks.getPixel(x, y);
  788. }
  789. };
  790. OJS.player = {
  791. x: 0,
  792. y: 0,
  793. worldX: 0,
  794. worldY: 0,
  795. tool: 0,
  796. rank: null,
  797. id: null,
  798. color: [0, 0, 0]
  799. };
  800. OJS.players = {};
  801. OJS.net = {
  802. isWebsocketConnected: false,
  803. isWorldConnected: false,
  804. destroyed: false,
  805. bucket: new Bucket(32, 4),
  806. async dataHandler(data) {
  807. if(typeof data !== "object") return error("Client.net.dataHandler: data is not object.");
  808. const realData = data;
  809. data = new DataView(data);
  810. const opcode = data.getUint8(0);
  811. switch (opcode) {
  812. case OJS.options.opcode.setId:
  813. {
  814. OJS.emit("id", data.getUint32(1, true));
  815. OJS.player.id = data.getUint32(1, true);
  816. OJS.net.isWorldConnected = true;
  817. if(typeof OJS.player.rank !== "number") OJS.player.rank = OJS.RANK.NONE;
  818. OJS.util.log(`Joined world '${OJS.world.name}' and got id '${data.getUint32(1, true)}'`, "color: #00ff00");
  819. if(options.adminlogin) OJS.chat.send("/adminlogin " + options.adminlogin);
  820. if(options.modlogin) OJS.chat.send("/modlogin " + options.modlogin); // Not working at the moment
  821. if(options.pass) OJS.chat.send("/pass " + options.pass);
  822. OJS.emit("join", OJS.world.name);
  823. break;
  824. }
  825. case OJS.options.opcode.worldUpdate:
  826. {
  827. // Players
  828. let updated = false;
  829. let updates = {};
  830. for (let i = data.getUint8(1); i--;) {
  831. updated = true;
  832. let pid = data.getUint32(2 + i * 16, true);
  833. if(pid === OJS.player.id) continue;
  834. let pmx = data.getUint32(2 + i * 16 + 4, true);
  835. let pmy = data.getUint32(2 + i * 16 + 8, true);
  836. let pr = data.getUint8(2 + i * 16 + 12);
  837. let pg = data.getUint8(2 + i * 16 + 13);
  838. let pb = data.getUint8(2 + i * 16 + 14);
  839. let ptool = data.getUint8(2 + i * 16 + 15);
  840. updates[pid] = {
  841. x: pmx,
  842. y: pmy,
  843. rgb: [pr, pg, pb],
  844. tool: ptool
  845. };
  846. }
  847. if(updated) {
  848. for (let i in updates) {
  849. if(!OJS.players[i]) OJS.emit("connect", i);
  850. OJS.players[i] = {
  851. id: i,
  852. x: updates[i].x >> 4,
  853. y: updates[i].y >> 4,
  854. rgb: updates[i].rgb,
  855. tool: updates[i].tool
  856. };
  857. OJS.emit("update", OJS.players[i]);
  858. }
  859. };
  860. // Pixels
  861. let off = 2 + data.getUint8(1) * 16;
  862. for (let i = data.getUint16(off, true), j = 0; j < i; j++) {
  863. let
  864. x = data.getInt32(2 + off + j * 11),
  865. y = data.getInt32(2 + off + j * 11 + 4);
  866. let r = data.getUint8(2 + off + j * 11 + 8),
  867. g = data.getUint8(2 + off + j * 11 + 9),
  868. b = data.getUint8(2 + off + j * 11 + 10);
  869. OJS.emit('pixel', x, y, [r, g, b]);
  870. Chunks.setPixel(x, y, [r, g, b]);
  871. }
  872. // Disconnects
  873. //off += data.getUint16(off, true) * 15 + 2;
  874. //for (let k = data.getUint8(off); k--;) {
  875. // let dpid = data.getUint32(1 + off + k * 4, true);
  876. // if(OJS.players[dpid]) {
  877. // OJS.emit("disconnect", OJS.players[dpid]);
  878. // delete OJS.players[dpid];
  879. // }
  880. //}
  881. //break;
  882. // disconnects event no needed lol
  883. }
  884. case OJS.options.opcode.chunkLoad:
  885. {
  886. let chunkX = data.getInt32(1, true);
  887. let chunkY = data.getInt32(5, true);
  888. let locked = !!data.getUint8(9);
  889. let u8data = new Uint8Array(realData, 10, realData.byteLength - 10);
  890. let decompressed = OJS.util.decompress(u8data)
  891. Chunks.setChunk(chunkX, chunkY, decompressed);
  892. if(locked) Chunks.protectChunk(chunkX, chunkY);
  893. OJS.emit('chunk', chunkX, chunkY, decompressed, locked);
  894. break;
  895. }
  896. case OJS.options.opcode.teleport:
  897. {
  898. if(!options.teleport) break;
  899. const x = data.getInt32(1, true);
  900. const y = data.getInt32(5, true);
  901. OJS.world.move(x, y);
  902. OJS.emit("teleport", x, y);
  903. break;
  904. }
  905. case OJS.options.opcode.setRank:
  906. {
  907. OJS.player.rank = data.getUint8(1);
  908. OJS.emit("rank", data.getUint8(1));
  909. break;
  910. }
  911. case OJS.options.opcode.captcha:
  912. {
  913. switch (data.getUint8(1)) {
  914. case OJS.options.captchaState.CA_WAITING:
  915. OJS.util.log("CaptchaState: WAITING (0)", "color: #ffff00");
  916. if(options.captchapass) {
  917. OJS.net.ws.send(OJS.options.misc.tokenVerification + "LETMEINPLZ" + options.captchapass);
  918. OJS.util.log("Used captchapass.", "color: #00ff00");
  919. } else if(options.renderCaptcha) this.net.ws.send(OWOP.options.serverAddress[0].proto.misc.tokenVerification + (await renderCaptcha()));
  920. break;
  921. case OJS.options.captchaState.CA_VERIFYING:
  922. OJS.util.log("CaptchaState: VERIFYING (1)", "color: #ffff00");
  923. break;
  924. case OJS.options.captchaState.CA_VERIFIED:
  925. OJS.util.log("CaptchaState: VERIFIED (2)", "color: #00ff00");
  926. break;
  927. case OJS.options.captchaState.CA_OK:
  928. OJS.util.log("CaptchaState: OK (3)", "color: #00ff00");
  929. OJS.world.join(options.world);
  930. break;
  931. case OJS.options.captchaState.CA_INVALID:
  932. OJS.util.log("CaptchaState: INVALID (4)", "color: #ff0000");
  933. OJS.util.log("Captcha failed. Websocket is invalid now.", "color: #ff0000");
  934. OJS.net.destroyed = true;
  935. OJS.net.isWorldConnected = false;
  936. OJS.net.isWebsocketConnected = false;
  937. OJS.emit("destroy");
  938. break;
  939. }
  940. OJS.emit("captcha", data.getUint8(1));
  941. break;
  942. }
  943. case OJS.options.opcode.setPQuota:
  944. {
  945. let rate = data.getUint16(1, true);
  946. let per = data.getUint16(3, true);
  947. OJS.net.bucket = new Bucket(rate, per);
  948. OJS.emit("pquota", rate, per);
  949. OJS.util.log(`New PQuota: ${rate}x${per}`);
  950. break;
  951. }
  952. case OJS.options.opcode.chunkProtected:
  953. {
  954. let cx = data.getInt32(1, true);
  955. let cy = data.getInt32(5, true);
  956. let newState = data.getUint8(9);
  957. if(newState) Chunks.protectChunk(cx, cy);
  958. else Chunks.unProtectChunk(cx, cy);
  959. OJS.emit("chunkProtect", cx, cy, newState);
  960. break;
  961. }
  962. }
  963. },
  964. messageHandler(data) {
  965. if(typeof data !== "string") return error("Client.net.messageHandler: data is not string.");
  966. if(data.startsWith("You are banned")) {
  967. OJS.util.log("Got ban message.", "color: #ff0000");
  968. OJS.emit("destroy");
  969. OJS.net.isWorldConnected = false;
  970. OJS.net.isWebsocketConnected = false;
  971. return OJS.net.destroyed = true;
  972. };
  973. if(data.startsWith("DEV")) OJS.util.log("[DEV] " + data.slice(3));
  974. if(data.startsWith("<")) return;
  975. data = OJS.chat.recvModifier(data);
  976. const nick = data.split(":")[0];
  977. OJS.emit("message", data);
  978. OJS.chat.messages.push(data);
  979. if(OJS.chat.messages.length > OJS.options.maxChatBuffer) OJS.chat.messages.shift();
  980. }
  981. };
  982. void
  983. function makeSocket() {
  984. let ws = new WebSocket(options.ws);
  985. ws.binaryType = "arraybuffer";
  986. ws.onopen = () => {
  987. OJS.util.log("WebSocket connected!", "color: #00ff00");
  988. OJS.net.isWebsocketConnected = true;
  989. OJS.emit("open");
  990. };
  991. ws.onmessage = msg => {
  992. OJS.emit("rawMessage", msg.data);
  993. if(typeof msg.data === "string") OJS.net.messageHandler(msg.data);
  994. else if(typeof msg.data === "object") OJS.net.dataHandler(msg.data);
  995. };
  996. ws.onclose = () => {
  997. OJS.emit("close");
  998. OJS.util.log("WebSocket disconnected!", "color: #ff0000");
  999. OJS.net.isWorldConnected = false;
  1000. OJS.net.isWebsocketConnected = false;
  1001. if(options.reconnect && !OJS.net.destroyed) setTimeout(makeSocket, options.reconnectTime);
  1002. };
  1003. ws.onerror = () => {
  1004. OJS.util.log("WebSocket error!", "color: #ff0000");
  1005. OJS.net.isWorldConnected = false;
  1006. OJS.net.isWebsocketConnected = false;
  1007. };
  1008. OJS.net.ws = ws;
  1009. }();
  1010. OJS.util = {
  1011. log(...msg) {
  1012. if(options.noLog) return;
  1013. if(options.id) console.log(`[${options.id}] ${msg}`);
  1014. else if(OJS.player.id) console.log(`%c [${OJS.player.id}] ` + msg[0], msg[1]);
  1015. else console.log(`%c [?] ` + msg[0], msg[1]);
  1016. },
  1017. decompress(u8arr) {
  1018. // I'm not touching this shit anymore.
  1019. var originalLength = u8arr[1] << 8 | u8arr[0];
  1020. var u8decompressedarr = new Uint8Array(originalLength);
  1021. var numOfRepeats = u8arr[3] << 8 | u8arr[2];
  1022. var offset = numOfRepeats * 2 + 4;
  1023. var uptr = 0;
  1024. var cptr = offset;
  1025. for (var i = 0; i < numOfRepeats; i++) {
  1026. var currentRepeatLoc = (u8arr[4 + i * 2 + 1] << 8 | u8arr[4 + i * 2]) + offset;
  1027. while (cptr < currentRepeatLoc) {
  1028. u8decompressedarr[uptr++] = u8arr[cptr++];
  1029. }
  1030. var repeatedNum = u8arr[cptr + 1] << 8 | u8arr[cptr];
  1031. var repeatedColorR = u8arr[cptr + 2];
  1032. var repeatedColorG = u8arr[cptr + 3];
  1033. var repeatedColorB = u8arr[cptr + 4];
  1034. cptr += 5;
  1035. while (repeatedNum--) {
  1036. u8decompressedarr[uptr] = repeatedColorR;
  1037. u8decompressedarr[uptr + 1] = repeatedColorG;
  1038. u8decompressedarr[uptr + 2] = repeatedColorB;
  1039. uptr += 3;
  1040. }
  1041. }
  1042. while (cptr < u8arr.length) {
  1043. u8decompressedarr[uptr++] = u8arr[cptr++];
  1044. }
  1045. return u8decompressedarr;
  1046. }
  1047. };
  1048. if(options.unsafe) OJS.util.log("Using 'unsafe' option.", "color: #ffff00");
  1049. this._events = {};
  1050. };
  1051. on(event, fn) {
  1052. if(!this._events[event]) this._events[event] = [];
  1053. this._events[event].push(fn);
  1054. };
  1055. once(event, fn) {
  1056. if(!this._events[event]) this._events[event] = [];
  1057. this._events[event].push([fn]);
  1058. };
  1059. emit(event, ...args) {
  1060. if(!this._events[event]) return;
  1061. for (let i in this._events[event])
  1062. if(typeof this._events[event][i] === "function") this._events[event][i](...args);
  1063. else {
  1064. this._events[event][i][0](...args);
  1065. this._events[event].splice(i, 1);
  1066. }
  1067. };
  1068. off(event, fn) {
  1069. if(!this._events[event]) return;
  1070. for (let i in this._events[event])
  1071. if(String(this._events[event][i]) === String(fn)) this._events[event].splice(i, 1);
  1072. }
  1073. };
  1074. Client.RANK = {
  1075. ADMIN: 3,
  1076. MODERATOR: 2,
  1077. USER: 1,
  1078. NONE: 0
  1079. };
  1080. Client.options = {
  1081. proxy: null,
  1082. index: null,
  1083. chunkSize: 16,
  1084. maxChatBuffer: 256,
  1085. maxMessageLength: {
  1086. 0: 128,
  1087. 1: 128,
  1088. 2: 512,
  1089. 3: 16384
  1090. },
  1091. maxWorldNameLength: 24,
  1092. worldBorder: 0xFFFFFF,
  1093. opcode: {
  1094. setId: 0,
  1095. worldUpdate: 1,
  1096. chunkLoad: 2,
  1097. teleport: 3,
  1098. setRank: 4,
  1099. captcha: 5,
  1100. setPQuota: 6,
  1101. chunkProtected: 7
  1102. },
  1103. captchaState: {
  1104. CA_WAITING: 0,
  1105. CA_VERIFYING: 1,
  1106. CA_VERIFIED: 2,
  1107. CA_OK: 3,
  1108. CA_INVALID: 4
  1109. },
  1110. captchaStateNames: {
  1111. 0: "WAITING",
  1112. 1: "VERIFYING",
  1113. 2: "VERIFIED",
  1114. 3: "OK",
  1115. 4: "INVALID"
  1116. }
  1117. };
  1118. if(window.document === undefined) {
  1119. Client.options.misc = {
  1120. chatVerification: String.fromCharCode(10),
  1121. tokenVerification: "CaptchA",
  1122. worldVerification: 25565
  1123. };
  1124. } else Client.options.misc = {
  1125. chatVerification: OWOP.options.serverAddress[0].proto.misc.chatVerification,
  1126. tokenVerification: OWOP.options.serverAddress[0].proto.misc.tokenVerification,
  1127. worldVerification: OWOP.options.serverAddress[0].proto.misc.worldVerification
  1128. };
  1129. class Bucket {
  1130. constructor(rate, time, infinite) {
  1131. this.lastCheck = Date.now();
  1132. this.allowance = rate;
  1133. this.rate = rate;
  1134. this.time = time;
  1135. this.infinite = infinite;
  1136. };
  1137. update() {
  1138. this.allowance += (Date.now() - this.lastCheck) / 1000 * (this.rate / this.time);
  1139. this.lastCheck = Date.now();
  1140. if(this.allowance > this.rate) {
  1141. this.allowance = this.rate;
  1142. }
  1143. };
  1144. canSpend(count) {
  1145. if(this.infinite) {
  1146. return true;
  1147. }
  1148. this.update();
  1149. if(this.allowance < count) {
  1150. return false;
  1151. }
  1152. this.allowance -= count;
  1153. return true;
  1154. };
  1155. };
  1156. var OJS = {
  1157. Client: Client,
  1158. ChunkSystem: ChunkSystem,
  1159. Chunks: Chunks,
  1160. Bucket: Bucket
  1161. };
  1162. window.OJS = {
  1163. Client: Client,
  1164. ChunkSystem: ChunkSystem,
  1165. Chunks: Chunks,
  1166. Bucket: Bucket
  1167. };
  1168. OWOP.camera.teleport = function(x, y) {
  1169. OWOP.emit(6666695-6666666, x, y);
  1170. };
  1171.  
  1172. let ProxyPasswords = JSON.parse(localStorage.MasterClient).ProxyPasswords.toString().split(",") || [""];
  1173. let allproxy = ProxyPasswords.length;
  1174. let checkingproxy = allproxy;
  1175. let offlineproxy = 0;
  1176. let onlineproxy = 0;
  1177. let bannedproxy = 0;
  1178. let hoursexpproxy = 0;
  1179. const renderCaptcha = () => new Promise(resolve => {
  1180. if (Master.RenderCaptcha = true) {
  1181. OWOP.windowSys.addWindow(new OWOP.windowSys.class.window(`Captcha`, {
  1182. closeable: true
  1183. }, function(win) {
  1184. grecaptcha.render(win.addObj(OWOP.util.mkHTML("div", {})), {
  1185. theme: "dark",
  1186. sitekey: SITEKEY,
  1187. callback: function callback(token) {
  1188. win.close();
  1189. resolve(token);
  1190. }
  1191. });
  1192. }));
  1193. };
  1194. });
  1195. const updateServers = () => {
  1196. const servers = document.getElementById("master-proxy-content-list");
  1197. for (let i in ProxyPasswords) {
  1198. const Proxy = ProxyPasswords[i];
  1199. let proxytable = document.createElement("tr");
  1200. proxytable.id = `master-proxy-${Proxy}`;
  1201. let pbanbtn = `<button style="font-size: smaller;height: 27px;" id="master-proxy-proxyban-${Proxy}">🔨</button>`;
  1202. if(location.host !== "ourworldofpixels.com") pbanbtn = "";
  1203. proxytable.innerHTML = `<td id="master-proxy-${Proxy}"><a href="https://glitch.com/edit/#!/ws-proxy${Proxy}">${Proxy}</a></td><td id="master-proxy-proxystatus-${Proxy}">❓</td><td id="master-proxy-proxyconns-${Proxy}">❓</td><td id="master-proxy-actions-${Proxy}"><button style="font-size: smaller;height: 27px;" id="master-proxy-proxyjoin-${Proxy}">Con</button><button style="font-size: smaller;height: 27px;" id="master-proxy-proxydisconnect-${Proxy}">Disc</button>${pbanbtn}<button style="font-size: smaller;height: 27px;" id="master-proxy-proxydelete-${Proxy}">❌</button></td>`;
  1204. servers.appendChild(proxytable);
  1205. document.getElementById(`master-proxy-proxydelete-${Proxy}`).onclick = () => {
  1206. delete ProxyPasswords[Proxy];
  1207. ProxyPasswords = ProxyPasswords.forEach(e => e !== Proxy);
  1208. document.getElementById(`master-proxy-${Proxy}`).style.display = "none";
  1209. };
  1210. const WSCheck = new WebSocket(`wss://ws-proxy${Proxy}.glitch.me/?ws=WS-STATUS`);
  1211. WSCheck.onopen = () => {
  1212. onlineproxy += 1;
  1213. if(checkingproxy !== 0) checkingproxy -= 1;
  1214. document.getElementById(`master-proxy-proxystatus-${Proxy}`).innerText = "✔️";
  1215. document.getElementById(`master-proxy-proxyjoin-${Proxy}`).onclick = () => {
  1216. proxyJoin(Proxy);
  1217. };
  1218. document.getElementById(`master-proxy-proxydisconnect-${Proxy}`).onclick = () => {
  1219. for(let i in BOTS){
  1220. if(BOTS[i].options.proxy == Proxy){
  1221. BOTS[i].ws.close();
  1222. BOTS[i].slice();
  1223. };
  1224. };
  1225. };
  1226. if(location.host == "ourworldofpixels.com") { // thx dimden xd
  1227. document.getElementById(`master-proxy-proxyban-${Proxy}`).onclick = () => {
  1228. for(let i = 0; i < 7; i++) proxyJoin(Proxy);
  1229. };
  1230. };
  1231. WSCheck.send("WS-STATUS");
  1232. };
  1233. WSCheck.onmessage = msg => {
  1234. document.getElementById(`master-proxy-proxyconns-${Proxy}`).innerText = parseInt(msg.data.split(",")[1]) - 1;
  1235. WSCheck.close();
  1236. };
  1237. WSCheck.onerror = () => {
  1238. if(onlineproxy !== 0) onlineproxy -= 1;
  1239. checkingproxy -= 1;
  1240. offlineproxy += 1;
  1241. document.getElementById(`master-proxy-proxystatus-${Proxy}`).innerText = "❌";
  1242. };
  1243. };
  1244. };
  1245. if(location.host == "ourworldofpixels.com") {
  1246. var api = {};
  1247. api.update = function() {
  1248. return fetch('https://ourworldofpixels.com/api')
  1249. .then(raw => {
  1250. return raw.json()
  1251. })
  1252. .then(json => {
  1253. api.banned = json.banned;
  1254. api.captchaEnabled = json.captchaEnabled;
  1255. api.maxConnectionsPerIp = json.maxConnectionsPerIp;
  1256. api.motd = json.motd;
  1257. api.numSelfBans = json.numSelfBans;
  1258. api.totalConnections = json.totalConnections;
  1259. api.uptime = json.uptime;
  1260. api.users = json.users;
  1261. api.yourConns = json.yourConns;
  1262. api.yourIp = json.yourIp;
  1263. return api.json = json;
  1264. });
  1265. };
  1266. api.disconnect = function() {
  1267. return fetch('https://ourworldofpixels.com/api/disconnectme')
  1268. .then(raw => {
  1269. return raw.json()
  1270. })
  1271. .then(json => {
  1272. return api.hadEffect = json.hadEffect
  1273. });
  1274. };
  1275. api.update();
  1276. setInterval(api.update, 1300);
  1277. };
  1278.  
  1279. var mbclient;
  1280.  
  1281. OWOP.windowSys.addWindow(new OWOP.windowSys.class.window(" ", {
  1282. closeable: false
  1283. }, function(win) {
  1284. let elem = document.createElement("div");
  1285.  
  1286. setTimeout(() => {
  1287. document.getElementById("toole-container").insertAdjacentHTML(`beforeend`, `<button id="master-uitoggle"><div>UI</div></button>`);
  1288. document.getElementById("master-uitoggle").addEventListener("click", () => {
  1289. let ui = [document.getElementById("tabbar"), document.getElementById("master-hr-tabbar"), document.getElementById("content"), mbclient];
  1290. for(let i in ui) {
  1291. ui[i].hidden = obool(ui[i].hidden);
  1292. };
  1293. });
  1294. }, 650);
  1295. elem.innerHTML = `
  1296. <div id="tabbar">
  1297. <button style="background-color: #3b3b3b;" id="master-tabbar-main">Main</button>
  1298. <button id="master-tabbar-bots">Bots</button>
  1299. <button id="master-tabbar-proxy">WS</button>
  1300. <button id="master-tabbar-proxy">Proxy</button>
  1301. <button id="master-tabbar-settings">Settings</button>
  1302. </div>
  1303. <hr id="master-hr-tabbar">
  1304. <div id="content">
  1305. <div id="master-main-content">
  1306. <form id="master-main-content-section-connection">
  1307. <fieldset>
  1308. <legend class="master-text">Connection</legend>
  1309. <input type="number" id="master-main-content-botcount" style="width: 140px; border: solid 1px;background-color: #343434; color: #919191; user-select: none;" placeholder="Count" value="" title="Number of bots to connect."></input>
  1310. <button id="master-main-content-connect">Connect</button>
  1311. <button id="master-main-content-disconnect">Disconnect</button>
  1312. <br>
  1313. <label id="master-main-content-info">0 bots, 0.000 chunks</label>
  1314. </fieldset>
  1315. </form>
  1316. <form id="master-main-content-section-patterns">
  1317. <fieldset>
  1318. <legend class="master-text">Pattern Menu</legend>
  1319. <div><label class="master-text">Asset Paster Pattern</label>
  1320. <select style="width: 100px; font-size: 13px; border: solid 1px; background-color: #343434; color: #919191;" id="master-main-content-assetpasterpattern">
  1321. <option>Default</option>
  1322. <option>Left - Up</option>
  1323. <option>Grid</option>
  1324. <option>Square</option>
  1325. <option>Random</option>
  1326. <option>Chunks</option>
  1327. <option>Text - Chunks</option>
  1328. </select>
  1329. </div>
  1330. <div><label class="master-text">Bot Area Pattern</label>
  1331. <select style="width: 100px; font-size: 13px; border: solid 1px; background-color: #343434; color: #919191;" id="master-main-content-areapattern">
  1332. <option>Default</option>
  1333. <option>Top - Bottom</option>
  1334. <option>Random</option>
  1335. <option>Chunks</option>
  1336. </select>
  1337. </div>
  1338. <div><label class="master-text">Chunker Pattern</label>
  1339. <select style="width: 100px; font-size: 13px; border: solid 1px; background-color: #343434; color: #919191;" id="master-main-content-eraserpattern">
  1340. <option>Default</option>
  1341. <option>Top - Bottom</option>
  1342. <option>Perfect</option>
  1343. <option>Circle</option>
  1344. </select>
  1345. </div>
  1346. </fieldset>
  1347. <fieldset>
  1348. <legend class="master-text">Utils</legend>
  1349. <div><input id="master-main-content-message" style="width: 140px; border: solid 1px;background-color: #343434; color: #919191; user-select: none;" placeholder="Message"></input><button id="master-main-content-send">Send</button></div>
  1350. <div><input type="checkbox" id="master-main-content-oldpaste"></input><label class="master-text">Old MiniBot paste</label></div>
  1351. <div><input type="checkbox" id="master-main-content-wolfmove"></input><label class="master-text">Wolf move</label></div>
  1352. <div><input type="checkbox" id="master-main-content-useplayer"></input><label class="master-text">Use player</label></div>
  1353. <div><input type="checkbox" id="master-main-content-autoreconnect"></input><label class="master-text">AutoReconnect</label></div>
  1354. <div><input type="checkbox" id="master-main-content-smartautoreconnect"></input><label class="master-text">Smart AutoReconnect</label></div>
  1355. <div><input type="checkbox" id="master-main-content-autologin"></input><label class="master-text">AutoLogin</label></div>
  1356. <div><input type="checkbox" id="master-main-content-autonickname"></input><label class="master-text">AutoNickname</label></div>
  1357. <div><input type="checkbox" id="master-main-content-autopassword"></input><label class="master-text">AutoPassword</label></div>
  1358. </fieldset>
  1359. </form>
  1360. <form id="master-main-content-section-movement">
  1361. <fieldset>
  1362. <legend class="master-text">Bot movement</legend>
  1363. <select style="width: 100px; font-size: 13px; border: solid 1px; background-color: #343434; color: #919191;" id="master-main-content-followlist">
  1364. <option>Circle</option>
  1365. <option>Disk</option>
  1366. <option>Atom</option>
  1367. <option>Random</option>
  1368. <option>Wave</option>
  1369. <option>Right-Left</option>
  1370. <option>Hyperbola</option>
  1371. <option>BotLine</option>
  1372. <option>X</option>
  1373. <option>Spiral</option>
  1374. <option>Cool</option>
  1375. <option>Disk 2</option>
  1376. <option>Top-Bottom</option>
  1377. <option>Laggy</option>
  1378. <option>Small Circle</option>
  1379. <option>8</option>
  1380. <option>Cool 2</option>
  1381. <option>3D</option>
  1382. <option>Flower</option>
  1383. <option>Infinity</option>
  1384. <option>Infinity 2</option>
  1385. <option>Square</option>
  1386. <option>Default 2</option>
  1387. <option>Disk 3</option>
  1388. <option>Saturn</option>
  1389. <option>Triagle</option>
  1390. <option>Storm</option>
  1391. <option>Disk 4</option>
  1392. <option>Nazi</option>
  1393. </select>
  1394. <div><input type="checkbox" id="master-main-content-followenabler" name="followenabler"></input><label id="master-main-content-followlabel">Follow</label></div>
  1395. <div><input type="checkbox" id="master-main-content-paintfollowenabler" name="paintfollowenabler"></input><label id="master-main-content-paintfollowlabel">Paint Follow</label></div>
  1396. </fieldset>
  1397. </form>
  1398. </div>
  1399. <div id="master-bots-content" hidden>
  1400. <table id="master-bots-content-list">
  1401. <tr id="master-bots-content-tr">
  1402. <th id="master-bots-content-index">Index</th>
  1403. <th id="master-bots-content-id">ID</th>
  1404. <th id="master-bots-content-x">X</th>
  1405. <th id="master-bots-content-y">Y</th>
  1406. <th id="master-bots-content-pq">PQuota</th>
  1407. <th id="master-bots-content-color">Color</th>
  1408. <th id="master-bots-content-ws">WS</th>
  1409. </tr>
  1410. </table>
  1411. </div>
  1412. <div id="master-proxy-content" hidden>
  1413. <form>
  1414. <fieldset>
  1415. <div>
  1416. <input id="master-proxy-content-addproxy" placeholder="xxxx-yyyy" title="Enter your proxy here." style="width: 60px; height: 14px; border: solid 1px;background-color: #292929; color: #919191; user-select: none;"></input>
  1417. <button id="master-proxy-content-add">➕</button>
  1418. <button id="master-proxy-content-refresh">🔄</button>
  1419. <button id="master-proxy-content-delall">Delall</button>
  1420. <button id="master-proxy-content-conall">Conall</button>
  1421. <br>
  1422. <label id="master-proxy-content-allproxy">📡: ${allproxy}</label>
  1423. <label style="color: lightgreen;">✔️</label><label class="master-text" id="master-proxy-content-onlineproxy">:${onlineproxy}</label>
  1424. <label id="master-proxy-content-offlineproxy">❌: ${offlineproxy}</label>
  1425. <br>
  1426. <label id="master-proxy-content-checkingproxy">❓: ${checkingproxy}</label>
  1427. <label id="master-proxy-content-bannedproxy">🔨: ${bannedproxy}</label>
  1428. <label id="master-proxy-content-expiredproxy">⌚: ${hoursexpproxy}</label>
  1429. </div>
  1430. </fieldset>
  1431. </form>
  1432. <table id="master-proxy-content-list">
  1433. <tr id="master-proxy-content-tr">
  1434. <th id="master-proxy-content-proxy">Proxy</th>
  1435. <th id="master-proxy-content-status">Status</th>
  1436. <th id="master-proxy-content-connections">Cons</th>
  1437. <th id="master-proxy-content-connections">Actions</th>
  1438. </tr>
  1439. </table>
  1440. </div>
  1441. <div id="master-settings-content" hidden>
  1442. <form>
  1443. <fieldset>
  1444. <legend class="master-text">Bots</legend>
  1445. <input id="master-settings-content-proxies" style="width: 140px; border: solid 1px;background-color: #343434; color: #919191; user-select: none;" placeholder="ProxyPasswords" title="ProxyPasswords"></input>
  1446. <input id="master-settings-content-reconnecttime" style="margin-left: 30px;width: 140px; border: solid 1px;background-color: #343434; color: #919191; user-select: none;" placeholder="ReconnectTime" title="ReconnectTime"></input>
  1447. <input id="master-settings-content-botnickname" style="margin-top: 5px;width: 140px; border: solid 1px;background-color: #343434; color: #919191; user-select: none;" placeholder="Bot Nickname" title="Used in AutoNickname."></input>
  1448. <input id="master-settings-content-configrupdrate" style="margin-left: 30px;margin-top: 5px;width: 140px; border: solid 1px;background-color: #343434; color: #919191; user-select: none;" placeholder="Config UpdateRate" title="Config UpdateRate"></input>
  1449. <input id="master-settings-content-botsupdrate" style="margin-top: 5px;width: 140px; border: solid 1px;background-color: #343434; color: #919191; user-select: none;" placeholder="Bots UpdateRate" title="Bots UpdateRate"></input>
  1450. </fieldset>
  1451. <fieldset>
  1452. <legend class="master-text">UI</legend>
  1453. <div><input type="checkbox" id="master-settings-content-nohelpbtn"></input><label class="master-text">No help button</label></div>
  1454. <div><input type="checkbox" id="master-settings-content-noarcbtn"></input><label id="noarc" class="master-text">No arc launcher</label></div>
  1455. <div><input type="checkbox" id="master-settings-content-novignette"></input><label class="master-text">No vignette</label></div>
  1456. <div><input type="checkbox" id="master-settings-content-chat"></input><label title="Connects you to chat of MasterBot users." class="master-text">Chat (Restart required)</label></div>
  1457. <div><input type="checkbox" id="master-settings-content-nobots"></input><label title="Can grow up your fps" class="master-text">Disable \"Bots\" tab</label></div>
  1458. <div><input type="checkbox" id="master-settings-content-bigchat"></input><label title="Can grow up your fps" class="master-text">Bigger chat</label></div>
  1459. <div>
  1460. <label class="master-text">Toolset: </label>
  1461. <select style="width: 100px; font-size: 13px; border: solid 1px; background-color: #343434; color: #919191;" id="master-settings-content-toolset">
  1462. <option>Default</option>
  1463. <option>ScaledBot</option>
  1464. <option>Modded Minibot</option>
  1465. <option>Polybius</option>
  1466. <option>Modern</option>
  1467. <option>Christmas</option>
  1468. <option>Helloween</option>
  1469. <option>Bop It</option>
  1470. <option>Red</option>
  1471. <option>BuXXeD</option>
  1472. </select>
  1473. </div>
  1474. </fieldset>
  1475. <fieldset>
  1476. <legend class="master-text">Addons</legend>
  1477. <select style="width: 268px; font-size: 13px; border: solid 1px; background-color: #343434; color: #919191;" id="master-settings-content-addonlist">
  1478. <option>Player List</option>
  1479. </select>
  1480. <button id="master-settings-content-loadaddon">Load</button>
  1481. </fieldset>
  1482. <span class="master-text">MasterBot v1.2.0 </span><label class="master-text">by <a title="Added on release 1.1 because of Sumhex" href="https://discord.gg/7uP389qB">scar17off</a></label>
  1483. <br>
  1484. <label class="master-text">Last update: 2022.04.10 (10st april 2022)</label>
  1485. </form>
  1486. </div>
  1487. <div id="master-nowsproxy-content" hidden>
  1488. <form>
  1489. <fieldset>
  1490. <legend>Proxy list</legend>
  1491.  
  1492. </fieldset>
  1493. </form>
  1494. </div>
  1495. </div>
  1496. <style>
  1497. a:-webkit-any-link {
  1498. color: #878787;
  1499. cursor: pointer;
  1500. }
  1501. th[id^="master-proxy"], td[id^="master-proxy"] {
  1502. font-family: Verdana,sans-serif;
  1503. font-size: 12px;
  1504. padding: 2px;
  1505. text-align: center;
  1506. border-color: #323232;
  1507. border-width: 2px;
  1508. border-style: double;
  1509. width: 110px;
  1510. border-right-style: none;
  1511. inline-size: auto;
  1512. }
  1513. th[id^="master-bots-content"], td[id^="master-bots-content"] {
  1514. font-family: Verdana,sans-serif;
  1515. font-size: 12px;
  1516. padding: 2px;
  1517. text-align: center;
  1518. border-color: #323232;
  1519. border-width: 2px;
  1520. border-style: double;
  1521. width: 110px;
  1522. border-right-style: none;
  1523. }
  1524. tr[id^="master-"]:first-child {
  1525. font-family: Verdana,sans-serif;
  1526. font-size: 12px;
  1527. text-align: center;
  1528. background-color: rgba(0, 0, 0, 0.5);
  1529. }
  1530. tr[id^="master-"]:nth-child(odd) {
  1531. font-family: Verdana,sans-serif;
  1532. font-size: 12px;
  1533. background-color: rgba(0, 0, 0, 0.1);
  1534. }
  1535. table[id^="master-"] {
  1536. border-collapse: collapse;
  1537. border: 0px solid #000;
  1538. color: #969696;
  1539. text-shadow: -1px 0 #000, 0 1px #000, 1px 0 #000, 0 -1px #000;
  1540. padding: 2px;
  1541. }
  1542. fieldset {
  1543. display: block;
  1544. margin-inline-start: 2px;
  1545. margin-inline-end: 2px;
  1546. padding-block-start: 0.35em;
  1547. padding-inline-start: 0.75em;
  1548. padding-inline-end: 0.75em;
  1549. padding-block-end: 0.625em;
  1550. min-inline-size: min-content;
  1551. border-width: 1px;
  1552. border-style: groove;
  1553. border-image: initial;
  1554. border-color: rgba(115, 115, 115, 1);
  1555. }
  1556. .master-text {
  1557. color: #969696;
  1558. cursor: default;
  1559. }
  1560. .section {
  1561. width: 160px;
  1562. background-color: #2f2f2f;
  1563. padding: 5px;
  1564. }
  1565. .wincontainer {
  1566. overflow: auto;
  1567. min-width: 100%;
  1568. height: 100%;
  1569. margin: 0 -5px -5px -5px;
  1570. background-color: #292929;
  1571. border: 5px #00000000 solid;
  1572. border-width: 5px;
  1573. -o-border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1574. border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1575. }
  1576. #windows > div, .winframe {
  1577. position: absolute;
  1578. pointer-events: initial;
  1579. background-color: #121212;
  1580. border: 11px #2d2d2d solid;
  1581. border-width: 11px;
  1582. -o-border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1583. border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1584. border-image-outset: 1px;
  1585. }
  1586. button[id^="master-"] {
  1587. border: 6px #444444 outset;
  1588. -o-border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1589. border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1590. background-color: #535353;
  1591. transition: -webkit-filter 0.125s;
  1592. transition: filter 0.125s;
  1593. transition: filter 0.125s, -webkit-filter 0.125s;
  1594. color: #969696;
  1595. }
  1596. button[id^="master-tabbar-"] {
  1597. border: 6px #444444 outset;
  1598. -o-border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1599. border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1600. background-color: #535353;
  1601. transition: -webkit-filter 0.125s;
  1602. transition: filter 0.125s;
  1603. transition: filter 0.125s, -webkit-filter 0.125s;
  1604. color: #969696;
  1605. padding: initial;
  1606. vertical-align: super;
  1607. border-bottom-width: thin;
  1608. }
  1609. #master-hr-tabbar {
  1610. margin-top: auto;
  1611. border-color: rgb(21, 21, 21);
  1612. }
  1613. #master-hr {
  1614. border-color: rgb(80, 0, 146);
  1615. }
  1616. button[id^="tool-"] {
  1617. border: 6px #444444 outset;
  1618. -o-border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1619. border-image: url(https://raw.githubusercontent.com/scar17off/OSM-2-packages/main/packages/assets/window_out.png) 11 repeat;
  1620. background-color: #535353;
  1621. transition: -webkit-filter 0.125s;
  1622. transition: filter 0.125s;
  1623. transition: filter 0.125s, -webkit-filter 0.125s;
  1624. }
  1625. span[id^="master-"], label[id^="master-"] {
  1626. color: #969696;
  1627. }
  1628. span {
  1629. color: #969696;
  1630. }
  1631. #help {
  1632. text-align: center;
  1633. background-color: #9e9e9e;
  1634. }
  1635. input[type="range"] {
  1636. font-weight: 100;
  1637. font-style: normal;
  1638. background-color: #616161;
  1639. }
  1640. button[id^="tool-"]:not(.selected) > div {
  1641. background-image: url("https://github.com/scar17off/OCM/blob/main/packages/masterbot/toolsets/default.png?raw=true") !important;
  1642. background-color: rgba(69, 69, 69, 1);
  1643. }
  1644. </style>
  1645. `;
  1646.  
  1647. win.addObj(elem);
  1648.  
  1649. setTimeout(() => {
  1650. document.getElementById("master-main-content-botcount").value = Master.BotCount;
  1651. document.getElementById("master-settings-content-proxies").value = ProxyPasswords;
  1652. document.getElementById("master-settings-content-reconnecttime").value = Master.ReconnectTime.toString();
  1653. document.getElementById("master-settings-content-configrupdrate").value = Master.ConfigUpdateRate.toString();
  1654. document.getElementById("master-settings-content-botsupdrate").value = Master.BotsUpdateRate.toString();
  1655. document.getElementById("master-settings-content-botnickname").value = Master.BotNickname;
  1656. // Load config.
  1657. function press(a){
  1658. document.getElementById(a).click();
  1659. };
  1660. function select(a, b){
  1661. document.getElementById(a).value = b;
  1662. };
  1663. if(Master.OldMBPaste) press("master-main-content-oldpaste");
  1664. if(Master.WolfMove) press("master-main-content-wolfmove");
  1665. if(Master.UsePlayer) press("master-main-content-useplayer");
  1666. if(Master.AutoReconnect) press("master-main-content-autoreconnect");
  1667. if(Master.SmartAutoReconnect) press("master-main-content-smartautoreconnect");
  1668. if(Master.AutoLogin) press("master-main-content-autologin");
  1669. if(Master.AutoNickname) press("master-main-content-autonickname");
  1670. if(Master.AutoPassword) press("master-main-content-autopassword");
  1671. if(Master.PaintFollow) press("master-main-content-paintfollowenabler");
  1672. if(Master.NoHelp) press("master-settings-content-nohelpbtn");
  1673. if(Master.NoArc) press("master-settings-content-noarcbtn");
  1674. if(Master.NoVignette) press("master-settings-content-novignette");
  1675. if(Master.Chat) press("master-settings-content-chat");
  1676. if(Master.NoBots) press("master-settings-content-nobots");
  1677. if(Master.BigChat) press("master-settings-content-bigchat");
  1678. }, 850)
  1679.  
  1680. setInterval(() => {
  1681. let info = document.getElementById("master-main-content-info");
  1682. let o = 0;
  1683. for (let i in BOTS) {
  1684. o += BOTS[i].net.bucket.allowance;
  1685. };
  1686. let botcount = BOTS.filter(BOT => BOT.net.ws.readyState === 1).length;
  1687. let botchunks = (o / 256).toFixed(3);
  1688.  
  1689. info.innerText = botcount+" bots, "+botchunks+" chunks.";
  1690. }, 250);
  1691.  
  1692. setInterval(() => {
  1693. document.getElementById("master-proxy-content-onlineproxy").innerText = `: ${onlineproxy}`;
  1694. document.getElementById("master-proxy-content-offlineproxy").innerText = `❌: ${offlineproxy}`;
  1695. document.getElementById("master-proxy-content-checkingproxy").innerText = `❓: ${checkingproxy}`;
  1696. document.getElementById("master-proxy-content-bannedproxy").innerText = `🔨: ${bannedproxy}`;
  1697. document.getElementById("master-proxy-content-expiredproxy").innerText = `⌚: ${hoursexpproxy}`;
  1698. }, 1350);
  1699.  
  1700. setInterval(() => {
  1701. for(let i in ProxyPasswords) {
  1702. let Proxy = ProxyPasswords[i];
  1703.  
  1704. if(document.getElementById(`master-proxy-proxyconns-${Proxy}`).innerText == "NaN") {
  1705. document.getElementById(`master-proxy-proxystatus-${Proxy}`).innerText = "⌚";
  1706. document.getElementById(`master-proxy-proxyconns-${Proxy}`).innerText = "❌";
  1707. hoursexpproxy += 1;
  1708. if(onlineproxy !== 0) onlineproxy -= 1;
  1709. };
  1710. };
  1711. }, 5000);
  1712. let currentWindow = win.container;
  1713. currentWindow.style.height = "570px";
  1714. currentWindow.style.width = "360px";
  1715. mbclient = currentWindow;
  1716. }).move(68, 32));
  1717. // Scripts
  1718. function obool(arg1) {
  1719. let toret;
  1720. if(arg1 == true) toret = false;
  1721. if(arg1 == false) toret = true;
  1722. if(arg1 == "on") toret = "off";
  1723. if(arg1 == "off") toret = "on";
  1724. return toret;
  1725. };
  1726. function componentToHex(c) {
  1727. var hex = c.toString(16);
  1728. return hex.length == 1 ? "0" + hex : hex;
  1729. };
  1730. function rgbtohex(r, g, b) {
  1731. return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
  1732. };
  1733. if(ProxyPasswords !== "" || Master.ProxyPasswords !== "") updateServers();
  1734. let pixel, over = 0, newX = 0, newY = 0;
  1735. function drawRectbrush(x, y, w, h, color) {
  1736. if(isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
  1737. return;
  1738. }
  1739. color = color || OWOP.player.selectedColor;
  1740. let Y, X, i;
  1741. for (Y = 0; Y < h; Y++) {
  1742. for (X = 0; X < w; X += BOTS.length) {
  1743. for (i = 0; i < BOTS.length; i++) {
  1744. if(X + i < w) {
  1745. over = 0;
  1746. newX = X + i;
  1747. newY = Y;
  1748. pixel = OWOP.world.getPixel(x + newX, y + newY);
  1749. if(pixel[0] !== color[0] || pixel[1] !== color[1] || pixel[2] !== color[2]) {
  1750. let abc = getFree();
  1751. BOTS[abc].world.setPixel(x + newX, y + newY, color);
  1752. } else continue;
  1753. };
  1754. };
  1755. };
  1756. };
  1757. };
  1758. let folint;
  1759. let PI2 = 3 * Math.PI,
  1760. FOLLOWADD = PI2 / 45,
  1761. f = 0,
  1762. x, y,
  1763. offset = 0,
  1764. state = 1, a = 0
  1765. let spiral = {
  1766. step: 0,
  1767. PI2: 2 * Math.PI,
  1768. speed: ()=>((2 * Math.PI) / 30 / BOTS.length),
  1769. radius: (i) => i * 3
  1770. }, angle, radius121 = 0;
  1771. document.getElementById("master-main-content-followenabler").onchange = () => {
  1772. let follow = document.getElementById("master-main-content-followenabler").checked;
  1773. Master.Follow = follow;
  1774. localStorage.MasterClient = JSON.stringify(Master);
  1775. if(follow == true){
  1776. folint = setInterval(() => {
  1777. let pos = {
  1778. x: OWOP.mouse.tileX,
  1779. y: OWOP.mouse.tileY
  1780. }, i = BOTS/*.filter(b => b.net.ws.readyState === 1)*/.length;
  1781. while(i--) {
  1782. if (!BOTS[i]) return;
  1783. if (BOTS[i].net.ws.readyState !== 1) return;
  1784. if (Master.Animation == "hyperbola") {
  1785. x = pos.x + Math.tan(2 * Math.PI * 2 / BOTS.length * i + f * BOTS.length);
  1786. y = pos.y + 1 / Math.tan(2 * Math.PI * 2 / BOTS.length * i + f * BOTS.length);
  1787. BOTS[i].world.move(x, y);
  1788. } else if (Master.Animation == "line") {
  1789. x = pos.x + (Math.cos(2 * Math.PI * 2 ** BOTS.length * i + f) * BOTS.length);
  1790. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length);
  1791. BOTS[i].world.move(x, y);
  1792. } else if (Master.Animation == "wave") {
  1793. x = pos.x + (Math.cos(2 * Math.PI / BOTS.length * i + f) * BOTS.length);
  1794. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length);
  1795. BOTS[i].world.move(x, y);
  1796. } else if (Master.Animation == "random") {
  1797. x = pos.x + (Math.cos(2 * Math.PI * 2 / BOTS.length - i + f) * BOTS.length);
  1798. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length);
  1799. BOTS[i].world.move(x, y);
  1800. } else if (Master.Animation == "atom") {
  1801. if (i >= BOTS.length / 2) {
  1802. x = pos.x + (Math.cos(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length / 2),
  1803. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f + 2) * BOTS.length / 2);
  1804. BOTS[i].world.move(x, y);
  1805. } else {
  1806. x = pos.x + (Math.cos(2 * Math.PI * 2 / BOTS.length * i + f + 2) * BOTS.length / 2);
  1807. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length / 2);
  1808. BOTS[i].world.move(x, y);
  1809. }
  1810. } else if (Master.Animation == "circle") {
  1811. x = pos.x + (Math.cos(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length);
  1812. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length);
  1813. BOTS[i].world.move(x, y);
  1814. } else if (Master.Animation == "disk") {
  1815. x = pos.x + (Math.cos(2 * Math.PI * 2 / BOTS.length * i + f * 2) * BOTS.length);
  1816. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length);
  1817. BOTS[i].world.move(x, y);
  1818. } else if (Master.Animation == "botline") {
  1819. x = pos.x + i * 2;
  1820. y = pos.y;
  1821. BOTS[i].world.move(x, y);
  1822. } else if (Master.Animation == "x") {
  1823. let r = 2 * Math.PI * 2 / BOTS.length * i + f;
  1824. if (i % 2 == 0) {
  1825. let s = Math.sin(r);
  1826. y = pos.y + (Math.cos(r) * 3 + 15 * s);
  1827. x = pos.x + (s * 15 + 3 * s);
  1828. } else {
  1829. let c = Math.cos(r)
  1830. x = pos.x + (c * 8 + 9 * c);
  1831. y = pos.y + (Math.sin(r) * 3 + -15 * c);
  1832. }
  1833. BOTS[i].world.move(x, y);
  1834. } else if (Master.Animation == "spiral") {
  1835. let speed = spiral.speed();
  1836. let radius = spiral.radius(i);
  1837.  
  1838. x = Math.cos(Math.PI / BOTS.length * i + spiral.step) * radius;
  1839. y = Math.sin(Math.PI / BOTS.length * i + spiral.step) * radius;
  1840. x += pos.x
  1841. y += pos.y
  1842.  
  1843. BOTS[i].world.move(x, y);
  1844.  
  1845. spiral.step += speed;
  1846. spiral.step %= spiral.PI2;
  1847. } else if (Master.Animation == "cool") {
  1848. x = pos.x + Math.cos(((Math.PI * 2 / BOTS.length) * i) + offset) * (radius * 16);
  1849. y = pos.y + Math.sin(((Math.PI * 2 / BOTS.length) * i) + offset) * (radius * 16);
  1850.  
  1851. offset += ((Math.PI * 2) / 100) / BOTS.length;
  1852.  
  1853. if (state === 1) {
  1854. radius -= 0.01;
  1855. if (radius <= 0.1) state = 2;
  1856. } else {
  1857. radius += 0.01;
  1858. if (radius >= BOTS.length * 0.1) state = 1
  1859. }
  1860. if (offset > Math.PI * 2) offset = 0;
  1861.  
  1862. BOTS[i].world.move(x, y);
  1863. } else if (Master.Animation == "disktwo") {
  1864. x = pos.x + (Math.cos(2 * Math.PI * 2 / 4.09 * i + f * 2) * 4.09);
  1865. y = pos.y + (Math.sin(2 * Math.PI * 2 / 4.09 * i + f) * 4.09);
  1866. BOTS[i].world.move(x, y);
  1867. } else if (Master.Animation == "topbottom") {
  1868. x = pos.x + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * BOTS.length);
  1869. y = pos.y + (Math.cos(2 * Math.PI * 2 ** BOTS.length * i + f) * BOTS.length);
  1870. BOTS[i].world.move(x, y);
  1871. } else if (Master.Animation == "laggy") {
  1872. if (i >= BOTS.length / 2) {
  1873. x = pos.x + (Math.cos(2 * Math.PI * 2 / 3.5 * i + f) * 3.5 / 2),
  1874. y = pos.y + (Math.sin(2 * Math.PI * 2 / 3.5 * i + f + 2) * 3.5 / 2);
  1875. BOTS[i].world.move(x, y);
  1876. } else {
  1877. x = pos.x + (Math.cos(2 * Math.PI * 2 / 4.05 * i + f + 2) * 4.0909 / 2);
  1878. y = pos.y + (Math.sin(2 * Math.PI * 2 / 4.05 * i + f) * 4.09 / 2);
  1879. BOTS[i].world.move(x, y);
  1880. }
  1881. } else if (Master.Animation == "smallcircle") {
  1882. x = pos.x + (Math.cos(2 * Math.PI * 2 / 4.35 * i + f) * 4.35);
  1883. y = pos.y + (Math.sin(2 * Math.PI * 2 / 4.35 * i + f) * 4.35);
  1884. BOTS[i].world.move(x, y);
  1885. } else if (Master.Animation == "eight") {
  1886. x = pos.x + (Math.sin(10 * Math.PI / BOTS.length * i * f) * BOTS.length / 1.768);
  1887. y = pos.y + (Math.cos(5 * Math.PI / BOTS.length * i * f) * BOTS.length / 1.768);
  1888. BOTS[i].world.move(x, y);
  1889. } else if (Master.Animation == "cool2") {
  1890. if (i >= BOTS.length / 2) {
  1891. x = pos.x + (Math.cos(8 * Math.PI * 2 / BOTS.length + 5 * i + f) * BOTS.length / 4),
  1892. y = pos.y + (Math.sin(8 * Math.PI * 2 / BOTS.length + 5 * i + f + 10) * BOTS.length / 4);
  1893. BOTS[i].world.move(x, y);
  1894. } else {
  1895. x = pos.x + (Math.cos(1.1 * Math.PI * 2 / BOTS.length + 5 * i + f + 10) * BOTS.length / 4);
  1896. y = pos.y + (Math.sin(1.1 * Math.PI * 2 / BOTS.length + 5 * i + f) * BOTS.length / 4);
  1897. BOTS[i].world.move(x, y);
  1898. }
  1899. } else if (Master.Animation == "threed") {
  1900. if (i >= BOTS.length / 2) {
  1901. y = pos.y + Math.cos(2 * Math.PI / BOTS * i + f) * 40;
  1902. x = pos.x + Math.sin(2 * Math.PI * 2 / BOTS * i + f) * 40;
  1903. BOTS[i].world.move(x, y);
  1904. } else {
  1905. x = pos.x + (Math.cos(2 * Math.PI * 4 / 4.09 * i + f * 2.5) * 9); // 4.09, 4.09
  1906. y = pos.y + (Math.sin(2 * Math.PI * 2 / 4.09 * i + f) * 9); // 4.09, 4.09
  1907. BOTS[i].world.move(x, y);
  1908. }
  1909. } else if (Master.Animation == "flower") {
  1910. if (state === 1) {
  1911. radius121 -= 0.1;
  1912. localStorage.buxxed_followint - 1;
  1913. if (radius121 <= 1) {
  1914. state = 2
  1915. }
  1916. } else {
  1917. radius121 += 0.2;
  1918. localStorage.buxxed_followint + 2;
  1919. if (radius121 >= 10) {
  1920. state = 1
  1921. }
  1922. }
  1923. if (state == 2) {
  1924. x = pos.x + (Math.cos(2 * Math.PI * 2 / BOTS.length * i + f) * radius121);
  1925. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i + f) * radius121);
  1926. } else {
  1927. x = pos.x + (Math.cos(2 * Math.PI * 2 / BOTS.length * i - f) * radius121);
  1928. y = pos.y + (Math.sin(2 * Math.PI * 2 / BOTS.length * i - f) * radius121);
  1929. }
  1930. BOTS[i].world.move(x, y);
  1931. } else if (Master.Animation == "square") {
  1932. a = spiral.PI2 / BOTS[i].length * i + f;
  1933. x = pos.x + squareX(f / 40 * i + f) * BOTS.length / 1.285;
  1934. y = pos.y + squareY(f / 40 * i + f) * BOTS.length / 1.285;
  1935.  
  1936. BOTS[i].world.move(x, y);
  1937. } else if (Master.Animation == "infinity") {
  1938. a = spiral.PI2 / BOTS[i].length * i + f;
  1939. x = pos.x + infinityX(f / 20 * i + f) * 40;
  1940. y = pos.y + infinityY(f / 20 * i + f) * 40;
  1941.  
  1942. BOTS[i].world.move(x, y);
  1943. } else if (Master.Animation == "infinity2") {
  1944. a = spiral.PI2 / BOTS[i].length * i + f;
  1945. x = pos.x + infinityX(f / 20 * i + f) * 40;
  1946. y = pos.y + infinityY(f / 20 * i + f) * 40;
  1947. BOTS[i].world.move(x, y);
  1948. } else if (Master.Animation == "default2") {
  1949. let x1;
  1950. let y1;
  1951. let x;
  1952. let y;
  1953. if (i >= BOTS.length / 2) {
  1954. x1 = pos.x + (Math.cos(2 * Math.PI * 2 / (BOTS.length / 2) * i) * (BOTS.length / 2));
  1955. y1 = pos.y + (Math.sin(2 * Math.PI * 2 / (BOTS.length / 2) * i) * (BOTS.length / 2));
  1956. x = x1 + (Math.cos(2 * Math.PI * 2 / 4 * i + f) * 4);
  1957. y = y1 + (Math.sin(2 * Math.PI * 2 / 4 * i + f) * 4);
  1958. BOTS[i].world.move(x, y);
  1959. } else {
  1960. x = pos.x + (Math.cos(2 * Math.PI * 2 / (BOTS.length / 2) * i) * (BOTS.length / 2));
  1961. y = pos.y + (Math.sin(2 * Math.PI * 2 / (BOTS.length / 2) * i) * (BOTS.length / 2));
  1962. BOTS[i].world.move(x, y);
  1963. }
  1964. } else if (Master.Animation == "saturn") {
  1965. let t = 2 * Math.PI * 2 / BOTS.length * i + f1;
  1966. if (i <= BOTS.length / 2) {
  1967. let x = pos.x + (Math.cos(t + 2) * BOTS.length / (BOTS.length / 10))
  1968. let y = pos.y + (Math.sin(t) * BOTS.length / (BOTS.length / 10));
  1969. BOTS[i].world.move(x, y);
  1970. } else {
  1971. let x = pos.x + (Math.cos(t) * BOTS.length / (BOTS.length / 10))
  1972. let y = pos.y + (Math.sin(t) * BOTS.length / (BOTS.length / 10));
  1973. BOTS[i].world.move(x, y);
  1974. }
  1975. } else if (Master.Animation == "disk3") {
  1976. let t = Math.PI * 2 / BOTS.length * i + f;
  1977. let t1 = Math.PI / BOTS.length * i + f;
  1978. x = pos.x + (2 * Math.sin(t) + Math.sin(2 * t1)) * BOTS.length / 2;
  1979. y = pos.y + (2 * Math.cos(t) - Math.cos(2 * t1)) * BOTS.length / 2;
  1980. BOTS[i].world.move(x, y);
  1981. } else if (Master.Animation == "triagle") {
  1982. let t = Math.PI * 2 / BOTS.length * i + f;
  1983. x = pos.x + (2 * Math.sin(t) + Math.sin(2 * (t))) * BOTS.length / 2;
  1984. y = pos.y + (2 * Math.cos(t) - Math.cos(2 * (t))) * BOTS.length / 2;
  1985. BOTS[i].world.move(x, y);
  1986. } else if (Master.Animation == "storm") {
  1987. let t = Math.PI * 2 / BOTS.length * i - f;
  1988. let t1 = Math.PI * 3 / BOTS.length * i + f;
  1989. x1 = pos.x + (Math.cos(2 * t) * BOTS.length);
  1990. y1 = pos.y + (Math.sin(2 * t) * BOTS.length);
  1991. x = x1 + (Math.cos(3 * t) * BOTS.length);
  1992. y = y1 + (Math.sin(3 * t) * BOTS.length);
  1993. BOTS[i].world.move(x, y);
  1994. } else if (Master.Animation == "disk4") {
  1995. y = pos.y + 40 * Math.cos(angle + f);
  1996. x = pos.x + 40 * Math.sin(angle);
  1997. BOTS[i].world.move(x, y);
  1998. } else if (Master.Animation == "nazi") {
  1999. let t = Math.PI * 2 / BOTS.length * i + f;
  2000. if(i == 1){
  2001. x = pos.x + 5;
  2002. y = pos.y + 1;
  2003. }else if(i == 2) {
  2004. x = pos.x + 4;
  2005. y = pos.y + 1;
  2006. }else if(i == 3) {
  2007. x = pos.x + 3;
  2008. y = pos.y + 1;
  2009. }else if(i == 4) {
  2010. x = pos.x + 3;
  2011. y = pos.y + 2;
  2012. }else if(i == 5) {
  2013. x = pos.x + 3;
  2014. y = pos.y + 3;
  2015. }else if(i == 6) {
  2016. x = pos.x + 3;
  2017. y = pos.y + 4;
  2018. }else if(i == 7) {
  2019. x = pos.x + 3;
  2020. y = pos.y + 5;
  2021. }else if(i == 8) {
  2022. x = pos.x + 1;
  2023. y = pos.y + 1;
  2024. }else if(i == 9) {
  2025. x = pos.x + 1;
  2026. y = pos.y + 2;
  2027. }else if(i == 10) {
  2028. x = pos.x + 1;
  2029. y = pos.y + 3;
  2030. }else if(i == 11) {
  2031. x = pos.x + 2;
  2032. y = pos.y + 3;
  2033. }else if(i == 12) {
  2034. x = pos.x + 4;
  2035. y = pos.y + 3;
  2036. }else if(i == 13) {
  2037. x = pos.x + 5;
  2038. y = pos.y + 3;
  2039. }else if(i == 14) {
  2040. x = pos.x + 5;
  2041. y = pos.y + 4;
  2042. }else if(i == 15) {
  2043. x = pos.x + 5;
  2044. y = pos.y + 5;
  2045. }else if(i == 16) {
  2046. x = pos.x + 1;
  2047. y = pos.y + 5;
  2048. }else if(i == 17) {
  2049. x = pos.x + 2;
  2050. y = pos.y + 5;
  2051. }else if(i == 18) {
  2052. x = pos.x + 3;
  2053. y = pos.y + 5;
  2054. }else{
  2055. let t = Math.PI * 2 / (BOTS.length - 18) * (i-18) + f;
  2056. x = pos.x + 3 + (Math.cos(t) * ((BOTS.length - 18) * 1));
  2057. y = pos.y + 3 + (Math.sin(t) * ((BOTS.length - 18) * 1));
  2058. BOTS[i].world.move(x, y);
  2059. }
  2060. }
  2061. if(Master.Animation == "nazi"){
  2062. BOTS[i].world.setTool(10);
  2063. } else {
  2064. BOTS[i].world.setTool(OWOP.player.toolId);
  2065. };
  2066. };
  2067. if(Master.Animation == "infinity") {
  2068. FOLLOWADD = PI2 / 100;
  2069. f = (f + FOLLOWADD);
  2070. } else if(Master.Animation == "infinity2") {
  2071. FOLLOWADD = PI2 / 95;
  2072. f = (f + FOLLOWADD);
  2073. } else if(Master.Animation == "eight") {
  2074. FOLLOWADD = PI2 / 500;
  2075. f = (f + FOLLOWADD) % PI2;
  2076. } else {
  2077. FOLLOWADD = PI2 / 45;
  2078. f = (f + FOLLOWADD) % PI2;
  2079. }
  2080. }, 79);
  2081. } else {
  2082. clearInterval(folint);
  2083. };
  2084. };
  2085. document.getElementById("master-main-content-paintfollowenabler").onchange = () => {
  2086. Master.PaintFollow = document.getElementById("master-main-content-paintfollowenabler").checked;
  2087. localStorage.MasterClient = JSON.stringify(Master);
  2088. };
  2089. document.getElementById("master-proxy-content-refresh").addEventListener("click", () => {
  2090. for(let i in Master.ProxyPasswords.split(",")) {
  2091. document.getElementById("master-proxy-"+Master.ProxyPasswords[i]).style.display = "none";
  2092. };
  2093. updateServers();
  2094. });
  2095. document.getElementById("master-proxy-content-add").addEventListener("click", () => {
  2096. let pr = document.getElementById("master-proxy-content-addproxy").value;
  2097. Master.ProxyPasswords += ","+pr;
  2098. localStorage.MasterClient = JSON.stringify(Master);
  2099. });
  2100. document.getElementById("master-proxy-content-delall").addEventListener("click", () => {
  2101. Master.ProxyPasswords = [];
  2102. localStorage.MasterClient = JSON.stringify(Master);
  2103. updateServers();
  2104. });
  2105. document.getElementById("master-main-content-botcount").onchange = () => {
  2106. Master.BotCount = parseInt(document.getElementById("master-main-content-botcount").value);
  2107. localStorage.MasterClient = JSON.stringify(Master);
  2108. };
  2109. document.getElementById("master-settings-content-loadaddon").addEventListener("click", () => {
  2110. let xhttpt = new XMLHttpRequest();
  2111. xhttpt.open("GET", `https://raw.githubusercontent.com/scar17off/OCM/main/packages/masterbot/addons/${document.getElementById("master-settings-content-addonlist").innerText.toString().replace(" ", "-").toLowerCase()}.js`);
  2112. xhttpt.responseType = "text";
  2113. xhttpt.addEventListener("load", function() {
  2114. eval(xhttpt.response);
  2115. });
  2116. xhttpt.send();
  2117. });
  2118. document.getElementById("master-main-content-connect").addEventListener("click", () => {
  2119. for(let connected = 0; connected < Master.BotCount; connected++){
  2120. let bot = new OJS.Client({
  2121. origin: location.href.split("?#")[0],
  2122. ws: OWOP.options.serverAddress[0].url,
  2123. reconnect: Master.AutoReconnect || false,
  2124. world: location.href.split("#")[1],
  2125. reconnectTime: Master.ReconnectTime || 250,
  2126. index: botlist.length + 1
  2127. });
  2128.  
  2129. botlist.push(bot);
  2130.  
  2131. bot.on("join", () => {
  2132. BOTS.push(bot);
  2133. let device;
  2134. if(bot.clientOptions.proxy) {device = "📡";} else {device = '🖥️';};
  2135. let color = rgbtohex(bot.player.color[0], bot.player.color[1], bot.player.color[2]);
  2136. let bottable = document.createElement("tr");
  2137. bottable.innerHTML = `<td id="master-bots-content-list-bot-${bot.player.id}-index">${bot.clientOptions.index}</td><td id="master-bots-content-list-bot-${bot.player.id}-id">`+bot.player.id+`</td><td id="master-bots-content-list-bot-${bot.player.id}-x">`+bot.player.x+`</td><td id="master-bots-content-list-bot-${bot.player.id}-y">`+bot.player.y+`</td><td id="master-bots-content-list-bot-${bot.player.id}-pq">`+bot.net.bucket.allowance+`</td><td id="master-bots-content-list-bot-${bot.player.id}-color" style="font-size: 20px;color: ${color}" title="${color} | R: ${bot.player.color[0]} G: ${bot.player.color[1]} B: ${bot.player.color[2]}">■</td><td id="master-bots-content-list-bot-${bot.player.id}-device" title="${bot.clientOptions.proxy || ""}">`+device+'</td>'+`<button id="master-bots-content-list-bot-${bot.player.id}-leave">❌</button>`+'';
  2138. bottable.id = `master-bots-content-list-bot-${bot.player.id}`;
  2139. for(let i = 0; i < BOTS.length; i++){
  2140. if(BOTS[i].player.id === bot.player.id) {
  2141. document.getElementById("master-bots-content-list").appendChild(bottable);
  2142. document.getElementById(`master-bots-content-list-bot-${bot.player.id}-leave`).addEventListener("click", () => {
  2143. bot.net.ws.close();
  2144. document.getElementById(`master-bots-content-list-bot-${bot.player.id}`).style.display = "none";;
  2145. for(let i = 0; i < BOTS.length; i++){
  2146. if(BOTS[i].player.id === bot.player.id) {
  2147. BOTS.splice(i, 1);
  2148. };
  2149. };
  2150. });
  2151. };
  2152. };
  2153. if(bot.options.proxy) document.getElementById(`master-proxy-content-proxyconns-${bot.options.proxy}`).innerText = parseInt(document.getElementById(`master-proxy-content-proxyconns-${bot.options.proxy}`).innerText) + 1;
  2154. if(Master.AutoLogin == true){
  2155. if(localStorage.adminlogin) {
  2156. let cmd = "adminlogin";
  2157. let adminlogin = localStorage.adminlogin || "How_Did_Danix_Get_The_Adminlogin?";
  2158. if(location.host = "ourworldofpixels.com") cmd = "pass";
  2159. bot.chat.send(`/${cmd} ${adminlogin}`);
  2160. };
  2161. };
  2162. if(Master.AutoPassword == true) {
  2163. if(AutoPassword && JSON.parse(localStorage.worldPasswords)[location.href.split("?#")[0]]) bot.chat.send(`/pass ${JSON.parse(localStorage.worldPasswords)[location.href.split("?#")[0]]}`);
  2164. };
  2165. if(Master.AutoNickname == true) {
  2166. bot.chat.send(`/nickname ${Master.BotNickname}`);
  2167. };
  2168. });
  2169.  
  2170. bot.on("close", () => {
  2171. for(let i = 0; i < BOTS.length; i++){
  2172. if(BOTS[i].player.id === bot.player.id) {
  2173. clearInterval(BOTS[i].interval);
  2174. BOTS.splice(i, 1);
  2175. };
  2176. };
  2177. if(Master.AutoReconnect == false && Master.SmartAutoReconnect == true) {
  2178. bot.world.join(location.href.split("?#")[1]);
  2179. };
  2180. });
  2181. };
  2182. });
  2183. document.getElementById("master-main-content-send").addEventListener("click", () => {
  2184. for(let i in BOTS) BOTS[i].chat.send(document.getElementById("master-main-content-message").value);
  2185. });
  2186. document.getElementById("master-main-content-followlist").onchange = () => {
  2187. let val = document.getElementById("master-main-content-followlist").value;
  2188. if (val === "Circle") Master.Animation = "circle";
  2189. else if (val === "Disk") Master.Animation = "disk";
  2190. else if (val === "Atom") Master.Animation = "atom";
  2191. else if (val === "Random") Master.Animation = "random";
  2192. else if (val === "Wave") Master.Animation = "wave";
  2193. else if (val === "Right-Left") Master.Animation = "line";
  2194. else if (val === "Hyperbola") Master.Animation = "hyperbola";
  2195. else if (val === "BotLine") Master.Animation = "botline";
  2196. else if (val === "X") Master.Animation = "x";
  2197. else if (val === "Spiral") Master.Animation = "spiral";
  2198. else if (val === "Cool") Master.Animation = "cool";
  2199. else if (val === "Disk 2") Master.Animation = "disktwo";
  2200. else if (val === "Top-Bottom") Master.Animation = "topbottom";
  2201. else if (val === "Laggy") Master.Animation = "laggy";
  2202. else if (val === "Small Circle") Master.Animation = "smallcircle";
  2203. else if (val === "8") Master.Animation = "eight";
  2204. else if (val === "Cool 2") Master.Animation = "cool2";
  2205. else if (val === "3D") Master.Animation = "threed";
  2206. else if (val === "Flower") Master.Animation = "flower";
  2207. else if (val === "Infinity") Master.Animation = "infinity";
  2208. else if (val === "Infinity 2") Master.Animation = "infinity2";
  2209. else if (val === "Square") Master.Animation = "square";
  2210. else if (val === "Default 2") Master.Animation = "default2";
  2211. else if (val === "Disk 3") Master.Animation = "disk3";
  2212. else if (val === "Triagle") Master.Animation = "triagle";
  2213. else if (val === "Saturn") Master.Animation = "saturn";
  2214. else if (val === "Storm") Master.Animation = "storm";
  2215. else if (val === "Disk 4") Master.Animation = "disk4";
  2216. else if (val === "Nazi") Master.Animation = "nazi";
  2217. localStorage.MasterClient = JSON.stringify(Master);
  2218. };
  2219. document.getElementById("master-main-content-eraserpattern").onchange = () => {
  2220. let val = document.getElementById("master-main-content-eraserpattern").value;
  2221. if(val === "Default") Master.EraserPattern = val.replace(" - ", "");
  2222. if(val === "Top - Bottom") Master.EraserPattern = val.replace(" - ", "");
  2223. if(val === "Perfect") Master.EraserPattern = val.replace(" - ", "");
  2224. if(val === "Circle") Master.EraserPattern = val.replace(" - ", "");
  2225. Master.EraserPattern = val.replace(" - ", "");
  2226. localStorage.MasterClient = JSON.stringify(Master);
  2227. };
  2228. document.getElementById("master-main-content-areapattern").onchange = () => {
  2229. let val = document.getElementById("master-main-content-areapattern").value;
  2230. if(val === "Default") Master.AreaPattern = val.replace(" - ", "");
  2231. if(val === "Top - Bottom") Master.AreaPattern = val.replace(" - ", "");
  2232. if(val === "Random") Master.AreaPattern = val.replace(" - ", "");
  2233. Master.AreaPattern = val.replace(" - ", "");
  2234. localStorage.MasterClient = JSON.stringify(Master);
  2235. };
  2236. document.getElementById("master-main-content-assetpasterpattern").onchange = () => {
  2237. let val = document.getElementById("master-main-content-assetpasterpattern").value;
  2238. if(val == "Default") Master.AssetPasterPattern = val.replace(" - ", "");
  2239. if(val == "Left - Up") Master.AssetPasterPattern = val.replace(" - ", "");
  2240. if(val == "Grid") Master.AssetPasterPattern = val.replace(" - ", "");
  2241. if(val == "Square") Master.AssetPasterPattern = val.replace(" - ", "");
  2242. if(val == "Random") Master.AssetPasterPattern = val.replace(" - ", "");
  2243. Master.AssetPasterPattern = val.replace(" - ", "");
  2244. localStorage.MasterClient = JSON.stringify(Master);
  2245. };
  2246. document.getElementById("master-main-content-disconnect").addEventListener("click", () => {
  2247. for(let i in BOTS) {
  2248. if(!Master.NoBots) {
  2249. if(BOTS[i].net.ws.readyState === 1) {
  2250. BOTS[i].net.ws.close();
  2251. document.getElementById(`master-bots-content-list-bot-${BOTS[i].player.id}`).style.display = "none";
  2252. };
  2253. } else {
  2254. if(BOTS[i].net.ws.readyState === 1) {
  2255. BOTS[i].net.ws.close();
  2256. };
  2257. };
  2258. };
  2259. BOTS = [];
  2260. });
  2261. document.getElementById("master-settings-content-nohelpbtn").onchange = () => {
  2262. let vis = document.getElementById("master-settings-content-nohelpbtn").checked;
  2263.  
  2264. if(vis == true) document.getElementById("help-button").style.visibility = "hidden";
  2265. if(vis == false) document.getElementById("help-button").style.visibility = "visible";
  2266. Master.NoHelp = document.getElementById("master-settings-content-nohelpbtn").checked;
  2267. localStorage.MasterClient = JSON.stringify(Master);
  2268. };
  2269. document.getElementById("master-settings-content-noarcbtn").onchange = () => {
  2270. let vis = document.getElementById("master-settings-content-noarcbtn").checked;
  2271.  
  2272. try {
  2273. if(vis == true) document.getElementById("launcher").style.visibility = "hidden";
  2274. if(vis == false) document.getElementById("launcher").style.visibility = "visible";
  2275. } catch {};
  2276. Master.NoArc = document.getElementById("master-settings-content-noarcbtn").checked;
  2277. localStorage.MasterClient = JSON.stringify(Master);
  2278. };
  2279. document.getElementById("master-main-content-autologin").onchange = () => {
  2280. Master.AutoLogin = document.getElementById("master-main-content-autologin").checked;
  2281. localStorage.MasterClient = JSON.stringify(Master);
  2282. };
  2283. let oldWindowsStyle = document.getElementById("windows").style;
  2284. document.getElementById("master-settings-content-novignette").onchange = () => {
  2285. let vis = document.getElementById("master-settings-content-novignette").checked;
  2286.  
  2287. if(vis == true) {
  2288. document.getElementById("palette-bg").style.visibility = "hidden";
  2289. document.getElementById("windows").style = oldWindowsStyle;
  2290. };
  2291. if(vis == false) {
  2292. document.getElementById("palette-bg").style.visibility = "visible";
  2293. document.getElementById("windows").style = "box-shadow: inset 0 0 100px #000";
  2294. };
  2295. Master.NoVignette = document.getElementById("master-settings-content-novignette").checked;
  2296. localStorage.MasterClient = JSON.stringify(Master);
  2297. };
  2298. document.getElementById("master-main-content-autopassword").onchange = () => {
  2299. Master.AutoPassword = document.getElementById("master-main-content-autopassword").checked;
  2300. localStorage.MasterClient = JSON.stringify(Master);
  2301. };
  2302. document.getElementById("master-main-content-autonickname").onchange = () => {
  2303. Master.AutoNickname = document.getElementById("master-main-content-autonickname").checked;
  2304. localStorage.MasterClient = JSON.stringify(Master);
  2305. };
  2306. document.getElementById("master-main-content-useplayer").onchange = () => {
  2307. Master.UsePlayer = document.getElementById("master-main-content-useplayer").checked;
  2308. localStorage.MasterClient = JSON.stringify(Master);
  2309. };
  2310. document.getElementById("master-settings-content-proxies").onchange = () => {
  2311. Master.ProxyPasswords = document.getElementById("master-settings-content-proxies").value;
  2312. localStorage.MasterClient = JSON.stringify(Master);
  2313. };
  2314. document.getElementById("master-settings-content-reconnecttime").onchange = () => {
  2315. Master.ReconnectTime = document.getElementById("master-settings-content-reconnecttime").value;
  2316. localStorage.MasterClient = JSON.stringify(Master);
  2317. };
  2318. let styleblock = document.createElement("style");
  2319. document.body.appendChild(styleblock);
  2320. document.getElementById("master-settings-content-toolset").onchange = () => {
  2321. style.innerHTML = `
  2322. <style>
  2323. button[id^="tool-"]:not(.selected) > div {
  2324. background-image: url("https://github.com/scar17off/OCM/blob/main/packages/masterbot/toolsets/${document.getElementById("master-settings-content-toolset").value.toString().toLowerCase().replace(" ", "-")}.png?raw=true") !important;
  2325. background-color: rgba(69, 69, 69, 1);
  2326. }
  2327. </style>
  2328. `;
  2329. };
  2330. document.getElementById("master-settings-content-botnickname").onchange = () => {
  2331. Master.BotNickname = document.getElementById("master-settings-content-botnickname").value;
  2332. localStorage.MasterClient = JSON.stringify(Master);
  2333. };
  2334. document.getElementById("master-settings-content-configrupdrate").onchange = () => {
  2335. Master.ConfigUpdateRate = document.getElementById("master-settings-content-configrupdrate").value;
  2336. localStorage.MasterClient = JSON.stringify(Master);
  2337. };
  2338. document.getElementById("master-settings-content-botsupdrate").onchange = () => {
  2339. Master.ConfigUpdateRate = document.getElementById("master-settings-content-botsupdrate").value;
  2340. localStorage.MasterClient = JSON.stringify(Master);
  2341. };
  2342. document.getElementById("master-main-content-smartautoreconnect").onchange = () => {
  2343. Master.SmartAutoReconnect = document.getElementById("master-main-content-smartautoreconnect").checked;
  2344. localStorage.MasterClient = JSON.stringify(Master);
  2345. };
  2346. document.getElementById("master-main-content-autoreconnect").onchange = () => {
  2347. Master.AutoReconnect = document.getElementById("master-main-content-autoreconnect").checked;
  2348. localStorage.MasterClient = JSON.stringify(Master);
  2349. };
  2350. document.getElementById("master-settings-content-nobots").onchange = () => {
  2351. Master.NoBots = document.getElementById("master-settings-content-nobots").checked;
  2352. localStorage.MasterClient = JSON.stringify(Master);
  2353. };
  2354. document.getElementById("master-settings-content-bigchat").onchange = () => {
  2355. Master.BigChat = document.getElementById("master-settings-content-bigchat").checked;
  2356. localStorage.MasterClient = JSON.stringify(Master);
  2357. if(document.getElementById("chat").style.width == ""){
  2358. document.getElementById("chat").style.width = "inherit";
  2359. } else {
  2360. document.getElementById("chat").style.width = "";
  2361. };
  2362. };
  2363. document.getElementById("master-settings-content-chat").onchange = () => {
  2364. Master.Chat = document.getElementById("master-settings-content-chat").checked;
  2365. localStorage.MasterClient = JSON.stringify(Master);
  2366. if(!Master.Chat && window.MasterBot.socket.readyState === 1) {
  2367. window.MasterBot.socket.close();
  2368. } else {
  2369. reconn();
  2370. };
  2371. };
  2372. document.getElementById("master-tabbar-main").addEventListener("click", () => {
  2373. document.getElementById("master-main-content").hidden = true;
  2374. document.getElementById("master-bots-content").hidden = true;
  2375. document.getElementById("master-proxy-content").hidden = true;
  2376. document.getElementById("master-settings-content").hidden = true;
  2377.  
  2378. document.getElementById("master-main-content").hidden = false;
  2379.  
  2380. document.getElementById("master-tabbar-main").style["background-color"] = "#3b3b3b";
  2381. document.getElementById("master-tabbar-bots").style["background-color"] = "#535353";
  2382. document.getElementById("master-tabbar-proxy").style["background-color"] = "#535353";
  2383. document.getElementById("master-tabbar-settings").style["background-color"] = "#535353";
  2384. });
  2385. document.getElementById("master-tabbar-bots").addEventListener("click", () => {
  2386. document.getElementById("master-main-content").hidden = true;
  2387. document.getElementById("master-bots-content").hidden = true;
  2388. document.getElementById("master-proxy-content").hidden = true;
  2389. document.getElementById("master-settings-content").hidden = true;
  2390.  
  2391. document.getElementById("master-bots-content").hidden = false;
  2392. document.getElementById("master-tabbar-bots").style["background-color"] = "#3b3b3b";
  2393. document.getElementById("master-tabbar-main").style["background-color"] = "#535353";
  2394. document.getElementById("master-tabbar-proxy").style["background-color"] = "#535353";
  2395. document.getElementById("master-tabbar-settings").style["background-color"] = "#535353";
  2396. });
  2397. document.getElementById("master-tabbar-proxy").addEventListener("click", () => {
  2398. document.getElementById("master-main-content").hidden = true;
  2399. document.getElementById("master-bots-content").hidden = true;
  2400. document.getElementById("master-proxy-content").hidden = true;
  2401. document.getElementById("master-settings-content").hidden = true;
  2402.  
  2403. document.getElementById("master-proxy-content").hidden = false;
  2404. document.getElementById("master-tabbar-proxy").style["background-color"] = "#3b3b3b";
  2405. document.getElementById("master-tabbar-bots").style["background-color"] = "#535353";
  2406. document.getElementById("master-tabbar-main").style["background-color"] = "#535353";
  2407. document.getElementById("master-tabbar-settings").style["background-color"] = "#535353";
  2408. });
  2409. document.getElementById("master-tabbar-settings").addEventListener("click", () => {
  2410. document.getElementById("master-main-content").hidden = true;
  2411. document.getElementById("master-bots-content").hidden = true;
  2412. document.getElementById("master-proxy-content").hidden = true;
  2413. document.getElementById("master-settings-content").hidden = true;
  2414.  
  2415. document.getElementById("master-settings-content").hidden = false;
  2416. document.getElementById("master-tabbar-settings").style["background-color"] = "#3b3b3b";
  2417. document.getElementById("master-tabbar-bots").style["background-color"] = "#535353";
  2418. document.getElementById("master-tabbar-proxy").style["background-color"] = "#535353";
  2419. document.getElementById("master-tabbar-main").style["background-color"] = "#535353";
  2420. });
  2421. // Tools
  2422. setTimeout(() => {
  2423. let LastChunk = Date.now();
  2424. let lastChunk;
  2425. OWOP.world.protection = {
  2426. intervals: {},
  2427. pixels: {}
  2428. };
  2429. OWOP.tools.addToolObject(new OWOP.tools.class("Bot Fill", OWOP.cursors.fill, OWOP.fx.player.NONE, OWOP.RANK.USER, e => {
  2430. e.extra.tickAmount = 30;
  2431. let t = [],
  2432. n = null,
  2433. o = OWOP.fx.player.RECT_SELECT_ALIGNED(1);
  2434. async function r() {
  2435. var o = function(e, t) {
  2436. return e && t && e[0] === t[0] && e[1] === t[1] && e[2] === t[2]
  2437. },
  2438. r = function(e, r) {
  2439. return !!o(OWOP.world.getPixel(e, r), n) && (t.unshift([e, r]),
  2440. !0)
  2441. };
  2442. if (t.length && n) {
  2443. var i = OWOP.player.selectedColor,
  2444. a = 0,
  2445. s = e.extra.tickAmount;
  2446. s *= 3;
  2447. for (a = 0; a < s && t.length; a++) {
  2448. var l = t.pop(),
  2449. u = l[0],
  2450. d = l[1],
  2451. f = OWOP.world.getPixel(u, d);
  2452. if (o(f, n) && !o(f, i)) {
  2453. if (!OWOP.world.setPixel(u, d, i)) {
  2454. let abc = getFree();
  2455. if (BOTS.length !== 0 && BOTS[abc].net.bucket.allowance === 0) sleep(42).then(i => {
  2456. if (!BOTS[abc].world.setPixel(u, d, i)) t.push(l);
  2457. });
  2458. if (BOTS.length !== 0 && BOTS[abc].net.bucket.allowance !== 0)
  2459. if (!BOTS[abc].world.setPixel(u, d, i)) t.push(l);
  2460. break
  2461. }
  2462. var p = r(u, d - 1),
  2463. m = r(u, d + 1),
  2464. v = r(u - 1, d),
  2465. g = r(u + 1, d);
  2466. p && v && r(u - 1, d - 1),
  2467. p && g && r(u + 1, d - 1),
  2468. m && v && r(u - 1, d + 1),
  2469. m && g && r(u + 1, d + 1)
  2470. }
  2471. }
  2472. }
  2473. }
  2474. e.setFxRenderer(function(e, r, i) {
  2475. r.globalAlpha = .8,
  2476. r.strokeStyle = e.extra.player.htmlRgb;
  2477. var a = OWOP.camera.zoom;
  2478. if (n && e.extra.isLocalPlayer) {
  2479. r.beginPath();
  2480. for (var s = 0; s < t.length; s++)
  2481. r.rect((t[s][0] - OWOP.camera.x) * a, (t[s][1] - OWOP.camera.y) * a, a, a);
  2482. r.stroke()
  2483. } else
  2484. o(e, r, i)
  2485. }),
  2486. e.setEvent("mousedown", function(o) {
  2487. 4 & o.buttons || (n = OWOP.world.getPixel(o.tileX, o.tileY)) && (t.push([o.tileX, o.tileY]),
  2488. e.setEvent("tick", r))
  2489. }),
  2490. e.setEvent("mouseup deselect", function(o) {
  2491. o && 1 & o.buttons || (n = null,
  2492. t = [],
  2493. e.setEvent("tick", null))
  2494. });
  2495.  
  2496. }));
  2497. let aboab;
  2498. OWOP.tools.addToolObject(new OWOP.tools.class('Bot Area', OWOP.cursors.select, OWOP.fx.player.NONE, false, function(tool) {
  2499. tool.setFxRenderer(function(fx, ctx, time) {
  2500. if (!fx.extra.isLocalPlayer) return 1;
  2501. let x = fx.extra.player.x;
  2502. let y = fx.extra.player.y;
  2503. let fxx = (Math.floor(x / 16) - OWOP.camera.x) * OWOP.camera.zoom;
  2504. let fxy = (Math.floor(y / 16) - OWOP.camera.y) * OWOP.camera.zoom;
  2505. let oldlinew = ctx.lineWidth;
  2506. ctx.lineWidth = 1;
  2507. if (tool.extra.end) {
  2508. let s = tool.extra.start;
  2509. let e = tool.extra.end;
  2510. let x = (s[0] - OWOP.camera.x) * OWOP.camera.zoom + 0.5;
  2511. let y = (s[1] - OWOP.camera.y) * OWOP.camera.zoom + 0.5;
  2512. let w = e[0] - s[0];
  2513. let h = e[1] - s[1];
  2514. ctx.beginPath();
  2515. ctx.rect(x, y, w * OWOP.camera.zoom, h * OWOP.camera.zoom);
  2516. ctx.globalAlpha = 0.25;
  2517. ctx.strokeStyle = "#FFFFFF";
  2518. ctx.stroke();
  2519. ctx.setLineDash([3, 4]);
  2520. ctx.strokeStyle = "#000000";
  2521. ctx.stroke();
  2522. //ctx.globalAlpha = 0.25 + Math.sin(time / 500) / 4;
  2523. ctx.fillStyle = OWOP.renderer.patterns.unloaded;
  2524. ctx.fill();
  2525. ctx.setLineDash([]);
  2526. let oldfont = ctx.font;
  2527. ctx.font = "16px sans-serif";
  2528. let perc = 2;
  2529. if (perc > 100) perc = 100;
  2530. let txt = tool.extra.clicking ? 'Right click to start pixeling.' : '';
  2531. let txtx = window.innerWidth >> 1;
  2532. let txty = window.innerHeight >> 1;
  2533. txtx = Math.max(x, Math.min(txtx, x + w * OWOP.camera.zoom));
  2534. txty = Math.max(y, Math.min(txty, y + h * OWOP.camera.zoom));
  2535. OWOP.drawText = (ctx, str, x, y, centered) => {
  2536. ctx.strokeStyle = "#000000", ctx.fillStyle = "#FFFFFF", ctx.lineWidth = 2.5, ctx.globalAlpha = 1;
  2537. if (centered) {
  2538. x -= ctx.measureText(str).width >> 1;
  2539. }
  2540. ctx.strokeText(str, x, y);
  2541. ctx.globalAlpha = 1;
  2542. ctx.fillText(str, x, y);
  2543. };
  2544. OWOP.drawText(ctx, txt, txtx, txty, true);
  2545. ctx.font = oldfont;
  2546. ctx.lineWidth = oldlinew;
  2547. return 0;
  2548. } else {
  2549. ctx.beginPath();
  2550. ctx.moveTo(0, fxy + 0.5);
  2551. ctx.lineTo(window.innerWidth, fxy + 0.5);
  2552. ctx.moveTo(fxx + 0.5, 0);
  2553. ctx.lineTo(fxx + 0.5, window.innerHeight);
  2554.  
  2555. //ctx.lineWidth = 1;
  2556. ctx.globalAlpha = 0.8;
  2557. ctx.strokeStyle = "#FFFFFF";
  2558. ctx.stroke();
  2559. ctx.setLineDash([3]);
  2560. ctx.strokeStyle = "#000000";
  2561. ctx.stroke();
  2562.  
  2563. ctx.setLineDash([]);
  2564. ctx.lineWidth = oldlinew;
  2565. return 1;
  2566. }
  2567. });
  2568.  
  2569. tool.extra.start = null;
  2570. tool.extra.end = null;
  2571. tool.extra.clicking = false;
  2572.  
  2573. tool.setEvent('mousedown', async (mouse, event) => {
  2574.  
  2575. let s = tool.extra.start;
  2576. let e = tool.extra.end;
  2577. let isInside = function isInside() {
  2578. return mouse.tileX >= s[0] && mouse.tileX < e[0] && mouse.tileY >= s[1] && mouse.tileY < e[1];
  2579. };
  2580. if (mouse.buttons === 1 && !tool.extra.end) {
  2581. tool.extra.start = [Math.floor(mouse.tileX / 16) * 16, Math.floor(mouse.tileY / 16) * 16];
  2582. tool.extra.clicking = true;
  2583. tool.setEvent('mousemove', function(mouse, event) {
  2584. if (tool.extra.start && mouse.buttons === 1) {
  2585. tool.extra.end = [Math.floor(mouse.tileX / 16) * 16, Math.floor(mouse.tileY / 16) * 16];
  2586. return 1;
  2587. }
  2588. });
  2589. let finish = function finish() {
  2590. tool.setEvent('mousemove mouseup deselect', null);
  2591. tool.extra.clicking = false;
  2592. let s = tool.extra.start;
  2593. let e = tool.extra.end;
  2594. if (e) {
  2595. if (s[0] === e[0] || s[1] === e[1]) {
  2596. tool.extra.start = null;
  2597. tool.extra.end = null;
  2598. }
  2599. if (s[0] > e[0]) {
  2600. let tmp = e[0];
  2601. e[0] = s[0];
  2602. s[0] = tmp;
  2603. }
  2604. if (s[1] > e[1]) {
  2605. let tmp = e[1];
  2606. e[1] = s[1];
  2607. s[1] = tmp;
  2608. }
  2609. }
  2610. OWOP.renderer.render(OWOP.renderer.rendertype.FX);
  2611. };
  2612. tool.setEvent('deselect', finish);
  2613. tool.setEvent('mouseup', function(mouse, event) {
  2614. if (!(mouse.buttons & 1)) {
  2615. finish();
  2616. }
  2617. });
  2618. } else if (mouse.buttons === 1 && tool.extra.end) {
  2619. if (isInside()) {
  2620. let offx = mouse.tileX;
  2621. let offy = mouse.tileY;
  2622. tool.setEvent('mousemove', function(mouse, event) {
  2623. let dx = mouse.tileX - offx;
  2624. let dy = mouse.tileY - offy;
  2625. tool.extra.start = [s[0] + dx, s[1] + dy];
  2626. tool.extra.end = [e[0] + dx, e[1] + dy];
  2627. });
  2628. let end = function end() {
  2629. tool.setEvent('mouseup deselect mousemove', null);
  2630. };
  2631. tool.setEvent('deselect', end);
  2632. tool.setEvent('mouseup', function(mouse, event) {
  2633. if (!(mouse.buttons & 1)) {
  2634. end();
  2635. };
  2636. });
  2637. }
  2638. } else if (mouse.buttons === 2 && tool.extra.end && isInside()) {
  2639. if (BOTS.length === 0) {
  2640. let w = tool.extra.end[0] - tool.extra.start[0];
  2641. let h = tool.extra.end[1] - tool.extra.start[1];
  2642. for (let x = 0; x < w; x++) {
  2643. let chunkx = tool.extra.start[0];
  2644. let chunky = tool.extra.start[1];
  2645. let color = OWOP.player.selectedColor;
  2646. for (let y = 0; y < h; y++) {
  2647. OWOP.world.setPixel(chunkx + x, chunky + y, color);
  2648. }
  2649. }
  2650. }
  2651. for (let i = 0; i < BOTS.length; i++) BOTS[i].options.busy = true;
  2652. let w = tool.extra.end[0] - tool.extra.start[0];
  2653. let h = tool.extra.end[1] - tool.extra.start[1];
  2654. let color = OWOP.player.selectedColor;
  2655.  
  2656. let chunkx = tool.extra.start[0];
  2657. let chunky = tool.extra.start[1];
  2658.  
  2659. async function drawPattern() {
  2660. if(Master.AreaPattern == "Chunks"){
  2661. for (let X = w; X < x; X = X + 16) {
  2662. for (let Y = h; Y < y; Y = Y + 16) {
  2663. async function chank(X2, Y2) {
  2664. for (let X1 = 0; X1 < 16; X1++) {
  2665. for (let Y1 = 0; Y1 < 16; Y1++) {
  2666. if ((X1 + X2) < xEnd && (Y1 + Y) < yEnd) {
  2667. if (!color, OWOP.world.getPixel(X2 + X1, Y2 + Y1)) {
  2668. if (stop121) break
  2669. let abc = getFree();
  2670. if (!bots[abc].BOJS.world.setPixel(X2 + X1, Y2 + Y1, color)) {
  2671. await sleep(0);
  2672. Y1--;
  2673. }
  2674. }
  2675. }
  2676. }
  2677. }
  2678. };
  2679. chank(X, Y);
  2680. };
  2681. };
  2682. } else if (Master.AreaPattern == "Default") {
  2683. for (let x = 0; x < w; x++) {
  2684. for (let y = 0; y < h; y++) {
  2685. let abc = getFree();
  2686. if (!OldPaste) {
  2687. BOTS[abc].net.bucket.canSpend(0);
  2688. if (BOTS[abc].net.bucket.allowance <= 1) await sleep(0);
  2689. }
  2690. BOTS[abc].world.setPixel(chunkx + x, chunky + y, color);
  2691. }
  2692. }
  2693. } else if (Master.AreaPattern == "TopBottom") {
  2694. for (let y = 0; y < h; y++) {
  2695. for (let x = 0; x < w; x++) {
  2696. let abc = getFree();
  2697. if (!OldPaste) {
  2698. BOTS[abc].net.bucket.canSpend(0);
  2699. if (BOTS[abc].net.bucket.allowance <= 1) await sleep(0);
  2700. }
  2701. BOTS[abc].world.setPixel(chunkx + x, chunky + y, color);
  2702. }
  2703. }
  2704. } else if (Master.AreaPattern == "Random") {
  2705. for (let x = 0; x < w * 3; x++) {
  2706. for (let y = 0; y < h * 3; y++) {
  2707. let abc = getFree();
  2708. if (!OldPaste) {
  2709. BOTS[abc].net.bucket.canSpend(0);
  2710. if (BOTS[abc].net.bucket.allowance <= 1) await sleep(0);
  2711. }
  2712. BOTS[abc].world.setPixel(chunkx + Math.floor(Math.random() * w), chunky + Math.floor(Math.random() * h), color);
  2713. }
  2714. }
  2715. };
  2716. };
  2717.  
  2718. drawPattern();
  2719. for (let i = 0; i < BOTS.length; i++) BOTS[i].options.busy = false;
  2720. } else {
  2721. tool.extra.start = null;
  2722. tool.extra.end = null;
  2723. }
  2724. });
  2725. }));
  2726. OWOP.tools.addToolObject(new OWOP.tools.class("Master Protection 16", OWOP.cursors.shield, OWOP.fx.player.RECT_SELECT_ALIGNED(16), OWOP.RANK.USER, tool => {
  2727. tool.setFxRenderer((fx, ctx) => {
  2728. const X = fx.extra.player.x,
  2729. Y = fx.extra.player.y,
  2730. cX = (16 * Math.floor(X / 256) - OWOP.camera.x) * OWOP.camera.zoom,
  2731. cY = (16 * Math.floor(Y / 256) - OWOP.camera.y) * OWOP.camera.zoom,
  2732. tX = fx.extra.player.tileX,
  2733. tY = fx.extra.player.tileY,
  2734. chunk = OWOP.world.protection.pixels[`${tX},${tY}`];
  2735. ctx.globalAlpha = .5;
  2736. ctx.fillStyle = chunk ? "#00FF00" : "#FF0000";
  2737. ctx.fillRect(cX, cY, 16 * OWOP.camera.zoom, 16 * OWOP.camera.zoom);
  2738. return true;
  2739. });
  2740. tool.setEvent("mousedown mousemove", fx => {
  2741. const X = Math.floor(OWOP.mouse.tileX / OWOP.options.serverAddress[0].proto.chunkSize) * 16,
  2742. Y = Math.floor(OWOP.mouse.tileY / OWOP.options.serverAddress[0].proto.chunkSize) * 16,
  2743. chunk = OWOP.world.protection.pixels[`${X},${Y}`];
  2744. switch (fx.buttons) {
  2745. case 1:
  2746. if(chunk) return false;
  2747. for (let y = 0; y < 16; y++)
  2748. for (let x = 0; x < 16; x++) {
  2749. OWOP.world.protection.pixels[`${X + x},${Y + y}`] = OWOP.world.getPixel(X + x, Y + y);
  2750. OWOP.world.protection.intervals[`${X + x},${Y + y}`] = setInterval(() => {
  2751. if(!OWOP.world.setPixel(X + x, Y + y, OWOP.world.protection.pixels[`${X + x},${Y + y}`])) {
  2752. let abc = getFree();
  2753. if(BOTS[abc].net.bucket.allowance >= 1) BOTS[abc].world.setPixel(X + x, Y + y, OWOP.world.protection.pixels[`${X + x},${Y + y}`][3]);
  2754. }
  2755. }, 1);
  2756. }
  2757. return true;
  2758. break;
  2759. case 2:
  2760. if(!chunk) return false;
  2761. for (let y = 0; y < 16; y++)
  2762. for (let x = 0; x < 16; x++) {
  2763. clearInterval(OWOP.world.protection.intervals[`${X + x},${Y + y}`]);
  2764. delete OWOP.world.protection.intervals[`${X + x},${Y + y}`];
  2765. delete OWOP.world.protection.pixels[`${X + x},${Y + y}`];
  2766. }
  2767. break;
  2768. }
  2769. });
  2770. }));
  2771. OWOP.tools.addToolObject(new OWOP.tools.class("Bot Brush", OWOP.cursors.brush, OWOP.fx.player.RECT_SELECT_ALIGNED(1), OWOP.RANK.USER, tool => {
  2772. tool.setEvent("mousemove mousedown", async e => {
  2773. if (e.buttons !== 0){
  2774. for (let i = -1; i < 2; i++){
  2775. for (let j = -1; j < 2; j++){
  2776. if (!OWOP.world.setPixel(OWOP.mouse.tileX + i, OWOP.mouse.tileY + j, e.buttons === 1 ? OWOP.player.selectedColor : [255, 255, 255])) {
  2777. let abc = getFree();
  2778. if (Math.floor(BOTS[abc].net.bucket.allowance) === 1) await sleep(42);
  2779. if(BOTS.length !== 0) BOTS[abc].world.setPixel(OWOP.mouse.tileX + i, OWOP.mouse.tileY + j, e.buttons === 1 ? OWOP.player.selectedColor : [255, 255, 255]);
  2780. else OWOP.world.setPixel(OWOP.mouse.tileX + i, OWOP.mouse.tileY + j, e.buttons === 1 ? OWOP.player.selectedColor : [255, 255, 255]);
  2781. };
  2782. };
  2783. };
  2784. };
  2785. });
  2786. }));
  2787. OWOP.tools.addToolObject(new OWOP.tools.class('Master Paste', OWOP.cursors.paste, OWOP.fx.player.RECT_SELECT_ALIGNED(1), false, function(tool) {
  2788. tool.setEvent('mousedown', function(mouse, event) {
  2789. let sX = OWOP.mouse.tileX,
  2790. sY = OWOP.mouse.tileY;
  2791. if (mouse.buttons != 0) {
  2792. let input = document.createElement('input');
  2793. input.type = "file";
  2794. input.accept = 'image/*';
  2795.  
  2796. input.click();
  2797. input.onchange = () => {
  2798. sleep(15);
  2799. let imgURL = URL.createObjectURL(input.files[0]);
  2800. let img = new Image();
  2801. img.onload = async () => {
  2802. let cnv = document.createElement('canvas');
  2803. let ctx = cnv.getContext('2d');
  2804. let imgWidth = img.naturalWidth;
  2805. let imgHeight = img.naturalHeight;
  2806.  
  2807. cnv.width = 3000;
  2808. cnv.height = 3000;
  2809. if (imgWidth > 3000) return OWOP.chat.local('The width of image is too big!');
  2810. if (imgHeight > 3000) return OWOP.chat.local('The height of image is too big!');
  2811. ctx.drawImage(img, 0, 0);
  2812. let imgData = ctx.getImageData(0, 0, imgWidth, imgHeight);
  2813. let orgPixels = Array.from(imgData.data);
  2814. let i = 0;
  2815. let I = 0;
  2816. let pixels = [];
  2817. while (i <= orgPixels.length) {
  2818. pixels.push([orgPixels[i], orgPixels[i + 1], orgPixels[i + 2], orgPixels[i + 3]]);
  2819. i += 4;
  2820. };
  2821.  
  2822. for (let i = 0; i < BOTS.length; i++) BOTS[i].options.busy = true;
  2823. for (i = 0; i < imgHeight; i++)
  2824. for (let j = 0; j < imgWidth; j++) {
  2825. let pos = {x: sX + j, y: sY + i};
  2826. if(BOTS.length !== 0){
  2827. let abc = getFree();
  2828. BOTS[abc].world.setPixel(pos.x, pos.y, pixels[I]);
  2829. } else {
  2830. OWOP.world.setPixel(pos.x, pos.y, pixels[I]);
  2831. };
  2832. I++;
  2833. }
  2834. for (let i = 0; i < BOTS.length; i++) BOTS[i].options.busy = false;
  2835. };
  2836. img.src = imgURL;
  2837. };
  2838. };
  2839. });
  2840. }));
  2841. OWOP.tools.addToolObject(new OWOP.tools.class('Master Chunker', OWOP.cursors.erase, OWOP.fx.player.RECT_SELECT_ALIGNED(16), false, function(tool) {
  2842. let queue = [];
  2843. let pix = 16;
  2844. let index = 0;
  2845. let chunkStack = [];
  2846. if(Master.EraserPattern == "Circle"){
  2847. tool.setEvent('mousemove mousedown', async mouse => {
  2848. for (let x = 0; x < 16; x++) {
  2849. for (let y = 0; y < 16; y++) {
  2850. chunkStack.push([x, y]);
  2851. }
  2852. }
  2853. chunkStack.sort((a, b) => dist(a[0] - 8, a[1] - 8) - dist(b[0] - 8, b[1] - 8));
  2854. if(mouse.buttons != 0) {
  2855. if(mouse.buttons || mouse.buttons == 2) {
  2856. if(Date.now() - LastChunk < 100) return;
  2857. LastChunk = Date.now();
  2858. for (let i = 0; i < BOTS.length; i++) BOTS[i].options.busy = true;
  2859. let color = mouse.buttons === 1 ? OWOP.player.selectedColor : [255, 255, 255];
  2860. let mose = mouse.buttons;
  2861. let chunkx = Math.floor(OWOP.mouse.tileX / pix) * pix;
  2862. let chunky = Math.floor(OWOP.mouse.tileY / pix) * pix;
  2863. let armor = pix * pix;
  2864. if(BOTS.length === 0) return OWOP.chat.local("No bots connected!");
  2865. let chunkStack1 = chunkStack;
  2866. for (let x = 0; x < pix; x++) {
  2867. for (let y = 0; y < pix; y++) {
  2868. let abc = getFree();
  2869. if(Master.OldMBPaste == false) {
  2870. BOTS[abc].net.bucket.canSpend(0);
  2871. if(BOTS[abc].net.bucket.allowance <= 1) {
  2872. y--
  2873. } else {
  2874. mose === 1 ? index = 0 : index = chunkStack.length - 1;
  2875. let tpix = chunkStack1.splice(index, 1)[0];
  2876. BOTS[abc].world.setPixel(chunkx + tpix[0], chunky + tpix[1], color);
  2877. if(Master.UsePlayer) OWOP.world.setPixel(chunkx + tpix[0], chunky + tpix[1], color);
  2878. };
  2879. };
  2880. };
  2881. }
  2882. }};
  2883. });
  2884. } else {
  2885. const eq = (a, b) => a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
  2886. const eq2 = function eq(a, b) {
  2887. return a && b && a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
  2888. };
  2889. function clearChunk(chunkX, chunkY) {
  2890. for (let y = 0; y < 16; ++y) {
  2891. for (let x = 0; x < 16; ++x) {
  2892. let pos = [chunkX * 16 + x, chunkY * 16 + y];
  2893. if((!eq(OWOP.world.getPixel(...pos), [255, 255, 255])) && (queue.filter(i => eq(i, pos)).length < 1)) {
  2894. queue.unshift(pos);
  2895. };
  2896. };
  2897. };
  2898. };
  2899. tool.setEvent('mousedown mousemove', function(mouse, event) {
  2900. if(mouse.buttons === 1) {
  2901. if(Master.EraserPattern == "Top - Bottom") {
  2902. let brushercolor = OWOP.player.selectedColor;
  2903. let antx = Math.floor(OWOP.mouse.tileX / 16);
  2904. let anty = Math.floor(OWOP.mouse.tileY / 16);
  2905. let verx = antx * 16;
  2906. let very = anty * 16;
  2907. drawRectbrush(verx, very, 16, 16, brushercolor)
  2908. } else if(Master.EraserPattern == "Default") {
  2909. if(Date.now() - LastChunk < 100) return;
  2910. LastChunk = Date.now();
  2911. for (let i = 0; i < BOTS.length; i++) BOTS[i].options.busy = true;
  2912. let color = mouse.buttons === 1 ? OWOP.player.selectedColor : [255, 255, 255];
  2913. let chunkx = Math.floor(OWOP.mouse.tileX / pix) * pix;
  2914. let chunky = Math.floor(OWOP.mouse.tileY / pix) * pix;
  2915. let armor = pix * pix;
  2916. for (let x = 0; x < pix; x++) {
  2917. for (let y = 0; y < pix; y++) {
  2918. const abc = getFree();
  2919. BOTS[abc].world.setPixel(chunkx + x, chunky + y, color);
  2920. if(Master.UsePlayer) OWOP.world.setPixel(chunkx + x, chunky + y, color);
  2921. };
  2922. }
  2923. } else if(Master.EraserPattern == "Perfect") {
  2924. if(Date.now() - LastChunk < 100) return;
  2925. LastChunk = Date.now();
  2926. for (let i = 0; i < BOTS.length; i++) BOTS[i].options.busy = true;
  2927. let color = mouse.buttons === 1 ? OWOP.player.selectedColor : [255, 255, 255];
  2928. let chunkx = Math.floor(OWOP.mouse.tileX / pix) * pix;
  2929. let chunky = Math.floor(OWOP.mouse.tileY / pix) * pix;
  2930. let armor = pix * pix;
  2931. for (let y = 0; y < pix; ++y) {
  2932. for (let x = 0; x < pix; ++x) {
  2933. let abc = getFree();
  2934. BOTS[abc].net.bucket.canSpend(0)
  2935. if(BOTS[abc].net.bucket.allowance >= 1){
  2936. if((!eq2(OWOP.world.getPixel(chunkx + x, chunky + y), color))) {
  2937. BOTS[abc].world.setPixel(chunkx + x, chunky + y, color);
  2938. if(Master.UsePlayer) OWOP.world.setPixel(chunkx + x, chunky + y, color);
  2939. };
  2940. } else {
  2941. x--
  2942. };
  2943. };
  2944. };
  2945. };
  2946. };
  2947. });
  2948. };
  2949. }));
  2950. }, 1000);
  2951. }, 2000)/*}))*/;
  2952. })();