torn-crime-crack-helper

Utilize password database to crack torn cracking crime.

目前为 2023-12-21 提交的版本。查看 最新版本

// ==UserScript==
// @name         torn-crime-crack-helper
// @namespace    nodelore.torn.crack-helper
// @version      1.0.3
// @description  Utilize password database to crack torn cracking crime.
// @author       nodelore[2786679]
// @match        https://www.torn.com/loader.php?sid=crimes*
// @grant        GM_getValue
// @grant        GM.getValue
// @grant        GM_setValue
// @grant        GM.setValue
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @grant        unsafeWindow
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';
  
    // Avoid duplicate injection
    if (window.CRACK_HELPER_INJECTED) {
      return;
    }

    // ========================= Configuration==============================================================================================================================
    const CRACKER_SEL = "1m";
    const LIMIT = 10;
    // add custom password list here, and set CRACKER_SEL to the one you want to choose
    const PASSWORD_DATABASE = {
        "1m": "https://raw.githubusercontent.com/ignis-sec/Pwdb-Public/master/wordlists/ignis-1M.txt",
        "1m_alter": "https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt",
        "100k": "https://raw.githubusercontent.com/ignis-sec/Pwdb-Public/master/wordlists/ignis-100K.txt",
        "100k_alter": "https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10-million-password-list-top-100000.txt",
        "10k": "https://raw.githubusercontent.com/ignis-sec/Pwdb-Public/master/wordlists/ignis-10K.txt",
        "1k": "https://raw.githubusercontent.com/ignis-sec/Pwdb-Public/master/wordlists/ignis-1K.txt",
    }
    // =====================================================================================================================================================================

    window.CRACK_HELPER_INJECTED = true;
    console.log('Userscript crime cracker starts');
  
    if (GM) {
        window.GM_getValue = GM.getValue;
        window.GM_setValue = GM.setValue;
    }

    if(!PASSWORD_DATABASE[CRACKER_SEL]){
        console.log("Fail to fetch cracker password");
        return;
    }
    const CRACKER_HELPER_KEY = "CRACKER_HELPER_STORAGE";
    let cracker_helper = {
        "source": "",
        "data": [],
    }

    let crackerObserver, titleInterval, updateInterval;

    const setCrackTitle = (title)=>{
        if(titleInterval){
            clearInterval(titleInterval);
        }
        titleInterval = setInterval(()=>{
            if($('div[class*=crimeHeading] div[class*=title]').length > 0){
                $('div[class*=crimeHeading] div[class*=title]').text(`CRACKING(${title})`)
                clearInterval(titleInterval);
                titleInterval = undefined;
            }
        }, 1000)
    }

    const addStyle = ()=>{
        const styles = `
            .cracker-detail-panel{
                display: flex;
                flex-flow: row nowrap;
                position: absolute;
                width: 310px;
                background: #F2F2F2;
                box-sizing: border-box;
                padding: 5px 0;
                z-index: 1000001;
                border-radius: 6px;
                border: 1px solid rgba(1, 1, 1, .15);
                pointer: default;
            }

            .cracker-detail-panel-minimize{
                width: 205px;
            }

            .cracker-detail-panel-minimize .cracker-current-info{
                display: none;
            }

            .cracker-current-info, .cracker-current-status{
                display: flow;
                flex-flow: column nowrap;
                flex: 1;
                border-right: 1px solid rgba(1, 1, 1, .15);
                box-sizing: border-box;
                padding: 5px;
            }
            
            .cracker-button-set{
                display: flow;
                flex-flow: row nowrap;
                width: 100px;
                justify-content: space-around;
                align-items: center;
                box-sizing: border-box;
                padding: 5px;
            }

            .cracker-button-set div{
                width: 40px;
                height: 40px;
                box-shadow: 0 0 6px 2px rgba(1, 1, 1, .08);
                border-radius: 50%;
                background: #FFF;
                font: 24px/normal Arial,Helvetica,sans-serif;
                line-height: 40px;
                text-align: center;
                vertical-align: middle;
                font-weight: bold;
            }

            .cracker-current-info div, .cracker-current-status div{
                width: 100%;
                color: #000;
                font: 12px/normal Arial,Helvetica,sans-serif;
            }
        `;
        const isTampermonkeyEnabled = typeof unsafeWindow !== 'undefined';
        if (isTampermonkeyEnabled){
            GM_addStyle(styles);
        } else {
            let style = document.createElement("style");
            style.type = "text/css";
            style.innerHTML = styles;
            document.head.appendChild(style);
        }
    }

    const cracker_record = {};

    const handleCrime = (item)=>{
        const index = item.index().toString();
        let target = "";
        item.find("div[class*=charSlot_]").each(function(){
            const val = $(this).text().trim();
            if(val == ""){
                target += "."
            }else{
                target += val;
            }
        });
        const targetRegex = new RegExp(`^${target}$`);
        // console.log(`target Regex is ${targetRegex}`);
        setCrackTitle("Calculating");
        const result = cracker_helper.data.filter(item => targetRegex.test(item)).slice(0, LIMIT);
        cracker_record[index] = result;
        setCrackTitle("Done");

        const found = $('.cracker-detail-panel').filter(function() {
            return $(this).attr('data-attr') === index;
        });

        if(found.length < 1){
            const detailPanel = $(`div.
                <div class="cracker-detail-panel" data-attr=${index}>
                    <div class="cracker-current-info">
                        <div class="cracker-info-label" style="margin-bottom: 5px;"><b>Current pattern:</b></div>
                        <div class="cracker-info-text">${targetRegex}</div>
                    </div>
                    <div class="cracker-current-status">
                        <div class="cracker-status-label" style="margin-bottom: 5px;"><b>Total ${result.length} results:</b></div>
                        <div class="cracker-status-text">${result[0]}</div>
                    </div>
                    <div class="cracker-button-set" style="display: flex; flex-flow: row nowrap" data-index="0">
                        <div title="previous one" data-attr=${index} class="cracker-button-prev" data-action="prev" >🔙</div>
                        <div title="next one" data-attr=${index} class="cracker-button-next" data-action="next">🔜</div>
                    </div>
                </div>
            `)

            if(window.innerWidth < 1800){
                detailPanel.addClass("cracker-detail-panel-minimize");
            }

            detailPanel.css({
                left: item.offset().left + item.width() + 10,
                top: item.offset().top,
                height: item.height(),
            })

            detailPanel.find(".cracker-button-set div").click(function(){
                const action = $(this).attr("data-action");
                const action_index = $(this).attr("data-attr");
                let current_index = parseInt($(this).parent().attr("data-index"));
                const action_record = cracker_record[action_index];
                if(action_record){
                    const record_length = action_record.length;
                    if(action === "next"){
                        if(current_index < record_length - 1){
                            current_index += 1;
                        }
                    } else if(action === "prev"){
                        if(current_index > 0){
                            current_index -= 1;
                        }
                    }
        
                    $(this).parent().attr("data-index", current_index);
                    $(this).parent().parent().find(".cracker-status-text").text(action_record[current_index]);
                } else{
                    console.error("Fail to fetch record detail")
                }
            });

            $(body).append(detailPanel);
        } else{
            found.find('.cracker-info-text').text(targetRegex);
            found.find('.cracker-status-label b').text(`Total ${result.length} results:`)
            found.find('.cracker-status-text').text(result[0])
            found.find('.cracker-button-set').attr("data-index", "0");
        }
    }

    const handlePage = (crimes)=>{
        crimes.each(function(){
            handleCrime($(this));
        })

        crackerObserver = new MutationObserver((mutationList)=>{
            for(const mut of mutationList){
                for(const addedNode of mut.addedNodes){
                    if(addedNode.tagName === "SPAN" && addedNode.classList.length > 0 && addedNode.classList[0].startsWith("discoveredChar")){
                        const parent = $(addedNode).parent().parent().parent().parent();
                        handleCrime(parent);
                    } else if(addedNode.tagName === "BUTTON" && $(addedNode).attr("aria-label") === "You have already cracked this password"){
                        const parent = $(addedNode).parent().parent().parent();
                        if(parent){
                            const parentIndex = parent.index().toString();
                            const found = $('.cracker-detail-panel').filter(function() {
                                return $(this).attr('data-attr') === parentIndex;
                            });
                            if(found){
                                delete cracker_record[parentIndex];
                                let i = parseInt(parentIndex) + 1;
                                while(cracker_record[i]){
                                    cracker_record[i-1] = cracker_record[i];
                                    i += 1;
                                }
                                found.remove();
                            }
                        }

                    }
                }
            }
        })

        crackerObserver.observe($("div.crimes-app")[0], {subtree: true, childList: true})
    }



    const updatePage = ()=>{
        if(location.href.endsWith("cracking")){
            const crimes = $('.crime-option');
            if(crimes.length < 1){
                if(!updateInterval){
                    updateInterval = setInterval(()=>{
                        if($('.crime-option').length > 0 && cracker_helper.data.length > 0){
                            handlePage($('.crime-option'));
                            clearInterval(updateInterval);
                            updateInterval = undefined;
                        }
                    }, 1000);
                }
            } else{
                handlePage(crimes);
            }
        } else{
            $('.cracker-detail-panel').each(function(){
                $(this).remove();
            })
        }
    }



    addStyle();

    setCrackTitle("Loading")
    GM.getValue(CRACKER_HELPER_KEY, cracker_helper).then((cracker)=>{
        cracker_helper = cracker;
        
        if(cracker_helper.source == CRACKER_SEL){
            setCrackTitle("Loaded")
            updatePage();

            console.log('load cracker_helper from cache:')
            console.log(cracker_helper)
        } 
        else{
            console.log(`try to fetch ${PASSWORD_DATABASE[CRACKER_SEL]}`);
            setCrackTitle("Loading from network")
            GM_xmlhttpRequest({
                method: 'GET',
                url: PASSWORD_DATABASE[CRACKER_SEL],
                timeout: 30000,
                onload: (res)=>{
                    const text = res.responseText;
                    cracker_helper.data = [];
                    text.split('\n').forEach((pwd)=>{
                        cracker_helper.data.push(pwd.trim().replace('\n', ''));
                    });
                    cracker_helper.source = CRACKER_SEL;
                    GM_setValue(CRACKER_HELPER_KEY, cracker_helper);
                    setCrackTitle("Loaded")
                    updatePage();

                    console.log('load cracker_helper from network:')
                    console.log(cracker_helper)
                },
                onerror: (res)=>{
                    console.error(`error: ${res}`);
                },
                ontimeout: ()=>{
                    console.error('timeout')
                }
            })
        }


        
    }).catch((err)=>{
        console.error(err);
    })

    window.onhashchange = ()=>{
        if(crackerObserver){
            crackerObserver.disconnect();
        }
        updatePage();
    }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址