PPT

Pixel Place Tools

目前為 2022-05-08 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/443807/1048501/PPT.js

// ==UserScript==
// @name         PPT
// @description  Pixel Place Tools
// @version      2.6
// @author       0vC4
// @namespace    https://gf.qytechs.cn/users/670183
// @match        https://pixelplace.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=pixelplace.io
// @license      MIT
// @grant        none
// @run-at       document-start
// ==/UserScript==





const PPT = (() => {
  if (window.PPT) return window.PPT;



  const worker = function(func) {
      const worker = new Worker(URL.createObjectURL(new Blob(["onmessage=async({data})=>self.postMessage(await(" + func.toString() + ")(data))"], { type: "text/javascript" })));
      const root = {};
      const post = data => (worker.postMessage(data), root);
      const then = callback => (worker.onmessage=({data})=>callback(data), root);
      return Object.assign(root, {post, then});
  };



  const PPT = {
      zero: 0xCCCCCC,
      default: new Uint32Array([
          0xFFFFFF,
          0xC4C4C4,
          0x888888,
          0x555555,
          0x222222,
          0x000000,
          0x006600,
          0x22B14C,
          0x02BE01,
          0x51E119,
          0x94E044,
          0xFBFF5B,
          0xE5D900,
          0xE6BE0C,
          0xE59500,
          0xA06A42,
          0x99530D,
          0x633C1F,
          0x6B0000,
          0x9F0000,
          0xE50000,
          0xFF3904,
          0xBB4F00,
          0xFF755F,
          0xFFC49F,
          0xFFDFCC,
          0xFFA7D1,
          0xCF6EE4,
          0xEC08EC,
          0x820080,
          0x5100FF,
          0x020763,
          0x0000EA,
          0x044BFF,
          0x6583CF,
          0x36BAFF,
          0x0083C7,
          0x00D3DD,
          0x45FFC8
      ]),
      exclude: new Uint32Array([
          0x51E119,
          0xFF3904,
          0x5100FF,
          0x45FFC8
      ]),
      get palette() {
          return this.default.map(color => this.exclude.includes(color) ? this.zero : color);
      },



      _wheelID: 0,
      get wheel() {
          let pixel = this._wheelID+1;

          while (this.palette[pixel] == this.zero)
              if (this.palette[++pixel] == null)
                  pixel = 0;

          this._wheelID = pixel;
          return this._wheelID;
      },



      RGB2P(r, g, b) {
          const closest = [...this.palette]
          .filter(n => n != this.zero)
          .map(clr =>
              [
                  ((r - ((clr>>16)&0xFF))*.299)**2 +
                  ((g - ((clr>>8)&0xFF))*.587)**2 +
                  ((b - (clr&0xFF))*.114)**2,
                  clr
              ]
          )
          .sort((a,b) => a[0]-b[0])
          [0][1];

          return this.palette.indexOf(closest);
      },
      CLR2P(color) {
          return this.RGB2P((color>>16)&0xFF, (color>>8)&0xFF, color&0xFF);
      },
      
      
      
      client: null,
      get order() {
          if (!this.client) throw new Error('assign client variable first');
          const client = this.client;
          const queue = client._pixelQueue;
          
          const [cxn, cyn] = queue.reduce(([x,y], [x2,y2]) => [x+x2,y+y2], [0, 0]);
          const [cx, cy] = [cxn/queue.length>>0, cyn/queue.length>>0];
          
          const workQueue = (func, ...args) => {
              let fin = queue => 0;
              const then = finish => finish && (fin = finish);
              
              worker(func)
              .then(queue => fin(client._pixelQueue = queue))
              .post([queue, ...args]);
              
              return {then}
          };
          
          return {
              start(finish){
                  workQueue(([queue]) => {
                      return [...queue].sort(([x,y,p,i], [x2,y2,p2,i2]) => i-i2);
                  }).then(finish);
              },
              end(finish){
                  workQueue(([queue]) => {
                      return [...queue].sort(([x,y,p,i], [x2,y2,p2,i2]) => i2-i);
                  }).then(finish);
              },
              rand(finish){
                  workQueue(([queue]) => {
                      return [...queue].sort(() => Math.random()-.5);
                  }).then(finish);
              },
              
              
              
              top(finish){
                  workQueue(([queue]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => y-y2);
                  }).then(finish);
              },
              left(finish){
                  workQueue(([queue]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => x-x2);
                  }).then(finish);
              },
              right(finish){
                  workQueue(([queue]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => x2-x);
                  }).then(finish);
              },
              bottom(finish){
                  workQueue(([queue]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => y2-y);
                  }).then(finish);
              },
              
              
              
              fromCenter(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => 
                          ((x-cx)**2+(y-cy)**2) - 
                          ((x2-cx)**2+(y2-cy)**2)
                      );
                  }, cx, cy).then(finish);
              },
              toCenter(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => 
                          ((x2-cx)**2+(y2-cy)**2) - 
                          ((x-cx)**2+(y-cy)**2)
                      );
                  }, cx, cy).then(finish);
              },
              
              
              
              fromVertical(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(x-cx) - Math.abs(x2-cx));
                  }, cx, cy).then(finish);
              },
              fromHorizontal(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(y-cy) - Math.abs(y2-cy));
                  }, cx, cy).then(finish);
              },
              
              
              
              toVertical(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(x2-cx) - Math.abs(x-cx));
                  }, cx, cy).then(finish);
              },
              toHorizontal(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(y2-cy) - Math.abs(y-cy));
                  }, cx, cy).then(finish);
              },
              
              
              
              
              
              fromMapCenter(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => 
                          ((x-cx)**2+(y-cy)**2) - 
                          ((x2-cx)**2+(y2-cy)**2)
                      );
                  }, client.map.width/2, client.map.height/2).then(finish);
              },
              toMapCenter(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => 
                          ((x2-cx)**2+(y2-cy)**2) - 
                          ((x-cx)**2+(y-cy)**2)
                      );
                  }, client.map.width/2, client.map.height/2).then(finish);
              },
              
              
              
              fromMapVertical(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(x-cx) - Math.abs(x2-cx));
                  }, client.map.width/2, client.map.height/2).then(finish);
              },
              fromMapHorizontal(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(y-cx) - Math.abs(y2-cx));
                  }, client.map.width/2, client.map.height/2).then(finish);
              },
              
              
              
              toMapVertical(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(x2-cx) - Math.abs(x-cx));
                  }, client.map.width/2, client.map.height/2).then(finish);
              },
              toMapHorizontal(finish){
                  workQueue(([queue, cx, cy]) => {
                      return [...queue].sort(([x,y], [x2,y2]) => Math.abs(y2-cx) - Math.abs(y-cx));
                  }, client.map.width/2, client.map.height/2).then(finish);
              },
          };
      },
      
      
      
      timer: window,
      pixel: 0,
      size: 1,
      innerSize: 0,
      speed: 100,
      map: {pixels:[],width:0,height:0,get(x,y){return 255}},
      
      square(x,y, callback, finish) {
          const {pixel, timer, speed, size, innerSize} = this;
          const half = size>>1;
          const innerHalf = innerSize>>1;
          let xi = -half;
          let yi = -half;
          
          let t = timer.setInterval(() => {
              let i = 0;
              
              for (; yi < half+1;) {
                  for (; xi < half+1;) {
                      if (pixel === 255 || xi > -innerHalf && xi < innerHalf && yi > -innerHalf && yi < innerHalf) {
                          xi++;
                          continue;
                      }
                      
                      callback(x+xi, y+yi, pixel, t);
                      xi++;
                      
                      i++;
                      if (i > speed) return;
                      continue;
                  }
                  yi++;
                  xi = -half;
              }
              
              timer.clearInterval(t);
              finish&&finish();
          });
          
          return t;
      },
      
      
      
      ring(x,y, callback, finish) {
          const {pixel, timer, speed, size, innerSize} = this;
          const half = size>>1;
          const innerHalf = innerSize>>1;
          let xi = -half;
          let yi = -half;
          
          let t = timer.setInterval(() => {
              let i = 0;
              
              for (; yi < half+1;) {
                  for (; xi < half+1;) {
                      if (pixel === 255 || xi**2 + yi**2 > half**2 || xi**2 + yi**2 < innerHalf**2) {
                          xi++;
                          continue;
                      }
                      
                      callback(x+xi, y+yi, pixel, t);
                      xi++;
                      
                      i++;
                      if (i > speed) return;
                      continue;
                  }
                  yi++;
                  xi = -half;
              }
              
              timer.clearInterval(t);
              finish&&finish();
          });
          
          return t;
      },
      
      
      
      shader(callback, finish) {
          const {timer, speed, map} = this;
          let pos = 0;
          
          let t = timer.setInterval(() => {
              let i = 0;
              
              for (; pos < map.pixels.length; ) {
                  if (map.pixels[pos] === 255) {
                      pos++;
                      continue;
                  }
                  
                  callback(pos%map.width, pos/map.width>>0, map.pixels[pos], t);
                  pos++;
                  
                  i++;
                  if (i > speed) return;
                  continue;
              }
              
              timer.clearInterval(t);
              finish&&finish();
          });
          
          return t;
      },
      
      
      
      image(pixels, x,y,w,h, callback, finish) {
          const {timer, speed} = this;
          let xi = 0;
          let yi = 0;
          
          let t = timer.setInterval(() => {
              let i = 0;
              
              for (; yi < h;) {
                  for (; xi < w;) {
                      const pixel = pixels[xi+yi*w];
                      
                      if (pixel === 255) {
                          xi++;
                          continue;
                      }
                      
                      callback(x+xi, y+yi, pixel, t);
                      xi++;
                      
                      i++;
                      if (i > speed) return;
                      continue;
                  }
                  yi++;
                  xi = 0;
              }
              
              timer.clearInterval(t);
              finish&&finish();
          });
          
          return t;
      }
  };



  window.PPT = PPT;
  return PPT;
})();
// 0vC4#7152

QingJ © 2025

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