Library For Mxobot

Library for Mxobot

当前为 2024-12-29 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/461063/1511569/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 = [16777215,12895428,10855846,8947848,7294847,5592405,3815994,2236962,0,13880,158722,4686800,1800192,2285836,184577,5364761,9755332,3442923,10041992,7723785,13235696,16573499,15075328,16763904,12632258,15194956,15057320,16732416,16719108,15007744,13598201,16727018,10420224,5043484,6996872,4456468,16740351,10528258,6500703,10089741,12210752,16761055,16773644,16744123,16753969,15466476,12234988,13527492,8202941,8519680,5826065,3342543,13227,5319198,234,282367,77314,234721,6667343,3615231,33834,54077,4590456,11948590];
  143. static STATIC_INDEX = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59];
  144. initalizePalette(type) {
  145. if (type == undefined) {
  146. type = NevinPalette.PALETTE_LOAD_STATIC;
  147. NevinLogger.warning(
  148. "NevinPalette invoked without specifying the loading type."
  149. );
  150. }
  151. NevinLogger.info(
  152. "NevinPalette loading with type: " +
  153. (type == NevinPalette.PALETTE_LOAD_DYNAMIC ? "DYNAMIC" : "STATIC")
  154. );
  155. if (type == NevinPalette.PALETTE_LOAD_DYNAMIC) {
  156. const palette = document.getElementById("palette-buttons");
  157. if (!palette) {
  158. NevinLogger.error(
  159. "Palette requested to be loaded dynamically but HTML is not loaded yet."
  160. );
  161. }
  162. this.colors = [];
  163. this.indexes = [];
  164. const palette_buttons = Array.from(palette.children);
  165. NevinLogger.info("Dynamic loading found these DOM elements:");
  166. console.log(palette_buttons);
  167. for (const palette_button of palette_buttons) {
  168. const color = {
  169. hex: palette_button.getAttribute("title"),
  170. index: palette_button.getAttribute("data-id"),
  171. };
  172. this.colors.push(NevinPalette.hexStrToHex(color.hex));
  173. this.indexes.push(parseInt(color.index));
  174. }
  175. } else {
  176. this.colors = NevinPalette.STATIC_COLORS;
  177. this.indexes = NevinPalette.STATIC_INDEX;
  178. }
  179. }
  180. getIndex(x) {
  181. if (x instanceof Array) {
  182. const [r, g, b] = x;
  183. const hex = (r << 16) | (g << 8) | b;
  184. return this.indexes[this.colors.indexOf(hex)] ?? -1;
  185. } else if (typeof x == "number") {
  186. return this.indexes[this.colors.indexOf(x)] ?? -1;
  187. } else {
  188. NevinLogger.error("Argument is neither type of Array nor a number");
  189. }
  190. }
  191. constructor(type) {
  192. this.colors = undefined;
  193. this.indexes = undefined;
  194. this.initalizePalette(type);
  195. }
  196. }
  197. class NevinOriginalWebSocket extends WebSocket {}
  198. class NevinWS {
  199. constructor(nevinPalette, webSocket) {
  200. if (webSocket) {
  201. this.ws = webSocket;
  202. if (nevinPalette) {
  203. this.nevinMapCache = new NevinMapCache(nevinPalette, this.ws);
  204. this.nevinMapCache.addPixelChangeListener(this);
  205. }
  206. } else {
  207. this.ws = undefined;
  208. var proxy = this;
  209. this.hook = class extends WebSocket {
  210. constructor(a, b) {
  211. super(a, b);
  212. NevinLogger.info("NevinWS has hooked the game WebSocket connection.");
  213. proxy.ws = this;
  214. proxy.nevinMapCache.addPixelChangeListener(proxy);
  215. }
  216. };
  217. if (typeof unsafeWindow !== undefined) {
  218. if (unsafeWindow.WebSocket != NevinWS) {
  219. unsafeWindow.WebSocket = this.hook;
  220. }
  221. }
  222. this.nevinMapCache = new NevinMapCache(nevinPalette, this);
  223. }
  224. }
  225. }
  226. var map_cache;
  227. class NevinMapCache {
  228. init(nevinPalette, nevinWS) {
  229. var canvas_id = parseInt(location.pathname.replace("/", "").split("-")[0]);
  230. var url = `https://pixelplace.io/canvas/${canvas_id}.png?a=${
  231. Math.floor(Math.random() * 1e9) + 1e9
  232. }`;
  233. var canvas_image = new Image();
  234. var spare_canvas = document.createElement("canvas");
  235. this.before_poll = [];
  236. this.cache = map_cache;
  237. if (this.cache) return;
  238. spare_canvas.ctx = spare_canvas.getContext("2d");
  239. canvas_image.onload = () => {
  240. NevinLogger.info("Map loaded");
  241. this.map_width = canvas_image.naturalWidth;
  242. this.map_height = canvas_image.naturalHeight;
  243. spare_canvas.width = this.map_width;
  244. spare_canvas.height = this.map_height;
  245. spare_canvas.ctx.drawImage(
  246. canvas_image,
  247. 0,
  248. 0,
  249. this.map_width,
  250. this.map_height
  251. );
  252. var data = spare_canvas.ctx.getImageData(
  253. 0,
  254. 0,
  255. this.map_width,
  256. this.map_height
  257. ).data;
  258. this.cache = new Int8Array(this.map_width * this.map_height);
  259. for (let i = 0; i < data.length; i += 4) {
  260. // slice is slower in custom arrays such as Int8Array
  261. var r = data[i];
  262. var g = data[i + 1];
  263. var b = data[i + 2];
  264. const i_color = nevinPalette.getIndex([r, g, b]);
  265. this.cache[i >> 2] = i_color;
  266. }
  267. for (let packet of this.before_poll) {
  268. this.cache[packet[0]] = packet[1];
  269. }
  270. this.before_poll = undefined;
  271. };
  272. canvas_image.src = url;
  273. }
  274. constructor(nevinPalette, nevinWS) {
  275. this.init(nevinPalette, nevinWS);
  276. }
  277. getPixel(x, y) {
  278. var i = y * this.map_width + x;
  279. return this.cache[i];
  280. }
  281. addPixelChangeListener(nevinWS) {
  282. nevinWS.ws.addEventListener("message", (e) => {
  283. var data = e.data;
  284. if (!data.startsWith('42["p",')) {
  285. return;
  286. }
  287. var packets = JSON.parse(data.replace("42", ""))[1];
  288. for (let packet of packets) {
  289. var [x, y, color] = packet;
  290. var i = this.map_width * y + x;
  291. if (this.cache) {
  292. this.cache[i] = color;
  293. } else {
  294. this.before_poll.push([i, color]);
  295. }
  296. }
  297. });
  298. }
  299. }
  300. class NevinImagePicker {
  301. static requestImageFromFileDialog(NevinPalette) {
  302. return new Promise((resolve) => {
  303. const input = document.createElement("input");
  304. input.type = "file";
  305. input.accept = "image/*";
  306. input.click();
  307. input.addEventListener("change", function () {
  308. const reader = new FileReader();
  309. reader.onload = function (e) {
  310. NevinLogger.info("Image loaded");
  311. resolve(new NevinImage(e.target.result, NevinPalette));
  312. };
  313. if (input.files && input.files[0]) {
  314. reader.readAsDataURL(input.files[0]);
  315. }
  316. });
  317. });
  318. }
  319. static addClipboardListener(NevinPalette, callback) {
  320. document.addEventListener("paste", function (paste_e) {
  321. var items = (paste_e.clipboardData || paste_e.originalEvent.clipboardData)
  322. .items;
  323. NevinLogger.info(
  324. "Recieved data from clipboard: " + JSON.stringify(items)
  325. );
  326. var blob = null;
  327. for (var i = 0; i < items.length; i++) {
  328. if (items[i].type.indexOf("image") === 0) {
  329. blob = items[i].getAsFile();
  330. }
  331. }
  332. if (blob !== null) {
  333. var reader = new FileReader();
  334. reader.onload = function (e) {
  335. NevinLogger.info("Readed image from clipboard!");
  336. callback(new NevinImage(e.target.result, NevinPalette));
  337. };
  338. reader.readAsDataURL(blob);
  339. }
  340. });
  341. }
  342. }
  343. function NevinWaitForElm(selector) {
  344. return new Promise((resolve) => {
  345. if (document.querySelector(selector)) {
  346. return resolve(document.querySelector(selector));
  347. }
  348. const observer = new MutationObserver((mutations) => {
  349. if (document.querySelector(selector)) {
  350. resolve(document.querySelector(selector));
  351. observer.disconnect();
  352. }
  353. });
  354. observer.observe(document.body, {
  355. childList: true,
  356. subtree: true,
  357. });
  358. });
  359. }
  360. function NevinCreateWorker(code) {
  361. var blob = new Blob([code], { type: "text/javascript" });
  362. var url = URL.createObjectURL(blob);
  363. var worker = new Worker(url);
  364. return worker;
  365. }
  366. class NevinImage {
  367. constructor(x, palette) {
  368. this.NevinPalette = palette;
  369. this.image = undefined;
  370. this.image_canvas = document.createElement("canvas");
  371. this.image_context = this.image_canvas.getContext("2d");
  372. if (x instanceof Image) {
  373. this.image = x;
  374. } else if (typeof x == "string") {
  375. this.image = new Image();
  376. this.image.src = x;
  377. }
  378. if (this.image == undefined) {
  379. NevinLogger.error("Argument is neither type of Image nor a string");
  380. }
  381. this.image_context.mozImageSmoothingEnabled = false;
  382. this.image.onload = () => {
  383. this.image_canvas.width = this.image.width;
  384. this.image_canvas.height = this.image.height;
  385. this.image_context.drawImage(this.image, 0, 0);
  386. this.image_data = this.image_context.getImageData(
  387. 0,
  388. 0,
  389. this.image_canvas.width,
  390. this.image_canvas.height
  391. );
  392. NevinLogger.info('Dithering loaded image!');
  393. this.image_data = NevinImageConverter.floydSteinberg(this.image_data, this.image.width, this.image.height, palette);
  394. };
  395. }
  396. convertToTasks(sx, sy, nevinWS) {
  397. if (typeof sx != "number" || typeof sy != "number") {
  398. NevinLogger.error(
  399. "Tried to convert an image to tasks yet the starting coordinates are not a number."
  400. );
  401. }
  402. if (!(nevinWS instanceof NevinWS)) {
  403. NevinLogger.error(
  404. "NevinImage.convertToTasks requires an NevinWS in new versions. Please update your code."
  405. );
  406. }
  407. var _tasks = [];
  408. for (let i = 0; i < this.image_data.data.length; i += 4) {
  409. var [r, g, b, a] = this.image_data.data.slice(i, i + 4);
  410. if (a == 0) {
  411. continue;
  412. }
  413. var x = (i / 4) % this.image_data.width;
  414. var y = Math.floor(i / 4 / this.image_data.width);
  415. var colorIndex = this.NevinPalette.getIndex([r, g, b]);
  416. const c_color = nevinWS.nevinMapCache.getPixel(sx + x, sy + y);
  417. if (colorIndex == -1) {
  418. console.log([r, g, b]);
  419. }
  420. if (c_color == colorIndex || c_color == -1 || colorIndex == -1) {
  421. continue;
  422. }
  423. _tasks.push([sx + x, sy + y, colorIndex]);
  424. }
  425. return _tasks;
  426. }
  427. }
  428. class NevinEngine {
  429. static convertToTask(x, y, colorIndex, packetType) {
  430. if (packetType == undefined) {
  431. packetType = 1;
  432. }
  433. return `42["p",${JSON.stringify([x, y, colorIndex, packetType])}]`;
  434. }
  435. putPixel(x, y, colorIndex) {
  436. this.tasks.push([x, y, colorIndex]);
  437. }
  438. putPixelWithPriority(x, y, colorIndex) {
  439. this.tasks.unshift([x, y, colorIndex]);
  440. }
  441. constructor(NevinWS, timeout) {
  442. if (!NevinWS || !timeout) {
  443. return;
  444. }
  445. this.tasks = [];
  446. this.NevinWS = NevinWS;
  447. this.intervalID = setInterval(() => {
  448. const task = this.tasks.shift();
  449. if (!task) {
  450. return;
  451. }
  452. if (this.NevinWS.nevinMapCache.getPixel(task[0], task[1]) == task[2]) {
  453. return;
  454. }
  455. this.NevinWS.ws.send(NevinEngine.convertToTask(...task));
  456. }, timeout);
  457. }
  458. }
  459. class NevinEngineMultiBot extends NevinEngine {
  460. static getAccountDetailsFromCookie(cookie) {
  461. const dict = cookie
  462. .split("; ")
  463. .map((a) => a.split("="))
  464. .reduce(function (b, a) {
  465. if (!["authKey", "authToken", "authId"].includes(a[0])) return b;
  466. b[a[0]] = a[1];
  467. return b;
  468. }, {});
  469. return [dict.authId, dict.authToken, dict.authKey];
  470. }
  471. addAccountFromCookies(authId, authToken, authKey) {
  472. if (!authId || !authToken || !authKey) {
  473. NevinLogger.warning(
  474. "Auth informations are not defined. (Maybe not logged in?)"
  475. );
  476. return;
  477. }
  478. const boardId = parseInt(location.pathname.replace("/", "").split("-")[0]);
  479. const socket = new NevinOriginalWebSocket(
  480. "wss://pixelplace.io/socket.io/?EIO=3&transport=websocket"
  481. );
  482. socket.headless = true;
  483. socket.onmessage = ({ data }) => {
  484. const [code, msg] = data.split(/(?<=^\d+)(?=[^\d])/);
  485. if (code == "40") {
  486. socket.send(
  487. "42" +
  488. JSON.stringify(["init", { authKey, authToken, authId, boardId }])
  489. );
  490. }
  491. const message = JSON.parse(msg || "[]");
  492. if (message.pingInterval)
  493. socket.ping = setInterval(() => socket.send("2"), message.pingInterval);
  494. if (!message.length) return arguments;
  495. const [event, json] = message;
  496. if (event == "throw.error") {
  497. socket.close();
  498. NevinLogger.error(json);
  499. }
  500. };
  501. socket.onclose = () => {
  502. NevinLogger.info("User Disconnected");
  503. };
  504. const nevinWS = new NevinWS(undefined, socket);
  505. this.sockets.push(nevinWS);
  506. }
  507. addAccountFromNevinWS(nevinWS) {
  508. this.sockets.push(nevinWS);
  509. }
  510. constructor(timeout, nevinPalette) {
  511. super();
  512. this.tasks = [];
  513. this.sockets = [];
  514. this.counter = 0;
  515. function interval() {
  516. if (this.sockets.length == 0) {
  517. setTimeout(interval, 100);
  518. return;
  519. }
  520. const task = this.tasks.shift();
  521. if (!task) {
  522. setTimeout(interval, timeout / this.sockets.length);
  523. return;
  524. }
  525. console.log(this);
  526. this.counter = (this.counter + 1) % this.sockets.length;
  527. this.sockets[this.counter]?.ws?.send(NevinEngine.convertToTask(...task));
  528. setTimeout(this.interval, timeout / this.sockets.length);
  529. }
  530. interval = interval.bind(this);
  531. interval();
  532. this.interval = interval;
  533. }
  534. }
  535. class NevinProtect {
  536. constructor(core) {
  537. NevinLogger.info("NevinProtect has been opened.");
  538. this.core = core;
  539. this.nimage = undefined;
  540. this.coordinates = undefined;
  541. this.working = false;
  542. this.core.nevinWS.ws.addEventListener(
  543. "message",
  544. function (e) {
  545. if (!this.working) return;
  546. if (!this.nimage) return;
  547. if (!this.coordinates) return;
  548. var data = e.data;
  549. if (!data.startsWith('42["p",')) {
  550. return;
  551. }
  552. var packets = JSON.parse(data.replace("42", ""))[1];
  553. for (let packet of packets) {
  554. var [x, y, color] = packet;
  555. var image_width = this.nimage.image.width;
  556. var image_height = this.nimage.image.height;
  557. var image_x = this.coordinates[0];
  558. var image_y = this.coordinates[1];
  559. var image_xmax = image_width + image_x;
  560. var image_ymax = image_height + image_y;
  561. if (!this.nimage) {
  562. continue;
  563. }
  564. if (
  565. x < image_x ||
  566. x >= image_xmax ||
  567. y < image_y ||
  568. y >= image_ymax
  569. ) {
  570. continue;
  571. }
  572. var img_data_index = 4 * (x - image_x + image_width * (y - image_y));
  573. var [r, g, b, a] = this.nimage.image_data.data.slice(
  574. img_data_index,
  575. img_data_index + 4
  576. );
  577. if (a == 0) continue;
  578. var image_color_i = this.core.palette.getIndex([r, g, b]);
  579. if (image_color_i == undefined) {
  580. NevinLogger.error(
  581. JSON.stringify([[r, g, b], image_color_i, img_data_index])
  582. );
  583. }
  584. if (image_color_i != color) {
  585. this.core.engine.putPixelWithPriority(x, y, image_color_i);
  586. }
  587. }
  588. }.bind(this)
  589. );
  590. }
  591. start() {
  592. this.working = true;
  593. }
  594. stop() {
  595. this.working = false;
  596. }
  597. load(nimage, coordinates) {
  598. this.nimage = nimage;
  599. this.coordinates = coordinates;
  600. }
  601. }
  602. class NevinCore {
  603. async testAccountValidation() {
  604. const req = await fetch(
  605. "https://pixelplace.io/api/get-painting.php?id=7&connected=1"
  606. );
  607. const json = await req.json();
  608. if (json.user.name == "Guest") {
  609. NevinLogger.warning("User is not logged in!");
  610. } else {
  611. NevinLogger.info("Logged in as " + json.user.name);
  612. }
  613. }
  614. constructor(options) {
  615. this.testAccountValidation();
  616. this.palette = new NevinPalette(NevinPalette.PALETTE_LOAD_STATIC);
  617. // this.accountManager = new NevinAccountManager();
  618. this.nevinWS = new NevinWS(this.palette); //, this.accountManager);
  619. if (options.multibot) {
  620. this.engine = new NevinEngineMultiBot(options.timeout);
  621. localStorage.nevinAccounts = localStorage.nevinAccounts || "[]";
  622. const nevinAccounts = JSON.parse(localStorage.nevinAccounts);
  623. unsafeWindow.addThisAccount = function () {
  624. const session_account = NevinEngineMultiBot.getAccountDetailsFromCookie(
  625. document.cookie
  626. ).join("_AND_");
  627. if (session_account[0] && !nevinAccounts.includes(session_account)) {
  628. nevinAccounts.push(session_account);
  629. }
  630. localStorage.nevinAccounts = JSON.stringify(nevinAccounts);
  631. };
  632. for (let account of nevinAccounts) {
  633. const [authId, authToken, authKey] = account.split("_AND_");
  634. if (!authId || !authToken || !authKey) {
  635. console.error(account);
  636. NevinLogger.error("Local account is corrupted");
  637. }
  638. this.engine.addAccountFromCookies(authId, authToken, authKey);
  639. }
  640. } else {
  641. this.engine = new NevinEngine(this.nevinWS, options.timeout);
  642. }
  643. this.picker = NevinImagePicker;
  644. this.logger = NevinLogger;
  645. }
  646. }

QingJ © 2025

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