From c84aaef994ff2cd687f2116d45eee385af65a0d2 Mon Sep 17 00:00:00 2001 From: Minoricew <154642983+Minoricew@users.noreply.github.com> Date: Sat, 22 Nov 2025 19:00:16 +0800 Subject: [PATCH] =?UTF-8?q?[=E2=9C=A8=20Feat]=20Add=20settings=20for=20Aik?= =?UTF-8?q?ari=20Telemetry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/aura/ui/aikari/onConnectedSeq.js | 23 ++- .../ui/composables/aikariConfigManager.js | 41 ++++++ src/aura/ui/composables/settingsRenderer.js | 2 +- .../behaviourCtrl/aikariStatus.js | 8 ++ .../behaviourCtrl/settings/basic.js | 132 ++++++++++++++++++ src/core/preload.js | 2 +- 7 files changed, 204 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c21e82b..7aa7550 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "HugoAura", - "version": "0.2.0-rc1-p1", + "version": "0.2.0-rc1-p2", "description": "Aura for SeewoHugo", "main": "app.asar/main.js", "dependencies": {}, diff --git a/src/aura/ui/aikari/onConnectedSeq.js b/src/aura/ui/aikari/onConnectedSeq.js index c8af9ea..c75c0eb 100644 --- a/src/aura/ui/aikari/onConnectedSeq.js +++ b/src/aura/ui/aikari/onConnectedSeq.js @@ -40,19 +40,36 @@ const actions = { data: {}, }) ); - const promise = new Promise((resolve) => { + const promiseForConfig = new Promise((resolve) => { wsGetCallbacks.set(eventId, resolve); }); - const data = await promise; + const data = await promiseForConfig; if (data.success) { console.debug( "[HugoAura / UI / Aikari OCMS] Received Aikari launcher config: ", data ); - return data.data; } else { return null; } + wsObj.send( + JSON.stringify({ + module: "launcher", + eventId, + method: "config.actions.getTelemetryIsEnabled", + data: {}, + }) + ); + const promiseForTelemetry = new Promise((resolve) => { + wsGetCallbacks.set(eventId, resolve); + }); + const telemetryConfig = await promiseForTelemetry; + if (telemetryConfig.success) { + data.data.telemetryEnabled = telemetryConfig.data.isEnabled; + } else { + data.data.telemetryEnabled = false; + } + return data.data; }, getAikariPLSRules: async (wsObj) => { const eventId = genRandomHex(); diff --git a/src/aura/ui/composables/aikariConfigManager.js b/src/aura/ui/composables/aikariConfigManager.js index abd536a..876c0b7 100644 --- a/src/aura/ui/composables/aikariConfigManager.js +++ b/src/aura/ui/composables/aikariConfigManager.js @@ -80,6 +80,46 @@ const updateAikariConfigToRemote = async ( }); }; +/** + * + * @param {boolean} newValue + */ +const updateAikariTelemetryConfigToRemote = async (newValue) => { + const aikariConfigUpdateEvent = new CustomEvent("onAikariConfigUpdate", { + detail: { + path: ["telemetry"], + value: newValue, + }, + }); + document.dispatchEvent(aikariConfigUpdateEvent); + const settingsEntries = document.getElementsByClassName( + "aura-settings-entry" + ); + if (settingsEntries.length > 0) { + Array.from(settingsEntries).forEach((entry) => { + entry.dispatchEvent(aikariConfigUpdateEvent); + }); + } + + /** + * @type {ClientAikariRequest} + */ + const data = { + method: "config.actions.setTelemetryIsEnabled", + data: { + isEnabled: newValue, + }, + eventId: genRandomHex(), + module: "launcher", + }; + + global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.ws.sendWsMessage`, data); + global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.syncAikariConfig`, { + basic: global.__HUGO_AURA__.aikariSettings, + rules: global.__HUGO_AURA__.aikariRules, + }); +}; + // [!] Will be deprecated const updateAikariPLSRulesToRemote = async ( configKey, @@ -131,6 +171,7 @@ module.exports = { updateAikariRulesFromLocal, updateAikariStatusFromLocal, updateAikariSettingsFromLocal, + updateAikariTelemetryConfigToRemote, updateAikariConfigToRemote, updateAikariPLSRulesToRemote, }; diff --git a/src/aura/ui/composables/settingsRenderer.js b/src/aura/ui/composables/settingsRenderer.js index 8abbc05..a5863b8 100755 --- a/src/aura/ui/composables/settingsRenderer.js +++ b/src/aura/ui/composables/settingsRenderer.js @@ -380,7 +380,7 @@ const renderNormalSettingsItem = (entry, formEl) => { } if (entry.aikariRequired) { - if (!global.__HUGO_AURA__.aikariStats.connected) { + if (!global.__HUGO_AURA__.aikariStats.connected && !entry.alwaysEnable) { setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续"); } diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.js index abece25..ebcf5b6 100644 --- a/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.js +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.js @@ -606,6 +606,14 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig) const result = await ipcRenderer.invoke( `${IPC_METHOD_BASE}.retryAikariConnect` ); + if ( + !global.__HUGO_AURA__.aikariSettings || + (global.__HUGO_AURA__.aikariStats.connected === false && + global.__HUGO_AURA__.aikariStats.launched === true) + ) { + ipcRenderer.invoke(`${IPC_METHOD_BASE}.forceReloadKeepAliveWin`); + } + if (result.success && result.status === "Retrying") { updateOperationBtnStatus("Refresh", true, "正在重连"); diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js index 22db8b9..4c8326a 100755 --- a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js @@ -1,7 +1,12 @@ const REQUIRE_BASE = "."; +const path = require("path"); + +const AIKARI_ROOT_DIR = path.join("C:\\ProgramData", "HugoAura", "Aikari"); + const { updateAikariConfigToRemote, + updateAikariTelemetryConfigToRemote, } = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`); const basicSettings = [ @@ -80,6 +85,133 @@ const basicSettings = [ }, ], }, + { + id: 1, + categoryName: "分析", + child: [ + { + index: 0, + id: "aikariTelemetryCtrl", + type: "switch", + name: "启用错误收集与分析", + description: "启用后, Aikari 将在发生错误时上报自托管 Sentry", + reactive: true, + reactiveVal: ["root.settings"], + restart: false, + reload: false, + aikariRequired: false, + restartAikari: false, + warning: true, + warningContent: + "我们不会收集您的设备用户名、管家内的学校名等信息, 也不会保存您的 IP 地址, 所有上传的数据仅供调试使用, 不会与任何第三方共享", + associateVal: null, + auraIf: () => true, + defaultValue: false, + valueGetter: () => { + if ( + !global.__HUGO_AURA__.aikariSettings || + !global.__HUGO_AURA__.aikariStats.connected + ) { + const fs = require("fs"); + return fs.existsSync( + path.join(AIKARI_ROOT_DIR, ".telemetryEnabled") + ); + } else { + return global.__HUGO_AURA__.aikariSettings.telemetryEnabled; + } + }, + callbackFn: (newVal) => { + if ( + !global.__HUGO_AURA__.aikariSettings || + !global.__HUGO_AURA__.aikariStats.connected + ) { + if (newVal) { + const fs = require("fs"); + fs.appendFile( + path.join(AIKARI_ROOT_DIR, ".telemetryEnabled"), + "", + (err) => { + if (err) console.warn(err); + } + ); + return true; + } else { + const fs = require("fs"); + try { + fs.unlinkSync(path.join(AIKARI_ROOT_DIR, ".telemetryEnabled")); + return true; + } catch (err) { + console.error("Error removing telemetry flag: ", err); + } + } + } else { + global.__HUGO_AURA__.aikariSettings.telemetryEnabled = newVal; + updateAikariTelemetryConfigToRemote(newVal); + return true; + } + }, + }, + { + index: 1, + id: "aikariTelemetryId", + type: "button", + style: "outline", + name: "Aikari Telemetry ID", + reactive: true, + reactiveVal: ["telemetry"], + restart: false, + reload: false, + aikariRequired: true, + restartAikari: false, + warning: true, + warningContent: "此标识符完全在初始化时随机生成, 与设备特征无关", + associateVal: ["telemetry"], + auraIf: () => true, + alwaysEnable: true, + buttonContent: "复制", + valueGetter: async () => { + if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl) + global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl = {}; + const getIdPromise = new Promise((resolve) => { + setTimeout(() => { + const fs = require("fs"); + const telemetryIdPath = path.join( + AIKARI_ROOT_DIR, + ".telemetryId" + ); + if (fs.existsSync(telemetryIdPath)) { + const fileContent = fs + .readFileSync(telemetryIdPath, { encoding: "utf-8" }) + .trim(); + + global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl.telemetryId = + fileContent; + resolve("标识符: " + fileContent); + } + global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl.telemetryId = + null; + resolve("未能获取标识符, Aikari 未安装或未初始化"); + }, 1000); + }); + return await getIdPromise; + }, + callbackFn: async (event) => { + if ( + global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl + .telemetryId + ) { + await navigator.clipboard.writeText( + global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl + .telemetryId + ); + event.target.textContent = "已复制"; + } else { + event.target.textContent = "复制失败"; + } + }, + }, + ], + }, ]; module.exports = { basicSettings }; diff --git a/src/core/preload.js b/src/core/preload.js index e1da9db..fd6dc85 100755 --- a/src/core/preload.js +++ b/src/core/preload.js @@ -1,6 +1,6 @@ // @ts-check -const __AURA_VERSION__ = "0.2.0-rc1-p1"; +const __AURA_VERSION__ = "0.2.0-rc1-p2"; (() => { if (require.main) return; // 如果只是导入 Aura Version, 不运行闭包逻辑