Flying OC Alert

Alerts you when you want to fly but an OC is about to start.

当前为 2025-04-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Flying OC Alert
// @namespace    http://tampermonkey.net/
// @version      1.1.0
// @description  Alerts you when you want to fly but an OC is about to start.
// @author       NichtGersti [3380912]
// @license      MIT
// @match        https://www.torn.com/page.php?sid=travel
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// ==/UserScript==

(function() {
    'use strict';

    let apiKey = localStorage.getItem("nichtgersti-flying-oc-alert-apikey") ?? '###PDA-APIKEY###' //Minimal access or above!
    let maxWarningHours = localStorage.getItem("nichtgersti-flying-oc-alert-max-warning-hours") ?? 10
    let alertOption = Number.parseInt(localStorage.getItem("nichtgersti-flying-oc-alert-alert-option")) ?? 0 //0 -> simple alert; 1 -> confirm prompt; 2 confirm math question
    let confirmMessage = localStorage.getItem("nichtgersti-flying-oc-alert-confirm-message") ?? "continue" //for confirmPrompt

    let alertOptionsMenuId
    let confirmMessageMenuId

    try {
        GM_registerMenuCommand('Set Api Key', setApiKey)
        GM_registerMenuCommand('Set Max Warning Hours', setMaxWarningHours)
        if (alertOption == 1) confirmMessageMenuId = GM_registerMenuCommand('Set Confirm Message', setConfirmMessage)
        setAlertOption(alertOption)
    } catch (error) {
        console.warn('[Flying OC Alert] Tampermonkey not detected!')
    }

    setApiKey(true)

    let ocUrl = "https://api.torn.com/v2/user/?selections=organizedcrime&key={apiKey}".replace("{apiKey}", apiKey)

    fetch(ocUrl).then( response => {
        if (response.ok) {
            return response.json();
        }
        throw new Error('Something went wrong');
    })
    .then( result => {

        if (result.error) {
            switch (result.error.code){
                    case 2:
                        apiKey = null;
                        localStorage.setItem("nichtgersti-flying-oc-alert-api", null)
                        console.error("[Flying OC Alert] Incorrect Api Key:", result)
                        return
                    case 9:
                        console.warn("[Flying OC Alert] The API is temporarily disabled, please try again later")
                        return
                    default:
                        console.error("[Flying OC Alert] Error:", result.error.error)
                        return
                }
        }

        let infoOc = result.organizedCrime

        let totalSeconds = infoOc.ready_at - Math.floor(Date.now() / 1000)
        if (totalSeconds / 3600 > 10) return

        let days = Math.floor(totalSeconds / 86400) % 24
        let hours = Math.floor(totalSeconds / 3600) % 60
        let minutes = Math.floor(totalSeconds / 60) % 60
        let seconds = totalSeconds % 60

        let timeString = ""
        if (totalSeconds > 86400) timeString += `${(days < 10) ? "0" : ""}${days}:`
        if (totalSeconds > 3600) timeString += `${(hours < 10) ? "0" : ""}${hours}:`
        if (totalSeconds > 60) timeString += `${(minutes < 10) ? "0" : ""}${minutes}:`
        timeString += `${(seconds < 10) ? "0" : ""}${seconds}`
        if (totalSeconds < 60) timeString = `${(seconds < 10) ? "0" : ""}${seconds} seconds`

        let message
        let randomNumber1 = Math.ceil((Math.random() * 50))
        let randomNumber2 = Math.ceil((Math.random() * 50))
        let correctAnswer = (randomNumber1 + randomNumber2).toString()
        switch (alertOption) {
            case 0:
                alert(`Your Organzied Crime is about to start:\n${timeString}`)
                break
            case 1:
                while (message != confirmMessage) message = prompt(`Your Organzied Crime is about to start:\n${timeString}\nWrite "${confirmMessage}" to continue.`)
                break
            case 2:
                while (message != correctAnswer) message = prompt(`Your Organzied Crime is about to start:\n${timeString}\nSolve "${randomNumber1} + ${randomNumber2}" to continue.`)
                break
            default:
                console.log(alertOption)
                throw new Error('Something went wrong');
        }
    })
    .catch(error => console.error("[Flying OC Alert] Error:", error))

    function setApiKey(checkExisting = false) {
        if (!checkExisting || apiKey === null || apiKey.indexOf('PDA-APIKEY') > -1 || apiKey.length != 16){
            let userInput = prompt("Please enter a minimal access API key.", apiKey ?? '')
            if (userInput !== null && userInput.length == 16) {
                apiKey = userInput
                localStorage.setItem("nichtgersti-flying-oc-alert-apikey", apiKey)
            }
        }
    }

    function setMaxWarningHours() {
        let userInput = prompt("Please enter the maximum time in hours you want to get warned at.", maxWarningHours ?? '10')
        if (userInput !== null) {
            try {
                maxWarningHours = Number.parseFloat(userInput)
                localStorage.setItem("nichtgersti-flying-oc-alert-max-warning-hours", maxWarningHours)
            } catch (error) { alert("Not a valid input") }
        }
    }

    function setAlertOption(option = (alertOption + 1) % 3) {
        alertOption = option
        localStorage.setItem("nichtgersti-flying-oc-alert-alert-option", alertOption)
        let optionText = ["Simple Alert", "Confirmation Prompt", "Confirmation Addition"]
        try {
            GM_unregisterMenuCommand(alertOptionsMenuId)
            GM_unregisterMenuCommand(confirmMessageMenuId)
        } catch (error) { console.log(error) }
        try {
            alertOptionsMenuId = GM_registerMenuCommand(optionText[option], function() {setAlertOption()})
            if (alertOption == 1) confirmMessageMenuId = GM_registerMenuCommand('Set Confirm Message', setConfirmMessage)
        } catch (error) { throw error }
        return option
    }

    function setConfirmMessage() {
        let userInput = prompt("Please enter what you want to type out to confirm that you have been alerted.", confirmMessage ?? '10')
        if (userInput !== null) {
            try {
                confirmMessage = userInput
                localStorage.setItem("nichtgersti-flying-oc-alert-confirm-message", confirmMessage)
            } catch (error) { alert("Not a valid input") }
        }
    }

})();