PPCC

Pixel Place Compile Client

当前为 2022-04-24 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/443844/1043715/PPCC.js

  1. // ==UserScript==
  2. // @name PPCC
  3. // @description Pixel Place Compile Client
  4. // @version 1.5.1
  5. // @author 0vC4
  6. // @namespace https://greasyfork.org/users/670183
  7. // @match https://pixelplace.io/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=pixelplace.io
  9. // @license MIT
  10. // @grant none
  11. // @run-at document-start
  12. // ==/UserScript==
  13.  
  14.  
  15.  
  16.  
  17.  
  18. const PPCC = (() => {
  19. return {
  20. speed: 30,
  21. compile(client, PPML, CWSS, timer=window) {
  22. const speed = this.speed;
  23. Object.assign(client, {
  24. _id: 0,
  25. _posSocket: 0,
  26. sockets: [],
  27. getSocket() {
  28. let i = 0;
  29. let ws = null;
  30. while (i++ < this.sockets.length) {
  31. if (this._posSocket > this.sockets.length-1) this._posSocket = 0;
  32. const _ws = this.sockets[this._posSocket++];
  33. if (!_ws._can) continue;
  34. ws = _ws;
  35. break;
  36. }
  37. return ws;
  38. },
  39. ws: null,
  40. map: {},
  41.  
  42. onclick: null,
  43.  
  44. last: [0, 0, 255],
  45. lock: false,
  46. _pixelQueue: [],
  47. _posQueue: 0,
  48. safeEmit(x, y, pixel) {
  49. client._pixelQueue.push(x, y, pixel);
  50. },
  51. send(data) {
  52. CWSS.send.call(client.ws, data);
  53. }
  54. });
  55. timer.setInterval(() => {
  56. while (client._posQueue <= client._pixelQueue.length-3) {
  57. client._posQueue += 3;
  58. const [x, y, pixel] = client._pixelQueue.slice(client._posQueue-3, client._posQueue);
  59. if (client.map.get(x,y) === 255 || pixel === 255) continue;
  60. if (client.map.get(x,y) === pixel) continue;
  61. const ws = client.getSocket();
  62. if (!ws) {
  63. client._posQueue -= 3;
  64. return;
  65. }
  66. CWSS.send.call(ws, `42["p",[${x},${y},${pixel},1]]`);
  67. ws._can = false;
  68. return;
  69. }
  70. if (client.lock && client._posQueue > client._pixelQueue.length-3) {
  71. client._posQueue = 0;
  72. return;
  73. }
  74. client._posQueue = 0;
  75. client._pixelQueue = [];
  76. });
  77.  
  78.  
  79.  
  80. PPML.onload = map => {
  81. Object.assign(client.map, map);
  82. client.map.pixels = new Uint8Array(map.pixels);
  83. };
  84.  
  85.  
  86.  
  87. CWSS.setHook({
  88. priority: 0,
  89. init() {
  90. if (client.ws) return arguments;
  91. client.ws = this;
  92. return arguments;
  93. },
  94. open() {
  95. client.sockets.push(this);
  96. this.id = client._id++;
  97. this.addEventListener('close', () => {
  98. timer.clearInterval(this._inter);
  99. client.sockets.splice(client.sockets.indexOf(this),1);
  100. });
  101. this._can = true;
  102. this._inter = timer.setInterval(() => {
  103. this._can = true;
  104. }, 1e3/speed);
  105. return arguments;
  106. },
  107.  
  108. message({data}) {
  109. if (client.ws != this) return arguments;
  110.  
  111. const message = JSON.parse(data.split(/(?<=^\d+)(?=[^\d])/)[1] || '[]');
  112. if (!message.length) return arguments;
  113.  
  114. const [event, json] = message;
  115. if (event == 'canvas' || event == 'p') json.map(p => client.map.set(...p));
  116.  
  117. return arguments;
  118. },
  119.  
  120. send(data) {
  121. if (client.ws != this) return arguments;
  122.  
  123. const message = JSON.parse(data.split(/(?<=^\d+)(?=[^\d])/)[1] || '[]');
  124. if (!message.length) return arguments;
  125.  
  126. const [event, json] = message;
  127. if (event == 'p') {
  128. const [x, y, pixel] = json;
  129. client.last = [x, y, pixel];
  130. if (client.onclick && client.onclick(x, y, pixel) === false) return;
  131. }
  132.  
  133. return arguments;
  134. }
  135. });
  136. }
  137. };
  138. })();
  139. // 0vC4#7152