RS Slide Captcha Solver

Auto-solve slide puzzle captcha

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name           RS Slide Captcha Solver
// @namespace      RS Slide puzzle captcha 
// @version        1.3
// @description    Auto-solve slide puzzle captcha
// @author         Shnethan
// @match          *://*.gamefaucet.fun/*
// @icon           https://docs.rs/-/rustdoc.static/favicon-32x32-eab170b8.png
// @license        © Shnethan
// @grant          none

// ==/UserScript==
 
         /*
                 * Copyright (c) 2026 Shnethan . All rights reserved.
         */

(() => {

    let b = false;

    const w = ms => new Promise(r => setTimeout(r, ms));

    const v = () => {
        const x = document.querySelector('#captchaBox');
        if (!x) return false;

        return (
            x.classList.contains('verified') ||
            (
                x.querySelector('input[name="rscaptcha_token"]')?.value?.length > 10 &&
                x.querySelector('input[name="rscaptcha_response"]')?.value?.length > 10
            )
        );
    };

    const r = () => {
        const g = document.querySelector('.gc-picture');
        const t = document.querySelector('.gc-tile');
        const s = document.querySelector('.gc-drag-block');

        return g && t && s &&
            g.complete && g.naturalWidth &&
            g.style.display !== 'none' &&
            t.style.display !== 'none';
    };

    const o = async () => {
        if (v()) return;

        const x = document.querySelector('#captchaBox');
        if (!x) return;

        ['mousedown', 'mouseup', 'click'].forEach(t =>
            x.dispatchEvent(new MouseEvent(t, {
                bubbles: true,
                cancelable: true,
                view: window
            }))
        );

        await w(900);
    };

    const f = async () => {
        const k = document.querySelector('.gc-icon-block svg:last-of-type');
        if (!k) return;

        k.dispatchEvent(new MouseEvent('click', {
            bubbles: true
        }));
        await w(1400);
    };

    const i = m => {
        const c = document.createElement('canvas');
        const x = c.getContext('2d');

        c.width = m.naturalWidth;
        c.height = m.naturalHeight;

        x.drawImage(m, 0, 0);

        try {
            return x.getImageData(0, 0, c.width, c.height);
        } catch {
            return null;
        }
    };

    const g = d => {
        const w = d.width;
        const h = d.height;
        const o = new Float32Array(w * h);

        for (let i = 0, j = 0; i < d.data.length; i += 4, j++)
            o[j] = d.data[i] * 0.299 + d.data[i + 1] * 0.587 + d.data[i + 2] * 0.114;

        return {
            g: o,
            w: w,
            h: h
        };
    };

    const s = (m) => {
        const w = m.w;
        const h = m.h;
        const o = new Float32Array(w * h);

        const x = [-1, 0, 1, -2, 0, 2, -1, 0, 1];
        const y = [-1, -2, -1, 0, 0, 0, 1, 2, 1];

        for (let j = 1; j < h - 1; j++) {
            for (let i = 1; i < w - 1; i++) {
                let p = 0,
                    q = 0,
                    k = 0;

                for (let b = -1; b <= 1; b++) {
                    for (let a = -1; a <= 1; a++) {
                        const v = m.g[(j + b) * w + (i + a)];
                        p += v * x[k];
                        q += v * y[k++];
                    }
                }
                o[j * w + i] = Math.sqrt(p * p + q * q);
            }
        }

        return {
            g: o,
            w: w,
            h: h
        };
    };

    const n = (g, p, x, y) => {
        let a = 0,
            b = 0,
            n = p.w * p.h;

        for (let j = 0; j < p.h; j++) {
            for (let i = 0; i < p.w; i++) {
                a += g.g[(y + j) * g.w + (x + i)];
                b += p.g[j * p.w + i];
            }
        }

        let u = a / n,
            v = b / n,
            num = 0,
            d1 = 0,
            d2 = 0;

        for (let j = 0; j < p.h; j++) {
            for (let i = 0; i < p.w; i++) {
                let s = g.g[(y + j) * g.w + (x + i)] - u;
                let t = p.g[j * p.w + i] - v;
                num += s * t;
                d1 += s * s;
                d2 += t * t;
            }
        }

        return Math.sqrt(d1 * d2) < 1e-6 ? 0 : num / Math.sqrt(d1 * d2);
    };

    const h = (gImg, pImg, t) => {
        const bgMat = s(g(i(gImg)));
        const pcMat = s(g(i(pImg)));

        let mx = bgMat.w - pcMat.w;
        let bx = 0,
            bst = -1;

        let y = parseInt(t.style.top) || 0;
        y = Math.max(0, Math.min(y, bgMat.h - pcMat.h));

        for (let x = 0; x <= mx; x += 4) {
            let sVal = n(bgMat, pcMat, x, y);
            if (sVal > bst) {
                bst = sVal;
                bx = x;
            }
        }

        return bst > 0.1 ? {
            x: bx,
            w: pcMat.w
        } : null;
    };

    const d = async (e, s, t, y) => {
        e.dispatchEvent(new MouseEvent('mousedown', {
            bubbles: true,
            clientX: s,
            clientY: y,
            buttons: 1
        }));

        await w(120);

        for (let i = 0; i <= 40; i++) {
            let k = i / 40;
            let x = s + (t - s) * (1 - Math.pow(1 - k, 4));

            e.dispatchEvent(new MouseEvent('mousemove', {
                bubbles: true,
                clientX: x,
                clientY: y,
                buttons: 1
            }));

            await w(10);
        }

        e.dispatchEvent(new MouseEvent('mouseup', {
            bubbles: true,
            clientX: t,
            clientY: y
        }));
    };

    const z = async () => {
        if (b || v() || !r()) return;
        b = true;

        const g = document.querySelector('.gc-picture');
        const t = document.querySelector('.gc-tile');
        const m = t.querySelector('img');
        const s = document.querySelector('.gc-drag-block');

        await w(400);

        const a = h(g, m, t);

        if (!a) {
            await f();
            b = false;
            return;
        }

        const c = g.getBoundingClientRect();
        const l = t.getBoundingClientRect();
        const k = s.getBoundingClientRect();

        const q = c.width / g.naturalWidth;
        const j = c.left + (a.x + a.w / 2) * q;
        const e = j - (l.left + l.width / 2);

        const x = k.left + k.width / 2;
        const y = x + e;
        const u = k.top + k.height / 2;

        await d(s, x, y, u);

        await w(1200);
        b = false;
    };

    setInterval(() => {
        if (v()) return;
        if (!r()) o();
        z();
    }, 1500);

})();