PPCC

Pixel Place Compile Client

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/443844/1050358/PPCC.js

  1. // ==UserScript==
  2. // @name PPCC
  3. // @description Pixel Place Compile Client
  4. // @version 1.6.2
  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. const PPClient = window.PPClient || {modules:{}};
  15. window.PPClient = PPClient;
  16. if ('Compiler' in PPClient.modules) return;
  17.  
  18.  
  19.  
  20. const module = {};
  21. module.args = {};
  22. module.intervals = [];
  23. module.main = null;
  24. module.config = ({timer, packetSpeed, packetCount}) => {
  25. if (module.main) {
  26. module.args.timer.clearInterval(module.main[0]);
  27. module.main = [
  28. timer.setInterval(module.main[1]),
  29. module.main[1]
  30. ];
  31. }
  32.  
  33. if (module.intervals.length) {
  34. module.intervals = module.intervals.map(([id, func, ws]) => {
  35. module.args.timer.clearInterval(id);
  36. ws._inter = timer.setInterval(func, packetCount > 0 ? 0 : 1e3/packetSpeed);
  37. return [ws._inter, func, ws];
  38. });
  39. }
  40.  
  41. Object.assign(module.args, {timer, packetSpeed, packetCount});
  42. };
  43.  
  44.  
  45.  
  46. module.compile = () => {
  47. const {timer, packetCount, packetSpeed} = module.args;
  48. Object.assign(PPClient, {
  49. ws: null,
  50. map: {},
  51. onclick: null,
  52.  
  53. queueId: 0,
  54. queue: [],
  55. pos: 0,
  56. lock: false,
  57. last: [0,0,255],
  58. set(x, y, p) {
  59. PPClient.queue.push([x, y, p, PPClient.queueId++]);
  60. },
  61.  
  62. _id: 0,
  63. _posSocket: 0,
  64. sockets: [],
  65. getSocket() {
  66. let i = 0;
  67. let ws = null;
  68. while (i++ < PPClient.sockets.length) {
  69. const _ws = PPClient.sockets[PPClient._posSocket++];
  70. if (PPClient._posSocket > PPClient.sockets.length-1) PPClient._posSocket = 0;
  71. if (!_ws) continue;
  72. if (_ws.ignore) continue;
  73. if (PPClient.config.packetCount > 0) {
  74. if (_ws.count > 0) _ws.count--;
  75. else continue;
  76. } else if (!_ws.can || !_ws.ready) continue;
  77.  
  78. ws = _ws;
  79. break;
  80. }
  81. return ws;
  82. }
  83. });
  84.  
  85. let progress = false;
  86. const mainFunc = () => {
  87. if (progress) return;
  88. progress = true;
  89. while (PPClient.pos < PPClient.queue.length) {
  90. const [x, y, p, i] = PPClient.queue[PPClient.pos++];
  91. if (p === 255 || PPClient.map.get(x,y) === 255) {
  92. PPClient.queue.splice(--PPClient.pos, 1);
  93. continue;
  94. }
  95. if (PPClient.map.get(x,y) === p) continue;
  96. const ws = PPClient.getSocket();
  97. if (!ws) {
  98. PPClient.pos--;
  99. progress = false;
  100. return;
  101. }
  102. ws.can = false;
  103. PPClient.CWSS.send.call(ws, `42["p",[${x},${y},${p},${1+PPClient.pos}]]`);
  104. continue;
  105. }
  106. if (PPClient.lock && PPClient.pos > PPClient.queue.length-1) {
  107. PPClient.pos = 0;
  108. progress = false;
  109. return;
  110. }
  111. PPClient.pos = 0;
  112. PPClient.queue = [];
  113. PPClient.queueId = 0;
  114. progress = false;
  115. };
  116. module.main = [timer.setInterval(mainFunc), mainFunc];
  117.  
  118.  
  119.  
  120. PPClient.modules.MapLoader.subscribe((module, map) => {
  121. Object.assign(PPClient.map, map);
  122. PPClient.map.pixels = new Uint8Array(map.pixels);
  123. PPClient.serverId = map.serverId;
  124. });
  125.  
  126.  
  127.  
  128. module.hook = {
  129. priority: 0,
  130. open() {
  131. if (!this.username) {
  132. PPClient.ws = this;
  133. this.addEventListener('close', e=>{
  134. PPClient.ws = null;
  135. });
  136. }
  137.  
  138. PPClient.sockets.push(this);
  139. this.id = PPClient._id++;
  140. const func = () => this.can = true;
  141.  
  142. this.addEventListener('close', () => {
  143. const el = module.intervals.find(([id, f, ws]) => f == func);
  144. module.intervals.splice(module.intervals.indexOf(el), 1);
  145. module.args.timer.clearInterval(this._inter);
  146. PPClient.sockets.splice(PPClient.sockets.indexOf(this),1);
  147. });
  148. this.can = true;
  149. this._inter = module.args.timer.setInterval(func, packetCount > 0 ? 0 : 1e3/packetSpeed);
  150. module.intervals.push([this._inter, func, this]);
  151. return arguments;
  152. },
  153.  
  154. message({data}) {
  155. if (PPClient.ws != this) return arguments;
  156.  
  157. const message = JSON.parse(data.split(/(?<=^\d+)(?=[^\d])/)[1] || '[]');
  158. if (!message.length) return arguments;
  159.  
  160. const [event, json] = message;
  161. if (event == 'canvas') {
  162. json.map(p => PPClient.map.set(...p));
  163. PPClient.ws.ready = true;
  164. }
  165. if (event == 'p') {
  166. json.map(p => PPClient.map.set(...p));
  167. this.count = PPClient.config.packetCount;
  168. }
  169.  
  170. return arguments;
  171. },
  172.  
  173. send(data) {
  174. if (PPClient.ws != this) return arguments;
  175.  
  176. const message = JSON.parse(data.split(/(?<=^\d+)(?=[^\d])/)[1] || '[]');
  177. if (!message.length) return arguments;
  178.  
  179. const [event, json] = message;
  180. if (event == 'p') {
  181. const [x, y, pixel] = json;
  182. PPClient.last = [x, y, pixel];
  183. if (PPClient.onclick && PPClient.onclick(x, y, pixel) === false) return;
  184. }
  185.  
  186. return arguments;
  187. }
  188. };
  189. PPClient.CWSS.setHook(module.hook);
  190. };
  191.  
  192.  
  193.  
  194. PPClient.modules.Compiler = module;
  195. })();
  196. // 0vC4#7152