diff --git a/INFOS/GOG Links.md b/INFOS/GOG Links.md index 5775e0c..d7d5c2d 100644 --- a/INFOS/GOG Links.md +++ b/INFOS/GOG Links.md @@ -1,7 +1,8 @@ ### USE CASE: -------------- Lazy game discovery. This userscript will add 2 new buttons to Gog.com; one to search for non(voice)commented gameplay videos -on youtube to roughly judge gameplay, and one for searching that game on gog-games.to for download. +on youtube to roughly judge gameplay, and one for searching that game on torrminatorr forum for download. +ATTENTION: IT IS NOW REQUIRED TO HAVE A USER ON TORRMINATORR TO WORK WITH THIS EXTENSION. ### USAGE: --------------- diff --git a/INFOS/GOG-Games Links.md b/INFOS/GOG-Games Links.md index 464997b..7173420 100644 --- a/INFOS/GOG-Games Links.md +++ b/INFOS/GOG-Games Links.md @@ -1,35 +1,27 @@ ### USE CASE: -------------- -Direct discovery of games on gog-games. +~~Direct discovery of games on gog-games.~~ ### USAGE: --------------- -Just click the purple button to search for a gameplay video of the selected game without annoying youtubers -screaming and mumbling word salads or click the orange button to HOPEFULLY get a changelog FROM STEAM. +~~Just click the purple button to search for a gameplay video of the selected game without annoying youtubers +screaming and mumbling word salads or click the orange button to HOPEFULLY get a changelog FROM STEAM.~~ -DISCLAIMER: -The script will search the dedicated steam "news hub" for the game using DuckDuckGo (because changelog pages -use the game numeric id instead of game name) in an effort to show you a changelog of the game but there are many conditions -for this to serve its purpose: +~~Gog-games will go offline on September 6 2026~~, according to the site owner: +> PLEASE READ: It has been decided that all operations will cease (no new +games, updates, etc.) and the site will go offline in 90 days from this +message (September 6). This was a personal decision and not because of +any legal pressure. All remaining funds (around 700 EUR in XMR) will be +donated to torrminatorr. ❤️ A huge thank you to anyone who donated. Your funds will be going to a good home. ❤️ -1- It simply makes a search on DDG for the "steam news hub" for that specific game, you will have to click the result to get -there (usually "[GAMENAME] - Steam News Hub" result) +I cannot imagine the face of the donors ❤️❤️❤️ 🤣😂 -2- I've chosen "steam news hub" to check for changelogs since developers focus more on steam than on gog releases of -their games; in other words, __they usually don't create changelogs for gog released games.__ Gogdb changelogs are -mostly outdated for a lot of games. - -3- Steam changelogs may differ from gog release of the same game in some aspects. - -4- There may not be any changelogs or may be completely abandoned. - -5- We rely on the devs maintaining the changelogs, so check the version before assuming anything. ### WHY?: --------------- -Sometimes, you just start your search for "available" games on gog-games directly instead of gog.com. The problem is that gog-games didn't have the possibility to quickly search for gameplay videos and changelogs. This userscript comes to fix that. +~~Sometimes, you just start your search for "available" games on gog-games directly instead of gog.com. The problem is that gog-games didn't have the possibility to quickly search for gameplay videos and changelogs. This userscript comes to fix that.~~ --------------- -[INSTALL LINK](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/--GOG-Games%20Links--.user.js) -You must have violentmonkey installed for this to work. +~~[INSTALL LINK](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/--GOG-Games%20Links--.user.js) +You must have violentmonkey installed for this to work.~~ diff --git a/INFOS/NSFW.XXX_Downloader.md b/INFOS/NSFW.XXX_Downloader.md new file mode 100644 index 0000000..db4a4e6 --- /dev/null +++ b/INFOS/NSFW.XXX_Downloader.md @@ -0,0 +1,22 @@ +### USE CASE: +-------------- +One click download. + +### USAGE: +--------------- +Click on the green download button. + +UPDATE 3.1: Fixed the script for the changes in nsfw.xxx. Changed button size and color. + + +### WHY?: +--------------- +Just a helper. + +--------------- +[INSTALL LINK](https://github.com/masterofobzene/UserScriptRepo/raw/refs/heads/main/NSFW/NSFW.XXX%20Downloader.user.js) +You must have violentmonkey installed for this to work. + + + + diff --git a/INFOS/NSFW Button Downloaders.md b/INFOS/Realbooru_Downloader.md similarity index 73% rename from INFOS/NSFW Button Downloaders.md rename to INFOS/Realbooru_Downloader.md index b7b85ae..1889e91 100644 --- a/INFOS/NSFW Button Downloaders.md +++ b/INFOS/Realbooru_Downloader.md @@ -1,11 +1,12 @@ ### USE CASE: -------------- -Download individual files from this especific site. If you want massive downloading, use gallery-dl instead! +Download individual files from realbooru with a single click on a button. If you want massive downloading, use gallery-dl instead! ### USAGE: --------------- Just click the "Download" button. +1.8: Updated to work again. ### WHY?: --------------- diff --git a/INFOS/Steam Links.md b/INFOS/Steam Links.md index 61972a9..65d69dc 100644 --- a/INFOS/Steam Links.md +++ b/INFOS/Steam Links.md @@ -4,7 +4,7 @@ Lazy game discovery and acquisition on clean sites, using Steam as a catalog. ### USAGE: --------------- -On each game shop page, you will have 6 big green buttons, each will search for the game in +On each game shop page, you will have 5 big green buttons, each will search for the game in different known-to-be-safe sites, some for review, some for dl. It also has one link to search for non-commented youtube gameplay videos, and one for checking if the game has been "infected" with DEI policies by searching for it on deidetected.com. diff --git a/INFOS/deepseek-answer-in-english.md b/INFOS/deepseek-answer-in-english.md new file mode 100644 index 0000000..5bcc430 --- /dev/null +++ b/INFOS/deepseek-answer-in-english.md @@ -0,0 +1,22 @@ +### USE CASE: +-------------- +Force Deepseek to use english. + +### USAGE: +--------------- +Just install it. A Checkbox will appear on the top right to turn ON or OFF this script. + + +### WHY?: +--------------- +Recently Deepseek started giving me a lot of answers in chinese (randomly and in the middle of an ongoing prompt). +This started randomly in very rare ocassions but now it has became an annoyance for the non-chinese speakers. So +with this dumb script we will append "answer in english" to every prompt. + +--------------- +[INSTALL LINK](https://github.com/masterofobzene/UserScriptRepo/raw/refs/heads/main/SFW/deepseek-answer-in-english.user.js) +You must have violentmonkey installed for this to work. + + + + diff --git a/INFOS/deepseek-concise.md b/INFOS/deepseek-concise.md new file mode 100644 index 0000000..8f321d1 --- /dev/null +++ b/INFOS/deepseek-concise.md @@ -0,0 +1,19 @@ +### USE CASE: +-------------- +Stop deepseek quackery and get to the point. + +### USAGE: +--------------- +Click the checkmark in the new box that appears on the upper right of the page. + +### WHY?: +--------------- +Deepseek is unbearable with its answers being walls of text and things nobody asked for that will quickly fill your context. +This script is very dumb, it only adds the phrase "be concise" at the end of every prompt you write after sending it, so +DS stops giving walls of useless text. + +--------------- +[INSTALL LINK](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/deepseek-concise.user.js) +You must have violentmonkey installed for this to work. + + diff --git a/INFOS/reddtastic_downloader.md b/INFOS/reddtastic_downloader.md new file mode 100644 index 0000000..4f01dff --- /dev/null +++ b/INFOS/reddtastic_downloader.md @@ -0,0 +1,20 @@ +### USE CASE: +-------------- +Download individual files from reddtastic with a single click on a button. If you want massive downloading, use gallery-dl instead! + +### USAGE: +--------------- +Just click the "Download" button. + +1.4.9: Removed "IDM" references that never worked. Changed button color for better visibility. Made button smaller. + +### WHY?: +--------------- +To avoid downloading trash and focus on what we want. Also it is way more lazy than having to +follow each link and manually clicking "save as". + +--------------- +[INSTALL LINK](https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/Reddtastic%20Downloader.user.js) +You must have violentmonkey installed for this to work. + + diff --git a/NSFW/NSFW.XXX Downloader.user.js b/NSFW/NSFW.XXX Downloader.user.js index 19a5372..edfb0a0 100644 --- a/NSFW/NSFW.XXX Downloader.user.js +++ b/NSFW/NSFW.XXX Downloader.user.js @@ -1,9 +1,9 @@ // ==UserScript== // @name NSFW.XXX Downloader // @namespace NSFW.XXX-Downloader -// @version 3.0 +// @version 3.1 // @icon https://nsfw.xxx/favicon.ico -// @description Download full-resolution images/videos from NSFW.XXX posts +// @description Download full-resolution images/videos from NSFW.XXX // @author masterofobzene // @homepage https://github.com/masterofobzene/UserScriptRepo // @match https://nsfw.xxx/* @@ -13,6 +13,8 @@ // @grant GM_addStyle // @connect nsfw.xxx // @connect cdn2.nsfw.xxx +// @connect cdn3.nsfw.xxx +// @connect cdn4.nsfw.xxx // @connect * // @downloadURL https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/NSFW.XXX%20Downloader.user.js // @updateURL https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/NSFW.XXX%20Downloader.user.js @@ -21,15 +23,14 @@ (function() { 'use strict'; - // --- Button styles --- GM_addStyle(` .nsfw-download-btn { position: absolute !important; bottom: 10px !important; right: 10px !important; z-index: 99999 !important; - background: #4CAF50 !important; - color: white !important; + background: #19FF19 !important; + color: black !important; border: none !important; border-radius: 4px !important; padding: 5px 10px !important; @@ -38,72 +39,39 @@ opacity: 0.9 !important; transition: opacity 0.2s !important; } - .nsfw-download-btn:hover { - opacity: 1 !important; - } - .media-container { - position: relative !important; - } + .nsfw-download-btn:hover { opacity: 1 !important; } + .post { position: relative !important; } `); - // --- Inject buttons into each media container --- function addDownloadButtons() { - document.querySelectorAll('.sh-section__image, .sh-section__media, .post-media, .image-container').forEach(container => { - if (container.querySelector('.nsfw-download-btn')) return; + document.querySelectorAll('.post:not([data-nsfw-dl])').forEach(card => { + card.setAttribute('data-nsfw-dl', '1'); const btn = document.createElement('button'); btn.className = 'nsfw-download-btn'; - btn.textContent = '↓ Download'; + btn.textContent = 'DL↓'; btn.addEventListener('click', async e => { - e.preventDefault(); e.stopPropagation(); - await onDownloadClick(container, btn); + e.preventDefault(); + e.stopPropagation(); + await onDownloadClick(card, btn); }); - container.classList.add('media-container'); - container.appendChild(btn); + card.appendChild(btn); }); } - // --- Handle button click --- - async function onDownloadClick(container, btn) { + async function onDownloadClick(card, btn) { btn.disabled = true; btn.textContent = 'Finding source...'; try { - let url = await extractMediaUrl(container); - if (!url) throw new Error('No media source found'); + const postLink = card.querySelector('a.post--link'); + if (!postLink || !postLink.href) throw new Error('No post link found'); + const url = await fetchFullResFromPost(postLink.href); + if (!url) throw new Error('No media source found on post page'); await downloadFile(url, btn); } catch (err) { notifyError(err, btn); } } - // --- Extract the best media URL from the container --- - async function extractMediaUrl(container) { - // 1. Direct full-res image already in page? - let img = container.querySelector('img'); - if (img && img.src && !img.src.includes('/thumbnails/')) { - return img.src; - } - - // 2. If it's still a thumbnail, follow the post link - if (img && (img.src.includes('/thumbnails/') || img.dataset.src?.includes('/thumbnails/'))) { - const link = img.closest('a.slider_init_href'); - if (!link || !link.href) { - throw new Error('Cannot find post link for thumbnail'); - } - return await fetchFullResFromPost(link.href); - } - - // 3. Fallback: video preview container - const vid = container.querySelector('video source'); - if (vid && vid.src) return vid.src; - - // 4. Iframe or other embed - const iframe = container.querySelector('iframe'); - if (iframe && iframe.src) return iframe.src; - - return null; - } - - // --- Fetch the post page and scrape the real full-res media URL --- async function fetchFullResFromPost(postUrl) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ @@ -113,17 +81,25 @@ try { const doc = new DOMParser().parseFromString(response.responseText, 'text/html'); - // Look *only* inside the .sh-section__image container for big images - const images = doc.querySelectorAll('.sh-section__image img'); - for (let img of images) { - const src = img.getAttribute('src') || img.dataset.src; - // Must be a real upload (not still thumbnail) - if (src && !src.includes('/thumbnails/') && src.includes('/uploads')) { + // 1. Look for an with /uploads in the src (not thumbnails) + for (const img of doc.querySelectorAll('img')) { + const src = img.getAttribute('src') || img.dataset.src || ''; + if (src.includes('/uploads') && !src.includes('/thumbnails/')) { return resolve(src); } } - // If no suitable image, try video + // 2. Check Vuetify background image on .v-image__image + const bgDiv = doc.querySelector('.v-image__image'); + if (bgDiv) { + const style = bgDiv.getAttribute('style') || ''; + const match = style.match(/url\("([^"]+)"\)/); + if (match && match[1] && match[1].includes('/uploads') && !match[1].includes('/thumbnails/')) { + return resolve(match[1]); + } + } + + // 3. Video source const videoSrc = doc.querySelector('video source')?.src; if (videoSrc) return resolve(videoSrc); @@ -132,14 +108,11 @@ reject(new Error('Error parsing post page HTML.')); } }, - onerror() { - reject(new Error('Failed to fetch post page.')); - } + onerror() { reject(new Error('Failed to fetch post page.')); } }); }); } - // --- Download via GM_download and update button state --- async function downloadFile(url, btn) { let filename = url.split('/').pop().split('?')[0].replace(/[^a-zA-Z0-9\.\-_]/g, '_'); btn.textContent = 'Downloading...'; @@ -148,32 +121,25 @@ onload() { btn.textContent = '✓ Done'; setTimeout(() => { - btn.textContent = '↓ Download'; + btn.textContent = 'DL↓'; btn.disabled = false; }, 2000); }, - onerror(err) { - notifyError(new Error(`Download failed: ${err.error}`), btn); - }, - ontimeout() { - notifyError(new Error('Download timed out'), btn); - } + onerror(err) { notifyError(new Error(`Download failed: ${err.error}`), btn); }, + ontimeout() { notifyError(new Error('Download timed out'), btn); } }); } - // --- Error handler --- function notifyError(err, btn) { console.error(err); GM_notification({ title: 'Download Error', text: err.message, timeout: 5000 }); - btn.textContent = '↓ Download'; + btn.textContent = 'DL↓'; btn.disabled = false; } - // --- Watch for dynamically loaded content --- - new MutationObserver(muts => muts.forEach(m => m.addedNodes.length && addDownloadButtons())) - .observe(document.body, { childList: true, subtree: true }); + new MutationObserver(muts => { + for (const m of muts) if (m.addedNodes.length) addDownloadButtons(); + }).observe(document.body, { childList: true, subtree: true }); - // --- Initial run --- addDownloadButtons(); - })(); diff --git a/NSFW/Realbooru Downloader.user.js b/NSFW/Realbooru Downloader.user.js index 8a254c3..aaa829b 100644 --- a/NSFW/Realbooru Downloader.user.js +++ b/NSFW/Realbooru Downloader.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Realbooru Downloader // @namespace Realbooru-Downloader -// @version 1.7 +// @version 1.8 // @icon https://realbooru.com/favicon.ico // @author masterofobzene // @homepage https://github.com/masterofobzene/UserScriptRepo @@ -29,7 +29,7 @@ border-radius: 3px; cursor: pointer; font-weight: bold; - font-size: 10px; + font-size: 17px; z-index: 9999; `; @@ -38,29 +38,59 @@ const pathname = new URL(url).pathname; return decodeURIComponent(pathname.substring(pathname.lastIndexOf('/') + 1)) || 'file'; } catch (e) { - console.error('❌ Error parsing filename from URL:', url, e); + console.error('❌ Error parsing filename:', url, e); return 'file'; } } - function extractFullMediaUrl(html) { + function extractFullMediaUrl(html, baseUrl) { const doc = new DOMParser().parseFromString(html, 'text/html'); + const base = baseUrl || doc.baseURI; - const image = doc.querySelector('#image'); - if (image?.src) return image.src; + const img = doc.querySelector('#image'); + if (img?.src) return new URL(img.getAttribute('src'), base).href; - const video = doc.querySelector('video source'); - if (video?.src) return video.src; + const videoSrc = doc.querySelector('video source'); + if (videoSrc?.src) return new URL(videoSrc.getAttribute('src'), base).href; - const meta = doc.querySelector('meta[property="og:video"]'); - if (meta?.content) return meta.content; + const metaImg = doc.querySelector('meta[property="og:image"]'); + if (metaImg?.content) return new URL(metaImg.content, base).href; + const metaVid = doc.querySelector('meta[property="og:video"]'); + if (metaVid?.content) return new URL(metaVid.content, base).href; - const ogImage = doc.querySelector('meta[property="og:image"]'); - if (ogImage?.content) return ogImage.content; + const origLink = doc.querySelector('a[href*="/images/"]'); + if (origLink) return new URL(origLink.getAttribute('href'), base).href; return null; } + function downloadFile(url, filename, referer) { + GM_xmlhttpRequest({ + method: 'GET', + url: url, + responseType: 'blob', + headers: { 'Referer': referer }, + onload: function (resp) { + if (resp.status === 200) { + const blob = resp.response; + const blobUrl = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = blobUrl; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(blobUrl); + } else { + console.error('❌ Download failed, status:', resp.status); + } + }, + onerror: function (err) { + console.error('❌ Download error:', err); + } + }); + } + function createDownloadButton(postUrl) { const btn = document.createElement('button'); btn.textContent = '⬇'; @@ -70,7 +100,6 @@ btn.addEventListener('click', async (e) => { e.preventDefault(); e.stopPropagation(); - console.log(`🔄 Fetching: ${postUrl}`); try { const response = await new Promise((resolve, reject) => { @@ -82,20 +111,13 @@ }); }); - const fullUrl = extractFullMediaUrl(response.responseText); + const fullUrl = extractFullMediaUrl(response.responseText, postUrl); if (!fullUrl) { - console.error('❌ Media URL not found'); + console.error('❌ Could not extract media URL.'); return; } - const filename = getFilenameFromUrl(fullUrl); - GM_download({ - url: fullUrl, - name: filename, - saveAs: false, - onerror: (err) => console.error('❌ Download error:', err), - onload: () => console.log('✅ Downloaded:', filename), - }); + downloadFile(fullUrl, getFilenameFromUrl(fullUrl), postUrl); } catch (err) { console.error('❌ Failed to fetch post page:', err); } @@ -117,19 +139,10 @@ selectors.forEach(selector => { document.querySelectorAll(selector).forEach(element => { - // Find the main post container const container = element.closest('div.thumb, article.thumbnail-preview, div.thumbnail-container') || element; - - // Skip if container already has a button if (container.querySelector('.realbooru-download-button')) return; - - // Find the post link - const link = element.href ? element : - element.querySelector('a[href*="page=post&s=view"]'); - + const link = element.href ? element : element.querySelector('a[href*="page=post&s=view"]'); if (!link || !link.href) return; - - // Prepare container and add button container.style.position = 'relative'; const btn = createDownloadButton(link.href); container.appendChild(btn); @@ -140,10 +153,8 @@ if (count > 0) console.log(`✅ Added ${count} download button(s).`); } - // Initial run setTimeout(addButtons, 1000); - // MutationObserver for dynamic content new MutationObserver(addButtons).observe(document.body, { childList: true, subtree: true diff --git a/NSFW/Reddtastic Downloader.user.js b/NSFW/Reddtastic Downloader.user.js index d1a73a8..6cae203 100644 --- a/NSFW/Reddtastic Downloader.user.js +++ b/NSFW/Reddtastic Downloader.user.js @@ -1,16 +1,12 @@ // ==UserScript== // @name Reddtastic Downloader -// @namespace Reddtastic-Downloader -// @homepage https://github.com/masterofobzene/UserScriptRepo -// @author masterofobzene -// @version 1.4.8 -// @description Shows a download button for each thumbnail to download the full res file. +// @namespace https://reddtastic.com/ +// @version 1.4.9 +// @description Shows a button for downloading media on each thumbnail. // @match https://reddtastic.com/* // @icon https://reddtastic.com/favicon.ico // @grant GM_download // @grant GM_xmlhttpRequest -// @grant GM_registerMenuCommand -// @connect * // @downloadURL https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/Reddtastic%20Downloader.user.js // @updateURL https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/Reddtastic%20Downloader.user.js // ==/UserScript== @@ -27,7 +23,7 @@ top: 5px; right: 5px; z-index: 9999; padding: 4px 8px; - background: rebeccapurple; + background: #FF00FF; color: white; font-size: 12px; font-weight: bold; @@ -39,14 +35,7 @@ `; document.head.appendChild(style); - GM_registerMenuCommand("Set Download Method", function () { - const method = prompt("Choose download method:\n1. IDM (recommended)\n2. Firefox Native", "1"); - localStorage.setItem('rdDownloadMethod', method === "2" ? "firefox" : "idm"); - }); - - function getDownloadMethod() { - return localStorage.getItem('rdDownloadMethod') || 'idm'; - } + // ---- removed: GM_registerMenuCommand & getDownloadMethod ---- function randStr(len = 8) { return Math.random().toString(36).substr(2, len); @@ -70,40 +59,18 @@ }); } - function triggerIDMDownload(url, filename) { - const a = document.createElement('a'); - a.href = url; - a.download = filename || url.split('/').pop() || `reddit_${randStr()}.jpg`; - a.style.display = 'none'; - document.body.appendChild(a); - a.click(); - setTimeout(() => document.body.removeChild(a), 100); - } + // ---- removed: triggerIDMDownload ---- function doDownload(url, defaultName) { - const method = getDownloadMethod(); - - if (method === 'firefox') { - GM_download({ - url: url, - name: defaultName, - saveAs: false, - onerror: () => { - console.warn('GM_download failed, falling back to IDM click method.'); - triggerIDMDownload(url, defaultName); - } - }); - } else { - GM_download({ - url: url, - name: defaultName, - saveAs: false, - onerror: () => { - console.warn('GM_download failed, falling back to fake link click.'); - triggerIDMDownload(url, defaultName); - } - }); - } + // Always use native GM_download – fallback to IDM removed + GM_download({ + url: url, + name: defaultName, + saveAs: false, + onerror: () => { + console.warn('GM_download failed for:', url); + } + }); } function makeBtn(parent, onClick) { @@ -112,8 +79,8 @@ parent.classList.add('vm-dl-wrap'); const btn = document.createElement('button'); btn.className = 'vm-dl-btn'; - btn.textContent = 'Download (IDM)'; - btn.title = 'Download with IDM'; + btn.textContent = 'DL⬇'; // changed from "Download (IDM)" + btn.title = 'Download'; // changed from "Download with IDM" btn.addEventListener('click', e => { e.stopPropagation(); e.preventDefault(); diff --git a/README.md b/README.md index f1e116c..12840a4 100644 --- a/README.md +++ b/README.md @@ -15,17 +15,20 @@ Click on the script name to install it. All scripts here were made for Firefox/L ### SFW ----------- -[::GOG Links::](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/--GOG%20Links--.user.js) Adds links for GOG store to gameplay videos without youtubers comments and direct search on Gog-games for free clean download. +[::GOG Links::](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/--GOG%20Links--.user.js) Adds links for GOG store to gameplay videos without youtubers comments and direct search on Torrminatorr for free clean download. - +GeaabI9Wys [DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/GOG%20Links.md) ----------- -[::GOG-Games Links::](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/--GOG-Games%20Links--.user.js) Adds "Gameplay Video" and "Changelog" buttons per game card to search for no-commentary gameplay videos and if lucky, a changelog. +~~[::GOG-Games Links::](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/--GOG-Games%20Links--.user.js)~~ ~~Adds "Gameplay Video" and "Changelog" buttons per game card to search for no-commentary gameplay videos and if lucky, a changelog.~~ + +Gog-games admin says he is not updating the site anymore and will close the site on September 6/2026. RIP gog-games.to 👋, now GET YOUR torrminatorr account created (free) and use the other scripts that are updated for it to search for your games! 😁 + +so long gog-games - [DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/GOG-Games%20Links.md) @@ -34,7 +37,8 @@ Click on the script name to install it. All scripts here were made for Firefox/L [::Steam Links::](https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/--Steam%20Links--.user.js) Lets you easily search the games on clean DL sites, watch gameplays without youtuber's comments and see if the game is woke-oriented. - +E9MtE02Pbt + [DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/Steam%20Links.md) @@ -99,7 +103,7 @@ above if you see prices in other currency. ----------- -[Steam Bad Reviews](https://github.com/masterofobzene/UserScriptRepo/raw/refs/heads/main/SFW/Steam_Bad_Reviews.user.js) Automatically switches to "bad reviews" when visiting the game page so you can judge the game a little bit better. +[Steam Bad Reviews](https://github.com/masterofobzene/UserScriptRepo/raw/refs/heads/main/SFW/Steam_Bad_Reviews.user.js) Automatically switches to "negative reviews" when visiting the game page so you can judge the game a little bit better. @@ -163,6 +167,28 @@ above if you see prices in other currency. ----------- +[DeepSeek be concise](https://github.com/masterofobzene/UserScriptRepo/raw/refs/heads/main/SFW/deepseek-concise.user.js) Makes DeepSeek give concise answers instead of walls of text. + +e65aw4NRcw + + + +[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/deepseek-concise.md) + +----------- + + +[DeepSeek always in english](https://github.com/masterofobzene/UserScriptRepo/raw/refs/heads/main/SFW/deepseek-answer-in-english.user.js) Makes DeepSeek give answers in english instead of randomly using chinese. + +2MepdZsKOX + + + + +[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/deepseek-answer-in-english.md) + +----------- +


@@ -174,24 +200,17 @@ above if you see prices in other currency. [NSFW.XXX Downloader](https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/NSFW.XXX%20Downloader.user.js) Download full-resolution images/videos from NSFW.XXX posts -[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/NSFW%20Button%20Downloaders.md) +[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/NSFW.XXX_Downloader.md) ----------- [Realbooru Downloader](https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/Realbooru%20Downloader.user.js) Download full-resolution images and videos from Realbooru posts with a small button -[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/NSFW%20Button%20Downloaders.md) +[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/Realbooru_Downloader.md) ----------- [Reddtastic Downloader](https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/Reddtastic%20Downloader.user.js) Shows a download button for each thumbnail to download the full res file. -[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/NSFW%20Button%20Downloaders.md) - ------------ -~~Successor of zzup~~ - -~~[up2img Infinite Scroll](https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/ZZup%20Infinite%20Scroll.user.js)~~ ~~Repaginates up2img.com so you get "infinite scroll"~~ - -~~[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/ZZup%20Infinite%20Scroll.md)~~ +[DESCRIPTION](https://github.com/masterofobzene/UserScriptRepo/blob/main/INFOS/reddtastic_downloader.md) ----------- [Pornpaw Gallery Filter](https://github.com/masterofobzene/UserScriptRepo/raw/main/NSFW/ZZup%20Infinite%20Scroll.user.js) Lets you filter galleries by using words that can be found in any the title or the tags of the galleries @@ -264,10 +283,18 @@ Description: Select text -> right click -> "search this" -> searches those words +
+
+
+
+-------------------------- - +> [!TIP] +> - azRggiVKee – This button is **not** for installing anything. +> - g41eGfc03s – This button is to show that you **like** this repo. +> - fIVz9FY5CQ – This button is to **get spam** every time I modify something. diff --git a/SFW/--GOG Links--.user.js b/SFW/--GOG Links--.user.js index 0a55ebb..cca96c2 100644 --- a/SFW/--GOG Links--.user.js +++ b/SFW/--GOG Links--.user.js @@ -2,8 +2,8 @@ // @name ::GOG Links:: // @namespace masterofobzene // @author masterofobzene -// @version 1.9 -// @description Adds links for GOG store to gameplay videos without youtubers comments and direct search on Gog-games for free clean download. +// @version 2.0 +// @description Adds links for GOG store to gameplay videos without youtubers comments and direct search on Torrminatorr for free clean download. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js // @match *://www.gog.com/*/game/* // @homepage https://github.com/masterofobzene/UserScriptRepo @@ -17,9 +17,9 @@ var pirateLinks = [ { - url: "https://gog-games.to/?search=", + url: "https://forum.torrminatorr.com/search.php?keywords=", urlSpecial: "", - title: "Search on GoG-Games" + title: "Search on Torrminatorr" }, { url: "https://www.youtube.com/results?search_query=", diff --git a/SFW/--Steam Links--.user.js b/SFW/--Steam Links--.user.js index 48031f3..25566b3 100644 --- a/SFW/--Steam Links--.user.js +++ b/SFW/--Steam Links--.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name ::Steam Links:: // @namespace Steam-Links -// @version 2.2 +// @version 2.3 // @icon https://cdn.freebiesupply.com/images/large/2x/steam-logo-black-transparent.png // @description Lets you easily search the games on clean DL sites, watch gameplays without youtuber's comments and see if the game is woke-oriented. // @author masterofobzene @@ -32,11 +32,10 @@ // Sites configuration const sites = [ - { name: 'GOG Games', url: `https://gog-games.to/?search=${encodeURIComponent(gameName)}`}, { name: 'CS.RIN.RU', url: `https://cs.rin.ru/forum/search.php?keywords=${encodeURIComponent(gameName)}` + '&terms=any&author=&sc=1&sf=titleonly&sk=t&sd=d&sr=topics&st=0&ch=300&t=0&submit=Search'}, { name: 'Torrminatorr', url: `https://forum.torrminatorr.com/search.php?keywords=${encodeURIComponent(gameName)}` }, { name: 'FitGirl Repacks', url: `https://fitgirl-repacks.site/?s=${encodeURIComponent(gameName)}` }, - { name: 'DElDETECTED', url: `https://deidetected.com/games/?search=${encodeURIComponent(gameName)}` }, + { name: 'DEIDETECTED', url: `https://deidetected.com/games/?search=${encodeURIComponent(gameName)}` }, { name: 'YouTube (No Commentary)', url: `https://www.youtube.com/results?search_query=${encodeURIComponent(gameName + ' no commentary')}` } ]; diff --git a/SFW/Steam_Block_Games.user.js b/SFW/Steam_Block_Games.user.js index 00a6f25..55ee769 100644 --- a/SFW/Steam_Block_Games.user.js +++ b/SFW/Steam_Block_Games.user.js @@ -1,10 +1,10 @@ // ==UserScript== // @name Steam Search Block Games // @namespace Steam_Search_Block_Games -// @version 1.1 +// @version 1.2 // @author masterofobzene // @description Block button to hide individual games. -// @match https://store.steampowered.com/search/* +// @match https://store.steampowered.com/search* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand diff --git a/SFW/deepseek-answer-in-english.user.js b/SFW/deepseek-answer-in-english.user.js new file mode 100644 index 0000000..0679abb --- /dev/null +++ b/SFW/deepseek-answer-in-english.user.js @@ -0,0 +1,178 @@ +// ==UserScript== +// @name DeepSeek Answer in English +// @namespace DeepSeek_Answer_In_English +// @version 1.0 +// @description Appends "answer in english" to the prompt before sending and provides an enable/disable toggle. +// @author masterofobzene +// @match *://*.deepseek.com/* +// @grant GM_getValue +// @grant GM_setValue +// @run-at document-idle +// @license GNU GPLv3 +// @icon https://deepseek.com/favicon.ico +// @downloadURL https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/deepseek-answer-in-english.user.js +// @updateURL https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/deepseek-answer-in-english.user.js +// ==/UserScript== + +(() => { + 'use strict'; + + console.log('[Answer in English] Script loaded'); + + let enabled = GM_getValue('answerInEnglishEnabled', true); + const SUFFIX = ' answer in english'; + + function appendSuffixToInput() { + try { + if (!enabled) { + return; + } + + const input = + document.querySelector('textarea') || + document.querySelector('[contenteditable="true"]'); + + if (!input) { + console.warn('[Answer in English] Input not found'); + return; + } + + const currentText = + input instanceof HTMLTextAreaElement + ? input.value + : input.textContent || ''; + + if (!currentText.trim()) { + return; + } + + if (currentText.endsWith(SUFFIX)) { + return; + } + + const newText = currentText + SUFFIX; + + if (input instanceof HTMLTextAreaElement) { + const descriptor = Object.getOwnPropertyDescriptor( + HTMLTextAreaElement.prototype, + 'value' + ); + + if (descriptor?.set) { + descriptor.set.call(input, newText); + } else { + input.value = newText; + } + } else { + input.textContent = newText; + } + + input.dispatchEvent( + new InputEvent('input', { + bubbles: true, + cancelable: true + }) + ); + + input.dispatchEvent( + new Event('change', { + bubbles: true + }) + ); + + console.log('[Answer in English] Prompt modified'); + } catch (error) { + console.error('[Answer in English]', error); + } + } + + document.addEventListener( + 'keydown', + event => { + try { + if (!enabled) { + return; + } + + if (event.key !== 'Enter') { + return; + } + + if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) { + return; + } + + appendSuffixToInput(); + } catch (error) { + console.error('[Answer in English]', error); + } + }, + true + ); + + function createToggle() { + try { + if (!document.body) { + setTimeout(createToggle, 500); + return; + } + + if (document.getElementById('answer-in-english-toggle')) { + return; + } + + const container = document.createElement('div'); + container.id = 'answer-in-english-toggle'; + + Object.assign(container.style, { + position: 'fixed', + top: '60px', + right: '10px', + zIndex: '2147483647', + background: 'rgba(255,255,255,0.95)', + border: '1px solid #ccc', + borderRadius: '8px', + padding: '8px 12px', + boxShadow: '0 2px 10px rgba(0,0,0,0.15)', + fontFamily: 'system-ui, sans-serif', + fontSize: '13px', + color: '#000' + }); + + container.innerHTML = ` + + `; + + document.body.appendChild(container); + + const checkbox = container.querySelector('#answer-in-english-checkbox'); + + checkbox.addEventListener('change', event => { + enabled = event.target.checked; + GM_setValue('answerInEnglishEnabled', enabled); + + console.log('[Answer in English] Enabled:', enabled); + }); + + console.log('[Answer in English] Toggle added'); + } catch (error) { + console.error('[Answer in English]', error); + } + } + + createToggle(); + + const observer = new MutationObserver(() => { + if (!document.getElementById('answer-in-english-toggle')) { + createToggle(); + } + }); + + observer.observe(document.documentElement, { + childList: true, + subtree: true + }); +})(); diff --git a/SFW/deepseek-concise.user.js b/SFW/deepseek-concise.user.js new file mode 100644 index 0000000..a8fc653 --- /dev/null +++ b/SFW/deepseek-concise.user.js @@ -0,0 +1,178 @@ +// ==UserScript== +// @name DeepSeek Be Concise +// @namespace DeepSeek_Be_Concise +// @version 1.0 +// @description Appends "be concise" to the prompt before sending and provides an enable/disable toggle. +// @author masterofobzene +// @match *://*.deepseek.com/* +// @grant GM_getValue +// @grant GM_setValue +// @run-at document-idle +// @license GNU GPLv3 +// @icon https://deepseek.com/favicon.ico +// @downloadURL https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/deepseek-concise.user.js +// @updateURL https://github.com/masterofobzene/UserScriptRepo/raw/main/SFW/deepseek-concise.user.js +// ==/UserScript== + +(() => { + 'use strict'; + + console.log('[Be Concise] Script loaded'); + + let enabled = GM_getValue('beConciseEnabled', true); + const SUFFIX = ' be concise'; + + function appendSuffixToInput() { + try { + if (!enabled) { + return; + } + + const input = + document.querySelector('textarea') || + document.querySelector('[contenteditable="true"]'); + + if (!input) { + console.warn('[Be Concise] Input not found'); + return; + } + + const currentText = + input instanceof HTMLTextAreaElement + ? input.value + : input.textContent || ''; + + if (!currentText.trim()) { + return; + } + + if (currentText.endsWith(SUFFIX)) { + return; + } + + const newText = currentText + SUFFIX; + + if (input instanceof HTMLTextAreaElement) { + const descriptor = Object.getOwnPropertyDescriptor( + HTMLTextAreaElement.prototype, + 'value' + ); + + if (descriptor?.set) { + descriptor.set.call(input, newText); + } else { + input.value = newText; + } + } else { + input.textContent = newText; + } + + input.dispatchEvent( + new InputEvent('input', { + bubbles: true, + cancelable: true + }) + ); + + input.dispatchEvent( + new Event('change', { + bubbles: true + }) + ); + + console.log('[Be Concise] Prompt modified'); + } catch (error) { + console.error('[Be Concise]', error); + } + } + + document.addEventListener( + 'keydown', + event => { + try { + if (!enabled) { + return; + } + + if (event.key !== 'Enter') { + return; + } + + if (event.shiftKey || event.ctrlKey || event.altKey || event.metaKey) { + return; + } + + appendSuffixToInput(); + } catch (error) { + console.error('[Be Concise]', error); + } + }, + true + ); + + function createToggle() { + try { + if (!document.body) { + setTimeout(createToggle, 500); + return; + } + + if (document.getElementById('be-concise-toggle')) { + return; + } + + const container = document.createElement('div'); + container.id = 'be-concise-toggle'; + + Object.assign(container.style, { + position: 'fixed', + top: '10px', + right: '10px', + zIndex: '2147483647', + background: 'rgba(255,255,255,0.95)', + border: '1px solid #ccc', + borderRadius: '8px', + padding: '8px 12px', + boxShadow: '0 2px 10px rgba(0,0,0,0.15)', + fontFamily: 'system-ui, sans-serif', + fontSize: '13px', + color: '#000' + }); + + container.innerHTML = ` + + `; + + document.body.appendChild(container); + + const checkbox = container.querySelector('#be-concise-checkbox'); + + checkbox.addEventListener('change', event => { + enabled = event.target.checked; + GM_setValue('beConciseEnabled', enabled); + + console.log('[Be Concise] Enabled:', enabled); + }); + + console.log('[Be Concise] Toggle added'); + } catch (error) { + console.error('[Be Concise]', error); + } + } + + createToggle(); + + const observer = new MutationObserver(() => { + if (!document.getElementById('be-concise-toggle')) { + createToggle(); + } + }); + + observer.observe(document.documentElement, { + childList: true, + subtree: true + }); +})();