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.
-
+
[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! 😁
+
+
-
[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.
-
+
+
[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.
+
+
+
+
+
+[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.
+
+
+
+
+
+
+[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]
+> - – This button is **not** for installing anything.
+> - – This button is to show that you **like** this repo.
+> - – 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
+ });
+})();