Torn Framework

Framework with proper script communication

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

You will need to install an extension such as Tampermonkey to install this script.

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name         Torn Framework
// @version      2.1
// @namespace    http://tampermonkey.net/
// @description  Framework with proper script communication
// @author
// @match        https://www.torn.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// @run-at document-body
// ==/UserScript==

(function () {
    'use strict';

    console.log('=== TORN FRAMEWORK VERSION STARTING ===');

    // Use unsafeWindow to ensure global access
    const globalWindow = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;

    // Prevent multiple instances
    if (globalWindow.TornFramework) {
        console.log('WARNING: TornFramework already exists!', globalWindow.TornFramework);
        return;
    }

    // Global framework object
    globalWindow.TornFramework = {
        version: '2.1-FIXED',
        modules: new Map(),
        initialized: false,
        debug: true
    };

    console.log('Framework object created on globalWindow:', globalWindow.TornFramework);

    // Settings
    let settings = {
        consoleEnabled: GM_getValue('consoleEnabled', true),
        menuVisible: GM_getValue('menuVisible', false)
    };

    function saveSettings() {
        Object.keys(settings).forEach(key => {
            GM_setValue(key, settings[key]);
        });
    }

    // =========================
    // LOGGING SYSTEM
    // =========================
    const logDiv = document.createElement("div");
    logDiv.id = 'torn-framework-console';
    logDiv.style.cssText = `
        position: fixed;
        bottom: 0;
        left: 0;
        width: 450px;
        max-height: 300px;
        overflow-y: auto;
        background: linear-gradient(135deg, rgba(0,0,0,0.95), rgba(20,20,20,0.95));
        color: white;
        font-size: 11px;
        z-index: 999999;
        padding: 12px;
        border-radius: 0 12px 0 0;
        font-family: 'Consolas', 'Monaco', monospace;
        border: 2px solid #37b24d;
        box-shadow: 0 4px 20px rgba(55,178,77,0.3);
        backdrop-filter: blur(10px);
        display: ${settings.consoleEnabled ? 'block' : 'none'};
    `;
    document.body.appendChild(logDiv);

    function log(msg, type = 'info', module = 'FRAMEWORK') {
        try {
            const timestamp = new Date().toLocaleTimeString();
            const p = document.createElement("div");

            const colors = {
                'error': '#ff6b6b',
                'success': '#51cf66',
                'warning': '#ffd43b',
                'info': '#74c0fc',
                'debug': '#9775fa'
            };

            p.style.cssText = `
                color: ${colors[type] || '#ccc'};
                padding: 3px 0;
                border-bottom: 1px solid rgba(255,255,255,0.1);
                font-size: 10px;
                line-height: 1.3;
            `;

            const moduleColor = module === 'FRAMEWORK' ? '#37b24d' : '#f59f00';
            p.innerHTML = `<span style="color: #666;">[${timestamp}]</span> <span style="color: ${moduleColor}; font-weight: bold;">[${module}]</span> ${msg}`;

            logDiv.appendChild(p);
            logDiv.scrollTop = logDiv.scrollHeight;

            // Limit to 100 logs
            while (logDiv.children.length > 100) {
                logDiv.removeChild(logDiv.firstChild);
            }

            console.log(`[TornFramework:${module}] ${msg}`);
        } catch (error) {
            console.error('Framework logging failed:', error);
        }
    }

    globalWindow.TornFramework.log = log;
    log('Framework logging system initialized', 'success');

    // =========================
    // MAIN MENU SYSTEM
    // =========================
    const modMenu = document.createElement("div");
    modMenu.id = 'torn-framework-menu';
    modMenu.style.cssText = `
        position: fixed;
        top: 10px;
        right: 10px;
        width: 420px;
        max-height: 85vh;
        overflow-y: auto;
        background: linear-gradient(135deg, rgba(0,0,0,0.95), rgba(20,20,20,0.95));
        color: white;
        font-size: 12px;
        z-index: 1000000;
        padding: 20px;
        border-radius: 12px;
        font-family: 'Segoe UI', Arial, sans-serif;
        border: 2px solid #37b24d;
        box-shadow: 0 8px 32px rgba(55,178,77,0.4);
        backdrop-filter: blur(10px);
        display: none;
    `;

    modMenu.innerHTML = `
        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 2px solid #37b24d; padding-bottom: 15px;">
            <h3 style="margin: 0; color: #37b24d; text-shadow: 0 2px 4px rgba(0,0,0,0.5);">Torn Framework v${globalWindow.TornFramework.version}</h3>
            <button id="closeMenu" style="background: linear-gradient(45deg, #f03e3e, #c92a2a); border: none; color: white; padding: 6px 10px; border-radius: 6px; cursor: pointer; font-size: 12px;">✕</button>
        </div>

        <!-- FRAMEWORK STATUS -->
        <div style="margin-bottom: 15px; padding: 12px; background: linear-gradient(45deg, rgba(55,178,77,0.1), rgba(116,184,22,0.1)); border-radius: 8px; border: 1px solid #37b24d;">
            <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; font-size: 10px; margin-bottom: 8px;">
                <div>Modules: <span id="moduleCount">0</span></div>
                <div>Active: <span id="activeCount">0</span></div>
                <div>Uptime: <span id="uptimeDisplay">0s</span></div>
            </div>
            <div id="moduleList" style="max-height: 80px; overflow-y: auto; font-size: 9px; color: #ccc;"></div>
        </div>

        <!-- FRAMEWORK SETTINGS -->
        <div style="margin-bottom: 15px; border: 1px solid #37b24d; padding: 12px; border-radius: 8px;">
            <h4 style="margin: 0 0 12px 0; color: #37b24d;">Framework Settings</h4>
            <label style="display: flex; align-items: center; cursor: pointer; margin-bottom: 8px;">
                <input type="checkbox" id="consoleEnabled" ${settings.consoleEnabled ? 'checked' : ''}>
                <span style="margin-left: 8px;">Debug Console</span>
            </label>
        </div>

        <!-- MODULE SECTIONS WILL BE INJECTED HERE -->
        <div id="moduleMenuSections"></div>
    `;
    document.body.appendChild(modMenu);

    // Menu toggle button
    const menuBtn = document.createElement("button");
    menuBtn.innerHTML = "⚙️";
    menuBtn.style.cssText = `
        position: fixed;
        top: 10px;
        right: 10px;
        z-index: 999999;
        background: linear-gradient(135deg, #37b24d, #51cf66);
        color: white;
        border: none;
        padding: 12px 14px;
        border-radius: 50%;
        cursor: pointer;
        font-size: 16px;
        box-shadow: 0 4px 16px rgba(55,178,77,0.4);
        transition: all 0.3s ease;
    `;
    menuBtn.onclick = () => {
        const isVisible = modMenu.style.display !== 'none';
        modMenu.style.display = isVisible ? 'none' : 'block';
        menuBtn.style.right = isVisible ? '10px' : '440px';
        if (!isVisible) updateFrameworkStatus();
        settings.menuVisible = !isVisible;
        saveSettings();
    };
    document.body.appendChild(menuBtn);

    // =========================
    // MODULE MANAGEMENT
    // =========================
    globalWindow.TornFramework.registerModule = function (moduleConfig) {
        const {
            name,
            version = '1.0',
            description = '',
            menuSection = null,
            initialize = null,
            cleanup = null,
            isActive = () => false
        } = moduleConfig;

        log(`Module registration attempt: ${name}`, 'info');

        if (!name) {
            log('Module registration failed: name is required', 'error');
            return false;
        }

        if (globalWindow.TornFramework.modules.has(name)) {
            log(`Module ${name} already registered, updating...`, 'warning');
        }

        const module = { name, version, description, menuSection, initialize, cleanup, isActive, registered: Date.now() };
        globalWindow.TornFramework.modules.set(name, module);
        log(`Module registered: ${name} v${version}`, 'success');

        if (menuSection) addModuleMenuSection(name, menuSection);

        if (initialize && typeof initialize === 'function') {
            try {
                initialize();
                log(`Module ${name} initialized`, 'success');
            } catch (error) {
                log(`Module ${name} initialization failed: ${error.message}`, 'error');
            }
        }

        updateFrameworkStatus();
        return true;
    };

    function addModuleMenuSection(moduleName, sectionHTML) {
        const container = document.getElementById('moduleMenuSections');
        if (!container) return;

        const existing = document.getElementById(`module-${moduleName}`);
        if (existing) existing.remove();

        const section = document.createElement('div');
        section.id = `module-${moduleName}`;
        section.style.cssText = 'margin-bottom: 15px; border: 1px solid #f59f00; padding: 12px; border-radius: 8px;';
        section.innerHTML = sectionHTML;

        container.appendChild(section);
        log(`Menu section added for module: ${moduleName}`, 'debug');
    }

    function updateFrameworkStatus() {
        try {
            const moduleCount = globalWindow.TornFramework.modules.size;
            const activeCount = Array.from(globalWindow.TornFramework.modules.values())
                .filter(module => module.isActive()).length;
            const uptime = Math.floor((Date.now() - globalWindow.TornFramework.startTime) / 1000);

            document.getElementById('moduleCount').textContent = moduleCount;
            document.getElementById('activeCount').textContent = activeCount;
            document.getElementById('uptimeDisplay').textContent = `${uptime}s`;

            const moduleList = document.getElementById('moduleList');
            if (moduleList) {
                const moduleInfo = Array.from(globalWindow.TornFramework.modules.values())
                    .map(module => {
                        const status = module.isActive() ? '🟢' : '🔴';
                        return `${status} ${module.name} v${module.version}`;
                    }).join('<br>');
                moduleList.innerHTML = moduleInfo || 'No modules loaded';
            }
        } catch (error) {
            log(`Status update failed: ${error.message}`, 'error');
        }
    }

    // =========================
    // SETTINGS EVENTS
    // =========================
    function setupFrameworkEvents() {
        document.getElementById('closeMenu').onclick = () => {
            modMenu.style.display = 'none';
            menuBtn.style.right = '10px';
            settings.menuVisible = false;
            saveSettings();
        };

        document.getElementById('consoleEnabled').onchange = function () {
            settings.consoleEnabled = this.checked;
            logDiv.style.display = settings.consoleEnabled ? 'block' : 'none';
            saveSettings();
        };
    }

    // =========================
    // INITIALIZATION
    // =========================
    function initFramework() {
        if (globalWindow.TornFramework.initialized) return;

        log('Initializing Torn Framework...', 'success');

        globalWindow.TornFramework.startTime = Date.now();
        globalWindow.TornFramework.initialized = true;

        setupFrameworkEvents();

        if (settings.menuVisible) {
            modMenu.style.display = 'block';
            menuBtn.style.right = '440px';
        }

        log('Framework ready! Modules can now register.', 'success');
        updateFrameworkStatus();

        // Periodically update status
        setInterval(updateFrameworkStatus, 5000);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            log('DOM loaded, initializing framework');
            setTimeout(initFramework, 500);
        });
    } else {
        log('DOM already loaded, initializing framework');
        setTimeout(initFramework, 500);
    }

    log('Framework script completed loading');
})();