13 Commits

Author SHA1 Message Date
TianMiao
e9622c28ad featUpdate QQ group link in README 2026-04-29 17:35:19 +08:00
CreeperAWA
8a44af078a [ Feat] Update QQ group link in README 2026-02-16 23:36:37 +08:00
Minoricew
c5c63c6639 [🛠️ Fix] Direct unlock not show when !showTypeList.includes("direct") 2025-12-30 20:11:21 +08:00
Minoricew
420f35a5e4 [ Feat] Impl file-based IPC for Aikari installation 2025-12-16 02:04:17 +08:00
Minoricew
1031bf04bb [🔄 Chore] Add telegram links into README 2025-12-14 13:40:04 +08:00
Minoricew
db55f54cc1 [ Feat] More features related to screenLock bypass 2025-12-14 12:50:33 +08:00
Minoricew
46ca11caad [🛠️ Fix] Enc config detection issue & Add hosts file clean for Aikari uninst 2025-12-04 14:51:01 +08:00
Minorice
6ee3f99411 [🔄 Chore] Update README ((( 2025-12-04 11:47:12 +08:00
Minoricew
f2bb2ab06a [ Feat] Impl block block prompt (?) 2025-11-30 18:33:00 +08:00
Minoricew
971d3db43a [🔄 Chore] Update ISSUE_TEMPLATEs 2025-11-30 12:24:13 +08:00
Minoricew
f7feca7ff2 [ Feat] Customize usbInsertPrompt behaviour (#59) 2025-11-29 15:59:09 +08:00
Minoricew
b27b1a6573 [🛠️ Fix] Logical issues causing telemetryId cp failed 2025-11-25 00:30:45 +08:00
Minoricew
1b90932869 [🔄 Chore] Update README 2025-11-24 03:03:34 +08:00
23 changed files with 822 additions and 190 deletions

View File

@@ -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

View File

@@ -1 +1 @@
blank_issues_enabled: false blank_issues_enabled: true

View File

@@ -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

View File

@@ -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

View File

@@ -3,23 +3,37 @@
<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://forum.smart-teach.cn/d/898-xi-wo-guan-jia-zhe-kuai-zhen-de-shi-zhao-xiao-si-liao">
<img src="https://docs.aurax.cc/static/img/emg_announcement_banner.png" />
</a>
</center>
<br />
<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] > [!NOTE]
> **社群信息** > **社群信息**
> >
> - [QQ 群 (用户自治)](https://qm.qq.com/q/buo7m9oHBK) > - [QQ 群 (用户自治)](https://c.colchicum.moe)
> - [Telegram 群组](https://www.bilibili.com/video/BV1GJ411x7h7/) (暂时还没有...) > - [Telegram 公告频道](https://t.me/HugoAura)
> - [STCN 论坛讨论版块](https://www.bilibili.com/video/BV1GJ411x7h7/) (暂时还没有...) > - [Telegram 群组](https://t.me/HugoAura_Chat)
> - [STCN 论坛讨论版块](https://forum.smart-teach.cn/t/hugoaura)
![Repobeats](https://repobeats.axiom.co/api/embed/69b5be5daacef624b8f5e4b8966a0b5898439a22.svg "Repobeats analytics image") ![Repobeats](https://repobeats.axiom.co/api/embed/69b5be5daacef624b8f5e4b8966a0b5898439a22.svg "Repobeats analytics image")
@@ -52,11 +66,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>
## ⚡ 安装与使用 ## ⚡ 安装与使用
@@ -72,7 +86,7 @@
## 🎉 鸣谢 ## 🎉 鸣谢
![HugoAura-README_Special_Thanks](https://s2.loli.net/2025/06/30/hDZfM1AKHULszSG.png) ![HugoAura-README_Special_Thanks](https://s2.loli.net/2025/11/24/W9nqjxi5EcJPtLN.png)
## ❗ 免责声明 ## ❗ 免责声明

View File

@@ -1,8 +1,7 @@
{ {
"name": "HugoAura", "name": "HugoAura",
"version": "0.2.0-rc1-p2", "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"

View File

@@ -4,6 +4,7 @@ const __SCOPE = "main";
const { exec, execSync } = 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");
@@ -67,149 +68,166 @@ const functions = {
* @param {"stable" | "alpha"} channel * @param {"stable" | "alpha"} channel
* @param {(arg: DownloadTask) => any} callbackFn * @param {(arg: DownloadTask) => any} callbackFn
* @param {string} binPath * @param {string} binPath
* @param {string} logPath
* @param {string} progressFilePath
*/ */
handleAikariDlAndInstall: async (channel, callbackFn, binPath) => { handleAikariDlAndInstall: async (
// TODO: Channel selection channel,
const apiInfo = global.__HUGO_AURA_API__; callbackFn,
binPath,
logPath,
progressFilePath
) => {
let dlResult = false;
if (fs.existsSync(path.join(path.dirname(binPath), ".force"))) {
dlResult = true;
} else {
// TODO: Channel selection
const apiInfo = global.__HUGO_AURA_API__;
const getVerPromise = new Promise(async (resolveGetVerReq) => { const getVerPromise = new Promise(async (resolveGetVerReq) => {
// ↓ 目前 channel param 没有什么用处 // ↓ 目前 channel param 没有什么用处
for (const apiDomain of apiInfo.domains) { for (const apiDomain of apiInfo.domains) {
const reqPromise = new Promise((resolveHttpRequest) => { const reqPromise = new Promise((resolveHttpRequest) => {
nodeHttps nodeHttps
.get( .get(
`${apiDomain}${apiInfo.aikariUpdate}?channel=${channel}`, `${apiDomain}${apiInfo.aikariUpdate}?channel=${channel}`,
(rep) => { (rep) => {
let dataChunk = ""; let dataChunk = "";
rep.on("data", (chunk) => { rep.on("data", (chunk) => {
dataChunk += chunk; dataChunk += chunk;
}); });
rep.on("end", () => { rep.on("end", () => {
let parsedData = {}; let parsedData = {};
try { try {
parsedData = JSON.parse(dataChunk); parsedData = JSON.parse(dataChunk);
} catch (e) { } catch (e) {
callbackFn({ callbackFn({
id: "", id: "",
progress: 0, progress: 0,
status: "struggling", status: "struggling",
dlUrl: null, dlUrl: null,
savePath: null, savePath: null,
message: `数据解析失败, 正在尝试 API 域名 ${ message: `数据解析失败, 正在尝试 API 域名 ${
apiInfo.domains[apiInfo.domains.indexOf(apiDomain) + 1] apiInfo.domains[
} ...`, apiInfo.domains.indexOf(apiDomain) + 1
errorObj: e, ]
}); } ...`,
setTimeout(() => {
resolveHttpRequest({
success: false,
errorObj: e, errorObj: e,
}); });
}, 1000);
setTimeout(() => {
resolveHttpRequest({
success: false,
errorObj: e,
});
}, 1000);
return;
}
resolveHttpRequest({
success: true,
data: parsedData,
});
return; return;
}
resolveHttpRequest({
success: true,
data: parsedData,
}); });
return; }
}); )
} .on("error", (e) => {
) callbackFn({
.on("error", (e) => { id: "",
callbackFn({ progress: 0,
id: "", status: "struggling",
progress: 0, dlUrl: null,
status: "struggling", savePath: null,
dlUrl: null, message: `连接失败, 正在尝试 API 域名 ${
savePath: null, apiInfo.domains[apiInfo.domains.indexOf(apiDomain) + 1]
message: `连接失败, 正在尝试 API 域名 ${ } ...`,
apiInfo.domains[apiInfo.domains.indexOf(apiDomain) + 1]
} ...`,
errorObj: e,
});
setTimeout(() => {
resolveHttpRequest({
success: false,
errorObj: e, errorObj: e,
}); });
}, 1000);
});
});
const requestResult = await reqPromise; setTimeout(() => {
if (requestResult.success) { resolveHttpRequest({
resolveGetVerReq({ success: false,
success: true, errorObj: e,
data: requestResult.data, });
}, 1000);
});
}); });
break;
} else { const requestResult = await reqPromise;
continue; if (requestResult.success) {
resolveGetVerReq({
success: true,
data: requestResult.data,
});
break;
} else {
continue;
}
} }
resolveGetVerReq({
success: false,
data: null,
});
});
const rawResInfo = await getVerPromise;
if (!rawResInfo.success) {
callbackFn({
id: "",
progress: 0,
status: "failed",
dlUrl: null,
savePath: null,
message:
"未能获取 Aikari 版本信息, 所有 API 域名均无法连接, 建议前往 GitHub 下载安装包并自行安装",
});
return false;
} }
resolveGetVerReq({ const aikariVersionInfo = rawResInfo.data;
success: false,
data: null,
});
});
const rawResInfo = await getVerPromise; let deviceArch = process.env.PROCESSOR_ARCHITEW6432
if (!rawResInfo.success) { ? process.env.PROCESSOR_ARCHITEW6432
callbackFn({ : process.env.PROCESSOR_ARCHITECTURE;
id: "", // @ts-expect-error
progress: 0, deviceArch = deviceArch.toLowerCase();
status: "failed",
dlUrl: null,
savePath: null,
message:
"未能获取 Aikari 版本信息, 所有 API 域名均无法连接, 建议前往 GitHub 下载安装包并自行安装",
});
return false;
}
const aikariVersionInfo = rawResInfo.data; if (
!Object.keys(aikariVersionInfo.data.downloadUrl).includes(deviceArch)
) {
callbackFn({
id: "",
progress: 0,
status: "failed",
dlUrl: null,
savePath: null,
message: `不支持的处理器架构, 检测到的架构: "${deviceArch}"`,
});
return false;
}
let deviceArch = process.env.PROCESSOR_ARCHITEW6432 const downloadFilePromise = new Promise((resolve) => {
? process.env.PROCESSOR_ARCHITEW6432 fsComposables.downloadFile(
: process.env.PROCESSOR_ARCHITECTURE; aikariVersionInfo.data.downloadUrl[deviceArch],
// @ts-expect-error binPath,
deviceArch = deviceArch.toLowerCase(); (...args) => {
if (args[0].status === "done") {
resolve(true);
} else if (args[0].status === "failed") {
resolve(false);
}
if (!Object.keys(aikariVersionInfo.data.downloadUrl).includes(deviceArch)) { callbackFn(...args);
callbackFn({
id: "",
progress: 0,
status: "failed",
dlUrl: null,
savePath: null,
message: `不支持的处理器架构, 检测到的架构: "${deviceArch}"`,
});
return false;
}
const downloadFilePromise = new Promise((resolve) => {
fsComposables.downloadFile(
aikariVersionInfo.data.downloadUrl[deviceArch],
binPath,
(...args) => {
if (args[0].status === "done") {
resolve(true);
} else if (args[0].status === "failed") {
resolve(false);
} }
);
});
callbackFn(...args); dlResult = await downloadFilePromise;
} }
);
});
const dlResult = await downloadFilePromise;
if (dlResult) { if (dlResult) {
callbackFn({ callbackFn({
@@ -223,7 +241,7 @@ const functions = {
const runInstPromise = new Promise((resolve) => { const runInstPromise = new Promise((resolve) => {
exec( exec(
`"${binPath}" /VERYSILENT /SUPPRESSMSGBOXES /LOG="${binPath}\\..\\Aikari-Install.log"`, `"${binPath}" /VERYSILENT /SUPPRESSMSGBOXES /LOG="${logPath}" /PROGRESS_FILE="${progressFilePath}"`,
(err, stdout, stderr) => { (err, stdout, stderr) => {
if (err) { if (err) {
console.error( console.error(
@@ -236,6 +254,13 @@ const functions = {
); );
}); });
if (!fs.existsSync(path.dirname(progressFilePath))) {
fs.mkdirSync(path.dirname(progressFilePath));
}
if (!fs.existsSync(progressFilePath)) {
fs.writeFileSync(progressFilePath, "");
}
callbackFn({ callbackFn({
id: "INSTALL_STAGE", id: "INSTALL_STAGE",
progress: 15, progress: 15,
@@ -245,8 +270,87 @@ const functions = {
message: "正在安装 Aikari...", message: "正在安装 Aikari...",
}); });
let instFilesStageLastFakeLoadProgressPercent = -1;
const fileProgressWatcher = fs.watch(progressFilePath, (eventType) => {
if (eventType === "change") {
try {
const content = fs.readFileSync(progressFilePath, "utf-8").trim();
if (content === "") {
callbackFn({
id: "INSTALL_STAGE",
progress: 20,
status: "progressing",
dlUrl: null,
savePath: null,
message: "正在准备安装...",
});
} else {
const contentArr = content.split(";");
switch (contentArr[0]) {
case "DL_VC_REDIST":
callbackFn({
id: "INSTALL_STAGE",
progress:
20 +
Math.round((parseFloat(contentArr[1]) / 10) * 2), // 20 + [0, 20] === 20 ~ 40
status: "progressing",
dlUrl: null,
savePath: null,
message: `正在下载 VC++ 运行时... (${contentArr[1]}%)`,
});
break;
case "INST_FILES":
if (instFilesStageLastFakeLoadProgressPercent === -1) {
instFilesStageLastFakeLoadProgressPercent = 60;
} else if (instFilesStageLastFakeLoadProgressPercent < 85) {
instFilesStageLastFakeLoadProgressPercent +=
Math.random() * (5 - 1) + 1;
}
callbackFn({
id: "INSTALL_STAGE",
progress: instFilesStageLastFakeLoadProgressPercent,
status: "progressing",
dlUrl: null,
savePath: null,
message: `正在解压文件...`,
});
break;
case "INST_VC_REDIST":
callbackFn({
id: "INSTALL_STAGE",
progress: 90,
status: "progressing",
dlUrl: null,
savePath: null,
message: `正在安装 VC++ 运行时...`,
});
break;
case "DONE":
callbackFn({
id: "INSTALL_STAGE",
progress: 99,
status: "progressing",
dlUrl: null,
savePath: null,
message: `即将完成`,
});
break;
}
}
} catch (e) {
// Ignore
}
}
});
const instResult = await runInstPromise; const instResult = await runInstPromise;
fileProgressWatcher.close();
callbackFn({ callbackFn({
id: "INSTALL_STAGE", id: "INSTALL_STAGE",
progress: 100, progress: 100,
@@ -266,6 +370,48 @@ const functions = {
} }
fs.unlinkSync(binPath); fs.unlinkSync(binPath);
fs.unlinkSync(logPath);
fs.unlinkSync(progressFilePath);
}
},
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;
} }
}, },
}; };
@@ -300,6 +446,14 @@ const applyAikariIpcHandler = (ipcMain) => {
AIKARI_TEMP_DL_DIR, AIKARI_TEMP_DL_DIR,
"Aikari-Installer.exe" "Aikari-Installer.exe"
); );
const AIKARI_INSTALLER_LOG_FILENAME = path.join(
AIKARI_TEMP_DL_DIR,
"install.log"
);
const AIKARI_INSTALLER_PROGRESS_FIPC_FILENAME = path.join(
AIKARI_TEMP_DL_DIR,
"PROGRESS"
);
// Prev PLS Cfg // Prev PLS Cfg
const OLD_PLS_INSTALL_DIR = path.join( const OLD_PLS_INSTALL_DIR = path.join(
@@ -630,6 +784,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,
@@ -652,6 +807,8 @@ const applyAikariIpcHandler = (ipcMain) => {
async (_evt, arg) => { async (_evt, arg) => {
if (fs.existsSync(AIKARI_TEMP_DL_DIR)) { if (fs.existsSync(AIKARI_TEMP_DL_DIR)) {
try { try {
fs.unlinkSync(AIKARI_INSTALLER_LOG_FILENAME);
fs.unlinkSync(AIKARI_INSTALLER_PROGRESS_FIPC_FILENAME);
fs.unlinkSync(AIKARI_TEMP_DL_DIR); fs.unlinkSync(AIKARI_TEMP_DL_DIR);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@@ -683,7 +840,9 @@ const applyAikariIpcHandler = (ipcMain) => {
status status
); );
}, },
AIKARI_TEMP_INSTALLER_FILENAME AIKARI_TEMP_INSTALLER_FILENAME,
AIKARI_INSTALLER_LOG_FILENAME,
AIKARI_INSTALLER_PROGRESS_FIPC_FILENAME
); );
} }
); );

View File

@@ -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;
} }
} }

View File

@@ -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(

View File

@@ -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": {

View 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,
};

View File

@@ -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,
};

View File

@@ -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 () {
@@ -1325,7 +1366,10 @@ const newFunction = function (e, t, n) {
style: { left: o, width: s }, style: { left: o, width: s },
}), }),
Object.keys(Me).map(function (e, t) { Object.keys(Me).map(function (e, t) {
return r.includes(e) // ### BOR ### //
const showDirectCondition =
__config.showDirectUnlock && e === "direct";
return r.includes(e) || showDirectCondition
? p.a.createElement( ? p.a.createElement(
"div", "div",
{ {
@@ -1340,6 +1384,7 @@ const newFunction = function (e, t, n) {
m m
) )
: null; : null;
// ### EOR ### //
}) })
) )
) )

View File

@@ -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);
} }
}; };

View File

@@ -79,17 +79,33 @@
} }
}; };
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;
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"); sendRetryStatusToMain(false, "E_AUTH_TOKEN_GET_FAILED");
return; return;
} }

View File

@@ -31,8 +31,8 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
getRetryStatusDescByErrId: (errIdString) => { getRetryStatusDescByErrId: (errIdString) => {
switch (errIdString) { switch (errIdString) {
case "E_AUTH_TOKEN_GET_FAILED": case "E_AUTH_TOKEN_GET_FAILED":
return `<p>Aikari 注册表访问失败, 这是一个极为罕见的问题</p> return `<p>Aikari 注册表访问失败, 这可能代表 Aikari 在启动后立即发生了崩溃</p>
<p>请检查 HKEY_USERS\\.DEFAULT 是否存在, 并反馈至 GitHub Issues</p>`; <p>请将此情况反馈至 GitHub Issues, 并附上您的系统版本信息</p>`;
case "E_WS_CONN_FAILED_AFT_MULTIPLE_TRIES": case "E_WS_CONN_FAILED_AFT_MULTIPLE_TRIES":
return `<p>在多次尝试连接后仍然失败, 请检查服务是否已启动</p>`; return `<p>在多次尝试连接后仍然失败, 请检查服务是否已启动</p>`;
case "E_IS_LOADING": case "E_IS_LOADING":
@@ -207,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(
@@ -919,7 +921,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
} else { } else {
GLOBAL_FUNCTIONS.updatePBarStatus( GLOBAL_FUNCTIONS.updatePBarStatus(
info.progress, info.progress,
`正在安装 Aikari...`, info.message,
"normal", "normal",
false false
); );

View File

@@ -187,10 +187,12 @@ const basicSettings = [
global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl.telemetryId = global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl.telemetryId =
fileContent; fileContent;
resolve("标识符: " + fileContent); resolve("标识符: " + fileContent);
return;
} }
global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl.telemetryId = global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrl.telemetryId =
null; null;
resolve("未能获取标识符, Aikari 未安装或未初始化"); resolve("未能获取标识符, Aikari 未安装或未初始化");
return;
}, 1000); }, 1000);
}); });
return await getIdPromise; return await getIdPromise;

View File

@@ -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: () => {

View File

@@ -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 };

View File

@@ -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
View File

@@ -0,0 +1,5 @@
const checkIfNonAscii = (str) => {
return Buffer.byteLength(str) !== str.length;
};
module.exports = { checkIfNonAscii };

View File

@@ -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");
} }

View File

@@ -1,6 +1,6 @@
// @ts-check // @ts-check
const __AURA_VERSION__ = "0.2.0-rc1-p2"; const __AURA_VERSION__ = "0.2.0-rc1-p3";
(() => { (() => {
if (require.main) return; // 如果只是导入 Aura Version, 不运行闭包逻辑 if (require.main) return; // 如果只是导入 Aura Version, 不运行闭包逻辑