TRLink Bypasser

Bypass aylink.co and cpmlink.pro short links automatically.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         TRLink Bypasser
// @namespace    https://github.com/alper-dev/aylink.co-bypasser
// @version      1.5
// @description  Bypass aylink.co and cpmlink.pro short links automatically.
// @author       alperdev
// @license      MIT
// @match        *://aylink.co/*
// @match        *://cpmlink.pro/*
// @icon         https://raw.githubusercontent.com/alper-dev/aylink.co-bypasser/refs/heads/main/icon.ico
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function () {
    'use strict';

    const host = location.host.replace('www.', '').toLowerCase();
    if (host !== 'aylink.co' && host !== 'cpmlink.pro') return;

    if (!/^\/[A-Za-z0-9]+$/.test(location.pathname)) return;

    const showBypassingAnimation = (() => {
        let styleInjected = false;
        return () => {
            if (!styleInjected) {
                document.head.insertAdjacentHTML("beforeend", `
                    <style id="bypass-anim-style">
                        #bypass-anim {
                            position: fixed; inset: 0; width: 100vw; height: 100vh;
                            background: rgba(0, 0, 0, 0.85); 
                            backdrop-filter: blur(10px);
                            -webkit-backdrop-filter: blur(10px);
                            z-index: 99999; display: flex;
                            align-items: center; justify-content: center; flex-direction: column;
                            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                        }
                        .bypass-container {
                            background: rgba(255, 255, 255, 0.95);
                            border-radius: 20px;
                            padding: 40px 60px;
                            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
                            text-align: center;
                        }
                        .bypass-spinner {
                            width: 50px; height: 50px; 
                            border: 5px solid #e0e0e0;
                            border-top: 5px solid #2196f3; 
                            border-radius: 50%;
                            animation: spin 0.8s linear infinite; 
                            margin: 0 auto 20px;
                        }
                        .bypass-text {
                            font-size: 1.2em;
                            font-weight: 600;
                            color: #333;
                            margin: 0;
                        }
                        @keyframes spin { to { transform: rotate(360deg); } }
                    </style>
                `);
                styleInjected = true;
            }
            const div = document.createElement('div');
            div.id = 'bypass-anim';
            div.innerHTML = `
                <div class="bypass-container">
                    <div class="bypass-spinner"></div>
                    <p class="bypass-text">Bypassing link...</p>
                </div>
            `;
            document.body.appendChild(div);
            return () => div.remove();
        };
    })();

    function makeRequest(url, method = 'GET', data = null, headers = {}, retries = 3, timeout = 30000) {
        return new Promise((resolve, reject) => {
            let attemptCount = 0;

            const attemptRequest = () => {
                attemptCount++;
                GM_xmlhttpRequest({
                    method,
                    url,
                    headers,
                    data,
                    timeout: timeout,
                    onload: res => {
                        try {
                            if (headers.Accept && headers.Accept.includes('application/json')) {
                                resolve(JSON.parse(res.responseText));
                            } else {
                                resolve(res.responseText);
                            }
                        } catch {
                            resolve(res.responseText);
                        }
                    },
                    onerror: err => {
                        if (attemptCount < retries) {
                            // wait before retrying
                            const delay = Math.min(1000 * Math.pow(2, attemptCount - 1), 5000);
                            console.log(`Request failed, retrying in ${delay}ms... (Attempt ${attemptCount}/${retries})`);
                            setTimeout(attemptRequest, delay);
                        } else {
                            reject(new Error('Network error after ' + retries + ' attempts: ' + (err.error || 'Unknown error')));
                        }
                    },
                    ontimeout: () => {
                        if (attemptCount < retries) {
                            // wait before retrying
                            const delay = Math.min(1000 * Math.pow(2, attemptCount - 1), 5000);
                            console.log(`Request timeout, retrying in ${delay}ms... (Attempt ${attemptCount}/${retries})`);
                            setTimeout(attemptRequest, delay);
                        } else {
                            reject(new Error('Request timeout after ' + retries + ' attempts'));
                        }
                    }
                });
            };

            attemptRequest();
        });
    }

    async function bypassAylink() {
        const removeAnim = showBypassingAnimation();
        try {
            const html = document.documentElement.outerHTML;
            const m = html.match(/_a\s*=\s*'([^']+)',\s*_t\s*=\s*'([^']+)',\s*_d\s*=\s*'([^']+)'/);
            if (!m) return alert('Failed to extract data');
            const [_a, _t, _d] = m.slice(1);
            const m2 = html.match(/name="alias"\s+value="([^"]+)"[\s\S]+?name="csrf"\s+value="([^"]+)"/);
            if (!m2) return alert('Failed to extract data');
            const [alias, csrf] = m2.slice(1);

            const headers = {
                "Accept": "application/json, text/javascript, */*; q=0.01",
                "Accept-Language": "tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7",
                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                "X-Requested-With": "XMLHttpRequest",
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
                "Referer": location.href,
                "sec-ch-ua": '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": '"Windows"',
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-origin"
            };

            const tkData = await makeRequest(`https://${host}/get/tk`, 'POST',
                `_a=${_a}&_t=${_t}&_d=${_d}`, headers);

            if (!tkData.status) return alert('Failed to get token');
            const tkn = tkData.th;

            const go2Data = await makeRequest(`https://${host}/links/go2`, 'POST',
                `alias=${alias}&csrf=${csrf}&tkn=${tkn}`, headers);

            if (go2Data.url) {
                if (go2Data.url.includes("bildirim.vip")) {
                    const finalHtml = await makeRequest(go2Data.url, 'GET');
                    console.log(finalHtml)
                    const match = finalHtml.match(/url\s*=\s*'([^']+)'/) || finalHtml.match(/uri_full:\s*'([^']*)'/)
                    if (match) {
                        removeAnim();
                        location.href = match[1];
                    } else {
                        removeAnim();
                        location.href = go2Data.url;
                    }
                } else {
                    removeAnim();
                    location.href = go2Data.url;
                }
            } else {
                removeAnim();
                alert('No URL found in response');
            }
        } catch (e) {
            removeAnim();
            alert('Error: ' + e.message);
        }
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', bypassAylink);
    } else {
        bypassAylink();
    }
})();