Nexus No Wait (Legacy Fork)

[Temporary fork] Download from Nexusmods.com without wait and redirect (support Manual/Vortex)

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

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

(I already have a user script manager, let me install it!)

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.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Nexus No Wait (Legacy Fork)
// @description [Temporary fork] Download from Nexusmods.com without wait and redirect (support Manual/Vortex)
// @namespace   NexusNoWait
// @include     https://www.nexusmods.com/*/mods/*
// @run-at      document-idle
// @grant       GM.xmlHttpRequest
// @grant       GM_xmlhttpRequest
// @version     1.5
// ==/UserScript==

(function() {
    var ajax_request_raw;
    
    if (typeof(GM_xmlhttpRequest) !== "undefined") {
		ajax_request_raw = GM_xmlhttpRequest;
	} else if (typeof(GM) !== "undefined" && typeof(GM.xmlHttpRequest) !== "undefined") {
		ajax_request_raw = GM.xmlHttpRequest;
	}
    
    var ajax_request = function(obj) {
        if (!ajax_request_raw) {
            console.log("Unable to request", obj);
            return;
        }
        
        var requestobj = {
            url: obj.url,
            method: obj.type,
            data: obj.data,
            headers: obj.headers,
        };
        
        var loadcb = function(result) {
            if (result.readyState !== 4)
                return;
            
            if (result.status !== 200) {
                return obj.error(result);
            } else {
                return obj.success(result.responseText);
            }
        };
        
        requestobj.onload = loadcb;
        requestobj.onerror = loadcb;
        
        ajax_request_raw(requestobj);
    };
    
    var btnError = function(button) {
        button.style.color = "red";
        button.innerText = 'ERROR';
    };

    var btnSuccess = function(button) {
        button.style.color = "green";
        button.innerText = 'LOADING';
    };
    
    var click_listener = function(event) {
        var href = this.href;
        if (/[?&]file_id=/.test(href)) {
            event.preventDefault();
            
            var button = this;

            button.style.color = "yellow";
            button.innerText = 'WAIT';

            var game_id = document.getElementById("section").dataset.gameId;
            var search_params = new URL(href).searchParams;
            
            var file_id = search_params.get("file_id");
            if (!file_id)
                file_id = search_params.get("id"); // for ModRequirementsPopUp

            if (!/[?&]nmm=/.test(href)) {
                ajax_request({
                    type: "POST",
                    url: "/Core/Libs/Common/Managers/Downloads?GenerateDownloadUrl",
                    data: "fid=" + file_id + "&game_id=" + game_id,
                    headers: {
                        Origin: "https://www.nexusmods.com",
                        Referer: href,
                        "Sec-Fetch-Site": "same-origin",
                        "X-Requested-With": "XMLHttpRequest",
                        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
                    },
                    success: function(data) {
                        if (data) {
                            try {
                                data = JSON.parse(data);

                                if (data.url) {
                                    console.log('Success', data.url);
                                    btnSuccess(button);
                                    document.location.href = data.url;
                                    return;
                                }
                            } catch (e) {
                                console.error(e);
                            }
                        }
                        
                        btnError(button);
                    },
                    error: function() {
                        btnError(button);
                    }
                });
            } else {
                ajax_request({
                    type: "GET",
                    url: href,
                    headers: {
                        Origin: "https://www.nexusmods.com",
                        Referer: document.location.href,
                        "Sec-Fetch-Site": "same-origin",
                        "X-Requested-With": "XMLHttpRequest"
                    },
                    success: function(data) {
                        if (data) {
                            var xml = new DOMParser().parseFromString(data, "text/html");
                            var slow = xml.getElementById("slowDownloadButton");
                            var downloadUrl = slow.getAttribute("data-download-url");
                            console.log('Success', downloadUrl);
                            btnSuccess(button);
                            document.location.href = downloadUrl;
                            return;
                        }
                        
                        btnError(button);
                    },
                    error: function(ajaxContext) {
                        console.log(ajaxContext.responseText);
                        btnError(button);
                    }
                });
            }

            var popup = $(this).parent();
            if (popup.hasClass('popup')) {
                popup.children("button").click();
            }
            
            return false;
        }
    };
    
    var add_click_listener = function(el) {
        el.addEventListener("click", click_listener, true);
    };
    
    var add_click_listeners = function(els) {
         for (var i = 0; i < els.length; i++) {
            add_click_listener(els[i]);
        }
    };
    
    add_click_listeners(document.querySelectorAll("a.btn"));

    var observer = new MutationObserver(function(mutations, observer) {
        for (var i = 0; i < mutations.length; i++) {
            if (mutations[i].addedNodes) {
                for (var x = 0; x < mutations[i].addedNodes.length; x++) {
                    var node = mutations[i].addedNodes[x];
                    
                    if (node.tagName === "A" && node.classList.contains("btn")) {
                        add_click_listener(node);
                    } else if (node.children && node.children.length > 0) {
                        add_click_listeners(node.querySelectorAll("a.btn"));
                    }
                }
            }
        }
    });
    observer.observe(document, {childList: true, subtree: true});
})();