├── nexusmods_downloadfix.meta.js ├── README.md └── nexusmods_downloadfix.user.js /nexusmods_downloadfix.meta.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Nexus Download Fix 3 | // @description Fixing the dumb new download system for nexusmods 4 | // @namespace randomtdev 5 | // @include *://www.nexusmods.com/*/mods/*?tab=files&file_id=* 6 | // @include *://www.nexusmods.com/*/mods/* 7 | // @grant none 8 | // @version 1.6.1 9 | // @author randomtdev 10 | // @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js 11 | // @homepageURL https://github.com/randomtdev/nexusmods_downloadfix 12 | // @run-at document-start 13 | // ==/UserScript== 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nexusmods_downloadfix 2 | Userscript to bypass the premium nag screen when downloading mods on nexus. 3 | 4 | ## Endorse Mods! ## 5 | 6 | People work quite a bit to deliver you the (probably)quality stuff you're using. The least you can do is press a button to let the mod developer know you enjoyed the mod. 7 | 8 | ## Download ## 9 | You can install the script below with your userscript manager of choice. 10 | 11 | Options include: 12 | 13 | * Tampermonkey ^[Chrome](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo) ^[Firefox](https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/) 14 | * Violentmonkey ^[Chrome](https://chrome.google.com/webstore/detail/violentmonkey/jinjaccalgkegednnccohejagnlnfdag) 15 | ^[Firefox](https://addons.mozilla.org/en-US/firefox/addon/violentmonkey/) 16 | 17 | I personally prefer Violentmonkey. 18 | 19 | After installing an extension of your choice, you can go to the install link and well.. install the script. 20 | 21 | [Install](https://github.com/randomtdev/nexusmods_downloadfix/raw/master/nexusmods_downloadfix.user.js) 22 | 23 | [Source](https://github.com/randomtdev/nexusmods_downloadfix) 24 | 25 | ### Updates #### 26 | 27 | **1.6.1** 28 | - Fix script not working for downloads with no mod requirements 29 | - Fix some buttons not being patched if not on the files tab 30 | 31 | **1.6** 32 | - Fix script 33 | - Made button patching more reliable 34 | - Merge derickso's PR to fix the script for premium users. 35 | 36 | **1.5.2** 37 | 38 | - Fixed top-right buttons not working properly if the mod has DLC/Mod requirements 39 | 40 | **1.5.1** 41 | 42 | - Fixed issue where closing requirements popup before downloading would stop download button from working properly when re-opening 43 | 44 | **1.5** 45 | 46 | - Improved patch process for buttons/requirement window. Requirement window download button should now always work properly. 47 | - Fixed issue where pressing the download button multiple times would come up with an error and redirect you to the premium page. 48 | - Fixed premium page auto-download fallback 49 | 50 | **Greasemonkey is no longer supported as of this version** 51 | 52 | It's a pain in the ass. 53 | 54 | 55 | **1.4** 56 | 57 | - Fix for new site update 58 | - Vortex banner is no longer being removed 59 | - Adblock banner is no longer removed (Not even sure this still exists) 60 | - Improved shitty patching system a bit 61 | - Cleaned up code quite a bit 62 | 63 | This new update makes getting the link for manual downloads a lot faster, courtesy of nexus staff. 64 | The script should also now work fine for premium users, if for some reason you're using this. 65 | 66 | **1.3.1** 67 | 68 | - Fixed an issue where the manual/vortex download buttons at the top right would give a "Download failed error" on mods with multiple main files 69 | 70 | **1.3(Compatibility is such a pain)** 71 | 72 | - Fixed jQuery issues? 73 | - Added a fallback in case the post_load detour fails; This makes it compatible with greasemonkey and well.. adds a fallback. 74 | - script now initializes using window.onload 75 | 76 | **1.2** 77 | 78 | - Fixed an issue where the script wouldn't work for greasemonkey. 79 | - Added auto-update urls; Might work, might not. 80 | 81 | **1.1**: 82 | 83 | - Fix: The server now knows you've downloaded the file so you can endorse the mod and probably count towards statistics. Whoops. 84 | 85 | ## What this does ## 86 | * Bypasses the redirect upon downloads that nags you to buy premium and forces you to wait 5 seconds if you don't. 87 | * Removes premium nag banner on files page 88 | 89 | ## What this does **NOT** do ## 90 | 91 | * Bypass the 1-2MB download speed restriction on non-premium users. 92 | * Block ads 93 | * Give you premium 94 | 95 | # **Disclaimer** # 96 | 97 | The script is in the end a roundabout way to bypass the redirect. The actual speed will depend on your connection and latency to the nexusmods servers among other factors. Sometimes preparing a download will take 5 seconds regardless. Still, you will skip the annoying redirects. 98 | -------------------------------------------------------------------------------- /nexusmods_downloadfix.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Nexus Download Fix 3 | // @description Bypass premium nag screen for downloads on nexusmods. 4 | // @namespace randomtdev 5 | // @include *://www.nexusmods.com/*/mods/*?tab=files&file_id=* 6 | // @include *://www.nexusmods.com/*/mods/* 7 | // @grant none 8 | // @version 1.6.1 9 | // @author randomtdev 10 | // @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js 11 | // @homepageURL https://github.com/randomtdev/nexusmods_downloadfix 12 | // @run-at document-start 13 | // ==/UserScript== 14 | 15 | this.$ = this.jQuery = jQuery.noConflict(true); 16 | 17 | function GetDownloadButtons() { 18 | return $('a.btn.inline-flex[data-tracking*="Download"]') 19 | } 20 | 21 | function GetButtonLabel(button) { 22 | if (!button) 23 | { 24 | return 25 | } 26 | var element = button.getElementsByTagName("span")[0] 27 | if (!element) { 28 | element = button 29 | } 30 | 31 | return element.innerHTML 32 | } 33 | 34 | function SetButtonLabel(button, text) { 35 | if (!button) 36 | { 37 | return 38 | } 39 | 40 | var element = button.getElementsByTagName("span")[0] 41 | if (!element) { 42 | element = button 43 | } 44 | 45 | let oldText = element.innerHTML 46 | element.innerHTML = text 47 | } 48 | 49 | function DownloadFile(href, button) 50 | { 51 | console.log("Attempting to download file from link", href) 52 | 53 | var q = $("#section.modpage") 54 | if (q.length > 0) 55 | { 56 | var section = q[0] 57 | var params = new URLSearchParams(new URL(href, document.URL).search) 58 | var gameId = section.getAttribute("data-game-id") 59 | var fileId = params.get("file_id") || params.get("id") 60 | 61 | var originalText = GetButtonLabel(button) 62 | if (params.get("nmm")) 63 | { 64 | console.log("Requesting premium page to get NXM protocol link") 65 | SetButtonLabel(button, "Getting link...") 66 | 67 | $.ajax({ 68 | url: href, 69 | data: "", 70 | success: function (response) { 71 | var prem = false 72 | var match = response.match(/data-download-url="(.*)"/) 73 | // Premium 74 | if (!match) { 75 | match = response.match(/id="dl_link" value="(.*)"/) 76 | prem = true 77 | } 78 | 79 | if (!match) { 80 | DisplayPopup("DownloadFix script error", "Download Failed! Are you logged in?") 81 | SetButtonLabel(button, originalText) 82 | return 83 | } 84 | 85 | // URL Param symbols in the html are escaping for some reason when they weren't before, so this is a hack to fix that. 86 | var url = match[1].replaceAll(";", "&") 87 | 88 | console.log("Got nxm link ", url) 89 | window.location.href = url 90 | 91 | if (prem) { 92 | $.magnificPopup.close(); 93 | } 94 | 95 | SetButtonLabel(button, "Got link!") 96 | 97 | setTimeout(function () { 98 | SetButtonLabel(button, originalText) 99 | if (button) 100 | button.downloading = false 101 | }, 5000) 102 | ClosePopUp() // Close mod requirements popup if any 103 | } 104 | }); 105 | } 106 | else 107 | { 108 | console.log("Requesting download URL for file", fileId, "with game ID", gameId) 109 | 110 | SetButtonLabel(button, "Getting link...") 111 | $.ajax( 112 | { 113 | type: "POST", 114 | url: "/Core/Libs/Common/Managers/Downloads?GenerateDownloadUrl", 115 | data: { 116 | fid: fileId, 117 | game_id: gameId, 118 | }, 119 | success: function (data) { 120 | if (button) 121 | { 122 | button.downloading = false 123 | SetButtonLabel(button, originalText) 124 | } 125 | 126 | if (data && data.url) { 127 | window.location.href = data.url; 128 | 129 | // This is pretty pointless because you can't use them, but whatever. 130 | $('a svg.icon-endorse').parent().removeClass('btn-inactive'); 131 | $('a svg.icon-vote').parent().removeClass('btn-inactive'); 132 | $.magnificPopup.close(); 133 | 134 | ClosePopUp() // Close mod requirements popup if any 135 | } else { 136 | console.error("GenerateDownloadUrl failed; Got data ", data) 137 | DisplayPopup("DownloadFix script error", "Download Failed! Request went through, but couldn't get URL.\n\nAre you logged in?") 138 | } 139 | }, 140 | error: function (_, s, e) { 141 | if (button) 142 | { 143 | button.downloading = false 144 | SetButtonLabel(button, originalText) 145 | } 146 | 147 | console.error("Download request failed for file", fileId, s, e) 148 | DisplayPopup("DownloadFix script error", "Download request failed!") 149 | } 150 | } 151 | ); 152 | } 153 | 154 | } 155 | else 156 | { 157 | console.error("uhhh is the page loaded yet?") 158 | } 159 | } 160 | 161 | function PatchButton(button) { 162 | var link = button.getAttribute("href") 163 | 164 | if (!link) 165 | { 166 | console.log("btn has no href") 167 | return false 168 | } 169 | 170 | if (link.includes("ModRequirementsPopUp") || link.includes("download-top-left-panel")) 171 | { 172 | return false 173 | } 174 | 175 | button.addEventListener("click", function (e) { 176 | e.preventDefault() 177 | 178 | if (!button.downloading) // Make sure we're not sending more requests while downloading; Won't work anyway. 179 | { 180 | button.downloading = true 181 | DownloadFile(link, button) 182 | } 183 | 184 | }) 185 | 186 | button.patched = true 187 | return true 188 | } 189 | 190 | function IsDownloadButton(button) 191 | { 192 | var params = new URLSearchParams(new URL(button.getAttribute("href"), document.URL).search) 193 | return params.get("file_id") || (params.get("id") && params.get("game_id")) 194 | } 195 | 196 | function PatchDownloadButtons() { 197 | /*if (document.URL.indexOf("?tab=files") == -1) 198 | { 199 | return false 200 | }*/ 201 | 202 | var count = 0 203 | var buttons = GetDownloadButtons() 204 | if (buttons.length == 0) { 205 | return false 206 | } 207 | 208 | for (var i = 0; i < buttons.length; i++) { 209 | var btn = buttons[i] 210 | if (btn) { 211 | if (btn.patched) { 212 | continue 213 | } 214 | 215 | if (IsDownloadButton(btn)) 216 | { 217 | PatchButton(btn) 218 | count++; 219 | } 220 | 221 | } 222 | } 223 | 224 | console.log("Patched", count, "download buttons") 225 | return true 226 | } 227 | 228 | function RemoveAdblockBanner() { 229 | if ($(".premium-banner").remove().length > 0) // oh no not the premium banner 230 | { 231 | console.log("Removed premium nag banner") 232 | } 233 | } 234 | 235 | function InitializePatches() 236 | { 237 | if (!PatchDownloadButtons()) { 238 | console.error("Looks like we failed to do button patches without an exception some reason. No buttons?") 239 | } 240 | } 241 | 242 | function Initialize() { 243 | if (document.URL.indexOf("&file_id=") == -1) // Is this NOT the download page? 244 | { 245 | InitializePatches() 246 | RemoveAdblockBanner() 247 | 248 | window.jQuery(document).ajaxComplete(function (e, request, settings) { 249 | if (settings.url.indexOf("ModFilesTab") != -1) // Was the files tab just loaded? 250 | { 251 | InitializePatches() // re-do button patches then 252 | RemoveAdblockBanner() 253 | } 254 | 255 | if (settings.url.indexOf("ModRequirementsPopUp") != -1) // Patch any popup download buttons 256 | { 257 | let btn = $(".widget-mod-requirements > a") 258 | if (btn) 259 | { 260 | //btn.css('background-color', '#EB8E01'); 261 | PatchButton(btn[0]) 262 | console.log("Patched popup button") 263 | } 264 | } 265 | 266 | }) 267 | 268 | /*if (document.URL.indexOf("?tab=files") > -1) // Do initial patches if we're loading the files page directly. 269 | { 270 | InitializePatches() 271 | RemoveAdblockBanner() 272 | }*/ 273 | 274 | return 275 | } 276 | else 277 | { 278 | // This portion was here before I did the button patching; Leaving it here as a failsafe in case patching fails or bugs out. 279 | // Cleaned up and adapted for new workaround. 280 | var slowBtn = $('#slowDownloadButton') 281 | var fastBtn = $('#fastDownloadButton') 282 | 283 | console.log("Downloading file") 284 | 285 | DownloadFile(document.URL) // Auto download in case this page comes up 286 | } 287 | } 288 | window.onload = Initialize 289 | --------------------------------------------------------------------------------