Guest User

Untitled

a guest
Jan 27th, 2026
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 3.03 KB | Source Code | 0 0
  1. // ==UserScript==
  2. // @name        4chan Captcha Formatter
  3. // @namespace   4chan-captcha-formatter
  4. // @match       https://boards.4chan.org/*
  5. // @match       https://sys.4chan.org/*/imgboard.php*
  6. // @grant       none
  7. // @version     1.1.1
  8. // @author      -
  9. // @description Shows the new 4chan captcha as a grid of images
  10. // ==/UserScript==
  11.  
  12. //TCaptcha module is defined in https://s.4cdn.org/js/tcaptcha.min.4.js
  13. (function () {
  14.     "use strict";
  15.  
  16.     function removeSliderIdempotently() {
  17.         const slider = TCaptcha.node.querySelector('#t-slider')
  18.         if (slider) {
  19.             TCaptcha.node.removeChild(slider)
  20.         }
  21.     }
  22.  
  23.     const createImageGrid = function () {
  24.         removeSliderIdempotently()
  25.         const bitmaps = TCaptcha.getCurrentTask().items
  26.         const description = TCaptcha.getCurrentTask().str.replace(/^Use the scroll bar below to\s*|,\s*then click next\.?/gi, '').replace(/^./, c => c.toUpperCase()) + '.';
  27.         const imageHTMLs = bitmaps.map((bitmap, imageNumber) => `<button class="tcaptcha-image" style="padding: 0; margin: 4px;border: none;background: none;"><img src="data:image/png;base64,${bitmap}" style="width:100%;height:100%"/></button>`).join('');
  28.         const containerHTML = `<div id="t-task" style="display: flex; flex-wrap: wrap; grid-gap: 4px; width: 100%; justify-content: center; margin: 0 auto;overflow:auto;max-height: 60vh;"></div>`;
  29.         const parent = TCaptcha.node;
  30.         parent.style.height = 'auto';
  31.         parent.children[1].outerHTML = containerHTML;
  32.         parent.children[1].innerHTML = `<div id="t-desc" style="white-space:pre-line;text-align:center;font-size:14px;user-select:none">${description}</div>` + imageHTMLs;
  33.  
  34.         parent.children[1].querySelectorAll('.tcaptcha-image').forEach((val, index) => {
  35.             val.addEventListener('click', () => submitCaptchaAnswer(index));
  36.         })
  37.         TCaptcha.taskNode = parent.children[1] //So the TCaptcha logic will put information like 'Done' or 'Captcha expired' onto containerHTML rather than nowhere
  38.     }
  39.  
  40.     window.submitCaptchaAnswer = function (imageNumber) { //copied from TCaptcha.onNextClick
  41.         let e = TCaptcha,
  42.             t = e.tasks ? e.tasks.length - 1 : 0;
  43.         if (t < 0) return !1;
  44.         let a = imageNumber + 1;
  45.         if (a < 1) return;
  46.         e.respNode.value += `${a - 1}`; //Submit answer
  47.         let o = e.taskId + 1;
  48.         o <= t ? (e.setTaskId(o), e.sliderNode.focus(), createImageGrid()) :  // Case 1: We now move onto the next captcha. We make another image grid after the first one
  49.             (e.nextNode.disabled = !0, e.setTaskNodeContent("Done."), e.sliderNode.blur(), e.toggleSlider(!1)) //Case 2: We just did the final captcha.
  50.     }
  51.  
  52.     //This is a code injection thing that will execute that first createImageGrid() needed for each challenge
  53.     const original_setChallenge = TCaptcha.setChallenge
  54.     const new_setChallenge = function (e) {
  55.         original_setChallenge(e);
  56.         createImageGrid()
  57.     }
  58.     TCaptcha.setChallenge = new_setChallenge
  59. })();
Add Comment
Please, Sign In to add comment