2025-05-25 22:40:12 +08:00
|
|
|
// @ts-check
|
|
|
|
|
|
|
|
|
|
const __SCOPE = "main";
|
|
|
|
|
|
2025-06-07 23:51:54 +08:00
|
|
|
const { exec } = require("child_process");
|
2025-05-25 22:40:12 +08:00
|
|
|
const fs = require("fs");
|
|
|
|
|
const path = require("path");
|
2025-06-09 18:02:11 +08:00
|
|
|
const nodeHttps = require("https");
|
|
|
|
|
const { fsComposables } = require("./fsIpcHandler");
|
2025-05-25 22:40:12 +08:00
|
|
|
|
2025-06-07 23:51:54 +08:00
|
|
|
const functions = {
|
|
|
|
|
querySvcDetail: (
|
|
|
|
|
/** @type {string} */ svcName,
|
|
|
|
|
/** @type {string} */ findTarget
|
|
|
|
|
) => {
|
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
|
exec(
|
|
|
|
|
`sc query ${svcName}`,
|
|
|
|
|
{ encoding: "utf8" },
|
|
|
|
|
(error, stdout, stderr) => {
|
|
|
|
|
if (error) {
|
|
|
|
|
resolve({
|
|
|
|
|
success: true,
|
|
|
|
|
result: false,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (stdout.includes(findTarget)) {
|
|
|
|
|
resolve({
|
|
|
|
|
success: true,
|
|
|
|
|
result: true,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
resolve({
|
|
|
|
|
success: true,
|
|
|
|
|
result: false,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {string} logHeader
|
|
|
|
|
* @param {string} binPath
|
|
|
|
|
* @param {string} command
|
|
|
|
|
* @returns {Promise<{ success: boolean, errorObj?: Error }>}
|
|
|
|
|
*/
|
|
|
|
|
execCommand: (logHeader, binPath, command) => {
|
2025-06-09 18:02:11 +08:00
|
|
|
const processedPath = binPath.includes(" ") ? `"${binPath}"` : binPath;
|
2025-06-07 23:51:54 +08:00
|
|
|
return new Promise((resolve) => {
|
2025-06-09 18:02:11 +08:00
|
|
|
exec(`${processedPath} ${command}`, (error, stdout, stderr) => {
|
2025-06-07 23:51:54 +08:00
|
|
|
if (error) {
|
|
|
|
|
console.error(`${logHeader} Failed to execute command:`, error);
|
|
|
|
|
resolve({ success: false, errorObj: error });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
resolve({ success: true });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
2025-06-09 18:02:11 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {"stable" | "alpha"} channel
|
|
|
|
|
* @param {(arg: DownloadTask) => any} callbackFn
|
|
|
|
|
* @param {string} binPath
|
|
|
|
|
*/
|
2025-11-14 02:58:09 +08:00
|
|
|
handleAikariDownload: async (channel, callbackFn, binPath) => {
|
2025-06-09 18:02:11 +08:00
|
|
|
// TODO: Channel selection
|
|
|
|
|
const apiInfo = global.__HUGO_AURA_API__;
|
|
|
|
|
|
2025-06-13 11:49:22 +08:00
|
|
|
const getVerPromise = new Promise(async (resolveGetVerReq) => {
|
2025-06-09 18:02:11 +08:00
|
|
|
// ↓ 目前 channel param 没有什么用处
|
2025-06-13 11:49:22 +08:00
|
|
|
for (const apiDomain of apiInfo.domains) {
|
|
|
|
|
const reqPromise = new Promise((resolveHttpRequest) => {
|
|
|
|
|
nodeHttps
|
|
|
|
|
.get(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${apiDomain}${apiInfo.aikariUpdate}?channel=${channel}`,
|
2025-06-13 11:49:22 +08:00
|
|
|
(rep) => {
|
|
|
|
|
let dataChunk = "";
|
|
|
|
|
rep.on("data", (chunk) => {
|
|
|
|
|
dataChunk += chunk;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
rep.on("end", () => {
|
|
|
|
|
let parsedData = {};
|
|
|
|
|
try {
|
|
|
|
|
parsedData = JSON.parse(dataChunk);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
callbackFn({
|
|
|
|
|
id: "",
|
|
|
|
|
progress: 0,
|
|
|
|
|
status: "struggling",
|
|
|
|
|
dlUrl: null,
|
|
|
|
|
savePath: null,
|
|
|
|
|
message: `数据解析失败, 正在尝试 API 域名 ${
|
|
|
|
|
apiInfo.domains[apiInfo.domains.indexOf(apiDomain) + 1]
|
|
|
|
|
} ...`,
|
|
|
|
|
errorObj: e,
|
|
|
|
|
});
|
2025-06-09 18:02:11 +08:00
|
|
|
|
2025-06-13 11:49:22 +08:00
|
|
|
setTimeout(() => {
|
|
|
|
|
resolveHttpRequest({
|
|
|
|
|
success: false,
|
|
|
|
|
errorObj: e,
|
|
|
|
|
});
|
|
|
|
|
}, 1000);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resolveHttpRequest({
|
|
|
|
|
success: true,
|
|
|
|
|
data: parsedData,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
.on("error", (e) => {
|
|
|
|
|
callbackFn({
|
|
|
|
|
id: "",
|
|
|
|
|
progress: 0,
|
|
|
|
|
status: "struggling",
|
|
|
|
|
dlUrl: null,
|
|
|
|
|
savePath: null,
|
|
|
|
|
message: `连接失败, 正在尝试 API 域名 ${
|
|
|
|
|
apiInfo.domains[apiInfo.domains.indexOf(apiDomain) + 1]
|
|
|
|
|
} ...`,
|
|
|
|
|
errorObj: e,
|
2025-06-09 18:02:11 +08:00
|
|
|
});
|
2025-06-13 11:49:22 +08:00
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
resolveHttpRequest({
|
|
|
|
|
success: false,
|
|
|
|
|
errorObj: e,
|
|
|
|
|
});
|
|
|
|
|
}, 1000);
|
2025-06-09 18:02:11 +08:00
|
|
|
});
|
|
|
|
|
});
|
2025-06-13 11:49:22 +08:00
|
|
|
|
|
|
|
|
const requestResult = await reqPromise;
|
|
|
|
|
if (requestResult.success) {
|
|
|
|
|
resolveGetVerReq({
|
|
|
|
|
success: true,
|
|
|
|
|
data: requestResult.data,
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resolveGetVerReq({
|
|
|
|
|
success: false,
|
|
|
|
|
data: null,
|
|
|
|
|
});
|
2025-06-09 18:02:11 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const rawResInfo = await getVerPromise;
|
|
|
|
|
if (!rawResInfo.success) {
|
|
|
|
|
callbackFn({
|
|
|
|
|
id: "",
|
|
|
|
|
progress: 0,
|
|
|
|
|
status: "failed",
|
|
|
|
|
dlUrl: null,
|
|
|
|
|
savePath: null,
|
2025-11-14 02:58:09 +08:00
|
|
|
message: "未能获取 Aikari 版本信息, 所有 API 域名均无法连接",
|
2025-06-09 18:02:11 +08:00
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
const aikariVersionInfo = rawResInfo.data;
|
2025-06-09 18:02:11 +08:00
|
|
|
|
|
|
|
|
let deviceArch = process.env.PROCESSOR_ARCHITEW6432
|
|
|
|
|
? process.env.PROCESSOR_ARCHITEW6432
|
|
|
|
|
: process.env.PROCESSOR_ARCHITECTURE;
|
|
|
|
|
// @ts-expect-error
|
|
|
|
|
deviceArch = deviceArch.toLowerCase();
|
|
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
if (!Object.keys(aikariVersionInfo.data.downloadUrl).includes(deviceArch)) {
|
2025-06-09 18:02:11 +08:00
|
|
|
callbackFn({
|
|
|
|
|
id: "",
|
|
|
|
|
progress: 0,
|
|
|
|
|
status: "failed",
|
|
|
|
|
dlUrl: null,
|
|
|
|
|
savePath: null,
|
|
|
|
|
message: `处理器架构识别失败, 检测到的架构: ${deviceArch}`,
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fsComposables.downloadFile(
|
2025-11-14 02:58:09 +08:00
|
|
|
aikariVersionInfo.data.downloadUrl[deviceArch],
|
2025-06-09 18:02:11 +08:00
|
|
|
binPath,
|
2025-06-13 11:49:22 +08:00
|
|
|
(...args) => {
|
|
|
|
|
if (args[0].status === "done") {
|
2025-11-14 02:58:09 +08:00
|
|
|
if (global.__HUGO_AURA__.aikariStats) {
|
|
|
|
|
global.__HUGO_AURA__.aikariStats.installed = true;
|
|
|
|
|
global.__HUGO_AURA__.aikariStats.status = "dead";
|
2025-06-13 11:49:22 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
callbackFn(...args);
|
|
|
|
|
}
|
2025-06-09 18:02:11 +08:00
|
|
|
);
|
|
|
|
|
},
|
2025-06-07 23:51:54 +08:00
|
|
|
};
|
|
|
|
|
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("../../../types/main/electron").AuraIPCMain} ipcMain
|
|
|
|
|
*/
|
2025-11-14 02:58:09 +08:00
|
|
|
const applyAikariIpcHandler = (ipcMain) => {
|
|
|
|
|
const methodBase = "$aura.aikari";
|
2025-05-25 22:40:12 +08:00
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
const AIKARI_DEFAULT_INSTALL_DIR = path.join(
|
|
|
|
|
"C:\\Program Files",
|
2025-11-16 18:35:53 +08:00
|
|
|
"HugoAura",
|
|
|
|
|
"Aikari"
|
2025-11-14 02:58:09 +08:00
|
|
|
);
|
|
|
|
|
const AIKARI_LAUNCHER_PATH = path.join(
|
|
|
|
|
AIKARI_DEFAULT_INSTALL_DIR,
|
|
|
|
|
"Aikari-Launcher.exe"
|
|
|
|
|
);
|
2025-11-16 18:35:53 +08:00
|
|
|
const AIKARI_UNINSTALLER_PATH = path.join(
|
|
|
|
|
AIKARI_DEFAULT_INSTALL_DIR,
|
|
|
|
|
"unins000.exe"
|
|
|
|
|
);
|
2025-11-14 02:58:09 +08:00
|
|
|
const AIKARI_SVC_NAME = "HugoAuraAikari";
|
2025-06-07 23:51:54 +08:00
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
const isAikariDetached = process.argv.includes("--aikari-detach");
|
2025-05-25 22:40:12 +08:00
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
global.__HUGO_AURA__.aikariStats = {
|
2025-05-25 22:40:12 +08:00
|
|
|
installed: false,
|
|
|
|
|
launched: false,
|
2025-11-14 02:58:09 +08:00
|
|
|
detached: isAikariDetached,
|
2025-05-25 22:40:12 +08:00
|
|
|
connected: false,
|
2025-06-21 19:20:01 +08:00
|
|
|
version: "unknown",
|
2025-05-25 22:40:12 +08:00
|
|
|
status: "dead",
|
2025-11-14 02:58:09 +08:00
|
|
|
authToken: global.__HUGO_AURA_CONFIG__.aikariToken,
|
2025-05-25 22:40:12 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.getIfAikariBinExists`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @returns {{ success: boolean; data: { isExists: boolean }; error?: Error }}
|
|
|
|
|
*/
|
|
|
|
|
(_event, _arg) => {
|
|
|
|
|
try {
|
2025-11-14 02:58:09 +08:00
|
|
|
const result = fs.existsSync(AIKARI_LAUNCHER_PATH);
|
2025-06-13 11:49:22 +08:00
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
if (global.__HUGO_AURA__.aikariStats?.status === "notInstalled") {
|
|
|
|
|
global.__HUGO_AURA__.aikariStats.status = "dead";
|
2025-06-13 11:49:22 +08:00
|
|
|
}
|
|
|
|
|
|
2025-05-25 22:40:12 +08:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
data: { isExists: result },
|
|
|
|
|
};
|
|
|
|
|
} catch (e) {
|
2025-06-13 11:49:22 +08:00
|
|
|
// @ts-expect-error
|
2025-11-14 02:58:09 +08:00
|
|
|
global.__HUGO_AURA__.aikariStats.status = "notInstalled";
|
2025-05-25 22:40:12 +08:00
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
data: { isExists: false },
|
|
|
|
|
error: e,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2025-06-09 18:02:11 +08:00
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.ensureAikariInstallDir`,
|
2025-06-09 18:02:11 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
|
|
|
|
* @param {any} _arg
|
|
|
|
|
* @returns {{ success: boolean; data: { alreadyExists: boolean; createdDir: string; }; error?: Error }}
|
|
|
|
|
*/
|
|
|
|
|
(_event, _arg) => {
|
2025-11-14 02:58:09 +08:00
|
|
|
const alreadyExists = fs.existsSync(AIKARI_DEFAULT_INSTALL_DIR);
|
2025-06-09 18:02:11 +08:00
|
|
|
if (alreadyExists) {
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
data: {
|
|
|
|
|
alreadyExists: true,
|
2025-11-14 02:58:09 +08:00
|
|
|
createdDir: AIKARI_DEFAULT_INSTALL_DIR,
|
2025-06-09 18:02:11 +08:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2025-11-14 02:58:09 +08:00
|
|
|
fs.mkdirSync(AIKARI_DEFAULT_INSTALL_DIR, { recursive: true });
|
2025-06-09 18:02:11 +08:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
data: {
|
|
|
|
|
alreadyExists: false,
|
2025-11-14 02:58:09 +08:00
|
|
|
createdDir: AIKARI_DEFAULT_INSTALL_DIR,
|
2025-06-09 18:02:11 +08:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
data: {
|
|
|
|
|
alreadyExists: false,
|
2025-11-14 02:58:09 +08:00
|
|
|
createdDir: AIKARI_DEFAULT_INSTALL_DIR,
|
2025-06-09 18:02:11 +08:00
|
|
|
},
|
|
|
|
|
error: error,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2025-05-25 22:40:12 +08:00
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.getAikariStatus`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
2025-11-14 02:58:09 +08:00
|
|
|
* @returns {{ success: boolean; data: import("../../../types/shared/aikari/status").AikariStatus | null | undefined; }}
|
2025-05-25 22:40:12 +08:00
|
|
|
*/
|
|
|
|
|
(_event, _arg) => {
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
2025-11-14 02:58:09 +08:00
|
|
|
data: global.__HUGO_AURA__.aikariStats,
|
2025-05-25 22:40:12 +08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.updateAikariStatus`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
2025-11-14 02:58:09 +08:00
|
|
|
* @param {import("../../../types/shared/aikari/status").AikariStatus} arg
|
2025-05-25 22:40:12 +08:00
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
(_event, arg) => {
|
2025-11-14 02:58:09 +08:00
|
|
|
global.__HUGO_AURA__.aikariStats = arg;
|
|
|
|
|
ipcMain.send("assistant", `${methodBase}.post.onAikariStatsUpdate`, arg);
|
2025-05-25 22:40:12 +08:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.getAikariSettings`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
2025-06-05 00:35:50 +08:00
|
|
|
* @returns {{ success: boolean; data: Record<any, any> | null | undefined }}
|
2025-05-25 22:40:12 +08:00
|
|
|
*/
|
|
|
|
|
(_event, _arg) => {
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
2025-11-14 02:58:09 +08:00
|
|
|
data: global.__HUGO_AURA__.aikariSettings,
|
2025-05-25 22:40:12 +08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.updateAikariSettings`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
|
|
|
|
* @param {Record<any, any>} arg
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
(_event, arg) => {
|
2025-11-14 02:58:09 +08:00
|
|
|
global.__HUGO_AURA__.aikariSettings = arg;
|
|
|
|
|
ipcMain.send(
|
|
|
|
|
"assistant",
|
|
|
|
|
`${methodBase}.post.onAikariSettingsUpdate`,
|
|
|
|
|
arg
|
|
|
|
|
);
|
2025-05-25 22:40:12 +08:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.getAikariRules`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
2025-06-05 00:35:50 +08:00
|
|
|
* @returns {{ success: boolean; data: Record<any, any> | null | undefined }}
|
2025-05-25 22:40:12 +08:00
|
|
|
*/
|
|
|
|
|
(_event, _arg) => {
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
2025-11-14 02:58:09 +08:00
|
|
|
data: global.__HUGO_AURA__.aikariRules,
|
2025-05-25 22:40:12 +08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.updateAikariRules`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
|
|
|
|
* @param {Record<any, any>} arg
|
|
|
|
|
* @returns
|
|
|
|
|
*/
|
|
|
|
|
(_event, arg) => {
|
2025-11-14 02:58:09 +08:00
|
|
|
global.__HUGO_AURA__.aikariRules = arg;
|
|
|
|
|
ipcMain.send("assistant", `${methodBase}.post.onAikariRulesUpdate`, arg);
|
2025-05-25 22:40:12 +08:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.on(
|
|
|
|
|
`${methodBase}.ws.broadcastMessageRecv`,
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainEvent} _event
|
2025-11-14 02:58:09 +08:00
|
|
|
* @param {AikariResponse} arg
|
2025-05-25 22:40:12 +08:00
|
|
|
*/
|
|
|
|
|
(_event, arg) => {
|
|
|
|
|
ipcMain.send("assistant", `${methodBase}.ws.post.onNewMsgRecv`, arg);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
|
|
|
|
`${methodBase}.ws.sendWsMessage`,
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
2025-11-14 02:58:09 +08:00
|
|
|
* @param {ClientAikariRequest} arg
|
2025-05-25 22:40:12 +08:00
|
|
|
*/
|
|
|
|
|
(_event, arg) => {
|
|
|
|
|
ipcMain.send(
|
2025-06-17 18:14:58 +08:00
|
|
|
"auraWsKeepAlive",
|
2025-05-25 22:40:12 +08:00
|
|
|
`${methodBase}.ws.post.onReqSendMsg`,
|
|
|
|
|
arg
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.syncAikariConfig`,
|
2025-05-25 22:40:12 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} event
|
|
|
|
|
* @param {{ basic: Record<any, any>, rules: Record<any, any> }} arg
|
|
|
|
|
*/
|
|
|
|
|
(event, arg) => {
|
2025-11-14 02:58:09 +08:00
|
|
|
global.__HUGO_AURA__.aikariRules = arg.rules;
|
|
|
|
|
global.__HUGO_AURA__.aikariSettings = arg.basic;
|
2025-05-25 22:40:12 +08:00
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
ipcMain.send("*", `${methodBase}.syncAikariConfig`, arg, event.sender);
|
2025-05-25 22:40:12 +08:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
2025-06-06 02:05:04 +08:00
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.aikariLifecycleQuery`,
|
2025-06-07 23:51:54 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
2025-11-14 02:58:09 +08:00
|
|
|
* @param {{ target: import("../../../types/shared/aikari/status").AikariLifecycleType }} arg
|
2025-06-07 23:51:54 +08:00
|
|
|
* @returns {Promise<{ success: boolean, result: boolean }>}
|
|
|
|
|
*/
|
|
|
|
|
async (_event, arg) => {
|
|
|
|
|
switch (arg.target) {
|
|
|
|
|
case "isDetached":
|
2025-11-14 02:58:09 +08:00
|
|
|
return { success: true, result: isAikariDetached };
|
2025-06-07 23:51:54 +08:00
|
|
|
case "isSvcInstalled":
|
2025-11-14 02:58:09 +08:00
|
|
|
return await functions.querySvcDetail(
|
|
|
|
|
AIKARI_SVC_NAME,
|
|
|
|
|
"SERVICE_NAME"
|
|
|
|
|
);
|
2025-06-07 23:51:54 +08:00
|
|
|
case "isSvcStart":
|
2025-11-14 02:58:09 +08:00
|
|
|
return await functions.querySvcDetail(AIKARI_SVC_NAME, "RUNNING");
|
2025-06-07 23:51:54 +08:00
|
|
|
default:
|
|
|
|
|
console.warn(
|
2025-11-14 02:58:09 +08:00
|
|
|
`[HugoAura / IPC / Aikari] <AikariLifecycleQuery> Invalid arg.target: ${arg.target}`
|
2025-06-07 23:51:54 +08:00
|
|
|
);
|
|
|
|
|
return {
|
|
|
|
|
success: false,
|
|
|
|
|
result: false,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.aikariLifecycleControl`,
|
2025-06-07 23:51:54 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {*} _event
|
2025-11-14 02:58:09 +08:00
|
|
|
* @param {{ target: import("../../../types/shared/aikari/status").AikariLifecycleControlType }} arg
|
2025-06-07 23:51:54 +08:00
|
|
|
* @returns {Promise<{ success: boolean, errorObj?: Error }>}
|
|
|
|
|
*/
|
|
|
|
|
async (_event, arg) => {
|
2025-11-14 02:58:09 +08:00
|
|
|
const logHeader = "[HugoAura / IPC / Aikari] <AikariLifecycleControl>";
|
2025-06-07 23:51:54 +08:00
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
// TODO: Impl this
|
2025-06-07 23:51:54 +08:00
|
|
|
switch (arg.target) {
|
|
|
|
|
case "instSvc":
|
|
|
|
|
return await functions.execCommand(
|
|
|
|
|
logHeader,
|
2025-11-14 02:58:09 +08:00
|
|
|
AIKARI_LAUNCHER_PATH,
|
2025-11-16 18:35:53 +08:00
|
|
|
"--service install"
|
2025-06-07 23:51:54 +08:00
|
|
|
);
|
2025-11-14 02:58:09 +08:00
|
|
|
case "uninstSvc": {
|
2025-06-21 19:20:01 +08:00
|
|
|
const result = await functions.execCommand(
|
|
|
|
|
logHeader,
|
2025-11-14 02:58:09 +08:00
|
|
|
AIKARI_LAUNCHER_PATH,
|
2025-11-16 18:35:53 +08:00
|
|
|
"--service uninstall"
|
2025-06-21 19:20:01 +08:00
|
|
|
);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2025-06-07 23:51:54 +08:00
|
|
|
case "startSvc":
|
2025-11-14 02:58:09 +08:00
|
|
|
return await functions.execCommand(
|
|
|
|
|
logHeader,
|
2025-11-16 18:35:53 +08:00
|
|
|
"sc.exe",
|
|
|
|
|
`start ${AIKARI_SVC_NAME}`
|
2025-11-14 02:58:09 +08:00
|
|
|
);
|
2025-06-21 19:20:01 +08:00
|
|
|
case "stopSvc": {
|
|
|
|
|
const result = await functions.execCommand(
|
|
|
|
|
logHeader,
|
2025-11-16 18:35:53 +08:00
|
|
|
"sc.exe",
|
|
|
|
|
`stop ${AIKARI_SVC_NAME}`
|
2025-06-21 19:20:01 +08:00
|
|
|
);
|
2025-11-14 02:58:09 +08:00
|
|
|
if (result.success && global.__HUGO_AURA__.aikariStats) {
|
|
|
|
|
global.__HUGO_AURA__.aikariStats.connected = false;
|
|
|
|
|
global.__HUGO_AURA__.aikariStats.launched = false;
|
|
|
|
|
global.__HUGO_AURA__.aikariStats.version = "unknown";
|
|
|
|
|
global.__HUGO_AURA__.aikariStats.status = "dead";
|
2025-06-21 19:20:01 +08:00
|
|
|
|
|
|
|
|
ipcMain.send(
|
|
|
|
|
"assistant",
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.post.onAikariStatsUpdate`,
|
|
|
|
|
global.__HUGO_AURA__.aikariStats
|
2025-06-21 19:20:01 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.send(
|
|
|
|
|
"auraWsKeepAlive",
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.post.aikariStopped`,
|
2025-06-21 19:20:01 +08:00
|
|
|
{}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2025-11-14 02:58:09 +08:00
|
|
|
case "inst":
|
|
|
|
|
// TODO: Impl Aikari INST
|
|
|
|
|
case "uninst":
|
2025-11-16 18:35:53 +08:00
|
|
|
return await functions.execCommand(
|
|
|
|
|
logHeader,
|
|
|
|
|
AIKARI_UNINSTALLER_PATH,
|
|
|
|
|
""
|
|
|
|
|
);
|
2025-06-07 23:51:54 +08:00
|
|
|
default:
|
|
|
|
|
return { success: false, errorObj: new Error("Method not found") };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.downloadAndInstallAikari`,
|
2025-06-09 18:02:11 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _evt
|
|
|
|
|
* @param {{channel?: "stable" | "alpha", reportTo?: import("../../../types/main/core").WindowName}} arg
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
(_evt, arg) => {
|
|
|
|
|
const channel = arg.channel ? arg.channel : "stable";
|
|
|
|
|
const reportWin = arg.reportTo ? arg.reportTo : "assistant";
|
2025-11-14 02:58:09 +08:00
|
|
|
functions.handleAikariDownload(
|
2025-06-09 18:02:11 +08:00
|
|
|
channel,
|
|
|
|
|
(status) => {
|
|
|
|
|
ipcMain.send(
|
|
|
|
|
reportWin,
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.post.reportAikariInstallStep`,
|
2025-06-09 18:02:11 +08:00
|
|
|
status
|
|
|
|
|
);
|
|
|
|
|
},
|
2025-11-14 02:58:09 +08:00
|
|
|
AIKARI_LAUNCHER_PATH
|
2025-06-09 18:02:11 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
2025-11-14 02:58:09 +08:00
|
|
|
`${methodBase}.retryAikariConnect`,
|
2025-06-06 02:05:04 +08:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
|
|
|
|
* @param {any} arg
|
|
|
|
|
* @returns {{ success: boolean, status: "Already" | "Retrying" }}
|
|
|
|
|
*/
|
|
|
|
|
(_event, arg) => {
|
2025-11-14 02:58:09 +08:00
|
|
|
if (global.__HUGO_AURA__.aikariStats?.connected) {
|
2025-06-06 02:05:04 +08:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
status: "Already",
|
|
|
|
|
};
|
|
|
|
|
} else {
|
2025-11-14 02:58:09 +08:00
|
|
|
ipcMain.send(
|
|
|
|
|
"auraWsKeepAlive",
|
|
|
|
|
`${methodBase}.retryAikariConnect`,
|
|
|
|
|
arg
|
|
|
|
|
);
|
2025-06-06 02:05:04 +08:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
status: "Retrying",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ipcMain.handle(
|
|
|
|
|
`${methodBase}.post.updateRetryStatus`,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {import("electron").IpcMainInvokeEvent} _event
|
|
|
|
|
* @param {{ success: boolean }} arg
|
|
|
|
|
*/
|
|
|
|
|
(_event, arg) => {
|
|
|
|
|
ipcMain.send("assistant", `${methodBase}.post.updateRetryStatus`, arg);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
);
|
2025-05-25 22:40:12 +08:00
|
|
|
};
|
|
|
|
|
|
2025-11-14 02:58:09 +08:00
|
|
|
module.exports = { applyAikariIpcHandler };
|