7Placer

typescript pixelplace.io bot

当前为 2024-06-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name 7Placer
  3. // @description typescript pixelplace.io bot
  4. // @version 1.4.0a
  5. // @author Azti
  6. // @match https://pixelplace.io/*
  7. // @require https://update.greasyfork.org/scripts/498080/1395134/Hacktimer.js
  8. // @require https://pixelplace.io/js/jquery.min.js?v2=1
  9. // @require https://pixelplace.io/js/jquery-ui.min.js?v2=1
  10. // @grant none
  11. // @run-at document-start
  12. // @namespace https://greasyfork.org/users/374503
  13. // ==/UserScript==
  14.  
  15. /******/ (() => { // webpackBootstrap
  16. /******/ "use strict";
  17. var __webpack_exports__ = {};
  18.  
  19. // UNUSED EXPORTS: Bot, BotSquare, Canvas, ImageToPixels, Queue, botImage
  20.  
  21. ;// CONCATENATED MODULE: ./src/canvas/util/canvasloader.ts
  22.  
  23. function loadcanvas(canvas) {
  24. canvasworker.onmessage = function (event) {
  25. if (Array.isArray(event.data)) {
  26. canvas.CanvasArray = event.data; // sets canvas
  27. }
  28. else {
  29. console.log(`[7placer] Processing took: ${Math.round(event.data)}ms`);
  30. }
  31. };
  32. canvasworker.postMessage(canvas_Canvas.ID);
  33. }
  34. const cloadercode = `
  35. const canvasworkerTimet = performance.now();
  36. const colors = [
  37. 0xFFFFFF, 0xC4C4C4, 0x888888, 0x555555, 0x222222, 0x000000, 0x006600, 0x22B14C,
  38. 0x02BE01, 0x51E119, 0x94E044, 0xFBFF5B, 0xE5D900, 0xE6BE0C, 0xE59500, 0xA06A42,
  39. 0x99530D, 0x633C1F, 0x6B0000, 0x9F0000, 0xE50000, 0xFF3904, 0xBB4F00, 0xFF755F,
  40. 0xFFC49F, 0xFFDFCC, 0xFFA7D1, 0xCF6EE4, 0xEC08EC, 0x820080, 0x5100FF, 0x020763,
  41. 0x0000EA, 0x044BFF, 0x6583CF, 0x36BAFF, 0x0083C7, 0x00D3DD, 0x45FFC8, 0x003638,
  42. 0x477050, 0x98FB98, 0xFF7000, 0xCE2939, 0xFF416A, 0x7D26CD, 0x330077, 0x005BA1,
  43. 0xB5E8EE, 0x1B7400, 0xCCCCCC
  44. ];
  45.  
  46. self.addEventListener('message', async (event) => {
  47. const imageResponse = await fetch('https://pixelplace.io/canvas/' + event.data + '.png?t200000=' + Date.now());
  48. const imageBlob = await imageResponse.blob();
  49. const imageBitmap = await createImageBitmap(imageBlob);
  50.  
  51. const canvas = new OffscreenCanvas(imageBitmap.width, imageBitmap.height);
  52. const ctx = canvas.getContext('2d');
  53. ctx.drawImage(imageBitmap, 0, 0, imageBitmap.width, imageBitmap.height);
  54.  
  55. const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  56. const pixelData = imageData.data;
  57. const CanvasArray = Array.from({ length: canvas.width }, () => Array.from({ length: canvas.height }, () => 50));
  58.  
  59. for (let y = 0; y < canvas.height; y++) {
  60. for (let x = 0; x < canvas.width; x++) {
  61. const pixelIndex = (y * canvas.width + x) * 4;
  62. const a = pixelData[pixelIndex + 3];
  63.  
  64. if (a < 1) {
  65. continue; // water (Be careful on canvasses without preset.)
  66. }
  67.  
  68. const r = pixelData[pixelIndex];
  69. const g = pixelData[pixelIndex + 1];
  70. const b = pixelData[pixelIndex + 2];
  71. const colornum = (r << 16) | (g << 8) | b;
  72.  
  73. const colorIndex = colors.indexOf(colornum);
  74. CanvasArray[x][y] = colorIndex
  75. }
  76. }
  77.  
  78. self.postMessage(CanvasArray);
  79. const canvasworkerendTime = performance.now();
  80. var processingTime = canvasworkerendTime - canvasworkerTimet;
  81. self.postMessage(processingTime);
  82. });
  83. `;
  84. const cloaderblob = new Blob([cloadercode], {
  85. type: 'application/javascript'
  86. });
  87. const canvasworker = new Worker(URL.createObjectURL(cloaderblob));
  88.  
  89. ;// CONCATENATED MODULE: ./src/css/style.ts
  90. const trackercss = {
  91. top: '0px',
  92. left: '0px',
  93. borderColor: 'rgb(138,43,226)',
  94. color: 'rgb(138,43,226)',
  95. backgroundColor: 'black',
  96. opacity: '60%',
  97. display: 'none',
  98. transition: 'all 0.06s ease-in-out',
  99. pointerEvents: 'none'
  100. };
  101. // design by 0vc4
  102. const drop = {
  103. width: 'calc(100% - 2em)',
  104. height: 'calc(100% - 2em)',
  105. position: 'fixed',
  106. left: '0px',
  107. top: '0px',
  108. backgroundColor: 'rgba(0, 0, 0, 0.533)',
  109. zIndex: '9999-',
  110. display: 'flex',
  111. color: 'white',
  112. fontSize: '48pt',
  113. justifyContent: 'center',
  114. alignItems: 'center',
  115. border: '3px white dashed',
  116. borderRadius: '18px',
  117. margin: '1em',
  118. };
  119. const canvascss = {
  120. position: 'absolute',
  121. pointerEvents: 'none',
  122. left: '0px',
  123. top: '0px',
  124. imageRendering: 'pixelated',
  125. opacity: '50%',
  126. animation: 'blink 3s ease-out infinite'
  127. };
  128. const blink = document.createElement("style");
  129. blink.type = "text/css";
  130. blink.innerText = `
  131. @keyframes blink {
  132. 0% { opacity: .30; }
  133. 50% { opacity: .10; }
  134. 100% { opacity: .30; }
  135. }`;
  136. document.head.appendChild(blink);
  137.  
  138. ;// CONCATENATED MODULE: ./src/canvas/Canvas.ts
  139.  
  140.  
  141. class Canvas {
  142. constructor() {
  143. Canvas.ID = this.ParseID();
  144. Canvas.isProcessed = false;
  145. loadcanvas(this);
  146. Canvas.customCanvas = this.createPreviewCanvas();
  147. }
  148. ParseID() {
  149. return parseInt(window.location.href.split("/").slice(-1)[0].split("-")[0]);
  150. }
  151. static get instance() {
  152. if (!Canvas._instance)
  153. Canvas._instance = new Canvas;
  154. return Canvas._instance;
  155. }
  156. set CanvasArray(array) {
  157. this._CanvasArray = array;
  158. Canvas.isProcessed = true;
  159. }
  160. get CanvasArray() {
  161. return this._CanvasArray;
  162. }
  163. getColor(x, y) {
  164. try {
  165. return this._CanvasArray[x][y];
  166. }
  167. catch {
  168. return 50;
  169. }
  170. ;
  171. }
  172. updatePixel(x, y, color) {
  173. if (!Canvas.isProcessed)
  174. return;
  175. this.CanvasArray[x][y] = color;
  176. // console.log(this.getColor(x, y), "->", color)
  177. }
  178. createPreviewCanvas() {
  179. const canvas = $(`<canvas width="2500" height="2088">`).css(canvascss);
  180. $('#canvas').ready(function () {
  181. $('#painting-move').append(canvas);
  182. });
  183. const ctx = canvas[0].getContext("2d");
  184. return ctx;
  185. }
  186. }
  187. /* harmony default export */ const canvas_Canvas = (Canvas);
  188.  
  189. ;// CONCATENATED MODULE: ./src/bot/util/palive.ts
  190. // credits to symmetry
  191. function randomString(charList, num) {
  192. return Array.from({ length: num }, () => charList.charAt(Math.floor(Math.random() * charList.length))).join('');
  193. }
  194. function randomString1(num) {
  195. const charList = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  196. return randomString(charList, num);
  197. }
  198. function randomString2(num) {
  199. const charList = 'gmbonjklezcfxta1234567890GMBONJKLEZCFXTA';
  200. return randomString(charList, num);
  201. }
  202. function randInt(min, max) {
  203. return Math.floor(Math.random() * (max - min + 1)) + min;
  204. }
  205. const paliveCharmap = {
  206. "0": "g",
  207. "1": "n",
  208. "2": "b",
  209. "3": "r",
  210. "4": "z",
  211. "5": "s",
  212. "6": "l",
  213. "7": "x",
  214. "8": "i",
  215. "9": "o",
  216. };
  217. function getPalive(serverTime, userId) {
  218. const tDelay = getTDelay(serverTime);
  219. const sequenceLengths = [6, 5, 9, 4, 5, 3, 6, 6, 3];
  220. const currentTimestamp = Math.floor(Date.now() / 1000) + tDelay - 5400;
  221. const timestampString = currentTimestamp.toString();
  222. const timestampCharacters = timestampString.split('');
  223. let result = '';
  224. for (let i = 0; i < sequenceLengths.length; i++) {
  225. const sequenceNumber = sequenceLengths[i];
  226. result += randInt(0, 1) == 1 ? randomString2(sequenceNumber) : randomString1(sequenceNumber);
  227. const letter = paliveCharmap[parseInt(timestampCharacters[i])];
  228. result += randInt(0, 1) == 0 ? letter.toUpperCase() : letter;
  229. }
  230. result += userId.toString().substring(0, 1) + (randInt(0, 1) == 1 ? randomString2(randInt(4, 20)) : randomString1(randInt(4, 25)));
  231. return result + "0=";
  232. }
  233. function getTDelay(serverTime) {
  234. const currentTime = new Date().getTime() / 1e3;
  235. return Math.floor(serverTime - currentTime);
  236. }
  237.  
  238. ;// CONCATENATED MODULE: ./src/auth/Auth.ts
  239. class Auth {
  240. constructor(authObj) {
  241. this.authKey = authObj.authKey;
  242. this.authId = authObj.authId;
  243. this.authToken = authObj.authToken;
  244. }
  245. }
  246.  
  247. ;// CONCATENATED MODULE: ./src/requests/getCookie.ts
  248. function getCookie(name) {
  249. const value = `; ${document.cookie}`;
  250. const parts = value.split(`; ${name}=`);
  251. if (parts.length === 2)
  252. return parts.pop().split(';').shift();
  253. }
  254.  
  255. ;// CONCATENATED MODULE: ./src/requests/get-painting.ts
  256.  
  257.  
  258. async function getPainting(authId, authKey, authToken) {
  259. const originalAuthId = getCookie('authId');
  260. const originalAuthKey = getCookie('authKey');
  261. const originalAuthToken = getCookie('authToken');
  262. document.cookie = `authId=${authId}; path=/`;
  263. document.cookie = `authKey=${authKey}; path=/`;
  264. document.cookie = `authToken=${authToken}; path=/`;
  265. try {
  266. const response = await fetch(`https://pixelplace.io/api/get-painting.php?id=${canvas_Canvas.ID}&connected=1`, {
  267. headers: {
  268. 'Accept': 'application/json, text/javascript, */*; q=0.01',
  269. },
  270. credentials: 'include'
  271. });
  272. const json = response.json();
  273. return json;
  274. }
  275. finally {
  276. document.cookie = `authId=${originalAuthId}; path=/`;
  277. document.cookie = `authKey=${originalAuthKey}; path=/`;
  278. document.cookie = `authToken=${originalAuthToken}; path=/`;
  279. }
  280. }
  281.  
  282. ;// CONCATENATED MODULE: ./src/auth/util/commands.ts
  283.  
  284.  
  285.  
  286.  
  287. const window2 = window;
  288. var LocalAccounts = new Map();
  289. // save changes in localstorage
  290. function storagePush() {
  291. const obj = Object.fromEntries(LocalAccounts);
  292. localStorage.setItem('LocalAccounts', JSON.stringify(obj));
  293. }
  294. // restore localstorage to localaccounts
  295. function storageGet() {
  296. const storedAccounts = localStorage.getItem('LocalAccounts');
  297. if (storedAccounts) {
  298. const parsedAccounts = JSON.parse(storedAccounts);
  299. LocalAccounts = new Map(Object.entries(parsedAccounts));
  300. }
  301. else
  302. LocalAccounts = new Map();
  303. }
  304. async function delay(ms) {
  305. return new Promise(resolve => setTimeout(resolve, ms));
  306. }
  307. // saves from params
  308. function saveAuth(username, authId, authKey, authToken, print = true) {
  309. if (!authId || !authKey || !authToken) {
  310. console.log('[7p] saveAuth usage: saveAuth(username, authId, authKey, authToken)');
  311. return;
  312. }
  313. const account = { authId, authKey, authToken };
  314. LocalAccounts.set(username, account);
  315. storagePush();
  316. if (print)
  317. console.log('Auth saved. Saved list: ', LocalAccounts);
  318. }
  319. // returns client's auth
  320. async function getAuth(print = true) {
  321. const cookieStore = window2.cookieStore;
  322. const authToken = await cookieStore.get("authToken");
  323. const authKey = await cookieStore.get("authKey");
  324. const authId = await cookieStore.get("authId");
  325. if (authToken == null || authKey == null || authId == null) {
  326. console.log('[7p] Please login first!');
  327. return;
  328. }
  329. if (print)
  330. console.log(`authId = "${authId.value}", authKey = "${authKey.value}", authToken = "${authToken.value}"`);
  331. return { authToken: authToken.value, authKey: authKey.value, authId: authId.value };
  332. }
  333. // saves auth from client cookies
  334. async function saveAccount() {
  335. storageGet();
  336. const AuthObj = await getAuth(false);
  337. const userinfo = await getPainting(AuthObj.authId, AuthObj.authKey, AuthObj.authToken);
  338. saveAuth(userinfo.user.name, AuthObj.authId, AuthObj.authKey, AuthObj.authToken, false);
  339. console.log('Auth saved. Saved list: ', LocalAccounts);
  340. }
  341. // logs saved auths
  342. function getAccounts() {
  343. storageGet();
  344. if (!LocalAccounts || LocalAccounts.size == 0) {
  345. console.log('No accounts found');
  346. return;
  347. }
  348. console.log(`Found ${LocalAccounts.size} accounts`);
  349. console.log(LocalAccounts);
  350. }
  351. // deletes auths
  352. function deleteAccount(identifier) {
  353. if (identifier == null) {
  354. console.log('deleteAccount usage: deleteAccount(user or index)');
  355. return;
  356. }
  357. storageGet();
  358. if (typeof identifier == 'string') {
  359. if (identifier == 'all') {
  360. LocalAccounts.forEach((value, key) => {
  361. LocalAccounts.delete(key);
  362. });
  363. return;
  364. }
  365. if (!LocalAccounts.has(identifier)) {
  366. console.log(`[7p] Error deleting: No account with name ${identifier}`);
  367. return;
  368. }
  369. LocalAccounts.delete(identifier);
  370. console.log(`[7p] Deleted account ${identifier}.`);
  371. console.log(LocalAccounts);
  372. }
  373. if (typeof identifier == 'number') {
  374. const keys = Array.from(LocalAccounts.keys());
  375. if (identifier > keys.length) {
  376. console.log(`[7p] Error deleting: No account with index ${identifier}`);
  377. return;
  378. }
  379. LocalAccounts.delete(keys[identifier]);
  380. console.log(`Deleted account ${identifier}`);
  381. console.log(LocalAccounts);
  382. }
  383. storagePush();
  384. }
  385. async function connect(username) {
  386. storageGet();
  387. const account = LocalAccounts.get(username);
  388. const connectedbot = window2.seven.bots.find((bot) => bot.generalinfo?.user.name == username);
  389. if (!username) {
  390. console.log('[7p] Missing bot username, connect("username")');
  391. return;
  392. }
  393. if (username == 'all') {
  394. for (const [username, account] of LocalAccounts) {
  395. // checks if bot is already connected
  396. const connectedbot = window2.seven.bots.find((bot) => bot.generalinfo?.user.name == username);
  397. const auth = new Auth(account);
  398. if (connectedbot) {
  399. console.log(`[7p] Account ${username} is already connected.`);
  400. continue;
  401. }
  402. new WSBot(auth, username);
  403. await delay(500);
  404. }
  405. return;
  406. }
  407. if (!account) {
  408. console.log(`[7p] No account found with username ${username}`);
  409. return;
  410. }
  411. if (connectedbot) {
  412. console.log(`[7p] Account ${username} is already connected.`);
  413. return;
  414. }
  415. const auth = new Auth(account);
  416. new WSBot(auth, username);
  417. }
  418. function disconnect(username) {
  419. const bot = window2.seven.bots.find((bot) => bot.generalinfo?.user.name == username);
  420. if (!username) {
  421. console.log('[7p] disconnect requires a username, disconnect("username")');
  422. return;
  423. }
  424. if (username == 'all') {
  425. if (window2.seven.bots.length == 1) {
  426. console.log('[7p] No bots connected.');
  427. return;
  428. }
  429. for (const bot of window2.seven.bots) {
  430. closeBot(bot);
  431. }
  432. return;
  433. }
  434. if (!bot) {
  435. console.log(`[7p] No bot connected with username ${username}`);
  436. return;
  437. }
  438. closeBot(bot);
  439. }
  440.  
  441. ;// CONCATENATED MODULE: ./src/variables.ts
  442.  
  443. /* harmony default export */ const variables = (window.seven = {
  444. bots: [],
  445. pixelspeed: 21,
  446. queue: [],
  447. inprogress: false,
  448. protect: false,
  449. tickspeed: 1000,
  450. order: 'fromCenter',
  451. saveAuth: saveAuth,
  452. getAuth: getAuth,
  453. saveAccount: saveAccount,
  454. getAccounts: getAccounts,
  455. deleteAccount: deleteAccount,
  456. connect: connect,
  457. disconnect: disconnect,
  458. });
  459.  
  460. ;// CONCATENATED MODULE: ./src/bot/util/onmessage.ts
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467. const seven = window.seven;
  468. // client
  469. function onClientMessage(event) {
  470. const msg = event.data;
  471. const bot = Client.instance;
  472. if (msg.startsWith("42")) {
  473. const msg = JSON.parse(event.data.substr(2));
  474. const type = msg[0];
  475. switch (type) {
  476. case "p":
  477. for (const pixel of msg[1]) {
  478. const canvas = canvas_Canvas.instance;
  479. const x = pixel[0];
  480. const y = pixel[1];
  481. const color = pixel[2];
  482. const id = pixel[4];
  483. canvas.updatePixel(x, y, color);
  484. }
  485. break;
  486. case "canvas":
  487. for (const pixel of msg[1]) {
  488. const canvas = canvas_Canvas.instance;
  489. const x = pixel[0];
  490. const y = pixel[1];
  491. const color = pixel[2];
  492. canvas.updatePixel(x, y, color);
  493. }
  494. break;
  495. }
  496. }
  497. }
  498. // multibot
  499. async function onBotMessage(event, bot) {
  500. const message = event.data;
  501. // game packets
  502. if (message.startsWith("42")) {
  503. const message = JSON.parse(event.data.substr(2));
  504. const type = message[0];
  505. const botid = bot.generalinfo.user.id;
  506. const botname = bot.username;
  507. switch (type) {
  508. case "server_time":
  509. bot.paliveServerTime = message[1]; // stores servertime for palive
  510. break;
  511. case "ping.alive":
  512. const hash = getPalive(bot.paliveServerTime, botid);
  513. console.log('[7p]', botname, ': pong =', hash, botid);
  514. bot.emit('pong.alive', `"${hash}"`);
  515. break;
  516. case "throw.error":
  517. if (message[1] == 49) {
  518. console.log(`[7p] [Bot ${botname}] Error (${message[1]}): This auth is not valid! Deleting account from saved accounts...`);
  519. deleteAccount(botname);
  520. closeBot(bot);
  521. return;
  522. }
  523. console.log(`[7p] [Bot ${botname}] Pixelplace WS error: ${message[1]}`);
  524. break;
  525. case "canvas":
  526. console.log(`[7p] Succesfully connected to bot ${bot.username}`);
  527. seven.bots.push(bot);
  528. break;
  529. }
  530. }
  531. // start
  532. if (message.startsWith("0"))
  533. bot.ws.send('40');
  534. // auth
  535. if (message.startsWith("40"))
  536. bot.ws.send(`42["init",{"authKey":"${bot.auth.authKey}","authToken":"${bot.auth.authToken}","authId":"${bot.auth.authId}","boardId":${canvas_Canvas.ID}}]`);
  537. // keep alive
  538. if (message.startsWith("2"))
  539. bot.ws.send('3');
  540. }
  541.  
  542. ;// CONCATENATED MODULE: ./src/bot/util/websocket.ts
  543.  
  544.  
  545.  
  546. const websocket_seven = window.seven;
  547. // client
  548. const customWS = window.WebSocket;
  549. window.WebSocket = function (url, protocols) {
  550. const client = new Client();
  551. const socket = new customWS(url, protocols);
  552. socket.addEventListener("message", (event) => { onClientMessage(event); });
  553. client.ws = socket;
  554. return socket;
  555. };
  556. // multibot
  557. async function hookBot(bot) {
  558. console.log(`[7p] Attempting to connect account ${bot.username}`);
  559. const socket = new customWS("wss://pixelplace.io/socket.io/?EIO=4&transport=websocket");
  560. socket.addEventListener("message", (event) => { onBotMessage(event, bot); });
  561. socket.addEventListener("close", () => { Bot.botIndex -= 1; });
  562. return socket;
  563. }
  564. function closeBot(bot) {
  565. if (bot instanceof Client)
  566. return;
  567. if (!bot) {
  568. console.log('[7p] Cannot close bot that doesnt exist.');
  569. return;
  570. }
  571. bot.ws.close();
  572. const result = websocket_seven.bots.filter((checkedBot) => checkedBot.botid != bot.botid);
  573. websocket_seven.bots = result;
  574. console.log('[7placer] Ended bot ', bot.botid);
  575. }
  576.  
  577. ;// CONCATENATED MODULE: ./src/bot/Bot.ts
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584. const Bot_seven = window.seven;
  585. class Bot {
  586. constructor() {
  587. this.trackeriters = 0;
  588. this.lastplace = Date.now();
  589. this.botid = Bot.botIndex;
  590. Bot.botIndex += 1; // id for next bot
  591. }
  592. emit(event, params) {
  593. this.ws.send(`42["${event}",${params}]`);
  594. }
  595. placePixel(x, y, color, tracker = true) {
  596. const canvas = canvas_Canvas.instance;
  597. const canvascolor = canvas.getColor(x, y);
  598. if (Date.now() - this.lastplace < Bot_seven.pixelspeed)
  599. return false;
  600. if (canvascolor == color || canvascolor == 50)
  601. return true;
  602. if (tracker && this.trackeriters >= 6) {
  603. $(this.tracker).css({ top: y, left: x, display: 'block' });
  604. this.trackeriters = 0;
  605. }
  606. this.trackeriters += 1;
  607. this.emit('p', `[${x},${y},${color},1]`);
  608. this.lastplace = Date.now();
  609. // console.log(`[7p] placing: ${canvascolor} -> ${color}`)
  610. return true;
  611. }
  612. createTracker() {
  613. const tracker = $('<div class="track" id="bottracker">').text(`[7P] ${this.username}`).css(trackercss);
  614. $('#canvas').ready(function () {
  615. // console.log(`[7p] created tracker: ${name}`)
  616. $('#painting-move').append(tracker);
  617. });
  618. return tracker;
  619. }
  620. set ws(wss) {
  621. this._ws = wss;
  622. }
  623. get ws() {
  624. return this._ws;
  625. }
  626. }
  627. Bot.botIndex = 0;
  628. class WSBot extends Bot {
  629. constructor(auth, username) {
  630. super();
  631. if (!username || !auth) {
  632. console.error("[7p ERROR]: 'auth' and 'username' should both be in the constructor arguments.");
  633. return;
  634. }
  635. this._auth = auth;
  636. this.username = username;
  637. this.startBot();
  638. }
  639. async startBot() {
  640. this.generalinfo = await getPainting(this.auth.authId, this.auth.authKey, this.auth.authToken);
  641. this.tracker = this.createTracker();
  642. this.ws = await hookBot(this);
  643. }
  644. get auth() {
  645. return this._auth;
  646. }
  647. }
  648. class Client extends Bot {
  649. constructor() {
  650. super();
  651. this.username = 'Client';
  652. Client.instance = this;
  653. this.tracker = this.createTracker();
  654. Bot_seven.bots.push(this);
  655. }
  656. static get Client() {
  657. return Client.instance;
  658. }
  659. }
  660.  
  661. ;// CONCATENATED MODULE: ./src/modules/defaultModules/SevenQueue.ts
  662.  
  663.  
  664. const SevenQueue_seven = window.seven;
  665. class Queue {
  666. constructor() {
  667. }
  668. static add(x, y, color) {
  669. SevenQueue_seven.queue.push({ x: x, y: y, color: color });
  670. }
  671. static clear() {
  672. // console.log('Queue cleared: ', seven.queue)
  673. SevenQueue_seven.queue = [];
  674. }
  675. static async start() {
  676. if (!canvas_Canvas.isProcessed) {
  677. console.log('[7p] Error starting queue: Canvas has not been processed yet.');
  678. Queue.stop();
  679. return;
  680. }
  681. const Bots = SevenQueue_seven.bots;
  682. var position = 0;
  683. var tick = 0;
  684. var botpos = 0;
  685. await Queue.sort();
  686. SevenQueue_seven.inprogress = true;
  687. while (SevenQueue_seven.inprogress == true && SevenQueue_seven.queue.length > 0) {
  688. if (botpos == Bots.length)
  689. botpos = 0;
  690. if (!SevenQueue_seven.protect && position == SevenQueue_seven.queue.length) {
  691. Queue.stop();
  692. console.log('[7p] Queue done.');
  693. }
  694. else if (SevenQueue_seven.protect == true && position == SevenQueue_seven.queue.length) {
  695. position = 0;
  696. }
  697. const bot = Bots[botpos];
  698. const pixel = SevenQueue_seven.queue[position];
  699. const response = bot.placePixel(pixel.x, pixel.y, pixel.color);
  700. botpos += 1;
  701. if (response)
  702. position += 1;
  703. // tick management
  704. if (tick >= SevenQueue_seven.tickspeed) {
  705. tick = 0;
  706. await new Promise(resolve => setTimeout(resolve, 0));
  707. }
  708. tick += 1;
  709. }
  710. }
  711. static async sort() {
  712. const array = SevenQueue_seven.queue;
  713. switch (SevenQueue_seven.order) {
  714. case 'rand':
  715. array.sort(() => Math.random() - 0.5);
  716. break;
  717. case 'colors':
  718. array.sort((a, b) => a.color - b.color);
  719. break;
  720. case 'vertical':
  721. array.sort((a, b) => a.x - b.x);
  722. break;
  723. case 'horizontal':
  724. array.sort((a, b) => a.y - b.y);
  725. break;
  726. default:
  727. case 'circle':
  728. const CX = Math.floor((array[0].x + array[array.length - 1].x) / 2);
  729. const CY = Math.floor((array[0].y + array[array.length - 1].y) / 2);
  730. array.sort((a, b) => {
  731. const distanceA = Math.sqrt((a.x - CX) ** 2 + (a.y - CY) ** 2);
  732. const distanceB = Math.sqrt((b.x - CX) ** 2 + (b.y - CY) ** 2);
  733. return distanceA - distanceB;
  734. });
  735. break;
  736. }
  737. }
  738. static stop() {
  739. SevenQueue_seven.inprogress = false;
  740. canvas_Canvas.customCanvas.clearRect(0, 0, 3000, 3000);
  741. Queue.clear();
  742. }
  743. }
  744. /* harmony default export */ const SevenQueue = (Queue);
  745.  
  746. ;// CONCATENATED MODULE: ./src/modules/defaultModules/SevenImageTools.ts
  747.  
  748.  
  749.  
  750. const SevenImageTools_seven = window.seven;
  751. const colors = [
  752. 0xFFFFFF, 0xC4C4C4, 0x888888, 0x555555, 0x222222, 0x000000, 0x006600, 0x22B14C,
  753. 0x02BE01, 0x51E119, 0x94E044, 0xFBFF5B, 0xE5D900, 0xE6BE0C, 0xE59500, 0xA06A42,
  754. 0x99530D, 0x633C1F, 0x6B0000, 0x9F0000, 0xE50000, 0xFF3904, 0xBB4F00, 0xFF755F,
  755. 0xFFC49F, 0xFFDFCC, 0xFFA7D1, 0xCF6EE4, 0xEC08EC, 0x820080, 0x5100FF, 0x020763,
  756. 0x0000EA, 0x044BFF, 0x6583CF, 0x36BAFF, 0x0083C7, 0x00D3DD, 0x45FFC8, 0x003638,
  757. 0x477050, 0x98FB98, 0xFF7000, 0xCE2939, 0xFF416A, 0x7D26CD, 0x330077, 0x005BA1,
  758. 0xB5E8EE, 0x1B7400
  759. ];
  760. function getColorDistance(c1, c2) {
  761. // Image Color
  762. const r1 = (c1 >> 16) & 0xFF;
  763. const g1 = (c1 >> 8) & 0xFF;
  764. const b1 = c1 & 0xFF;
  765. // Pixelplace Color
  766. const r2 = (c2 >> 16) & 0xFF;
  767. const g2 = (c2 >> 8) & 0xFF;
  768. const b2 = c2 & 0xFF;
  769. return (r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2;
  770. }
  771. function findClosestColor(color) {
  772. let minDistance = Infinity;
  773. let colorNumber;
  774. let index = 0;
  775. for (const pxpColor of colors) {
  776. const distance = getColorDistance(color, pxpColor);
  777. if (distance < minDistance) {
  778. minDistance = distance;
  779. colorNumber = index;
  780. }
  781. index += 1;
  782. }
  783. return colorNumber;
  784. }
  785. function previewCanvasImage(x, y, image) {
  786. const ctx = canvas_Canvas.customCanvas;
  787. const img = new Image();
  788. img.onload = function () {
  789. ctx.drawImage(img, x, y);
  790. };
  791. img.src = URL.createObjectURL(image);
  792. }
  793. async function ImageToPixels(image) {
  794. const result = [];
  795. const canvas = new OffscreenCanvas(image.width, image.height);
  796. const ctx = canvas.getContext('2d');
  797. ctx.drawImage(image, 0, 0, image.width, image.height);
  798. const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  799. const pixelData = imageData.data;
  800. for (let y = 0; y < canvas.height; y++) {
  801. for (let x = 0; x < canvas.width; x++) {
  802. const pixelIndex = (y * canvas.width + x) * 4;
  803. const r = pixelData[pixelIndex];
  804. const g = pixelData[pixelIndex + 1];
  805. const b = pixelData[pixelIndex + 2];
  806. const a = pixelData[pixelIndex + 3];
  807. const colornum = (r << 16) | (g << 8) | b;
  808. if (a < 1) {
  809. continue; // ignore transparent pixels
  810. }
  811. const color = findClosestColor(colornum);
  812. result.push({ x, y, color });
  813. }
  814. }
  815. return result;
  816. }
  817. async function botImage(x, y, image) {
  818. const bitmap = await createImageBitmap(image);
  819. const processed = await ImageToPixels(bitmap);
  820. previewCanvasImage(x, y, image);
  821. processed.forEach((pixel) => SevenQueue.add(pixel.x + x, pixel.y + y, pixel.color));
  822. SevenQueue.start();
  823. }
  824.  
  825. ;// CONCATENATED MODULE: ./src/modules/defaultModules/SevenSquareMaker.ts
  826.  
  827. function BotSquare(x1, y1, x2, y2, color) {
  828. if (x2 < x1)
  829. [x1, x2] = [x2, x1];
  830. if (y2 < y1)
  831. [y1, y2] = [y2, y1];
  832. for (let x = x1; x <= x2; x++) {
  833. for (let y = y1; y <= y2; y++) {
  834. SevenQueue.add(x, y, color);
  835. }
  836. }
  837. SevenQueue.start();
  838. }
  839.  
  840. ;// CONCATENATED MODULE: ./src/modules/util/getClientMouse.ts
  841. function getClientMouse() {
  842. const coordinates = $('#coordinates').text();
  843. const [x, y] = coordinates.split(',').map(coord => parseInt(coord.trim()));
  844. const selectedcolor = $('#palette-buttons a.selected').data('id');
  845. return [x, y, selectedcolor];
  846. }
  847.  
  848. ;// CONCATENATED MODULE: ./src/css/drop.ts
  849.  
  850.  
  851.  
  852. function createDropArea() {
  853. const dropobject = $('<div>').text('Drop Image').css(drop);
  854. const [x, y] = getClientMouse();
  855. $('body').append(dropobject);
  856. dropobject.on("click", function () {
  857. dropobject.remove();
  858. });
  859. dropobject.on("drop", async function (event) {
  860. event.preventDefault();
  861. event.stopPropagation();
  862. const image = event.originalEvent.dataTransfer.files[0];
  863. dropobject.remove();
  864. await botImage(x, y, image);
  865. // console.log(image)
  866. }).on('dragover', false);
  867. }
  868.  
  869. ;// CONCATENATED MODULE: ./src/modules/defaultModules/defaultKeys.ts
  870.  
  871.  
  872.  
  873.  
  874. var coord1 = null;
  875. $(document).on('keyup', function (event) {
  876. if ($(':input[type="text"]').is(':focus'))
  877. return; //; prevent with chat open
  878. switch (event.which) {
  879. case (87):
  880. if (!event.altKey)
  881. return;
  882. SevenQueue.stop();
  883. break;
  884. case (66):
  885. if (!event.altKey)
  886. return;
  887. createDropArea();
  888. break;
  889. case 88:
  890. const [x, y, color] = getClientMouse();
  891. if (coord1 == null) {
  892. coord1 = { x: x, y: y };
  893. return;
  894. }
  895. BotSquare(coord1.x, coord1.y, x, y, color);
  896. coord1 = null;
  897. break;
  898. // add more
  899. }
  900. });
  901.  
  902. ;// CONCATENATED MODULE: ./src/modules/defaultModules/index.ts
  903.  
  904.  
  905.  
  906.  
  907.  
  908. ;// CONCATENATED MODULE: ./src/modules/index.ts
  909.  
  910. // custom exports
  911.  
  912. ;// CONCATENATED MODULE: ./src/index.ts
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919. Object.defineProperty(window.console, 'log', {
  920. configurable: false,
  921. enumerable: true,
  922. writable: false,
  923. value: console.log
  924. });
  925.  
  926.  
  927.  
  928.  
  929.  
  930.  
  931. /******/ })()
  932. ;