您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Core logic library for TriX Executor.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/541461/1622888/TriX%20Core%20Library.js
// ==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 < 15000); 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; if(this.uiInitialized) TriX_UI.updateTabCountUI(e.length); this.checkMasterStatus(); }, checkMasterStatus(){ this.isMaster = this.amIMaster(); if(this.isMaster && !this.uiInitialized) { this.initUI(); } }, amIMaster(){ if (!this.myTabInfo.username || this.myTabInfo.username.startsWith("Guest_")) return true; 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 name = document.getElementById("trix-save-name").value.trim(); const jsCode = document.getElementById("trix-editor").value; const pyCode = document.getElementById("trix-python-editor").value; if (!name) return TriX_UI.log("Cannot save: Name is required.", "error"); if (!jsCode && !pyCode) return TriX_UI.log("Cannot save: Editor is empty.", "warn"); const scriptData = JSON.stringify({ js: jsCode, py: pyCode }); await _GM.GM_setValue(`trix_script_${name}`, scriptData); TriX_UI.log(`Script '${name}' saved.`, "info"); this.populateScriptList(); }, async loadScriptToEditor(key) { if (!key) return TriX_UI.log("Invalid script key.", "error"); const scriptJSON = await _GM.GM_getValue(key, "{}"); const name = key.replace("trix_script_", ""); try { const scriptData = JSON.parse(scriptJSON); document.getElementById("trix-editor").value = scriptData.js || ""; document.getElementById("trix-python-editor").value = scriptData.py || ""; document.getElementById("trix-save-name").value = name; TriX_UI.log(`Loaded script: ${name}`, "info"); TriX_UI.currentScriptName = name; TriX_UI.setActiveScriptItem(key); } catch (e) { TriX_UI.log("Error loading script data. It might be in an old format.", "error"); } }, async deleteCurrentScript() { const name = TriX_UI.currentScriptName; if (name && confirm(`Are you sure you want to delete '${name}'?`)) { await _GM.GM_deleteValue(`trix_script_${name}`); TriX_UI.log(`Script '${name}' 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() { const listEl = document.getElementById("trix-script-list"); listEl.innerHTML = ""; const keys = (await _GM.GM_listValues()).filter(e => e.startsWith("trix_script_")); keys.sort().forEach(key => { const item = document.createElement("div"); item.className = "trix-script-item"; item.textContent = key.replace("trix_script_", ""); item.dataset.scriptKey = key; listEl.appendChild(item); }); TriX_UI.setActiveScriptItem(TriX_UI.currentScriptName ? `trix_script_${TriX_UI.currentScriptName}` : null); } }; const Executor = { executeJS(code) { if (!code.trim()) return TriX_UI.log("JS Execution skipped: script is empty.", "warn"); TriX_UI.log("Executing JavaScript...", "info"); try { const api = this.createAPI(); new Function("TriX", code)(api); } catch (e) { TriX_UI.log(`JavaScript Error: ${e.message}`, "error"); } }, executePY(code) { if (!code.trim()) return TriX_UI.log("Python Execution skipped: script is empty.", "warn"); if (typeof Sk === 'undefined') return TriX_UI.log("Skulpt not loaded. Cannot run Python.", "error"); TriX_UI.log("Executing Python via Skulpt...", "info"); Sk.configure({ output: (text) => { if (text.trim()) TriX_UI.log(`[Python]: ${text.trim()}`, 'log'); }, read: (x) => { if (Sk.builtinFiles === undefined || Sk.builtinFiles.files[x] === undefined) throw "File not found: '" + x + "'"; return Sk.builtinFiles.files[x]; } }); Sk.misceval.asyncToPromise(() => Sk.importMainWithBody("<stdin>", false, code, true)) .then(res => TriX_UI.log("Python script finished.", "info")) .catch(err => TriX_UI.log(err.toString(), "error")); }, 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(gmFunctions) { _GM = gmFunctions; const TAB_ID = `tab_${Date.now().toString(36)}_${Math.random().toString(36).substring(2)}`; this.TAB_ID = TAB_ID; _GM.GM_addValueChangeListener("trix_broadcast_channel", this.listener.bind(this)); }, listener(name, oldValue, newValue, remote) { if (remote && newValue.senderId !== this.TAB_ID) { TriX_UI.log(`Received broadcast: ${JSON.stringify(newValue.payload)}`, "broadcast"); } }, broadcast(payload) { const message = { senderId: this.TAB_ID, timestamp: Date.now(), payload: payload }; _GM.GM_setValue("trix_broadcast_channel", message); TriX_UI.log(`Broadcast sent: ${JSON.stringify(payload)}`, "broadcast"); } }; function init(username, gmFunctions) { TabManager.init(username, gmFunctions); } return { init, ScriptManager, Executor, MultiTab }; })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址