Torn Efficiency Manager

Efficiency suite. Monitors Education, Organized Crimes, and Life/Energy waste using persistent settings.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         Torn Efficiency Manager
// @namespace    http://torn.efficiency
// @version      1.0
// @description  Efficiency suite. Monitors Education, Organized Crimes, and Life/Energy waste using persistent settings.
// @author       Nicholas_Herr [3863644]
// @license MIT
// @match        https://www.torn.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let DEBUG_FORCE_ALL = false;

    const getSettings = () => {
        const defaults = { edu: true, oc: true, life: true, xanax: true };
        const saved = localStorage.getItem('EfficiencySettings');
        return saved ? JSON.parse(saved) : defaults;
    };

    const saveSettings = (settings) => {
        localStorage.setItem('EfficiencySettings', JSON.stringify(settings));
    };

    const CONFIG = {
        CHECK_INTERVAL: 15000,
        SELECTORS: {
            SIDEBAR_MENU: '.toggle-content___BJ9Q9',
            STATUS_BAR: 'ul[class*="status-icons"]',
            LIFE_BAR: 'a[class*="life"]',
            ENERGY_BAR: 'a[class*="energy"]',
            EDU_LINK: 'a[href*="sid=education"]',
            OC_LINK: 'a[href*="tab=crimes"]',
            DRUG_CD: 'li[class*="icon49"]',
            MAIN_CONTAINER: '#mainContainer',
            ACTUAL_BAR: 'div[class*="progress-line"]:not([class*="timer"])'
        },
        COLORS: {
            RED: "#ff4444", DARK_RED: "#cc0000", ORANGE: "#ffa500",
            YELLOW: "#e3af00", GREEN: "#37b24d", GRAY: "#444444"
        }
    };

    const EfficiencyManager = {
        getAlerts() {
            if (DEBUG_FORCE_ALL) {
                return [
                    { text: "DEBUG: NO EDUCATION COURSE", color: CONFIG.COLORS.RED, url: "#" },
                    { text: "DEBUG: NO ORGANIZED CRIME", color: CONFIG.COLORS.ORANGE, url: "#" },
                    { text: "DEBUG: LIFE FULL: MAKE BLOOD BAGS!", color: CONFIG.COLORS.DARK_RED, url: "#" },
                    { text: "DEBUG: ENERGY AT 500: TAKE A XANAX!", color: CONFIG.COLORS.GREEN, url: "#" },
                    { text: "DEBUG: WASTE WARNING: BURN 50 ENERGY!", color: CONFIG.COLORS.YELLOW, url: "#" }
                ];
            }

            const settings = getSettings();
            const alerts = [];
            const isEduPage = window.location.href.includes('sid=education');
            const eduActive = !!document.querySelector(`${CONFIG.SELECTORS.STATUS_BAR} ${CONFIG.SELECTORS.EDU_LINK}`);
            const ocActive = !!document.querySelector(`${CONFIG.SELECTORS.STATUS_BAR} ${CONFIG.SELECTORS.OC_LINK}`);

            if (settings.edu && !isEduPage && !eduActive) {
                alerts.push({ text: "NO EDUCATION COURSE", color: CONFIG.COLORS.RED, url: "/page.php?sid=education" });
            }
            if (settings.oc && !ocActive) {
                alerts.push({ text: "NO ORGANIZED CRIME", color: CONFIG.COLORS.ORANGE, url: "/factions.php?step=your#/tab=crimes" });
            }

            const lifeBar = document.querySelector(CONFIG.SELECTORS.LIFE_BAR);
            const progress = lifeBar?.querySelector(CONFIG.SELECTORS.ACTUAL_BAR);
            if (settings.life && progress) {
                const healthPct = parseInt(progress.style.width) || 0;
                if (healthPct === 100) {
                    alerts.push({ text: "LIFE FULL: MAKE BLOOD BAGS!", color: CONFIG.COLORS.DARK_RED, url: "/item.php#v=blood" });
                } else if (healthPct >= 33) {
                    alerts.push({ text: `Life ${healthPct}%: You could make bags`, color: CONFIG.COLORS.GRAY, url: "/item.php#v=blood" });
                }
            }

            if (settings.xanax) {
                const energyBar = document.querySelector(CONFIG.SELECTORS.ENERGY_BAR);
                const energyVal = energyBar?.querySelector('p[class*="bar-value"]')?.textContent || "0/0";
                const currentEnergy = parseInt(energyVal.split('/')[0].replace(/[^0-9]/g, '')) || 0;
                const onCooldown = !!document.querySelector(CONFIG.SELECTORS.DRUG_CD);

                if (!onCooldown && currentEnergy < 1000) {
                    if (currentEnergy > 750) {
                        const waste = (currentEnergy + 250) - 1000;
                        alerts.push({ text: `WASTE WARNING: BURN ${waste} ENERGY!`, color: CONFIG.COLORS.YELLOW, url: "/gym.php" });
                    } else {
                        alerts.push({ text: `ENERGY AT ${currentEnergy}: TAKE A XANAX!`, color: CONFIG.COLORS.GREEN, url: "/item.php#v=drugs" });
                    }
                }
            }
            return alerts;
        }
    };

    const UIManager = {
        renderAlerts() {
            const alerts = EfficiencyManager.getAlerts();
            let container = document.getElementById('torn-efficiency-bar');
            if (container) container.remove();
            if (alerts.length === 0) return;

            container = document.createElement('div');
            container.id = 'torn-efficiency-bar';
            Object.assign(container.style, { display: 'flex', flexDirection: 'column', width: '100%', zIndex: '999999', position: 'relative', gap: '2px' });

            alerts.forEach(alert => {
                const div = document.createElement('div');
                div.innerHTML = `⚠️ ${alert.text}`;
                Object.assign(div.style, { background: alert.color, color: '#fff', textAlign: 'center', padding: '14px', fontWeight: 'bold', fontSize: '14px', cursor: 'pointer', boxShadow: '0 2px 5px rgba(0,0,0,0.1)', textShadow: '1px 1px 2px rgba(0,0,0,0.5)' });
                div.onclick = () => { if(alert.url !== "#") window.location.href = alert.url; };
                container.appendChild(div);
            });
            document.querySelector(CONFIG.SELECTORS.MAIN_CONTAINER)?.before(container);
        },

        injectSettingsMenu() {
            const menu = document.querySelector(CONFIG.SELECTORS.SIDEBAR_MENU);
            if (!menu || document.getElementById('nav-efficiency-settings')) return;

            const settings = getSettings();
            const container = document.createElement('div');
            container.id = 'nav-efficiency-settings';
            container.className = 'area-desktop___bpqAS';
            container.style.borderLeft = "4px solid #37b24d";

            container.innerHTML = `
                <div id="settings-header" style="padding: 10px; cursor: pointer; background: rgba(55, 178, 77, 0.1); display: flex; justify-content: space-between; align-items: center;">
                    <span style="color: #37b24d; font-size: 11px; font-weight: bold;">EFFICIENCY SETTINGS</span>
                    <span id="settings-chevron">▼</span>
                </div>
                <div id="settings-content" style="display: none; padding: 10px; flex-direction: column; gap: 8px; background: rgba(0,0,0,0.2);">
                    ${['edu', 'oc', 'life', 'xanax'].map(key => `
                        <label style="display: flex; justify-content: space-between; color: #ccc; font-size: 11px; cursor: pointer;">
                            ${key.toUpperCase()} ALERTS
                            <input type="checkbox" data-key="${key}" ${settings[key] ? 'checked' : ''} style="cursor: pointer;">
                        </label>
                    `).join('')}
                    <button id="debug-show-all" style="margin-top: 5px; background: #444; color: #00ffcc; border: 1px solid #00ffcc; padding: 5px; font-size: 10px; cursor: pointer; font-weight: bold; border-radius: 3px;">
                        DEBUG: SHOW ALL ALERTS
                    </button>
                    <div id="debug-info-tray" style="display: none; margin-top: 10px; padding-top: 10px; border-top: 1px solid #555; text-align: center; flex-direction: column; gap: 10px;">
                        <a href="https://www.torn.com/profiles.php?XID=3863644" target="_blank" style="color: #37b24d; font-size: 10px; font-weight: bold; text-decoration: none; display: block;">
                            💸 Support Efficiency Logic?
                        </a>
                        <a href="https://www.torn.com/profiles.php?XID=3863644" target="_blank" style="color: #aaa; font-size: 9px; text-decoration: none; display: block; font-style: italic;">
                            Want a custom script? Message me.
                        </a>
                    </div>
                </div>
            `;

            menu.prepend(container);

            const header = document.getElementById('settings-header');
            const content = document.getElementById('settings-content');
            const chevron = document.getElementById('settings-chevron');
            const debugBtn = document.getElementById('debug-show-all');
            const infoTray = document.getElementById('debug-info-tray');

            header.onclick = () => {
                const active = content.style.display === 'flex';
                content.style.display = active ? 'none' : 'flex';
                chevron.style.transform = active ? 'rotate(0deg)' : 'rotate(180deg)';
            };

            debugBtn.onclick = (e) => {
                e.stopPropagation();
                DEBUG_FORCE_ALL = !DEBUG_FORCE_ALL;
                debugBtn.style.background = DEBUG_FORCE_ALL ? "#00ffcc" : "#444";
                debugBtn.style.color = DEBUG_FORCE_ALL ? "#000" : "#00ffcc";
                debugBtn.textContent = DEBUG_FORCE_ALL ? "DEBUG: ACTIVE" : "DEBUG: SHOW ALL ALERTS";
                infoTray.style.display = DEBUG_FORCE_ALL ? "flex" : "none";
                UIManager.renderAlerts();
            };

            content.onchange = (e) => {
                if(e.target.tagName !== "INPUT") return;
                const key = e.target.getAttribute('data-key');
                const current = getSettings();
                current[key] = e.target.checked;
                saveSettings(current);
                UIManager.renderAlerts();
            };
        }
    };

    const run = () => {
        UIManager.renderAlerts();
        UIManager.injectSettingsMenu();
    };

    setTimeout(run, 2000);
    setInterval(() => UIManager.renderAlerts(), CONFIG.CHECK_INTERVAL);
    window.addEventListener('hashchange', () => setTimeout(run, 1000));
    new MutationObserver(() => { if (!document.getElementById('nav-efficiency-settings')) UIManager.injectSettingsMenu(); })
        .observe(document.body, { childList: true, subtree: true });
})();