Advertisement
Guest User

Untitled

a guest
Feb 1st, 2022
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        4chan slider solver
  3. // @namespace   slider
  4. // @match       https://boards.4channel.org/*
  5. // @match       https://boards.4chan.org/*
  6. // @grant       none
  7. // @version     1.0
  8. // @author      Anon
  9. // ==/UserScript==
  10.  
  11. 'use strict';
  12.  
  13. // Calculates "disorder" of the image. "Disorder" is the percentage of black pixels that have a
  14. // non-black pixel below them. Minimizing this seems to be good enough metric for solcing the slider.
  15. function calculateDisorder(imgdata) {
  16.     const a = imgdata.data;
  17.     const stride = imgdata.width * 4;
  18.     const len = a.length - stride;
  19.  
  20.     let res=0;
  21.     let total = 0;
  22.     for (let i = 0; i < len; i += 4) {
  23.         if (a[i]!=a[i+stride]) res += 1;
  24.         if (a[i]==0) total += 1;
  25.     }
  26.     return res / (total==0 ? 1 : total);
  27. }
  28.  
  29. // returns ImageData from captcha's background image, foreground image, and offset (ranging from 0 to -50)
  30. function calcOffset(img, bg) {
  31.     const h=img.height, w=img.width;
  32.     const th=34;
  33.     const pw=16;
  34.     const scale = th/h;
  35.  
  36.     const canvas = document.createElement('canvas');
  37.     canvas.height = w * scale + pw*2;
  38.     canvas.width = 48;
  39.  
  40.     const ctx = canvas.getContext('2d');
  41.     ctx.mozImageSmoothingEnabled = false;
  42.     ctx.webkitImageSmoothingEnabled = false;
  43.     ctx.imageSmoothingEnabled = false;
  44.  
  45.     ctx.fillStyle = 'rgb(238,238,238)';
  46.     ctx.fillRect(0, 0, canvas.width, canvas.height);
  47.  
  48.     ctx.translate(canvas.width / 2, canvas.height / 2);
  49.     ctx.scale(-scale,scale);
  50.     ctx.rotate(90*Math.PI/180);
  51.  
  52.     const draw = (off) => {
  53.         const offset = (bg.width - img.width) / 2 + off;
  54.         ctx.translate( offset, 0);
  55.         ctx.drawImage( bg, -bg.width / 2, -bg.height / 2, bg.width, bg.height );
  56.         ctx.translate( -offset, 0);
  57.         ctx.drawImage( img, -w / 2, -h / 2, w, h );
  58.     };
  59.  
  60.     // if off is not specified and background image is present, try to figure out
  61.     // the best offset automatically; select the offset that has smallest value of
  62.     // calculateDisorder for the resulting image
  63.     let bestDisorder = 999;
  64.     let bestOff = 0;
  65.  
  66.     for (let off = 0; off > -50; --off) {
  67.         draw(off);
  68.  
  69.         const imgdata = ctx.getImageData(0, 0, canvas.width, canvas.height);
  70.         const disorder = calculateDisorder(imgdata);
  71.  
  72.         if (disorder < bestDisorder) {
  73.             bestDisorder = disorder;
  74.             bestOff = off;
  75.         }
  76.     }
  77.  
  78.     return bestOff;
  79. }
  80.  
  81. function imageFromUri(uri) {
  82.     let u = uri;
  83.     if (u.startsWith('url("')) u = u.substr(5, u.length-7);
  84.     if (!u.startsWith('data:')) return null;
  85.  
  86.     const img = new Image();
  87.     img.src = u;
  88.     return img;
  89. }
  90.  
  91.  
  92. function findSliderPos(urifg, uribg) {
  93.     const fg = imageFromUri(urifg);
  94.     if (!fg) return 1;
  95.     const bg = imageFromUri(uribg);
  96.     return bg !== null ? calcOffset(fg, bg) : 1;
  97. }
  98.  
  99. let lastSlider = null;
  100. const observer = new MutationObserver(() => {
  101.     const resp = document.getElementById('t-resp');
  102.     if (!resp) return;
  103.  
  104.     const bg = document.getElementById('t-bg');
  105.     if (!bg) return;
  106.  
  107.     const fg = document.getElementById('t-fg');
  108.     if (!fg) return;
  109.  
  110.     const slider=document.getElementById('t-slider');
  111.     if (!slider || lastSlider == slider) return;
  112.  
  113.     const off = findSliderPos(
  114.         fg.style.backgroundImage ?? '',
  115.         bg.style.backgroundImage ?? '',
  116.     );
  117.     if (off == 1) return;
  118.     lastSlider = slider;
  119.  
  120.     slider.value = -off * 2;
  121.     bg.style.backgroundPositionX = `${off}px`;
  122. });
  123.  
  124. observer.observe(document.body, { attributes: true, childList: true, subtree: true });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement