Speed up roulette by skipping the animation :)
// ==UserScript==
// @name Fast Roulette
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Speed up roulette by skipping the animation :)
// @author Lollipop [2717731]
// @match https://www.torn.com/page.php?sid=roulette*
// @icon https://www.torn.com/favicon.ico
// @grant none
// ==/UserScript==
(function() {
'use strict';
console.log('Fast Roulette: Initialized');
// Store the last detected stake data
let lastStakeData = {
rfcv: null,
decodedStake: null
};
// Function to add the custom repeat element
function addCustomElement() {
// Check if infoSpot exists
const infoSpot = document.getElementById('infoSpot');
if (!infoSpot || document.getElementById('customRepeatButton')) {
return; // Element not found or button already exists
}
console.log('Fast Roulette: Adding custom repeat button');
// Create the custom element with the same styling as infoSpot
const customElement = document.createElement('div');
customElement.id = 'customRepeatButton';
customElement.className = 'info-msg-cont border-round m-top10';
customElement.innerHTML = `
<div class="info-msg border-round">
<i class="info-icon"></i>
<div class="delimiter">
<div class="msg right-round" id="customRepeatText" style="color: #FF69B4;">Repeat Last Bet</div>
</div>
</div>
`;
// Add some cursor pointer style to make it look clickable
customElement.style.cursor = 'pointer';
// Insert the custom element after infoSpot
infoSpot.parentNode.insertBefore(customElement, infoSpot.nextSibling);
// Add click event listener
customElement.addEventListener('click', function() {
console.log('Fast Roulette: Custom repeat button clicked');
if (lastStakeData.rfcv && lastStakeData.decodedStake) {
console.log('Fast Roulette: Repeating bet with stake:', lastStakeData.decodedStake);
// Use jQuery's AJAX to match Torn's format
$.ajax({
url: 'page.php',
type: 'GET',
data: {
rfcv: lastStakeData.rfcv,
sid: 'rouletteData',
step: 'processStakes',
mode: 'html',
stake0: lastStakeData.decodedStake
},
success: onSuccessResponse,
error: function(error) {
console.error('Fast Roulette: Error placing bet:', error);
displayInfo('Failed to place bet. Please try again.', 'red');
}
});
} else {
console.log('Fast Roulette: No previous bet data available');
displayInfo('No previous bet data available. Place a bet first.', 'red');
}
});
}
// Function to handle bet response without animation
function onSuccessResponse(response) {
try {
// Parse the response if it's a string
if (typeof response === 'string') {
try {
response = JSON.parse(response);
} catch (e) {
console.error('Fast Roulette: Failed to parse response:', e);
displayInfo('Failed to parse response. Please try again.', 'red');
return;
}
}
// Update UI with result
const title = response.won ? `You won \$${response.won}!` : 'You lost...';
const message = ' The ball landed on ' + response.number;
// Display result info
displayInfo(title + message, response.won ? 'green' : 'red');
// Update money and tokens (no animation)
$('#st_money_val').html('$' + toNumberFormat(response.totalAmount));
$('#st_tokens_val').html(response.tokens);
// Update other UI elements if needed
if (response.bet) {
$('#st_bet_val').html(response.bet);
}
if (response.won) {
$('#st_won_val').html('$' + toNumberFormat(response.won));
} else {
$('#st_won_val').html('$0');
}
} catch (e) {
console.error('Fast Roulette: Error handling bet response:', e);
displayInfo('Error handling bet response. Please try again.', 'red');
}
}
// Helper function to display info message
function displayInfo(message, color) {
const infoSpotText = document.getElementById('infoSpotText');
if (infoSpotText) {
infoSpotText.textContent = message;
infoSpotText.style.color = color || '';
// Reset color after a delay
setTimeout(() => {
infoSpotText.style.color = '';
}, 5000);
}
}
// Helper function to format numbers like Torn does
function toNumberFormat(number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// Function to safely decode a URL component
function safeDecodeURIComponent(str) {
try {
return decodeURIComponent(str);
} catch (e) {
console.error('Fast Roulette: Error decoding:', str);
return str;
}
}
// Create a proxy for the original XMLHttpRequest
const originalXHR = window.XMLHttpRequest;
function newXHR() {
const xhr = new originalXHR();
const originalOpen = xhr.open;
const originalSend = xhr.send;
xhr.open = function() {
this._url = arguments[1];
return originalOpen.apply(this, arguments);
};
xhr.send = function() {
const url = this._url;
if (url && typeof url === 'string') {
// Check if this is a processStakes request
if (
url.includes('sid=rouletteData') &&
url.includes('step=processStakes') &&
url.includes('stake0=')
) {
// Extract the rfcv value
const rfcvMatch = url.match(/rfcv=([^&]+)/);
const rfcv = rfcvMatch ? rfcvMatch[1] : null;
// Extract the stake0 value
const stakeMatch = url.match(/stake0=([^&]+)/);
const encodedStake = stakeMatch ? stakeMatch[1] : null;
if (rfcv && encodedStake) {
// Decode the stake value
const decodedStake = safeDecodeURIComponent(encodedStake);
console.log('Fast Roulette: Detected stake processing request');
console.log('Fast Roulette: Decoded Stake:', decodedStake);
// Store the stake data
lastStakeData = {
rfcv: rfcv,
decodedStake: decodedStake
};
// Add or update the custom element after a short delay
setTimeout(addCustomElement, 500);
}
}
}
return originalSend.apply(this, arguments);
};
return xhr;
}
// Replace the global XMLHttpRequest with our proxied version
window.XMLHttpRequest = newXHR;
// Also handle fetch requests
const originalFetch = window.fetch;
window.fetch = function(input, init) {
if (input && typeof input === 'string') {
// Check if this is a processStakes request
if (
input.includes('sid=rouletteData') &&
input.includes('step=processStakes') &&
input.includes('stake0=')
) {
// Extract the rfcv value
const rfcvMatch = input.match(/rfcv=([^&]+)/);
const rfcv = rfcvMatch ? rfcvMatch[1] : null;
// Extract the stake0 value
const stakeMatch = input.match(/stake0=([^&]+)/);
const encodedStake = stakeMatch ? stakeMatch[1] : null;
if (rfcv && encodedStake) {
// Decode the stake value
const decodedStake = safeDecodeURIComponent(encodedStake);
console.log('Fast Roulette: Detected stake processing fetch request');
console.log('Fast Roulette: Decoded Stake:', decodedStake);
// Store the stake data
lastStakeData = {
rfcv: rfcv,
decodedStake: decodedStake
};
// Add or update the custom element after a short delay
setTimeout(addCustomElement, 500);
}
}
}
return originalFetch.apply(this, arguments);
};
})();