Skip to content

Instantly share code, notes, and snippets.

@AliMirlou
Last active February 7, 2024 09:22
Show Gist options
  • Save AliMirlou/32a2972419e2f8b3bdba6384cbb8aaf9 to your computer and use it in GitHub Desktop.
Save AliMirlou/32a2972419e2f8b3bdba6384cbb8aaf9 to your computer and use it in GitHub Desktop.
Automatically copies and collects your online store sales in Torn's Bootlegging crime.
// ==UserScript==
// @name Torn Bootlegging Auto Collector
// @namespace https://github.com/AliMirlou
// @version 0.5
// @description Adds and copies DVDs and collects from Online Store.
// @author Piastasa & Xerac
// @match https://www.torn.com/loader.php?sid=crimes
// @icon https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @downloadURL https://gist.github.com/AliMirlou/32a2972419e2f8b3bdba6384cbb8aaf9/raw/torn-bootlegging-auto-collector.user.js
// @updateURL https://gist.github.com/AliMirlou/32a2972419e2f8b3bdba6384cbb8aaf9/raw/torn-bootlegging-auto-collector.user.js
// ==/UserScript==
const INTERVAL_TIME = 500;
(function() {
'use strict';
let intervalID = null, checkingDVDs = false;
const intervalCallback = async () => {
await checkAndClickCollect();
await checkStock();
await checkDVDs();
}
const checkDVDs = async () => {
if (!/#\/bootlegging/.test(location.hash)) {
stopInterval();
return;
}
if (checkingDVDs) return;
checkingDVDs = true;
if (document.querySelector('div[class^="dvdCellWrapper"] > button > div > span').innerText.trim() !== '0') {
checkingDVDs = false;
return;
}
if (document.evaluate("//div[text()='Select a Pack of Blank DVDs']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue === null) {
document.querySelector('div[class^="dvdCellWrapper"] > button').click();
}
while (document.evaluate("//div[text()='Select a Pack of Blank DVDs']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue === null) {
await new Promise(r => setTimeout(r, 250));
}
document.querySelector('div[class^="packs"] > button').click();
checkingDVDs = false;
}
const checkStock = async () => {
if (!/#\/bootlegging/.test(location.hash)) {
stopInterval();
return;
}
for (const stock of document.querySelectorAll('span[class^="currentStock"]')) {
if (stock.innerText.trim() !== '0' || stock.parentElement.parentElement.children[0].innerText.trim() !== '0 queued') {
return;
}
}
const copyButton = document.evaluate("//span[text()='Copy']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.parentElement.parentElement;
if (copyButton.classList.contains('disabled')) return;
copyButton.click();
}
const checkAndClickCollect = async () => {
if (!/#\/bootlegging/.test(location.hash)) {
stopInterval();
return;
}
try {
let button = document.evaluate("//div[text()='Online Store']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.parentElement.children[6].children[0];
if (!button.classList.contains('disabled')) button.click();
} catch (e) {}
}
const startInterval = () => {
intervalID = setInterval(intervalCallback, INTERVAL_TIME);
document.querySelector("span#auto-collector-toggle-text").innerText = 'Disable Auto Collect';
document.querySelector("svg#auto-collector-enable-icon").style.display = 'none';
document.querySelector("svg#auto-collector-disable-icon").style.display = 'inline';
console.log("[Torn Auto Collector] Auto collector enabled!");
}
const stopInterval = () => {
clearInterval(intervalID);
intervalID = null;
document.querySelector("span#auto-collector-toggle-text").innerText = 'Enable Auto Collect';
document.querySelector("svg#auto-collector-enable-icon").style.display = 'inline';
document.querySelector("svg#auto-collector-disable-icon").style.display = 'none';
console.log("[Torn Auto Collector] Auto collector disabled!");
}
window.addEventListener('load', async () => {
const btn = document.createElement("a");
btn.id = "auto-collector-toggle";
while (document.querySelector("div.crimes-app > div") === null) {
await new Promise(r => setTimeout(r, 250));
}
const headerButtons = document.querySelector("div.crimes-app > div");
const firstHeaderButton = headerButtons.children[1];
btn.className = firstHeaderButton.className;
btn.innerHTML = `<span><svg id="auto-collector-enable-icon" class="${firstHeaderButton.children[0].className.baseVal}" style="display: inline" xmlns="http://www.w3.org/2000/svg" filter="url(#defaultFilter)" fill="#777" stroke="transparent" stroke-width="0" width="16" height="16" viewBox="0 0 24 24"><path d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"></path></svg><svg id="auto-collector-disable-icon" class="${firstHeaderButton.children[0].className.baseVal}" style="display: none" xmlns="http://www.w3.org/2000/svg" filter="url(#defaultFilter)" fill="#777" stroke="transparent" stroke-width="0" width="12" height="12" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"></path></svg></span><span id="auto-collector-toggle-text">Enable Auto Collect</span>`;
headerButtons.insertBefore(btn, firstHeaderButton);
btn.onclick = () => {
if (intervalID === null) {
// Enable
startInterval();
} else {
// Disable
stopInterval();
}
}
console.log("[Torn Auto Collector] Auto collector is ready!");
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment