Adds a guide button to Crimes 2.0 pages to open a new tab with Emforus guide
// ==UserScript==
// @name Emforus, Help Me!
// @namespace torn
// @version 1.0
// @description Adds a guide button to Crimes 2.0 pages to open a new tab with Emforus guide
// @match https://www.torn.com/page.php?sid=crimes*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const GUIDES = {
searchforcash: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16343473',
bootlegging: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16341811',
graffiti: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16344567',
shoplifting: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16346491',
pickpocketing: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16358739',
cardskimming: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16350490',
burglary: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16353303',
hustling: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16363421',
disposal: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16367936',
cracking: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16373016',
forgery: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16388086',
scamming: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16418415',
arson: 'https://www.torn.com/forums.php#/p=threads&f=61&t=16510947'
};
function getCrimeFromUrl() {
const match = location.hash.match(/#\/([^/?]+)/);
return match ? match[1].toLowerCase() : null;
}
function findCrimeHeader() {
const crime = getCrimeFromUrl();
if (!crime) return null;
return [...document.querySelectorAll('h4')]
.find(h4 => {
const header = h4.parentElement;
if (!header) return false;
const hasBackLink = !!header.querySelector('a[href="#/"]');
const titleMatchesCrime = h4.textContent
.trim()
.replace(/\s+/g, '')
.toLowerCase() === crime;
return hasBackLink && titleMatchesCrime;
})?.parentElement || null;
}
function addGuideButton() {
const existing = document.getElementById('crime-guide-button');
if (existing) existing.remove();
const crime = getCrimeFromUrl();
if (!crime || !GUIDES[crime]) return;
const header = findCrimeHeader();
if (!header) return;
const title = header.querySelector('h4');
const backLink = header.querySelector('a[href="#/"]');
if (!title || !backLink) return;
const button = document.createElement('a');
button.id = 'crime-guide-button';
button.href = GUIDES[crime];
button.target = '_blank';
button.rel = 'noopener noreferrer';
button.title = 'Open Emforus guide';
button.textContent = '?';
button.style.cssText = `
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
margin-left: 8px;
margin-right: auto;
border-radius: 50%;
background: #3b82f6;
color: white;
font-size: 14px;
line-height: 1;
font-weight: bold;
text-decoration: none;
cursor: pointer;
flex-shrink: 0;
box-sizing: border-box;
`;
title.insertAdjacentElement('afterend', button);
}
let lastHash = '';
function checkPage() {
if (location.hash !== lastHash) {
lastHash = location.hash;
setTimeout(addGuideButton, 300);
return;
}
if (!document.getElementById('crime-guide-button')) {
addGuideButton();
}
}
const observer = new MutationObserver(() => {
checkPage();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
window.addEventListener('hashchange', () => {
setTimeout(addGuideButton, 300);
});
checkPage();
})();