mirror of
https://github.com/HugoAura/Seewo-HugoAura.git
synced 2026-06-24 09:54:26 +08:00
Compare commits
13 Commits
v0.2.0-rc1
...
v0.2.0-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db55f54cc1 | ||
|
|
46ca11caad | ||
|
|
6ee3f99411 | ||
|
|
f2bb2ab06a | ||
|
|
971d3db43a | ||
|
|
f7feca7ff2 | ||
|
|
b27b1a6573 | ||
|
|
1b90932869 | ||
|
|
c84aaef994 | ||
|
|
8656fd0334 | ||
|
|
80354cc310 | ||
|
|
cd946a60fb | ||
|
|
a6c68782a0 |
15
.github/ISSUE_TEMPLATE/bugReport.yml
vendored
15
.github/ISSUE_TEMPLATE/bugReport.yml
vendored
@@ -3,6 +3,19 @@ description: 反馈应用中的问题, 或预期外的行为
|
|||||||
labels: ["Bug"]
|
labels: ["Bug"]
|
||||||
title: "[Bug] "
|
title: "[Bug] "
|
||||||
body:
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: 在开始之前 / Before starting
|
||||||
|
options:
|
||||||
|
- label: 我了解本 Repo 仅接受 HugoAura-Main 本体 (管家 Electron 侧 Hook) 的问题反馈
|
||||||
|
required: true
|
||||||
|
- label: 我知晓, 如果这是关于 HugoAura 安装器的 Bug, 我应该前往 [HugoAura-Install Issues](https://github.com/HugoAura/HugoAura-Install/issues) 提交 Bug Report
|
||||||
|
required: true
|
||||||
|
- label: 我知晓, 如果这是 HugoAura Aikari 的 Bug, 我应该前往 [HugoAura-Aikari Issues](https://github.com/HugoAura/HugoAura-Aikari/issues) 提交 Bug Report
|
||||||
|
required: true
|
||||||
|
- label: 我知晓, 如果我将 Issue 提交到了错误的 Repo, 可能会引发开发者响应速度降低 / Issue 被忽略 / Issue 被 Close as duplicate / Issue 被 Transfer 等情况
|
||||||
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: 复现步骤 / Reproduce steps
|
label: 复现步骤 / Reproduce steps
|
||||||
@@ -48,7 +61,7 @@ body:
|
|||||||
options:
|
options:
|
||||||
- label: 我已经在 [HugoAura Issues](https://github.com/HugoAura/Seewo-HugoAura/issues) 中查询过相关关键词, 并确定此 Issue 是唯一的。
|
- label: 我已经在 [HugoAura Issues](https://github.com/HugoAura/Seewo-HugoAura/issues) 中查询过相关关键词, 并确定此 Issue 是唯一的。
|
||||||
required: true
|
required: true
|
||||||
- label: 我已经确认, 我运行的 HugoAura 版本与希沃管家客户端版本相兼容
|
- label: 我已经确认, 我正在使用最新版本的希沃管家客户端
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1 +1 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: true
|
||||||
|
|||||||
13
.github/ISSUE_TEMPLATE/featureRequest.yml
vendored
13
.github/ISSUE_TEMPLATE/featureRequest.yml
vendored
@@ -3,6 +3,19 @@ description: 提交你想要的新功能
|
|||||||
labels: ["Feature"]
|
labels: ["Feature"]
|
||||||
title: "[Feature Request] "
|
title: "[Feature Request] "
|
||||||
body:
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: 在开始之前 / Before starting
|
||||||
|
options:
|
||||||
|
- label: 我了解本 Repo 仅接受 HugoAura-Main 本体 (管家 Electron 侧 Hook) 的功能请求
|
||||||
|
required: true
|
||||||
|
- label: 我知晓, 如果这是关于 HugoAura 安装器的功能请求, 我应该前往 [HugoAura-Install Issues](https://github.com/HugoAura/HugoAura-Install/issues) 提交 Feature Request
|
||||||
|
required: true
|
||||||
|
- label: 我知晓, 如果本功能请求涉及流量过滤、底层修改等目的, 我应该前往 [HugoAura-Aikari Issues](https://github.com/HugoAura/HugoAura-Aikari/issues) 提交 Feature Request
|
||||||
|
required: true
|
||||||
|
- label: 我知晓, 如果我将 Issue 提交到了错误的 Repo, 可能会引发开发者响应速度降低 / Issue 被忽略 / Issue 被 Close as duplicate / Issue 被 Transfer 等情况
|
||||||
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: 概述 / Overview
|
label: 概述 / Overview
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/other.yml
vendored
2
.github/ISSUE_TEMPLATE/other.yml
vendored
@@ -16,5 +16,5 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: 提交前请确认 / Confirm before submit
|
label: 提交前请确认 / Confirm before submit
|
||||||
options:
|
options:
|
||||||
- label: 请勿利用此 Issue 类型进行闲聊 / 灌水, 如需闲聊, 可移步至 HugoAura 社区 (forum.aurax.cc)
|
- label: 请勿利用此 Issue 类型进行闲聊 / 灌水, 如需闲聊, 可移步至 HugoAura 位于 STCN Forum 的论坛版块 (https://forum.smart-teach.cn/t/hugoaura)
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
31
README.md
31
README.md
@@ -3,16 +3,35 @@
|
|||||||
<h1 align="center">HugoAura</h1>
|
<h1 align="center">HugoAura</h1>
|
||||||
<h4 align="center">下一代希沃管家注入式修改方案</h4>
|
<h4 align="center">下一代希沃管家注入式修改方案</h4>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://github.com/HugoAura/HugoAura">首页</a> · <a href="https://hugo.aurax.cc/about">关于 (WIP)</a> · <a href="https://docs.aurax.cc/HugoAura-Main/">文档 (WIP)</a> · <a href="https://github.com/HugoAura/HugoAura/issues">反馈</a> · <a href="https://forum.aurax.cc/">社区</a>
|
<a href="https://github.com/HugoAura/HugoAura">首页</a> · <a href="https://hugo.aurax.cc/about">关于 (WIP)</a> · <a href="https://docs.aurax.cc/">文档</a> · <a href="https://github.com/HugoAura/HugoAura/issues">反馈</a> · <a href="https://forum.smart-teach.cn/t/hugoaura">社区</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<a href="https://campus.seewo.com/iot-public/file/?key=iot_doc_seewoServiceUpdateLog">
|
||||||
|
<img src="https://docs.aurax.cc/static/img/emg_announcement_banner.png" />
|
||||||
|
</a>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> 在[此处](https://github.com/HugoAura/HugoAura/wiki)查看 HugoAura 的安装教程
|
> 在[此处](https://docs.aurax.cc/)查看 HugoAura 的文档与安装教程
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
>
|
||||||
|
> 我们正在进行品牌形象更新, 本仓库 (`HugoAura/Seewo-HugoAura` / HugoAura SSA Electron Injection Loader) 将会逐渐改称 `HugoAura-Main`。这是为了区分 Project HugoAura 与 HugoAura SSA Electron Injection Loader 二者。
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> 已经过测试的希沃管家版本: v1.5.5.3878
|
> 已经过测试的希沃管家版本: v1.5.5.3917
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> **社群信息**
|
||||||
|
>
|
||||||
|
> - [QQ 群 (用户自治)](https://qm.qq.com/q/buo7m9oHBK)
|
||||||
|
> - [Telegram 群组](https://www.bilibili.com/video/BV1GJ411x7h7/) (暂时还没有...)
|
||||||
|
> - [STCN 论坛讨论版块](https://forum.smart-teach.cn/t/hugoaura)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -45,11 +64,11 @@
|
|||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> 演示图片, 请以实际安装后效果为准
|
> 演示图片, 请以实际安装后效果为准
|
||||||
|
|
||||||
<center><img src="https://s2.loli.net/2025/04/18/2KoGaXR9463tAgP.png" /></center>
|
<center><img src="https://s2.loli.net/2025/11/24/CUNDch9yps5IY1L.png" /></center>
|
||||||
|
|
||||||
<center><img src="https://s2.loli.net/2025/04/18/2lANiTpX79FcwfC.png" /></center>
|
<center><img src="https://s2.loli.net/2025/04/18/2lANiTpX79FcwfC.png" /></center>
|
||||||
|
|
||||||
<center><img src="https://s2.loli.net/2025/04/18/VNrdt7IC1PgXSpl.png" /></center>
|
<center><img src="https://s2.loli.net/2025/11/24/YgOqytCkxncRAs7.png" /></center>
|
||||||
|
|
||||||
## ⚡ 安装与使用
|
## ⚡ 安装与使用
|
||||||
|
|
||||||
@@ -65,7 +84,7 @@
|
|||||||
|
|
||||||
## 🎉 鸣谢
|
## 🎉 鸣谢
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## ❗ 免责声明
|
## ❗ 免责声明
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "HugoAura",
|
"name": "HugoAura",
|
||||||
"version": "0.2.0-rc1",
|
"version": "0.2.0-rc1-p3",
|
||||||
"description": "Aura for SeewoHugo",
|
"description": "Aura for SeewoHugo",
|
||||||
"main": "app.asar/main.js",
|
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "^36.3.2"
|
"electron": "^36.3.2"
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
const __SCOPE = "main";
|
const __SCOPE = "main";
|
||||||
|
|
||||||
const { exec } = require("child_process");
|
const { exec, execSync } = require("child_process");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const os = require("os");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const nodeHttps = require("https");
|
const nodeHttps = require("https");
|
||||||
const { fsComposables } = require("./fsIpcHandler");
|
const { fsComposables } = require("./fsIpcHandler");
|
||||||
@@ -268,6 +269,46 @@ const functions = {
|
|||||||
fs.unlinkSync(binPath);
|
fs.unlinkSync(binPath);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
clearHostFileItem: async () => {
|
||||||
|
const AIKARI_HOST_STR =
|
||||||
|
"127.11.45.14 iot-broker-mis.seewo.com # This line is generated by HugoAura-Aikari, please do not edit or delete it";
|
||||||
|
const hostPath = path.join(
|
||||||
|
process.env.SystemRoot || "C:\\WINDOWS",
|
||||||
|
"System32",
|
||||||
|
"drivers",
|
||||||
|
"etc",
|
||||||
|
"hosts"
|
||||||
|
);
|
||||||
|
if (fs.existsSync(hostPath)) {
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(hostPath, "utf-8");
|
||||||
|
const lines = content.split(/\r?\n/);
|
||||||
|
const newContent = lines.filter((line) => {
|
||||||
|
const shouldKeep = !line.includes(AIKARI_HOST_STR);
|
||||||
|
if (!shouldKeep) {
|
||||||
|
console.log(
|
||||||
|
`[HugoAura / IPC / Aikari] Cleaned hosts file item: ${line}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return shouldKeep;
|
||||||
|
});
|
||||||
|
if (lines.length === newContent.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const newData = newContent.join(os.EOL);
|
||||||
|
fs.writeFileSync(hostPath, newData, "utf-8");
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(
|
||||||
|
"[HugoAura / IPC / Aikari] Error cleaning hosts file: ",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -301,6 +342,14 @@ const applyAikariIpcHandler = (ipcMain) => {
|
|||||||
"Aikari-Installer.exe"
|
"Aikari-Installer.exe"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Prev PLS Cfg
|
||||||
|
const OLD_PLS_INSTALL_DIR = path.join(
|
||||||
|
"C:\\Program Files",
|
||||||
|
"HugoAura PLS",
|
||||||
|
"bin"
|
||||||
|
);
|
||||||
|
const OLD_PLS_SVC_NAME = "HugoAuraPLS";
|
||||||
|
|
||||||
const isAikariDetached = process.argv.includes("--aikari-detach");
|
const isAikariDetached = process.argv.includes("--aikari-detach");
|
||||||
|
|
||||||
global.__HUGO_AURA__.aikariStats = {
|
global.__HUGO_AURA__.aikariStats = {
|
||||||
@@ -622,6 +671,7 @@ const applyAikariIpcHandler = (ipcMain) => {
|
|||||||
case "inst":
|
case "inst":
|
||||||
// TODO: Impl Aikari INST
|
// TODO: Impl Aikari INST
|
||||||
case "uninst":
|
case "uninst":
|
||||||
|
await functions.clearHostFileItem();
|
||||||
return await functions.execCommand(
|
return await functions.execCommand(
|
||||||
logHeader,
|
logHeader,
|
||||||
AIKARI_UNINSTALLER_PATH,
|
AIKARI_UNINSTALLER_PATH,
|
||||||
@@ -651,6 +701,19 @@ const applyAikariIpcHandler = (ipcMain) => {
|
|||||||
} else {
|
} else {
|
||||||
fs.mkdirSync(AIKARI_TEMP_DL_DIR);
|
fs.mkdirSync(AIKARI_TEMP_DL_DIR);
|
||||||
}
|
}
|
||||||
|
if (fs.existsSync(OLD_PLS_INSTALL_DIR)) {
|
||||||
|
try {
|
||||||
|
execSync(`sc stop ${OLD_PLS_SVC_NAME}`);
|
||||||
|
execSync(`sc delete ${OLD_PLS_SVC_NAME}`);
|
||||||
|
} catch (err) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(OLD_PLS_INSTALL_DIR);
|
||||||
|
} catch (err) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
const channel = arg.channel ? arg.channel : "stable";
|
const channel = arg.channel ? arg.channel : "stable";
|
||||||
const reportWin = arg.reportTo ? arg.reportTo : "assistant";
|
const reportWin = arg.reportTo ? arg.reportTo : "assistant";
|
||||||
functions.handleAikariDlAndInstall(
|
functions.handleAikariDlAndInstall(
|
||||||
@@ -696,13 +759,31 @@ const applyAikariIpcHandler = (ipcMain) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ipcMain.handle(
|
||||||
|
`${methodBase}.forceReloadKeepAliveWin`,
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
||||||
|
* @param {any} arg
|
||||||
|
*/
|
||||||
|
(_event, arg) => {
|
||||||
|
ipcMain.send(
|
||||||
|
"auraWsKeepAlive",
|
||||||
|
`${methodBase}.post.onForceReloadRequested`,
|
||||||
|
arg
|
||||||
|
);
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
`${methodBase}.post.updateRetryStatus`,
|
`${methodBase}.post.updateRetryStatus`,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {import("electron").IpcMainInvokeEvent} _event
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
||||||
* @param {{ success: boolean }} arg
|
* @param {{ success: boolean; message: string }} arg
|
||||||
*/
|
*/
|
||||||
(_event, arg) => {
|
(_event, arg) => {
|
||||||
ipcMain.send("assistant", `${methodBase}.post.updateRetryStatus`, arg);
|
ipcMain.send("assistant", `${methodBase}.post.updateRetryStatus`, arg);
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ class NetworkHook {
|
|||||||
endOfHook: rule.endOfHook || null,
|
endOfHook: rule.endOfHook || null,
|
||||||
hookedContent: rule.hookedContent || null,
|
hookedContent: rule.hookedContent || null,
|
||||||
hookedContentFunc: rule.hookedContentFunc || null,
|
hookedContentFunc: rule.hookedContentFunc || null,
|
||||||
|
ruleFn: rule.ruleFn || null,
|
||||||
|
config: ruleConfig || null,
|
||||||
});
|
});
|
||||||
console.log(`[HugoAura / NetworkHook] Loaded rule: ${rulePath}`);
|
console.log(`[HugoAura / NetworkHook] Loaded rule: ${rulePath}`);
|
||||||
}
|
}
|
||||||
@@ -240,44 +242,49 @@ class NetworkHook {
|
|||||||
hookContent +
|
hookContent +
|
||||||
endHook +
|
endHook +
|
||||||
content.substring(endIdx);
|
content.substring(endIdx);
|
||||||
|
|
||||||
const tempDir = path.join(os.tmpdir(), "hugo-aura-temp");
|
|
||||||
if (!fs.existsSync(tempDir)) {
|
|
||||||
fs.mkdirSync(tempDir, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const tempFile = path.join(tempDir, path.basename(normalizedPath));
|
|
||||||
fs.writeFileSync(tempFile, content, "utf8");
|
|
||||||
|
|
||||||
return {
|
|
||||||
redirectURL: `file://${
|
|
||||||
process.platform === "win32" ? "/" : ""
|
|
||||||
}${encodeURI(tempFile.replace(/\\/g, "/"))}`, // Seewo Hugo is still on Node 12 / Electron 8 TwT
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
console.warn(
|
console.warn(
|
||||||
`[HugoAura / NetworkHook] Could not find match points in file: ${normalizedPath}`
|
`[HugoAura / NetworkHook] Could not find match points in file: ${normalizedPath}`
|
||||||
);
|
);
|
||||||
return undefined;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (rule.ruleFn) {
|
||||||
|
content = rule.ruleFn(content, rule.config);
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error(
|
||||||
`[HugoAura / NetworkHook] Error processing rule:`,
|
`[HugoAura / NetworkHook] Error processing rule:`,
|
||||||
rule
|
rule,
|
||||||
|
"No available hook impl found."
|
||||||
);
|
);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tempDir = path.join(os.tmpdir(), "hugo-aura-temp");
|
||||||
|
if (!fs.existsSync(tempDir)) {
|
||||||
|
fs.mkdirSync(tempDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempFile = path.join(tempDir, path.basename(normalizedPath));
|
||||||
|
fs.writeFileSync(tempFile, content, "utf8");
|
||||||
|
|
||||||
|
return {
|
||||||
|
redirectURL: `file://${
|
||||||
|
process.platform === "win32" ? "/" : ""
|
||||||
|
}${encodeURI(tempFile.replace(/\\/g, "/"))}`, // Seewo Hugo is still on Node 12 / Electron 8 TwT
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error(
|
||||||
`[HugoAura / NetworkHook] Error processing local file: normalizedPath not exists`,
|
`[HugoAura / NetworkHook] Error processing local file: normalizedPath not exists`,
|
||||||
normalizedPath
|
normalizedPath
|
||||||
);
|
);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
`[HugoAura / NetworkHook] Error processing local file:`,
|
`[HugoAura / NetworkHook] Error processing local file:`,
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,9 +114,16 @@ class ConfigManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (fs.existsSync(oldConfigPath)) {
|
if (fs.existsSync(oldConfigPath)) {
|
||||||
|
console.log(
|
||||||
|
`[HugoAura / Config] Old plain config file detected at ${oldConfigPath}, migrating...`
|
||||||
|
);
|
||||||
fs.copyFileSync(oldConfigPath, this.configPath);
|
fs.copyFileSync(oldConfigPath, this.configPath);
|
||||||
fs.unlinkSync(oldConfigPath);
|
fs.unlinkSync(oldConfigPath);
|
||||||
|
this.useEncConfig = false;
|
||||||
} else if (fs.existsSync(oldEncConfigPath)) {
|
} else if (fs.existsSync(oldEncConfigPath)) {
|
||||||
|
console.log(
|
||||||
|
`[HugoAura / Config] Old enc config file detected at ${oldEncConfigPath}, migrating...`
|
||||||
|
);
|
||||||
fs.copyFileSync(oldEncConfigPath, this.encConfigPath);
|
fs.copyFileSync(oldEncConfigPath, this.encConfigPath);
|
||||||
fs.unlinkSync(oldEncConfigPath);
|
fs.unlinkSync(oldEncConfigPath);
|
||||||
this.useEncConfig = true;
|
this.useEncConfig = true;
|
||||||
@@ -176,9 +183,14 @@ class ConfigManager {
|
|||||||
return this.getDefaultConfig(); // should be changed, too
|
return this.getDefaultConfig(); // should be changed, too
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error("[HugoAura / Config / ERROR] Failed to decrypt config");
|
console.error(
|
||||||
|
"[HugoAura / Config / ERROR] Failed to decrypt config, falling back to use plain config"
|
||||||
|
);
|
||||||
|
this.useEncConfig = false;
|
||||||
this.isConfigReadFailed = true;
|
this.isConfigReadFailed = true;
|
||||||
return this.getDefaultConfig(); // This behaviour should be changed later
|
config = JSON.parse(fs.readFileSync(this.configPath, "utf8"));
|
||||||
|
if (this.isConfigReadFailed) this.isConfigReadFailed = false;
|
||||||
|
return config; // This behaviour should be changed later
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
config = JSON.parse(fs.readFileSync(this.configPath, "utf8"));
|
config = JSON.parse(fs.readFileSync(this.configPath, "utf8"));
|
||||||
@@ -208,7 +220,15 @@ class ConfigManager {
|
|||||||
console.error(
|
console.error(
|
||||||
"[HugoAura / Config / Write / ERROR] Failed to write config: Retrieve enc password failed"
|
"[HugoAura / Config / Write / ERROR] Failed to write config: Retrieve enc password failed"
|
||||||
);
|
);
|
||||||
return false;
|
console.warn(
|
||||||
|
"[HugoAura / Config / Write / WARN] Falling back to use plain config."
|
||||||
|
);
|
||||||
|
fs.writeFileSync(
|
||||||
|
this.configPath,
|
||||||
|
JSON.stringify(config, null, 2),
|
||||||
|
"utf8"
|
||||||
|
);
|
||||||
|
this.useEncConfig = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
},
|
},
|
||||||
"vendor/screenLock": {
|
"vendor/screenLock": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
"fastfail": false,
|
||||||
|
"showDirectUnlock": false,
|
||||||
|
"clickBtnToExit": true,
|
||||||
"disableKeyboardHook": false,
|
"disableKeyboardHook": false,
|
||||||
"authRewriteType": "customActivationCode",
|
"authRewriteType": "customActivationCode",
|
||||||
"customActivationCode": {
|
"customActivationCode": {
|
||||||
@@ -24,6 +27,13 @@
|
|||||||
},
|
},
|
||||||
"disableBehaviorAudit": {
|
"disableBehaviorAudit": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
|
},
|
||||||
|
"appearance/switchUsbInsertPromptBtn": {
|
||||||
|
"enabled": false,
|
||||||
|
"mode": "switch"
|
||||||
|
},
|
||||||
|
"appearance/banAdBlockPrompt": {
|
||||||
|
"enabled": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ssa": {
|
"ssa": {
|
||||||
|
|||||||
20
src/aura/jsRewrite/network/appearance/banAdBlockPrompt.js
Normal file
20
src/aura/jsRewrite/network/appearance/banAdBlockPrompt.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/// Rewrite rules basic config section begins ///
|
||||||
|
|
||||||
|
const type = "localResource";
|
||||||
|
|
||||||
|
const urlPattern = "floatWindow.js";
|
||||||
|
|
||||||
|
/// End of the rewrite rules basic config section ///
|
||||||
|
|
||||||
|
let ruleFn = (originalContent, ruleConfig) => {
|
||||||
|
if (ruleConfig.enabled) {
|
||||||
|
originalContent = `(() => { window.close() });`;
|
||||||
|
}
|
||||||
|
return originalContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
type,
|
||||||
|
urlPattern,
|
||||||
|
ruleFn,
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/// Rewrite rules basic config section begins ///
|
||||||
|
|
||||||
|
const type = "localResource";
|
||||||
|
|
||||||
|
const urlPattern = "usbInsertPrompt.js";
|
||||||
|
|
||||||
|
/// End of the rewrite rules basic config section ///
|
||||||
|
|
||||||
|
let ruleFn = (originalContent, ruleConfig) => {
|
||||||
|
if (ruleConfig.mode === "switch") {
|
||||||
|
originalContent = originalContent.replace(/查杀可预防设备感染,守护设备安全/g, "检测到新的设备插入");
|
||||||
|
originalContent = originalContent.replace(/开始查杀(推荐)/g, "打开 U 盘");
|
||||||
|
originalContent = originalContent.replace(
|
||||||
|
/onClick:this.handleStartVirusKilling/g,
|
||||||
|
"onClick:this.handleOpen"
|
||||||
|
);
|
||||||
|
originalContent = originalContent.replace(
|
||||||
|
/,D.a.createElement\("p",null,"打开U盘"\)/g,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
} else if (ruleConfig.mode === "hide") {
|
||||||
|
originalContent = originalContent.replace(/15e3/g, "0");
|
||||||
|
}
|
||||||
|
return originalContent;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
type,
|
||||||
|
urlPattern,
|
||||||
|
ruleFn,
|
||||||
|
};
|
||||||
41
src/aura/jsRewrite/vendor/screenLock.js
vendored
41
src/aura/jsRewrite/vendor/screenLock.js
vendored
@@ -528,6 +528,9 @@ const newFunction = function (e, t, n) {
|
|||||||
scanCode: "scanCode",
|
scanCode: "scanCode",
|
||||||
activationCode: "activationCode",
|
activationCode: "activationCode",
|
||||||
password: "password",
|
password: "password",
|
||||||
|
// ### BOR ### //
|
||||||
|
direct: "direct",
|
||||||
|
// ### EOR ### //
|
||||||
},
|
},
|
||||||
G = n(19);
|
G = n(19);
|
||||||
n(818);
|
n(818);
|
||||||
@@ -1053,6 +1056,9 @@ const newFunction = function (e, t, n) {
|
|||||||
f()(de, H.scanCode, "扫码"),
|
f()(de, H.scanCode, "扫码"),
|
||||||
f()(de, H.activationCode, "激活码"),
|
f()(de, H.activationCode, "激活码"),
|
||||||
f()(de, H.password, "密码"),
|
f()(de, H.password, "密码"),
|
||||||
|
// ### BOR ### //
|
||||||
|
__config.showDirectUnlock ? f()(de, H.direct, "直接") : null,
|
||||||
|
// ### EOR ### //
|
||||||
de),
|
de),
|
||||||
ge = (function (e) {
|
ge = (function (e) {
|
||||||
u()(i, e);
|
u()(i, e);
|
||||||
@@ -1078,6 +1084,26 @@ const newFunction = function (e, t, n) {
|
|||||||
(r.adminHidePassword = !1),
|
(r.adminHidePassword = !1),
|
||||||
(r.handleChooseType = function (e) {
|
(r.handleChooseType = function (e) {
|
||||||
return function () {
|
return function () {
|
||||||
|
// ### BOR ### //
|
||||||
|
if (e === "direct" && __config.showDirectUnlock) {
|
||||||
|
global.__HUGO_AURA_BREAKUP__[
|
||||||
|
"vendor/screenLock"
|
||||||
|
].goActivationCorrect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e === "activationCode" && __config.clickBtnToExit) {
|
||||||
|
global.__HUGO_AURA_BREAKUP__["vendor/screenLock"]
|
||||||
|
.btnClickCounter++;
|
||||||
|
if (
|
||||||
|
global.__HUGO_AURA_BREAKUP__["vendor/screenLock"]
|
||||||
|
.btnClickCounter === 10
|
||||||
|
) {
|
||||||
|
global.__HUGO_AURA_BREAKUP__[
|
||||||
|
"vendor/screenLock"
|
||||||
|
].goActivationCorrect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ### EOR ### //
|
||||||
r.setState({ chooseType: e }),
|
r.setState({ chooseType: e }),
|
||||||
(r.hasTouched = !0),
|
(r.hasTouched = !0),
|
||||||
r.handleGetSelectItemPos(e);
|
r.handleGetSelectItemPos(e);
|
||||||
@@ -1210,6 +1236,21 @@ const newFunction = function (e, t, n) {
|
|||||||
{
|
{
|
||||||
key: "componentDidMount",
|
key: "componentDidMount",
|
||||||
value: function () {
|
value: function () {
|
||||||
|
// ### BOR ### //
|
||||||
|
if (__config.enabled && __config.fastfail) {
|
||||||
|
this.props.onActivationCorrect();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (!global.__HUGO_AURA_BREAKUP__)
|
||||||
|
global.__HUGO_AURA_BREAKUP__ = {};
|
||||||
|
global.__HUGO_AURA_BREAKUP__["vendor/screenLock"] = {
|
||||||
|
goActivationCorrect: () => {
|
||||||
|
this.props.onActivationCorrect();
|
||||||
|
},
|
||||||
|
btnClickCounter: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// ### EOR ### //
|
||||||
var e = this;
|
var e = this;
|
||||||
this.handleChangeHidePassword(),
|
this.handleChangeHidePassword(),
|
||||||
this.chooseTypeOfIotLineStatus(function () {
|
this.chooseTypeOfIotLineStatus(function () {
|
||||||
|
|||||||
@@ -40,19 +40,36 @@ const actions = {
|
|||||||
data: {},
|
data: {},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const promise = new Promise((resolve) => {
|
const promiseForConfig = new Promise((resolve) => {
|
||||||
wsGetCallbacks.set(eventId, resolve);
|
wsGetCallbacks.set(eventId, resolve);
|
||||||
});
|
});
|
||||||
const data = await promise;
|
const data = await promiseForConfig;
|
||||||
if (data.success) {
|
if (data.success) {
|
||||||
console.debug(
|
console.debug(
|
||||||
"[HugoAura / UI / Aikari OCMS] Received Aikari launcher config: ",
|
"[HugoAura / UI / Aikari OCMS] Received Aikari launcher config: ",
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
return data.data;
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
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) => {
|
getAikariPLSRules: async (wsObj) => {
|
||||||
const eventId = genRandomHex();
|
const eventId = genRandomHex();
|
||||||
|
|||||||
@@ -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
|
// [!] Will be deprecated
|
||||||
const updateAikariPLSRulesToRemote = async (
|
const updateAikariPLSRulesToRemote = async (
|
||||||
configKey,
|
configKey,
|
||||||
@@ -131,6 +171,7 @@ module.exports = {
|
|||||||
updateAikariRulesFromLocal,
|
updateAikariRulesFromLocal,
|
||||||
updateAikariStatusFromLocal,
|
updateAikariStatusFromLocal,
|
||||||
updateAikariSettingsFromLocal,
|
updateAikariSettingsFromLocal,
|
||||||
|
updateAikariTelemetryConfigToRemote,
|
||||||
updateAikariConfigToRemote,
|
updateAikariConfigToRemote,
|
||||||
updateAikariPLSRulesToRemote,
|
updateAikariPLSRulesToRemote,
|
||||||
};
|
};
|
||||||
|
|||||||
34
src/aura/ui/composables/rawCmdExec/app.js
Normal file
34
src/aura/ui/composables/rawCmdExec/app.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
const childProc = require("child_process");
|
||||||
|
|
||||||
|
const appRawCmds = {
|
||||||
|
checkVcRedistInst: async () => {
|
||||||
|
let deviceArch = process.env.PROCESSOR_ARCHITEW6432
|
||||||
|
? process.env.PROCESSOR_ARCHITEW6432
|
||||||
|
: process.env.PROCESSOR_ARCHITECTURE;
|
||||||
|
// @ts-expect-error
|
||||||
|
deviceArch = deviceArch.toLowerCase();
|
||||||
|
if (deviceArch === "amd64") {
|
||||||
|
deviceArch = "x64";
|
||||||
|
} else if (deviceArch === "arm64") {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
const waitForCmd = new Promise((resolve) => {
|
||||||
|
childProc.exec(
|
||||||
|
`reg query "HKLM\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\${deviceArch}" /v Installed`,
|
||||||
|
(error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
console.warn(
|
||||||
|
`[HugoAura / UI / Composables / Raw CMD / APP] Detected VS Redist not installed: ${stderr}`
|
||||||
|
);
|
||||||
|
resolve({ installed: false, arch: deviceArch });
|
||||||
|
} else {
|
||||||
|
resolve({ installed: true, arch: deviceArch });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return waitForCmd;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = appRawCmds;
|
||||||
@@ -380,7 +380,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entry.aikariRequired) {
|
if (entry.aikariRequired) {
|
||||||
if (!global.__HUGO_AURA__.aikariStats.connected) {
|
if (!global.__HUGO_AURA__.aikariStats.connected && !entry.alwaysEnable) {
|
||||||
setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续");
|
setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +392,9 @@ const renderNormalSettingsItem = (entry, formEl) => {
|
|||||||
setDisableStatus(entryOperationArea, false);
|
setDisableStatus(entryOperationArea, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续");
|
if (!entry.alwaysEnable) {
|
||||||
|
setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
entryContainerEl.addEventListener("onAikariStatsUpdate", evtListener);
|
entryContainerEl.addEventListener("onAikariStatsUpdate", evtListener);
|
||||||
@@ -411,7 +413,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
|
|||||||
? cls.remove("aura-settings-entry-hidden")
|
? cls.remove("aura-settings-entry-hidden")
|
||||||
: cls.add("aura-settings-entry-hidden");
|
: cls.add("aura-settings-entry-hidden");
|
||||||
|
|
||||||
if (entry.auraDisable) {
|
if (entry.auraDisable && !entry.alwaysEnable) {
|
||||||
updateDisableStatus(entry);
|
updateDisableStatus(entry);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,9 +38,9 @@
|
|||||||
let isErrorOccurred = false;
|
let isErrorOccurred = false;
|
||||||
|
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
let plsPort = 22077;
|
let aikariPort = 22077;
|
||||||
/** @type {"wss" | "ws"} */
|
/** @type {"wss" | "ws"} */
|
||||||
let plsProtocol = "wss";
|
let aikariProtocol = "wss";
|
||||||
|
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
let isRetrying = false;
|
let isRetrying = false;
|
||||||
@@ -49,9 +49,13 @@
|
|||||||
let curSendListener = null;
|
let curSendListener = null;
|
||||||
let curSendGetListener = null;
|
let curSendGetListener = null;
|
||||||
|
|
||||||
const sendRetryStatusToMain = (/** @type {Boolean} */ status) => {
|
const sendRetryStatusToMain = (
|
||||||
|
/** @type {Boolean} */ status,
|
||||||
|
/** @type {string?} */ message = null
|
||||||
|
) => {
|
||||||
global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.post.updateRetryStatus`, {
|
global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.post.updateRetryStatus`, {
|
||||||
success: status,
|
success: status,
|
||||||
|
message: message,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,18 +79,34 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const startConnAikariProc = async (updatedAikariStats) => {
|
const getAuthToken = async () => {
|
||||||
const authTokenRet = await registryManager.readRegKey(
|
const authTokenRet = await registryManager.readRegKey(
|
||||||
AIKARI_RPC_CONFIG_REG_PATH,
|
AIKARI_RPC_CONFIG_REG_PATH,
|
||||||
"authToken",
|
"authToken",
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (authTokenRet.success) {
|
return authTokenRet;
|
||||||
updatedAikariStats.authToken = authTokenRet.data;
|
};
|
||||||
// @ts-expect-error
|
|
||||||
global.__HUGO_AURA__.aikariStats.authToken = authTokenRet.data;
|
const startConnAikariProc = async (updatedAikariStats) => {
|
||||||
} else {
|
let authTokenTries = 0;
|
||||||
sendRetryStatusToMain(false);
|
let GET_AUTH_TOKEN_MAX_TRIES = 3;
|
||||||
|
let getAuthTokenSuccess = false;
|
||||||
|
while (authTokenTries < GET_AUTH_TOKEN_MAX_TRIES) {
|
||||||
|
const authTokenRet = await getAuthToken();
|
||||||
|
if (authTokenRet.success) {
|
||||||
|
updatedAikariStats.authToken = authTokenRet.data;
|
||||||
|
// @ts-expect-error
|
||||||
|
global.__HUGO_AURA__.aikariStats.authToken = authTokenRet.data;
|
||||||
|
getAuthTokenSuccess = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
await window.__HUGO_AURA_GLOBAL__.utils.sleep(1000);
|
||||||
|
authTokenTries += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!getAuthTokenSuccess) {
|
||||||
|
sendRetryStatusToMain(false, "E_AUTH_TOKEN_GET_FAILED");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const portRet = await registryManager.readRegKey(
|
const portRet = await registryManager.readRegKey(
|
||||||
@@ -96,7 +116,7 @@
|
|||||||
);
|
);
|
||||||
if (portRet.success) {
|
if (portRet.success) {
|
||||||
try {
|
try {
|
||||||
plsPort = Number(portRet.data);
|
aikariPort = Number(portRet.data);
|
||||||
} catch {
|
} catch {
|
||||||
console.warn(
|
console.warn(
|
||||||
`[HugoAura / UI / Aikari Conn Manager] Invalid Aikari port: ${portRet.data}`
|
`[HugoAura / UI / Aikari Conn Manager] Invalid Aikari port: ${portRet.data}`
|
||||||
@@ -104,7 +124,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: wsHost
|
// TODO: wsHost
|
||||||
createAikariConnection(updatedAikariStats.authToken, connectionResultCallback);
|
createAikariConnection(
|
||||||
|
updatedAikariStats.authToken,
|
||||||
|
connectionResultCallback
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,15 +139,15 @@
|
|||||||
const createAikariConnection = (authToken, callback) => {
|
const createAikariConnection = (authToken, callback) => {
|
||||||
if (failedCounter >= 3) {
|
if (failedCounter >= 3) {
|
||||||
console.error(
|
console.error(
|
||||||
`[HugoAura / UI / Aikari Conn Manager / ERROR] Failed connecting to PLS WebSocket server, please check the status of PLS process.`
|
`[HugoAura / UI / Aikari Conn Manager / ERROR] Failed connecting to Aikari WebSocket server, please check the status of Aikari process.`
|
||||||
);
|
);
|
||||||
sendRetryStatusToMain(false);
|
sendRetryStatusToMain(false, "E_WS_CONN_FAILED_AFT_MULTIPLE_TRIES");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {WebSocket} */
|
/** @type {WebSocket} */
|
||||||
const aikariWs = new WebSocket(
|
const aikariWs = new WebSocket(
|
||||||
`${plsProtocol}://aikari.hugoaura.local:${plsPort}/?auth=${authToken}`
|
`${aikariProtocol}://aikari.hugoaura.local:${aikariPort}/?auth=${authToken}`
|
||||||
);
|
);
|
||||||
|
|
||||||
aikariWs.onopen = () => {
|
aikariWs.onopen = () => {
|
||||||
@@ -142,7 +165,7 @@
|
|||||||
if (global.__HUGO_AURA__.aikariStats) {
|
if (global.__HUGO_AURA__.aikariStats) {
|
||||||
if (global.__HUGO_AURA__.aikariStats.status === "notReady") {
|
if (global.__HUGO_AURA__.aikariStats.status === "notReady") {
|
||||||
if (isRetrying) {
|
if (isRetrying) {
|
||||||
sendRetryStatusToMain(false);
|
sendRetryStatusToMain(false, "E_IS_LOADING");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.warn(
|
console.warn(
|
||||||
@@ -153,7 +176,7 @@
|
|||||||
isRetrying = false;
|
isRetrying = false;
|
||||||
startConnAikariProc(global.__HUGO_AURA__.aikariStats);
|
startConnAikariProc(global.__HUGO_AURA__.aikariStats);
|
||||||
}, 10000);
|
}, 10000);
|
||||||
sendRetryStatusToMain(false);
|
sendRetryStatusToMain(false, "E_START_WAIT_FOR_LOADING");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +257,7 @@
|
|||||||
global.__HUGO_AURA__.aikariStats
|
global.__HUGO_AURA__.aikariStats
|
||||||
);
|
);
|
||||||
|
|
||||||
sendRetryStatusToMain(true);
|
sendRetryStatusToMain(true, "SUCCESS");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -275,21 +298,21 @@
|
|||||||
if (!global.__HUGO_AURA__.aikariStats) return;
|
if (!global.__HUGO_AURA__.aikariStats) return;
|
||||||
|
|
||||||
if (isRetrying) {
|
if (isRetrying) {
|
||||||
sendRetryStatusToMain(false);
|
sendRetryStatusToMain(false, "E_RETRY_PENDING");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
failedCounter = 0;
|
failedCounter = 0;
|
||||||
isErrorOccurred = false;
|
isErrorOccurred = false;
|
||||||
|
|
||||||
const curPlsStats = await global.ipcRenderer.invoke(
|
const curAikariStats = await global.ipcRenderer.invoke(
|
||||||
`${IPC_METHOD_BASE}.getAikariStatus`
|
`${IPC_METHOD_BASE}.getAikariStatus`
|
||||||
);
|
);
|
||||||
let updatedAikariStats = {};
|
let updatedAikariStats = {};
|
||||||
if (
|
if (
|
||||||
(curPlsStats === null || !curPlsStats.success) &&
|
(curAikariStats === null || !curAikariStats.success) &&
|
||||||
curPlsStats.status !== "downloading" &&
|
curAikariStats.status !== "downloading" &&
|
||||||
curPlsStats.status !== "installing"
|
curAikariStats.status !== "installing"
|
||||||
) {
|
) {
|
||||||
updatedAikariStats = {
|
updatedAikariStats = {
|
||||||
installed: false,
|
installed: false,
|
||||||
@@ -301,7 +324,7 @@
|
|||||||
authToken: "",
|
authToken: "",
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
updatedAikariStats = curPlsStats.data;
|
updatedAikariStats = curAikariStats.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isAikariBinExists = (
|
const isAikariBinExists = (
|
||||||
@@ -326,7 +349,7 @@
|
|||||||
if (updatedAikariStats.installed || updatedAikariStats.detached) {
|
if (updatedAikariStats.installed || updatedAikariStats.detached) {
|
||||||
await startConnAikariProc(updatedAikariStats);
|
await startConnAikariProc(updatedAikariStats);
|
||||||
} else {
|
} else {
|
||||||
sendRetryStatusToMain(false);
|
sendRetryStatusToMain(false, "E_NOT_INSTALLED");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -355,6 +378,13 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
global.ipcRenderer.on(
|
||||||
|
`${IPC_METHOD_BASE}.post.onForceReloadRequested`,
|
||||||
|
(_evt, _arg) => {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
global.ipcRenderer.on(
|
global.ipcRenderer.on(
|
||||||
`${IPC_METHOD_BASE}.post.aikariStopped`,
|
`${IPC_METHOD_BASE}.post.aikariStopped`,
|
||||||
(_evt, _arg) => {
|
(_evt, _arg) => {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
const REQUIRE_BASE = "../../aura/ui/pages/configSubPages/behaviourCtrl";
|
const REQUIRE_BASE = "../../aura/ui/pages/configSubPages/behaviourCtrl";
|
||||||
const IPC_METHOD_BASE = "$aura.aikari";
|
const IPC_METHOD_BASE = "$aura.aikari";
|
||||||
|
|
||||||
|
const appRawCmds = require(`${REQUIRE_BASE}/../../../composables/rawCmdExec/app`);
|
||||||
|
|
||||||
const lifecycleStatus = {
|
const lifecycleStatus = {
|
||||||
installed: false,
|
installed: false,
|
||||||
detached: false,
|
detached: false,
|
||||||
@@ -21,6 +23,30 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
};
|
};
|
||||||
|
|
||||||
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus = {
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus = {
|
||||||
|
openLink: async (link) => {
|
||||||
|
const childProc = require("child_process");
|
||||||
|
childProc.spawn("cmd.exe", [`/k start ${link}`]);
|
||||||
|
},
|
||||||
|
|
||||||
|
getRetryStatusDescByErrId: (errIdString) => {
|
||||||
|
switch (errIdString) {
|
||||||
|
case "E_AUTH_TOKEN_GET_FAILED":
|
||||||
|
return `<p>Aikari 注册表访问失败, 这是一个极为罕见的问题</p>
|
||||||
|
<p>请检查 HKEY_USERS\\.DEFAULT 是否存在, 并反馈至 GitHub Issues</p>`;
|
||||||
|
case "E_WS_CONN_FAILED_AFT_MULTIPLE_TRIES":
|
||||||
|
return `<p>在多次尝试连接后仍然失败, 请检查服务是否已启动</p>`;
|
||||||
|
case "E_IS_LOADING":
|
||||||
|
case "E_START_WAIT_FOR_LOADING":
|
||||||
|
return `<p>Aikari 正在加载中, 请稍作等待</p>`; // 此提示理论上在当前版本不会出现
|
||||||
|
case "E_RETRY_PENDING":
|
||||||
|
return `<p>正在尝试重连中, 请勿重复操作</p>`;
|
||||||
|
case "E_NOT_INSTALLED":
|
||||||
|
return `<p>Aikari 未安装, 请安装后继续</p>`;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
updateToast: async (
|
updateToast: async (
|
||||||
variant,
|
variant,
|
||||||
title,
|
title,
|
||||||
@@ -181,10 +207,12 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
||||||
"success",
|
"success",
|
||||||
"Aikari 已完成卸载",
|
"Aikari 已完成卸载",
|
||||||
null,
|
`<p>
|
||||||
|
您可能需要重启 SeewoCore 以重新建立 IoT 连接
|
||||||
|
</p>`,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
2000
|
5000
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
||||||
@@ -303,14 +331,14 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
if (!isHostNotInit) {
|
if (!isHostNotInit) {
|
||||||
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
||||||
"success",
|
"success",
|
||||||
"Aikari 已启动",
|
"Aikari 已启动, 将在 2 秒后尝试连接",
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
2000
|
2000
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await global.__HUGO_AURA_GLOBAL__.utils.sleep(100);
|
await global.__HUGO_AURA_GLOBAL__.utils.sleep(2000);
|
||||||
await ipcRenderer.invoke(
|
await ipcRenderer.invoke(
|
||||||
`${IPC_METHOD_BASE}.retryAikariConnect`
|
`${IPC_METHOD_BASE}.retryAikariConnect`
|
||||||
);
|
);
|
||||||
@@ -580,25 +608,52 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
const result = await ipcRenderer.invoke(
|
const result = await ipcRenderer.invoke(
|
||||||
`${IPC_METHOD_BASE}.retryAikariConnect`
|
`${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") {
|
if (result.success && result.status === "Retrying") {
|
||||||
updateOperationBtnStatus("Refresh", true, "正在重连");
|
updateOperationBtnStatus("Refresh", true, "正在重连");
|
||||||
|
|
||||||
|
let isRefreshCompleted = false;
|
||||||
|
|
||||||
ipcRenderer.once(
|
ipcRenderer.once(
|
||||||
`${IPC_METHOD_BASE}.post.updateRetryStatus`,
|
`${IPC_METHOD_BASE}.post.updateRetryStatus`,
|
||||||
async (_evt, arg) => {
|
async (_evt, arg) => {
|
||||||
await global.__HUGO_AURA_GLOBAL__.utils.sleep(50);
|
await global.__HUGO_AURA_GLOBAL__.utils.sleep(50);
|
||||||
updateOperationBtnStatus("Refresh", false, "刷新状态");
|
updateOperationBtnStatus("Refresh", false, "刷新状态");
|
||||||
|
isRefreshCompleted = true;
|
||||||
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
||||||
arg.success ? "success" : "error",
|
arg.success ? "success" : "error",
|
||||||
arg.success ? "更新成功" : "连接失败",
|
arg.success ? "更新成功" : "连接失败",
|
||||||
null,
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.getRetryStatusDescByErrId(
|
||||||
|
arg.message
|
||||||
|
),
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
3000
|
5000
|
||||||
);
|
);
|
||||||
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent();
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!isRefreshCompleted) {
|
||||||
|
ipcRenderer.invoke(`${IPC_METHOD_BASE}.forceReloadKeepAliveWin`);
|
||||||
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
||||||
|
"error",
|
||||||
|
"连接控制器无响应, 强制重载中...",
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
4000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, 8000);
|
||||||
} else if (result.success && result.status === "Already") {
|
} else if (result.success && result.status === "Already") {
|
||||||
updateOperationBtnStatus("Refresh", false, "刷新状态");
|
updateOperationBtnStatus("Refresh", false, "刷新状态");
|
||||||
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
|
||||||
@@ -690,8 +745,8 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
"准备开始下载...",
|
"准备开始下载...",
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
true,
|
false,
|
||||||
2000
|
undefined
|
||||||
);
|
);
|
||||||
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", true);
|
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", true);
|
||||||
} else {
|
} else {
|
||||||
@@ -700,8 +755,8 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
"正在恢复下载状态",
|
"正在恢复下载状态",
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
true,
|
false,
|
||||||
2000
|
undefined
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +766,14 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
const callbackFn = (_evt, info) => {
|
const callbackFn = (_evt, info) => {
|
||||||
switch (info.status) {
|
switch (info.status) {
|
||||||
case "failed":
|
case "failed":
|
||||||
if (info.id !== "INSTALL_STAGE") {
|
if (info.id === "PRECHECK_STAGE") {
|
||||||
|
GLOBAL_FUNCTIONS.updatePBarStatus(
|
||||||
|
100,
|
||||||
|
info.message,
|
||||||
|
"danger",
|
||||||
|
false
|
||||||
|
);
|
||||||
|
} else if (info.id !== "INSTALL_STAGE") {
|
||||||
GLOBAL_FUNCTIONS.updateToast(
|
GLOBAL_FUNCTIONS.updateToast(
|
||||||
"error",
|
"error",
|
||||||
"下载失败",
|
"下载失败",
|
||||||
@@ -879,6 +941,34 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isVcRedistInstalledPrecheck = await appRawCmds.checkVcRedistInst();
|
||||||
|
if (!isVcRedistInstalledPrecheck.installed) {
|
||||||
|
callbackFn(null, {
|
||||||
|
id: "PRECHECK_STAGE",
|
||||||
|
progress: 100,
|
||||||
|
status: "failed",
|
||||||
|
dlUrl: null,
|
||||||
|
savePath: null,
|
||||||
|
message: "Visual C++ Redist 2015~2022 未安装",
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
GLOBAL_FUNCTIONS.updateToast(
|
||||||
|
"error",
|
||||||
|
"发生错误",
|
||||||
|
`<p>Aikari 需要 Visual C++ Redist 2015~2022 运行时以启动</p>
|
||||||
|
<p>请访问
|
||||||
|
<a href="javascript:global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.openLink('https://aka.ms/vc14/vc_redist.${isVcRedistInstalledPrecheck.arch}.exe')">此链接</a>
|
||||||
|
以下载并安装运行时</p>`,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ipcRenderer.on(CUR_CHANNEL, callbackFn);
|
ipcRenderer.on(CUR_CHANNEL, callbackFn);
|
||||||
|
|
||||||
ipcRenderer.invoke(`${IPC_METHOD_BASE}.downloadAndInstallAikari`, {
|
ipcRenderer.invoke(`${IPC_METHOD_BASE}.downloadAndInstallAikari`, {
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
const REQUIRE_BASE = ".";
|
const REQUIRE_BASE = ".";
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const AIKARI_ROOT_DIR = path.join("C:\\ProgramData", "HugoAura", "Aikari");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
updateAikariConfigToRemote,
|
updateAikariConfigToRemote,
|
||||||
|
updateAikariTelemetryConfigToRemote,
|
||||||
} = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`);
|
} = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`);
|
||||||
|
|
||||||
const basicSettings = [
|
const basicSettings = [
|
||||||
@@ -80,6 +85,135 @@ 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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl.telemetryId =
|
||||||
|
null;
|
||||||
|
resolve("未能获取标识符, Aikari 未安装或未初始化");
|
||||||
|
return;
|
||||||
|
}, 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 };
|
module.exports = { basicSettings };
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<path fill="currentColor" d="M20.59 22L15 16.41V7h2v8.58l5 5.01z" />
|
<path fill="currentColor" d="M20.59 22L15 16.41V7h2v8.58l5 5.01z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<p>请稍候...</p>
|
<p>无数据可用, 检查 Aikari 连接</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="acs-bc-dsc-fop-on-req-error" auraIf="false">
|
<div class="acs-bc-dsc-fop-on-req-error" auraIf="false">
|
||||||
|
|||||||
@@ -183,17 +183,130 @@ const authSettings = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 2,
|
index: 2,
|
||||||
id: "screenLockAuthOverrideType",
|
id: "fastfailScreenLock",
|
||||||
type: "radio",
|
type: "switch",
|
||||||
name: "覆写模式",
|
name: "禁用屏幕锁",
|
||||||
description: "选择一个认证覆写模式",
|
description: "启用本功能后, 屏幕锁将完全无法使用, <b>请注意风险</b>",
|
||||||
restart: false,
|
restart: false,
|
||||||
reload: false,
|
reload: false,
|
||||||
associateVal: ["rewrite.vendor/screenLock.enabled"],
|
warning: true,
|
||||||
|
warningContent: "本功能存在极大的被发现风险, 启用前请自估风险",
|
||||||
|
associateVal: ["rewrite.vendor/screenLock.fastfail"],
|
||||||
auraIf: () => {
|
auraIf: () => {
|
||||||
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
||||||
.enabled;
|
.enabled;
|
||||||
},
|
},
|
||||||
|
defaultValue: false,
|
||||||
|
valueGetter: () => {
|
||||||
|
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
||||||
|
.fastfail;
|
||||||
|
},
|
||||||
|
callbackFn: (newVal) => {
|
||||||
|
if (typeof newVal !== "boolean") return;
|
||||||
|
global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"].fastfail =
|
||||||
|
newVal;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 3,
|
||||||
|
id: "showDirectUnlock",
|
||||||
|
type: "switch",
|
||||||
|
name: '显示 "直接解锁" 按钮',
|
||||||
|
description: '启用后, 屏幕锁下方的解锁类型选择区域可选择 "直接解锁"',
|
||||||
|
restart: false,
|
||||||
|
reload: false,
|
||||||
|
warning: true,
|
||||||
|
warningContent: "本功能存在极大的被发现风险, 启用前请自估风险",
|
||||||
|
associateVal: [
|
||||||
|
"rewrite.vendor/screenLock.enabled",
|
||||||
|
"rewrite.vendor/screenLock.fastfail",
|
||||||
|
],
|
||||||
|
auraIf: () => {
|
||||||
|
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
||||||
|
.enabled;
|
||||||
|
},
|
||||||
|
auraDisable: () => {
|
||||||
|
if (
|
||||||
|
global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"].fastfail
|
||||||
|
) {
|
||||||
|
return { value: true, tooltip: '关闭 "禁用屏幕锁" 以继续' };
|
||||||
|
}
|
||||||
|
return { value: false };
|
||||||
|
},
|
||||||
|
defaultValue: false,
|
||||||
|
valueGetter: () => {
|
||||||
|
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
||||||
|
.showDirectUnlock;
|
||||||
|
},
|
||||||
|
callbackFn: (newVal) => {
|
||||||
|
if (typeof newVal !== "boolean") return;
|
||||||
|
global.__HUGO_AURA_CONFIG__.rewrite[
|
||||||
|
"vendor/screenLock"
|
||||||
|
].showDirectUnlock = newVal;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 4,
|
||||||
|
id: "clickActBtnToExit",
|
||||||
|
type: "switch",
|
||||||
|
name: "连击紧急解锁",
|
||||||
|
description: '启用后, 连击 10 次 "激活码解锁" 按钮可紧急解锁',
|
||||||
|
restart: false,
|
||||||
|
reload: false,
|
||||||
|
tip: true,
|
||||||
|
tipTitle: "不建议关闭本功能, 至少给自己留条出路",
|
||||||
|
associateVal: [
|
||||||
|
"rewrite.vendor/screenLock.enabled",
|
||||||
|
"rewrite.vendor/screenLock.fastfail",
|
||||||
|
],
|
||||||
|
auraIf: () => {
|
||||||
|
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
||||||
|
.enabled;
|
||||||
|
},
|
||||||
|
auraDisable: () => {
|
||||||
|
if (
|
||||||
|
global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"].fastfail
|
||||||
|
) {
|
||||||
|
return { value: true, tooltip: '关闭 "禁用屏幕锁" 以继续' };
|
||||||
|
}
|
||||||
|
return { value: false };
|
||||||
|
},
|
||||||
|
defaultValue: true,
|
||||||
|
valueGetter: () => {
|
||||||
|
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
||||||
|
.clickBtnToExit;
|
||||||
|
},
|
||||||
|
callbackFn: (newVal) => {
|
||||||
|
if (typeof newVal !== "boolean") return;
|
||||||
|
global.__HUGO_AURA_CONFIG__.rewrite[
|
||||||
|
"vendor/screenLock"
|
||||||
|
].clickBtnToExit = newVal;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 5,
|
||||||
|
id: "screenLockAuthOverrideType",
|
||||||
|
type: "radio",
|
||||||
|
name: "认证覆写模式",
|
||||||
|
description: "选择一个认证覆写模式, 或不修改认证策略",
|
||||||
|
restart: false,
|
||||||
|
reload: false,
|
||||||
|
associateVal: [
|
||||||
|
"rewrite.vendor/screenLock.enabled",
|
||||||
|
"rewrite.vendor/screenLock.fastfail",
|
||||||
|
],
|
||||||
|
auraIf: () => {
|
||||||
|
return global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"]
|
||||||
|
.enabled;
|
||||||
|
},
|
||||||
|
auraDisable: () => {
|
||||||
|
if (
|
||||||
|
global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"].fastfail
|
||||||
|
) {
|
||||||
|
return { value: true, tooltip: '关闭 "禁用屏幕锁" 以继续' };
|
||||||
|
}
|
||||||
|
return { value: false };
|
||||||
|
},
|
||||||
defaultValue: "none",
|
defaultValue: "none",
|
||||||
templates: ["customActivationCode", "none"],
|
templates: ["customActivationCode", "none"],
|
||||||
templateLabels: ["自定义激活码", "不修改"],
|
templateLabels: ["自定义激活码", "不修改"],
|
||||||
@@ -208,7 +321,7 @@ const authSettings = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 3,
|
index: 6,
|
||||||
id: "customActivationCode",
|
id: "customActivationCode",
|
||||||
type: "input",
|
type: "input",
|
||||||
subType: "password",
|
subType: "password",
|
||||||
@@ -221,6 +334,7 @@ const authSettings = [
|
|||||||
associateVal: [
|
associateVal: [
|
||||||
"rewrite.vendor/screenLock.enabled",
|
"rewrite.vendor/screenLock.enabled",
|
||||||
"rewrite.vendor/screenLock.authRewriteType",
|
"rewrite.vendor/screenLock.authRewriteType",
|
||||||
|
"rewrite.vendor/screenLock.fastfail",
|
||||||
],
|
],
|
||||||
auraIf: () => {
|
auraIf: () => {
|
||||||
return (
|
return (
|
||||||
@@ -229,6 +343,14 @@ const authSettings = [
|
|||||||
.authRewriteType === "customActivationCode"
|
.authRewriteType === "customActivationCode"
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
auraDisable: () => {
|
||||||
|
if (
|
||||||
|
global.__HUGO_AURA_CONFIG__.rewrite["vendor/screenLock"].fastfail
|
||||||
|
) {
|
||||||
|
return { value: true, tooltip: '关闭 "禁用屏幕锁" 以继续' };
|
||||||
|
}
|
||||||
|
return { value: false };
|
||||||
|
},
|
||||||
defaultValue: "",
|
defaultValue: "",
|
||||||
placeHolder: "留空表示不修改, 保留已设置值",
|
placeHolder: "留空表示不修改, 保留已设置值",
|
||||||
valueGetter: () => {
|
valueGetter: () => {
|
||||||
|
|||||||
@@ -57,6 +57,146 @@ const uxAndAppearanceSettings = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
categoryName: "U 盘提示",
|
||||||
|
child: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
id: "switchUsbInsertPromptButton",
|
||||||
|
type: "switch",
|
||||||
|
name: '隐藏 U 盘插入提示悬浮窗的 "开始查杀" 按钮',
|
||||||
|
description: '启用后, "打开 U 盘" 将成为悬浮窗中的 Primary 按钮',
|
||||||
|
restart: true,
|
||||||
|
reload: false,
|
||||||
|
associateVal: [
|
||||||
|
"networkRewrite.appearance/switchUsbInsertPromptBtn.enabled",
|
||||||
|
],
|
||||||
|
auraIf: () => true,
|
||||||
|
defaultValue: false,
|
||||||
|
auraDisable: () => {
|
||||||
|
if (
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].mode === "hide" &&
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].enabled
|
||||||
|
) {
|
||||||
|
return { value: true, tooltip: '禁用 "隐藏 U 盘插入提示" 以继续' };
|
||||||
|
} else {
|
||||||
|
return { value: false };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
valueGetter: () => {
|
||||||
|
return (
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].mode === "switch" &&
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].enabled
|
||||||
|
);
|
||||||
|
},
|
||||||
|
callbackFn: (newVal) => {
|
||||||
|
if (typeof newVal !== "boolean") return;
|
||||||
|
if (newVal === true) {
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].mode = "switch";
|
||||||
|
}
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].enabled = newVal;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
index: 1,
|
||||||
|
id: "hideUsbInsertPrompt",
|
||||||
|
type: "switch",
|
||||||
|
name: "隐藏 U 盘插入提示",
|
||||||
|
description: "启用后, 插入 U 盘将不再显示悬浮窗",
|
||||||
|
restart: true,
|
||||||
|
reload: false,
|
||||||
|
associateVal: [
|
||||||
|
"networkRewrite.appearance/switchUsbInsertPromptBtn.enabled",
|
||||||
|
],
|
||||||
|
auraIf: () => true,
|
||||||
|
defaultValue: false,
|
||||||
|
auraDisable: () => {
|
||||||
|
if (
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].mode === "switch" &&
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].enabled
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
value: true,
|
||||||
|
tooltip:
|
||||||
|
'禁用 "隐藏 U 盘插入提示悬浮窗的 "开始查杀" 按钮" 以继续',
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return { value: false };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
valueGetter: () => {
|
||||||
|
return (
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].mode === "hide" &&
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].enabled
|
||||||
|
);
|
||||||
|
},
|
||||||
|
callbackFn: (newVal) => {
|
||||||
|
if (typeof newVal !== "boolean") return;
|
||||||
|
if (newVal === true) {
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].mode = "hide";
|
||||||
|
}
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/switchUsbInsertPromptBtn"
|
||||||
|
].enabled = newVal;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
categoryName: "广告拦截",
|
||||||
|
child: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
id: "banAdBlockPrompt",
|
||||||
|
type: "switch",
|
||||||
|
name: "隐藏广告拦截悬浮窗",
|
||||||
|
description: "启用后, 管家检测到未拦截广告弹窗时, 将不会再显示悬浮窗",
|
||||||
|
restart: true,
|
||||||
|
reload: false,
|
||||||
|
warning: true,
|
||||||
|
warningContent:
|
||||||
|
'此功能不会完全禁用 "广告拦截" 功能, 已被拦截的广告弹窗依然会被拦截。如果您希望彻底禁用广告拦截, 请参阅 Aikari 的相关设置项 (WIP)',
|
||||||
|
associateVal: [],
|
||||||
|
auraIf: () => true,
|
||||||
|
defaultValue: false,
|
||||||
|
valueGetter: () => {
|
||||||
|
return global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/banAdBlockPrompt"
|
||||||
|
].enabled;
|
||||||
|
},
|
||||||
|
callbackFn: (newVal) => {
|
||||||
|
if (typeof newVal !== "boolean") return;
|
||||||
|
global.__HUGO_AURA_CONFIG__.networkRewrite[
|
||||||
|
"appearance/banAdBlockPrompt"
|
||||||
|
].enabled = newVal;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = { uxAndAppearanceSettings };
|
module.exports = { uxAndAppearanceSettings };
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
display: none;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
let global = window;
|
let global = window;
|
||||||
</script>
|
</script>
|
||||||
|
<script src="../../../js/global.js"></script>
|
||||||
<script src="../../../js/aikariConnectionManager.js"></script>
|
<script src="../../../js/aikariConnectionManager.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
|
|||||||
5
src/aura/utils/string.js
Normal file
5
src/aura/utils/string.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
const checkIfNonAscii = (str) => {
|
||||||
|
return Buffer.byteLength(str) !== str.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { checkIfNonAscii };
|
||||||
@@ -48,6 +48,7 @@ const ConfigManager = require("../aura/init/shared/configManager");
|
|||||||
const RegistryManager = require("../aura/init/shared/registryManager");
|
const RegistryManager = require("../aura/init/shared/registryManager");
|
||||||
const { buildIpcMain } = require("../aura/init/main/ipcHandler");
|
const { buildIpcMain } = require("../aura/init/main/ipcHandler");
|
||||||
const plsUtils = require("../aura/utils/pls");
|
const plsUtils = require("../aura/utils/pls");
|
||||||
|
const stringUtils = require("../aura/utils/string");
|
||||||
|
|
||||||
const { initLogger } = require("../aura/init/main/logger");
|
const { initLogger } = require("../aura/init/main/logger");
|
||||||
|
|
||||||
@@ -60,18 +61,26 @@ const getUserDocumentsDirPath = () => {
|
|||||||
true,
|
true,
|
||||||
/REG_EXPAND_SZ\s+(.+)/
|
/REG_EXPAND_SZ\s+(.+)/
|
||||||
);
|
);
|
||||||
if (pathInfo.success && pathInfo.data) {
|
try {
|
||||||
const resolvedPath = pathInfo.data.replace(
|
if (pathInfo.success && pathInfo.data) {
|
||||||
/%([^%]+)%/g,
|
const resolvedPath = pathInfo.data.replace(
|
||||||
(match, varName) => {
|
/%([^%]+)%/g,
|
||||||
return process.env[varName] || match;
|
(match, varName) => {
|
||||||
}
|
return process.env[varName] || match;
|
||||||
);
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return resolvedPath;
|
if (stringUtils.checkIfNonAscii(resolvedPath)) {
|
||||||
} else {
|
console.warn("[HugoAura / Init] Detected non-ASCII char in resolved user personal folder: ", resolvedPath);
|
||||||
|
throw new Error("Non-ASCII char detected");
|
||||||
|
}
|
||||||
|
return resolvedPath;
|
||||||
|
} else {
|
||||||
|
throw new Error("Registry data failed to get");
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
console.error(
|
console.error(
|
||||||
"[HugoAura / Init / Logger] Failed to get the path of documents dir, using default val."
|
"[HugoAura / Init / Logger] Failed to get the path of documents dir, using default val. | Error: ", err
|
||||||
);
|
);
|
||||||
return path.join(os.homedir(), "Documents");
|
return path.join(os.homedir(), "Documents");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// @ts-check
|
// @ts-check
|
||||||
|
|
||||||
const __AURA_VERSION__ = "0.2.0-rc1";
|
const __AURA_VERSION__ = "0.2.0-rc1-p3";
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
if (require.main) return; // 如果只是导入 Aura Version, 不运行闭包逻辑
|
if (require.main) return; // 如果只是导入 Aura Version, 不运行闭包逻辑
|
||||||
|
|||||||
Reference in New Issue
Block a user