RR Tracker Premium (Loader)

Premium RR Tracker Auth (PDA Hard Reload Fix)

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

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

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         RR Tracker Premium (Loader)
// @namespace    https://greasyfork.org/users/1493252
// @version      1.8
// @description  Premium RR Tracker Auth (PDA Hard Reload Fix)
// @match        https://www.torn.com/*
// @grant        GM_xmlhttpRequest
// @grant        GM.xmlHttpRequest
// @grant        GM_setValue
// @grant        GM.setValue
// @grant        GM_getValue
// @grant        GM.getValue
// @connect      api.torn.com
// @connect      script.google.com
// @connect      script.googleusercontent.com
// @connect      workers.dev
// ==/UserScript==

(async function() {
    'use strict';

    // 🛑 CLOUDFLARE URL 🛑
    const WORKER_URL = "https://rr-tracker-auth.othmanmohamadre.workers.dev";

    // 1. PDA-Safe Helper to get the active Torn Player ID
    function getActiveTornId() {
        let match = document.cookie.match(/(?:^|; )uid=([^;]*)/);
        if (match && match[1]) return match[1];
        if (typeof window.uid !== 'undefined') return String(window.uid);
        return null;
    }

    // ---------------------------------------------------------
    // 2. OMNI-STORAGE HELPERS (Bulletproof Saving for PDA)
    // ---------------------------------------------------------
    async function getSavedCreds() {
        let u = "", k = "";
        try { if (typeof GM !== 'undefined' && GM.getValue) { u = await GM.getValue("rr_prem_uid", ""); k = await GM.getValue("rr_prem_key", ""); } } catch(e) {}
        try { if (!u && typeof GM_getValue === 'function') { u = GM_getValue("rr_prem_uid", ""); k = GM_getValue("rr_prem_key", ""); } } catch(e) {}
        try { if (!u) { u = localStorage.getItem("rr_prem_uid") || sessionStorage.getItem("rr_prem_uid") || ""; k = localStorage.getItem("rr_prem_key") || sessionStorage.getItem("rr_prem_key") || ""; } } catch(e) {}
        return { uid: u, key: k };
    }

    async function saveCreds(u, k, remember) {
        if (remember) {
            try { if (typeof GM !== 'undefined' && GM.setValue) { await GM.setValue("rr_prem_uid", u); await GM.setValue("rr_prem_key", k); } } catch(e) {}
            try { if (typeof GM_setValue === 'function') { GM_setValue("rr_prem_uid", u); GM_setValue("rr_prem_key", k); } } catch(e) {}
            try { localStorage.setItem("rr_prem_uid", u); localStorage.setItem("rr_prem_key", k); } catch(e) {}
        } else {
            try { sessionStorage.setItem("rr_prem_uid", u); sessionStorage.setItem("rr_prem_key", k); } catch(e) {}
        }
    }

    async function clearCreds() {
        try { if (typeof GM !== 'undefined' && GM.setValue) { await GM.setValue("rr_prem_uid", ""); await GM.setValue("rr_prem_key", ""); } } catch(e) {}
        try { if (typeof GM_setValue === 'function') { GM_setValue("rr_prem_uid", ""); GM_setValue("rr_prem_key", ""); } } catch(e) {}
        try { localStorage.removeItem("rr_prem_uid"); localStorage.removeItem("rr_prem_key"); } catch(e) {}
        try { sessionStorage.removeItem("rr_prem_uid"); sessionStorage.removeItem("rr_prem_key"); } catch(e) {}
    }

    // ---------------------------------------------------------

    const creds = await getSavedCreds();
    let savedUid = creds.uid;
    let savedKey = creds.key;

    // 3. THE LOGIN PANEL UI
    function showLoginPanel() {
        if (!document.body) {
            setTimeout(showLoginPanel, 50);
            return;
        }

        const panel = document.createElement('div');
        Object.assign(panel.style, {
            position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)',
            background: 'linear-gradient(135deg, #1e1e1e 0%, #000000 100%)',
            border: '2px solid #64B4FF', borderRadius: '10px', padding: '25px',
            color: 'white', zIndex: '999999', fontFamily: 'monospace', width: '300px',
            boxShadow: '0px 10px 30px rgba(0,0,0,0.9)', textAlign: 'center'
        });

        panel.innerHTML = `
            <h2 style="color: #64B4FF; margin-top: 0; border-bottom: 1px solid #444; padding-bottom: 10px;">RR Tracker Premium</h2>
            <div style="text-align: left; margin-bottom: 10px;">
                <label>Torn ID:</label><br>
                <input id="rr-auth-uid" type="number" style="width: 100%; padding: 8px; margin-top: 5px; background: #222; color: #fff; border: 1px solid #555; border-radius: 4px; box-sizing: border-box;" placeholder="e.g. 1234567">
            </div>
            <div style="text-align: left; margin-bottom: 15px;">
                <label>License Key:</label><br>
                <input id="rr-auth-key" type="password" style="width: 100%; padding: 8px; margin-top: 5px; background: #222; color: #fff; border: 1px solid #555; border-radius: 4px; box-sizing: border-box;" placeholder="Paste Key Here">
            </div>
            <div style="text-align: left; margin-bottom: 20px;">
                <input type="checkbox" id="rr-auth-remember" checked>
                <label for="rr-auth-remember">Keep me logged in</label>
            </div>
            <button id="rr-auth-btn" style="width: 100%; padding: 12px; background: #2196F3; color: white; font-weight: bold; border: none; border-radius: 4px; cursor: pointer;">Login & Load Script</button>
            <div id="rr-auth-status" style="margin-top: 10px; color: #ff7a7a; font-size: 12px; height: 15px;"></div>
        `;

        document.body.appendChild(panel);

        document.getElementById('rr-auth-btn').onclick = async (e) => {
            e.preventDefault(); // Prevents double-taps on mobile
            const uid = document.getElementById('rr-auth-uid').value.trim();
            const key = document.getElementById('rr-auth-key').value.trim();
            const remember = document.getElementById('rr-auth-remember').checked;
            const status = document.getElementById('rr-auth-status');

            if (!uid || !key) {
                status.innerText = "Please fill in all fields.";
                return;
            }

            const currentActiveId = getActiveTornId();
            if (currentActiveId && currentActiveId !== uid) {
                status.innerText = "Error: This ID does not match your active Torn account!";
                return;
            }

            // Visual feedback that the button worked
            status.style.color = "#64B4FF";
            status.innerText = "Saving credentials...";

            await saveCreds(uid, key, remember);
            
            status.style.color = "#4CAF50";
            status.innerText = "Success! Reloading page...";

            // Hard Reload (Bypasses PDA's reload block)
            setTimeout(() => {
                window.location.href = "https://www.torn.com/page.php?sid=russianRoulette&refresh=" + Date.now();
            }, 500);
        };
    }

    // 4. Initial Gatekeeper Check
    if (!savedUid || !savedKey) {
        if (window.location.href.includes('sid=russianRoulette')) {
            showLoginPanel();
        }
        return; 
    }

    // 5. Active User ID Mismatch Check
    const activeId = getActiveTornId();
    if (activeId && activeId !== savedUid) {
        alert("RR Tracker Premium: Account mismatch detected! Logging out.");
        await clearCreds();
        window.location.href = "https://www.torn.com/page.php?sid=russianRoulette&refresh=" + Date.now();
        return;
    }

    // 6. Network Fetcher Detection
    let fetchFunc = null;
    if (typeof GM_xmlhttpRequest !== 'undefined') {
        fetchFunc = GM_xmlhttpRequest;
    } else if (typeof GM !== 'undefined' && typeof GM.xmlHttpRequest !== 'undefined') {
        fetchFunc = GM.xmlHttpRequest;
    }

    if (!fetchFunc) {
        if (window.location.href.includes('sid=russianRoulette')) {
            alert("RR Tracker: Your script manager does not support network requests. Please ensure GM_xmlhttpRequest is enabled.");
        }
        return;
    }

    // 7. Fetch the Obfuscated Payload from Cloudflare
    fetchFunc({
        method: "GET",
        url: `${WORKER_URL}?uid=${savedUid}&key=${savedKey}`,
        onload: function(response) {
            if (response.status === 200) {
                try {
                    const safeEvalCode = `
                        var GM = typeof GM !== 'undefined' ? GM : {};
                        if (!GM.xmlHttpRequest && typeof GM_xmlhttpRequest !== 'undefined') GM.xmlHttpRequest = GM_xmlhttpRequest;
                        if (!GM.setValue && typeof GM_setValue !== 'undefined') GM.setValue = GM_setValue;
                        if (!GM.getValue && typeof GM_getValue !== 'undefined') GM.getValue = GM_getValue;
                        
                        ${response.responseText}
                    `;
                    eval(safeEvalCode);
                    console.log("RR Tracker Premium: Vault Unlocked and Running.");

                    // 8. THE 5-MINUTE SECURITY CHECK LOOP
                    setInterval(async () => {
                        const currentId = getActiveTornId();
                        if (currentId && currentId !== savedUid) {
                            alert("RR Tracker Security: Active Torn ID has changed! Session terminated.");
                            await clearCreds();
                            window.location.href = "https://www.torn.com/page.php?sid=russianRoulette&refresh=" + Date.now();
                        }
                    }, 5 * 60 * 1000); 

                } catch (e) {
                    console.error("RR Tracker Execution Error:", e);
                }
            } else {
                if (window.location.href.includes('sid=russianRoulette')) {
                    alert("RR Tracker Authentication Failed: " + response.responseText);
                    clearCreds().then(() => showLoginPanel());
                } else {
                    clearCreds();
                }
            }
        }
    });
})();