Library For Mxobot

Library for Mxobot

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

  1. // ==UserScript==
  2. // @name Mxobot Library
  3. // @namespace http://tampermonkey.net/<3nevin
  4. // @version 1.5
  5. // @description Library for Mxobot
  6. // @author @ngixl
  7. // @match https://pixelplace.io/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=pixelplace.io
  9. // @grant unsafeWindow
  10. // @require https://update.gf.qytechs.cn/scripts/461063/1371348/Library%20For%20MxoBot.js
  11. /* globals unsafeWindow*/
  12. /*jshint esversion: 11 */
  13. Object.defineProperty(unsafeWindow, "console", {
  14. value: console,
  15. writable: false,
  16. });
  17. class NevinLoggerFactory {
  18. static TEMPLATE = "%c[NevinCore] %s: %s";
  19. static CSS_INFO = "color:green";
  20. static CSS_WARNING = "color:yellow;";
  21. static CSS_ERROR = "color:red;font-weight: bold;";
  22. static TEMPLATE_INFO = "INFO";
  23. static TEMPLATE_WARNING = "WARNING";
  24. static TEMPLATE_ERROR = "ERROR";
  25. static LEVEL_INFO = 0;
  26. static LEVEL_WARNING = 1;
  27. static LEVEL_ERROR = 2;
  28. LEVEL = NevinLoggerFactory.LEVEL_INFO;
  29. constructor() {
  30. this.listeners = [];
  31. this.listeners.push(function (template, css, level, msg) {
  32. console.log(template, css, level, msg);
  33. });
  34. }
  35. dispatch(template, css, level, msg) {
  36. this.listeners.forEach((listener) => {
  37. listener(template, css, level, msg);
  38. });
  39. }
  40. info(msg) {
  41. if (this.LEVEL <= NevinLoggerFactory.LEVEL_INFO) {
  42. this.dispatch(
  43. NevinLoggerFactory.TEMPLATE,
  44. NevinLoggerFactory.CSS_INFO,
  45. NevinLoggerFactory.TEMPLATE_INFO,
  46. msg
  47. );
  48. }
  49. }
  50. warning(msg) {
  51. if (this.LEVEL <= NevinLoggerFactory.LEVEL_WARNING) {
  52. this.dispatch(
  53. NevinLoggerFactory.TEMPLATE,
  54. NevinLoggerFactory.CSS_WARNING,
  55. NevinLoggerFactory.TEMPLATE_WARNING,
  56. msg
  57. );
  58. }
  59. }
  60. error(msg) {
  61. if (this.LEVEL <= NevinLoggerFactory.LEVEL_ERROR) {
  62. this.dispatch(
  63. NevinLoggerFactory.TEMPLATE,
  64. NevinLoggerFactory.CSS_ERROR,
  65. NevinLoggerFactory.TEMPLATE_ERROR,
  66. msg
  67. );
  68. throw Error(msg);
  69. }
  70. }
  71. }
  72. class NevinImageConverter {
  73. static getClosestColor(r, g, b, palette) {
  74. let closestColor = {r: 0, g: 0, b: 0};
  75. let closestDistance = Number.MAX_VALUE;
  76. for (let i = 0;i < palette.colors.length; i++) {
  77. let bigint = palette.colors[i];
  78. let p_r = (bigint >> 16) & 255;
  79. let p_g = (bigint >> 8) & 255;
  80. let p_b = bigint & 255;
  81. let distance = (r - p_r)**2 + (g - p_g)**2 + (b - p_b)**2;
  82. if (distance < closestDistance) {
  83. closestColor = {r: p_r, g: p_g, b: p_b};
  84. closestDistance = distance;
  85. }
  86. }
  87. return closestColor;
  88. }
  89. static floydSteinberg(img_data, w, h, palette) {
  90. if (unsafeWindow.BOT_DO_NOT_DITHER === true) {
  91. return img_data;
  92. }
  93. let dithered = new Uint8ClampedArray(img_data.data);
  94. let error_matrix = new Float32Array(w * h * 4);
  95. for (let y = 0; y < h; y++) {
  96. for (let x = 0;x < w; x++) {
  97. let i = (y * w + x) * 4;
  98. let r = img_data.data[i] + error_matrix[i];
  99. let g = img_data.data[i + 1] + error_matrix[i + 1];
  100. let b = img_data.data[i + 2] + error_matrix[i + 2];
  101. let closest = NevinImageConverter.getClosestColor(r, g, b, palette);
  102. dithered[i] = closest.r;
  103. dithered[i + 1] = closest.g;
  104. dithered[i + 2] = closest.b;
  105. dithered[i + 3] = img_data.data[i + 3];
  106. let err_r = r - closest.r;
  107. let err_g = g - closest.g;
  108. let err_b = b - closest.b;
  109. if (x + 1 < w) {
  110. error_matrix[i + 4] += err_r * 7 / 16;
  111. error_matrix[i + 5] += err_g * 7 / 16;
  112. error_matrix[i + 6] += err_b * 7 / 16;
  113. }
  114. if (y + 1 < h) {
  115. if (x > 0) {
  116. error_matrix[i + 4 * w - 4] += err_r * 3 / 16;
  117. error_matrix[i + 4 * w - 3] += err_g * 3 / 16;
  118. error_matrix[i + 4 * w - 2] += err_b * 3 / 16;
  119. }
  120. error_matrix[i + 4 * w] += err_r * 5 / 16;
  121. error_matrix[i + 4 * w + 1] += err_g * 5 / 16;
  122. error_matrix[i + 4 * w + 2] += err_b * 5 / 16;
  123. if (x + 1 < w) {
  124. error_matrix[i + 4 * w + 4] += err_r * 1 / 16;
  125. error_matrix[i + 4 * w + 5] += err_g * 1 / 16;
  126. error_matrix[i + 4 * w + 6] += err_b * 1 / 16;
  127. }
  128. }
  129. }
  130. }
  131. const dithered_img_data = new ImageData(dithered, w, h);
  132. return dithered_img_data;
  133. }
  134. }
  135. const NevinLogger = new NevinLoggerFactory();
  136. class NevinPalette {
  137. static PALETTE_LOAD_STATIC = 0;
  138. static PALETTE_LOAD_DYNAMIC = 1;
  139. static hexStrToHex(hex_str) {
  140. return parseInt(hex_str.slice(1), 16);
  141. }
  142. static STATIC_COLORS = [
  143. 16777215, 12895428, 8947848, 5592405, 2236962, 0, 13880, 26112, 1799168,
  144. 4681808, 2273612, 179713, 5366041, 9756740, 10025880, 16514907, 15063296,
  145. 15121932, 15045888, 16740352, 16726276, 15007744, 13510969, 16728426,
  146. 10420224, 7012352, 16741727, 10512962, 6503455, 10048269, 12275456,
  147. 16762015, 16768972, 16754641, 13594340, 8201933, 15468780, 8519808, 3342455,
  148. 132963, 5308671, 234, 281599, 23457, 6652879, 3586815, 33735, 54237,
  149. 4587464, 11921646,
  150. ];
  151. static STATIC_INDEX = [
  152. 0, 1, 2, 3, 4, 5, 39, 6, 49, 40, 7, 8, 9, 10, 41, 11, 12, 13, 14, 42, 21,
  153. 20, 43, 44, 19, 18, 23, 15, 17, 16, 22, 24, 25, 26, 27, 45, 28, 29, 46, 31,
  154. 30, 32, 33, 47, 34, 35, 36, 37, 38, 48,
  155. ];
  156. initalizePalette(type) {
  157. if (type == undefined) {
  158. type = NevinPalette.PALETTE_LOAD_STATIC;
  159. NevinLogger.warning(
  160. "NevinPalette invoked without specifying the loading type."
  161. );
  162. }
  163. NevinLogger.info(
  164. "NevinPalette loading with type: " +
  165. (type == NevinPalette.PALETTE_LOAD_DYNAMIC ? "DYNAMIC" : "STATIC")
  166. );
  167. if (type == NevinPalette.PALETTE_LOAD_DYNAMIC) {
  168. const palette = document.getElementById("palette-buttons");
  169. if (!palette) {
  170. NevinLogger.error(
  171. "Palette requested to be loaded dynamically but HTML is not loaded yet."
  172. );
  173. }
  174. this.colors = [];
  175. this.indexes = [];
  176. const palette_buttons = Array.from(palette.children);
  177. NevinLogger.info("Dynamic loading found these DOM elements:");
  178. console.log(palette_buttons);
  179. for (const palette_button of palette_buttons) {
  180. const color = {
  181. hex: palette_button.getAttribute("title"),
  182. index: palette_button.getAttribute("data-id"),
  183. };
  184. this.colors.push(NevinPalette.hexStrToHex(color.hex));
  185. this.indexes.push(parseInt(color.index));
  186. }
  187. } else {
  188. this.colors = NevinPalette.STATIC_COLORS;
  189. this.indexes = NevinPalette.STATIC_INDEX;
  190. }
  191. }
  192. getIndex(x) {
  193. if (x instanceof Array) {
  194. const [r, g, b] = x;
  195. const hex = (r << 16) | (g << 8) | b;
  196. return this.indexes[this.colors.indexOf(hex)] ?? -1;
  197. } else if (typeof x == "number") {
  198. return this.indexes[this.colors.indexOf(x)] ?? -1;
  199. } else {
  200. NevinLogger.error("Argument is neither type of Array nor a number");
  201. }
  202. }
  203. constructor(type) {
  204. this.colors = undefined;
  205. this.indexes = undefined;
  206. this.initalizePalette(type);
  207. }
  208. }
  209. class NevinOriginalWebSocket extends WebSocket {}
  210. class NevinWS {
  211. constructor(nevinPalette, webSocket) {
  212. if (webSocket) {
  213. this.ws = webSocket;
  214. if (nevinPalette) {
  215. this.nevinMapCache = new NevinMapCache(nevinPalette, this.ws);
  216. this.nevinMapCache.addPixelChangeListener(this);
  217. }
  218. } else {
  219. this.ws = undefined;
  220. var proxy = this;
  221. this.hook = class extends WebSocket {
  222. constructor(a, b) {
  223. super(a, b);
  224. NevinLogger.info("NevinWS has hooked the game WebSocket connection.");
  225. proxy.ws = this;
  226. proxy.nevinMapCache.addPixelChangeListener(proxy);
  227. }
  228. };
  229. if (typeof unsafeWindow !== undefined) {
  230. if (unsafeWindow.WebSocket != NevinWS) {
  231. unsafeWindow.WebSocket = this.hook;
  232. }
  233. }
  234. this.nevinMapCache = new NevinMapCache(nevinPalette, this);
  235. }
  236. }
  237. }
  238. var map_cache;
  239. class NevinMapCache {
  240. init(nevinPalette, nevinWS) {
  241. var canvas_id = parseInt(location.pathname.replace("/", "").split("-")[0]);
  242. var url = `https://pixelplace.io/canvas/${canvas_id}.png?a=${
  243. Math.floor(Math.random() * 1e9) + 1e9
  244. }`;
  245. var canvas_image = new Image();
  246. var spare_canvas = document.createElement("canvas");
  247. this.before_poll = [];
  248. this.cache = map_cache;
  249. if (this.cache) return;
  250. spare_canvas.ctx = spare_canvas.getContext("2d");
  251. canvas_image.onload = () => {
  252. NevinLogger.info("Map loaded");
  253. this.map_width = canvas_image.naturalWidth;
  254. this.map_height = canvas_image.naturalHeight;
  255. spare_canvas.width = this.map_width;
  256. spare_canvas.height = this.map_height;
  257. spare_canvas.ctx.drawImage(
  258. canvas_image,
  259. 0,
  260. 0,
  261. this.map_width,
  262. this.map_height
  263. );
  264. var data = spare_canvas.ctx.getImageData(
  265. 0,
  266. 0,
  267. this.map_width,
  268. this.map_height
  269. ).data;
  270. this.cache = new Int8Array(this.map_width * this.map_height);
  271. for (let i = 0; i < data.length; i += 4) {
  272. // slice is slower in custom arrays such as Int8Array
  273. var r = data[i];
  274. var g = data[i + 1];
  275. var b = data[i + 2];
  276. const i_color = nevinPalette.getIndex([r, g, b]);
  277. this.cache[i >> 2] = i_color;
  278. }
  279. for (let packet of this.before_poll) {
  280. this.cache[packet[0]] = packet[1];
  281. }
  282. this.before_poll = undefined;
  283. };
  284. canvas_image.src = url;
  285. }
  286. constructor(nevinPalette, nevinWS) {
  287. this.init(nevinPalette, nevinWS);
  288. }
  289. getPixel(x, y) {
  290. var i = y * this.map_width + x;
  291. return this.cache[i];
  292. }
  293. addPixelChangeListener(nevinWS) {
  294. nevinWS.ws.addEventListener("message", (e) => {
  295. var data = e.data;
  296. if (!data.startsWith('42["p",')) {
  297. return;
  298. }
  299. var packets = JSON.parse(data.replace("42", ""))[1];
  300. for (let packet of packets) {
  301. var [x, y, color] = packet;
  302. var i = this.map_width * y + x;
  303. if (this.cache) {
  304. this.cache[i] = color;
  305. } else {
  306. this.before_poll.push([i, color]);
  307. }
  308. }
  309. });
  310. }
  311. }
  312. class NevinImagePicker {
  313. static requestImageFromFileDialog(NevinPalette) {
  314. return new Promise((resolve) => {
  315. const input = document.createElement("input");
  316. input.type = "file";
  317. input.accept = "image/*";
  318. input.click();
  319. input.addEventListener("change", function () {
  320. const reader = new FileReader();
  321. reader.onload = function (e) {
  322. NevinLogger.info("Image loaded");
  323. resolve(new NevinImage(e.target.result, NevinPalette));
  324. };
  325. if (input.files && input.files[0]) {
  326. reader.readAsDataURL(input.files[0]);
  327. }
  328. });
  329. });
  330. }
  331. static addClipboardListener(NevinPalette, callback) {
  332. document.addEventListener("paste", function (paste_e) {
  333. var items = (paste_e.clipboardData || paste_e.originalEvent.clipboardData)
  334. .items;
  335. NevinLogger.info(
  336. "Recieved data from clipboard: " + JSON.stringify(items)
  337. );
  338. var blob = null;
  339. for (var i = 0; i < items.length; i++) {
  340. if (items[i].type.indexOf("image") === 0) {
  341. blob = items[i].getAsFile();
  342. }
  343. }
  344. if (blob !== null) {
  345. var reader = new FileReader();
  346. reader.onload = function (e) {
  347. NevinLogger.info("Readed image from clipboard!");
  348. callback(new NevinImage(e.target.result, NevinPalette));
  349. };
  350. reader.readAsDataURL(blob);
  351. }
  352. });
  353. }
  354. }
  355. function NevinWaitForElm(selector) {
  356. return new Promise((resolve) => {
  357. if (document.querySelector(selector)) {
  358. return resolve(document.querySelector(selector));
  359. }
  360. const observer = new MutationObserver((mutations) => {
  361. if (document.querySelector(selector)) {
  362. resolve(document.querySelector(selector));
  363. observer.disconnect();
  364. }
  365. });
  366. observer.observe(document.body, {
  367. childList: true,
  368. subtree: true,
  369. });
  370. });
  371. }
  372. function NevinCreateWorker(code) {
  373. var blob = new Blob([code], { type: "text/javascript" });
  374. var url = URL.createObjectURL(blob);
  375. var worker = new Worker(url);
  376. return worker;
  377. }
  378. class NevinImage {
  379. constructor(x, palette) {
  380. this.NevinPalette = palette;
  381. this.image = undefined;
  382. this.image_canvas = document.createElement("canvas");
  383. this.image_context = this.image_canvas.getContext("2d");
  384. if (x instanceof Image) {
  385. this.image = x;
  386. } else if (typeof x == "string") {
  387. this.image = new Image();
  388. this.image.src = x;
  389. }
  390. if (this.image == undefined) {
  391. NevinLogger.error("Argument is neither type of Image nor a string");
  392. }
  393. this.image_context.mozImageSmoothingEnabled = false;
  394. this.image.onload = () => {
  395. this.image_canvas.width = this.image.width;
  396. this.image_canvas.height = this.image.height;
  397. this.image_context.drawImage(this.image, 0, 0);
  398. this.image_data = this.image_context.getImageData(
  399. 0,
  400. 0,
  401. this.image_canvas.width,
  402. this.image_canvas.height
  403. );
  404. NevinLogger.info('Dithering loaded image!');
  405. this.image_data = NevinImageConverter.floydSteinberg(this.image_data, this.image.width, this.image.height, palette);
  406. };
  407. }
  408. convertToTasks(sx, sy, nevinWS) {
  409. if (typeof sx != "number" || typeof sy != "number") {
  410. NevinLogger.error(
  411. "Tried to convert an image to tasks yet the starting coordinates are not a number."
  412. );
  413. }
  414. if (!(nevinWS instanceof NevinWS)) {
  415. NevinLogger.error(
  416. "NevinImage.convertToTasks requires an NevinWS in new versions. Please update your code."
  417. );
  418. }
  419. var _tasks = [];
  420. for (let i = 0; i < this.image_data.data.length; i += 4) {
  421. var [r, g, b, a] = this.image_data.data.slice(i, i + 4);
  422. if (a == 0) {
  423. continue;
  424. }
  425. var x = (i / 4) % this.image_data.width;
  426. var y = Math.floor(i / 4 / this.image_data.width);
  427. var colorIndex = this.NevinPalette.getIndex([r, g, b]);
  428. const c_color = nevinWS.nevinMapCache.getPixel(sx + x, sy + y);
  429. if (colorIndex == -1) {
  430. console.log([r, g, b]);
  431. }
  432. if (c_color == colorIndex || c_color == -1 || colorIndex == -1) {
  433. continue;
  434. }
  435. _tasks.push([sx + x, sy + y, colorIndex]);
  436. }
  437. return _tasks;
  438. }
  439. }
  440. class NevinEngine {
  441. static convertToTask(x, y, colorIndex, packetType) {
  442. if (packetType == undefined) {
  443. packetType = 1;
  444. }
  445. return `42["p",${JSON.stringify([x, y, colorIndex, packetType])}]`;
  446. }
  447. putPixel(x, y, colorIndex) {
  448. this.tasks.push([x, y, colorIndex]);
  449. }
  450. putPixelWithPriority(x, y, colorIndex) {
  451. this.tasks.unshift([x, y, colorIndex]);
  452. }
  453. constructor(NevinWS, timeout) {
  454. if (!NevinWS || !timeout) {
  455. return;
  456. }
  457. this.tasks = [];
  458. this.NevinWS = NevinWS;
  459. this.intervalID = setInterval(() => {
  460. const task = this.tasks.shift();
  461. if (!task) {
  462. return;
  463. }
  464. if (this.NevinWS.nevinMapCache.getPixel(task[0], task[1]) == task[2]) {
  465. return;
  466. }
  467. this.NevinWS.ws.send(NevinEngine.convertToTask(...task));
  468. }, timeout);
  469. }
  470. }
  471. class NevinEngineMultiBot extends NevinEngine {
  472. static getAccountDetailsFromCookie(cookie) {
  473. const dict = cookie
  474. .split("; ")
  475. .map((a) => a.split("="))
  476. .reduce(function (b, a) {
  477. if (!["authKey", "authToken", "authId"].includes(a[0])) return b;
  478. b[a[0]] = a[1];
  479. return b;
  480. }, {});
  481. return [dict.authId, dict.authToken, dict.authKey];
  482. }
  483. addAccountFromCookies(authId, authToken, authKey) {
  484. if (!authId || !authToken || !authKey) {
  485. NevinLogger.warning(
  486. "Auth informations are not defined. (Maybe not logged in?)"
  487. );
  488. return;
  489. }
  490. const boardId = parseInt(location.pathname.replace("/", "").split("-")[0]);
  491. const socket = new NevinOriginalWebSocket(
  492. "wss://pixelplace.io/socket.io/?EIO=3&transport=websocket"
  493. );
  494. socket.headless = true;
  495. socket.onmessage = ({ data }) => {
  496. const [code, msg] = data.split(/(?<=^\d+)(?=[^\d])/);
  497. if (code == "40") {
  498. socket.send(
  499. "42" +
  500. JSON.stringify(["init", { authKey, authToken, authId, boardId }])
  501. );
  502. }
  503. const message = JSON.parse(msg || "[]");
  504. if (message.pingInterval)
  505. socket.ping = setInterval(() => socket.send("2"), message.pingInterval);
  506. if (!message.length) return arguments;
  507. const [event, json] = message;
  508. if (event == "throw.error") {
  509. socket.close();
  510. NevinLogger.error(json);
  511. }
  512. };
  513. socket.onclose = () => {
  514. NevinLogger.info("User Disconnected");
  515. };
  516. const nevinWS = new NevinWS(undefined, socket);
  517. this.sockets.push(nevinWS);
  518. }
  519. addAccountFromNevinWS(nevinWS) {
  520. this.sockets.push(nevinWS);
  521. }
  522. constructor(timeout, nevinPalette) {
  523. super();
  524. this.tasks = [];
  525. this.sockets = [];
  526. this.counter = 0;
  527. function interval() {
  528. if (this.sockets.length == 0) {
  529. setTimeout(interval, 100);
  530. return;
  531. }
  532. const task = this.tasks.shift();
  533. if (!task) {
  534. setTimeout(interval, timeout / this.sockets.length);
  535. return;
  536. }
  537. console.log(this);
  538. this.counter = (this.counter + 1) % this.sockets.length;
  539. this.sockets[this.counter]?.ws?.send(NevinEngine.convertToTask(...task));
  540. setTimeout(this.interval, timeout / this.sockets.length);
  541. }
  542. interval = interval.bind(this);
  543. interval();
  544. this.interval = interval;
  545. }
  546. }
  547. class NevinProtect {
  548. constructor(core) {
  549. NevinLogger.info("NevinProtect has been opened.");
  550. this.core = core;
  551. this.nimage = undefined;
  552. this.coordinates = undefined;
  553. this.working = false;
  554. this.core.nevinWS.ws.addEventListener(
  555. "message",
  556. function (e) {
  557. if (!this.working) return;
  558. if (!this.nimage) return;
  559. if (!this.coordinates) return;
  560. var data = e.data;
  561. if (!data.startsWith('42["p",')) {
  562. return;
  563. }
  564. var packets = JSON.parse(data.replace("42", ""))[1];
  565. for (let packet of packets) {
  566. var [x, y, color] = packet;
  567. var image_width = this.nimage.image.width;
  568. var image_height = this.nimage.image.height;
  569. var image_x = this.coordinates[0];
  570. var image_y = this.coordinates[1];
  571. var image_xmax = image_width + image_x;
  572. var image_ymax = image_height + image_y;
  573. if (!this.nimage) {
  574. continue;
  575. }
  576. if (
  577. x < image_x ||
  578. x >= image_xmax ||
  579. y < image_y ||
  580. y >= image_ymax
  581. ) {
  582. continue;
  583. }
  584. var img_data_index = 4 * (x - image_x + image_width * (y - image_y));
  585. var [r, g, b, a] = this.nimage.image_data.data.slice(
  586. img_data_index,
  587. img_data_index + 4
  588. );
  589. if (a == 0) continue;
  590. var image_color_i = this.core.palette.getIndex([r, g, b]);
  591. if (image_color_i == undefined) {
  592. NevinLogger.error(
  593. JSON.stringify([[r, g, b], image_color_i, img_data_index])
  594. );
  595. }
  596. if (image_color_i != color) {
  597. this.core.engine.putPixelWithPriority(x, y, image_color_i);
  598. }
  599. }
  600. }.bind(this)
  601. );
  602. }
  603. start() {
  604. this.working = true;
  605. }
  606. stop() {
  607. this.working = false;
  608. }
  609. load(nimage, coordinates) {
  610. this.nimage = nimage;
  611. this.coordinates = coordinates;
  612. }
  613. }
  614. class NevinCore {
  615. async testAccountValidation() {
  616. const req = await fetch(
  617. "https://pixelplace.io/api/get-painting.php?id=7&connected=1"
  618. );
  619. const json = await req.json();
  620. if (json.user.name == "Guest") {
  621. NevinLogger.warning("User is not logged in!");
  622. } else {
  623. NevinLogger.info("Logged in as " + json.user.name);
  624. }
  625. }
  626. constructor(options) {
  627. this.testAccountValidation();
  628. this.palette = new NevinPalette(NevinPalette.PALETTE_LOAD_STATIC);
  629. // this.accountManager = new NevinAccountManager();
  630. this.nevinWS = new NevinWS(this.palette); //, this.accountManager);
  631. if (options.multibot) {
  632. this.engine = new NevinEngineMultiBot(options.timeout);
  633. localStorage.nevinAccounts = localStorage.nevinAccounts || "[]";
  634. const nevinAccounts = JSON.parse(localStorage.nevinAccounts);
  635. unsafeWindow.addThisAccount = function () {
  636. const session_account = NevinEngineMultiBot.getAccountDetailsFromCookie(
  637. document.cookie
  638. ).join("_AND_");
  639. if (session_account[0] && !nevinAccounts.includes(session_account)) {
  640. nevinAccounts.push(session_account);
  641. }
  642. localStorage.nevinAccounts = JSON.stringify(nevinAccounts);
  643. };
  644. for (let account of nevinAccounts) {
  645. const [authId, authToken, authKey] = account.split("_AND_");
  646. if (!authId || !authToken || !authKey) {
  647. console.error(account);
  648. NevinLogger.error("Local account is corrupted");
  649. }
  650. this.engine.addAccountFromCookies(authId, authToken, authKey);
  651. }
  652. } else {
  653. this.engine = new NevinEngine(this.nevinWS, options.timeout);
  654. }
  655. this.picker = NevinImagePicker;
  656. this.logger = NevinLogger;
  657. }
  658. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址