TriX Core Library

Core logic library for TriX Executor.

Version au 11/07/2025. Voir la dernière version.

Ce script ne doit pas être installé directement. C'est une librairie destinée à être incluse dans d'autres scripts avec la méta-directive // @require https://updategf.qytechs.cn/scripts/541461/1622873/TriX%20Core%20Library.js

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name        TriX Core Library
// @namespace   https://github.com/YourUsername/TriX-Executor
// @version     2.3.2
// @description Core logic library for TriX Executor.
// @author      You
// @license     MIT
// ==/UserScript==

const TriX_Core = (function() {
    'use strict';
    let _GM; // Internal storage for GM functions

    const TabManager = {
        tabs:[], myTabInfo:{}, uiInitialized:false, isMaster:false,
        init(username, gmFunctions){
            _GM = gmFunctions; 
            const TAB_ID = `tab_${Date.now().toString(36)}_${Math.random().toString(36).substring(2)}`;
            const LOAD_TIME = Date.now();
            this.myTabInfo={id:TAB_ID,username:username,loadTime:LOAD_TIME,lastSeen:Date.now()};
            _GM.GM_addValueChangeListener('trix_active_tabs',(name,old_value,new_value,remote)=>{if(remote)this.pruneAndRefresh(new_value)});
            this.register();
            setInterval(()=>this.register(), 5000);
            window.addEventListener('beforeunload',()=>this.unregister());
        },
        async register(){let e=await _GM.GM_getValue("trix_active_tabs",[]);const t=Date.now();e=e.filter(e=>t-e.lastSeen<15e3),this.myTabInfo.lastSeen=t;const i=e.findIndex(e=>e.id===this.myTabInfo.id);-1<i?e[i]=this.myTabInfo:e.push(this.myTabInfo),await _GM.GM_setValue("trix_active_tabs",e),this.pruneAndRefresh(e)},
        async unregister(){let e=await _GM.GM_getValue("trix_active_tabs",[]);e=e.filter(e=>e.id!==this.myTabInfo.id),await _GM.GM_setValue("trix_active_tabs",e)},
        pruneAndRefresh(e){this.tabs=e,this.uiInitialized&&TriX_UI.updateTabCountUI(e.length),this.checkMasterStatus()},
        checkMasterStatus(){this.isMaster=this.amIMaster(),this.isMaster&&!this.uiInitialized&&this.initUI()},
        amIMaster(){if(!this.myTabInfo.username||this.myTabInfo.username.startsWith("Guest_"))return!0;const e=this.tabs.filter(e=>e.username===this.myTabInfo.username);return 0===e.length||this.myTabInfo.loadTime===Math.min(...e.map(e=>e.loadTime))},
        initUI(){if(this.uiInitialized)return;console.log("[TriX Core] This tab is the master. Initializing UI.");this.uiInitialized=true;TriX_UI.init(_GM)}
    };
    const ScriptManager={async saveScriptFromEditor(){const e=document.getElementById("trix-save-name").value.trim(),t=document.getElementById("trix-editor").value,i=document.getElementById("trix-python-editor").value;e?t||i?(await _GM.GM_setValue(`trix_script_${e}`,JSON.stringify({js:t,py:i})),TriX_UI.log(`Script '${e}' saved.`,"info"),this.populateScriptList()):TriX_UI.log("Cannot save: Editor is empty.","warn"):TriX_UI.log("Cannot save: Name is required.","error")},async loadScriptToEditor(e){if(!e)return TriX_UI.log("Invalid script key.","error");const t=await _GM.GM_getValue(e,"{}"),i=e.replace("trix_script_","");try{const s=JSON.parse(t);document.getElementById("trix-editor").value=s.js||"",document.getElementById("trix-python-editor").value=s.py||"",document.getElementById("trix-save-name").value=i,TriX_UI.log(`Loaded script: ${i}`,"info"),TriX_UI.currentScriptName=i,TriX_UI.setActiveScriptItem(e)}catch(e){TriX_UI.log("Error loading script data. It might be in an old format.","error")}},async deleteCurrentScript(){const e=TriX_UI.currentScriptName;e&&confirm(`Are you sure you want to delete '${e}'?`)&&(await _GM.GM_deleteValue(`trix_script_${e}`),TriX_UI.log(`Script '${e}' deleted.`,"info"),document.getElementById("trix-editor").value="",document.getElementById("trix-python-editor").value="",document.getElementById("trix-save-name").value="",TriX_UI.currentScriptName="",this.populateScriptList())},async populateScriptList(e=null){const t=document.getElementById("trix-script-list");t.innerHTML="";const i=(await _GM.GM_listValues()).filter(e=>e.startsWith("trix_script_"));i.sort().forEach(e=>{const i=document.createElement("div");i.className="trix-script-item",i.textContent=e.replace("trix_script_",""),i.dataset.scriptKey=e,t.appendChild(i)}),TriX_UI.setActiveScriptItem(e||TriX_UI.currentScriptName?`trix_script_${TriX_UI.currentScriptName}`:null)}};
    const Executor={executeJS(e){if(!e.trim())return TriX_UI.log("JS Execution skipped: script is empty.","warn");TriX_UI.log("Executing JavaScript...","info");try{const t=this.createAPI(),i=new Function("TriX",e);i(t)}catch(e){TriX_UI.log(`JavaScript Error: ${e.message}`,"error"),console.error("TriX Executor JS Error:",e)}},executePY(e){if(!e.trim())return TriX_UI.log("Python Execution skipped: script is empty.","warn");TriX_Python.run(e)},createAPI:()=>({log:(e,t="log")=>{const i="object"==typeof e?JSON.stringify(e):String(e);TriX_UI.log(i,t)},broadcast:e=>{MultiTab.broadcast(e)},query:(e,t="text")=>{const i=document.querySelector(e);return i?"html"===t?i.innerHTML:"value"===t?i.value:"element"===t?i:i.textContent:null},queryAll:(e,t="text")=>{const i=document.querySelectorAll(e);return Array.from(i).map(e=>"html"===t?e.innerHTML:"value"===t?e.value:"element"===t?e:e.textContent)}})};
    const MultiTab={init(e){_GM=e;const t=`tab_${Date.now().toString(36)}_${Math.random().toString(36).substring(2)}`;this.TAB_ID=t,_GM.GM_addValueChangeListener("trix_broadcast_channel",this.listener)},listener(e,t,i,s){s&&i.senderId!==this.TAB_ID&&TriX_UI.log(`Received broadcast: ${JSON.stringify(i.payload)}`,"broadcast")},broadcast(e){const t={senderId:this.TAB_ID,timestamp:Date.now(),payload:e};_GM.GM_setValue("trix_broadcast_channel",t),TriX_UI.log(`Broadcast sent: ${JSON.stringify(e)}`,"broadcast")}};
    
    function init(username, gmFunctions) {
        TabManager.init(username, gmFunctions);
    }
    
    return { init, ScriptManager, Executor, MultiTab };
})();