racenao

race helper for torn

// ==UserScript==
// @name         racenao
// @namespace    racenao.zero.nao
// @version      0.5
// @description  race helper for torn
// @author       nao [2669774]
// @match        https://www.torn.com/page.php?sid=racing
// @match        https://www.torn.com/loader.php?sid=racing
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @grant        GM_addStyle
// ==/UserScript==

GM_addStyle(`
.race-button {
  color: white;
  margin: 5px;
  height: 40px;
padding: 5px !important;
border-radius: 5px;
background: #069494 !important;
}

@keyframes blink {
  0% { opacity: 1; }
  50% { opacity: 0; }
  100% { opacity: 1; }
}

.blinking {
  animation: blink 1s infinite;
}

.save-button {
width: 50px;
}
`);

if (!localStorage.getItem("racesNao")) {
    localStorage.setItem("racesNao", JSON.stringify({}));
}

if (!localStorage.getItem("chosenCarsNao")) {
    localStorage.setItem("chosenCarsNao", JSON.stringify({}));
}

let races = JSON.parse(localStorage.getItem("racesNao"));
let chosenCars = JSON.parse(localStorage.getItem("chosenCarsNao"));
let lastRaceInfo;

let rfc = getRFC();

function getRFC() {
    var rfc = $.cookie("rfc_v");
    if (!rfc) {
        var cookies = document.cookie.split("; ");
        for (var i in cookies) {
            var cookie = cookies[i].split("=");
            if (cookie[0] == "rfc_v") {
                return cookie[1];
            }
        }
    }
    return rfc;
}

function saveRace() {
    const raceTitle = prompt(`
Race Name: ${lastRaceInfo.title}
Track: ${lastRaceInfo.trackID}
Min Drivers: ${lastRaceInfo.minDrivers}
Max Drivers: ${lastRaceInfo.maxDrivers}
Laps: ${lastRaceInfo.laps}
Min Class: ${lastRaceInfo.minClass}
Cars Type Allowed: ${lastRaceInfo.carsTypeAllowed}
Cars Allowed: ${lastRaceInfo.carsAllowed}
Bet Amount: ${lastRaceInfo.betAmount}
Wait Time: ${lastRaceInfo.waitTime}

Enter the race title:`);
    if (raceTitle) {
        races[raceTitle] = lastRaceInfo;
        localStorage.setItem("racesNao", JSON.stringify(races));
        updateRace();

        const saveButton = document.querySelector(".save-button");
        saveButton.classList.remove("blinking");
    }
}

function insert() {
    const container = document.querySelector("div[class^='titleContainer_']");

    if (!container) {
        setTimeout(insert, 1000);
        return;
    }

    const containerNao = document.createElement("div");
    containerNao.style.display = "flex";
    containerNao.style.flexDirection = "column";
    container.parentNode.parentNode.appendChild(containerNao);

    const saveButton = document.createElement("button");
    saveButton.innerText = "Save";
    saveButton.className = "race-button save-button";
    saveButton.addEventListener("click", function () {
        saveRace();
    });
    containerNao.appendChild(saveButton);

    const racesContainer = document.createElement("div");
    racesContainer.className = "races-container";
    containerNao.appendChild(racesContainer);


    for (let raceId in races) {
        const raceName = raceId;
        const raceButton = document.createElement("button");
        raceButton.innerText = raceName;
        raceButton.className = "race-button";
        raceButton.addEventListener("click", function () {
            startRace(raceId);
        });
        raceButton.addEventListener("contextmenu", function (e) {
            e.preventDefault();
            removeRace(raceId);
        });

        racesContainer.appendChild(raceButton);
    }
}

function updateRace() {
    const racesContainer = document.querySelector(".races-container");
    racesContainer.innerHTML = "";
    for (let raceId in races) {
        const raceName = raceId;
        const raceButton = document.createElement("button");
        raceButton.innerText = raceName;
        raceButton.className = "race-button";
        raceButton.addEventListener("click", function () {
            startRace(raceId);
        });
        raceButton.addEventListener("contextmenu", function (e) {
            e.preventDefault();
            removeRace(raceId);
        });

        racesContainer.appendChild(raceButton);
    }
}

function removeRace(raceId) {
    delete races[raceId];
    localStorage.setItem("racesNao", JSON.stringify(races));
    updateRace();
}

function startRace(raceId) {
    const raceName = races[raceId].title;
    const minDrivers = races[raceId].minDrivers;
    const maxDrivers = races[raceId].maxDrivers;
    const trackId = races[raceId].trackID;
    const laps = races[raceId].laps;
    const minClass = races[raceId].minClass;
    const carsTypeAllowed = races[raceId].carsTypeAllowed;
    const carsAllowed = races[raceId].carsAllowed;
    const betAmount = races[raceId].betAmount;
    const waitTime = races[raceId].waitTime;
    const carId = races[raceId].carID;

    let raceLink = `https://www.torn.com/page.php?sid=racing&tab=customrace&section=getInRace&step=getInRace&id=&carID=${carId}&createRace=true&title=${raceName}&minDrivers=${minDrivers}&maxDrivers=${maxDrivers}&trackID=${trackId}&laps=${laps}&minClass=${minClass}&carsTypeAllowed=${carsTypeAllowed}&carsAllowed=${carsAllowed}&betAmount=${betAmount}&waitTime=0&rfcv=${getRFC()}`;
    $.post(raceLink, function (response) {
        console.log("Race started");
        const saveButton = document.querySelector(".save-button");
        saveButton.classList.remove("blinking");
    });
}

insert();

const originalAjax = $.ajax;
$.ajax = function (options) {
    console.log("[RACENAO] :", options);
    if (options?.url?.includes("sid=racing") && options?.url?.includes("getInRace")) {
        const requestUrl = options.url.split("step=getInRace&")[1];
        const urlPieces = requestUrl.split("&");

        lastRaceInfo = {};
        for (let piece of urlPieces) {
            const [key, value] = piece.split("=");
            lastRaceInfo[key] = value;
        }

        const saveButton = document.querySelector(".save-button");
        if (lastRaceInfo && lastRaceInfo.title) {
            saveButton.classList.add("blinking");
        } else {
            saveButton.classList.remove("blinking");
        }
    }

    return originalAjax(options);
};

function checkForRace() {
    const raceTitle =
          $("div.enlisted-btn-wrap:nth-child(1)")?.text() || undefined;
    if (raceTitle) {
        showPreference(raceTitle);
    }
}

function showPreference(raceTitle) {
    if (chosenCars[raceTitle]) {
        const link = chosenCars[raceTitle];
        const carLink = document.createElement("a");
        carLink.href = link;
        $("div.enlisted-btn-wrap:nth-child(1)").append(carLink);
    }
}